2 // extracted from: https://github.com/eddiehung/vtr-with-yosys/blob/vtr7-with-yosys/vtr_flow/misc/yosys_models.v#L220
3 // revised by Andre DeHon
4 // further revised by David Shah
6 $error("Macro DSP_A_MAXWIDTH must be defined");
9 $error("Macro DSP_B_MAXWIDTH must be defined");
13 $error("Macro DSP_NAME must be defined");
16 `define MAX(a,b) (a > b ? a : b)
17 `define MIN(a,b) (a < b ? a : b)
19 module \$mul (A, B, Y);
20 parameter A_SIGNED = 0;
21 parameter B_SIGNED = 0;
22 parameter A_WIDTH = 1;
23 parameter B_WIDTH = 1;
24 parameter Y_WIDTH = 1;
26 input [A_WIDTH-1:0] A;
27 input [B_WIDTH-1:0] B;
28 output [Y_WIDTH-1:0] Y;
31 if (A_SIGNED != B_SIGNED)
32 wire _TECHMAP_FAIL_ = 1;
34 else if (!A_SIGNED) begin
39 .A_WIDTH(A_WIDTH + 1),
40 .B_WIDTH(B_WIDTH + 1),
49 // NB: A_SIGNED == B_SIGNED == 0 from here
50 else if (A_WIDTH >= B_WIDTH)
77 module \$__mul_gen (A, B, Y);
78 parameter A_SIGNED = 0;
79 parameter B_SIGNED = 0;
80 parameter A_WIDTH = 1;
81 parameter B_WIDTH = 1;
82 parameter Y_WIDTH = 1;
84 input [A_WIDTH-1:0] A;
85 input [B_WIDTH-1:0] B;
86 output [Y_WIDTH-1:0] Y;
88 wire [1023:0] _TECHMAP_DO_ = "proc; clean";
91 localparam sign_headroom = 1;
93 localparam sign_headroom = 0;
98 if (A_WIDTH > `DSP_A_MAXWIDTH) begin
99 localparam n = (A_WIDTH+`DSP_A_MAXWIDTH-sign_headroom-1) / (`DSP_A_MAXWIDTH-sign_headroom);
100 localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH);
101 if (A_SIGNED && B_SIGNED) begin
102 wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
103 wire signed [Y_WIDTH-1:0] partial_sum [n-1:0];
106 wire [partial_Y_WIDTH-1:0] partial [n-1:0];
107 wire [Y_WIDTH-1:0] partial_sum [n-1:0];
111 .A_SIGNED(sign_headroom),
113 .A_WIDTH(`DSP_A_MAXWIDTH),
115 .Y_WIDTH(partial_Y_WIDTH)
117 .A({{sign_headroom{1'b0}}, A[`DSP_A_MAXWIDTH-sign_headroom-1 : 0]}),
121 assign partial_sum[0] = partial[0];
123 for (i = 1; i < n-1; i=i+1) begin:slice
125 .A_SIGNED(sign_headroom),
127 .A_WIDTH(`DSP_A_MAXWIDTH),
129 .Y_WIDTH(partial_Y_WIDTH)
131 .A({{sign_headroom{1'b0}}, A[i*(`DSP_A_MAXWIDTH-sign_headroom) +: `DSP_A_MAXWIDTH-sign_headroom]}),
135 assign partial_sum[i] = (partial[i] << i*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[i-1];
141 .A_WIDTH(A_WIDTH-(n-1)*(`DSP_A_MAXWIDTH-sign_headroom)),
143 .Y_WIDTH(partial_Y_WIDTH)
145 .A(A[A_WIDTH-1 : (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)]),
149 assign partial_sum[n-1] = (partial[n-1] << (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[n-2];
150 assign Y = partial_sum[n-1];
152 else if (B_WIDTH > `DSP_B_MAXWIDTH) begin
153 localparam n = (B_WIDTH+`DSP_B_MAXWIDTH-sign_headroom-1) / (`DSP_B_MAXWIDTH-sign_headroom);
154 localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH);
155 if (A_SIGNED && B_SIGNED) begin
156 wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
157 wire signed [Y_WIDTH-1:0] partial_sum [n-1:0];
160 wire [partial_Y_WIDTH-1:0] partial [n-1:0];
161 wire [Y_WIDTH-1:0] partial_sum [n-1:0];
166 .B_SIGNED(sign_headroom),
168 .B_WIDTH(`DSP_B_MAXWIDTH),
169 .Y_WIDTH(partial_Y_WIDTH)
172 .B({{sign_headroom{1'b0}}, B[`DSP_B_MAXWIDTH-sign_headroom-1 : 0]}),
175 assign partial_sum[0] = partial[0];
177 for (i = 1; i < n-1; i=i+1) begin:slice
180 .B_SIGNED(sign_headroom),
182 .B_WIDTH(`DSP_B_MAXWIDTH),
183 .Y_WIDTH(partial_Y_WIDTH)
186 .B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH-sign_headroom) +: `DSP_B_MAXWIDTH-sign_headroom]}),
189 assign partial_sum[i] = (partial[i] << i*(`DSP_B_MAXWIDTH-sign_headroom)) + partial_sum[i-1];
196 .B_WIDTH(B_WIDTH-(n-1)*(`DSP_B_MAXWIDTH-sign_headroom)),
197 .Y_WIDTH(partial_Y_WIDTH)
200 .B(B[B_WIDTH-1 : (n-1)*(`DSP_B_MAXWIDTH-sign_headroom)]),
203 assign partial_sum[n-1] = (partial[n-1] << (n-1)*(`DSP_A_MAXWIDTH-sign_headroom)) + partial_sum[n-2];
204 assign Y = partial_sum[n-1];
208 wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A);
210 wire [`DSP_A_MAXWIDTH-1:0] Aext = A;
212 wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B);
214 wire [`DSP_B_MAXWIDTH-1:0] Bext = B;
219 .A_WIDTH(`DSP_A_MAXWIDTH),
220 .B_WIDTH(`DSP_B_MAXWIDTH),
221 .Y_WIDTH(`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH),
222 ) _TECHMAP_REPLACE_ (