Search code examples
synthesisyosys

Addition/Substraction Optimization in Yosys


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

Solution

  • 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.