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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [sparc_core/] [lsu_stb_rwctl.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: lsu_stb_rwctl.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
//  Description:  Control for Unified STB CAM/DATA of LSU
29
*/
30
////////////////////////////////////////////////////////////////////////
31
// Global header file includes
32
////////////////////////////////////////////////////////////////////////
33 113 albert.wat
`include  "sys.h" // system level definition file which contains the 
34 95 fafa1971
          // time scale definition
35
 
36 113 albert.wat
`include "iop.h"
37 95 fafa1971
 
38
////////////////////////////////////////////////////////////////////////
39
// Local header file includes / local defines
40
////////////////////////////////////////////////////////////////////////
41
 
42
module lsu_stb_rwctl (/*AUTOARG*/
43
   // Outputs
44
   so, lsu_stbctl_flush_pipe_w, stb_cam_wr_no_ivld_m,
45
   ld_rawp_st_ced_w2, stb_data_wr_ptr, stb_data_wptr_vld,
46
   stb_data_rd_ptr, stb_data_rptr_vld, stb_wdata_ramd_b75_b64,
47
   stb_cam_cm_tid, stb_ldst_byte_msk, stb_ldst_byte_msk_min,
48
   stb_cam_rw_ptr, stb_cam_wptr_vld, stb_cam_rptr_vld,
49
   lsu_st_sz_bhww_m, lsu_st_sz_dw_m, lsu_st_sz_bhw_m,
50
   lsu_st_sz_wdw_m, lsu_st_sz_b_m, lsu_st_sz_w_m, lsu_st_sz_hw_m,
51
   lsu_st_sz_hww_m, ld_rawp_st_ackid_w2, stb_flush_st_g,
52
   stb_cam_wvld_m, lsu_st_rq_type_m, lsu_stb_data_early_sel_e,
53
   lsu_stb_data_final_sel_m, lsu_ldquad_inst_m, stb_thrd_en_g,
54
   flsh_inst_m, lsu_stb_va_m, lsu_stb_empty_buf, lsu_spu_stb_empty,
55
   ifu_tlu_inst_vld_m_bf1, ifu_tlu_inst_vld_m_bf2, lsu_ifu_stbcnt0,
56
   lsu_ifu_stbcnt1, lsu_ifu_stbcnt2, lsu_ifu_stbcnt3,
57
   lsu_ffu_stb_full0, lsu_ffu_stb_full1, lsu_ffu_stb_full2,
58
   lsu_ffu_stb_full3,
59
   // Inputs
60
   rclk, rst_tri_en, si, se, ld_inst_vld_e, ldst_sz_e, st_inst_vld_e,
61
   stb_pcx_rptr0, stb_wrptr0, stb_pcx_rptr1, stb_wrptr1,
62
   stb_pcx_rptr2, stb_wrptr2, stb_pcx_rptr3, stb_wrptr3,
63
   stb_cam_hit_ptr, stb_cam_hit, lsu_ldst_va_m, sta_internal_m,
64
   ifu_tlu_thrid_e, tlu_exu_early_flush_pipe_w, lsu_ttype_vld_m2,
65
   ifu_lsu_flush_w, lsu_defr_trp_taken_g, ifu_lsu_casa_e,
66
   ifu_lsu_ldstub_e, ifu_lsu_swap_e, ifu_lsu_ldst_dbl_e,
67
   stb_state_ced0, stb_state_ced1, stb_state_ced2, stb_state_ced3,
68
   stb_ld_full_raw, stb_ld_partial_raw, stb_wrptr0_prev,
69
   stb_wrptr1_prev, stb_wrptr2_prev, stb_wrptr3_prev,
70
   ifu_lsu_alt_space_e, ifu_lsu_ldst_fp_e, lsu_quad_asi_e,
71
   lsu_st_rmo_m, lsu_bst_in_pipe_m, ffu_lsu_kill_fst_w,
72
   ffu_lsu_blk_st_e, ffu_lsu_blk_st_tid_m, ffu_lsu_blk_st_va_e,
73
   lsu_snap_blk_st_m, tlb_pgnum_b39_g, lsu_stb_empty,
74
   ifu_tlu_flsh_inst_e, stb_cam_mhit, ifu_tlu_inst_vld_m,
75
   lsu_st_pcx_rq_pick, lsu_st_pcx_rq_vld, stb_rdata_ramc_b8t0,
76
   lsu_stbcnt0, lsu_stbcnt1, lsu_stbcnt2, lsu_stbcnt3
77
   ) ;
78
 
79
input     rclk ;
80
//input     grst_l ;   
81
//input     arst_l ;   
82
   input  rst_tri_en;
83
 
84
   input  si;
85
   input  se;
86
   output so;
87
 
88
 
89
input     ld_inst_vld_e ;   // load in pipe.
90
input [1:0]   ldst_sz_e ;   // size of load.
91
input     st_inst_vld_e ;   // store in pipe.
92
// Currently bypass flop make request 
93
//input [3:0]   pcx_rq_for_stb ;  // pcx request rd of dfq - threaded
94
//input [2:0]   stb_dfq_rptr0 ;   // dfq rptr for stb0
95
input [2:0]   stb_pcx_rptr0 ;   // pcx rptr for stb0
96
input [2:0]   stb_wrptr0 ;    // wrt ptr - stb0
97
//input [2:0]   stb_dfq_rptr1 ;   // dfq rptr for stb1
98
input [2:0]   stb_pcx_rptr1 ;   // pcx rptr for stb1
99
input [2:0]   stb_wrptr1 ;    // wrt ptr - stb1
100
//input [2:0]   stb_dfq_rptr2 ;   // dfq rptr for stb2
101
input [2:0]   stb_pcx_rptr2 ;   // pcx rptr for stb2
102
input [2:0]   stb_wrptr2 ;    // wrt ptr - stb2
103
//input [2:0]   stb_dfq_rptr3 ;   // dfq rptr for stb3
104
input [2:0]   stb_pcx_rptr3 ;   // pcx rptr for stb3
105
input [2:0]   stb_wrptr3 ;    // wrt ptr - stb3
106
input [2:0]     stb_cam_hit_ptr ; // entry which hit
107
input     stb_cam_hit ;   // hit has occurred
108
//input [7:0]     stb_state_vld0 ;  // valid bits - stb0
109
//input [7:0]     stb_state_vld1 ;  // valid bits - stb1
110
//input [7:0]     stb_state_vld2 ;  // valid bits - stb2
111
//input [7:0]     stb_state_vld3 ;  // valid bits - stb3
112
input [9:0]    lsu_ldst_va_m ;
113
input     sta_internal_m ;   // internal stxa
114
input [1:0]   ifu_tlu_thrid_e ; // thread-id.
115
 
116
//   output     lsu_stbrwctl_flush_pipe_w ;  // tmp for tso_mon
117
   input      tlu_exu_early_flush_pipe_w;
118
   input      lsu_ttype_vld_m2;
119
 
120
   input      ifu_lsu_flush_w;
121
   input      lsu_defr_trp_taken_g;
122
   output     lsu_stbctl_flush_pipe_w;
123
 
124
 
125
input                   ifu_lsu_casa_e ;        // compare-swap instr
126
input                   ifu_lsu_ldstub_e ;      // ldstub
127
input                   ifu_lsu_swap_e ;        // swap
128
input     ifu_lsu_ldst_dbl_e; // ldst dbl, specifically for stquad.
129
//input   [63:0]          lsu_stb_st_data_g ;     // data to be written to stb
130
input [7:0]   stb_state_ced0 ;
131
input [7:0]   stb_state_ced1 ;
132
input [7:0]   stb_state_ced2 ;
133
input [7:0]   stb_state_ced3 ;
134
input [7:0]   stb_ld_full_raw ;
135
input [7:0]   stb_ld_partial_raw ;
136
input   [2:0]   stb_wrptr0_prev ;
137
input   [2:0]   stb_wrptr1_prev ;
138
input   [2:0]     stb_wrptr2_prev ;
139
input   [2:0]   stb_wrptr3_prev ;
140
input     ifu_lsu_alt_space_e ; // alt_space inst
141
input     ifu_lsu_ldst_fp_e ;
142
//input     tlb_cam_hit ;   // tlb cam hit - mstage
143
input     lsu_quad_asi_e ;  // quad ldst asi
144
//input  [3:0]      lsu_st_ack_rq_stb ;
145
//input     lsu_dtlb_bypass_e ;
146
input   lsu_st_rmo_m ;  // rmo st in m cycle.
147
input   lsu_bst_in_pipe_m ;     // 1st helper for bst.
148
input           ffu_lsu_kill_fst_w ;    // ecc error on st.
149
input           ffu_lsu_blk_st_e ;      // blk st helper signalled by ffu
150
input   [1:0]    ffu_lsu_blk_st_tid_m ;  // blk st tid - from ffu_lsu_data
151
input   [5:3]   ffu_lsu_blk_st_va_e ;   // bits 5:3 of va from increment
152
input           lsu_snap_blk_st_m ;             // snap blk st state
153
input           tlb_pgnum_b39_g ;
154
 
155
input   [3:0]   lsu_stb_empty ;         // thread's stb is empty
156
input           ifu_tlu_flsh_inst_e;
157
input           stb_cam_mhit ;
158
input           ifu_tlu_inst_vld_m ;
159
//input   [3:0]   lsu_st_pcx_rq_kill_w2 ;
160
 
161
input [3:0]   lsu_st_pcx_rq_pick ;
162
 
163
input         lsu_st_pcx_rq_vld ;
164
 
165
input   [8:0]    stb_rdata_ramc_b8t0 ;   // scan-only
166
 
167
output          stb_cam_wr_no_ivld_m ;
168
 
169
//output      ld_rawp_st_ced_g ;
170
output      ld_rawp_st_ced_w2 ;
171
output  [4:0]   stb_data_wr_ptr ; // write ptr - stb data
172
output      stb_data_wptr_vld ; // wr vld for stb data
173
output  [4:0]   stb_data_rd_ptr ; // rd ptr for stb data
174
output      stb_data_rptr_vld ; // rptr vld for stb data
175
output  [75:64]    stb_wdata_ramd_b75_b64 ;  // write data for DATA RAM. 
176
 
177
// partial or full raw required
178
output  [1:0]   stb_cam_cm_tid ;  // cam tid - stb cam
179
//output  [7:0]   stb_cam_sqsh_msk ;  // squash spurious hits
180
//output      stb_cam_vld ;
181
output  [7:0]   stb_ldst_byte_msk ; // byte mask for write/cam
182
output  [7:0]   stb_ldst_byte_msk_min ; // byte mask for write/cam for min path
183
 
184
//output  [3:0]   stb_rd_for_pcx_sel ;    // stb's st selected for read for pcx
185
output  [4:0]   stb_cam_rw_ptr ;        // rw ptr for shared stb cam port
186
output          stb_cam_wptr_vld ;      // wr vld for stb write   
187
output          stb_cam_rptr_vld ;      // rd vld for stb write   
188
 
189
 
190
//output      lsu_stb_pcx_rvld_d1 ; // stb has been read-delayby1cycle
191
//output      lsu_stb_dfq_rvld ;  // wr to dfq stb bypass ff
192
 
193
output                  lsu_st_sz_bhww_m ;      // byte or hword or word
194
output                  lsu_st_sz_dw_m ;        // double word
195
output                  lsu_st_sz_bhw_m ;       // byte or hword
196
output                  lsu_st_sz_wdw_m ;       // word or dword
197
output                  lsu_st_sz_b_m ;         // byte
198
output                  lsu_st_sz_w_m ;         // word
199
output                  lsu_st_sz_hw_m ;        // hword
200
output                  lsu_st_sz_hww_m ;       // hword or word
201
 
202
//output     ld_stb_full_raw_g ;
203
//output     ld_stb_partial_raw_g ;
204
//output  [3:0]   ld_stb_full_raw_g ;
205
//output  [3:0]   ld_stb_partial_raw_g ;
206
 
207
output  [2:0]   ld_rawp_st_ackid_w2 ;
208
 
209
//output  [2:0]   stb_dfq_rd_id ;   // stb entry being read for current thread for current thread
210
 
211
output  [3:0]     stb_flush_st_g ;  // st is flushed in cycle g
212
output  [3:0]     stb_cam_wvld_m ;
213
 
214
output  [2:1]   lsu_st_rq_type_m ;
215
 
216
output  [3:0]   lsu_stb_data_early_sel_e ;// select source of stb data.
217
output      lsu_stb_data_final_sel_m ;// select source of stb data.
218
 
219
output      lsu_ldquad_inst_m ; // stquad inst
220
//output      lsu_stdbl_inst_m ;  // stdbl inst
221
 
222
//output  [1:0]   lsu_stb_rd_tid ;  // thread for which stb read occurs
223
 
224
output  [3:0]    stb_thrd_en_g ; // thread id for current stb access
225
 
226
   output     flsh_inst_m;
227
 
228
   output [9:3] lsu_stb_va_m;
229
 
230
output  [3:0]    lsu_stb_empty_buf ;
231
output  [3:0]    lsu_spu_stb_empty ;
232
 
233
   output     ifu_tlu_inst_vld_m_bf1;
234
   output     ifu_tlu_inst_vld_m_bf2;
235
 
236
   input [3:0] lsu_stbcnt0;
237
   input [3:0] lsu_stbcnt1;
238
   input [3:0] lsu_stbcnt2;
239
   input [3:0] lsu_stbcnt3;
240
 
241
   output [3:0] lsu_ifu_stbcnt0;
242
   output [3:0] lsu_ifu_stbcnt1;
243
   output [3:0] lsu_ifu_stbcnt2;
244
   output [3:0] lsu_ifu_stbcnt3;
245
 
246
   output       lsu_ffu_stb_full0;
247
   output       lsu_ffu_stb_full1;
248
   output       lsu_ffu_stb_full2;
249
   output       lsu_ffu_stb_full3;
250
 
251
/*AUTOWIRE*/
252
// Beginning of automatic wires (for undeclared instantiated-module outputs)
253
// End of automatics
254
// Beginning of automatic wires (for undeclared instantiated-module outputs)
255 113 albert.wat
`ifdef SIMPLY_RISC_TWEAKS
256
wire bst_in_pipe_g;
257
`endif
258 95 fafa1971
// End of automatics
259
//wire  [4:0] stb_dequeue_ptr ;
260
wire  [2:0] stb_wptr_prev ;
261
wire  [1:0] st_thrid_m,st_thrid_g ;
262
wire  [7:0] ld_any_raw_vld ;
263
wire  [7:0] ld_any_raw_vld_d1 ;
264
//wire    ld_raw_mhit ;
265
wire  [2:0] st_rq_type_m,st_rq_type_g ;
266
 
267
wire  [1:0] ldst_sz_m,ldst_sz_g, pipe_ldst_sz_m ;
268
wire    ldst_byte, ldst_hwrd, ldst_word, ldst_dwrd ;
269
wire  [7:0] ldst_byte_mask ;
270
wire  [2:0] stb_wptr ;
271
wire  [1:0] thrid_m,thrid_g ;
272
wire    ld_inst_vld_m, st_inst_vld_m ;
273
 
274
wire    ldst_dbl_m;
275
wire    atomic_m ;
276
wire    ldstub_m ;
277
wire    casa_m, casa_g ;
278
wire    swap_m;
279
wire    flush_st_g ;
280
wire    cam_wptr_vld_g ;
281
wire  [2:0] cam_wptr_d1 ;
282
 
283
wire  [2:0] stb_rdptr0,stb_rdptr1 ;
284
wire  [2:0] stb_rdptr2,stb_rdptr3 ;
285
 
286
//wire  [3:0] stb_rd_mask ;
287
wire  [3:0] stb_select_rptr ;
288
wire  [1:0] stb_rd_thrid ;
289
//wire    cam_vld_g ;
290
wire  [9:0]  ldst_va_m, pipe_ldst_va_m ;
291
wire  [3:0]  ldst_va_g ;
292
wire  [2:0] cam_wr_ptr ;
293
wire  thread0_m, thread1_m, thread2_m, thread3_m ;
294
wire  thread0_g, thread1_g, thread2_g, thread3_g ;
295
wire  [2:0]   ld_rawp_stb_id ;
296
 
297
//wire  rd_for_dfq_granted ;
298
wire  [7:0] stb_state_ced,stb_state_ced_d1 ;
299
//wire    stq_wr_en ;
300
//wire  [3:0] stq_wr_en_g ;
301
//wire  [3:0] stquad_vld ;
302
//wire  [2:0] stquad_ptr0,stquad_ptr1,stquad_ptr2,stquad_ptr3 ;
303
//wire  [3:0] ld_stq_hit_g ;
304
//wire  ldq_hit_g ;
305
//wire  [3:0] ldq_hit_g ;
306
wire  ldst_fp_m;
307
wire  ldstub_e,casa_e,ldst_dbl_e;
308
//wire  stb_data_final_sel_e ;
309
wire  alt_space_e,alt_space_m ;
310
wire  quad_asi_m ;
311
//wire  stquad_e, stquad_m ;
312
wire  stdbl_e ;
313
//wire  dfq_any_rq_for_stb ;
314
//wire  [3:0]   stb_rd_for_dfq ;  // read rq for dfq - threaded
315
wire    blkst_m,blkst_g ;
316
wire    stb_not_empty ;
317
 
318
   wire       clk;
319
   assign     clk = rclk;
320
 
321
//   wire       rst_l;
322
//   wire       stb_rwctl_rst_l;
323
 
324
//   dffrl_async rstff(.din (grst_l),
325
//                     .q   (stb_rwctl_rst_l),
326 113 albert.wat
//                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so(),
327 95 fafa1971
//                     .rst_l (arst_l));
328
 
329
//=========================================================================================
330
//  MISC
331
//=========================================================================================
332
 
333
// Scan-only flops.
334
 
335
wire    [8:0]    stb_rdata_ramc_b8t0_so ;
336 113 albert.wat
dff_s #(9)  scmscan_ff (
337 95 fafa1971
        .din    (stb_rdata_ramc_b8t0[8:0]),
338
        .q      (stb_rdata_ramc_b8t0_so[8:0]),
339
        .clk    (clk),
340 113 albert.wat
        .se   (se),       `SIMPLY_RISC_SCANIN,          .so ()
341 95 fafa1971
        );
342
 
343
//=========================================================================================
344
//  INST_VLD_W GENERATION
345
//=========================================================================================
346
 
347
wire    flush_w_inst_vld_m ;
348
wire    lsu_inst_vld_w ;
349
wire    lsu_stbrwctl_flush_pipe_w;
350
 
351
//=======================================
352
//instaniate buffers
353
//======================================
354
 
355
   wire   ifu_tlu_inst_vld_m_bf0;
356
 
357
bw_u1_buf_10x UZfix_ifu_tlu_inst_vld_m_bf0 ( .a(ifu_tlu_inst_vld_m), .z(ifu_tlu_inst_vld_m_bf0) );
358
bw_u1_buf_30x UZfix_ifu_tlu_inst_vld_m_bf1 ( .a(ifu_tlu_inst_vld_m_bf0), .z(ifu_tlu_inst_vld_m_bf1) );
359
bw_u1_buf_20x UZfix_ifu_tlu_inst_vld_m_bf2 ( .a(ifu_tlu_inst_vld_m_bf0), .z(ifu_tlu_inst_vld_m_bf2) );
360
 
361
assign  flush_w_inst_vld_m =
362
        ifu_tlu_inst_vld_m_bf0 &
363
        ~(lsu_stbrwctl_flush_pipe_w & (thrid_m[1:0] == thrid_g[1:0])) ; // really lsu_flush_pipe_w
364
 
365 113 albert.wat
dff_s  stgw_ivld (
366 95 fafa1971
        .din    (flush_w_inst_vld_m),
367
        .q      (lsu_inst_vld_w),
368
        .clk    (clk),
369 113 albert.wat
        .se   (se),       `SIMPLY_RISC_SCANIN,          .so ()
370 95 fafa1971
        );
371
 
372
   wire other_flush_pipe_w;
373
   wire tlu_early_flush_pipe_w;
374
   assign tlu_early_flush_pipe_w = tlu_exu_early_flush_pipe_w;
375
 
376
assign  other_flush_pipe_w =
377
tlu_early_flush_pipe_w | (lsu_ttype_vld_m2 & lsu_inst_vld_w) |
378
lsu_defr_trp_taken_g ;
379
 
380
   wire lsu_flush_pipe_w;
381
 
382
assign  lsu_flush_pipe_w = other_flush_pipe_w | ifu_lsu_flush_w ;
383
assign  lsu_stbctl_flush_pipe_w = lsu_flush_pipe_w ;
384
assign  lsu_stbrwctl_flush_pipe_w = lsu_flush_pipe_w ;
385
 
386
//=========================================================================================
387
//  STB Array Addr/Ctl Generation
388
//=========================================================================================
389
 
390
assign  ldstub_e = ifu_lsu_ldstub_e ;
391
assign  casa_e   = ifu_lsu_casa_e ;
392
assign  ldst_dbl_e = ifu_lsu_ldst_dbl_e ;
393
 
394
assign  alt_space_e = ifu_lsu_alt_space_e ;
395
 
396
//assign  stdbl_e =  ldst_dbl_e & (~alt_space_e | (alt_space_e & ~lsu_quad_asi_e)) ;
397
assign  stdbl_e =  ldst_dbl_e ;
398
 
399
//   wire lsu_stdbl_inst_m;
400
 
401
//dff  stq_stgm (
402
//  .din  (stdbl_e), 
403
//  .q          (lsu_stdbl_inst_m),  
404
//  .clk  (clk), 
405 113 albert.wat
//  .se (se), `SIMPLY_RISC_SCANIN, .so ()
406 95 fafa1971
//  );
407
 
408
// This path can probably be eased.
409
assign  lsu_stb_data_early_sel_e[0] = ldstub_e  & ~rst_tri_en;
410
assign  lsu_stb_data_early_sel_e[1] = casa_e & ~rst_tri_en;
411
assign  lsu_stb_data_early_sel_e[2] = ~(ldstub_e | casa_e |  stdbl_e) | rst_tri_en;
412
assign  lsu_stb_data_early_sel_e[3] = stdbl_e & ~rst_tri_en ;
413
 
414
// modify for accepting bst data out of pipe.
415
//assign  stb_data_final_sel_e = ~(ldst_fp_e | ffu_lsu_blk_st_e) ;
416
 
417
/*dff  lsel_g (
418
  .din  (stb_data_final_sel_e),
419
  .q  (lsu_stb_data_final_sel_m),
420
  .clk  (clk),
421 113 albert.wat
  .se (se), `SIMPLY_RISC_SCANIN, .so ()
422 95 fafa1971
  );*/
423
 
424
assign  lsu_stb_data_final_sel_m = ~(ldst_fp_m | blkst_m) ;
425
 
426
wire    real_st_m ;
427
wire    flsh_inst_m, flsh_inst_g ;
428
// !!! could qualify st_inst_vld_e with stxa_internal !!!
429 113 albert.wat
dff_s #(13) stgm_vld  (
430 95 fafa1971
  .din  ({ld_inst_vld_e,st_inst_vld_e,ldst_sz_e[1:0],
431
    ifu_lsu_swap_e, ifu_lsu_ldstub_e, ifu_lsu_casa_e,ifu_lsu_ldst_dbl_e,
432
    ifu_tlu_thrid_e[1:0],ifu_lsu_ldst_fp_e,lsu_quad_asi_e,ifu_tlu_flsh_inst_e}),
433
  .q  ({ld_inst_vld_m,real_st_m,pipe_ldst_sz_m[1:0],
434
    swap_m,ldstub_m,casa_m,ldst_dbl_m,thrid_m[1:0],ldst_fp_m,quad_asi_m,flsh_inst_m}),
435
  .clk  (clk),
436 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
437 95 fafa1971
  );
438
 
439
assign  st_inst_vld_m = real_st_m | flsh_inst_m ;
440
 
441
// do we need ld/st unflushed ?
442
   wire sta_internal_g;
443
 
444 113 albert.wat
dff_s #(7) stgw_vld  (
445 95 fafa1971
  .din  ({sta_internal_m,
446
    casa_m, thrid_m[1:0],ldst_sz_m[1:0], flsh_inst_m}),
447
  .q    ({sta_internal_g,
448
    casa_g, thrid_g[1:0],ldst_sz_g[1:0], flsh_inst_g}),
449
  .clk  (clk),
450 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
451 95 fafa1971
  );
452
 
453
 
454
// stb-cam will be written by st at rising edge of g-stage.
455
// However, st can be flushed after write. To keep, the stb state consistent,
456
// The valid and write ptr will not be updated until the rising edge of w2.
457
 
458
wire    early_flush_cond_g,partial_flush_st_g ;
459
assign early_flush_cond_g =
460
(sta_internal_g | ~(lsu_inst_vld_w | blkst_g) | ffu_lsu_kill_fst_w) ;
461
assign  flush_st_g = (early_flush_cond_g | lsu_stbrwctl_flush_pipe_w) & cam_wptr_vld_g ;
462
 
463
//timing, send to stb_ctl and qualified by stb_cam_wvld_g (thread version of cam_wptr_vld_g)   
464
//assign        partial_flush_st_g = early_flush_cond_g & cam_wptr_vld_g ;
465
assign  partial_flush_st_g = early_flush_cond_g ;
466
 
467
assign  atomic_m = (casa_m | ldstub_m | swap_m) & st_inst_vld_m ;
468
 
469
// WRITE PTR VALID GENERATION.
470
 
471
// meant specifically to squash pcx_rq_for_stb.
472
assign  stb_cam_wr_no_ivld_m
473
  = (st_inst_vld_m | casa_m | ldstub_m | swap_m | blkst_m) ;
474
 
475
//bug3610 - kill cam write vld(==stb data write vld next cycle) to avoid datat read and write same cycle
476
//          to the same entry
477
wire  b2b_st_detect ;
478
 
479
assign  stb_cam_wptr_vld
480
  = (((st_inst_vld_m | atomic_m) & ifu_tlu_inst_vld_m_bf0) | blkst_m) & ~(flush_st_g & b2b_st_detect) ;
481
  //= ((st_inst_vld_m | atomic_m) & ifu_tlu_inst_vld_m_bf0) | blkst_m ;  // bug3610
482
  //= (st_inst_vld_m | atomic_m | (ldst_dbl_m & st_inst_vld_m) | blkst_m) ;
483
 
484 113 albert.wat
dff_s  wptr_g (
485 95 fafa1971
  .din  (stb_cam_wptr_vld), .q  (cam_wptr_vld_g),
486
  .clk  (clk),
487 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
488 95 fafa1971
  );
489
 
490
//flop move into mem cell (roll back)  
491
assign  stb_data_wptr_vld = cam_wptr_vld_g ;
492
 
493
// WRITE PTR GENERATION
494
 
495
// It is assumed that if there is a store in the pipe, there is a 
496
// free entry in the corresponding stb. Otherwise, the pipe would've
497
// stalled for the thread.      
498
 
499
// If a store-like inst has been flushed, then the old ptr has to be restored
500
// and used.  This is done within thread specific stb control
501
 
502
assign  thread0_m = ~st_thrid_m[1] & ~st_thrid_m[0] ;
503
assign  thread1_m = ~st_thrid_m[1] &  st_thrid_m[0] ;
504
assign  thread2_m =  st_thrid_m[1] & ~st_thrid_m[0] ;
505
assign  thread3_m =  st_thrid_m[1] &  st_thrid_m[0] ;
506
 
507 113 albert.wat
dff_s #(4) stgg_thrd (
508 95 fafa1971
  .din  ({thread0_m,thread1_m,thread2_m,thread3_m}),
509
  .q  ({thread0_g,thread1_g,thread2_g,thread3_g}),
510
  .clk  (clk),
511 113 albert.wat
  .se (se), `SIMPLY_RISC_SCANIN, .so ()
512 95 fafa1971
  );
513
 
514
assign  stb_thrd_en_g[0] = thread0_g ;
515
assign  stb_thrd_en_g[1] = thread1_g ;
516
assign  stb_thrd_en_g[2] = thread2_g ;
517
assign  stb_thrd_en_g[3] = thread3_g ;
518
 
519
//assign  stb_wptr[2:0] = 
520
//  thread0_m ? stb_wrptr0[2:0] :
521
//    thread1_m ? stb_wrptr1[2:0] :
522
//      thread2_m ? stb_wrptr2[2:0] :
523
//        thread3_m ? stb_wrptr3[2:0] : 3'bxxx ;
524
 
525
assign  stb_wptr[2:0] =
526
  (thread0_m ? stb_wrptr0[2:0] :  3'b000) |
527
  (thread1_m ? stb_wrptr1[2:0] :  3'b000) |
528
  (thread2_m ? stb_wrptr2[2:0] :  3'b000) |
529
  (thread3_m ? stb_wrptr3[2:0] :  3'b000) ;
530
 
531
assign  b2b_st_detect =   // detect back-to-back store
532
  (thread0_m & thread0_g) |
533
  (thread1_m & thread1_g) |
534
  (thread2_m & thread2_g) |
535
  (thread3_m & thread3_g) ;
536
 
537
assign  cam_wr_ptr[2:0] = (flush_st_g & b2b_st_detect) ? cam_wptr_d1[2:0] : stb_wptr[2:0] ;
538
 
539 113 albert.wat
dff_s #(3)  wptr_d1 (
540 95 fafa1971
  .din  (cam_wr_ptr[2:0]),  .q  (cam_wptr_d1[2:0]),
541
  .clk  (clk),
542 113 albert.wat
  .se (se), `SIMPLY_RISC_SCANIN, .so ()
543 95 fafa1971
  );
544
 
545
assign  stb_cam_wvld_m[0] = stb_cam_wptr_vld & thread0_m ;
546
assign  stb_cam_wvld_m[1] = stb_cam_wptr_vld & thread1_m ;
547
assign  stb_cam_wvld_m[2] = stb_cam_wptr_vld & thread2_m ;
548
assign  stb_cam_wvld_m[3] = stb_cam_wptr_vld & thread3_m ;
549
 
550
// contains potential flush conditions.
551
assign  stb_flush_st_g[0] = partial_flush_st_g ;
552
assign  stb_flush_st_g[1] = partial_flush_st_g ;
553
assign  stb_flush_st_g[2] = partial_flush_st_g ;
554
assign  stb_flush_st_g[3] = partial_flush_st_g ;
555
 
556
// stb-data has a delayed write in w2. Alignment of stb data will be done on write
557
// of 64b into stb. This allows write of stb cam and data to be done in the
558
// same cycle, and thus read can occur simultaneously for pcx. 
559
 
560
//mem cell change to bw_r_rf32x80, flop move into mem cell (roll back)
561
//flop outside mem cell
562
assign  stb_data_wr_ptr[4:0] =  {st_thrid_g[1:0],cam_wptr_d1[2:0]};
563
 
564
// RD PTR/VLD GENERATION
565
 
566
// stb read for dfq dumps data into a bypass flop. Thus a read for the dfq can occur
567
// if a thread's stb has an acked entry and the bypass flop is empty.
568
// stb read for pcx occurs on availability of queue entry. 
569
 
570
// Both dfq and pcx require a read of the cam and data. The reads
571
// can thus not happen when load that hits in the stb is in the w2 (change to W3)
572
// stage and a store is in the g-stage of the pipe. Both
573
// probabilities are low.
574
 
575
// ??Read for pcx takes priority over dfq. No deadlock can occur
576
// ??as at some point the pcx reads will be exhausted and the stb
577
// ??will have to drain itself. The stb is self-regulating in this regard.
578
 
579
// priority of stb read: ld_cam_hit (full raw bypass) > dfq > pcx 
580
 
581
//====================================================================================
582
//raw bypass timing 
583
//G/WB                          W2     W3                      W4
584
//cam_hit(from stb_cam output)  flop   stb_data rd_ptr/rd_vld  read STB_DATA/BYP
585
//====================================================================================
586
 
587
   wire [1:0] thrid_w2;
588
   wire [2:0] stb_cam_hit_ptr_w2;
589
   wire       stb_cam_hit_w2;
590
   wire       stb_cam_hit_w;
591
 
592
   //bug3503
593
   assign stb_cam_hit_w  =  stb_cam_hit & lsu_inst_vld_w & ~lsu_stbrwctl_flush_pipe_w;
594
 
595 113 albert.wat
dff_s #(6) stb_cam_hit_stg_w2 (
596 95 fafa1971
  .din  ({thrid_g[1:0],  stb_cam_hit_ptr[2:0],    stb_cam_hit_w   }),
597
  .q    ({thrid_w2[1:0], stb_cam_hit_ptr_w2[2:0], stb_cam_hit_w2}),
598
  .clk  (clk),
599 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
600 95 fafa1971
  );
601
 
602
// logic moved to qctl1
603
// pcx is making request for data in current cycle. Can be multi-hot.
604
//assign  pcx_any_rq_for_stb = |pcx_rq_for_stb[3:0] ;
605
//assign  pcx_any_rq_for_stb = 
606
//      (pcx_rq_for_stb[0] & ~lsu_st_pcx_rq_kill_w2[0]) | 
607
//      (pcx_rq_for_stb[1] & ~lsu_st_pcx_rq_kill_w2[1]) | 
608
//      (pcx_rq_for_stb[2] & ~lsu_st_pcx_rq_kill_w2[2]) | 
609
//      (pcx_rq_for_stb[3] & ~lsu_st_pcx_rq_kill_w2[3]) ; 
610
 
611
// ??ld-cam hit based read takes precedence
612
// ??Timing : This could be made pessimistic by using ld_inst_vld_g
613
 
614
//assign  stb_select_rptr[3:0] =  pcx_rq_for_stb[3:0] ;  // timing fix
615
assign  stb_select_rptr[3:0] =  lsu_st_pcx_rq_pick[3:0] ;
616
 
617
// This could be a critical path. Be careful !
618
//assign  stb_rdptr0[2:0] = ~dfq_any_rq_for_stb ? stb_pcx_rptr0[2:0] : stb_dfq_rptr0[2:0] ; 
619
assign  stb_rdptr0[2:0] = stb_pcx_rptr0[2:0] ;
620
assign  stb_rdptr1[2:0] = stb_pcx_rptr1[2:0] ;
621
assign  stb_rdptr2[2:0] = stb_pcx_rptr2[2:0] ;
622
assign  stb_rdptr3[2:0] = stb_pcx_rptr3[2:0] ;
623
 
624
// logic moved to qctl1
625
//wire  [1:0] stb_rd_tid ;
626
//
627
//assign  stb_rd_tid[0] = pcx_rq_for_stb[1] | pcx_rq_for_stb[3] ;
628
//assign  stb_rd_tid[1] = pcx_rq_for_stb[2] | pcx_rq_for_stb[3] ;
629
//   
630
//dff #(2) stbtid_stgd1 (
631
//  .din    (stb_rd_tid[1:0]),  .q  (lsu_stb_rd_tid[1:0]),
632
//  .clk    (clk), 
633 113 albert.wat
//  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
634 95 fafa1971
//  );
635
 
636
//assign  stb_dfq_rd_id[2:0] = stb_data_rd_ptr[2:0] ; // or cam rd ptr
637
 
638
//timing fix:5/6/03
639
//bug4988 - change the prirority from 0->3 to 3->0; the reason is when select_rptr=0, the
640
//          default thread id(rptr[4:3])=thread0 but the default rptr[2:0]=thread3. If
641
//          thread0 and thread3 rptr are the same and the thread0 write is occuring, the
642
//          rptr[4:0] is same as wptr[4:0]
643
wire  [2:0]  stb_rdptr ;
644
//assign  stb_rdptr[2:0] = 
645
//  stb_select_rptr[0] ? stb_rdptr0[2:0] :
646
//    stb_select_rptr[1] ? stb_rdptr1[2:0] :
647
//      stb_select_rptr[2] ? stb_rdptr2[2:0] :
648
//                             stb_rdptr3[2:0] ;
649
 
650
//assign  stb_rdptr[2:0] = 
651
//  stb_select_rptr[3] ? stb_rdptr3[2:0] :
652
//    stb_select_rptr[2] ? stb_rdptr2[2:0] :
653
//      stb_select_rptr[1] ? stb_rdptr1[2:0] :
654
//                             stb_rdptr0[2:0] ;
655
 
656
assign  stb_rdptr[2:0] =
657
  (stb_select_rptr[3] ? stb_rdptr3[2:0] : 3'b0) |
658
  (stb_select_rptr[2] ? stb_rdptr2[2:0] : 3'b0) |
659
  (stb_select_rptr[1] ? stb_rdptr1[2:0] : 3'b0) |
660
  (stb_select_rptr[0] ? stb_rdptr0[2:0] : 3'b0) ;
661
 
662
//timing fix: 8/29/03 - remove the default select logic for stb_select_rptr since synthesis is forced to replace 
663
//            4to1 mux w/ and-or mux or 2to1 mux
664
//wire   stb_select_rptr_b3;
665
//assign stb_select_rptr_b3 =  ~|stb_select_rptr[2:0];
666
 
667
wire  [2:0]  stb_rdptr_l;
668
 
669
assign stb_rdptr_l[2:0] =  ~stb_rdptr[2:0] ;
670
//bw_u1_muxi41d_2x  UZsize_stb_rdptr_b0_mux(
671
//                  .z(stb_rdptr_l[0]), 
672
//                  .d0(stb_rdptr0[0]), 
673
//                  .d1(stb_rdptr1[0]), 
674
//                  .d2(stb_rdptr2[0]), 
675
//                  .d3(stb_rdptr3[0]), 
676
//                  .s0(stb_select_rptr[0]), 
677
//                  .s1(stb_select_rptr[1]), 
678
//                  .s2(stb_select_rptr[2]), 
679
//                  .s3(stb_select_rptr[3]));
680
//   
681
//bw_u1_muxi41d_2x  UZsize_stb_rdptr_b1_mux(
682
//                  .z(stb_rdptr_l[1]), 
683
//                  .d0(stb_rdptr0[1]), 
684
//                  .d1(stb_rdptr1[1]), 
685
//                  .d2(stb_rdptr2[1]), 
686
//                  .d3(stb_rdptr3[1]), 
687
//                  .s0(stb_select_rptr[0]), 
688
//                  .s1(stb_select_rptr[1]), 
689
//                  .s2(stb_select_rptr[2]), 
690
//                  .s3(stb_select_rptr[3]));
691
//   
692
//bw_u1_muxi41d_2x  UZsize_stb_rdptr_b2_mux(
693
//                  .z(stb_rdptr_l[2]), 
694
//                  .d0(stb_rdptr0[2]), 
695
//                  .d1(stb_rdptr1[2]), 
696
//                  .d2(stb_rdptr2[2]), 
697
//                  .d3(stb_rdptr3[2]), 
698
//                  .s0(stb_select_rptr[0]), 
699
//                  .s1(stb_select_rptr[1]), 
700
//                  .s2(stb_select_rptr[2]), 
701
//                  .s3(stb_select_rptr[3]));
702
//   
703
 
704
assign  stb_rd_thrid[0] = stb_select_rptr[1] | stb_select_rptr[3] ;
705
assign  stb_rd_thrid[1] = stb_select_rptr[2] | stb_select_rptr[3] ;
706
 
707
// read
708
// this mux will have to be accommodated in path !!! Talk to Satya. 
709
// Timing : This could be made pessimistic by using ld_inst_vld_g
710
 
711
// raw read STB at W3 (changed from W2)        
712
assign  stb_data_rd_ptr[4:0] = stb_cam_hit_w2 ?
713
        {thrid_w2[1:0],stb_cam_hit_ptr_w2[2:0]} :  // rd based on ld hit
714
        {stb_rd_thrid[1:0],~stb_rdptr_l[2:0]} ;       // rd for pcx or dfq
715
 
716
// Blk-st modification for thread.
717
assign  st_thrid_m[1:0] = blkst_m ? ffu_lsu_blk_st_tid_m[1:0] : thrid_m[1:0] ;
718 113 albert.wat
dff_s #(2)  stid_stgg (
719 95 fafa1971
  .din  (st_thrid_m[1:0]),
720
  .q    (st_thrid_g[1:0]),
721
  .clk  (clk),
722 113 albert.wat
  .se (se), `SIMPLY_RISC_SCANIN, .so ()
723 95 fafa1971
  );
724
 
725
//timing fix: 5/6/03
726
//assign  stb_cam_rw_ptr[4:0]  = stb_cam_wptr_vld ? 
727
//        {st_thrid_m[1:0],cam_wr_ptr[2:0]} :  // write
728
//        {stb_rd_thrid[1:0],stb_rdptr[2:0]} ;  // read
729
 
730
wire [2:0] cam_wr_ptr_l;
731
wire [1:0] stb_rd_thrid_l;
732
wire [1:0] st_thrid_m_l;
733
 
734
assign cam_wr_ptr_l[2:0]  =  ~cam_wr_ptr[2:0];
735
assign stb_rd_thrid_l[1:0]  =  ~stb_rd_thrid[1:0];
736
assign st_thrid_m_l[1:0]  =  ~st_thrid_m[1:0];
737
 
738
bw_u1_muxi21_2x  UZsize_stb_cam_rw_ptr_b0_mux(
739
                  .z(stb_cam_rw_ptr[0]),
740
                  .d0(stb_rdptr_l[0]),
741
                  .d1(cam_wr_ptr_l[0]),
742
                  .s(stb_cam_wptr_vld));
743
 
744
bw_u1_muxi21_2x  UZsize_stb_cam_rw_ptr_b1_mux(
745
                  .z(stb_cam_rw_ptr[1]),
746
                  .d0(stb_rdptr_l[1]),
747
                  .d1(cam_wr_ptr_l[1]),
748
                  .s(stb_cam_wptr_vld));
749
 
750
bw_u1_muxi21_2x  UZsize_stb_cam_rw_ptr_b2_mux(
751
                  .z(stb_cam_rw_ptr[2]),
752
                  .d0(stb_rdptr_l[2]),
753
                  .d1(cam_wr_ptr_l[2]),
754
                  .s(stb_cam_wptr_vld));
755
 
756
bw_u1_muxi21_2x  UZsize_stb_cam_rw_ptr_b3_mux(
757
                  .z(stb_cam_rw_ptr[3]),
758
                  .d0(stb_rd_thrid_l[0]),
759
                  .d1(st_thrid_m_l[0]),
760
                  .s(stb_cam_wptr_vld));
761
 
762
bw_u1_muxi21_2x  UZsize_stb_cam_rw_ptr_b4_mux(
763
                  .z(stb_cam_rw_ptr[4]),
764
                  .d0(stb_rd_thrid_l[1]),
765
                  .d1(st_thrid_m_l[1]),
766
                  .s(stb_cam_wptr_vld));
767
 
768
 
769
 
770
//raw read STB at W3 (not W2)
771
//timing fix: 9/2/03 - reduce fanout in stb_rwctl for lsu_st_pcx_rq_pick - gen separate signal for
772
//                     stb_cam_rptr_vld and stb_data_rptr_vld
773
 
774
//bug4988 - qual lsu_st_pcx_rq_vld w/ no write vld to stb_data. use stb_cam_wr_no_ivld_m instead of write vld.
775
//          this is the same signal used to kill pcx_rq_for_stb
776
//          stb_cam_rptr_vld is not set if stb_cam_wptr_vld=1
777
 
778
assign  stb_data_rptr_vld =
779
  //(|stb_select_rptr[3:0]) |  // pcx/dfq rd - timing fix
780
  //lsu_st_pcx_rq_vld |  // pcx/dfq rd  // bug4988
781
   (lsu_st_pcx_rq_vld & ~stb_cam_wr_no_ivld_m) |  // pcx/dfq rd
782
    stb_cam_hit_w2 ;         // cam hit requires read whether single or multiple
783
 
784
//raw read STB at W3 (not W2)      
785
//timing fix: 9/2/03 - reduce fanout in stb_rwctl for lsu_st_pcx_rq_pick - gen separate signal for
786
//                     stb_cam_rptr_vld and stb_data_rptr_vld
787
assign  stb_cam_rptr_vld =
788
  //((|stb_select_rptr[3:0]) & ~(stb_cam_hit_w2)) & // only pcx read  - timing fix
789
  (lsu_st_pcx_rq_vld & ~(stb_cam_hit_w2)) & // only pcx read 
790
      ~stb_cam_wptr_vld ;   // st,st-like write does not block
791
 
792
// lsu_stb_rd_vld_d1 - not used
793
//dff  stbrd_stgd1  (
794
//  .din    (stb_cam_rptr_vld), .q  (lsu_stb_rd_vld_d1),
795
//  .clk    (clk), 
796 113 albert.wat
//  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
797 95 fafa1971
//  );
798
 
799
// logic moved to qctl1
800
//dff #(1)  prvld_stgd1 (
801
//  .din  (pcx_any_rq_for_stb), 
802
//  .q  (lsu_stb_pcx_rvld_d1),
803
//  .clk  (clk), 
804 113 albert.wat
//  .se (se), `SIMPLY_RISC_SCANIN, .so ()
805 95 fafa1971
//  );
806
 
807
assign  stb_cam_cm_tid[1:0] = thrid_m[1:0] ;
808
 
809
 
810
//=========================================================================================
811
//  BYTE MASK FORMATTING
812
//=========================================================================================
813
 
814
 
815
// Write/CAM Data for CAM RAM.
816
// Physical dword aligned addr - PA[39:3] (37b)
817
// Byte Mask - (8b)
818
// Total - 45b
819
 
820
//  | b7  |  b6 | b5  | b4  | b3  | b2  | b1  | b0  |
821
//  |   hw3 |   hw2 |   hw1 |   hw0 |
822
//  |     w1    |   w0    |
823
//  |       dw        | 
824
 
825
 
826
 
827
//dff  #(11) va_m (
828
//  .din    (exu_lsu_ldst_va_e[10:0]),  .q  (pipe_ldst_va_m[10:0]),
829
//  .clk    (clk), 
830 113 albert.wat
//  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
831 95 fafa1971
//  );
832
 
833
assign pipe_ldst_va_m[9:0] = lsu_ldst_va_m[9:0];
834
 
835
// ldst_byte may not be needed
836
assign ldst_byte = ~ldst_sz_m[1] & ~ldst_sz_m[0] ;  // 00
837
assign ldst_hwrd = ~ldst_sz_m[1] &  ldst_sz_m[0] ;  // 01
838
assign ldst_word =  ldst_sz_m[1] & ~ldst_sz_m[0] ;  // 10
839
assign ldst_dwrd =  ldst_sz_m[1] &  ldst_sz_m[0] ;  // 11
840
 
841
// Note : dword term is common. 
842
assign ldst_byte_mask[0]  =
843
  ( ldst_va_m[2] &  ldst_va_m[1] &  ldst_va_m[0] )       |
844
  ( ldst_va_m[2] &  ldst_va_m[1] & ~ldst_va_m[0] & (ldst_hwrd)) |
845
  ( ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_word))  |
846
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd))  ;
847
assign ldst_byte_mask[1]  =
848
  ( ldst_va_m[2] &  ldst_va_m[1] & ~ldst_va_m[0])        |
849
  ( ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_word))  |
850
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd))  ;
851
assign ldst_byte_mask[2]  =
852
  ( ldst_va_m[2] & ~ldst_va_m[1] &  ldst_va_m[0])         |
853
  ( ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_hwrd | ldst_word))  |
854
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd))  ;
855
assign ldst_byte_mask[3]  =
856
  ( ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0])       |
857
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd))  ;
858
assign ldst_byte_mask[4]  =
859
  (~ldst_va_m[2] &  ldst_va_m[1] &  ldst_va_m[0])        |
860
  (~ldst_va_m[2] &  ldst_va_m[1] & ~ldst_va_m[0] & (ldst_hwrd)) |
861
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd | ldst_word)) ;
862
assign ldst_byte_mask[5]  =
863
  (~ldst_va_m[2] &  ldst_va_m[1] & ~ldst_va_m[0])         |
864
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] &  (ldst_dwrd | ldst_word))  ;
865
assign ldst_byte_mask[6]  =
866
  (~ldst_va_m[2] & ~ldst_va_m[1] &  ldst_va_m[0])     |
867
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0] & (ldst_dwrd | ldst_word | ldst_hwrd)) ;
868
assign ldst_byte_mask[7]  =
869
  (~ldst_va_m[2] & ~ldst_va_m[1] & ~ldst_va_m[0])   ;
870
 
871
assign  stb_ldst_byte_msk[7:0]  = ldst_byte_mask[7:0];
872
 
873
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b0 (.a(ldst_byte_mask[0]), .z(stb_ldst_byte_msk_min[0]));
874
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b1 (.a(ldst_byte_mask[1]), .z(stb_ldst_byte_msk_min[1]));
875
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b2 (.a(ldst_byte_mask[2]), .z(stb_ldst_byte_msk_min[2]));
876
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b3 (.a(ldst_byte_mask[3]), .z(stb_ldst_byte_msk_min[3]));
877
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b4 (.a(ldst_byte_mask[4]), .z(stb_ldst_byte_msk_min[4]));
878
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b5 (.a(ldst_byte_mask[5]), .z(stb_ldst_byte_msk_min[5]));
879
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b6 (.a(ldst_byte_mask[6]), .z(stb_ldst_byte_msk_min[6]));
880
   bw_u1_minbuf_5x UZfix_stb_ldst_byte_msk_min_b7 (.a(ldst_byte_mask[7]), .z(stb_ldst_byte_msk_min[7]));
881
 
882
 
883
// Generate selects to format st data
884
assign  lsu_st_sz_bhww_m = ldst_byte | ldst_hwrd | ldst_word ;      // byte or hword or word
885
assign  lsu_st_sz_dw_m   = ldst_dwrd ;            // double word
886
assign  lsu_st_sz_bhw_m  = ldst_byte | ldst_hwrd ;      // byte or hword
887
assign  lsu_st_sz_wdw_m  = ldst_word | ldst_dwrd ;      // word or dword
888
assign  lsu_st_sz_b_m    = ldst_byte ;            // byte
889
assign  lsu_st_sz_w_m    = ldst_word ;            // word
890
assign  lsu_st_sz_hw_m   = ldst_hwrd ;            // hword
891
assign  lsu_st_sz_hww_m  = ldst_hwrd | ldst_word ;      // hword or word
892
 
893
//=========================================================================================
894
//  BLK-ST HANDLING
895
//=========================================================================================
896
 
897
wire    blkst_m_tmp ;
898 113 albert.wat
dff_s  stgm_bst (
899 95 fafa1971
  .din (ffu_lsu_blk_st_e),
900
  .q   (blkst_m_tmp),
901
  .clk (clk),
902 113 albert.wat
  .se   (se),       `SIMPLY_RISC_SCANIN,          .so ()
903 95 fafa1971
);
904
 
905
assign  blkst_m = blkst_m_tmp & ~(real_st_m  | flsh_inst_m |
906
                ld_inst_vld_m) ; // Bug 3444
907
 
908 113 albert.wat
dff_s  stgg_bst (
909 95 fafa1971
  .din (blkst_m),
910
  .q   (blkst_g),
911
  .clk (clk),
912 113 albert.wat
  .se   (se),       `SIMPLY_RISC_SCANIN,          .so ()
913 95 fafa1971
);
914
 
915
wire    snap_blk_st_local_m ;
916
assign  snap_blk_st_local_m = lsu_snap_blk_st_m & ifu_tlu_inst_vld_m_bf0 ;
917
 
918
wire    [1:0]    bst_sz_m ;
919
wire    [9:0]    bst_va_m ;
920
// output to be used in m-stage.
921 113 albert.wat
dffe_s #(9) bst_state_m (
922 95 fafa1971
        .din    ({ldst_sz_m[1:0],ldst_va_m[9:6],ldst_va_m[2:0]}),
923
        .q      ({bst_sz_m[1:0],bst_va_m[9:6],bst_va_m[2:0]}),
924
        .en     (snap_blk_st_local_m),
925
        .clk    (clk),
926 113 albert.wat
        .se   (se),       `SIMPLY_RISC_SCANIN,          .so ()
927 95 fafa1971
        );
928
 
929 113 albert.wat
dff_s #(3)  bsva_stgm (
930 95 fafa1971
  .din    (ffu_lsu_blk_st_va_e[5:3]), .q (bst_va_m[5:3]),
931
  .clk    (clk),
932 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
933 95 fafa1971
  );
934
 
935
//assign        bst_va_m[5:3]   = ffu_lsu_blk_st_va_e[5:3] ;
936
 
937
//assign  ldst_va_m[10] =  pipe_ldst_va_m[10] ;
938
assign  ldst_va_m[9:0] = blkst_m ?  bst_va_m[9:0] : pipe_ldst_va_m[9:0] ;
939
 
940
assign  lsu_stb_va_m[9:3] = ldst_va_m[9:3] ;
941
 
942
assign  ldst_sz_m[1:0]   =  blkst_m ? bst_sz_m[1:0] : pipe_ldst_sz_m[1:0] ;
943
 
944
//=========================================================================================
945
//  WRITE DATA FOR DATA RAM
946
//=========================================================================================
947
 
948
// Write Data for DATA RAM.
949
// Data - (64b)
950
// (8b parity is generated on read)
951
// Rqtype - (3b)
952
// Size - (3b). 
953
// Addr - (3b). Lower 3b of 40b addr.
954
// (set index and way available from ctl state.
955
// Total - 73b.
956
 
957
// st-quad requires own encoding.
958
// assume does not have to be changed for blk-st
959
assign  st_rq_type_m[2:0] =
960
                casa_m ? 3'b010 :                       // cas pkt 1
961
                        (ldstub_m | swap_m) ? 3'b110 :  // ldstub/swap
962
                          //(stquad_m)  ? 3'b111 :  // stquad-pkt1
963
                                  3'b001 ;        // normal store or partial interrupt rq type
964
 
965
//assign  lsu_st_rq_type_m[2:0] = st_rq_type_m[2:0] ;
966
assign  lsu_st_rq_type_m[2:1] = st_rq_type_m[2:1] ;
967
 
968
// Need ASI decode
969
/*wire  lsu_stquad_inst_m ;
970
assign  lsu_stquad_inst_m = ldst_dbl_m & st_inst_vld_m & quad_asi_m ;
971
*/
972
 
973
wire    st_rmo_m,st_rmo_g ;
974
assign  st_rmo_m = lsu_st_rmo_m | blkst_m ; // binit and blk rmo stores.
975 113 albert.wat
dff_s #(9)  stgg_etc  (
976 95 fafa1971
  .din    ({ldst_va_m[3:0],st_rq_type_m[2:0],st_rmo_m,lsu_bst_in_pipe_m}),
977
  .q      ({ldst_va_g[3:0],st_rq_type_g[2:0],st_rmo_g,bst_in_pipe_g}),
978
  .clk    (clk),
979 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
980 95 fafa1971
  );
981
 
982
wire    bst_any_helper ;
983
assign  bst_any_helper = blkst_g | bst_in_pipe_g ; // Bug 3934
984
 
985
// Size will have to be changed to 2bits.
986
// 7 more bits could be added to data ram to save read of cam in providing dfq pkt !!! 
987
assign stb_wdata_ramd_b75_b64[75:64]   =
988
  {st_rmo_g,st_rq_type_g[2:0],flsh_inst_g,bst_any_helper,ldst_sz_g[1:0],ldst_va_g[3:0]};
989
        // Bug3395, 3934
990
 
991
//=========================================================================================
992
//  FULL/PARTIAL RAW CALCULATION
993
//=========================================================================================
994
 
995
// io load cannot bypass from stb. A stb hit results in an io-ld being treated
996
// as a partial-raw. (OR should it be serialized behind any io store ??)
997
wire    io_ld,io_ld_w2 ;
998
assign  io_ld = tlb_pgnum_b39_g ; // Bug 4362
999
 
1000
// full-raw is squashed on multiple hits in stb. Treated like partial raw.
1001
// Ensure that all ld and ld-like instructions signal ld_inst_vld. We can then
1002
// remove qualification with ld_inst_vld_g.
1003
/*assign  ld_stb_full_raw_g =
1004
        (|stb_ld_full_raw[7:0]) & ~(stb_cam_mhit | ldq_hit_g | io_ld) ;
1005
assign  ld_stb_full_raw_g[0] = (|stb_ld_full_raw[7:0]) & ld_inst_vld_g &
1006
          ~(stb_cam_mhit | ldq_hit_g[0] | io_ld) & thread0_g ;
1007
          //~(ld_raw_mhit | ld_stq_hit_g[0] | io_ld) & thread0_g ;
1008
assign  ld_stb_full_raw_g[1] = (|stb_ld_full_raw[7:0]) & ld_inst_vld_g &
1009
          ~(stb_cam_mhit | ldq_hit_g[1] | io_ld) & thread1_g ;
1010
assign  ld_stb_full_raw_g[2] = (|stb_ld_full_raw[7:0]) & ld_inst_vld_g &
1011
          ~(stb_cam_mhit | ldq_hit_g[2] | io_ld) & thread2_g ;
1012
assign  ld_stb_full_raw_g[3] = (|stb_ld_full_raw[7:0]) & ld_inst_vld_g &
1013
          ~(stb_cam_mhit | ldq_hit_g[3] | io_ld) & thread3_g ; */
1014
// Multiple full raws are also treated like a partial.
1015
/*assign  ld_stb_partial_raw_g =
1016
        ((|stb_ld_partial_raw[7:0]) | stb_cam_mhit | ldq_hit_g | (io_ld & stb_not_empty)) ;
1017
assign  ld_stb_partial_raw_g[0] =
1018
        ((|stb_ld_partial_raw[7:0]) | stb_cam_mhit | ldq_hit_g[0] | (io_ld & stb_not_empty))
1019
          & ld_inst_vld_g & thread0_g ;
1020
assign  ld_stb_partial_raw_g[1] =
1021
        ((|stb_ld_partial_raw[7:0]) | stb_cam_mhit | ldq_hit_g[1] | (io_ld & stb_not_empty))
1022
          & ld_inst_vld_g & thread1_g ;
1023
assign  ld_stb_partial_raw_g[2] =
1024
        ((|stb_ld_partial_raw[7:0]) | stb_cam_mhit | ldq_hit_g[2] | (io_ld & stb_not_empty))
1025
          & ld_inst_vld_g & thread2_g ;
1026
assign  ld_stb_partial_raw_g[3] =
1027
        ((|stb_ld_partial_raw[7:0]) | stb_cam_mhit | ldq_hit_g[3] | (io_ld & stb_not_empty))
1028
          & ld_inst_vld_g & thread3_g; */
1029
 
1030
//=========================================================================================
1031
//  STQ HANDLING
1032
//=========================================================================================
1033
 
1034
/*      REMOVE STQUAD */
1035
 
1036
//=========================================================================================
1037
//      LD QUAD HANDLING
1038
//=========================================================================================
1039
 
1040 113 albert.wat
dff_s  altsp_stgm (
1041 95 fafa1971
  .din    (alt_space_e), .q (alt_space_m),
1042
  .clk    (clk),
1043 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
1044 95 fafa1971
  );
1045
 
1046
assign  lsu_ldquad_inst_m = ldst_dbl_m & ld_inst_vld_m & quad_asi_m & alt_space_m ;
1047
 
1048
/*wire  ldquad_inst_g ;
1049 113 albert.wat
dff_s  ldq_stgg (
1050 95 fafa1971
  .din    (lsu_ldquad_inst_m), .q (ldquad_inst_g),
1051
  .clk    (clk),
1052 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
1053 95 fafa1971
  );
1054
 
1055
wire    ldq_stb_cam_hit ;
1056
assign  ldq_stb_cam_hit = stb_cam_hit & ldquad_inst_g ;
1057
// Terms can be made common.
1058
assign  ldq_hit_g = ldq_stb_cam_hit ; */
1059
/*assign  ldq_hit_g[0] = thread0_g & ldq_stb_cam_hit ;
1060
assign  ldq_hit_g[1] = thread1_g & ldq_stb_cam_hit ;
1061
assign  ldq_hit_g[2] = thread2_g & ldq_stb_cam_hit ;
1062
assign  ldq_hit_g[3] = thread3_g & ldq_stb_cam_hit ; */
1063
 
1064
//=========================================================================================
1065
//  STB MULTIPLE HIT GENERATION
1066
//=========================================================================================
1067
 
1068
// Multiple hits in stb is to be treated as a partial raw case. The ld however must wait
1069
// until the youngest store which hit exits the stb. A ptr needs to be calculated for this case.
1070
// A version of stb_wptr is used instead because it is easily available. (Would this have
1071
// any significant performance impact ? - No)
1072
 
1073
assign  ld_any_raw_vld[7:0] = stb_ld_full_raw[7:0] | stb_ld_partial_raw[7:0] ;
1074
 
1075 113 albert.wat
dff_s #(16)  stgw2_rvld (
1076 95 fafa1971
        .din    ({ld_any_raw_vld[7:0],stb_state_ced[7:0]}),
1077
        .q      ({ld_any_raw_vld_d1[7:0],stb_state_ced_d1[7:0]}),
1078
        .clk    (clk),
1079 113 albert.wat
        .se     (se),       `SIMPLY_RISC_SCANIN,          .so ()
1080 95 fafa1971
        );
1081
 
1082
 
1083
// This equation can be optimized for the grape flow.
1084
// This can be obtained from stb.
1085
/*assign  ld_raw_mhit =
1086
  (ld_any_raw_vld[7] & |(ld_any_raw_vld[6:0])) |
1087
  (ld_any_raw_vld[6] & |(ld_any_raw_vld[5:0])) |
1088
  (ld_any_raw_vld[5] & |(ld_any_raw_vld[4:0])) |
1089
  (ld_any_raw_vld[4] & |(ld_any_raw_vld[3:0])) |
1090
  (ld_any_raw_vld[3] & |(ld_any_raw_vld[2:0])) |
1091
  (ld_any_raw_vld[2] & |(ld_any_raw_vld[1:0])) |
1092
  (ld_any_raw_vld[1] &   ld_any_raw_vld[0]) ; */
1093
 
1094
//=========================================================================================
1095
//  STB Partial Raw ptr generation
1096
//=========================================================================================
1097
 
1098
// The loading on the raw output of the stb cam will be significant if the signal 
1099
// has to fan out to all 4 ctl blocks. That's why the control has to be localized.
1100
 
1101
// Using the ack bit may result in pessimistic issue of partial raw loads.
1102
// For a single partial raw or multiple hit case, detecting whether there is any
1103
// unacked store is sufficient. Calculation is for no unacked store.
1104
// Can we use cam_hit ptr instead !!!
1105
 
1106
//assign  ld_rawp_st_ced_w2 = (~(|(ld_any_raw_vld_d1[7:0] & ~stb_state_ced_d1[7:0]))) ;
1107
wire [2:0] wptr_prev ;
1108
assign  wptr_prev[2:0] = stb_wptr_prev[2:0] ;
1109
wire [7:0] wptr_dcd ; // Bug 4294
1110
assign  wptr_dcd[0] = ~wptr_prev[2] & ~wptr_prev[1] & ~wptr_prev[0] ;
1111
assign  wptr_dcd[1] = ~wptr_prev[2] & ~wptr_prev[1] &  wptr_prev[0] ;
1112
assign  wptr_dcd[2] = ~wptr_prev[2] &  wptr_prev[1] & ~wptr_prev[0] ;
1113
assign  wptr_dcd[3] = ~wptr_prev[2] &  wptr_prev[1] &  wptr_prev[0] ;
1114
assign  wptr_dcd[4] =  wptr_prev[2] & ~wptr_prev[1] & ~wptr_prev[0] ;
1115
assign  wptr_dcd[5] =  wptr_prev[2] & ~wptr_prev[1] &  wptr_prev[0] ;
1116
assign  wptr_dcd[6] =  wptr_prev[2] &  wptr_prev[1] & ~wptr_prev[0] ;
1117
assign  wptr_dcd[7] =  wptr_prev[2] &  wptr_prev[1] &  wptr_prev[0] ;
1118
 
1119
wire iold_st_ced_g,iold_st_ced_w2 ;
1120
assign  iold_st_ced_g = |(wptr_dcd[7:0] & stb_state_ced[7:0]) ;
1121
 
1122 113 albert.wat
dff_s #(2)   ioldced_stgw2  (
1123 95 fafa1971
  .din  ({iold_st_ced_g,io_ld}),
1124
  .q    ({iold_st_ced_w2,io_ld_w2}),
1125
  .clk  (clk),
1126 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
1127 95 fafa1971
  );
1128
 
1129
assign  ld_rawp_st_ced_w2 =
1130
        io_ld_w2 ? iold_st_ced_w2 :
1131
        (~(|(ld_any_raw_vld_d1[7:0] & ~stb_state_ced_d1[7:0]))) ;
1132
 
1133
// For the case of a single partial raw.
1134
assign  ld_rawp_stb_id[0] = stb_cam_hit_ptr[0] ;
1135
assign  ld_rawp_stb_id[1] = stb_cam_hit_ptr[1] ;
1136
assign  ld_rawp_stb_id[2] = stb_cam_hit_ptr[2] ;
1137
/*assign  ld_rawp_stb_id[0] = stb_ld_partial_raw[1] | stb_ld_partial_raw[3] |
1138
        stb_ld_partial_raw[5] | stb_ld_partial_raw[7] ;
1139
assign  ld_rawp_stb_id[1] = stb_ld_partial_raw[2] | stb_ld_partial_raw[3] |
1140
        stb_ld_partial_raw[6] | stb_ld_partial_raw[7] ;
1141
assign  ld_rawp_stb_id[2] = stb_ld_partial_raw[4] | stb_ld_partial_raw[5] |
1142
        stb_ld_partial_raw[6] | stb_ld_partial_raw[7] ; */
1143
 
1144
   wire [3:0] pipe_thread_g;
1145
   assign     pipe_thread_g[0] = ~thrid_g[1] & ~thrid_g[0];
1146
   assign     pipe_thread_g[1] = ~thrid_g[1] &  thrid_g[0];
1147
   assign     pipe_thread_g[2] =  thrid_g[1] & ~thrid_g[0];
1148
   assign     pipe_thread_g[3] =  thrid_g[1] &  thrid_g[0];
1149
 
1150
assign  stb_state_ced[7:0] =
1151
( pipe_thread_g[0] ? stb_state_ced0[7:0] : 8'b0 ) |
1152
( pipe_thread_g[1] ? stb_state_ced1[7:0] : 8'b0 ) |
1153
( pipe_thread_g[2] ? stb_state_ced2[7:0] : 8'b0 ) |
1154
( pipe_thread_g[3] ? stb_state_ced3[7:0] : 8'b0 );
1155
 
1156
assign  stb_wptr_prev[2:0] =
1157
  (pipe_thread_g[0] ? stb_wrptr0_prev[2:0] : 3'b0) |
1158
  (pipe_thread_g[1] ? stb_wrptr1_prev[2:0] : 3'b0) |
1159
  (pipe_thread_g[2] ? stb_wrptr2_prev[2:0] : 3'b0) |
1160
  (pipe_thread_g[3] ? stb_wrptr3_prev[2:0] : 3'b0);
1161
 
1162
assign  stb_not_empty  =
1163
  (pipe_thread_g[0]  & ~lsu_stb_empty[0] ) |
1164
  (pipe_thread_g[1]  & ~lsu_stb_empty[1] ) |
1165
  (pipe_thread_g[2]  & ~lsu_stb_empty[2] ) |
1166
  (pipe_thread_g[3]  & ~lsu_stb_empty[3] ) ;
1167
 
1168
assign  lsu_stb_empty_buf[3:0] = lsu_stb_empty[3:0] ;
1169
assign  lsu_spu_stb_empty[3:0] = lsu_stb_empty[3:0] ;
1170
 
1171
//wire ldstdbl_g ;
1172
// stdbl should be qualified with quad_asi_g !!!
1173
//assign  ldstdbl_g = ldst_dbl_g & (ld_inst_vld_g | st_inst_vld_g) & ~ldst_fp_g ;
1174
 
1175
// casa_g and stdbl_g may not be required.
1176
//assign  ld_rawp_st_ackid_g[2:0] = 
1177
//  (casa_g | ldstdbl_g | stb_cam_mhit | (io_ld & stb_not_empty))
1178
//  ? stb_wptr_prev[2:0] : ld_rawp_stb_id[2:0] ;
1179
 
1180
//===================================================
1181
//casa: need st-st order
1182
//st cam mhit: cannot figure out the youngest
1183
//io: side effect
1184
//remove int ldd and quad ldd, why need ldstdbl?
1185
//===================================================
1186
wire    [2:0]    ld_rawp_st_ackid_g ;
1187
 
1188
assign  ld_rawp_st_ackid_g[2:0] =
1189
  (casa_g | stb_cam_mhit | (io_ld & stb_not_empty))?
1190
   stb_wptr_prev[2:0] : ld_rawp_stb_id[2:0] ;
1191
 
1192 113 albert.wat
dff_s #(3)  rawpackid_w2 (
1193 95 fafa1971
  .din  (ld_rawp_st_ackid_g[2:0]),
1194
  .q    (ld_rawp_st_ackid_w2[2:0]),
1195
  .clk  (clk),
1196 113 albert.wat
  .se   (se), `SIMPLY_RISC_SCANIN, .so ()
1197 95 fafa1971
  );
1198
 
1199
 
1200
   assign lsu_ifu_stbcnt0[3:0] = lsu_stbcnt0[3:0] ;
1201
   assign lsu_ifu_stbcnt1[3:0] = lsu_stbcnt1[3:0] ;
1202
   assign lsu_ifu_stbcnt2[3:0] = lsu_stbcnt2[3:0] ;
1203
   assign lsu_ifu_stbcnt3[3:0] = lsu_stbcnt3[3:0] ;
1204
 
1205
   assign lsu_ffu_stb_full0 =    lsu_stbcnt0[3];
1206
   assign lsu_ffu_stb_full1 =    lsu_stbcnt1[3];
1207
   assign lsu_ffu_stb_full2 =    lsu_stbcnt2[3];
1208
   assign lsu_ffu_stb_full3 =    lsu_stbcnt3[3];
1209
 
1210
endmodule
1211
 

powered by: WebSVN 2.1.0

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