1 |
2 |
dmitryr |
// ========== 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
|