amaranth icon indicating copy to clipboard operation
amaranth copied to clipboard

Code duplication when using a Value multiple times

Open tilk opened this issue 2 years ago • 2 comments

Take the following Amaranth code:

class X(Elaboratable):
    def __init__(self):
        self.i = Signal(8)
        self.o = Signal(8)

    def elaborate(self, platform):
        m = Module()

        v = self.i + self.i
        m.d.comb += self.o.eq(v * v)

        return m

It generates the following Verilog (comments removed for readability):

module top(o, i);
  wire [17:0] \$1 ;
  wire [8:0] \$2 ;
  wire [8:0] \$4 ;
  wire [17:0] \$6 ;
  input [7:0] i;
  wire [7:0] i;
  output [7:0] o;
  wire [7:0] o;
  assign \$2  = i + i;
  assign \$4  = i + i;
  assign \$6  = \$2  * \$4 ;
  assign \$1  = \$6 ;
  assign o = \$6 [7:0];
endmodule

Notice that the single assignment v = self.i + self.i translated to two Verilog assign statements assign \$2 = i + i; and assign \$4 = i + i;.

I understand that this is the consequence of treating Amaranth ASTs as trees (as opposed to DAGs, directed acyclic graphs). But this behavior might be unexpected for many Amaranth users, and lead to unexpected performance loss in some situations. (Here, Yosys is able to de-duplicate the expression; this might not work in general). Is this the intended behavior, or a bug?

tilk avatar May 22 '23 10:05 tilk

It was the intended behavior originally. However, I have some plans for a new Verilog/RTLIL backend, which would reuse identical subexpressions. There is no ETA on that.

whitequark avatar May 22 '23 11:05 whitequark

We have implemented the new IR. However, due to various compatibility reasons, the duplication still happens. It will likely be deduplicated by Amaranth 0.7.

whitequark avatar May 30 '24 10:05 whitequark