OpenCores
URL https://opencores.org/ocsvn/sparc64soc/sparc64soc/trunk

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-CPU/] [spu/] [spu_mared.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.