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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-CPU/] [exu/] [sparc_exu_rml.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dmitryr
// ========== Copyright Header Begin ==========================================
2
// 
3
// OpenSPARC T1 Processor File: sparc_exu_rml.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
//  Module Name: sparc_exu_rml
24
//      Description: Register management logic.  Contains CWP, CANSAVE, CANRESTORE
25
//              and other window management registers.  Generates RF related traps
26
//              and switches the global registers to alternate globals.  All the registers
27
//              are written in the W stage (there is no bypassing so they must
28
//              swap out) and will either get a new value generated by a window management
29
//              Instruction or by a WRPS instruction.  The following traps can be generated:
30
//                      Fill: restore with canrestore == 0
31
//                      clean_window: save with cleanwin-canrestore == 0
32
//                      spill: flushw with cansave != nwindows -2 or
33
//                              save with cansave == 0
34
//              It is assumed that the contents of the new window will get squashed
35
//              on a clean_window or fill trap so the save or restore gets executed
36
//              normally.  Spill traps or WRCWPs mean that all 16 windowed registers
37
//              must be saved and restored (a 4 cycle operation).
38
*/
39
module sparc_exu_rml (/*AUTOARG*/
40
   // Outputs
41
   exu_tlu_spill_wtype, exu_tlu_spill_other, exu_tlu_cwp_retry,
42
   exu_tlu_cwp3_w, exu_tlu_cwp2_w, exu_tlu_cwp1_w, exu_tlu_cwp0_w,
43
   so, exu_tlu_cwp_cmplt, exu_tlu_cwp_cmplt_tid, rml_ecl_cwp_d,
44
   rml_ecl_cansave_d, rml_ecl_canrestore_d, rml_ecl_otherwin_d,
45
   rml_ecl_wstate_d, rml_ecl_cleanwin_d, rml_ecl_fill_e,
46
   rml_ecl_clean_window_e, rml_ecl_other_e, rml_ecl_wtype_e,
47
   exu_ifu_spill_e, rml_ecl_gl_e, rml_irf_old_lo_cwp_e,
48
   rml_irf_new_lo_cwp_e, rml_irf_old_e_cwp_e, rml_irf_new_e_cwp_e,
49
   rml_irf_swap_even_e, rml_irf_swap_odd_e, rml_irf_swap_local_e,
50
   rml_irf_kill_restore_w, rml_irf_cwpswap_tid_e, rml_ecl_swap_done,
51
   rml_ecl_rmlop_done_e, exu_ifu_oddwin_s, exu_tlu_spill,
52
   exu_tlu_spill_tid, rml_ecl_kill_m, rml_irf_old_agp,
53
   rml_irf_new_agp, rml_irf_swap_global, rml_irf_global_tid,
54
   // Inputs
55
   tlu_exu_cwp_retry_m, rst_tri_en, rclk, se, si, grst_l, arst_l,
56
   ifu_exu_tid_s2, ifu_exu_save_d, ifu_exu_restore_d,
57
   ifu_exu_saved_e, ifu_exu_restored_e, ifu_exu_flushw_e,
58
   ecl_rml_thr_m, ecl_rml_thr_w, ecl_rml_cwp_wen_e,
59
   ecl_rml_cansave_wen_w, ecl_rml_canrestore_wen_w,
60
   ecl_rml_otherwin_wen_w, ecl_rml_wstate_wen_w,
61
   ecl_rml_cleanwin_wen_w, ecl_rml_xor_data_e, ecl_rml_kill_e,
62
   ecl_rml_kill_w, ecl_rml_early_flush_w, exu_tlu_wsr_data_w,
63
   tlu_exu_agp, tlu_exu_agp_swap, tlu_exu_agp_tid, tlu_exu_cwp_m,
64 4 dmitryr
   tlu_exu_cwpccr_update_m, ecl_rml_inst_vld_w,current_cwp
65 2 dmitryr
   ) ;
66
   input rclk;
67
   input se;
68
   input si;
69
   input grst_l;
70
   input arst_l;
71
   input [1:0] ifu_exu_tid_s2;
72
   input       ifu_exu_save_d;
73
   input       ifu_exu_restore_d;
74
   input       ifu_exu_saved_e;
75
   input       ifu_exu_restored_e;
76
   input       ifu_exu_flushw_e;
77
   input [3:0] ecl_rml_thr_m;
78
   input [3:0] ecl_rml_thr_w;
79
   input       ecl_rml_cwp_wen_e;
80
   input       ecl_rml_cansave_wen_w;
81
   input       ecl_rml_canrestore_wen_w;
82
   input       ecl_rml_otherwin_wen_w;
83
   input       ecl_rml_wstate_wen_w;
84
   input       ecl_rml_cleanwin_wen_w;
85
   input [2:0] ecl_rml_xor_data_e;
86
   input       ecl_rml_kill_e;// needed for oddwin updates
87
   input       ecl_rml_kill_w;
88
   input       ecl_rml_early_flush_w;
89
   input [5:0] exu_tlu_wsr_data_w; // for wstate
90
   input [1:0]   tlu_exu_agp;   // alternate global pointer
91
   input         tlu_exu_agp_swap;// switch globals
92
   input [1:0]   tlu_exu_agp_tid;// thread that agp refers to
93
   input [2:0] tlu_exu_cwp_m;   // for switching cwp on return from trap
94
   input       tlu_exu_cwpccr_update_m;
95
   input       ecl_rml_inst_vld_w;
96
   /*AUTOINPUT*/
97
   // Beginning of automatic inputs (from unused autoinst inputs)
98
   input                rst_tri_en;             // To cwp of sparc_exu_rml_cwp.v
99
   input                tlu_exu_cwp_retry_m;    // To cwp of sparc_exu_rml_cwp.v
100
   // End of automatics
101
 
102
   /*AUTOOUTPUT*/
103
   // Beginning of automatic outputs (from unused autoinst outputs)
104
   output [2:0]         exu_tlu_cwp0_w;         // From cwp of sparc_exu_rml_cwp.v
105
   output [2:0]         exu_tlu_cwp1_w;         // From cwp of sparc_exu_rml_cwp.v
106
   output [2:0]         exu_tlu_cwp2_w;         // From cwp of sparc_exu_rml_cwp.v
107
   output [2:0]         exu_tlu_cwp3_w;         // From cwp of sparc_exu_rml_cwp.v
108
   output               exu_tlu_cwp_retry;      // From cwp of sparc_exu_rml_cwp.v
109
   output               exu_tlu_spill_other;    // From cwp of sparc_exu_rml_cwp.v
110
   output [2:0]         exu_tlu_spill_wtype;    // From cwp of sparc_exu_rml_cwp.v
111
   // End of automatics
112
   output               so;
113
   output      exu_tlu_cwp_cmplt;
114
   output [1:0] exu_tlu_cwp_cmplt_tid;
115
   output [2:0]  rml_ecl_cwp_d;
116
   output [2:0]  rml_ecl_cansave_d;
117
   output [2:0]  rml_ecl_canrestore_d;
118
   output [2:0]  rml_ecl_otherwin_d;
119
   output [5:0]  rml_ecl_wstate_d;
120
   output [2:0]  rml_ecl_cleanwin_d;
121
   output        rml_ecl_fill_e;
122
   output        rml_ecl_clean_window_e;
123
   output        rml_ecl_other_e;
124
   output [2:0] rml_ecl_wtype_e;
125
   output       exu_ifu_spill_e;
126
   output [1:0] rml_ecl_gl_e;
127
 
128
   output [2:0]  rml_irf_old_lo_cwp_e;  // current window pointer for locals and odds
129
   output [2:0]  rml_irf_new_lo_cwp_e;  // current window pointer for locals and odd
130
   output [1:0]  rml_irf_old_e_cwp_e;  // current window pointer for evens
131
   output [1:0]  rml_irf_new_e_cwp_e;  // current window pointer for evens
132
   output        rml_irf_swap_even_e;
133
   output        rml_irf_swap_odd_e;
134
   output        rml_irf_swap_local_e;
135
   output        rml_irf_kill_restore_w;
136
   output [1:0]  rml_irf_cwpswap_tid_e;
137
 
138
   output [3:0] rml_ecl_swap_done;
139
   output       rml_ecl_rmlop_done_e;
140
   output [3:0] exu_ifu_oddwin_s;
141
   output       exu_tlu_spill;
142
   output [1:0] exu_tlu_spill_tid;
143
   output       rml_ecl_kill_m;
144
 
145
   output [1:0]  rml_irf_old_agp; // alternate global pointer
146
   output [1:0]  rml_irf_new_agp; // alternate global pointer
147
   output        rml_irf_swap_global;
148
   output [1:0]  rml_irf_global_tid;
149 4 dmitryr
   output reg [11:0] current_cwp;
150
 
151 2 dmitryr
   wire          clk;
152
   wire [1:0]    tid_d;
153
   wire [3:0]    thr_d;
154
   wire [1:0]    tid_e;
155
   wire          rml_reset_l;
156
   wire          reset;
157
   wire          save_e;
158
   wire          save_m;
159
   wire          restore_e;
160
   wire          swap_e;
161
   wire          agp_wen;
162
   wire [1:0]    agp_thr0;
163
   wire [1:0]    agp_thr1;
164
   wire [1:0]    agp_thr2;
165
   wire [1:0]    agp_thr3;
166
   wire [1:0]    agp_thr0_next;
167
   wire [1:0]    agp_thr1_next;
168
   wire [1:0]    agp_thr2_next;
169
   wire [1:0]    agp_thr3_next;
170
   wire          agp_wen_thr0_w;
171
   wire          agp_wen_thr1_w;
172
   wire          agp_wen_thr2_w;
173
   wire          agp_wen_thr3_w;
174
   wire [1:0]    new_agp;
175
   wire [1:0]    agp_tid;
176
   wire [3:0]    agp_thr;
177
   wire        full_swap_e;
178
   wire   did_restore_m;
179
   wire   did_restore_w;
180
   wire   kill_restore_m;
181
   wire   kill_restore_w;
182
 
183
   wire [2:0]  rml_ecl_cwp_e;
184
   wire [2:0]  rml_ecl_cansave_e;
185
   wire [2:0]  rml_ecl_canrestore_e;
186
   wire [2:0]  rml_ecl_otherwin_e;
187
   wire [2:0]  rml_ecl_cleanwin_e;
188
 
189
   wire [2:0]  rml_next_cwp_e;
190
   wire [2:0]  rml_next_cansave_e;// e-stage of rml generated new data
191
   wire [2:0]  rml_next_canrestore_e;
192
   wire [2:0]  rml_next_otherwin_e;
193
   wire [2:0]  rml_next_cleanwin_e;
194
 
195
   wire [2:0]  next_cwp_e;
196
   wire [2:0]  next_cansave_e;  // e-stage of new data
197
   wire [2:0]  next_canrestore_e;
198
   wire [2:0]  next_otherwin_e;
199
   wire [2:0]  next_cleanwin_e;
200
   wire [2:0]  next_cwp_m;      // m-stage of new data
201
   wire [2:0]  next_cansave_m;
202
   wire [2:0]  next_canrestore_m;
203
   wire [2:0]  next_otherwin_m;
204
   wire [2:0]  next_cleanwin_m;
205
   wire [2:0]  next_cansave_w;// w-stage of new data
206
   wire [2:0]  next_canrestore_w;
207
   wire [2:0]  next_otherwin_w;
208
   wire [2:0]  next_cleanwin_w;
209
   wire [2:0]  next_cwp_noreset_w;
210
   wire [2:0]  next_cwp_w;
211
 
212
   wire   rml_cwp_wen_e;        // wen for cwp from rml
213
   wire   rml_cwp_wen_m;        // wen for cwp from rml
214
   wire [2:0] spill_cwp_e;      // next cwp if there is a spill trap 
215
   wire       spill_cwp_carry0; // carry bit from spill cwp computations
216
   wire       spill_cwp_carry1;
217
   wire       next_cwp_sel_inc; // select line to next_cwp mux
218
 
219
   wire        rml_cansave_wen_w;// rml generated wen
220
   wire        rml_canrestore_wen_w;
221
   wire        rml_otherwin_wen_w;
222
   wire        rml_cleanwin_wen_w;
223
 
224
   wire        cansave_wen_w;// wen to registers
225
   wire        canrestore_wen_w;
226
   wire        otherwin_wen_w;
227
   wire        cleanwin_wen_w;
228
   wire        cwp_wen_nokill_w;
229
   wire        cwp_wen_w;
230
   wire        wstate_wen_w;
231
 
232
   wire        cwp_wen_m;       // rml generated wen w/o kills
233
   wire        cansave_wen_m;
234
   wire        canrestore_wen_m;
235
   wire        otherwin_wen_m;
236
   wire        cleanwin_wen_m;
237
   wire        cansave_wen_valid_m;     // rml generated wen w/ kills
238
   wire        canrestore_wen_valid_m;
239
   wire        otherwin_wen_valid_m;
240
   wire        cleanwin_wen_valid_m;
241
 
242
   wire          cwp_wen_e;       // rml generated wen_e
243
   wire        cansave_wen_e;
244
   wire        canrestore_wen_e;
245
   wire        otherwin_wen_e;
246
   wire        cleanwin_wen_e;
247
 
248
   wire        cansave_inc_e;
249
   wire        canrestore_inc_e;
250
 
251
   wire        spill_trap_save;
252
   wire        spill_trap_flush;
253
   wire        spill_m;
254
   wire [2:0]  cleanwin_xor_canrestore;
255
 
256
   wire        otherwin_is0_e;
257
   wire        cansave_is0_e;
258
   wire        canrestore_is0_e;
259
 
260
   wire        swap_locals_ins;
261
   wire        swap_outs;
262
   wire [2:0]  old_cwp_e;
263
   wire [2:0]  new_cwp_e;
264
 
265
   wire [2:0]   rml_ecl_wtype_d;
266
   wire [2:0]   rml_ecl_wtype_e;
267
   wire         rml_ecl_other_d;
268
   wire         rml_ecl_other_e;
269
   wire        exu_tlu_spill_e;
270
   wire         rml_ecl_kill_e;
271
   wire         rml_kill_w;
272
   wire         vld_w;
273
   wire         win_trap_e;
274
   wire         win_trap_m;
275
   wire         win_trap_w;
276
 
277
   assign       clk = rclk;
278
   // Reset flop
279
    dffrl_async rstff(.din (grst_l),
280
                        .q   (rml_reset_l),
281
                        .clk (clk),
282
                        .rst_l (arst_l), .se(se), .si(), .so());
283
   assign       reset = ~rml_reset_l;
284
 
285
   dff_s #(2) tid_s2d(.din(ifu_exu_tid_s2[1:0]), .clk(clk), .q(tid_d[1:0]), .se(se), .si(), .so());
286
   dff_s #(2) tid_d2e(.din(tid_d[1:0]), .clk(clk), .q(tid_e[1:0]), .se(se), .si(), .so());
287
   assign       thr_d[3] = tid_d[1] & tid_d[0];
288
   assign       thr_d[2] = tid_d[1] & ~tid_d[0];
289
   assign       thr_d[1] = ~tid_d[1] & tid_d[0];
290
   assign       thr_d[0] = ~tid_d[1] & ~tid_d[0];
291
 
292
   dff_s save_d2e(.din(ifu_exu_save_d), .clk(clk), .q(save_e), .se(se), .si(), .so());
293
   dff_s save_e2m(.din(save_e), .clk(clk), .q(save_m), .se(se), .si(), .so());
294
   dff_s restore_d2e(.din(ifu_exu_restore_d), .clk(clk), .q(restore_e), .se(se), .si(), .so());
295
 
296
   // don't check flush_pipe in w if caused by rml trap.  Things with a higher priority
297
   // than a window trap have been accumulated into ecl_rml_kill_w
298
   assign       vld_w = ecl_rml_inst_vld_w & (~ecl_rml_early_flush_w | win_trap_w);
299
   assign     rml_kill_w = ecl_rml_kill_w | ~vld_w;
300
 
301
   assign     win_trap_e = rml_ecl_fill_e | exu_tlu_spill_e | rml_ecl_clean_window_e;
302
   dff_s win_trap_e2m(.din(win_trap_e), .clk(clk), .q(win_trap_m), .se(se), .si(), .so());
303
   dff_s win_trap_m2w(.din(win_trap_m), .clk(clk), .q(win_trap_w), .se(se), .si(), .so());
304
 
305
   assign canrestore_is0_e = (~rml_ecl_canrestore_e[0] & ~rml_ecl_canrestore_e[1]
306
                              & ~rml_ecl_canrestore_e[2]);
307
   assign cansave_is0_e = (~rml_ecl_cansave_e[0] & ~rml_ecl_cansave_e[1] &
308
                           ~rml_ecl_cansave_e[2]);
309
   assign otherwin_is0_e = ~rml_ecl_other_e;
310
 
311
   ///////////////////////////////////////
312
   // Signals that operations are done
313
   // restore/return is not signalled here
314
   // because it depends on the write to the
315
   // irf (computed in ecl_wb)
316
   ////////////////////////////////////////
317
   assign rml_ecl_rmlop_done_e = (ifu_exu_saved_e | ifu_exu_restored_e |
318
                                  (ifu_exu_flushw_e & ~spill_trap_flush));
319
 
320
   //////////////////////////
321
   // Trap generation
322
   //////////////////////////
323
   // Fill trap generated on restore and canrestore == 0
324
   assign rml_ecl_fill_e = restore_e & canrestore_is0_e;
325
 
326
   // Spill trap on save with cansave == 0
327
   assign spill_trap_save = save_e & cansave_is0_e;
328
   assign exu_ifu_spill_e = spill_trap_save;
329
   // Spill trap on wflush with cansave != (NWINDOWS - 2 = 6)
330
   assign spill_trap_flush = (ifu_exu_flushw_e & ~(rml_ecl_cansave_e[2] &
331
                                                 rml_ecl_cansave_e[1] &
332
                                                 ~rml_ecl_cansave_e[0]));
333
   assign exu_tlu_spill_e = (spill_trap_save | spill_trap_flush);
334
   dff_s spill_e2m(.din(exu_tlu_spill_e), .clk(clk), .q(spill_m), .se(se), .si(), .so());
335
 
336
   // Clean window trap on save w/ cleanwin - canrestore == 0
337
   // or cleanwin == canrestore
338
   // (not signalled on spill traps because spill is higher priority)
339
   assign cleanwin_xor_canrestore = rml_ecl_cleanwin_e ^ rml_ecl_canrestore_e;
340
   assign rml_ecl_clean_window_e = ~(cleanwin_xor_canrestore[2] |
341
                                cleanwin_xor_canrestore[1] |
342
                                cleanwin_xor_canrestore[0]) & save_e & ~exu_tlu_spill_e;
343
 
344
   // Kill signal for w1 wen bit (all others don't care)
345
   assign rml_ecl_kill_e = rml_ecl_fill_e | exu_tlu_spill_e;
346
   dff_s rml_kill_e2m(.din(rml_ecl_kill_e), .clk(clk), .q(rml_ecl_kill_m),
347
                    .se(se), .si(), .so());
348
 
349
 
350
   // WTYPE generation
351
   assign rml_ecl_other_d = (rml_ecl_otherwin_d[0] | rml_ecl_otherwin_d[1]
352
                            | rml_ecl_otherwin_d[2]);
353
   dff_s other_d2e(.din(rml_ecl_other_d), .clk(clk), .q(rml_ecl_other_e), .se(se),
354
                 .si(), .so());
355
   mux2ds #(3) wtype_mux(.dout(rml_ecl_wtype_d[2:0]),
356
                          .in0(rml_ecl_wstate_d[2:0]),
357
                          .in1(rml_ecl_wstate_d[5:3]),
358
                          .sel0(~rml_ecl_other_d),
359
                          .sel1(rml_ecl_other_d));
360
   dff_s #(3) wtype_d2e(.din(rml_ecl_wtype_d[2:0]), .clk(clk), .q(rml_ecl_wtype_e[2:0]),
361
                    .se(se), .si(), .so());
362
 
363
 
364
   ////////////////////////////
365
   // Interface with IRF
366
   ////////////////////////////
367
   assign rml_irf_old_lo_cwp_e[2:0] = old_cwp_e[2:0];
368
   assign rml_irf_new_lo_cwp_e[2:0] = new_cwp_e[2:0];
369
   assign rml_irf_old_e_cwp_e[1:0] = (old_cwp_e[0])? old_cwp_e[2:1] + 2'b01: old_cwp_e[2:1];
370
   assign rml_irf_new_e_cwp_e[1:0] = (new_cwp_e[0])? new_cwp_e[2:1] + 2'b01: new_cwp_e[2:1];
371
 
372
   assign rml_irf_swap_local_e = (swap_e | swap_locals_ins);
373
   assign rml_irf_swap_odd_e = ((save_e | ecl_rml_cwp_wen_e | spill_trap_flush | swap_locals_ins) & old_cwp_e[0]) |
374
                                 ((restore_e | swap_outs) & ~old_cwp_e[0]);
375
   assign rml_irf_swap_even_e = ((save_e | ecl_rml_cwp_wen_e | spill_trap_flush | swap_locals_ins) & ~old_cwp_e[0]) |
376
                                  ((restore_e | swap_outs) & old_cwp_e[0]);
377
 
378
   assign swap_e = save_e | restore_e | ecl_rml_cwp_wen_e | spill_trap_flush;
379
   dff_s dff_did_restore_e2m(.din(swap_e), .clk(clk),
380
                       .q(did_restore_m), .se(se),
381
                       .si(), .so());
382
   dff_s dff_did_restore_m2w(.din(did_restore_m), .clk(clk),
383
                       .q(did_restore_w), .se(se),
384
                       .si(), .so());
385
   // kill restore on all saves (except those that spill) and any swaps that
386
   // get kill signals
387
   assign kill_restore_m = (~spill_m & save_m);
388
   dff_s dff_kill_restore_m2w(.din(kill_restore_m), .clk(clk), .q(kill_restore_w),
389
                            .se(se), .si(), .so());
390
   assign rml_irf_kill_restore_w = kill_restore_w | (did_restore_w & rml_kill_w);
391
 
392
 
393
   ///////////////////////////////
394
   // CWP logic
395
   ///////////////////////////////
396
   // Logic to compute next_cwp on spill trap.
397
   //  CWP = CWP + CANSAVE + 2
398
   assign spill_cwp_e[0] = rml_ecl_cwp_e[0] ^ rml_ecl_cansave_e[0];
399
   assign spill_cwp_carry0 = rml_ecl_cwp_e[0] & rml_ecl_cansave_e[0];
400
   assign spill_cwp_e[1] = rml_ecl_cwp_e[1] ^ rml_ecl_cansave_e[1] ^ ~spill_cwp_carry0;
401
   assign spill_cwp_carry1 = (rml_ecl_cwp_e[1] | rml_ecl_cansave_e[1] |
402
                              spill_cwp_carry0) & ~(rml_ecl_cwp_e[1] &
403
                                                    rml_ecl_cansave_e[1] &
404
                                                    spill_cwp_carry0);
405
   assign spill_cwp_e[2] = rml_ecl_cwp_e[2] ^ rml_ecl_cansave_e[2] ^ spill_cwp_carry1;
406
 
407
   assign rml_cwp_wen_e = (save_e | restore_e) & ~exu_tlu_spill_e;
408
   assign cwp_wen_e = (rml_cwp_wen_e | ecl_rml_cwp_wen_e) & ~ecl_rml_kill_e;
409
   sparc_exu_rml_inc3 cwp_inc(.dout(rml_next_cwp_e[2:0]), .din(rml_ecl_cwp_e[2:0]),
410
                                  .inc(save_e));
411
 
412
   assign     next_cwp_sel_inc = ~(ecl_rml_cwp_wen_e | exu_tlu_spill_e);
413
   mux3ds #(3) next_cwp_mux(.dout(next_cwp_e[2:0]),
414
                          .in0(rml_next_cwp_e[2:0]),
415
                          .in1(ecl_rml_xor_data_e[2:0]),
416
                          .in2(spill_cwp_e[2:0]),
417
                          .sel0(next_cwp_sel_inc),
418
                          .sel1(ecl_rml_cwp_wen_e),
419
                          .sel2(exu_tlu_spill_e));
420
 
421
   dff_s cwp_wen_e2m(.din(cwp_wen_e), .clk(clk), .q(rml_cwp_wen_m),
422
                       .se(se), .si(), .so());
423
   dff_s #(3) next_cwp_e2m(.din(next_cwp_e[2:0]), .clk(clk), .q(next_cwp_m[2:0]),
424
                           .se(se), .si(), .so());
425
   assign     cwp_wen_m = rml_cwp_wen_m;
426
   dff_s #(3) next_cwp_m2w(.din(next_cwp_m[2:0]), .clk(clk), .q(next_cwp_noreset_w[2:0]),
427
                         .se(se), .si(), .so());
428
   dff_s cwp_wen_m2w(.din(cwp_wen_m), .clk(clk), .q(cwp_wen_nokill_w),
429
                       .se(se), .si(), .so());
430
   assign cwp_wen_w = cwp_wen_nokill_w & ~rml_kill_w;
431
   assign next_cwp_w[2:0] = next_cwp_noreset_w[2:0];
432
 
433
   assign full_swap_e = (exu_tlu_spill_e | ecl_rml_cwp_wen_e);
434
 
435
 
436
   // oddwin signal for ifu needs bypass from w.  It is done in M and staged for timing.
437
   // This is possible because the thread is switched out so there is only one bypass condition.
438
   // Only save/return will switch in fast enough for a bypass so this is the only write condition
439
   // we need to check
440
   wire [3:0] oddwin_m;
441
   wire [3:0] oddwin_w;
442
   assign     oddwin_m[3] = (cwp_wen_m & ecl_rml_thr_m[3])? next_cwp_m[0]: oddwin_w[3];
443
   assign     oddwin_m[2] = (cwp_wen_m & ecl_rml_thr_m[2])? next_cwp_m[0]: oddwin_w[2];
444
   assign     oddwin_m[1] = (cwp_wen_m & ecl_rml_thr_m[1])? next_cwp_m[0]: oddwin_w[1];
445
   assign     oddwin_m[0] = (cwp_wen_m & ecl_rml_thr_m[0])? next_cwp_m[0]: oddwin_w[0];
446
   dff_s #(4) oddwin_dff(.din(oddwin_m[3:0]), .clk(clk), .q(exu_ifu_oddwin_s[3:0]),
447
                       .se(se), .si(), .so());
448 4 dmitryr
 
449
   integer i;
450
   wire [11:0] next_cwp;
451
   always @(posedge clk)
452
      begin
453
         current_cwp[2:0]<=(cwp_wen_m & ecl_rml_thr_m[0])? next_cwp_m: next_cwp[2:0];
454
         current_cwp[5:3]<=(cwp_wen_m & ecl_rml_thr_m[1])? next_cwp_m: next_cwp[5:3];
455
         current_cwp[8:6]<=(cwp_wen_m & ecl_rml_thr_m[2])? next_cwp_m: next_cwp[8:6];
456
         current_cwp[11:9]<=(cwp_wen_m & ecl_rml_thr_m[3])? next_cwp_m: next_cwp[11:9];
457
      end
458
 
459 2 dmitryr
   sparc_exu_rml_cwp cwp(
460
                         .swap_outs     (swap_outs),
461
                         .swap_locals_ins(swap_locals_ins),
462
                         .rml_ecl_cwp_e (rml_ecl_cwp_e[2:0]),
463
                         .old_cwp_e     (old_cwp_e[2:0]),
464
                         .new_cwp_e     (new_cwp_e[2:0]),
465 4 dmitryr
                         .oddwin_w     (oddwin_w[3:0]),
466
                         .next_cwp     (next_cwp),
467 2 dmitryr
                         /*AUTOINST*/
468
                         // Outputs
469
                         .rml_ecl_cwp_d (rml_ecl_cwp_d[2:0]),
470
                         .exu_tlu_cwp0_w(exu_tlu_cwp0_w[2:0]),
471
                         .exu_tlu_cwp1_w(exu_tlu_cwp1_w[2:0]),
472
                         .exu_tlu_cwp2_w(exu_tlu_cwp2_w[2:0]),
473
                         .exu_tlu_cwp3_w(exu_tlu_cwp3_w[2:0]),
474
                         .rml_irf_cwpswap_tid_e(rml_irf_cwpswap_tid_e[1:0]),
475
                         .exu_tlu_spill (exu_tlu_spill),
476
                         .exu_tlu_spill_wtype(exu_tlu_spill_wtype[2:0]),
477
                         .exu_tlu_spill_other(exu_tlu_spill_other),
478
                         .exu_tlu_spill_tid(exu_tlu_spill_tid[1:0]),
479
                         .rml_ecl_swap_done(rml_ecl_swap_done[3:0]),
480
                         .exu_tlu_cwp_cmplt(exu_tlu_cwp_cmplt),
481
                         .exu_tlu_cwp_cmplt_tid(exu_tlu_cwp_cmplt_tid[1:0]),
482
                         .exu_tlu_cwp_retry(exu_tlu_cwp_retry),
483
                         // Inputs
484
                         .clk           (clk),
485
                         .se            (se),
486
                         .reset         (reset),
487
                         .rst_tri_en    (rst_tri_en),
488
                         .rml_ecl_wtype_e(rml_ecl_wtype_e[2:0]),
489
                         .rml_ecl_other_e(rml_ecl_other_e),
490
                         .exu_tlu_spill_e(exu_tlu_spill_e),
491
                         .tlu_exu_cwpccr_update_m(tlu_exu_cwpccr_update_m),
492
                         .tlu_exu_cwp_retry_m(tlu_exu_cwp_retry_m),
493
                         .tlu_exu_cwp_m (tlu_exu_cwp_m[2:0]),
494
                         .thr_d         (thr_d[3:0]),
495
                         .ecl_rml_thr_m (ecl_rml_thr_m[3:0]),
496
                         .ecl_rml_thr_w (ecl_rml_thr_w[3:0]),
497
                         .tid_e         (tid_e[1:0]),
498
                         .next_cwp_w    (next_cwp_w[2:0]),
499
                         .next_cwp_e    (next_cwp_e[2:0]),
500
                         .cwp_wen_w     (cwp_wen_w),
501
                         .save_e        (save_e),
502
                         .restore_e     (restore_e),
503
                         .ifu_exu_flushw_e(ifu_exu_flushw_e),
504
                         .ecl_rml_cwp_wen_e(ecl_rml_cwp_wen_e),
505
                         .full_swap_e   (full_swap_e),
506
                         .rml_kill_w    (rml_kill_w));
507
 
508
   ///////////////////////////////
509
   // Cansave logic
510
   ///////////////////////////////
511
   assign cansave_wen_e = ((save_e & ~cansave_is0_e & ~rml_ecl_clean_window_e) |
512
                           ifu_exu_saved_e |
513
                           (restore_e & ~canrestore_is0_e) |
514
                           (ifu_exu_restored_e & otherwin_is0_e));
515
   sparc_exu_rml_inc3 cansave_inc(.dout(rml_next_cansave_e[2:0]), .din(rml_ecl_cansave_e[2:0]),
516
                                  .inc(cansave_inc_e));
517
   assign cansave_inc_e = restore_e | ifu_exu_saved_e;
518
 
519
   mux2ds #(3) next_cansave_mux(.dout(next_cansave_e[2:0]),
520
                              .in0(ecl_rml_xor_data_e[2:0]),
521
                              .in1(rml_next_cansave_e[2:0]),
522
                              .sel0(~cansave_wen_e),
523
                              .sel1(cansave_wen_e));
524
   dff_s cansave_wen_e2m(.din(cansave_wen_e), .clk(clk), .q(cansave_wen_m),
525
                       .se(se), .si(), .so());
526
   dff_s #(3) next_cansave_e2m(.din(next_cansave_e[2:0]), .clk(clk), .q(next_cansave_m[2:0]),
527
                           .se(se), .si(), .so());
528
   assign cansave_wen_valid_m = cansave_wen_m;
529
   dff_s cansave_wen_m2w(.din(cansave_wen_valid_m), .clk(clk), .q(rml_cansave_wen_w),
530
                       .se(se), .si(), .so());
531
   dff_s #(3) next_cansave_m2w(.din(next_cansave_m[2:0]), .clk(clk), .q(next_cansave_w[2:0]),
532
                           .se(se), .si(), .so());
533
   assign cansave_wen_w = (rml_cansave_wen_w | ecl_rml_cansave_wen_w) & ~rml_kill_w;
534
 
535
   ///////////////////////////////
536
   // Canrestore logic
537
   ///////////////////////////////
538
   assign canrestore_wen_e = ((save_e & ~cansave_is0_e & ~rml_ecl_clean_window_e) |
539
                              ifu_exu_restored_e |
540
                              (restore_e & ~canrestore_is0_e) |
541
                              (ifu_exu_saved_e & otherwin_is0_e));
542
   sparc_exu_rml_inc3 canrestore_inc(.dout(rml_next_canrestore_e[2:0]),
543
                                     .din(rml_ecl_canrestore_e[2:0]),
544
                                     .inc(canrestore_inc_e));
545
   assign canrestore_inc_e = ifu_exu_restored_e | save_e;
546
 
547
   mux2ds #(3) next_canrestore_mux(.dout(next_canrestore_e[2:0]),
548
                                    .in0(ecl_rml_xor_data_e[2:0]),
549
                                    .in1(rml_next_canrestore_e[2:0]),
550
                                    .sel0(~canrestore_wen_e),
551
                                    .sel1(canrestore_wen_e));
552
   dff_s canrestore_wen_e2m(.din(canrestore_wen_e), .clk(clk), .q(canrestore_wen_m),
553
                       .se(se), .si(), .so());
554
   dff_s #(3) next_canrestore_e2m(.din(next_canrestore_e[2:0]), .clk(clk), .q(next_canrestore_m[2:0]),
555
                           .se(se), .si(), .so());
556
   assign canrestore_wen_valid_m = canrestore_wen_m;
557
   dff_s canrestore_wen_m2w(.din(canrestore_wen_valid_m), .clk(clk), .q(rml_canrestore_wen_w),
558
                       .se(se), .si(), .so());
559
   dff_s #(3) next_canrestore_m2w(.din(next_canrestore_m[2:0]), .clk(clk), .q(next_canrestore_w[2:0]),
560
                           .se(se), .si(), .so());
561
   assign canrestore_wen_w = (rml_canrestore_wen_w | ecl_rml_canrestore_wen_w) & ~rml_kill_w;
562
 
563
   ///////////////////////////////
564
   // Otherwin logic
565
   ///////////////////////////////
566
   // Decrements on saved or restored if otherwin != 0
567
   assign otherwin_wen_e = ((ifu_exu_saved_e | ifu_exu_restored_e)
568
                            & ~otherwin_is0_e);
569
   assign rml_next_otherwin_e[2] = ((rml_ecl_otherwin_e[2] & rml_ecl_otherwin_e[1]) |
570
                                (rml_ecl_otherwin_e[2] & rml_ecl_otherwin_e[0]));
571
   assign rml_next_otherwin_e[1] = rml_ecl_otherwin_e[1] ^ ~rml_ecl_otherwin_e[0];
572
   assign rml_next_otherwin_e[0] = ~rml_ecl_otherwin_e[0];
573
 
574
   mux2ds #(3) next_otherwin_mux(.dout(next_otherwin_e[2:0]),
575
                               .in0(ecl_rml_xor_data_e[2:0]),
576
                               .in1(rml_next_otherwin_e[2:0]),
577
                               .sel0(~otherwin_wen_e),
578
                               .sel1(otherwin_wen_e));
579
   dff_s otherwin_wen_e2m(.din(otherwin_wen_e), .clk(clk), .q(otherwin_wen_m),
580
                       .se(se), .si(), .so());
581
   dff_s #(3) next_otherwin_e2m(.din(next_otherwin_e[2:0]), .clk(clk), .q(next_otherwin_m[2:0]),
582
                           .se(se), .si(), .so());
583
   assign otherwin_wen_valid_m = otherwin_wen_m;
584
   dff_s otherwin_wen_m2w(.din(otherwin_wen_valid_m), .clk(clk), .q(rml_otherwin_wen_w),
585
                       .se(se), .si(), .so());
586
   dff_s #(3) next_otherwin_m2w(.din(next_otherwin_m[2:0]), .clk(clk), .q(next_otherwin_w[2:0]),
587
                           .se(se), .si(), .so());
588
   assign otherwin_wen_w = (rml_otherwin_wen_w | ecl_rml_otherwin_wen_w) & ~rml_kill_w;
589
 
590
   ///////////////////////////////
591
   // Cleanwin logic
592
   ///////////////////////////////
593
   // increments on restored if cleanwin != 7
594
   assign cleanwin_wen_e = (ifu_exu_restored_e &
595
                            ~(rml_ecl_cleanwin_e[2] & rml_ecl_cleanwin_e[1]
596
                              & rml_ecl_cleanwin_e[0]));
597
   assign rml_next_cleanwin_e[2] = ((~rml_ecl_cleanwin_e[2] & rml_ecl_cleanwin_e[1]
598
                                 & rml_ecl_cleanwin_e[0]) | rml_ecl_cleanwin_e[2]);
599
   assign rml_next_cleanwin_e[1] = rml_ecl_cleanwin_e[1] ^ rml_ecl_cleanwin_e[0];
600
   assign rml_next_cleanwin_e[0] = ~rml_ecl_cleanwin_e[0];
601
 
602
   mux2ds #(3) next_cleanwin_mux(.dout(next_cleanwin_e[2:0]),
603
                                  .in0(ecl_rml_xor_data_e[2:0]),
604
                                  .in1(rml_next_cleanwin_e[2:0]),
605
                                  .sel0(~cleanwin_wen_e),
606
                                  .sel1(cleanwin_wen_e));
607
   dff_s cleanwin_wen_e2m(.din(cleanwin_wen_e), .clk(clk), .q(cleanwin_wen_m),
608
                       .se(se), .si(), .so());
609
   dff_s #(3) next_cleanwin_e2m(.din(next_cleanwin_e[2:0]), .clk(clk), .q(next_cleanwin_m[2:0]),
610
                           .se(se), .si(), .so());
611
   assign cleanwin_wen_valid_m = cleanwin_wen_m;
612
   dff_s cleanwin_wen_m2w(.din(cleanwin_wen_valid_m), .clk(clk), .q(rml_cleanwin_wen_w),
613
                       .se(se), .si(), .so());
614
   dff_s #(3) next_cleanwin_m2w(.din(next_cleanwin_m[2:0]), .clk(clk), .q(next_cleanwin_w[2:0]),
615
                           .se(se), .si(), .so());
616
   assign cleanwin_wen_w = (rml_cleanwin_wen_w | ecl_rml_cleanwin_wen_w) & ~rml_kill_w;
617
 
618
   ///////////////////////////////
619
   // WSTATE logic
620
   ///////////////////////////////
621
   assign wstate_wen_w = ecl_rml_wstate_wen_w & ~rml_kill_w;
622
 
623
   ///////////////////////////////
624
   // Storage of other WMRs
625
   ///////////////////////////////
626
   sparc_exu_reg  cansave_reg(.clk(clk), .se(se),
627
                                .data_out(rml_ecl_cansave_d[2:0]), .thr_out(thr_d[3:0]),
628
                                .thr_w(ecl_rml_thr_w[3:0]),
629
                              .wen_w(cansave_wen_w), .data_in_w(next_cansave_w[2:0]));
630
   dff_s #(3) cansave_d2e(.din(rml_ecl_cansave_d[2:0]), .clk(clk), .q(rml_ecl_cansave_e[2:0]), .se(se),
631
                  .si(), .so());
632
   sparc_exu_reg  canrestore_reg(.clk(clk), .se(se),
633
                                   .data_out(rml_ecl_canrestore_d[2:0]), .thr_out(thr_d[3:0]),
634
                                   .thr_w(ecl_rml_thr_w[3:0]),
635
                                   .wen_w(canrestore_wen_w),
636
                                   .data_in_w(next_canrestore_w[2:0]));
637
   dff_s #(3) canrestore_d2e(.din(rml_ecl_canrestore_d[2:0]), .clk(clk), .q(rml_ecl_canrestore_e[2:0]),
638
                         .se(se), .si(), .so());
639
   sparc_exu_reg  otherwin_reg(.clk(clk), .se(se),
640
                                 .data_out(rml_ecl_otherwin_d[2:0]), .thr_out(thr_d[3:0]),
641
                                 .thr_w(ecl_rml_thr_w[3:0]),
642
                                 .wen_w(otherwin_wen_w), .data_in_w(next_otherwin_w[2:0]));
643
   dff_s #(3) otherwin_d2e(.din(rml_ecl_otherwin_d[2:0]), .clk(clk), .q(rml_ecl_otherwin_e[2:0]),
644
                       .se(se), .si(), .so());
645
   sparc_exu_reg  cleanwin_reg(.clk(clk), .se(se),
646
                                 .data_out(rml_ecl_cleanwin_d[2:0]), .thr_out(thr_d[3:0]),
647
                                 .thr_w(ecl_rml_thr_w[3:0]),
648
                                 .wen_w(cleanwin_wen_w), .data_in_w(next_cleanwin_w[2:0]));
649
   dff_s #(3) cleanwin_d2e(.din(rml_ecl_cleanwin_d[2:0]), .clk(clk), .q(rml_ecl_cleanwin_e[2:0]),
650
                       .se(se), .si(), .so());
651
   sparc_exu_reg hi_wstate_reg(.clk(clk), .se(se),
652
                               .data_out(rml_ecl_wstate_d[5:3]), .thr_out(thr_d[3:0]),
653
                               .thr_w(ecl_rml_thr_w[3:0]),
654
                               .wen_w(wstate_wen_w),
655
                               .data_in_w(exu_tlu_wsr_data_w[5:3]));
656
   sparc_exu_reg lo_wstate_reg(.clk(clk), .se(se),
657
                               .data_out(rml_ecl_wstate_d[2:0]), .thr_out(thr_d[3:0]),
658
                               .thr_w(ecl_rml_thr_w[3:0]),
659
                               .wen_w(wstate_wen_w),
660
                               .data_in_w(exu_tlu_wsr_data_w[2:0]));
661
 
662
 
663
   /////////////////////////////////
664
   // Alternate Globals control
665
   //----------------------------
666
   /////////////////////////////////
667
   assign rml_irf_new_agp[1:0] = tlu_exu_agp[1:0];
668
   assign agp_tid[1:0] = tlu_exu_agp_tid[1:0];
669
 
670
`ifdef FPGA_SYN_1THREAD
671
   assign rml_irf_old_agp[1:0] = agp_thr0[1:0];
672
   assign        agp_wen_thr0_w = (agp_thr[0] & agp_wen) | reset;
673
   // mux between new and current value
674
   mux2ds #(2) agp_next0_mux(.dout(agp_thr0_next[1:0]),
675
                               .in0(agp_thr0[1:0]),
676
                               .in1(new_agp[1:0]),
677
                               .sel0(~agp_wen_thr0_w),
678
                               .sel1(agp_wen_thr0_w));
679
   dff_s #(2) dff_agp_thr0(.din(agp_thr0_next[1:0]), .clk(clk), .q(agp_thr0[1:0]),
680
                       .se(se), .si(), .so());
681
   // generation of controls
682
   assign        agp_wen = tlu_exu_agp_swap;
683
   assign        rml_irf_swap_global = agp_wen;
684
   assign        rml_irf_global_tid[1:0] = agp_tid[1:0];
685
 
686
   // decode tids
687
   assign        agp_thr[0] = ~agp_tid[1] & ~agp_tid[0];
688
      // Decode agp input
689
   assign new_agp[1:0] = rml_irf_new_agp[1:0] | {2{reset}};
690
 
691
   // send current global level to ecl for error logging
692
   assign rml_ecl_gl_e[1:0] = agp_thr0[1:0];
693
 
694
`else
695
 
696
   //  Output selection for current agp
697
   mux4ds #(2) mux_agp_out1(.dout(rml_irf_old_agp[1:0]),
698
                            .sel0(agp_thr[0]),
699
                            .sel1(agp_thr[1]),
700
                            .sel2(agp_thr[2]),
701
                            .sel3(agp_thr[3]),
702
                            .in0(agp_thr0[1:0]),
703
                            .in1(agp_thr1[1:0]),
704
                            .in2(agp_thr2[1:0]),
705
                            .in3(agp_thr3[1:0]));
706
 
707
   //////////////////////////////////////
708
   //  Storage of agp
709
   //////////////////////////////////////
710
 
711
   // enable input for each thread
712
   assign        agp_wen_thr0_w = (agp_thr[0] & agp_wen) | reset;
713
   assign        agp_wen_thr1_w = (agp_thr[1] & agp_wen) | reset;
714
   assign        agp_wen_thr2_w = (agp_thr[2] & agp_wen) | reset;
715
   assign        agp_wen_thr3_w = (agp_thr[3] & agp_wen) | reset;
716
 
717
   // mux between new and current value
718
   mux2ds #(2) agp_next0_mux(.dout(agp_thr0_next[1:0]),
719
                               .in0(agp_thr0[1:0]),
720
                               .in1(new_agp[1:0]),
721
                               .sel0(~agp_wen_thr0_w),
722
                               .sel1(agp_wen_thr0_w));
723
   mux2ds #(2) agp_next1_mux(.dout(agp_thr1_next[1:0]),
724
                               .in0(agp_thr1[1:0]),
725
                               .in1(new_agp[1:0]),
726
                               .sel0(~agp_wen_thr1_w),
727
                               .sel1(agp_wen_thr1_w));
728
   mux2ds #(2) agp_next2_mux(.dout(agp_thr2_next[1:0]),
729
                               .in0(agp_thr2[1:0]),
730
                               .in1(new_agp[1:0]),
731
                               .sel0(~agp_wen_thr2_w),
732
                               .sel1(agp_wen_thr2_w));
733
   mux2ds #(2) agp_next3_mux(.dout(agp_thr3_next[1:0]),
734
                               .in0(agp_thr3[1:0]),
735
                               .in1(new_agp[1:0]),
736
                               .sel0(~agp_wen_thr3_w),
737
                               .sel1(agp_wen_thr3_w));
738
 
739
   // store new value
740
   dff_s #(2) dff_agp_thr0(.din(agp_thr0_next[1:0]), .clk(clk), .q(agp_thr0[1:0]),
741
                       .se(se), .si(), .so());
742
   dff_s #(2) dff_agp_thr1(.din(agp_thr1_next[1:0]), .clk(clk), .q(agp_thr1[1:0]),
743
                       .se(se), .si(), .so());
744
   dff_s #(2) dff_agp_thr2(.din(agp_thr2_next[1:0]), .clk(clk), .q(agp_thr2[1:0]),
745
                       .se(se), .si(), .so());
746
   dff_s #(2) dff_agp_thr3(.din(agp_thr3_next[1:0]), .clk(clk), .q(agp_thr3[1:0]),
747
                       .se(se), .si(), .so());
748
 
749
   // generation of controls
750
   assign        agp_wen = tlu_exu_agp_swap;
751
   assign        rml_irf_swap_global = agp_wen;
752
   assign        rml_irf_global_tid[1:0] = agp_tid[1:0];
753
 
754
   // decode tids
755
   assign        agp_thr[0] = ~agp_tid[1] & ~agp_tid[0];
756
   assign        agp_thr[1] = ~agp_tid[1] & agp_tid[0];
757
   assign        agp_thr[2] = agp_tid[1] & ~agp_tid[0];
758
   assign        agp_thr[3] = agp_tid[1] & agp_tid[0];
759
 
760
   // Decode agp input
761
   assign new_agp[1:0] = rml_irf_new_agp[1:0] | {2{reset}};
762
 
763
   // send current global level to ecl for error logging
764
   assign rml_ecl_gl_e[1:0] = ((tid_e[1:0] == 2'b00)? agp_thr0[1:0]:
765
                               (tid_e[1:0] == 2'b01)? agp_thr1[1:0]:
766
                               (tid_e[1:0] == 2'b10)? agp_thr2[1:0]:
767
                                                              agp_thr3[1:0]);
768
`endif // !`ifdef FPGA_SYN_1THREAD
769
 
770
endmodule // sparc_exu_rml

powered by: WebSVN 2.1.0

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