Open eddiehung opened 5 years ago
Discussion with @cliffordwolf indicates that the problem could be that 1'bx in mux cells are not passed to ABC as 1'bx, but instead set to 1'b0...
It appears that ABC does not support 'bx
so it should be up to Yosys to perform don't care optimisations. Currently, the BLIF writer inside ABC will set all 'bx
to 'b0
Revisiting this, here are two even more obvious examples where $shiftx
sould be optimised:
// Only one value of A is not 1'bx, should be optimised to Y = A[0]
module test1 (A, B, Y);
input [15:0] A;
input [3:0] B;
output Y;
\$shiftx #(
.A_SIGNED(32'd0),
.A_WIDTH(32'sd16),
.B_SIGNED(32'd0),
.B_WIDTH(32'sd4),
.Y_WIDTH(32'd1)
) u1 (
.A({{15{1'bx}},A[32]}),
.B(B[3:0]),
.Y(Y)
);
endmodule
// All of A is 1'bx, should be optimised away entirely
module test2 (A, B, Y);
input [15:0] A;
input [3:0] B;
output Y;
\$shiftx #(
.A_SIGNED(32'd0),
.A_WIDTH(32'sd16),
.B_SIGNED(32'd0),
.B_WIDTH(32'sd4),
.Y_WIDTH(32'd1)
) u2 (
.A({16{1'bx}}),
.B(B[3:0]),
.Y(Y)
);
endmodule
// TODO: All but least-significant 2 bits of A are 1'bx, thus should transform into $shiftx with B_WIDTH=1, etc.
./yosys -p "opt -full; stat" shiftx.v
on the above gives:
=== test1 ===
Number of wires: 3
Number of wire bits: 21
Number of public wires: 3
Number of public wire bits: 21
Number of memories: 0
Number of memory bits: 0
Number of processes: 0
Number of cells: 1
\$shiftx 1
=== test2 ===
Number of wires: 3
Number of wire bits: 21
Number of public wires: 3
Number of public wire bits: 21
Number of memories: 0
Number of memory bits: 0
Number of processes: 0
Number of cells: 1
\$shiftx 1
@cliffordwolf Where should these optimisations be done? I can optimise them away using techmap rules, but they're not so much a pattern nor a peephole, so perhaps we should be enhancing opt
or wreduce
?
Where should these optimisations be done?
Afaict they are all combinatorical single-cell optimizations. As such they should go into opt_expr
.
Steps to reproduce the issue
yosys -p "read_verilog -icells shiftx.v; synth_xilinx; stat"
Expected behavior
no_opt*
circuits should be optimised away since all its inputs are the same. Difference between those andopt*
is that the latter have A_WIDTH == 2**B_WIDTH exactly.Actual behavior
no_opt*
circuits are not optimised away.