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 2

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

powered by: WebSVN 2.1.0

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