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