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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [sparc_core/] [sparc_exu_ecl_wb.v] - Blame information for rev 113

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 95 fafa1971
// ========== Copyright Header Begin ==========================================
2
// 
3
// OpenSPARC T1 Processor File: sparc_exu_ecl_wb.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 113 albert.wat
`ifdef SIMPLY_RISC_TWEAKS
22
`define SIMPLY_RISC_SCANIN .si(0)
23
`else
24
`define SIMPLY_RISC_SCANIN .si()
25
`endif
26 95 fafa1971
////////////////////////////////////////////////////////////////////////
27
/*
28
//  Module Name: sparc_exu_ecl_wb
29
//      Description:  Implements the writeback logic for the exu.
30
//              This includes the control signals for the w1 and w2 input
31
//      muxes as well as keeping track of the wen signal for ALU ops.
32
*/
33
 
34
module sparc_exu_ecl_wb (/*AUTOARG*/
35
   // Outputs
36
   wb_ccr_wrccr_w, ecl_rml_cwp_wen_e, ecl_rml_cansave_wen_w,
37
   ecl_rml_canrestore_wen_w, ecl_rml_otherwin_wen_w,
38
   ecl_rml_wstate_wen_w, ecl_rml_cleanwin_wen_w, ecl_byp_sel_load_m,
39
   ecl_byp_sel_restore_m, ecl_byp_sel_pipe_m, ecl_byp_restore_m,
40
   ecl_irf_tid_m, ecl_irf_rd_m, ecl_irf_rd_g, ecl_irf_wen_w2,
41
   ecl_irf_tid_g, wb_e, bypass_m, ecl_irf_wen_w, ecl_byp_sel_load_g,
42
   ecl_byp_sel_muldiv_g, ecl_byp_sel_restore_g, wb_divcntl_ack_g,
43
   wb_ccr_setcc_g, ecl_byp_eclpr_e, exu_ifu_longop_done_g,
44
   ecl_div_yreg_wen_w, ecl_div_yreg_wen_g, ecl_div_yreg_shift_g,
45
   ecl_div_yreg_wen_l, wb_eccctl_spec_wen_next, bypass_w,
46
   wb_byplog_rd_w2, wb_byplog_tid_w2, wb_byplog_wen_w2,
47
   wb_byplog_rd_g2, wb_byplog_wen_g2, read_yreg_e,
48
   exu_ffu_wsr_inst_e,
49
   // Inputs
50
   clk, se, reset, sehold, ld_rd_g, ld_tid_g, lsu_exu_dfill_vld_g,
51
   lsu_exu_ldst_miss_g2, rd_m, tid_m, thr_m, tid_w1, ifu_exu_wen_d,
52
   ifu_exu_kill_e, ecl_exu_kill_m, rml_ecl_kill_m, ifu_tlu_flush_w,
53
   flush_w1, divcntl_wb_req_g, mdqctl_wb_divrd_g, mdqctl_wb_divthr_g,
54
   mdqctl_wb_mulrd_g, mdqctl_wb_multhr_g, mdqctl_wb_divsetcc_g,
55
   mdqctl_wb_mulsetcc_g, ecl_div_sel_div, ifu_tlu_wsr_inst_d,
56
   ifu_tlu_sraddr_d, rml_ecl_cwp_d, rml_ecl_cansave_d,
57
   rml_ecl_canrestore_d, rml_ecl_otherwin_d, rml_ecl_wstate_d,
58
   rml_ecl_cleanwin_d, exu_ifu_cc_d, rml_ecl_swap_done,
59
   rml_ecl_rmlop_done_e, mdqctl_wb_yreg_wen_g,
60
   mdqctl_wb_yreg_shift_g, ecl_byp_sel_ecc_m, eccctl_wb_rd_m,
61
   ifu_exu_inst_vld_e, ifu_exu_inst_vld_w, ifu_exu_return_d,
62
   restore_e, rml_ecl_fill_e, early_flush_w, ecl_byp_ldxa_g
63
   ) ;
64
   input clk;
65
   input se;
66
   input reset;
67
   input sehold;
68
   input [4:0] ld_rd_g;
69
   input [1:0] ld_tid_g;
70
   input       lsu_exu_dfill_vld_g;
71
   input        lsu_exu_ldst_miss_g2;
72
   input [4:0]  rd_m;
73
   input [1:0]  tid_m;
74
   input [3:0]  thr_m;
75
   input [1:0]  tid_w1;
76
   input        ifu_exu_wen_d;
77
   input        ifu_exu_kill_e;
78
   input        ecl_exu_kill_m;
79
   input        rml_ecl_kill_m; // kill from spill or fill trap
80
   input        ifu_tlu_flush_w;
81
   input        flush_w1;
82
   input        divcntl_wb_req_g;
83
   input [4:0]  mdqctl_wb_divrd_g;
84
   input [1:0]  mdqctl_wb_divthr_g;
85
   input [4:0]  mdqctl_wb_mulrd_g;
86
   input [1:0]  mdqctl_wb_multhr_g;
87
   input        mdqctl_wb_divsetcc_g;
88
   input        mdqctl_wb_mulsetcc_g;
89
   input        ecl_div_sel_div;
90
   input        ifu_tlu_wsr_inst_d;
91
   input [6:0] ifu_tlu_sraddr_d;
92
   input [2:0] rml_ecl_cwp_d;
93
   input [2:0] rml_ecl_cansave_d;
94
   input [2:0] rml_ecl_canrestore_d;
95
   input [2:0] rml_ecl_otherwin_d;
96
   input [5:0] rml_ecl_wstate_d;
97
   input [2:0] rml_ecl_cleanwin_d;
98
   input [7:0] exu_ifu_cc_d;
99
   input [3:0] rml_ecl_swap_done;
100
   input       rml_ecl_rmlop_done_e;
101
   input         mdqctl_wb_yreg_wen_g;
102
   input         mdqctl_wb_yreg_shift_g;
103
   input         ecl_byp_sel_ecc_m;
104
   input  [4:0] eccctl_wb_rd_m;
105
   input        ifu_exu_inst_vld_e;
106
   input        ifu_exu_inst_vld_w;
107
   input        ifu_exu_return_d;
108
   input  restore_e;
109
   input  rml_ecl_fill_e;
110
   input  early_flush_w;
111
   input        ecl_byp_ldxa_g;
112
 
113
   output      wb_ccr_wrccr_w;
114
   output      ecl_rml_cwp_wen_e;
115
   output      ecl_rml_cansave_wen_w;
116
   output      ecl_rml_canrestore_wen_w;
117
   output      ecl_rml_otherwin_wen_w;
118
   output      ecl_rml_wstate_wen_w;
119
   output      ecl_rml_cleanwin_wen_w;
120
   output      ecl_byp_sel_load_m;
121
   output      ecl_byp_sel_restore_m;
122
   output      ecl_byp_sel_pipe_m;
123
   output      ecl_byp_restore_m;
124
   output [1:0] ecl_irf_tid_m;
125
   output [4:0] ecl_irf_rd_m;
126
   output [4:0] ecl_irf_rd_g;
127
   output       ecl_irf_wen_w2;
128
   output [1:0] ecl_irf_tid_g;
129
   output       wb_e;
130
   output       bypass_m;
131
   output       ecl_irf_wen_w;
132
   output       ecl_byp_sel_load_g;
133
   output       ecl_byp_sel_muldiv_g;
134
   output       ecl_byp_sel_restore_g;
135
   output       wb_divcntl_ack_g;
136
   output       wb_ccr_setcc_g;
137
   output [7:0] ecl_byp_eclpr_e;
138
   output [3:0]  exu_ifu_longop_done_g;
139
   output [3:0]  ecl_div_yreg_wen_w;
140
   output [3:0]  ecl_div_yreg_wen_g;
141
   output [3:0]  ecl_div_yreg_shift_g;
142
   output [3:0]  ecl_div_yreg_wen_l;// w or w2 or shift
143
   output        wb_eccctl_spec_wen_next;
144
   output        bypass_w;
145
   output [4:0] wb_byplog_rd_w2;
146
   output [1:0] wb_byplog_tid_w2;
147
   output       wb_byplog_wen_w2;
148
   output [4:0] wb_byplog_rd_g2;
149
   output       wb_byplog_wen_g2;
150
   output       read_yreg_e;
151
   output       exu_ffu_wsr_inst_e;
152
 
153
   wire          wb_e;
154
   wire          wb_m;
155
   wire          wb_w;
156
   wire          inst_vld_noflush_wen_m;
157
   wire          inst_vld_noflush_wen_w;
158
   wire       ecl_irf_wen_g;
159
   wire      yreg_wen_w;
160
   wire      yreg_wen_w1;
161
   wire      yreg_wen_w1_vld;
162
   wire      wen_no_inst_vld_m;         // load or restore or ce wen
163
   wire        wen_no_inst_vld_w;
164
   wire        wen_w_inst_vld;
165
   wire        valid_e;
166
   wire        valid_m;
167
   wire    valid_w;
168
   wire    ecl_sel_mul_g;
169
   wire    ecl_sel_div_g;
170
   wire [1:0] muldiv_tid;
171
   wire        setcc_g;        // without wen from divcntl
172
   wire    wrsr_e;
173
   wire    wrsr_m;
174
   wire    wrsr_w;
175
   wire    [6:0] sraddr_e;
176
   wire    [6:0] sraddr_m;
177
   wire    [6:0] sraddr_w;
178
   wire    sraddr_ccr_w;
179
   wire    sraddr_y_w;
180
   wire    sraddr_cwp_e;
181
   wire    sraddr_cansave_w;
182
   wire    sraddr_canrestore_w;
183
   wire    sraddr_cleanwin_w;
184
   wire    sraddr_otherwin_w;
185
   wire    sraddr_wstate_w;
186
   wire    sel_cleanwin_d;
187
   wire    sel_otherwin_d;
188
   wire    sel_wstate_d;
189
   wire    sel_canrestore_d;
190
   wire    sel_ccr_d;
191
   wire    sel_cansave_d;
192
   wire    sel_cwp_d;
193
   wire    sel_rdpr_mux1_d;
194
   wire [2:0] rdpr_mux1_out;
195
   wire [7:0] rdpr_mux2_out;
196
   wire [3:0] muldiv_done_g;
197
   wire [3:0]    multhr_dec_g;
198
   wire [3:0]    divthr_dec_g;
199
   wire [3:0]    thrdec_w1;
200
   wire   short_longop_done_e;
201
   wire   short_longop_done_m;
202
   wire [3:0] short_longop_done;
203
   wire       return_e;
204
   wire   restore_m;
205
   wire   restore_w;
206
   wire   vld_restore_e;
207
   wire   vld_restore_w;
208
   wire   restore_request;
209
   wire   restore_wen;
210
   wire   restore_ready;
211
   wire   restore_ready_next;
212
   wire   restore_picked;
213
   wire [3:0]  restore_done;
214
   wire [1:0] restore_tid;
215
   wire [4:0] restore_rd;
216
   wire [3:0] restore_thr;
217
   wire [3:0] ecl_longop_done_kill_m;
218
   wire [3:0] ecl_longop_done_nokill_m;
219
   wire       dfill_vld_g2;
220
   wire       ld_g;
221
   wire       ld_g2;
222
   wire [1:0] dfill_tid_g2;
223
   wire [4:0] dfill_rd_g2;
224
   wire       kill_ld_g2;
225
   wire [1:0] tid_w2;
226
   wire [4:0] rd_w2;
227
 
228
   ////////////////////////////////////////////
229
   // Pass along result of load for one cycle
230
   ////////////////////////////////////////////
231
   assign     ld_g = lsu_exu_dfill_vld_g | ecl_byp_ldxa_g;
232 113 albert.wat
   dff_s dfill_vld_dff (.din(ld_g), .clk(clk), .q(ld_g2),
233
                      .se(se), `SIMPLY_RISC_SCANIN, .so());
234 95 fafa1971
   assign     kill_ld_g2 = flush_w1 & (dfill_tid_g2[1:0] == tid_w1[1:0]);
235
   assign     dfill_vld_g2 = ld_g2 & ~kill_ld_g2 & ~lsu_exu_ldst_miss_g2;
236 113 albert.wat
   dff_s #(2) dfill_tid_dff(.din(ld_tid_g[1:0]), .clk(clk), .q(dfill_tid_g2[1:0]),
237
                          .se(se), `SIMPLY_RISC_SCANIN, .so());
238
   dff_s #(5) dfill_rd_dff(.din(ld_rd_g[4:0]), .clk(clk), .q(dfill_rd_g2[4:0]),
239
                         .se(se), `SIMPLY_RISC_SCANIN, .so());
240 95 fafa1971
 
241
   ///////////////////////////////////////////
242
   // Help with bypassing of long latency ops
243
   ///////////////////////////////////////////
244
   assign       wb_byplog_rd_w2[4:0] = rd_w2[4:0];
245
   assign       wb_byplog_wen_w2 = ecl_irf_wen_w2;
246
   assign       wb_byplog_tid_w2[1:0] = tid_w2[1:0];
247
   assign       wb_byplog_rd_g2[4:0] = dfill_rd_g2[4:0];
248
   assign       wb_byplog_wen_g2 = ld_g2;
249
 
250
 
251
   ////////////////////////////////////////////////////////////////
252
   // G selection logic (picks between LOAD and MUL/DIV outputs)
253
   ////////////////////////////////////////////////////////////////
254
   // select signals: priority LOAD, RESTORE, MUL, DIV
255
   assign      ecl_byp_sel_load_g = (ld_g2 & (wb_m | wrsr_m | ecl_byp_sel_ecc_m));
256
   assign      ecl_byp_sel_restore_g = restore_request & ((wb_m | wrsr_m | ecl_byp_sel_ecc_m) ^ ld_g2);
257
   assign      ecl_byp_sel_muldiv_g = ~(ecl_byp_sel_load_g | ecl_byp_sel_restore_g);
258
   assign      ecl_sel_mul_g = ~ecl_div_sel_div & ecl_byp_sel_muldiv_g;
259
   assign      ecl_sel_div_g = ecl_div_sel_div & ecl_byp_sel_muldiv_g;
260
   assign      wb_divcntl_ack_g = ecl_byp_sel_muldiv_g;
261
 
262
   assign      muldiv_tid[1:0] = (ecl_div_sel_div)? mdqctl_wb_divthr_g[1:0]: mdqctl_wb_multhr_g[1:0];
263
   assign muldiv_done_g[3] = ((wb_divcntl_ack_g & divcntl_wb_req_g) &
264
                              muldiv_tid[1] & muldiv_tid[0]);
265
   assign muldiv_done_g[2] = ((wb_divcntl_ack_g & divcntl_wb_req_g) &
266
                              muldiv_tid[1] & ~muldiv_tid[0]);
267
   assign muldiv_done_g[1] = ((wb_divcntl_ack_g & divcntl_wb_req_g) &
268
                              ~muldiv_tid[1] & muldiv_tid[0]);
269
   assign muldiv_done_g[0] = ((wb_divcntl_ack_g & divcntl_wb_req_g) &
270
                              ~muldiv_tid[1] & ~muldiv_tid[0]);
271
 
272
   assign ecl_irf_wen_g = (sehold)? ecl_irf_wen_w2:
273
                                   (ecl_byp_sel_load_g & dfill_vld_g2 |
274
                                    (ecl_byp_sel_restore_g & restore_wen) |
275
                                    (ecl_byp_sel_muldiv_g & divcntl_wb_req_g));
276
 
277 113 albert.wat
   dff_s wen_w2_dff(.din(ecl_irf_wen_g), .clk(clk), .q(ecl_irf_wen_w2),
278
                  .se(se), `SIMPLY_RISC_SCANIN, .so());
279 95 fafa1971
   mux4ds #(5) rd_g_mux(.dout(ecl_irf_rd_g[4:0]), .in0(dfill_rd_g2[4:0]),
280
                       .in1(mdqctl_wb_divrd_g[4:0]),
281
                       .in2(mdqctl_wb_mulrd_g[4:0]),
282
                        .in3(restore_rd[4:0]),
283
                       .sel0(ecl_byp_sel_load_g),
284
                       .sel1(ecl_sel_div_g),
285
                        .sel2(ecl_sel_mul_g),
286
                        .sel3(ecl_byp_sel_restore_g));
287
   mux4ds #(2) thr_g_mux(.dout(ecl_irf_tid_g[1:0]), .in0(dfill_tid_g2[1:0]),
288
                        .in1(mdqctl_wb_divthr_g[1:0]),
289
                        .in2(mdqctl_wb_multhr_g[1:0]),
290
                         .in3(restore_tid[1:0]),
291
                        .sel0(ecl_byp_sel_load_g),
292
                        .sel1(ecl_sel_div_g),
293
                         .sel2(ecl_sel_mul_g),
294
                         .sel3(ecl_byp_sel_restore_g));
295
   mux2ds setcc_g_mux(.dout(setcc_g),
296
                         .in0(mdqctl_wb_mulsetcc_g),
297
                         .in1(mdqctl_wb_divsetcc_g),
298
                         .sel0(~ecl_div_sel_div),
299
                         .sel1(ecl_div_sel_div));
300 113 albert.wat
   dff_s #(2) dff_thr_g2w2(.din(ecl_irf_tid_g[1:0]), .clk(clk), .q(tid_w2[1:0]), .se(se),
301
                      `SIMPLY_RISC_SCANIN, .so());
302
   dff_s #(5) dff_rd_g2w2(.din(ecl_irf_rd_g[4:0]), .clk(clk), .q(rd_w2[4:0]), .se(se),
303
                     `SIMPLY_RISC_SCANIN, .so());
304 95 fafa1971
   // needs wen to setcc
305
   assign wb_ccr_setcc_g = wb_divcntl_ack_g & divcntl_wb_req_g & setcc_g;
306
 
307
 
308
   ///////////////////
309
   // W1 port control
310
   ///////////////////
311
   // sehold will turn off in pipe writes and put the hold functionality through
312
   // the non inst_vld part
313
   // Mux between load and ALU for rd, thr, and wen
314
   assign      ecl_byp_sel_load_m = ~(wb_m | wrsr_m | ecl_byp_sel_ecc_m) & ld_g2;
315
   assign      ecl_byp_sel_pipe_m = (wb_m | wrsr_m) & ~ecl_byp_sel_ecc_m;
316
   assign      ecl_byp_sel_restore_m = ~(wb_m | wrsr_m | ld_g2 | ecl_byp_sel_ecc_m);
317
   assign      wen_no_inst_vld_m = (sehold)? ecl_irf_wen_w:
318
                                             ((dfill_vld_g2 & ecl_byp_sel_load_m) |
319
                                              (ecl_byp_sel_restore_m & restore_wen));
320 113 albert.wat
   dff_s dff_lsu_wen_m2w(.din(wen_no_inst_vld_m), .clk(clk), .q(wen_no_inst_vld_w), .se(se), `SIMPLY_RISC_SCANIN,
321 95 fafa1971
                       .so());
322
   // ecc_wen must be kept separate because it needs to check inst_vld but not flush
323
   assign      inst_vld_noflush_wen_m = ecl_byp_sel_ecc_m & ~sehold;
324 113 albert.wat
   dff_s ecc_wen_m2w(.din(inst_vld_noflush_wen_m), .clk(clk), .q(inst_vld_noflush_wen_w), .se(se), `SIMPLY_RISC_SCANIN, .so());
325 95 fafa1971
 
326
   assign ecl_irf_tid_m[1:0] = ((ecl_byp_sel_load_m)? dfill_tid_g2[1:0]:
327
                                (ecl_byp_sel_restore_m)? restore_tid[1:0]:
328
                                tid_m[1:0]);
329
 
330
   mux4ds #(5) rd_mux(.dout(ecl_irf_rd_m[4:0]),
331
                      .in0(rd_m[4:0]),
332
                      .in1(dfill_rd_g2[4:0]),
333
                      .in2(eccctl_wb_rd_m[4:0]),
334
                      .in3(restore_rd[4:0]),
335
                      .sel0(ecl_byp_sel_pipe_m),
336
                      .sel1(ecl_byp_sel_load_m),
337
                      .sel2(ecl_byp_sel_ecc_m),
338
                      .sel3(ecl_byp_sel_restore_m));
339
   assign wen_w_inst_vld = valid_w | inst_vld_noflush_wen_w;
340
   assign ecl_irf_wen_w = ifu_exu_inst_vld_w & wen_w_inst_vld | wen_no_inst_vld_w;
341
 
342
   // bypass valid logic and flops
343 113 albert.wat
   dff_s dff_wb_d2e(.din(ifu_exu_wen_d), .clk(clk), .q(wb_e), .se(se),
344
                  `SIMPLY_RISC_SCANIN, .so());
345
   dff_s dff_wb_e2m(.din(valid_e), .clk(clk), .q(wb_m), .se(se),
346
                  `SIMPLY_RISC_SCANIN, .so());
347
   dffr_s dff_wb_m2w(.din(valid_m), .clk(clk), .q(wb_w), .se(se),
348
                  `SIMPLY_RISC_SCANIN, .so(), .rst(reset));
349 95 fafa1971
   assign  valid_e = wb_e & ~ifu_exu_kill_e & ~restore_e & ~wrsr_e;// restore doesn't finish on time
350
   assign  bypass_m = wb_m;// bypass doesn't need to check for traps or sehold
351
   assign  valid_m = bypass_m & ~rml_ecl_kill_m & ~sehold;// sehold turns off writes from this path
352
   assign  valid_w = (wb_w & ~early_flush_w & ~ifu_tlu_flush_w);// check inst_vld later
353
   // don't check flush for bypass
354
   assign  bypass_w = wb_w | inst_vld_noflush_wen_w | wen_no_inst_vld_w;
355
 
356
   // speculative wen for ecc injection
357
   assign  wb_eccctl_spec_wen_next = valid_m | dfill_vld_g2 | restore_request |  divcntl_wb_req_g;
358
 
359
   ///////////////////////////////////////////////////////
360
   // Priviledged register read and write flops and logic
361
   ///////////////////////////////////////////////////////
362
/* -----\/----- EXCLUDED -----\/-----
363
   Decoded sraddr
364
   sraddr[5] = 1-priv, 0-state
365
   Y -   0
366
   CCR - 2
367
   CWP - 9
368
   CANSAVE - a
369
   CARESTORE - b
370
   CLEANWIN - c
371
   OTHERWIN - d
372
   WSTATE - e
373
   GSR - 0x13
374
 -----/\----- EXCLUDED -----/\----- */
375
   assign  ecl_rml_cwp_wen_e = sraddr_cwp_e & wrsr_e;
376
   assign  sraddr_cwp_e = ~sraddr_e[6] & sraddr_e[5] & ~sraddr_e[4] & sraddr_e[3] & ~sraddr_e[2] &
377
           ~sraddr_e[1] & sraddr_e[0];
378
 
379
   assign  sraddr_y_w = ~sraddr_w[6] & ~sraddr_w[5] & ~sraddr_w[4] & ~sraddr_w[3] & ~sraddr_w[2] &
380
           ~sraddr_w[1] & ~sraddr_w[0];
381
   assign  sraddr_ccr_w = ~sraddr_w[6] & ~sraddr_w[5] & ~sraddr_w[4] & ~sraddr_w[3] & ~sraddr_w[2] &
382
           sraddr_w[1] & ~sraddr_w[0];
383
   assign  sraddr_cansave_w = ~sraddr_w[6] & sraddr_w[5] & ~sraddr_w[4] & sraddr_w[3] & ~sraddr_w[2] &
384
           sraddr_w[1] & ~sraddr_w[0];
385
   assign  sraddr_canrestore_w = ~sraddr_w[6] & sraddr_w[5] & ~sraddr_w[4] & sraddr_w[3] & ~sraddr_w[2] &
386
           sraddr_w[1] & sraddr_w[0];
387
   assign  sraddr_cleanwin_w = ~sraddr_w[6] & sraddr_w[5] & ~sraddr_w[4] & sraddr_w[3] & sraddr_w[2] &
388
           ~sraddr_w[1] & ~sraddr_w[0];
389
   assign  sraddr_otherwin_w = ~sraddr_w[6] & sraddr_w[5] & ~sraddr_w[4] & sraddr_w[3] & sraddr_w[2] &
390
           ~sraddr_w[1] & sraddr_w[0];
391
   assign  sraddr_wstate_w = ~sraddr_w[6] & sraddr_w[5] & ~sraddr_w[4] & sraddr_w[3] & sraddr_w[2] &
392
           sraddr_w[1] & ~sraddr_w[0];
393
 
394
   // yreg writes cycle after w and checks flush in that cycle
395
   assign  yreg_wen_w = sraddr_y_w & wrsr_w & ifu_exu_inst_vld_w;
396
   assign  yreg_wen_w1_vld = yreg_wen_w1 & ~flush_w1;
397
 
398
   // controls for all other writes (and flush checks) are in their respective blocks
399
   assign  wb_ccr_wrccr_w = sraddr_ccr_w & wrsr_w;
400
   assign  ecl_rml_cansave_wen_w = sraddr_cansave_w & wrsr_w;
401
   assign  ecl_rml_canrestore_wen_w = sraddr_canrestore_w & wrsr_w;
402
   assign  ecl_rml_cleanwin_wen_w = sraddr_cleanwin_w & wrsr_w;
403
   assign  ecl_rml_otherwin_wen_w = sraddr_otherwin_w & wrsr_w;
404
   assign  ecl_rml_wstate_wen_w = sraddr_wstate_w & wrsr_w;
405
 
406
 
407 113 albert.wat
   dff_s dff_wrsr_d2e(.din(ifu_tlu_wsr_inst_d), .clk(clk), .q(wrsr_e), .se(se),
408
                   `SIMPLY_RISC_SCANIN, .so());
409 95 fafa1971
   assign  exu_ffu_wsr_inst_e = wrsr_e;
410 113 albert.wat
   dff_s dff_wrsr_e2m(.din(wrsr_e), .clk(clk), .q(wrsr_m), .se(se),
411
                   `SIMPLY_RISC_SCANIN, .so());
412
   dff_s dff_wrsr_m2w(.din(wrsr_m), .clk(clk), .q(wrsr_w), .se(se),
413
                   `SIMPLY_RISC_SCANIN, .so());
414
   dff_s #(7) dff_sraddr_d2e(.din(ifu_tlu_sraddr_d[6:0]), .clk(clk), .q(sraddr_e[6:0]), .se(se),
415
                       `SIMPLY_RISC_SCANIN, .so());
416
   dff_s #(7) dff_sraddr_e2m(.din(sraddr_e[6:0]), .clk(clk), .q(sraddr_m[6:0]), .se(se),
417
                       `SIMPLY_RISC_SCANIN, .so());
418
   dff_s #(7) dff_sraddr_m2w(.din(sraddr_m[6:0]), .clk(clk), .q(sraddr_w[6:0]), .se(se),
419
                       `SIMPLY_RISC_SCANIN, .so());
420
   dff_s dff_yreg_wen_w2w1(.din(yreg_wen_w), .clk(clk), .q(yreg_wen_w1), .se(se), `SIMPLY_RISC_SCANIN, .so());
421 95 fafa1971
 
422
   // Logic for rdpr/rdsr
423
   // This mux takes advantage of the fact that these 4 encodings don't overlap
424
   assign sel_cleanwin_d = ~ifu_tlu_sraddr_d[1] & ~ifu_tlu_sraddr_d[0];
425
   assign sel_otherwin_d = ~ifu_tlu_sraddr_d[1] & ifu_tlu_sraddr_d[0];
426
   assign sel_cansave_d = ifu_tlu_sraddr_d[1] & ~ifu_tlu_sraddr_d[0];
427
   assign sel_canrestore_d = ifu_tlu_sraddr_d[1] & ifu_tlu_sraddr_d[0];
428
   mux4ds #(3) rdpr_mux1(.dout(rdpr_mux1_out[2:0]),
429
                       .in0(rml_ecl_canrestore_d[2:0]),
430
                       .in1(rml_ecl_cleanwin_d[2:0]),
431
                       .in2(rml_ecl_cansave_d[2:0]),
432
                       .in3(rml_ecl_otherwin_d[2:0]),
433
                       .sel0(sel_canrestore_d),
434
                       .sel1(sel_cleanwin_d),
435
                       .sel2(sel_cansave_d),
436
                       .sel3(sel_otherwin_d));
437
   assign sel_ccr_d = ~ifu_tlu_sraddr_d[3];
438
   assign sel_cwp_d = ifu_tlu_sraddr_d[3] & ~ifu_tlu_sraddr_d[2] & ~ifu_tlu_sraddr_d[1] & ifu_tlu_sraddr_d[0];
439
   assign sel_wstate_d = ifu_tlu_sraddr_d[3] & ifu_tlu_sraddr_d[2] & ifu_tlu_sraddr_d[1] & ~ifu_tlu_sraddr_d[0];
440
   assign sel_rdpr_mux1_d = ~(sel_ccr_d | sel_cwp_d | sel_wstate_d);
441
   mux4ds #(8) rdpr_mux2(.dout(rdpr_mux2_out[7:0]),
442
                       .in0(exu_ifu_cc_d[7:0]),
443
                       .in1({5'b0, rml_ecl_cwp_d[2:0]}),
444
                       .in2({2'b0, rml_ecl_wstate_d[5:0]}),
445
                       .in3({5'b0, rdpr_mux1_out[2:0]}),
446
                       .sel0(sel_ccr_d),
447
                       .sel1(sel_cwp_d),
448
                       .sel2(sel_wstate_d),
449
                       .sel3(sel_rdpr_mux1_d));
450
 
451
   assign read_yreg_e = ~(sraddr_e[3] | sraddr_e[1]);
452 113 albert.wat
   dff_s #(8) rdpr_dff(.din(rdpr_mux2_out[7:0]), .clk(clk), .q(ecl_byp_eclpr_e[7:0]),
453
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
454 95 fafa1971
 
455
 
456
   ///////////////////////////////
457
   // YREG write enable logic
458
   ///////////////////////////////
459
   // decode thr_g for mux select
460
   assign multhr_dec_g[0] = ~mdqctl_wb_multhr_g[1] & ~mdqctl_wb_multhr_g[0];
461
   assign multhr_dec_g[1] = ~mdqctl_wb_multhr_g[1] & mdqctl_wb_multhr_g[0];
462
   assign multhr_dec_g[2] = mdqctl_wb_multhr_g[1] & ~mdqctl_wb_multhr_g[0];
463
   assign multhr_dec_g[3] = mdqctl_wb_multhr_g[1] & mdqctl_wb_multhr_g[0];
464
 
465
   assign divthr_dec_g[0] = ~mdqctl_wb_divthr_g[1] & ~mdqctl_wb_divthr_g[0];
466
   assign divthr_dec_g[1] = ~mdqctl_wb_divthr_g[1] & mdqctl_wb_divthr_g[0];
467
   assign divthr_dec_g[2] = mdqctl_wb_divthr_g[1] & ~mdqctl_wb_divthr_g[0];
468
   assign divthr_dec_g[3] = mdqctl_wb_divthr_g[1] & mdqctl_wb_divthr_g[0];
469
 
470
   assign thrdec_w1[0] = ~tid_w1[1] & ~tid_w1[0];
471
   assign thrdec_w1[1] = ~tid_w1[1] & tid_w1[0];
472
   assign thrdec_w1[2] = tid_w1[1] & ~tid_w1[0];
473
   assign thrdec_w1[3] = tid_w1[1] & tid_w1[0];
474
 
475
   // enable input for each thread
476
 
477
   assign ecl_div_yreg_shift_g[0] = divthr_dec_g[0] & mdqctl_wb_yreg_shift_g;
478
   assign ecl_div_yreg_wen_w[0] = (thrdec_w1[0] & yreg_wen_w1_vld &
479
                                   ~ecl_div_yreg_shift_g[0] &
480
                                   ~ecl_div_yreg_wen_g[0]);
481
   assign ecl_div_yreg_wen_g[0] = (multhr_dec_g[0] & mdqctl_wb_yreg_wen_g &
482
                                   ~ecl_div_yreg_shift_g[0]);
483
   assign ecl_div_yreg_wen_l[0] = ~(ecl_div_yreg_wen_w[0] | ecl_div_yreg_wen_g[0]
484
                                    | ecl_div_yreg_shift_g[0]);
485
   assign ecl_div_yreg_shift_g[1] = divthr_dec_g[1] & mdqctl_wb_yreg_shift_g;
486
   assign ecl_div_yreg_wen_w[1] = (thrdec_w1[1] & yreg_wen_w1_vld &
487
                                   ~ecl_div_yreg_shift_g[1] &
488
                                   ~ecl_div_yreg_wen_g[1]);
489
   assign ecl_div_yreg_wen_g[1] = (multhr_dec_g[1] & mdqctl_wb_yreg_wen_g &
490
                                   ~ecl_div_yreg_shift_g[1]);
491
   assign ecl_div_yreg_wen_l[1] = ~(ecl_div_yreg_wen_w[1] | ecl_div_yreg_wen_g[1]
492
                                    | ecl_div_yreg_shift_g[1]);
493
   assign ecl_div_yreg_shift_g[2] = divthr_dec_g[2] & mdqctl_wb_yreg_shift_g;
494
   assign ecl_div_yreg_wen_w[2] = (thrdec_w1[2] & yreg_wen_w1_vld &
495
                                   ~ecl_div_yreg_shift_g[2] &
496
                                   ~ecl_div_yreg_wen_g[2]);
497
   assign ecl_div_yreg_wen_g[2] = (multhr_dec_g[2] & mdqctl_wb_yreg_wen_g &
498
                                   ~ecl_div_yreg_shift_g[2]);
499
   assign ecl_div_yreg_wen_l[2] = ~(ecl_div_yreg_wen_w[2] | ecl_div_yreg_wen_g[2]
500
                                    | ecl_div_yreg_shift_g[2]);
501
   assign ecl_div_yreg_shift_g[3] = divthr_dec_g[3] & mdqctl_wb_yreg_shift_g;
502
   assign ecl_div_yreg_wen_w[3] = (thrdec_w1[3] & yreg_wen_w1_vld &
503
                                   ~ecl_div_yreg_shift_g[3] &
504
                                   ~ecl_div_yreg_wen_g[3]);
505
   assign ecl_div_yreg_wen_g[3] = (multhr_dec_g[3] & mdqctl_wb_yreg_wen_g &
506
                                   ~ecl_div_yreg_shift_g[3]);
507
   assign ecl_div_yreg_wen_l[3] = ~(ecl_div_yreg_wen_w[3] | ecl_div_yreg_wen_g[3]
508
                                    | ecl_div_yreg_shift_g[3]);
509
 
510
   //////////////////////////////////////////////////////////
511
   // Completion logic for restore
512
   //////////////////////////////////////////////////////////
513
 
514
   // only worry about restores.  Returns are automatically switched back in
515
   assign ecl_byp_restore_m = restore_m;
516
   assign vld_restore_e = restore_e & wb_e & ~return_e & ~rml_ecl_fill_e & ifu_exu_inst_vld_e;
517
   assign vld_restore_w = (restore_w & ~ifu_tlu_flush_w & ~early_flush_w
518
                           & ifu_exu_inst_vld_w & ~reset);
519
 
520
   assign restore_request = restore_w | restore_ready;
521
   assign restore_wen = vld_restore_w | restore_ready;
522
   assign restore_picked = ecl_byp_sel_restore_m | ecl_byp_sel_restore_g;
523
   assign restore_done[3:0] = restore_thr[3:0] & {4{restore_picked & restore_request}};
524
   // restore request waits for kills in the w stage.  they
525
   // won't start until after the flop
526
   assign restore_ready_next = (vld_restore_w  | restore_ready) & ~restore_picked;
527
 
528 113 albert.wat
   dffe_s #(2) restore_tid_dff(.din(tid_m[1:0]), .clk(clk), .q(restore_tid[1:0]),
529
                             .se(se), `SIMPLY_RISC_SCANIN, .so(), .en(restore_m));
530
   dffe_s #(5) restore_rd_dff(.din(rd_m[4:0]), .clk(clk), .q(restore_rd[4:0]),
531
                            .se(se), `SIMPLY_RISC_SCANIN, .so(), .en(restore_m));
532
   dff_s return_d2e(.din(ifu_exu_return_d), .clk(clk), .q(return_e),
533
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
534
   dff_s restore_e2m(.din(vld_restore_e), .clk(clk), .q(restore_m),
535
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
536
   dff_s restore_m2w(.din(restore_m), .clk(clk), .q(restore_w),
537
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
538
   dff_s restore_ready_dff(.din(restore_ready_next), .q(restore_ready),
539
                         .clk(clk), .se(se), .so(), `SIMPLY_RISC_SCANIN);
540 95 fafa1971
 
541
   //////////////////////////////////////////////////////////
542
   // Completion logic for non integer-pipeline operations
543
   //////////////////////////////////////////////////////////
544
   // short_longops must check inst_vld_e to protect against invalid completion signal
545
   assign short_longop_done_e = (rml_ecl_rmlop_done_e | (restore_e & ~wb_e & ~return_e)) &
546
                                  ifu_exu_inst_vld_e & ~ifu_exu_kill_e;
547 113 albert.wat
   dff_s longop_done_e2m (.din(short_longop_done_e), .clk(clk), .q(short_longop_done_m), .se(se), `SIMPLY_RISC_SCANIN, .so());
548 95 fafa1971
   assign short_longop_done[3:0] = thr_m[3:0] & {4{short_longop_done_m}};
549
 
550
   assign ecl_longop_done_nokill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | short_longop_done[3:0] |
551
                                           rml_ecl_swap_done[3:0]);
552
   assign ecl_longop_done_kill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | rml_ecl_swap_done[3:0]);
553
   assign exu_ifu_longop_done_g[3:0] = (ecl_exu_kill_m)? ecl_longop_done_kill_m[3:0]: ecl_longop_done_nokill_m[3:0];
554
 
555
 
556
   // decode tid
557
   assign restore_thr[3] = restore_tid[1] & restore_tid[0];
558
   assign restore_thr[2] = restore_tid[1] & ~restore_tid[0];
559
   assign restore_thr[1] = ~restore_tid[1] & restore_tid[0];
560
   assign restore_thr[0] = ~restore_tid[1] & ~restore_tid[0];
561
 
562
endmodule // sparc_exu_ecl_wb

powered by: WebSVN 2.1.0

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