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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-common/] [srams/] [bw_r_l2d_32k.v] - Blame information for rev 7

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: bw_r_l2d_32k.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
//FPGA_SYN enables all FPGA related modifications
22
`ifdef FPGA_SYN
23
`define FPGA_SYN_RED
24
`endif
25
 
26
module bw_r_l2d_32k (/*AUTOARG*/
27
   // Outputs
28
   decc_out, so, l2d_fuse_data_out,
29
   // Inputs
30
   decc_in_l, decc_read_in, word_en_l, way_sel_l, set_l,
31
   col_offset_l, wr_en_l, rclk, arst_l, mem_write_disable,
32
   sehold, se, si, fuse_l2d_wren, fuse_l2d_rden,
33
   fuse_l2d_rid, fuse_clk1, fuse_clk2,
34
   fuse_l2d_data_in, fuse_read_data_in
35
   );
36
 
37
   input [155:0] decc_in_l;
38
   input [155:0]         decc_read_in;
39
   input [3:0]           word_en_l;
40
   input [1:0]           way_sel_l;
41
   input [9:0]           set_l;
42
   input                col_offset_l;
43
   input                wr_en_l;
44
   input                rclk;
45
   input                arst_l;
46
 
47
   // Test signals
48
   input                mem_write_disable;
49
   input                sehold;
50
   input                se;
51
   input                si;
52
 
53
 
54
   // Efuse inputs
55
   input                fuse_l2d_wren;
56
   input                fuse_l2d_rden;
57
   input [2:0]           fuse_l2d_rid;
58
   input                fuse_clk1;
59
   input                fuse_clk2;
60
   input                fuse_l2d_data_in;
61
   input                fuse_read_data_in;
62
 
63
 
64
   output [155:0]        decc_out ;
65
   output               so;
66
 
67
   // Efuse outputs
68
   output               l2d_fuse_data_out;
69
 
70
   reg [155:0]           tmp_decc_out;
71
   reg [155:0]           decc_out_tmp;
72
   reg [155:0]           reg_decc_in;
73
 
74
`ifdef DEFINE_0IN
75
`else
76
   reg [155:0]           way0_decc[1023:0] ;
77
   reg [155:0]           way1_decc[1023:0] ;
78
`endif
79
 
80
   wire                 acc_en_d1;
81
   reg [1:0]             way_sel_d1;
82
   reg [9:0]             set_d1;
83
   reg [3:0]             word_en_d1;
84
   reg                  wr_en_d1;
85
   reg [155:0]           decc_in_d1;
86
   reg [155:0]           decc_out_d1;
87
   reg                  col_offset_d1;
88
 
89
   wire [1:0]            way_sel_sehold;
90
   wire [9:0]            set_sehold;
91
   wire [3:0]            word_en_sehold;
92
   wire                 wr_en_sehold;
93
   wire [155:0]  decc_in_sehold;
94
   wire                 col_offset;
95
 
96
   wire [155:0]  decc_out ;
97
 
98
// JC begin
99
// Because of this 2 cycle block,
100
// The following codes are just helping me for Innologic verification 
101
// stop_1_cyc: when col_offset = 1, the next cycle will be ignore
102
// keep_rd_out: The output data will be kept for another cycle
103
   reg                  keep_rd_out;
104
   reg                  stop_1_cyc;
105
   always @(posedge rclk) begin
106
      if (col_offset && (|way_sel_sehold)) begin
107
         stop_1_cyc <= 1'b1;
108
      end
109
      else stop_1_cyc <= 1'b0;
110
      if (acc_en_d1 & ~wr_en_d1) begin
111
         keep_rd_out <= 1'b1;
112
      end
113
      else keep_rd_out <= 1'b0;
114
   end
115
// JC end  
116
 
117
 
118
   assign               wr_en_sehold = (sehold) ? wr_en_d1 : ~wr_en_l;
119
   assign               set_sehold = (sehold) ? set_d1 : ~set_l;
120
   assign               way_sel_sehold = (sehold) ? way_sel_d1 : ~way_sel_l;
121
   assign               word_en_sehold = (sehold) ? word_en_d1 : ~word_en_l;
122
// In Circuits, we use se to disable write, however, I modified testbench as following 
123
// to verify write disable:
124
//     force inno_tb_top.xtor.xcnt.se_l = ~mem_write_disable ;
125
 
126
   assign               col_offset = (stop_1_cyc || mem_write_disable ) ? (1'b0) : ~col_offset_l ;
127
 
128
   assign acc_en_d1 = col_offset_d1 & (|way_sel_d1);
129
 
130
   always @(posedge rclk) begin
131
      col_offset_d1 <= col_offset;
132
      way_sel_d1  <= way_sel_sehold;
133
      set_d1  <= set_sehold;
134
      word_en_d1 <= word_en_sehold;
135
      wr_en_d1  <= wr_en_sehold;
136
// JC 
137
// EVEN THOUGH We don't have any write data latch,
138
// Our write-data drivers act like latch which gating by 
139
// Worden signals.
140
      decc_in_d1 <= ~decc_in_l;
141
// JC 
142
//This is NOT output flops, but we can keep read outs for
143
// 2 cycles.      
144
      decc_out_d1 <= decc_out_tmp;
145
   end
146
 
147
 
148
`ifdef DEFINE_0IN
149
   wire [155:0] decc_out0, decc_out1;
150
 
151
   wire [155:0] wm  = { {39{word_en_d1[3]}}, {39{word_en_d1[2]}}, {39{word_en_d1[1]}}, {39{word_en_d1[0]}} };
152
   wire         we0 = acc_en_d1 & wr_en_d1 & way_sel_d1[0];
153
   wire         we1 = acc_en_d1 & wr_en_d1 & way_sel_d1[1];
154
 
155
l2data_axis     data_array0 (.data_out  (decc_out0[155:0]),
156
                             .rclk      (rclk),
157
                             .adr       (set_d1[9:0]),
158
                             .data_in   (decc_in_d1[155:0]),
159
                             .we        (we0),
160
                             .wm        (wm[155:0]) );
161
l2data_axis     data_array1 (.data_out  (decc_out1[155:0]),
162
                             .rclk      (rclk),
163
                             .adr       (set_d1[9:0]),
164
                             .data_in   (decc_in_d1[155:0]),
165
                             .we        (we1),
166
                             .wm        (wm[155:0]) );
167
 
168
   always @(/*AUTOSENSE*/acc_en_d1 or decc_in_d1 or decc_out0
169
            or decc_out1 or way_sel_d1 or word_en_d1 or wr_en_d1) begin
170
        if (acc_en_d1 & ~wr_en_d1) begin
171
           //////////////////////////
172
           // 16 or 64B byte read
173
           //////////////////////////
174
           decc_out_tmp = way_sel_d1[0] ? decc_out0[155:0] : decc_out1[155:0];
175
        end
176
 
177
        if (acc_en_d1 & wr_en_d1) begin
178
           //////////////////////////
179
           // Store word/dword OR 64B store
180
           //////////////////////////
181
           tmp_decc_out = way_sel_d1[0] ? decc_out0[155:0] : decc_out1[155:0];
182
 
183
           //////////////////////////////////////
184
           // Write data based on Word enables.
185
           //////////////////////////////////////
186
 
187
           reg_decc_in[155:117] = (decc_in_d1[155:117] & {39{word_en_d1[3]}} |
188
                                   tmp_decc_out[155:117] & {39{~word_en_d1[3]}});
189
           reg_decc_in[116:78] = (decc_in_d1[116:78] & {39{word_en_d1[2]}} |
190
                                  tmp_decc_out[116:78] & {39{~word_en_d1[2]}});
191
           reg_decc_in[77:39] = (decc_in_d1[77:39] & {39{word_en_d1[1]}} |
192
                                 tmp_decc_out[77:39] & {39{~word_en_d1[1]}});
193
           reg_decc_in[38:0] = (decc_in_d1[38:0] & {39{word_en_d1[0]}} |
194
                                tmp_decc_out[38:0] & {39{~word_en_d1[0]}});
195
 
196
           //////////////////////////////////////////////////////////
197
           // the store data gets reflected onto the read output bus
198
           //////////////////////////////////////////////////////////
199
 
200
//           decc_out_tmp[155:0] = reg_decc_in[155:0];
201
// Store data is *not* reflected onto the read output bus in the physical implementation
202
             decc_out_tmp[155:0] = 156'b0;
203
 
204
        end // of write operation
205
 
206
      if (~acc_en_d1) begin
207
        // no access
208
         decc_out_tmp[155:0] = 156'b0;
209
      end
210
 
211
   end // of always block
212
 
213
`else
214
 
215
   always @(/*AUTOSENSE*/acc_en_d1 or decc_in_d1 or set_d1
216
            or way_sel_d1 or word_en_d1 or wr_en_d1) begin
217
 
218
`ifdef  INNO_MUXEX
219
`else
220
//----- PURELY FOR VERIFICATION -----------------------
221
      if(wr_en_d1==1'bx) begin
222
        `ifdef MODELSIM
223
         $display("L2_DATA_ERR"," wr en error %b ", wr_en_d1);
224
        `else
225
         $error("L2_DATA_ERR"," wr en error %b ", wr_en_d1);
226
        `endif
227
      end
228
//----- PURELY FOR VERIFICATION -----------------------
229
`endif
230
 
231
 
232
//////////////////
233
// MEMORY ACCESS
234
//////////////////
235
 
236
      if (acc_en_d1) begin
237
 
238
`ifdef  INNO_MUXEX
239
`else
240
//----- PURELY FOR VERIFICATION -----------------------
241
         if(set_d1==10'bx) begin
242
        `ifdef MODELSIM
243
            $error("L2_DATA_ERR"," index error %h ", set_d1[9:0]);
244
        `else
245
            $display("L2_DATA_ERR"," index error %h ", set_d1[9:0]);
246
        `endif
247
         end
248
//----- PURELY FOR VERIFICATION -----------------------
249
`endif
250
 
251
 
252
        if (~wr_en_d1) begin
253
           //////////////////////////
254
           // 16 or 64B byte read 
255
           //////////////////////////
256
           decc_out_tmp = way_sel_d1[0] ? way0_decc[set_d1] : way1_decc[set_d1];
257
//JC: For keeping data for 2 cycle
258
//         keep_rd_out = 2'b01;    
259
        end
260
 
261
        else begin
262
           //////////////////////////
263
           // Store word/dword OR 64B store
264
           //////////////////////////
265
           tmp_decc_out = way_sel_d1[0] ? way0_decc[set_d1] : way1_decc[set_d1];
266
 
267
//         keep_rd_out = 2'b00;    
268
           //////////////////////////////////////
269
           // Write data based on Word enables.
270
           //////////////////////////////////////
271
 
272
           reg_decc_in[155:117] = (decc_in_d1[155:117] & {39{word_en_d1[3]}} |
273
                                   tmp_decc_out[155:117] & {39{~word_en_d1[3]}});
274
           reg_decc_in[116:78] = (decc_in_d1[116:78] & {39{word_en_d1[2]}} |
275
                                  tmp_decc_out[116:78] & {39{~word_en_d1[2]}});
276
           reg_decc_in[77:39] = (decc_in_d1[77:39] & {39{word_en_d1[1]}} |
277
                                 tmp_decc_out[77:39] & {39{~word_en_d1[1]}});
278
           reg_decc_in[38:0] = (decc_in_d1[38:0] & {39{word_en_d1[0]}} |
279
                                tmp_decc_out[38:0] & {39{~word_en_d1[0]}});
280
 
281
           if (way_sel_d1[0]) way0_decc[set_d1] =  reg_decc_in;
282
           if (way_sel_d1[1]) way1_decc[set_d1] =  reg_decc_in;
283
 
284
           //////////////////////////////////////////////////////////
285
           // the store data gets reflected onto the read output bus
286
           //////////////////////////////////////////////////////////
287
 
288
//           decc_out_tmp[155:0] = reg_decc_in[155:0];
289
// Store data is *not* reflected onto the read output bus in the physical implementation
290
 
291
             decc_out_tmp[155:0] = 156'b0;
292
 
293
        end // of write operation
294
 
295
      end
296
 
297
      else begin
298
        // no access
299
         decc_out_tmp[155:0] = 156'b0;
300
      end
301
 
302
   end // of always block
303
`endif
304
   // Modeling wired-OR
305
 
306
// JC we don't have any flop in this level
307
//   assign decc_out[155:0] = decc_out_d1[155:0] | decc_read_in[155:0];   
308
 
309
   assign decc_out[155:0] = (acc_en_d1 & ~wr_en_d1) ? 156'bX : (keep_rd_out) ?
310
                            (decc_out_d1[155:0] | decc_read_in[155:0]) :
311
                            (decc_out_tmp[155:0] | decc_read_in[155:0]);
312
 
313
/////////////////////////////////////////////////////////////////////
314
// Redundancy Registers
315
/////////////////////////////////////////////////////////////////////
316
 
317
   reg [8:0]     s_red_reg0;
318
   reg [8:0]     s_red_reg1;
319
   reg [8:0]     s_red_reg2;
320
   reg [8:0]     s_red_reg3;
321
   reg [8:0]     s_red_reg4;
322
   reg [8:0]     s_red_reg5;
323
 
324
   reg [8:0]     m_red_reg0;
325
   reg [8:0]     m_red_reg1;
326
   reg [8:0]     m_red_reg2;
327
   reg [8:0]     m_red_reg3;
328
   reg [8:0]     m_red_reg4;
329
   reg [8:0]     m_red_reg5;
330
 
331
   wire      l2d_fuse_data_out;
332
 
333
assign l2d_fuse_data_out = s_red_reg5[8];
334
 
335
   always @(arst_l or fuse_clk1 or fuse_l2d_rid or fuse_l2d_wren or fuse_l2d_rden
336
            or fuse_l2d_data_in or fuse_read_data_in
337
            or s_red_reg0 or s_red_reg1 or s_red_reg2
338
            or s_red_reg3 or s_red_reg4 or s_red_reg5) begin
339
 
340
      if (!arst_l) begin
341
         m_red_reg0[8:0] = 9'b0;
342
         m_red_reg1[8:0] = 9'b0;
343
         m_red_reg2[8:0] = 9'b0;
344
         m_red_reg3[8:0] = 9'b0;
345
         m_red_reg4[8:0] = 9'b0;
346
         m_red_reg5[8:0] = 9'b0;
347
      end
348
 
349
      if (arst_l && fuse_clk1) begin
350
 
351
      /////////////////////////////////
352
      // Write operation
353
      /////////////////////////////////
354
 
355
         if (fuse_l2d_wren) begin
356
            case (fuse_l2d_rid) //selecting among the six registers
357
              3'b101: m_red_reg0[8:0] = {s_red_reg0[7:0], fuse_l2d_data_in};// bottom odd row
358
              3'b011: m_red_reg1[8:0] = {s_red_reg1[7:0], fuse_l2d_data_in};// bottom even row
359
              3'b010: m_red_reg2[8:0] = {s_red_reg2[7:0], fuse_l2d_data_in};// bottom column
360
              3'b100: m_red_reg3[8:0] = {s_red_reg3[7:0], fuse_l2d_data_in};// top odd row
361
              3'b001: m_red_reg4[8:0] = {s_red_reg4[7:0], fuse_l2d_data_in};// top even row
362
              3'b000: m_red_reg5[8:0] = {s_red_reg5[7:0], fuse_l2d_data_in};// top column
363
              default: ;
364
            endcase // case(fuse_l2d_rid)
365
         end // if (fuse_l2d_wren)
366
 
367
      /////////////////////////////////
368
      // Read operation
369
      /////////////////////////////////
370
 
371
//JC This is just temporary fix for read operation, rid = 3'b111 will turn on everything
372
         else if (fuse_l2d_rden) begin
373
                      m_red_reg0[8:0] = {s_red_reg0[7:0], fuse_read_data_in};
374
                      m_red_reg1[8:0] = {s_red_reg1[7:0], s_red_reg0[8]};
375
                      m_red_reg2[8:0] = {s_red_reg2[7:0], s_red_reg1[8]};
376
                      m_red_reg3[8:0] = {s_red_reg3[7:0], s_red_reg2[8]};
377
                      m_red_reg4[8:0] = {s_red_reg4[7:0], s_red_reg3[8]};
378
                      m_red_reg5[8:0] = {s_red_reg5[7:0], s_red_reg4[8]};
379
              end // if (fuse_l2d_rden)
380
 
381
      end // if (fuse_clk1)
382
 
383
   end // always @ (fuse_clk1 or...
384
 
385
//   always @(posedge efc_scdata_fuse_clk1) begin
386
 
387
   always @(arst_l or fuse_clk2 or fuse_l2d_rid or fuse_l2d_wren or fuse_l2d_rden
388
            or m_red_reg0 or m_red_reg1 or m_red_reg2
389
            or m_red_reg3 or m_red_reg4 or m_red_reg5) begin
390
 
391
`ifdef DEFINE_0IN
392
`else
393
  `ifdef FPGA_SYN_RED
394
  `else
395
      if (!arst_l) begin
396
         m_red_reg0[8:0] = 9'b0;
397
         m_red_reg1[8:0] = 9'b0;
398
         m_red_reg2[8:0] = 9'b0;
399
         m_red_reg3[8:0] = 9'b0;
400
         m_red_reg4[8:0] = 9'b0;
401
         m_red_reg5[8:0] = 9'b0;
402
      end
403
  `endif
404
`endif
405
 
406
      if (fuse_clk2) begin
407
 
408
         if (fuse_l2d_wren) begin
409
            case (fuse_l2d_rid) //selecting among the six registers
410
              3'b101: s_red_reg0[8:0] = m_red_reg0[8:0];// bottom odd row
411
              3'b011: s_red_reg1[8:0] = m_red_reg1[8:0];// bottom even row
412
              3'b010: s_red_reg2[8:0] = m_red_reg2[8:0];// bottom column
413
              3'b100: s_red_reg3[8:0] = m_red_reg3[8:0];// top odd row
414
              3'b001: s_red_reg4[8:0] = m_red_reg4[8:0];// top even row
415
              3'b000: s_red_reg5[8:0] = m_red_reg5[8:0];// top column
416
             default: ;
417
            endcase // case(fuse_l2d_rid)
418
         end // if (fuse_l2d_wren)
419
         else if (fuse_l2d_rden) begin
420
                s_red_reg0[8:0] = m_red_reg0[8:0];// bottom odd row
421
                s_red_reg1[8:0] = m_red_reg1[8:0];// bottom even row
422
                s_red_reg2[8:0] = m_red_reg2[8:0];// bottom column
423
                s_red_reg3[8:0] = m_red_reg3[8:0];// top odd row
424
                s_red_reg4[8:0] = m_red_reg4[8:0];// top even row
425
                s_red_reg5[8:0] = m_red_reg5[8:0];// top column
426
              end // if (fuse_l2d_rden)
427
 
428
      end // if (fuse_clk2)
429
 
430
   end // always @ (fuse_clk2 or...
431
 
432
endmodule // bw_r_l2d_32k
433
 

powered by: WebSVN 2.1.0

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