mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-24 16:12:33 +00:00
mul2dsp: normalize operand order
Move the operand commute that puts the wider operand on A ahead of the min-width checks. Checking the min-widths first made an asymmetric rule (DSP_A_MINWIDTH != DSP_B_MINWIDTH) match only products that already had the wider operand on A; a product in the other order was rejected before the normalization.
This commit is contained in:
parent
9914b6fa25
commit
63457de80e
2 changed files with 46 additions and 12 deletions
|
|
@ -68,6 +68,20 @@ module _80_mul (A, B, Y);
|
|||
|
||||
generate
|
||||
if (0) begin end
|
||||
// Normalize operand order (wider operand on A) to simplify asymmetric
|
||||
// rules (DSP_A_MINWIDTH != DSP_B_MINWIDTH) below.
|
||||
else if (_TECHMAP_CELLTYPE_ == "$mul" && A_WIDTH < B_WIDTH)
|
||||
\$mul #(
|
||||
.A_SIGNED(B_SIGNED),
|
||||
.B_SIGNED(A_SIGNED),
|
||||
.A_WIDTH(B_WIDTH),
|
||||
.B_WIDTH(A_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(B),
|
||||
.B(A),
|
||||
.Y(Y)
|
||||
);
|
||||
`ifdef DSP_A_MINWIDTH
|
||||
else if (A_WIDTH < `DSP_A_MINWIDTH)
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
|
|
@ -94,18 +108,6 @@ module _80_mul (A, B, Y);
|
|||
.Y(Y)
|
||||
);
|
||||
`endif
|
||||
else if (_TECHMAP_CELLTYPE_ == "$mul" && A_WIDTH < B_WIDTH)
|
||||
\$mul #(
|
||||
.A_SIGNED(B_SIGNED),
|
||||
.B_SIGNED(A_SIGNED),
|
||||
.A_WIDTH(B_WIDTH),
|
||||
.B_WIDTH(A_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(B),
|
||||
.B(A),
|
||||
.Y(Y)
|
||||
);
|
||||
else begin
|
||||
wire [1023:0] _TECHMAP_DO_ = "proc; clean";
|
||||
|
||||
|
|
|
|||
32
tests/techmap/mul2dsp_asymmetric.ys
Normal file
32
tests/techmap/mul2dsp_asymmetric.ys
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Test operand-order normalization: a 4x13 product with an asymmetric rule
|
||||
# (A_MIN=10, B_MIN=4) fails in this order (A=4 < A_MIN) but maps to one DSP
|
||||
# cell once the wide operand is normalized onto A.
|
||||
|
||||
read_verilog <<EOF
|
||||
module top(a, b, y);
|
||||
input signed [3:0] a;
|
||||
input signed [12:0] b;
|
||||
output signed [16:0] y;
|
||||
assign y = a * b;
|
||||
endmodule
|
||||
EOF
|
||||
|
||||
read_verilog -lib <<EOF
|
||||
module \$__MUL18X18 (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 18;
|
||||
parameter B_WIDTH = 18;
|
||||
parameter Y_WIDTH = 36;
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
endmodule
|
||||
EOF
|
||||
|
||||
hierarchy -top top
|
||||
proc
|
||||
techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=\$__MUL18X18
|
||||
|
||||
select -module top
|
||||
select -assert-count 1 t:\$__MUL18X18
|
||||
Loading…
Add table
Add a link
Reference in a new issue