I have the following very simple verilog module, which depending on the input op either performs a+b or a-b.
module addsub (a, b, op, r);
parameter DATA_WIDTH = 4;
input [DATA_WIDTH-1:0] a, b;
input op;
output [DATA_WIDTH-1:0] r;
assign r = op ? a-b : a+b;
endmodule
Now when I synthesize this code using yosys (version 0.9, script below) I get two $alu modules, both fed by the inputs a and b, where one has its CI and BI inputs asserted. The output r is generated using a mutliplexer.
read_verilog addsub.v
synth -flatten -run begin:fine
#share -aggressive; opt
show
However, I would like to get yosys the recognize that only one $alu is necessary, where the CI and BI inputs are connected to op. Hence, I tried the share command (commented out in the script above) and indeed the two $alus are merged into one, but now I get a strange (redundant) multiplexer structure at the inputs a and b see here.
My question is what am I doing wrong, is there a special pass to get rid of these multiplexers, or am I completely on the wrong track here?
Solution as suggested by David Shah: The yosys version I had installed did not feature the opt_share command. Hence, I compiled the current version (0.9+3558) and now the following synthesis script works as expected:
read_verilog addsub.v
synth -flatten -run begin:fine
share -aggressive; opt
opt_share; opt
show
The pass you are looking for is opt_share
, but it might be newer than the 0.9 release in which case you will need Yosys from git master.