Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : // Copyright 2020 Western Digital Corporation or its affiliates.
3 : //
4 : // Licensed under the Apache License, Version 2.0 (the "License");
5 : // you may not use this file except in compliance with the License.
6 : // You may obtain a copy of the License at
7 : //
8 : // http://www.apache.org/licenses/LICENSE-2.0
9 : //
10 : // Unless required by applicable law or agreed to in writing, software
11 : // distributed under the License is distributed on an "AS IS" BASIS,
12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : // See the License for the specific language governing permissions and
14 : // limitations under the License.
15 :
16 :
17 : module el2_exu_div_ctl
18 : import el2_pkg::*;
19 : #(
20 : `include "el2_param.vh"
21 : )
22 : (
23 115887953 : input logic clk, // Top level clock
24 304 : input logic rst_l, // Reset
25 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
26 : /*pragma coverage off*/
27 : input logic scan_mode, // Scan mode
28 : /*pragma coverage on*/
29 :
30 951600 : input el2_div_pkt_t dp, // valid, sign, rem
31 5932435 : input logic [31:0] dividend, // Numerator
32 4842468 : input logic [31:0] divisor, // Denominator
33 :
34 2466 : input logic cancel, // Cancel divide
35 :
36 :
37 125198 : output logic finish_dly, // Finish to match data
38 42230 : output logic [31:0] out // Result
39 : );
40 :
41 :
42 72291 : logic [31:0] out_raw;
43 :
44 : assign out[31:0] = {32{finish_dly}} & out_raw[31:0]; // Qualification added to quiet result bus while divide is iterating
45 :
46 :
47 :
48 : if (pt.DIV_NEW == 0)
49 : begin : genblock1
50 : el2_exu_div_existing_1bit_cheapshortq i_existing_1bit_div_cheapshortq (
51 : .clk ( clk ), // I
52 : .rst_l ( rst_l ), // I
53 : .scan_mode ( scan_mode ), // I
54 : .cancel ( cancel ), // I
55 : .valid_in ( dp.valid ), // I
56 : .signed_in (~dp.unsign ), // I
57 : .rem_in ( dp.rem ), // I
58 : .dividend_in ( dividend[31:0] ), // I
59 : .divisor_in ( divisor[31:0] ), // I
60 : .valid_out ( finish_dly ), // O
61 : .data_out ( out_raw[31:0] )); // O
62 : end
63 :
64 :
65 : if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 1) )
66 : begin : genblock2
67 : el2_exu_div_new_1bit_fullshortq i_new_1bit_div_fullshortq (
68 : .clk ( clk ), // I
69 : .rst_l ( rst_l ), // I
70 : .scan_mode ( scan_mode ), // I
71 : .cancel ( cancel ), // I
72 : .valid_in ( dp.valid ), // I
73 : .signed_in (~dp.unsign ), // I
74 : .rem_in ( dp.rem ), // I
75 : .dividend_in ( dividend[31:0] ), // I
76 : .divisor_in ( divisor[31:0] ), // I
77 : .valid_out ( finish_dly ), // O
78 : .data_out ( out_raw[31:0] )); // O
79 : end
80 :
81 :
82 : if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 2) )
83 : begin : genblock3
84 : el2_exu_div_new_2bit_fullshortq i_new_2bit_div_fullshortq (
85 : .clk ( clk ), // I
86 : .rst_l ( rst_l ), // I
87 : .scan_mode ( scan_mode ), // I
88 : .cancel ( cancel ), // I
89 : .valid_in ( dp.valid ), // I
90 : .signed_in (~dp.unsign ), // I
91 : .rem_in ( dp.rem ), // I
92 : .dividend_in ( dividend[31:0] ), // I
93 : .divisor_in ( divisor[31:0] ), // I
94 : .valid_out ( finish_dly ), // O
95 : .data_out ( out_raw[31:0] )); // O
96 : end
97 :
98 :
99 : if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 3) )
100 : begin : genblock4
101 : el2_exu_div_new_3bit_fullshortq i_new_3bit_div_fullshortq (
102 : .clk ( clk ), // I
103 : .rst_l ( rst_l ), // I
104 : .scan_mode ( scan_mode ), // I
105 : .cancel ( cancel ), // I
106 : .valid_in ( dp.valid ), // I
107 : .signed_in (~dp.unsign ), // I
108 : .rem_in ( dp.rem ), // I
109 : .dividend_in ( dividend[31:0] ), // I
110 : .divisor_in ( divisor[31:0] ), // I
111 : .valid_out ( finish_dly ), // O
112 : .data_out ( out_raw[31:0] )); // O
113 : end
114 :
115 :
116 : if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 4) )
117 : begin : genblock5
118 : el2_exu_div_new_4bit_fullshortq i_new_4bit_div_fullshortq (
119 : .clk ( clk ), // I
120 : .rst_l ( rst_l ), // I
121 : .scan_mode ( scan_mode ), // I
122 : .cancel ( cancel ), // I
123 : .valid_in ( dp.valid ), // I
124 : .signed_in (~dp.unsign ), // I
125 : .rem_in ( dp.rem ), // I
126 : .dividend_in ( dividend[31:0] ), // I
127 : .divisor_in ( divisor[31:0] ), // I
128 : .valid_out ( finish_dly ), // O
129 : .data_out ( out_raw[31:0] )); // O
130 : end
131 :
132 :
133 :
134 : endmodule // el2_exu_div_ctl
135 :
136 :
137 :
138 :
139 :
140 :
141 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
142 : module el2_exu_div_existing_1bit_cheapshortq
143 : (
144 : input logic clk, // Top level clock
145 : input logic rst_l, // Reset
146 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
147 : /*pragma coverage off*/
148 : input logic scan_mode, // Scan mode
149 : /*pragma coverage on*/
150 :
151 : input logic cancel, // Flush pipeline
152 : input logic valid_in,
153 : input logic signed_in,
154 : input logic rem_in,
155 : input logic [31:0] dividend_in,
156 : input logic [31:0] divisor_in,
157 :
158 : output logic valid_out,
159 : output logic [31:0] data_out
160 : );
161 :
162 :
163 : logic div_clken;
164 : logic run_in, run_state;
165 : logic [5:0] count_in, count;
166 : logic [32:0] m_ff;
167 : logic qff_enable;
168 : logic aff_enable;
169 : logic [32:0] q_in, q_ff;
170 : logic [32:0] a_in, a_ff;
171 : logic [32:0] m_eff;
172 : logic [32:0] a_shift;
173 : logic dividend_neg_ff, divisor_neg_ff;
174 : logic [31:0] dividend_comp;
175 : logic [31:0] dividend_eff;
176 : logic [31:0] q_ff_comp;
177 : logic [31:0] q_ff_eff;
178 : logic [31:0] a_ff_comp;
179 : logic [31:0] a_ff_eff;
180 : logic sign_ff, sign_eff;
181 : logic rem_ff;
182 : logic add;
183 : logic [32:0] a_eff;
184 : logic [64:0] a_eff_shift;
185 : logic rem_correct;
186 : logic valid_ff_x;
187 : logic valid_x;
188 : logic finish;
189 : logic finish_ff;
190 :
191 : logic smallnum_case, smallnum_case_ff;
192 : logic [3:0] smallnum, smallnum_ff;
193 : logic m_already_comp;
194 :
195 : logic [4:0] a_cls;
196 : logic [4:0] b_cls;
197 : logic [5:0] shortq_shift;
198 : logic [5:0] shortq_shift_ff;
199 : logic [5:0] shortq;
200 : logic shortq_enable;
201 : logic shortq_enable_ff;
202 : logic [32:0] short_dividend;
203 : logic [3:0] shortq_raw;
204 : logic [3:0] shortq_shift_xx;
205 :
206 :
207 :
208 : rvdffe #(23) i_misc_ff (.*, .clk(clk), .en(div_clken), .din ({valid_in & ~cancel,
209 : finish & ~cancel,
210 : run_in,
211 : count_in[5:0],
212 : (valid_in & dividend_in[31]) | (~valid_in & dividend_neg_ff),
213 : (valid_in & divisor_in[31] ) | (~valid_in & divisor_neg_ff ),
214 : (valid_in & sign_eff ) | (~valid_in & sign_ff ),
215 : (valid_in & rem_in ) | (~valid_in & rem_ff ),
216 : smallnum_case,
217 : smallnum[3:0],
218 : shortq_enable,
219 : shortq_shift[3:0]}),
220 :
221 : .dout({valid_ff_x,
222 : finish_ff,
223 : run_state,
224 : count[5:0],
225 : dividend_neg_ff,
226 : divisor_neg_ff,
227 : sign_ff,
228 : rem_ff,
229 : smallnum_case_ff,
230 : smallnum_ff[3:0],
231 : shortq_enable_ff,
232 : shortq_shift_xx[3:0]}));
233 :
234 :
235 : rvdffe #(33) mff (.*, .clk(clk), .en(valid_in), .din({signed_in & divisor_in[31], divisor_in[31:0]}), .dout(m_ff[32:0]));
236 : rvdffe #(33) qff (.*, .clk(clk), .en(qff_enable), .din(q_in[32:0]), .dout(q_ff[32:0]));
237 : rvdffe #(33) aff (.*, .clk(clk), .en(aff_enable), .din(a_in[32:0]), .dout(a_ff[32:0]));
238 :
239 : rvtwoscomp #(32) i_dividend_comp (.din(q_ff[31:0]), .dout(dividend_comp[31:0]));
240 : rvtwoscomp #(32) i_q_ff_comp (.din(q_ff[31:0]), .dout(q_ff_comp[31:0]));
241 : rvtwoscomp #(32) i_a_ff_comp (.din(a_ff[31:0]), .dout(a_ff_comp[31:0]));
242 :
243 :
244 : assign valid_x = valid_ff_x & ~cancel;
245 :
246 :
247 : // START - short circuit logic for small numbers {{
248 :
249 : // small number divides - any 4b / 4b is done in 1 cycle (divisor != 0)
250 : // to generate espresso equations:
251 : // 1. smalldiv > smalldiv.e
252 : // 2. espresso -Dso -oeqntott smalldiv.e | addassign > smalldiv
253 :
254 : // smallnum case does not cover divide by 0
255 : assign smallnum_case = ((q_ff[31:4] == 28'b0) & (m_ff[31:4] == 28'b0) & (m_ff[31:0] != 32'b0) & ~rem_ff & valid_x) |
256 : ((q_ff[31:0] == 32'b0) & (m_ff[31:0] != 32'b0) & ~rem_ff & valid_x);
257 :
258 :
259 : assign smallnum[3] = ( q_ff[3] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] );
260 :
261 :
262 : assign smallnum[2] = ( q_ff[3] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) |
263 : ( q_ff[2] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) |
264 : ( q_ff[3] & q_ff[2] & ~m_ff[3] & ~m_ff[2] );
265 :
266 :
267 : assign smallnum[1] = ( q_ff[2] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) |
268 : ( q_ff[1] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) |
269 : ( q_ff[3] & ~m_ff[3] & ~m_ff[1] & ~m_ff[0]) |
270 : ( q_ff[3] & ~q_ff[2] & ~m_ff[3] & ~m_ff[2] & m_ff[1] & m_ff[0]) |
271 : (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & ~m_ff[2] ) |
272 : ( q_ff[3] & q_ff[2] & ~m_ff[3] & ~m_ff[0]) |
273 : ( q_ff[3] & q_ff[2] & ~m_ff[3] & m_ff[2] & ~m_ff[1] ) |
274 : ( q_ff[3] & q_ff[1] & ~m_ff[3] & ~m_ff[1] ) |
275 : ( q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[2] );
276 :
277 :
278 : assign smallnum[0] = ( q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & ~m_ff[1] ) |
279 : ( q_ff[3] & ~q_ff[2] & q_ff[0] & ~m_ff[3] & m_ff[1] & m_ff[0]) |
280 : ( q_ff[2] & ~m_ff[3] & ~m_ff[1] & ~m_ff[0]) |
281 : ( q_ff[1] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) |
282 : ( q_ff[0] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) |
283 : (~q_ff[3] & q_ff[2] & ~q_ff[1] & ~m_ff[3] & ~m_ff[2] & m_ff[1] & m_ff[0]) |
284 : (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & ~m_ff[0]) |
285 : ( q_ff[3] & ~m_ff[2] & ~m_ff[1] & ~m_ff[0]) |
286 : ( q_ff[3] & ~q_ff[2] & ~m_ff[3] & m_ff[2] & m_ff[1] ) |
287 : (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[2] & ~m_ff[1] ) |
288 : (~q_ff[3] & q_ff[2] & q_ff[0] & ~m_ff[3] & ~m_ff[1] ) |
289 : ( q_ff[3] & ~q_ff[2] & ~q_ff[1] & ~m_ff[3] & m_ff[2] & m_ff[0]) |
290 : ( ~q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & ~m_ff[2] ) |
291 : ( q_ff[3] & q_ff[2] & ~m_ff[1] & ~m_ff[0]) |
292 : ( q_ff[3] & q_ff[1] & ~m_ff[2] & ~m_ff[0]) |
293 : (~q_ff[3] & q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & m_ff[2] ) |
294 : ( q_ff[3] & q_ff[2] & m_ff[3] & ~m_ff[2] ) |
295 : ( q_ff[3] & q_ff[1] & m_ff[3] & ~m_ff[2] & ~m_ff[1] ) |
296 : ( q_ff[3] & q_ff[0] & ~m_ff[2] & ~m_ff[1] ) |
297 : ( q_ff[3] & ~q_ff[1] & ~m_ff[3] & m_ff[2] & m_ff[1] & m_ff[0]) |
298 : ( q_ff[3] & q_ff[2] & q_ff[1] & m_ff[3] & ~m_ff[0]) |
299 : ( q_ff[3] & q_ff[2] & q_ff[1] & m_ff[3] & ~m_ff[1] ) |
300 : ( q_ff[3] & q_ff[2] & q_ff[0] & m_ff[3] & ~m_ff[1] ) |
301 : ( q_ff[3] & ~q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[1] ) |
302 : ( q_ff[3] & q_ff[1] & q_ff[0] & ~m_ff[2] ) |
303 : ( q_ff[3] & q_ff[2] & q_ff[1] & q_ff[0] & m_ff[3] );
304 :
305 :
306 : // END - short circuit logic for small numbers }}
307 :
308 :
309 : // *** Start Short Q *** {{
310 :
311 : assign short_dividend[31:0] = q_ff[31:0];
312 : assign short_dividend[32] = sign_ff & q_ff[31];
313 :
314 :
315 : // A B
316 : // 210 210 SH
317 : // --- --- --
318 : // 1xx 000 0
319 : // 1xx 001 8
320 : // 1xx 01x 16
321 : // 1xx 1xx 24
322 : // 01x 000 8
323 : // 01x 001 16
324 : // 01x 01x 24
325 : // 01x 1xx 32
326 : // 001 000 16
327 : // 001 001 24
328 : // 001 01x 32
329 : // 001 1xx 32
330 : // 000 000 24
331 : // 000 001 32
332 : // 000 01x 32
333 : // 000 1xx 32
334 :
335 : assign a_cls[4:3] = 2'b0;
336 : assign a_cls[2] = (~short_dividend[32] & (short_dividend[31:24] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[31:23] != {9{1'b1}}));
337 : assign a_cls[1] = (~short_dividend[32] & (short_dividend[23:16] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[22:15] != {8{1'b1}}));
338 : assign a_cls[0] = (~short_dividend[32] & (short_dividend[15:08] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[14:07] != {8{1'b1}}));
339 :
340 : assign b_cls[4:3] = 2'b0;
341 : assign b_cls[2] = (~m_ff[32] & ( m_ff[31:24] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[31:24] != {8{1'b1}}));
342 : assign b_cls[1] = (~m_ff[32] & ( m_ff[23:16] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[23:16] != {8{1'b1}}));
343 : assign b_cls[0] = (~m_ff[32] & ( m_ff[15:08] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[15:08] != {8{1'b1}}));
344 :
345 : assign shortq_raw[3] = ( (a_cls[2:1] == 2'b01 ) & (b_cls[2] == 1'b1 ) ) | // Shift by 32
346 : ( (a_cls[2:0] == 3'b001) & (b_cls[2] == 1'b1 ) ) |
347 : ( (a_cls[2:0] == 3'b000) & (b_cls[2] == 1'b1 ) ) |
348 : ( (a_cls[2:0] == 3'b001) & (b_cls[2:1] == 2'b01 ) ) |
349 : ( (a_cls[2:0] == 3'b000) & (b_cls[2:1] == 2'b01 ) ) |
350 : ( (a_cls[2:0] == 3'b000) & (b_cls[2:0] == 3'b001) );
351 :
352 : assign shortq_raw[2] = ( (a_cls[2] == 1'b1 ) & (b_cls[2] == 1'b1 ) ) | // Shift by 24
353 : ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:1] == 2'b01 ) ) |
354 : ( (a_cls[2:0] == 3'b001) & (b_cls[2:0] == 3'b001) ) |
355 : ( (a_cls[2:0] == 3'b000) & (b_cls[2:0] == 3'b000) );
356 :
357 : assign shortq_raw[1] = ( (a_cls[2] == 1'b1 ) & (b_cls[2:1] == 2'b01 ) ) | // Shift by 16
358 : ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:0] == 3'b001) ) |
359 : ( (a_cls[2:0] == 3'b001) & (b_cls[2:0] == 3'b000) );
360 :
361 : assign shortq_raw[0] = ( (a_cls[2] == 1'b1 ) & (b_cls[2:0] == 3'b001) ) | // Shift by 8
362 : ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:0] == 3'b000) );
363 :
364 :
365 : assign shortq_enable = valid_ff_x & (m_ff[31:0] != 32'b0) & (shortq_raw[3:0] != 4'b0);
366 :
367 : assign shortq_shift[3:0] = ({4{shortq_enable}} & shortq_raw[3:0]);
368 :
369 : assign shortq[5:0] = 6'b0;
370 : assign shortq_shift[5:4] = 2'b0;
371 : assign shortq_shift_ff[5] = 1'b0;
372 :
373 : assign shortq_shift_ff[4:0] = ({5{shortq_shift_xx[3]}} & 5'b1_1111) | // 31
374 : ({5{shortq_shift_xx[2]}} & 5'b1_1000) | // 24
375 : ({5{shortq_shift_xx[1]}} & 5'b1_0000) | // 16
376 : ({5{shortq_shift_xx[0]}} & 5'b0_1000); // 8
377 :
378 : // *** End Short *** }}
379 :
380 :
381 :
382 :
383 :
384 : assign div_clken = valid_in | run_state | finish | finish_ff;
385 :
386 : assign run_in = (valid_in | run_state) & ~finish & ~cancel;
387 :
388 : assign count_in[5:0] = {6{run_state & ~finish & ~cancel & ~shortq_enable}} & (count[5:0] + {1'b0,shortq_shift_ff[4:0]} + 6'd1);
389 :
390 :
391 : assign finish = (smallnum_case | ((~rem_ff) ? (count[5:0] == 6'd32) : (count[5:0] == 6'd33)));
392 :
393 : assign valid_out = finish_ff & ~cancel;
394 :
395 : assign sign_eff = signed_in & (divisor_in[31:0] != 32'b0);
396 :
397 :
398 : assign q_in[32:0] = ({33{~run_state }} & {1'b0,dividend_in[31:0]}) |
399 : ({33{ run_state & (valid_ff_x | shortq_enable_ff)}} & ({dividend_eff[31:0], ~a_in[32]} << shortq_shift_ff[4:0])) |
400 : ({33{ run_state & ~(valid_ff_x | shortq_enable_ff)}} & {q_ff[31:0], ~a_in[32]});
401 :
402 : assign qff_enable = valid_in | (run_state & ~shortq_enable);
403 :
404 :
405 :
406 :
407 : assign dividend_eff[31:0] = (sign_ff & dividend_neg_ff) ? dividend_comp[31:0] : q_ff[31:0];
408 :
409 :
410 : assign m_eff[32:0] = ( add ) ? m_ff[32:0] : ~m_ff[32:0];
411 :
412 : assign a_eff_shift[64:0] = {33'b0, dividend_eff[31:0]} << shortq_shift_ff[4:0];
413 :
414 : assign a_eff[32:0] = ({33{ rem_correct }} & a_ff[32:0] ) |
415 : ({33{~rem_correct & ~shortq_enable_ff}} & {a_ff[31:0], q_ff[32]} ) |
416 : ({33{~rem_correct & shortq_enable_ff}} & a_eff_shift[64:32] );
417 :
418 : assign a_shift[32:0] = {33{run_state}} & a_eff[32:0];
419 :
420 : assign a_in[32:0] = {33{run_state}} & (a_shift[32:0] + m_eff[32:0] + {32'b0,~add});
421 :
422 : assign aff_enable = valid_in | (run_state & ~shortq_enable & (count[5:0]!=6'd33)) | rem_correct;
423 :
424 :
425 : assign m_already_comp = (divisor_neg_ff & sign_ff);
426 :
427 : // if m already complemented, then invert operation add->sub, sub->add
428 : assign add = (a_ff[32] | rem_correct) ^ m_already_comp;
429 :
430 : assign rem_correct = (count[5:0] == 6'd33) & rem_ff & a_ff[32];
431 :
432 :
433 :
434 : assign q_ff_eff[31:0] = (sign_ff & (dividend_neg_ff ^ divisor_neg_ff)) ? q_ff_comp[31:0] : q_ff[31:0];
435 :
436 : assign a_ff_eff[31:0] = (sign_ff & dividend_neg_ff) ? a_ff_comp[31:0] : a_ff[31:0];
437 :
438 : assign data_out[31:0] = ({32{ smallnum_case_ff }} & {28'b0, smallnum_ff[3:0]}) |
439 : ({32{ rem_ff}} & a_ff_eff[31:0] ) |
440 : ({32{~smallnum_case_ff & ~rem_ff}} & q_ff_eff[31:0] );
441 :
442 :
443 :
444 :
445 : endmodule // el2_exu_div_existing_1bit_cheapshortq
446 :
447 :
448 :
449 :
450 :
451 :
452 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
453 : module el2_exu_div_new_1bit_fullshortq
454 : (
455 : input logic clk, // Top level clock
456 : input logic rst_l, // Reset
457 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
458 : /*pragma coverage off*/
459 : input logic scan_mode, // Scan mode
460 : /*pragma coverage on*/
461 :
462 : input logic cancel, // Flush pipeline
463 : input logic valid_in,
464 : input logic signed_in,
465 : input logic rem_in,
466 : input logic [31:0] dividend_in,
467 : input logic [31:0] divisor_in,
468 :
469 : output logic valid_out,
470 : output logic [31:0] data_out
471 : );
472 :
473 :
474 : logic valid_ff_in, valid_ff;
475 : logic finish_raw, finish, finish_ff;
476 : logic running_state;
477 : logic misc_enable;
478 : logic [2:0] control_in, control_ff;
479 : logic dividend_sign_ff, divisor_sign_ff, rem_ff;
480 : logic count_enable;
481 : logic [6:0] count_in, count_ff;
482 :
483 : logic smallnum_case;
484 : logic [3:0] smallnum;
485 :
486 : logic a_enable, a_shift;
487 : logic [31:0] a_in, a_ff;
488 :
489 : logic b_enable, b_twos_comp;
490 : logic [32:0] b_in, b_ff;
491 :
492 : logic [31:0] q_in, q_ff;
493 :
494 : logic rq_enable, r_sign_sel, r_restore_sel, r_adder_sel;
495 : logic [31:0] r_in, r_ff;
496 :
497 : logic twos_comp_q_sel, twos_comp_b_sel;
498 : logic [31:0] twos_comp_in, twos_comp_out;
499 :
500 : logic quotient_set;
501 : logic [32:0] adder_out;
502 :
503 : logic [63:0] ar_shifted;
504 : logic [5:0] shortq;
505 : logic [4:0] shortq_shift;
506 : logic [4:0] shortq_shift_ff;
507 : logic shortq_enable;
508 : logic shortq_enable_ff;
509 : logic [32:0] shortq_dividend;
510 :
511 : logic by_zero_case;
512 : logic by_zero_case_ff;
513 :
514 :
515 :
516 : rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
517 : .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
518 :
519 : rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
520 : rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
521 : rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0]));
522 : rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
523 :
524 :
525 :
526 :
527 : assign valid_ff_in = valid_in & ~cancel;
528 :
529 : assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]);
530 : assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]);
531 : assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in);
532 :
533 : assign dividend_sign_ff = control_ff[2];
534 : assign divisor_sign_ff = control_ff[1];
535 : assign rem_ff = control_ff[0];
536 :
537 :
538 : assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0);
539 :
540 : assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
541 : assign running_state = (| count_ff[6:0]) | shortq_enable_ff;
542 : assign finish_raw = smallnum_case |
543 : by_zero_case |
544 : (count_ff[6:0] == 7'd32);
545 :
546 :
547 : assign finish = finish_raw & ~cancel;
548 : assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable;
549 : assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {6'b0,1'b1} + {2'b0,shortq_shift_ff[4:0]});
550 :
551 :
552 : assign a_enable = valid_in | running_state;
553 : assign a_shift = running_state & ~shortq_enable_ff;
554 :
555 : assign ar_shifted[63:0] = { {32{dividend_sign_ff}} , a_ff[31:0]} << shortq_shift_ff[4:0];
556 :
557 : assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) |
558 : ( {32{ a_shift }} & {a_ff[30:0],1'b0} ) |
559 : ( {32{ shortq_enable_ff}} & ar_shifted[31:0] );
560 :
561 :
562 :
563 : assign b_enable = valid_in | b_twos_comp;
564 : assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
565 :
566 : assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) |
567 : ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } );
568 :
569 :
570 : assign rq_enable = valid_in | valid_ff | running_state;
571 : assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case;
572 : assign r_restore_sel = running_state & ~quotient_set & ~shortq_enable_ff;
573 : assign r_adder_sel = running_state & quotient_set & ~shortq_enable_ff;
574 :
575 :
576 : assign r_in[31:0] = ( {32{r_sign_sel }} & 32'hffffffff ) |
577 : ( {32{r_restore_sel }} & {r_ff[30:0] ,a_ff[31]} ) |
578 : ( {32{r_adder_sel }} & adder_out[31:0] ) |
579 : ( {32{shortq_enable_ff}} & ar_shifted[63:32] ) |
580 : ( {32{by_zero_case }} & a_ff[31:0] );
581 :
582 :
583 : assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[30:0], quotient_set} ) |
584 : ( {32{ smallnum_case }} & {28'b0 , smallnum[3:0]} ) |
585 : ( {32{ by_zero_case }} & {32{1'b1}} );
586 :
587 :
588 :
589 : assign adder_out[32:0] = {r_ff[31:0],a_ff[31]} + {b_ff[32:0] };
590 :
591 :
592 : assign quotient_set = (~adder_out[32] ^ dividend_sign_ff) | ( (a_ff[30:0] == 31'b0) & (adder_out[32:0] == 33'b0) );
593 :
594 :
595 :
596 : assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
597 : assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff;
598 :
599 : assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
600 : ( {32{twos_comp_b_sel}} & b_ff[31:0] );
601 :
602 : rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
603 :
604 :
605 :
606 : assign valid_out = finish_ff & ~cancel;
607 :
608 : assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) |
609 : ( {32{ rem_ff }} & r_ff[31:0] ) |
610 : ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] );
611 :
612 :
613 :
614 :
615 : // *** *** *** START : SMALLNUM {{
616 :
617 : assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) |
618 : ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel);
619 :
620 : assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] );
621 :
622 : assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
623 : ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
624 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] );
625 :
626 : assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
627 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
628 : ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
629 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
630 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) |
631 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) |
632 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
633 : ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) |
634 : ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] );
635 :
636 : assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
637 : ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) |
638 : ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
639 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
640 : ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
641 : (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
642 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) |
643 : ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) |
644 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) |
645 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
646 : (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
647 : ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) |
648 : ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) |
649 : ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) |
650 : ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) |
651 : (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) |
652 : ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) |
653 : ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
654 : ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) |
655 : ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) |
656 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) |
657 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) |
658 : ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) |
659 : ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) |
660 : ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) |
661 : ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] );
662 :
663 : // *** *** *** END : SMALLNUM }}
664 :
665 :
666 :
667 :
668 : // *** *** *** Start : Short Q {{
669 :
670 : assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]};
671 :
672 :
673 : logic [5:0] dw_a_enc;
674 : logic [5:0] dw_b_enc;
675 : logic [6:0] dw_shortq_raw;
676 :
677 :
678 :
679 : el2_exu_div_cls i_a_cls (
680 : .operand ( shortq_dividend[32:0] ),
681 : .cls ( dw_a_enc[4:0] ));
682 :
683 : el2_exu_div_cls i_b_cls (
684 : .operand ( b_ff[32:0] ),
685 : .cls ( dw_b_enc[4:0] ));
686 :
687 : assign dw_a_enc[5] = 1'b0;
688 : assign dw_b_enc[5] = 1'b0;
689 :
690 :
691 :
692 : assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1;
693 : assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0];
694 :
695 : assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:1] == 4'b1111) & ~cancel;
696 :
697 : assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : (5'b11111 - shortq[4:0]);
698 :
699 :
700 : // *** *** *** End : Short Q }}
701 :
702 :
703 :
704 :
705 :
706 : endmodule // el2_exu_div_new_1bit_fullshortq
707 :
708 :
709 :
710 :
711 :
712 :
713 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
714 : module el2_exu_div_new_2bit_fullshortq
715 : (
716 : input logic clk, // Top level clock
717 : input logic rst_l, // Reset
718 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
719 : /*pragma coverage off*/
720 : input logic scan_mode, // Scan mode
721 : /*pragma coverage on*/
722 :
723 : input logic cancel, // Flush pipeline
724 : input logic valid_in,
725 : input logic signed_in,
726 : input logic rem_in,
727 : input logic [31:0] dividend_in,
728 : input logic [31:0] divisor_in,
729 :
730 : output logic valid_out,
731 : output logic [31:0] data_out
732 : );
733 :
734 :
735 : logic valid_ff_in, valid_ff;
736 : logic finish_raw, finish, finish_ff;
737 : logic running_state;
738 : logic misc_enable;
739 : logic [2:0] control_in, control_ff;
740 : logic dividend_sign_ff, divisor_sign_ff, rem_ff;
741 : logic count_enable;
742 : logic [6:0] count_in, count_ff;
743 :
744 : logic smallnum_case;
745 : logic [3:0] smallnum;
746 :
747 : logic a_enable, a_shift;
748 : logic [31:0] a_in, a_ff;
749 :
750 : logic b_enable, b_twos_comp;
751 : logic [32:0] b_in;
752 : logic [34:0] b_ff;
753 :
754 : logic [31:0] q_in, q_ff;
755 :
756 : logic rq_enable, r_sign_sel, r_restore_sel, r_adder1_sel, r_adder2_sel, r_adder3_sel;
757 : logic [31:0] r_in, r_ff;
758 :
759 : logic twos_comp_q_sel, twos_comp_b_sel;
760 : logic [31:0] twos_comp_in, twos_comp_out;
761 :
762 : logic [3:1] quotient_raw;
763 : logic [1:0] quotient_new;
764 : logic [32:0] adder1_out;
765 : logic [33:0] adder2_out;
766 : logic [34:0] adder3_out;
767 :
768 : logic [63:0] ar_shifted;
769 : logic [5:0] shortq;
770 : logic [4:0] shortq_shift;
771 : logic [4:1] shortq_shift_ff;
772 : logic shortq_enable;
773 : logic shortq_enable_ff;
774 : logic [32:0] shortq_dividend;
775 :
776 : logic by_zero_case;
777 : logic by_zero_case_ff;
778 :
779 :
780 :
781 : rvdffe #(18) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:1], finish, count_in[6:0]}),
782 : .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:1], finish_ff, count_ff[6:0]}));
783 :
784 : rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
785 : rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
786 : rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0]));
787 : rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
788 :
789 :
790 :
791 :
792 : assign valid_ff_in = valid_in & ~cancel;
793 :
794 : assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]);
795 : assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]);
796 : assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in);
797 :
798 : assign dividend_sign_ff = control_ff[2];
799 : assign divisor_sign_ff = control_ff[1];
800 : assign rem_ff = control_ff[0];
801 :
802 :
803 : assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0);
804 :
805 : assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
806 : assign running_state = (| count_ff[6:0]) | shortq_enable_ff;
807 : assign finish_raw = smallnum_case |
808 : by_zero_case |
809 : (count_ff[6:0] == 7'd32);
810 :
811 :
812 : assign finish = finish_raw & ~cancel;
813 : assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable;
814 : assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {5'b0,2'b10} + {2'b0,shortq_shift_ff[4:1],1'b0});
815 :
816 :
817 : assign a_enable = valid_in | running_state;
818 : assign a_shift = running_state & ~shortq_enable_ff;
819 :
820 : assign ar_shifted[63:0] = { {32{dividend_sign_ff}} , a_ff[31:0]} << {shortq_shift_ff[4:1],1'b0};
821 :
822 : assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) |
823 : ( {32{ a_shift }} & {a_ff[29:0],2'b0} ) |
824 : ( {32{ shortq_enable_ff}} & ar_shifted[31:0] );
825 :
826 :
827 :
828 : assign b_enable = valid_in | b_twos_comp;
829 : assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
830 :
831 : assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) |
832 : ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } );
833 :
834 :
835 : assign rq_enable = valid_in | valid_ff | running_state;
836 : assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case;
837 : assign r_restore_sel = running_state & (quotient_new[1:0] == 2'b00) & ~shortq_enable_ff;
838 : assign r_adder1_sel = running_state & (quotient_new[1:0] == 2'b01) & ~shortq_enable_ff;
839 : assign r_adder2_sel = running_state & (quotient_new[1:0] == 2'b10) & ~shortq_enable_ff;
840 : assign r_adder3_sel = running_state & (quotient_new[1:0] == 2'b11) & ~shortq_enable_ff;
841 :
842 :
843 : assign r_in[31:0] = ( {32{r_sign_sel }} & 32'hffffffff ) |
844 : ( {32{r_restore_sel }} & {r_ff[29:0] ,a_ff[31:30]} ) |
845 : ( {32{r_adder1_sel }} & adder1_out[31:0] ) |
846 : ( {32{r_adder2_sel }} & adder2_out[31:0] ) |
847 : ( {32{r_adder3_sel }} & adder3_out[31:0] ) |
848 : ( {32{shortq_enable_ff}} & ar_shifted[63:32] ) |
849 : ( {32{by_zero_case }} & a_ff[31:0] );
850 :
851 :
852 : assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[29:0], quotient_new[1:0]} ) |
853 : ( {32{ smallnum_case }} & {28'b0 , smallnum[3:0]} ) |
854 : ( {32{ by_zero_case }} & {32{1'b1}} );
855 :
856 :
857 : assign b_ff[34:33] = {b_ff[32],b_ff[32]};
858 :
859 :
860 : assign adder1_out[32:0] = { r_ff[30:0],a_ff[31:30]} + b_ff[32:0];
861 : assign adder2_out[33:0] = { r_ff[31:0],a_ff[31:30]} + {b_ff[32:0],1'b0};
862 : assign adder3_out[34:0] = {r_ff[31],r_ff[31:0],a_ff[31:30]} + {b_ff[33:0],1'b0} + b_ff[34:0];
863 :
864 :
865 : assign quotient_raw[1] = (~adder1_out[32] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder1_out[32:0] == 33'b0) );
866 : assign quotient_raw[2] = (~adder2_out[33] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder2_out[33:0] == 34'b0) );
867 : assign quotient_raw[3] = (~adder3_out[34] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder3_out[34:0] == 35'b0) );
868 :
869 : assign quotient_new[1] = quotient_raw[3] | quotient_raw[2];
870 : assign quotient_new[0] = quotient_raw[3] |(~quotient_raw[2] & quotient_raw[1]);
871 :
872 :
873 : assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
874 : assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff;
875 :
876 : assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
877 : ( {32{twos_comp_b_sel}} & b_ff[31:0] );
878 :
879 : rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
880 :
881 :
882 :
883 : assign valid_out = finish_ff & ~cancel;
884 :
885 : assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) |
886 : ( {32{ rem_ff }} & r_ff[31:0] ) |
887 : ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] );
888 :
889 :
890 :
891 :
892 : // *** *** *** START : SMALLNUM {{
893 :
894 : assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) |
895 : ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel);
896 :
897 : assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] );
898 :
899 : assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
900 : ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
901 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] );
902 :
903 : assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
904 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
905 : ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
906 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
907 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) |
908 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) |
909 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
910 : ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) |
911 : ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] );
912 :
913 : assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
914 : ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) |
915 : ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
916 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
917 : ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
918 : (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
919 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) |
920 : ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) |
921 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) |
922 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
923 : (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
924 : ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) |
925 : ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) |
926 : ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) |
927 : ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) |
928 : (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) |
929 : ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) |
930 : ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
931 : ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) |
932 : ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) |
933 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) |
934 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) |
935 : ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) |
936 : ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) |
937 : ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) |
938 : ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] );
939 :
940 : // *** *** *** END : SMALLNUM }}
941 :
942 :
943 :
944 :
945 : // *** *** *** Start : Short Q {{
946 :
947 : assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]};
948 :
949 :
950 : logic [5:0] dw_a_enc;
951 : logic [5:0] dw_b_enc;
952 : logic [6:0] dw_shortq_raw;
953 :
954 :
955 :
956 : el2_exu_div_cls i_a_cls (
957 : .operand ( shortq_dividend[32:0] ),
958 : .cls ( dw_a_enc[4:0] ));
959 :
960 : el2_exu_div_cls i_b_cls (
961 : .operand ( b_ff[32:0] ),
962 : .cls ( dw_b_enc[4:0] ));
963 :
964 : assign dw_a_enc[5] = 1'b0;
965 : assign dw_b_enc[5] = 1'b0;
966 :
967 :
968 :
969 : assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1;
970 : assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0];
971 :
972 : assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:1] == 4'b1111) & ~cancel;
973 :
974 : assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : (5'b11111 - shortq[4:0]); // [0] is unused
975 :
976 :
977 : // *** *** *** End : Short Q }}
978 :
979 :
980 :
981 :
982 :
983 : endmodule // el2_exu_div_new_2bit_fullshortq
984 :
985 :
986 :
987 :
988 :
989 :
990 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
991 : module el2_exu_div_new_3bit_fullshortq
992 : (
993 : input logic clk, // Top level clock
994 : input logic rst_l, // Reset
995 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
996 : /*pragma coverage off*/
997 : input logic scan_mode, // Scan mode
998 : /*pragma coverage on*/
999 :
1000 : input logic cancel, // Flush pipeline
1001 : input logic valid_in,
1002 : input logic signed_in,
1003 : input logic rem_in,
1004 : input logic [31:0] dividend_in,
1005 : input logic [31:0] divisor_in,
1006 :
1007 : output logic valid_out,
1008 : output logic [31:0] data_out
1009 : );
1010 :
1011 :
1012 : logic valid_ff_in, valid_ff;
1013 : logic finish_raw, finish, finish_ff;
1014 : logic running_state;
1015 : logic misc_enable;
1016 : logic [2:0] control_in, control_ff;
1017 : logic dividend_sign_ff, divisor_sign_ff, rem_ff;
1018 : logic count_enable;
1019 : logic [6:0] count_in, count_ff;
1020 :
1021 : logic smallnum_case;
1022 : logic [3:0] smallnum;
1023 :
1024 : logic a_enable, a_shift;
1025 : logic [32:0] a_in, a_ff;
1026 :
1027 : logic b_enable, b_twos_comp;
1028 : logic [32:0] b_in;
1029 : logic [36:0] b_ff;
1030 :
1031 : logic [31:0] q_in, q_ff;
1032 :
1033 : logic rq_enable;
1034 : logic r_sign_sel;
1035 : logic r_restore_sel;
1036 : logic r_adder1_sel, r_adder2_sel, r_adder3_sel, r_adder4_sel, r_adder5_sel, r_adder6_sel, r_adder7_sel;
1037 : logic [32:0] r_in, r_ff;
1038 :
1039 : logic twos_comp_q_sel, twos_comp_b_sel;
1040 : logic [31:0] twos_comp_in, twos_comp_out;
1041 :
1042 : logic [7:1] quotient_raw;
1043 : logic [2:0] quotient_new;
1044 : logic [33:0] adder1_out;
1045 : logic [34:0] adder2_out;
1046 : logic [35:0] adder3_out;
1047 : logic [36:0] adder4_out;
1048 : logic [36:0] adder5_out;
1049 : logic [36:0] adder6_out;
1050 : logic [36:0] adder7_out;
1051 :
1052 : logic [65:0] ar_shifted;
1053 : logic [5:0] shortq;
1054 : logic [4:0] shortq_shift;
1055 : logic [4:0] shortq_decode;
1056 : logic [4:0] shortq_shift_ff;
1057 : logic shortq_enable;
1058 : logic shortq_enable_ff;
1059 : logic [32:0] shortq_dividend;
1060 :
1061 : logic by_zero_case;
1062 : logic by_zero_case_ff;
1063 :
1064 :
1065 :
1066 : rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
1067 : .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
1068 :
1069 : rvdffe #(33) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[32:0]), .dout(a_ff[32:0]));
1070 : rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
1071 : rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0]));
1072 : rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
1073 :
1074 :
1075 :
1076 :
1077 : assign valid_ff_in = valid_in & ~cancel;
1078 :
1079 : assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]);
1080 : assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]);
1081 : assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in);
1082 :
1083 : assign dividend_sign_ff = control_ff[2];
1084 : assign divisor_sign_ff = control_ff[1];
1085 : assign rem_ff = control_ff[0];
1086 :
1087 :
1088 : assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0);
1089 :
1090 : assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
1091 : assign running_state = (| count_ff[6:0]) | shortq_enable_ff;
1092 : assign finish_raw = smallnum_case |
1093 : by_zero_case |
1094 : (count_ff[6:0] == 7'd33);
1095 :
1096 :
1097 : assign finish = finish_raw & ~cancel;
1098 : assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable;
1099 : assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {5'b0,2'b11} + {2'b0,shortq_shift_ff[4:0]});
1100 :
1101 :
1102 : assign a_enable = valid_in | running_state;
1103 : assign a_shift = running_state & ~shortq_enable_ff;
1104 :
1105 : assign ar_shifted[65:0] = { {33{dividend_sign_ff}} , a_ff[32:0]} << {shortq_shift_ff[4:0]};
1106 :
1107 : assign a_in[32:0] = ( {33{~a_shift & ~shortq_enable_ff}} & {signed_in & dividend_in[31],dividend_in[31:0]} ) |
1108 : ( {33{ a_shift }} & {a_ff[29:0],3'b0} ) |
1109 : ( {33{ shortq_enable_ff}} & ar_shifted[32:0] );
1110 :
1111 :
1112 :
1113 : assign b_enable = valid_in | b_twos_comp;
1114 : assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
1115 :
1116 : assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) |
1117 : ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } );
1118 :
1119 :
1120 : assign rq_enable = valid_in | valid_ff | running_state;
1121 : assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case;
1122 : assign r_restore_sel = running_state & (quotient_new[2:0] == 3'b000) & ~shortq_enable_ff;
1123 : assign r_adder1_sel = running_state & (quotient_new[2:0] == 3'b001) & ~shortq_enable_ff;
1124 : assign r_adder2_sel = running_state & (quotient_new[2:0] == 3'b010) & ~shortq_enable_ff;
1125 : assign r_adder3_sel = running_state & (quotient_new[2:0] == 3'b011) & ~shortq_enable_ff;
1126 : assign r_adder4_sel = running_state & (quotient_new[2:0] == 3'b100) & ~shortq_enable_ff;
1127 : assign r_adder5_sel = running_state & (quotient_new[2:0] == 3'b101) & ~shortq_enable_ff;
1128 : assign r_adder6_sel = running_state & (quotient_new[2:0] == 3'b110) & ~shortq_enable_ff;
1129 : assign r_adder7_sel = running_state & (quotient_new[2:0] == 3'b111) & ~shortq_enable_ff;
1130 :
1131 :
1132 : assign r_in[32:0] = ( {33{r_sign_sel }} & {33{1'b1}} ) |
1133 : ( {33{r_restore_sel }} & {r_ff[29:0] ,a_ff[32:30]} ) |
1134 : ( {33{r_adder1_sel }} & adder1_out[32:0] ) |
1135 : ( {33{r_adder2_sel }} & adder2_out[32:0] ) |
1136 : ( {33{r_adder3_sel }} & adder3_out[32:0] ) |
1137 : ( {33{r_adder4_sel }} & adder4_out[32:0] ) |
1138 : ( {33{r_adder5_sel }} & adder5_out[32:0] ) |
1139 : ( {33{r_adder6_sel }} & adder6_out[32:0] ) |
1140 : ( {33{r_adder7_sel }} & adder7_out[32:0] ) |
1141 : ( {33{shortq_enable_ff}} & ar_shifted[65:33] ) |
1142 : ( {33{by_zero_case }} & {1'b0,a_ff[31:0]} );
1143 :
1144 :
1145 : assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[28:0], quotient_new[2:0]} ) |
1146 : ( {32{ smallnum_case}} & {28'b0 , smallnum[3:0]} ) |
1147 : ( {32{ by_zero_case }} & {32{1'b1}} );
1148 :
1149 :
1150 : assign b_ff[36:33] = {b_ff[32],b_ff[32],b_ff[32],b_ff[32]};
1151 :
1152 :
1153 : assign adder1_out[33:0] = { r_ff[30:0],a_ff[32:30]} + b_ff[33:0];
1154 : assign adder2_out[34:0] = { r_ff[31:0],a_ff[32:30]} + {b_ff[33:0],1'b0};
1155 : assign adder3_out[35:0] = { r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],1'b0} + b_ff[35:0];
1156 : assign adder4_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0};
1157 : assign adder5_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + b_ff[36:0];
1158 : assign adder6_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + {b_ff[35:0],1'b0};
1159 : assign adder7_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + {b_ff[35:0],1'b0} + b_ff[36:0];
1160 :
1161 : assign quotient_raw[1] = (~adder1_out[33] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder1_out[33:0] == 34'b0) );
1162 : assign quotient_raw[2] = (~adder2_out[34] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder2_out[34:0] == 35'b0) );
1163 : assign quotient_raw[3] = (~adder3_out[35] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder3_out[35:0] == 36'b0) );
1164 : assign quotient_raw[4] = (~adder4_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder4_out[36:0] == 37'b0) );
1165 : assign quotient_raw[5] = (~adder5_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder5_out[36:0] == 37'b0) );
1166 : assign quotient_raw[6] = (~adder6_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder6_out[36:0] == 37'b0) );
1167 : assign quotient_raw[7] = (~adder7_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder7_out[36:0] == 37'b0) );
1168 :
1169 : assign quotient_new[2] = quotient_raw[7] | quotient_raw[6] | quotient_raw[5] | quotient_raw[4];
1170 : assign quotient_new[1] = quotient_raw[7] | quotient_raw[6] | (~quotient_raw[4] & quotient_raw[3]) | (~quotient_raw[3] & quotient_raw[2]);
1171 : assign quotient_new[0] = quotient_raw[7] | (~quotient_raw[6] & quotient_raw[5]) | (~quotient_raw[4] & quotient_raw[3]) | (~quotient_raw[2] & quotient_raw[1]);
1172 :
1173 :
1174 : assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
1175 : assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff;
1176 :
1177 : assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
1178 : ( {32{twos_comp_b_sel}} & b_ff[31:0] );
1179 :
1180 : rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
1181 :
1182 :
1183 :
1184 : assign valid_out = finish_ff & ~cancel;
1185 :
1186 : assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) |
1187 : ( {32{ rem_ff }} & r_ff[31:0] ) |
1188 : ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] );
1189 :
1190 :
1191 :
1192 :
1193 : // *** *** *** START : SMALLNUM {{
1194 :
1195 : assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) |
1196 : ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel);
1197 :
1198 : assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] );
1199 :
1200 : assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1201 : ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1202 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] );
1203 :
1204 : assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1205 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1206 : ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
1207 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
1208 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) |
1209 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) |
1210 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
1211 : ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) |
1212 : ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] );
1213 :
1214 : assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
1215 : ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) |
1216 : ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
1217 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1218 : ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1219 : (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
1220 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) |
1221 : ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) |
1222 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) |
1223 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
1224 : (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
1225 : ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) |
1226 : ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) |
1227 : ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) |
1228 : ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) |
1229 : (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) |
1230 : ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) |
1231 : ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1232 : ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) |
1233 : ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) |
1234 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) |
1235 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) |
1236 : ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) |
1237 : ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) |
1238 : ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) |
1239 : ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] );
1240 :
1241 : // *** *** *** END : SMALLNUM }}
1242 :
1243 :
1244 :
1245 :
1246 : // *** *** *** Start : Short Q {{
1247 :
1248 : assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]};
1249 :
1250 :
1251 : logic [5:0] dw_a_enc;
1252 : logic [5:0] dw_b_enc;
1253 : logic [6:0] dw_shortq_raw;
1254 :
1255 :
1256 :
1257 : el2_exu_div_cls i_a_cls (
1258 : .operand ( shortq_dividend[32:0] ),
1259 : .cls ( dw_a_enc[4:0] ));
1260 :
1261 : el2_exu_div_cls i_b_cls (
1262 : .operand ( b_ff[32:0] ),
1263 : .cls ( dw_b_enc[4:0] ));
1264 :
1265 : assign dw_a_enc[5] = 1'b0;
1266 : assign dw_b_enc[5] = 1'b0;
1267 :
1268 :
1269 :
1270 : assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1;
1271 : assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0];
1272 :
1273 : assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:2] == 3'b111) & ~cancel;
1274 :
1275 : assign shortq_decode[4:0] = ( {5{shortq[4:0] == 5'd31}} & 5'd00) |
1276 : ( {5{shortq[4:0] == 5'd30}} & 5'd00) |
1277 : ( {5{shortq[4:0] == 5'd29}} & 5'd00) |
1278 : ( {5{shortq[4:0] == 5'd28}} & 5'd00) |
1279 : ( {5{shortq[4:0] == 5'd27}} & 5'd03) |
1280 : ( {5{shortq[4:0] == 5'd26}} & 5'd06) |
1281 : ( {5{shortq[4:0] == 5'd25}} & 5'd06) |
1282 : ( {5{shortq[4:0] == 5'd24}} & 5'd06) |
1283 : ( {5{shortq[4:0] == 5'd23}} & 5'd09) |
1284 : ( {5{shortq[4:0] == 5'd22}} & 5'd09) |
1285 : ( {5{shortq[4:0] == 5'd21}} & 5'd09) |
1286 : ( {5{shortq[4:0] == 5'd20}} & 5'd12) |
1287 : ( {5{shortq[4:0] == 5'd19}} & 5'd12) |
1288 : ( {5{shortq[4:0] == 5'd18}} & 5'd12) |
1289 : ( {5{shortq[4:0] == 5'd17}} & 5'd15) |
1290 : ( {5{shortq[4:0] == 5'd16}} & 5'd15) |
1291 : ( {5{shortq[4:0] == 5'd15}} & 5'd15) |
1292 : ( {5{shortq[4:0] == 5'd14}} & 5'd18) |
1293 : ( {5{shortq[4:0] == 5'd13}} & 5'd18) |
1294 : ( {5{shortq[4:0] == 5'd12}} & 5'd18) |
1295 : ( {5{shortq[4:0] == 5'd11}} & 5'd21) |
1296 : ( {5{shortq[4:0] == 5'd10}} & 5'd21) |
1297 : ( {5{shortq[4:0] == 5'd09}} & 5'd21) |
1298 : ( {5{shortq[4:0] == 5'd08}} & 5'd24) |
1299 : ( {5{shortq[4:0] == 5'd07}} & 5'd24) |
1300 : ( {5{shortq[4:0] == 5'd06}} & 5'd24) |
1301 : ( {5{shortq[4:0] == 5'd05}} & 5'd27) |
1302 : ( {5{shortq[4:0] == 5'd04}} & 5'd27) |
1303 : ( {5{shortq[4:0] == 5'd03}} & 5'd27) |
1304 : ( {5{shortq[4:0] == 5'd02}} & 5'd27) |
1305 : ( {5{shortq[4:0] == 5'd01}} & 5'd27) |
1306 : ( {5{shortq[4:0] == 5'd00}} & 5'd27);
1307 :
1308 :
1309 : assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : shortq_decode[4:0];
1310 :
1311 :
1312 : // *** *** *** End : Short Q }}
1313 :
1314 :
1315 :
1316 :
1317 :
1318 : endmodule // el2_exu_div_new_3bit_fullshortq
1319 :
1320 :
1321 :
1322 :
1323 :
1324 :
1325 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1326 : module el2_exu_div_new_4bit_fullshortq
1327 : (
1328 115887953 : input logic clk, // Top level clock
1329 304 : input logic rst_l, // Reset
1330 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
1331 : /*pragma coverage off*/
1332 : input logic scan_mode, // Scan mode
1333 : /*pragma coverage on*/
1334 :
1335 2466 : input logic cancel, // Flush pipeline
1336 127664 : input logic valid_in,
1337 950218 : input logic signed_in,
1338 61957 : input logic rem_in,
1339 5932435 : input logic [31:0] dividend_in,
1340 4842468 : input logic [31:0] divisor_in,
1341 :
1342 125198 : output logic valid_out,
1343 72291 : output logic [31:0] data_out
1344 : );
1345 :
1346 :
1347 127664 : logic valid_ff_in, valid_ff;
1348 126098 : logic finish_raw, finish, finish_ff;
1349 123204 : logic running_state;
1350 126244 : logic misc_enable;
1351 32033 : logic [2:0] control_in, control_ff;
1352 32033 : logic dividend_sign_ff, divisor_sign_ff, rem_ff;
1353 78506 : logic count_enable;
1354 81610 : logic [6:0] count_in, count_ff;
1355 :
1356 18300 : logic smallnum_case;
1357 46062 : logic [3:0] smallnum;
1358 :
1359 250846 : logic a_enable, a_shift;
1360 5962672 : logic [31:0] a_in, a_ff;
1361 :
1362 127664 : logic b_enable, b_twos_comp;
1363 4860542 : logic [32:0] b_in;
1364 107068 : logic [37:0] b_ff;
1365 :
1366 161533 : logic [31:0] q_in, q_ff;
1367 :
1368 127642 : logic rq_enable;
1369 9784 : logic r_sign_sel;
1370 61410 : logic r_restore_sel;
1371 16968 : logic r_adder01_sel, r_adder02_sel, r_adder03_sel;
1372 6326 : logic r_adder04_sel, r_adder05_sel, r_adder06_sel, r_adder07_sel;
1373 8308 : logic r_adder08_sel, r_adder09_sel, r_adder10_sel, r_adder11_sel;
1374 9542 : logic r_adder12_sel, r_adder13_sel, r_adder14_sel, r_adder15_sel;
1375 66772 : logic [32:0] r_in, r_ff;
1376 :
1377 109564 : logic twos_comp_q_sel, twos_comp_b_sel;
1378 73114 : logic [31:0] twos_comp_in, twos_comp_out;
1379 :
1380 165929 : logic [15:1] quotient_raw;
1381 167727 : logic [3:0] quotient_new;
1382 163536 : logic [34:0] adder01_out;
1383 157784 : logic [35:0] adder02_out;
1384 180361 : logic [36:0] adder03_out;
1385 157124 : logic [37:0] adder04_out;
1386 172489 : logic [37:0] adder05_out;
1387 176384 : logic [37:0] adder06_out;
1388 179988 : logic [37:0] adder07_out;
1389 152291 : logic [37:0] adder08_out;
1390 167908 : logic [37:0] adder09_out;
1391 165299 : logic [37:0] adder10_out;
1392 170367 : logic [37:0] adder11_out;
1393 163140 : logic [37:0] adder12_out;
1394 161894 : logic [37:0] adder13_out;
1395 162103 : logic [37:0] adder14_out;
1396 160856 : logic [37:0] adder15_out;
1397 :
1398 63861 : logic [64:0] ar_shifted;
1399 85683 : logic [5:0] shortq;
1400 107452 : logic [4:0] shortq_shift;
1401 54360 : logic [4:0] shortq_decode;
1402 107452 : logic [4:0] shortq_shift_ff;
1403 116748 : logic shortq_enable;
1404 116748 : logic shortq_enable_ff;
1405 60589 : logic [32:0] shortq_dividend;
1406 :
1407 29292 : logic by_zero_case;
1408 29292 : logic by_zero_case_ff;
1409 :
1410 :
1411 :
1412 : rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
1413 : .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
1414 :
1415 : rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
1416 : rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
1417 : rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0]));
1418 : rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
1419 :
1420 :
1421 :
1422 :
1423 : assign valid_ff_in = valid_in & ~cancel;
1424 :
1425 : assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]);
1426 : assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]);
1427 : assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in);
1428 :
1429 : assign dividend_sign_ff = control_ff[2];
1430 : assign divisor_sign_ff = control_ff[1];
1431 : assign rem_ff = control_ff[0];
1432 :
1433 :
1434 : assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0);
1435 :
1436 : assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
1437 : assign running_state = (| count_ff[6:0]) | shortq_enable_ff;
1438 : assign finish_raw = smallnum_case |
1439 : by_zero_case |
1440 : (count_ff[6:0] == 7'd32);
1441 :
1442 :
1443 : assign finish = finish_raw & ~cancel;
1444 : assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable;
1445 : assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + 7'd4 + {2'b0,shortq_shift_ff[4:0]});
1446 :
1447 :
1448 : assign a_enable = valid_in | running_state;
1449 : assign a_shift = running_state & ~shortq_enable_ff;
1450 :
1451 : assign ar_shifted[64:0] = { {33{dividend_sign_ff}} , a_ff[31:0]} << {shortq_shift_ff[4:0]};
1452 :
1453 : assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) |
1454 : ( {32{ a_shift }} & {a_ff[27:0],4'b0} ) |
1455 : ( {32{ shortq_enable_ff}} & ar_shifted[31:0] );
1456 :
1457 :
1458 :
1459 : assign b_enable = valid_in | b_twos_comp;
1460 : assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
1461 :
1462 : assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) |
1463 : ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } );
1464 :
1465 :
1466 : assign rq_enable = valid_in | valid_ff | running_state;
1467 : assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case;
1468 : assign r_restore_sel = running_state & (quotient_new[3:0] == 4'd00) & ~shortq_enable_ff;
1469 : assign r_adder01_sel = running_state & (quotient_new[3:0] == 4'd01) & ~shortq_enable_ff;
1470 : assign r_adder02_sel = running_state & (quotient_new[3:0] == 4'd02) & ~shortq_enable_ff;
1471 : assign r_adder03_sel = running_state & (quotient_new[3:0] == 4'd03) & ~shortq_enable_ff;
1472 : assign r_adder04_sel = running_state & (quotient_new[3:0] == 4'd04) & ~shortq_enable_ff;
1473 : assign r_adder05_sel = running_state & (quotient_new[3:0] == 4'd05) & ~shortq_enable_ff;
1474 : assign r_adder06_sel = running_state & (quotient_new[3:0] == 4'd06) & ~shortq_enable_ff;
1475 : assign r_adder07_sel = running_state & (quotient_new[3:0] == 4'd07) & ~shortq_enable_ff;
1476 : assign r_adder08_sel = running_state & (quotient_new[3:0] == 4'd08) & ~shortq_enable_ff;
1477 : assign r_adder09_sel = running_state & (quotient_new[3:0] == 4'd09) & ~shortq_enable_ff;
1478 : assign r_adder10_sel = running_state & (quotient_new[3:0] == 4'd10) & ~shortq_enable_ff;
1479 : assign r_adder11_sel = running_state & (quotient_new[3:0] == 4'd11) & ~shortq_enable_ff;
1480 : assign r_adder12_sel = running_state & (quotient_new[3:0] == 4'd12) & ~shortq_enable_ff;
1481 : assign r_adder13_sel = running_state & (quotient_new[3:0] == 4'd13) & ~shortq_enable_ff;
1482 : assign r_adder14_sel = running_state & (quotient_new[3:0] == 4'd14) & ~shortq_enable_ff;
1483 : assign r_adder15_sel = running_state & (quotient_new[3:0] == 4'd15) & ~shortq_enable_ff;
1484 :
1485 : assign r_in[32:0] = ( {33{r_sign_sel }} & {33{1'b1}} ) |
1486 : ( {33{r_restore_sel }} & {r_ff[28:0],a_ff[31:28]} ) |
1487 : ( {33{r_adder01_sel }} & adder01_out[32:0] ) |
1488 : ( {33{r_adder02_sel }} & adder02_out[32:0] ) |
1489 : ( {33{r_adder03_sel }} & adder03_out[32:0] ) |
1490 : ( {33{r_adder04_sel }} & adder04_out[32:0] ) |
1491 : ( {33{r_adder05_sel }} & adder05_out[32:0] ) |
1492 : ( {33{r_adder06_sel }} & adder06_out[32:0] ) |
1493 : ( {33{r_adder07_sel }} & adder07_out[32:0] ) |
1494 : ( {33{r_adder08_sel }} & adder08_out[32:0] ) |
1495 : ( {33{r_adder09_sel }} & adder09_out[32:0] ) |
1496 : ( {33{r_adder10_sel }} & adder10_out[32:0] ) |
1497 : ( {33{r_adder11_sel }} & adder11_out[32:0] ) |
1498 : ( {33{r_adder12_sel }} & adder12_out[32:0] ) |
1499 : ( {33{r_adder13_sel }} & adder13_out[32:0] ) |
1500 : ( {33{r_adder14_sel }} & adder14_out[32:0] ) |
1501 : ( {33{r_adder15_sel }} & adder15_out[32:0] ) |
1502 : ( {33{shortq_enable_ff}} & ar_shifted[64:32] ) |
1503 : ( {33{by_zero_case }} & {1'b0,a_ff[31:0]} );
1504 :
1505 :
1506 : assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[27:0], quotient_new[3:0]} ) |
1507 : ( {32{ smallnum_case}} & {28'b0 , smallnum[3:0]} ) |
1508 : ( {32{ by_zero_case }} & {32{1'b1}} );
1509 :
1510 :
1511 : assign b_ff[37:33] = {b_ff[32],b_ff[32],b_ff[32],b_ff[32],b_ff[32]};
1512 :
1513 :
1514 : assign adder01_out[34:0] = { r_ff[30:0],a_ff[31:28]} + b_ff[34:0];
1515 : assign adder02_out[35:0] = { r_ff[31:0],a_ff[31:28]} + {b_ff[34:0],1'b0};
1516 : assign adder03_out[36:0] = { r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],1'b0} + b_ff[36:0];
1517 : assign adder04_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0};
1518 : assign adder05_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + b_ff[37:0];
1519 : assign adder06_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0};
1520 : assign adder07_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0} + b_ff[37:0];
1521 : assign adder08_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0};
1522 : assign adder09_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + b_ff[37:0];
1523 : assign adder10_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[36:0],1'b0};
1524 : assign adder11_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[36:0],1'b0} + b_ff[37:0];
1525 : assign adder12_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0};
1526 : assign adder13_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + b_ff[37:0];
1527 : assign adder14_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0};
1528 : assign adder15_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0} + b_ff[37:0];
1529 :
1530 : assign quotient_raw[01] = (~adder01_out[34] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder01_out[34:0] == 35'b0) );
1531 : assign quotient_raw[02] = (~adder02_out[35] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder02_out[35:0] == 36'b0) );
1532 : assign quotient_raw[03] = (~adder03_out[36] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder03_out[36:0] == 37'b0) );
1533 : assign quotient_raw[04] = (~adder04_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder04_out[37:0] == 38'b0) );
1534 : assign quotient_raw[05] = (~adder05_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder05_out[37:0] == 38'b0) );
1535 : assign quotient_raw[06] = (~adder06_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder06_out[37:0] == 38'b0) );
1536 : assign quotient_raw[07] = (~adder07_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder07_out[37:0] == 38'b0) );
1537 : assign quotient_raw[08] = (~adder08_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder08_out[37:0] == 38'b0) );
1538 : assign quotient_raw[09] = (~adder09_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder09_out[37:0] == 38'b0) );
1539 : assign quotient_raw[10] = (~adder10_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder10_out[37:0] == 38'b0) );
1540 : assign quotient_raw[11] = (~adder11_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder11_out[37:0] == 38'b0) );
1541 : assign quotient_raw[12] = (~adder12_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder12_out[37:0] == 38'b0) );
1542 : assign quotient_raw[13] = (~adder13_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder13_out[37:0] == 38'b0) );
1543 : assign quotient_raw[14] = (~adder14_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder14_out[37:0] == 38'b0) );
1544 : assign quotient_raw[15] = (~adder15_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder15_out[37:0] == 38'b0) );
1545 :
1546 :
1547 : assign quotient_new[0] = ( quotient_raw[15:01] == 15'b000_0000_0000_0001 ) | // 1
1548 : ( quotient_raw[15:03] == 13'b000_0000_0000_01 ) | // 3
1549 : ( quotient_raw[15:05] == 11'b000_0000_0001 ) | // 5
1550 : ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7
1551 : ( quotient_raw[15:09] == 7'b000_0001 ) | // 9
1552 : ( quotient_raw[15:11] == 5'b000_01 ) | // 11
1553 : ( quotient_raw[15:13] == 3'b001 ) | // 13
1554 : ( quotient_raw[ 15] == 1'b1 ); // 15
1555 :
1556 : assign quotient_new[1] = ( quotient_raw[15:02] == 14'b000_0000_0000_001 ) | // 2
1557 : ( quotient_raw[15:03] == 13'b000_0000_0000_01 ) | // 3
1558 : ( quotient_raw[15:06] == 10'b000_0000_001 ) | // 6
1559 : ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7
1560 : ( quotient_raw[15:10] == 6'b000_001 ) | // 10
1561 : ( quotient_raw[15:11] == 5'b000_01 ) | // 11
1562 : ( quotient_raw[15:14] == 2'b01 ) | // 14
1563 : ( quotient_raw[ 15] == 1'b1 ); // 15
1564 :
1565 : assign quotient_new[2] = ( quotient_raw[15:04] == 12'b000_0000_0000_1 ) | // 4
1566 : ( quotient_raw[15:05] == 11'b000_0000_0001 ) | // 5
1567 : ( quotient_raw[15:06] == 10'b000_0000_001 ) | // 6
1568 : ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7
1569 : ( quotient_raw[15:12] == 4'b000_1 ) | // 12
1570 : ( quotient_raw[15:13] == 3'b001 ) | // 13
1571 : ( quotient_raw[15:14] == 2'b01 ) | // 14
1572 : ( quotient_raw[ 15] == 1'b1 ); // 15
1573 :
1574 : assign quotient_new[3] = ( quotient_raw[15:08] == 8'b000_0000_1 ) | // 8
1575 : ( quotient_raw[15:09] == 7'b000_0001 ) | // 9
1576 : ( quotient_raw[15:10] == 6'b000_001 ) | // 10
1577 : ( quotient_raw[15:11] == 5'b000_01 ) | // 11
1578 : ( quotient_raw[15:12] == 4'b000_1 ) | // 12
1579 : ( quotient_raw[15:13] == 3'b001 ) | // 13
1580 : ( quotient_raw[15:14] == 2'b01 ) | // 14
1581 : ( quotient_raw[ 15] == 1'b1 ); // 15
1582 :
1583 :
1584 : assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff);
1585 : assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff;
1586 :
1587 : assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
1588 : ( {32{twos_comp_b_sel}} & b_ff[31:0] );
1589 :
1590 : rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
1591 :
1592 :
1593 :
1594 : assign valid_out = finish_ff & ~cancel;
1595 :
1596 : assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) |
1597 : ( {32{ rem_ff }} & r_ff[31:0] ) |
1598 : ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] );
1599 :
1600 :
1601 :
1602 :
1603 : // *** *** *** START : SMALLNUM {{
1604 :
1605 : assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) |
1606 : ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel);
1607 :
1608 : assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] );
1609 :
1610 : assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1611 : ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1612 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] );
1613 :
1614 : assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1615 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1616 : ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
1617 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
1618 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) |
1619 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) |
1620 : ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
1621 : ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) |
1622 : ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] );
1623 :
1624 : assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
1625 : ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) |
1626 : ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) |
1627 : ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) |
1628 : ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1629 : (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) |
1630 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) |
1631 : ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) |
1632 : ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) |
1633 : (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) |
1634 : (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) |
1635 : ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) |
1636 : ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) |
1637 : ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) |
1638 : ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) |
1639 : (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) |
1640 : ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) |
1641 : ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) |
1642 : ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) |
1643 : ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) |
1644 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) |
1645 : ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) |
1646 : ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) |
1647 : ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) |
1648 : ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) |
1649 : ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] );
1650 :
1651 : // *** *** *** END : SMALLNUM }}
1652 :
1653 :
1654 :
1655 :
1656 : // *** *** *** Start : Short Q {{
1657 :
1658 : assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]};
1659 :
1660 :
1661 57682 : logic [5:0] dw_a_enc;
1662 44620 : logic [5:0] dw_b_enc;
1663 83828 : logic [6:0] dw_shortq_raw;
1664 :
1665 :
1666 :
1667 : el2_exu_div_cls i_a_cls (
1668 : .operand ( shortq_dividend[32:0] ),
1669 : .cls ( dw_a_enc[4:0] ));
1670 :
1671 : el2_exu_div_cls i_b_cls (
1672 : .operand ( b_ff[32:0] ),
1673 : .cls ( dw_b_enc[4:0] ));
1674 :
1675 : assign dw_a_enc[5] = 1'b0;
1676 : assign dw_b_enc[5] = 1'b0;
1677 :
1678 :
1679 : assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1;
1680 : assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0];
1681 :
1682 : assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:2] == 3'b111) & ~cancel;
1683 :
1684 : assign shortq_decode[4:0] = ( {5{shortq[4:0] == 5'd31}} & 5'd00) |
1685 : ( {5{shortq[4:0] == 5'd30}} & 5'd00) |
1686 : ( {5{shortq[4:0] == 5'd29}} & 5'd00) |
1687 : ( {5{shortq[4:0] == 5'd28}} & 5'd00) |
1688 : ( {5{shortq[4:0] == 5'd27}} & 5'd04) |
1689 : ( {5{shortq[4:0] == 5'd26}} & 5'd04) |
1690 : ( {5{shortq[4:0] == 5'd25}} & 5'd04) |
1691 : ( {5{shortq[4:0] == 5'd24}} & 5'd04) |
1692 : ( {5{shortq[4:0] == 5'd23}} & 5'd08) |
1693 : ( {5{shortq[4:0] == 5'd22}} & 5'd08) |
1694 : ( {5{shortq[4:0] == 5'd21}} & 5'd08) |
1695 : ( {5{shortq[4:0] == 5'd20}} & 5'd08) |
1696 : ( {5{shortq[4:0] == 5'd19}} & 5'd12) |
1697 : ( {5{shortq[4:0] == 5'd18}} & 5'd12) |
1698 : ( {5{shortq[4:0] == 5'd17}} & 5'd12) |
1699 : ( {5{shortq[4:0] == 5'd16}} & 5'd12) |
1700 : ( {5{shortq[4:0] == 5'd15}} & 5'd16) |
1701 : ( {5{shortq[4:0] == 5'd14}} & 5'd16) |
1702 : ( {5{shortq[4:0] == 5'd13}} & 5'd16) |
1703 : ( {5{shortq[4:0] == 5'd12}} & 5'd16) |
1704 : ( {5{shortq[4:0] == 5'd11}} & 5'd20) |
1705 : ( {5{shortq[4:0] == 5'd10}} & 5'd20) |
1706 : ( {5{shortq[4:0] == 5'd09}} & 5'd20) |
1707 : ( {5{shortq[4:0] == 5'd08}} & 5'd20) |
1708 : ( {5{shortq[4:0] == 5'd07}} & 5'd24) |
1709 : ( {5{shortq[4:0] == 5'd06}} & 5'd24) |
1710 : ( {5{shortq[4:0] == 5'd05}} & 5'd24) |
1711 : ( {5{shortq[4:0] == 5'd04}} & 5'd24) |
1712 : ( {5{shortq[4:0] == 5'd03}} & 5'd28) |
1713 : ( {5{shortq[4:0] == 5'd02}} & 5'd28) |
1714 : ( {5{shortq[4:0] == 5'd01}} & 5'd28) |
1715 : ( {5{shortq[4:0] == 5'd00}} & 5'd28);
1716 :
1717 :
1718 : assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : shortq_decode[4:0];
1719 :
1720 :
1721 : // *** *** *** End : Short Q }}
1722 :
1723 :
1724 :
1725 :
1726 :
1727 : endmodule // el2_exu_div_new_4bit_fullshortq
1728 :
1729 :
1730 :
1731 :
1732 :
1733 :
1734 : // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1735 :
1736 : module el2_exu_div_cls
1737 : (
1738 140682 : input logic [32:0] operand,
1739 :
1740 98207 : output logic [4:0] cls // Count leading sign bits - "n" format ignoring [32]
1741 : );
1742 :
1743 :
1744 120195 : logic [4:0] cls_zeros;
1745 74409 : logic [4:0] cls_ones;
1746 :
1747 :
1748 : assign cls_zeros[4:0] = ({5{operand[31] == { 1'b1} }} & 5'd00) |
1749 : ({5{operand[31:30] == {{ 1{1'b0}},1'b1} }} & 5'd01) |
1750 : ({5{operand[31:29] == {{ 2{1'b0}},1'b1} }} & 5'd02) |
1751 : ({5{operand[31:28] == {{ 3{1'b0}},1'b1} }} & 5'd03) |
1752 : ({5{operand[31:27] == {{ 4{1'b0}},1'b1} }} & 5'd04) |
1753 : ({5{operand[31:26] == {{ 5{1'b0}},1'b1} }} & 5'd05) |
1754 : ({5{operand[31:25] == {{ 6{1'b0}},1'b1} }} & 5'd06) |
1755 : ({5{operand[31:24] == {{ 7{1'b0}},1'b1} }} & 5'd07) |
1756 : ({5{operand[31:23] == {{ 8{1'b0}},1'b1} }} & 5'd08) |
1757 : ({5{operand[31:22] == {{ 9{1'b0}},1'b1} }} & 5'd09) |
1758 : ({5{operand[31:21] == {{10{1'b0}},1'b1} }} & 5'd10) |
1759 : ({5{operand[31:20] == {{11{1'b0}},1'b1} }} & 5'd11) |
1760 : ({5{operand[31:19] == {{12{1'b0}},1'b1} }} & 5'd12) |
1761 : ({5{operand[31:18] == {{13{1'b0}},1'b1} }} & 5'd13) |
1762 : ({5{operand[31:17] == {{14{1'b0}},1'b1} }} & 5'd14) |
1763 : ({5{operand[31:16] == {{15{1'b0}},1'b1} }} & 5'd15) |
1764 : ({5{operand[31:15] == {{16{1'b0}},1'b1} }} & 5'd16) |
1765 : ({5{operand[31:14] == {{17{1'b0}},1'b1} }} & 5'd17) |
1766 : ({5{operand[31:13] == {{18{1'b0}},1'b1} }} & 5'd18) |
1767 : ({5{operand[31:12] == {{19{1'b0}},1'b1} }} & 5'd19) |
1768 : ({5{operand[31:11] == {{20{1'b0}},1'b1} }} & 5'd20) |
1769 : ({5{operand[31:10] == {{21{1'b0}},1'b1} }} & 5'd21) |
1770 : ({5{operand[31:09] == {{22{1'b0}},1'b1} }} & 5'd22) |
1771 : ({5{operand[31:08] == {{23{1'b0}},1'b1} }} & 5'd23) |
1772 : ({5{operand[31:07] == {{24{1'b0}},1'b1} }} & 5'd24) |
1773 : ({5{operand[31:06] == {{25{1'b0}},1'b1} }} & 5'd25) |
1774 : ({5{operand[31:05] == {{26{1'b0}},1'b1} }} & 5'd26) |
1775 : ({5{operand[31:04] == {{27{1'b0}},1'b1} }} & 5'd27) |
1776 : ({5{operand[31:03] == {{28{1'b0}},1'b1} }} & 5'd28) |
1777 : ({5{operand[31:02] == {{29{1'b0}},1'b1} }} & 5'd29) |
1778 : ({5{operand[31:01] == {{30{1'b0}},1'b1} }} & 5'd30) |
1779 : ({5{operand[31:00] == {{31{1'b0}},1'b1} }} & 5'd31) |
1780 : ({5{operand[31:00] == {{32{1'b0}} } }} & 5'd00); // Don't care case as it will be handled as special case
1781 :
1782 :
1783 : assign cls_ones[4:0] = ({5{operand[31:30] == {{ 1{1'b1}},1'b0} }} & 5'd00) |
1784 : ({5{operand[31:29] == {{ 2{1'b1}},1'b0} }} & 5'd01) |
1785 : ({5{operand[31:28] == {{ 3{1'b1}},1'b0} }} & 5'd02) |
1786 : ({5{operand[31:27] == {{ 4{1'b1}},1'b0} }} & 5'd03) |
1787 : ({5{operand[31:26] == {{ 5{1'b1}},1'b0} }} & 5'd04) |
1788 : ({5{operand[31:25] == {{ 6{1'b1}},1'b0} }} & 5'd05) |
1789 : ({5{operand[31:24] == {{ 7{1'b1}},1'b0} }} & 5'd06) |
1790 : ({5{operand[31:23] == {{ 8{1'b1}},1'b0} }} & 5'd07) |
1791 : ({5{operand[31:22] == {{ 9{1'b1}},1'b0} }} & 5'd08) |
1792 : ({5{operand[31:21] == {{10{1'b1}},1'b0} }} & 5'd09) |
1793 : ({5{operand[31:20] == {{11{1'b1}},1'b0} }} & 5'd10) |
1794 : ({5{operand[31:19] == {{12{1'b1}},1'b0} }} & 5'd11) |
1795 : ({5{operand[31:18] == {{13{1'b1}},1'b0} }} & 5'd12) |
1796 : ({5{operand[31:17] == {{14{1'b1}},1'b0} }} & 5'd13) |
1797 : ({5{operand[31:16] == {{15{1'b1}},1'b0} }} & 5'd14) |
1798 : ({5{operand[31:15] == {{16{1'b1}},1'b0} }} & 5'd15) |
1799 : ({5{operand[31:14] == {{17{1'b1}},1'b0} }} & 5'd16) |
1800 : ({5{operand[31:13] == {{18{1'b1}},1'b0} }} & 5'd17) |
1801 : ({5{operand[31:12] == {{19{1'b1}},1'b0} }} & 5'd18) |
1802 : ({5{operand[31:11] == {{20{1'b1}},1'b0} }} & 5'd19) |
1803 : ({5{operand[31:10] == {{21{1'b1}},1'b0} }} & 5'd20) |
1804 : ({5{operand[31:09] == {{22{1'b1}},1'b0} }} & 5'd21) |
1805 : ({5{operand[31:08] == {{23{1'b1}},1'b0} }} & 5'd22) |
1806 : ({5{operand[31:07] == {{24{1'b1}},1'b0} }} & 5'd23) |
1807 : ({5{operand[31:06] == {{25{1'b1}},1'b0} }} & 5'd24) |
1808 : ({5{operand[31:05] == {{26{1'b1}},1'b0} }} & 5'd25) |
1809 : ({5{operand[31:04] == {{27{1'b1}},1'b0} }} & 5'd26) |
1810 : ({5{operand[31:03] == {{28{1'b1}},1'b0} }} & 5'd27) |
1811 : ({5{operand[31:02] == {{29{1'b1}},1'b0} }} & 5'd28) |
1812 : ({5{operand[31:01] == {{30{1'b1}},1'b0} }} & 5'd29) |
1813 : ({5{operand[31:00] == {{31{1'b1}},1'b0} }} & 5'd30) |
1814 : ({5{operand[31:00] == {{32{1'b1}} } }} & 5'd31);
1815 :
1816 :
1817 : assign cls[4:0] = operand[32] ? cls_ones[4:0] : cls_zeros[4:0];
1818 :
1819 : endmodule // el2_exu_div_cls
|