1 | // ========== Copyright Header Begin ========================================== |
---|
2 | // |
---|
3 | // OpenSPARC T1 Processor File: spu_mared.v |
---|
4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
---|
5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
---|
6 | // |
---|
7 | // The above named program is free software; you can redistribute it and/or |
---|
8 | // modify it under the terms of the GNU General Public |
---|
9 | // License version 2 as published by the Free Software Foundation. |
---|
10 | // |
---|
11 | // The above named program is distributed in the hope that it will be |
---|
12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
14 | // General Public License for more details. |
---|
15 | // |
---|
16 | // You should have received a copy of the GNU General Public |
---|
17 | // License along with this work; if not, write to the Free Software |
---|
18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
19 | // |
---|
20 | // ========== Copyright Header End ============================================ |
---|
21 | //////////////////////////////////////////////////////////////////////// |
---|
22 | /* |
---|
23 | // Description: state machine to do MA reduction. |
---|
24 | */ |
---|
25 | //////////////////////////////////////////////////////////////////////// |
---|
26 | |
---|
27 | module spu_mared ( |
---|
28 | |
---|
29 | /*outputs*/ |
---|
30 | spu_mared_data_sel_l, |
---|
31 | spu_mared_j_ptr_sel, |
---|
32 | spu_mared_nm_rd_oprnd_sel, |
---|
33 | spu_mared_m_rd_oprnd_sel, |
---|
34 | spu_mared_me_rd_oprnd_sel, |
---|
35 | spu_mared_x_wr_oprnd_sel, |
---|
36 | spu_mared_xe_wr_oprnd_sel, |
---|
37 | spu_mared_nr_rd_oprnd_sel, |
---|
38 | spu_mared_a_rd_oprnd_sel, |
---|
39 | spu_mared_r_wr_oprnd_sel, |
---|
40 | spu_mared_update_jptr, |
---|
41 | spu_mared_rst_jptr, |
---|
42 | spu_mared_maxlen_wen, |
---|
43 | spu_mared_rdn_wen, |
---|
44 | spu_mared_oprnd2_wen, |
---|
45 | |
---|
46 | spu_mared_memren, |
---|
47 | spu_mared_memwen, |
---|
48 | |
---|
49 | spu_mared_cin_set_4sub, |
---|
50 | spu_mared_cin_oprnd_sub_mod, |
---|
51 | |
---|
52 | spu_mared_done_set, |
---|
53 | spu_mared_start_wen, |
---|
54 | spu_mared_start_sel, |
---|
55 | |
---|
56 | spu_mared_red_done, |
---|
57 | |
---|
58 | spu_mared_update_redwr_jptr, |
---|
59 | spu_mared_jjptr_wen, |
---|
60 | |
---|
61 | spu_mared_not_idle, |
---|
62 | |
---|
63 | /*inputs*/ |
---|
64 | mul_data_out_0, |
---|
65 | spu_madp_m_eq_n, |
---|
66 | spu_madp_m_lt_n, |
---|
67 | |
---|
68 | spu_mactl_expop, |
---|
69 | spu_mactl_mulop, |
---|
70 | spu_mactl_redop, |
---|
71 | spu_mamul_mul_done, |
---|
72 | spu_mactl_iss_pulse_dly, |
---|
73 | |
---|
74 | spu_maaddr_jptr_eqz, |
---|
75 | spu_maaddr_len_eqmax, |
---|
76 | |
---|
77 | spu_mast_stbuf_wen, |
---|
78 | spu_madp_cout_oprnd_sub_mod, |
---|
79 | |
---|
80 | spu_mactl_kill_op, |
---|
81 | |
---|
82 | spu_mactl_stxa_force_abort, |
---|
83 | |
---|
84 | se, |
---|
85 | reset, |
---|
86 | rclk); |
---|
87 | |
---|
88 | // ------------------------------------------------------------------------- |
---|
89 | input reset; |
---|
90 | input rclk; |
---|
91 | input se; |
---|
92 | |
---|
93 | input mul_data_out_0; |
---|
94 | |
---|
95 | input spu_madp_m_eq_n; |
---|
96 | input spu_madp_m_lt_n; |
---|
97 | |
---|
98 | input spu_mactl_expop; |
---|
99 | input spu_mactl_mulop; |
---|
100 | input spu_mactl_redop; |
---|
101 | input spu_mamul_mul_done; |
---|
102 | input spu_mactl_iss_pulse_dly; |
---|
103 | |
---|
104 | input spu_maaddr_jptr_eqz; |
---|
105 | input spu_maaddr_len_eqmax; |
---|
106 | |
---|
107 | input spu_mast_stbuf_wen; |
---|
108 | input spu_madp_cout_oprnd_sub_mod; |
---|
109 | |
---|
110 | input spu_mactl_kill_op; |
---|
111 | |
---|
112 | input spu_mactl_stxa_force_abort; |
---|
113 | |
---|
114 | // ------------------------------------------------------------------------- |
---|
115 | |
---|
116 | output [3:0] spu_mared_data_sel_l; |
---|
117 | output spu_mared_j_ptr_sel; |
---|
118 | output spu_mared_nm_rd_oprnd_sel; |
---|
119 | output spu_mared_m_rd_oprnd_sel; |
---|
120 | output spu_mared_me_rd_oprnd_sel; |
---|
121 | output spu_mared_x_wr_oprnd_sel; |
---|
122 | output spu_mared_xe_wr_oprnd_sel; |
---|
123 | output spu_mared_nr_rd_oprnd_sel; |
---|
124 | output spu_mared_a_rd_oprnd_sel; |
---|
125 | output spu_mared_r_wr_oprnd_sel; |
---|
126 | output spu_mared_update_jptr; |
---|
127 | output spu_mared_rst_jptr; |
---|
128 | output spu_mared_maxlen_wen; |
---|
129 | output spu_mared_rdn_wen; |
---|
130 | output spu_mared_oprnd2_wen; |
---|
131 | |
---|
132 | output spu_mared_memren; |
---|
133 | output spu_mared_memwen; |
---|
134 | |
---|
135 | output spu_mared_cin_set_4sub; |
---|
136 | output spu_mared_cin_oprnd_sub_mod; |
---|
137 | |
---|
138 | output spu_mared_done_set; |
---|
139 | output spu_mared_start_wen; |
---|
140 | output spu_mared_start_sel; |
---|
141 | output spu_mared_red_done; |
---|
142 | output spu_mared_update_redwr_jptr; |
---|
143 | output spu_mared_jjptr_wen; |
---|
144 | output spu_mared_not_idle; |
---|
145 | |
---|
146 | // ------------------------------------------------------------------------- |
---|
147 | // ------------------------------------------------------------------------- |
---|
148 | |
---|
149 | wire m_gt_n_rst; |
---|
150 | wire spu_mared_red_done; |
---|
151 | wire m_gt_n_set,m_lt_n_rst,m_lt_n_set; |
---|
152 | wire start_op; |
---|
153 | wire tr2idle_frm_wr0tox,tr2idle_frm_wrmtox,tr2idle_frm_wrstox; |
---|
154 | wire tr2rdm_frm_wr0tox,tr2rdm_frm_saveptrs,dly_saveptrs_state, |
---|
155 | tr2rdm_frm_wrstox,tr2rdm_frm_wrmtox; |
---|
156 | |
---|
157 | wire start_mtox_from_msw; |
---|
158 | |
---|
159 | wire local_stxa_abort; |
---|
160 | wire cur_rdm_state; |
---|
161 | // ------------------------------------------------------------------------- |
---|
162 | // ------------------------------------------------------------------------- |
---|
163 | // ------------------------------------------------------------------------- |
---|
164 | wire state_reset = reset | spu_mared_red_done | spu_mactl_kill_op | |
---|
165 | local_stxa_abort; |
---|
166 | // ------------------------------------------------------------------------- |
---|
167 | // ------------------------------------------------------------------------- |
---|
168 | // ------------------------------------------------------------------------- |
---|
169 | // ------------------------------------------------------------------------- |
---|
170 | // ------------------------------------------------------------------------- |
---|
171 | // we need a state set to indcate mulred/red is done, and when an |
---|
172 | // masync gets issued later, then the load asi is returned. |
---|
173 | // ********* ONLY FOR mul_op & red_op NOT exp_op. |
---|
174 | wire spu_mared_done_wen = (spu_mared_red_done | spu_mactl_kill_op | local_stxa_abort) & |
---|
175 | (spu_mactl_mulop | spu_mactl_redop); |
---|
176 | wire spu_mared_done_rst = reset | spu_mactl_iss_pulse_dly; |
---|
177 | |
---|
178 | dffre_s #(1) spu_mared_done_ff ( |
---|
179 | .din(1'b1) , |
---|
180 | .q(spu_mared_done_set), |
---|
181 | .en(spu_mared_done_wen), |
---|
182 | .rst(spu_mared_done_rst), .clk (rclk) |
---|
183 | , .se(se), .si(), .so()); |
---|
184 | |
---|
185 | // ------------------------------------------------------------------------- |
---|
186 | // ------------------------------------------------------------------------- |
---|
187 | // ------------------------------------------------------------------------- |
---|
188 | // ------------------------------------------------------------------------- |
---|
189 | // ------------------------------------------------------------------------- |
---|
190 | |
---|
191 | dff_s #(1) idle_state_ff ( |
---|
192 | .din(nxt_idle_state) , |
---|
193 | .q(cur_idle_state), |
---|
194 | .clk (rclk) |
---|
195 | , .se(se), .si(), .so()); |
---|
196 | |
---|
197 | dffr_s #(1) rdm_state_ff ( |
---|
198 | .din(nxt_rdm_state) , |
---|
199 | .q(cur_rdm_state), |
---|
200 | .rst(state_reset), .clk (rclk) |
---|
201 | , .se(se), .si(), .so()); |
---|
202 | |
---|
203 | assign local_stxa_abort = cur_rdm_state & spu_mactl_stxa_force_abort; |
---|
204 | |
---|
205 | // the delay is for the loop which is rdm,wrmtox to |
---|
206 | //match the cycles for other read/write loops |
---|
207 | dffr_s #(1) rdmdly_state_ff ( |
---|
208 | .din(nxt_rdmdly_state) , |
---|
209 | .q(cur_rdmdly_state), |
---|
210 | .rst(state_reset), .clk (rclk) |
---|
211 | , .se(se), .si(), .so()); |
---|
212 | |
---|
213 | dffr_s #(1) rdn_state_ff ( |
---|
214 | .din(nxt_rdn_state) , |
---|
215 | .q(cur_rdn_state), |
---|
216 | .rst(state_reset), .clk (rclk) |
---|
217 | , .se(se), .si(), .so()); |
---|
218 | |
---|
219 | dffr_s #(1) cmpsub_state_ff ( |
---|
220 | .din(nxt_cmpsub_state) , |
---|
221 | .q(cur_cmpsub_state), |
---|
222 | .rst(state_reset), .clk (rclk) |
---|
223 | , .se(se), .si(), .so()); |
---|
224 | |
---|
225 | dffr_s #(1) wr0tox_state_ff ( |
---|
226 | .din(nxt_wr0tox_state) , |
---|
227 | .q(cur_wr0tox_state), |
---|
228 | .rst(state_reset), .clk (rclk) |
---|
229 | , .se(se), .si(), .so()); |
---|
230 | |
---|
231 | dffr_s #(1) wrmtox_state_ff ( |
---|
232 | .din(nxt_wrmtox_state) , |
---|
233 | .q(cur_wrmtox_state), |
---|
234 | .rst(state_reset), .clk (rclk) |
---|
235 | , .se(se), .si(), .so()); |
---|
236 | |
---|
237 | // s = m-n |
---|
238 | dffr_s #(1) wrstox_state_ff ( |
---|
239 | .din(nxt_wrstox_state) , |
---|
240 | .q(cur_wrstox_state), |
---|
241 | .rst(state_reset), .clk (rclk) |
---|
242 | , .se(se), .si(), .so()); |
---|
243 | |
---|
244 | dffr_s #(1) saveptrs_state_ff ( |
---|
245 | .din(nxt_saveptrs_state) , |
---|
246 | .q(cur_saveptrs_state), |
---|
247 | .rst(state_reset), .clk (rclk) |
---|
248 | , .se(se), .si(), .so()); |
---|
249 | |
---|
250 | dffr_s #(1) submn_state_ff ( |
---|
251 | .din(nxt_submn_state) , |
---|
252 | .q(cur_submn_state), |
---|
253 | .rst(state_reset), .clk (rclk) |
---|
254 | , .se(se), .si(), .so()); |
---|
255 | // ------------------------------------------------------------------------- |
---|
256 | // ------------------------------------------------------------------------- |
---|
257 | wire m_gt_n_q,m_lt_n_q; |
---|
258 | |
---|
259 | wire spu_mared_m_eq_n = spu_madp_m_eq_n & ~(m_lt_n_q | m_gt_n_q); |
---|
260 | //assign spu_mared_m_gt_n = ~(spu_madp_m_eq_n | spu_madp_m_lt_n | m_lt_n_q); |
---|
261 | wire spu_mared_m_lt_n = ~(spu_madp_m_eq_n | m_gt_n_q) & spu_madp_m_lt_n; |
---|
262 | |
---|
263 | // ------------------------------------------------------------------------- |
---|
264 | // ------------------------------------------------------------------------- |
---|
265 | wire mamulred_op_rst = state_reset; |
---|
266 | |
---|
267 | wire spu_mamul_mul_done_qual = spu_mamul_mul_done & ~spu_mactl_kill_op; |
---|
268 | |
---|
269 | wire mamulred_op_set = (spu_mactl_mulop | spu_mactl_expop) & spu_mamul_mul_done_qual; |
---|
270 | wire mulred_start = mamulred_op_set; |
---|
271 | |
---|
272 | dffre_s #(1) mamulred_op_ff ( |
---|
273 | .din(1'b1) , |
---|
274 | .q(mamulred_op_q), |
---|
275 | .en(mamulred_op_set), |
---|
276 | .rst(mamulred_op_rst), .clk (rclk) |
---|
277 | , .se(se), .si(), .so()); |
---|
278 | |
---|
279 | // ------------------------------------------------------------------------- |
---|
280 | // ------------------------------------------------------------------------- |
---|
281 | |
---|
282 | assign m_gt_n_rst = state_reset; |
---|
283 | |
---|
284 | assign m_gt_n_set = ((spu_mactl_mulop | spu_mactl_expop) & mul_data_out_0 & spu_mamul_mul_done_qual) | |
---|
285 | (cur_saveptrs_state & ~m_lt_n_q); |
---|
286 | |
---|
287 | dffre_s #(1) m_gt_n_ff ( |
---|
288 | .din(1'b1) , |
---|
289 | .q(m_gt_n_q), |
---|
290 | .en(m_gt_n_set), |
---|
291 | .rst(m_gt_n_rst), .clk (rclk) |
---|
292 | , .se(se), .si(), .so()); |
---|
293 | |
---|
294 | // ------------------------------------------------------------------------- |
---|
295 | assign m_lt_n_rst = state_reset; |
---|
296 | assign m_lt_n_set = cur_cmpsub_state & spu_mared_m_lt_n; |
---|
297 | |
---|
298 | dffre_s #(1) m_lt_n_ff ( |
---|
299 | .din(1'b1) , |
---|
300 | .q(m_lt_n_q), |
---|
301 | .en(m_lt_n_set), |
---|
302 | .rst(m_lt_n_rst), .clk (rclk) |
---|
303 | , .se(se), .si(), .so()); |
---|
304 | |
---|
305 | // ------------------------------------------------------------------------- |
---|
306 | // ------------------------------------------------------------------------- |
---|
307 | // transition to idle state |
---|
308 | |
---|
309 | // this dley is so that m_gt_n_q is updated by the time we start. as |
---|
310 | // this is one of the conditions to come out of idle state. |
---|
311 | wire mulred_start_q; |
---|
312 | dff_s #(1) dly_start_mulred_ff ( |
---|
313 | .din(mulred_start) , |
---|
314 | .q(mulred_start_q), |
---|
315 | .clk (rclk) |
---|
316 | , .se(se), .si(), .so()); |
---|
317 | |
---|
318 | |
---|
319 | // delaying mared_start so we can save len ptr to jptr before |
---|
320 | // starting. |
---|
321 | wire mared_start_p1 = spu_mactl_redop & spu_mactl_iss_pulse_dly; |
---|
322 | |
---|
323 | wire mared_start_p1_q,mared_start_q; |
---|
324 | dff_s #(2) dly_start_red_ff ( |
---|
325 | .din({mared_start_p1,mared_start_p1_q}) , |
---|
326 | .q({mared_start_p1_q,mared_start_q}), |
---|
327 | .clk (rclk) |
---|
328 | , .se(se), .si(), .so()); |
---|
329 | |
---|
330 | assign spu_mared_start_wen = mared_start_p1_q | start_mtox_from_msw | spu_mamul_mul_done_qual; |
---|
331 | assign spu_mared_start_sel = mared_start_p1_q | start_mtox_from_msw | spu_mamul_mul_done; |
---|
332 | |
---|
333 | assign start_op = mulred_start_q | mared_start_q; |
---|
334 | |
---|
335 | |
---|
336 | assign tr2idle_frm_wr0tox = cur_wr0tox_state & spu_maaddr_jptr_eqz; |
---|
337 | assign tr2idle_frm_wrmtox = cur_wrmtox_state & spu_maaddr_jptr_eqz; |
---|
338 | assign tr2idle_frm_wrstox = cur_wrstox_state & spu_maaddr_len_eqmax; |
---|
339 | |
---|
340 | wire spu_mared_red_done_pre = tr2idle_frm_wr0tox | tr2idle_frm_wrmtox | |
---|
341 | tr2idle_frm_wrstox; |
---|
342 | |
---|
343 | dffr_s #(2) spu_mared_red_done_ff ( |
---|
344 | .din({spu_mared_red_done_pre,spu_mared_red_done_dly1}) , |
---|
345 | .q({spu_mared_red_done_dly1,spu_mared_red_done_dly2}), |
---|
346 | .rst(state_reset), .clk (rclk) |
---|
347 | , .se(se), .si(), .so()); |
---|
348 | |
---|
349 | assign spu_mared_red_done = spu_mared_red_done_dly2 | local_stxa_abort; |
---|
350 | |
---|
351 | // -------------------------- |
---|
352 | |
---|
353 | assign spu_mared_not_idle = ~cur_idle_state; |
---|
354 | |
---|
355 | |
---|
356 | assign nxt_idle_state = ( |
---|
357 | state_reset | spu_mared_red_done | |
---|
358 | (cur_idle_state & ~start_op)); |
---|
359 | |
---|
360 | |
---|
361 | // ------------------------------------------------------------------------- |
---|
362 | // transition to rdm state |
---|
363 | |
---|
364 | wire twodly_saveptrs_state; |
---|
365 | |
---|
366 | assign tr2rdm_frm_wr0tox = cur_wr0tox_state & ~spu_maaddr_jptr_eqz; |
---|
367 | assign tr2rdm_frm_saveptrs = twodly_saveptrs_state & ~cur_idle_state; |
---|
368 | assign tr2rdm_frm_wrstox = cur_wrstox_state & ~spu_maaddr_len_eqmax; |
---|
369 | assign tr2rdm_frm_wrmtox = cur_wrmtox_state & m_lt_n_q & ~spu_maaddr_jptr_eqz; |
---|
370 | |
---|
371 | assign nxt_rdm_state = ( |
---|
372 | tr2rdm_frm_wrmtox | |
---|
373 | tr2rdm_frm_wr0tox | tr2rdm_frm_saveptrs | |
---|
374 | tr2rdm_frm_wrstox | |
---|
375 | (cur_idle_state & start_op & ~(m_lt_n_q|m_gt_n_q))); |
---|
376 | //(cur_idle_state & start_op & ~m_lt_n_q)); |
---|
377 | |
---|
378 | // this goes to spu_mamul to get ored with the logic there before |
---|
379 | // sending to spu_madp. |
---|
380 | assign spu_mared_oprnd2_wen = cur_rdm_state; |
---|
381 | |
---|
382 | |
---|
383 | // ------------------------------------------------------------------------- |
---|
384 | // transition to rdmdly state |
---|
385 | |
---|
386 | assign nxt_rdmdly_state = ( |
---|
387 | (cur_rdm_state & m_lt_n_q) ); |
---|
388 | |
---|
389 | // ------------------------------------------------------------------------- |
---|
390 | // transition to rdn state |
---|
391 | |
---|
392 | |
---|
393 | assign nxt_rdn_state = ( |
---|
394 | (cur_rdm_state & ~m_lt_n_q)); |
---|
395 | |
---|
396 | // the following is for capturing the N data into flop |
---|
397 | // used for subtract & compare. |
---|
398 | assign spu_mared_rdn_wen = cur_rdn_state | spu_mast_stbuf_wen; |
---|
399 | |
---|
400 | // ------------------------------------------------------------------------- |
---|
401 | // transition to cmpsub state |
---|
402 | |
---|
403 | assign nxt_cmpsub_state = ( |
---|
404 | (cur_rdn_state & ~(m_lt_n_q | m_gt_n_q))); |
---|
405 | |
---|
406 | // ------------------------------------------------------------------------- |
---|
407 | // transition to wr0tox state |
---|
408 | |
---|
409 | assign nxt_wr0tox_state = ( |
---|
410 | (cur_cmpsub_state & spu_mared_m_eq_n)); |
---|
411 | |
---|
412 | // ------------------------------------------------------------------------- |
---|
413 | // transition to wrmtox state |
---|
414 | |
---|
415 | assign nxt_wrmtox_state = ( |
---|
416 | (cur_rdmdly_state) ); |
---|
417 | |
---|
418 | // ------------------------------------------------------------------------- |
---|
419 | // transition to wrstox state |
---|
420 | |
---|
421 | assign nxt_wrstox_state = ( |
---|
422 | (cur_submn_state)); |
---|
423 | |
---|
424 | // ------------------------------------------------------------------------- |
---|
425 | // transition to saveptrs state |
---|
426 | |
---|
427 | assign nxt_saveptrs_state = ( |
---|
428 | (cur_idle_state & start_op & m_gt_n_q) | |
---|
429 | (cur_cmpsub_state & ~spu_mared_m_eq_n)); |
---|
430 | /* |
---|
431 | (cur_cmpsub_state & spu_mared_m_gt_n) | |
---|
432 | (cur_cmpsub_state & spu_mared_m_lt_n)); |
---|
433 | */ |
---|
434 | |
---|
435 | |
---|
436 | dffr_s #(1) dly_saveptrs_ff ( |
---|
437 | .din(cur_saveptrs_state) , |
---|
438 | .q(dly_saveptrs_state), |
---|
439 | .clk (rclk), |
---|
440 | .rst(state_reset), .se(se), .si(), .so()); |
---|
441 | |
---|
442 | // the delay is needed so we can save the pointer before |
---|
443 | // reseting it. |
---|
444 | assign spu_mared_maxlen_wen = cur_saveptrs_state & ~m_lt_n_q; |
---|
445 | assign spu_mared_rst_jptr = dly_saveptrs_state & ~m_lt_n_q; |
---|
446 | |
---|
447 | assign start_mtox_from_msw = cur_saveptrs_state & m_lt_n_q; |
---|
448 | |
---|
449 | // need to delay this an extra cycle to trigger nxt_rdm_state, so |
---|
450 | // the len_eqmax has correct value by then. |
---|
451 | dffr_s #(1) twodly_saveptrs_ff ( |
---|
452 | .din(dly_saveptrs_state) , |
---|
453 | .q(twodly_saveptrs_state), |
---|
454 | .clk (rclk), |
---|
455 | .rst(state_reset), .se(se), .si(), .so()); |
---|
456 | |
---|
457 | // ------------------------------------------------------------------------- |
---|
458 | // transition to submn state |
---|
459 | |
---|
460 | assign nxt_submn_state = ( |
---|
461 | (cur_rdn_state & m_gt_n_q)); |
---|
462 | |
---|
463 | // ------------------------------------------------------------------------- |
---|
464 | // ------------------------------------------------------------------------- |
---|
465 | // ------------------------------------------------------------------------- |
---|
466 | // ------------------------------------------------------------------------- |
---|
467 | /* |
---|
468 | assign spu_mared_incr_jptr = nxt_wr0tox_state | nxt_wrmtox_state | |
---|
469 | nxt_wstox_state; |
---|
470 | */ |
---|
471 | |
---|
472 | // the follwoing is to mux the updated jjptr from a temp |
---|
473 | // flop for the transition to rdm state and then the mux selects |
---|
474 | // the jptr updated value for rdn and wr. |
---|
475 | assign spu_mared_update_jptr = tr2rdm_frm_wr0tox | tr2rdm_frm_wrmtox | |
---|
476 | tr2rdm_frm_wrstox; |
---|
477 | |
---|
478 | // ------------------------------------------------------------------------- |
---|
479 | // ------------------------------------------------------------------------- |
---|
480 | // ------------------------------------------------------------------------- |
---|
481 | |
---|
482 | |
---|
483 | // added spu_mactl_stxa_force_abort to the following since ren causes perr_set with x's. |
---|
484 | assign spu_mared_memren = (nxt_rdm_state | nxt_rdn_state) & ~spu_mactl_stxa_force_abort; |
---|
485 | |
---|
486 | // --------------------- |
---|
487 | assign spu_mared_jjptr_wen = nxt_wr0tox_state | nxt_wrmtox_state | |
---|
488 | nxt_wrstox_state; |
---|
489 | |
---|
490 | dff_s #(3) nxt_wr0tox_state_ff( |
---|
491 | .din({nxt_wr0tox_state,nxt_wr0tox_state_dly1,nxt_wr0tox_state_dly2}) , |
---|
492 | .q({nxt_wr0tox_state_dly1,nxt_wr0tox_state_dly2,nxt_wr0tox_state_dly3}), |
---|
493 | .clk (rclk) |
---|
494 | , .se(se), .si(), .so()); |
---|
495 | |
---|
496 | dff_s #(3) nxt_wrstox_state_ff( |
---|
497 | .din({nxt_wrstox_state,nxt_wrstox_state_dly1,nxt_wrstox_state_dly2}) , |
---|
498 | .q({nxt_wrstox_state_dly1,nxt_wrstox_state_dly2,nxt_wrstox_state_dly3}), |
---|
499 | .clk (rclk) |
---|
500 | , .se(se), .si(), .so()); |
---|
501 | |
---|
502 | |
---|
503 | dff_s #(2) nxt_wrmtox_state_ff( |
---|
504 | .din({nxt_wrmtox_state,nxt_wrmtox_state_dly1}) , |
---|
505 | .q({nxt_wrmtox_state_dly1,nxt_wrmtox_state_dly2}), |
---|
506 | .clk (rclk) |
---|
507 | , .se(se), .si(), .so()); |
---|
508 | |
---|
509 | assign spu_mared_memwen = nxt_wr0tox_state_dly3 | nxt_wrmtox_state_dly2 | |
---|
510 | nxt_wrstox_state_dly3; |
---|
511 | // ----------------------- |
---|
512 | |
---|
513 | dff_s #(2) spu_mared_start_wen_ff( |
---|
514 | .din({spu_mared_start_wen,spu_mared_start_wen_dly}) , |
---|
515 | .q({spu_mared_start_wen_dly,spu_mared_start_wen_dly2}), |
---|
516 | .clk (rclk) |
---|
517 | , .se(se), .si(), .so()); |
---|
518 | |
---|
519 | dff_s #(2) spu_mared_rst_jptr_ff( |
---|
520 | .din({spu_mared_rst_jptr,spu_mared_rst_jptr_dly}) , |
---|
521 | .q({spu_mared_rst_jptr_dly,spu_mared_rst_jptr_dly2}), |
---|
522 | .clk (rclk) |
---|
523 | , .se(se), .si(), .so()); |
---|
524 | |
---|
525 | dff_s #(1) spu_mared_memwen_ff ( |
---|
526 | .din(spu_mared_memwen) , |
---|
527 | .q(spu_mared_memwen_dly), |
---|
528 | .clk (rclk) |
---|
529 | , .se(se), .si(), .so()); |
---|
530 | |
---|
531 | assign spu_mared_update_redwr_jptr = spu_mared_rst_jptr_dly2 | spu_mared_start_wen_dly2 | |
---|
532 | spu_mared_memwen_dly; |
---|
533 | |
---|
534 | // ------------------------------------------------------------------------- |
---|
535 | // ------------------------------------------------------------------------- |
---|
536 | // ------------------------------------------------------------------------- |
---|
537 | /* |
---|
538 | assign spu_mared_m_rd_oprnd_sel = nxt_rdm_state & (mamulred_op_q | mamulred_op_set); |
---|
539 | assign spu_mared_nm_rd_oprnd_sel = nxt_rdn_state & (mamulred_op_q | mamulred_op_set); |
---|
540 | assign spu_mared_x_wr_oprnd_sel = spu_mared_memwen & mamulred_op_q; |
---|
541 | */ |
---|
542 | |
---|
543 | assign spu_mared_m_rd_oprnd_sel = nxt_rdm_state & spu_mactl_mulop; |
---|
544 | assign spu_mared_nm_rd_oprnd_sel = nxt_rdn_state & (spu_mactl_mulop | spu_mactl_expop); |
---|
545 | assign spu_mared_x_wr_oprnd_sel = spu_mared_memwen & spu_mactl_mulop; |
---|
546 | |
---|
547 | assign spu_mared_me_rd_oprnd_sel = nxt_rdm_state & spu_mactl_expop; |
---|
548 | assign spu_mared_xe_wr_oprnd_sel = spu_mared_memwen & spu_mactl_expop; |
---|
549 | |
---|
550 | assign spu_mared_a_rd_oprnd_sel = nxt_rdm_state & spu_mactl_redop; |
---|
551 | assign spu_mared_nr_rd_oprnd_sel = nxt_rdn_state & spu_mactl_redop; |
---|
552 | assign spu_mared_r_wr_oprnd_sel = spu_mared_memwen & spu_mactl_redop; |
---|
553 | |
---|
554 | //assign spu_mared_j_ptr_sel = spu_mared_memren | spu_mared_memwen; |
---|
555 | assign spu_mared_j_ptr_sel = spu_mared_memren ; |
---|
556 | |
---|
557 | // ------------------------------------------------------------------------- |
---|
558 | // the following selects go to spu_madp. |
---|
559 | wire [3:0] spu_mared_data_sel; |
---|
560 | assign spu_mared_data_sel[0] = ~(mamulred_op_q | spu_mactl_redop); |
---|
561 | //assign spu_mared_data_sel[1] = (mamulred_op_q | spu_mactl_redop) & spu_mared_m_eq_n; |
---|
562 | assign spu_mared_data_sel[1] = (mamulred_op_q | spu_mactl_redop) & ~m_lt_n_q & ~m_gt_n_q; |
---|
563 | assign spu_mared_data_sel[2] = (mamulred_op_q | spu_mactl_redop) & m_lt_n_q & ~m_gt_n_q; |
---|
564 | assign spu_mared_data_sel[3] = (mamulred_op_q | spu_mactl_redop) & m_gt_n_q; |
---|
565 | |
---|
566 | assign spu_mared_data_sel_l[3:0] = ~spu_mared_data_sel[3:0]; |
---|
567 | // ------------------------------------------------------------------------- |
---|
568 | |
---|
569 | assign spu_mared_cin_set_4sub = spu_mared_data_sel[2] | spu_mared_data_sel[1]; |
---|
570 | |
---|
571 | // ------------------------------------------------------------------------- |
---|
572 | |
---|
573 | // except for the first word subtract(starting at jptr=0), use borrow from the |
---|
574 | // previous stage as cin for the next stage. |
---|
575 | wire sel_cout_frm_prev_stage = (~spu_maaddr_jptr_eqz & m_gt_n_q) & ~start_op; |
---|
576 | |
---|
577 | wire spu_mared_cin_oprnd_sub_mod_pre; |
---|
578 | mux3ds #(1) cin_sel_mux ( |
---|
579 | .in0 (1'b0), |
---|
580 | .in1 (1'b1), |
---|
581 | .in2 (spu_madp_cout_oprnd_sub_mod), |
---|
582 | .sel0 (1'b0), |
---|
583 | .sel1 (~sel_cout_frm_prev_stage), |
---|
584 | .sel2 (sel_cout_frm_prev_stage), |
---|
585 | .dout (spu_mared_cin_oprnd_sub_mod_pre) |
---|
586 | ); |
---|
587 | |
---|
588 | |
---|
589 | wire dly_cur_wrstox_state; |
---|
590 | |
---|
591 | wire cin_cout_wen = start_op | dly_cur_wrstox_state; |
---|
592 | |
---|
593 | wire spu_mared_cin_oprnd_sub_mod_q; |
---|
594 | dffre_s #(1) cin_cout_ff ( |
---|
595 | .din(spu_mared_cin_oprnd_sub_mod_pre) , |
---|
596 | .q(spu_mared_cin_oprnd_sub_mod_q), |
---|
597 | .en(cin_cout_wen), |
---|
598 | .rst(reset), |
---|
599 | .clk (rclk) |
---|
600 | , .se(se), .si(), .so()); |
---|
601 | |
---|
602 | |
---|
603 | // for ld and store ops force cin to zero, since the adder is used for MPA calculations. |
---|
604 | wire force_cin_to_zero = spu_mactl_expop | spu_mactl_mulop | spu_mactl_redop; |
---|
605 | |
---|
606 | wire force_cin_to_zero_q; |
---|
607 | dff_s #(1) force_cin_to_zero_ff ( |
---|
608 | .din(force_cin_to_zero) , |
---|
609 | .q(force_cin_to_zero_q), |
---|
610 | .clk (rclk) |
---|
611 | , .se(se), .si(), .so()); |
---|
612 | |
---|
613 | assign spu_mared_cin_oprnd_sub_mod = spu_mared_cin_oprnd_sub_mod_q & force_cin_to_zero_q; |
---|
614 | |
---|
615 | // ------------------------- |
---|
616 | // delaying cur_wrstox_state to write the cout to cin reg. this delay |
---|
617 | // is for when the j-ptr comes out of being zero is when we need to capture |
---|
618 | // the next cout to cin. |
---|
619 | |
---|
620 | dff_s #(1) dly_cur_wrstox_state_ff ( |
---|
621 | .din(cur_wrstox_state) , |
---|
622 | .q(dly_cur_wrstox_state), |
---|
623 | .clk (rclk) |
---|
624 | , .se(se), .si(), .so()); |
---|
625 | |
---|
626 | |
---|
627 | |
---|
628 | endmodule |
---|