Open
Description
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?