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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-common/] [srams/] [bw_r_rf16x32.v] - Blame information for rev 2

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_rf16x32.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:  bw_r_rf16x32
24
 //  Description:
25
 //   1r1w array for icache and dcache valid bits.
26
 //   Modified to conform to naming convention
27
 //   Added 16 bit wr en
28
 //   Made bit_wen and din flopped inputs
29
 //   So all inputs are setup to flops in the stage before memory
30
 //   access.  The data output is available one cycle later (same
31
 //   stage as mem access)
32
 //
33
 //  IMPORTANT NOTE: This block has to work even in the case where
34
 //  there is contention between a read and write operation for the
35
 //  same address.  Based on ease of implementation, the behavior
36
 //  during contention is defined as follows.
37
 //    -- write always succeeds
38
 //    -- read data is (array_data & write_data)
39
 //       (i.e. old_data & new_data)
40
 //
41
 //   So read 0 always succeeds.  read 1 succeeds if the data being
42
 //   written is also a 1.  Otherwise it fails.
43
 //
44
 // new_data = 1, old_data = 0, does not give the expected or
45
 // predictable result in post layout, so the code has been modified
46
 // to be
47
 // old new rd_data
48
 // --- --- -------
49
 // 0    0     0
50
 // 0    1     X
51
 // 1    0     0
52
 // 1    1     1
53
 //
54
 // **The write still succeeds in ALL cases**
55
 */
56
 
57
////////////////////////////////////////////////////////////////////////
58
// Global header file includes
59
////////////////////////////////////////////////////////////////////////
60
//`include "sys.h" // system level definition file which contains the 
61
// time scale definition
62
 
63
//`include "iop.h"
64
 
65
////////////////////////////////////////////////////////////////////////
66
// Local header file includes / local defines
67
////////////////////////////////////////////////////////////////////////
68
 
69
//FPGA_SYN enables all FPGA related modifications
70
`ifdef FPGA_SYN
71
`define FPGA_SYN_IDCT
72
`endif
73
 
74
 
75
 
76
module bw_r_rf16x32 (/*AUTOARG*/
77
   // Outputs
78
   dout, so,
79
   // Inputs
80
   rclk, se, si, reset_l, sehold, rst_tri_en, rd_adr1, rd_adr2,
81
   rd_adr1_sel, rd_en, wr_adr, wr_en, bit_wen, din
82
   );
83
 
84
 
85
   input        rclk;
86
   input        se;
87
   input        si;
88
   input        reset_l;
89
   input        sehold;       // scan enable hold
90
   input        rst_tri_en;
91
 
92
   // 11:5(I);10:4(D)
93
   input [6:0]   rd_adr1 ;     // rd address-1
94
   input [6:0]   rd_adr2 ;     // rd address-2
95
 
96
   input        rd_adr1_sel ;   // sel rd addr 1 
97
   input        rd_en ;             // rd enable 
98
 
99
   // 11:7(I);10:6(D)
100
   input [6:2]  wr_adr ;  // wr address 
101
 
102
   input        wr_en ;         // wr enable
103
   input [15:0] bit_wen ;        // write enable with bit select
104
   input        din ;             // write data
105
 
106
   output [3:0]  dout ;    // valid bits for tag compare
107
 
108
   output       so;
109
 
110
   wire         clk;
111
   assign       clk = rclk;
112
 
113
   //----------------------------------------------------------------------
114
   // Declarations
115
   //----------------------------------------------------------------------
116
   // local signals
117
   wire [6:0]    rd_index ;
118
 
119
   // 512 bit array  
120
`ifdef FPGA_SYN_IDCT
121
   reg [31:0]    idcv_ary_0000;
122
   reg [31:0]    idcv_ary_0001;
123
   reg [31:0]    idcv_ary_0010;
124
   reg [31:0]    idcv_ary_0011;
125
   reg [31:0]    idcv_ary_0100;
126
   reg [31:0]    idcv_ary_0101;
127
   reg [31:0]    idcv_ary_0110;
128
   reg [31:0]    idcv_ary_0111;
129
   reg [31:0]    idcv_ary_1000;
130
   reg [31:0]    idcv_ary_1001;
131
   reg [31:0]    idcv_ary_1010;
132
   reg [31:0]    idcv_ary_1011;
133
   reg [31:0]    idcv_ary_1100;
134
   reg [31:0]    idcv_ary_1101;
135
   reg [31:0]    idcv_ary_1110;
136
   reg [31:0]    idcv_ary_1111;
137
`else
138
   reg [511:0]   idcv_ary;
139
`endif
140
 
141
   reg [3:0]     vbit,
142
                vbit_sa;
143
 
144
   reg [6:2]    wr_index_d1;
145
   reg [6:0]     rd_index_d1;
146
 
147
   reg          rdreq_d1,
148
                            wrreq_d1;
149
 
150
   reg [15:0]   bit_wen_d1;
151
   reg          din_d1;
152
   reg [4:0] index;
153
 
154
   wire         rst_all;
155
 
156
   //----------------------------------------------------------------------
157
   // Code Begins Here
158
   //----------------------------------------------------------------------
159
   assign       rst_all = rst_tri_en | ~reset_l;
160
 
161
   // mux merged with flop on index
162
   assign rd_index = rd_adr1_sel ? rd_adr1:rd_adr2 ;
163
 
164
   // input flops
165
   always @ (posedge clk)
166
     begin
167
        if (~sehold)
168
          begin
169
                   rdreq_d1 <= rd_en ;
170
                   wrreq_d1 <= wr_en ;
171
                   rd_index_d1 <= rd_index;
172
                   wr_index_d1 <= wr_adr;
173
             bit_wen_d1 <= bit_wen;
174
             din_d1 <= din;
175
          end
176
     end
177
 
178
 
179
   //----------------------------------------------------------------------
180
   // Read Operation
181
   //----------------------------------------------------------------------
182
`ifdef FPGA_SYN_IDCT
183
   always @(/*AUTOSENSE*/
184
            idcv_ary_0000 or idcv_ary_0001 or idcv_ary_0010 or idcv_ary_0011 or
185
            idcv_ary_0100 or idcv_ary_1001 or idcv_ary_1010 or idcv_ary_0111 or
186
            idcv_ary_1000 or idcv_ary_0101 or idcv_ary_0110 or idcv_ary_1011 or
187
            idcv_ary_1100 or idcv_ary_1101 or idcv_ary_1110 or idcv_ary_1111 or rd_index_d1 or rdreq_d1)
188
`else
189
   always @(/*AUTOSENSE*/idcv_ary or rd_index_d1 or rdreq_d1)
190
`endif
191
     begin
192
              if (rdreq_d1)  // should work even if there is read
193
                                   // write conflict.  Data can be latest
194
                             // or previous but should not be x
195
                begin
196
`ifdef FPGA_SYN_IDCT
197
            case(rd_index_d1[1:0])
198
              2'b00: begin
199
              vbit[0] = idcv_ary_0000[{rd_index_d1[6:2]}];
200
              vbit[1] = idcv_ary_0001[{rd_index_d1[6:2]}];
201
              vbit[2] = idcv_ary_0010[{rd_index_d1[6:2]}];
202
              vbit[3] = idcv_ary_0011[{rd_index_d1[6:2]}];
203
              end
204
              2'b01: begin
205
              vbit[0] = idcv_ary_0100[{rd_index_d1[6:2]}];
206
              vbit[1] = idcv_ary_0101[{rd_index_d1[6:2]}];
207
              vbit[2] = idcv_ary_0110[{rd_index_d1[6:2]}];
208
              vbit[3] = idcv_ary_0111[{rd_index_d1[6:2]}];
209
              end
210
              2'b10: begin
211
              vbit[0] = idcv_ary_1000[{rd_index_d1[6:2]}];
212
              vbit[1] = idcv_ary_1001[{rd_index_d1[6:2]}];
213
              vbit[2] = idcv_ary_1010[{rd_index_d1[6:2]}];
214
              vbit[3] = idcv_ary_1011[{rd_index_d1[6:2]}];
215
              end
216
              2'b11: begin
217
              vbit[0] = idcv_ary_1100[{rd_index_d1[6:2]}];
218
              vbit[1] = idcv_ary_1101[{rd_index_d1[6:2]}];
219
              vbit[2] = idcv_ary_1110[{rd_index_d1[6:2]}];
220
              vbit[3] = idcv_ary_1111[{rd_index_d1[6:2]}];
221
              end
222
            endcase
223
`else
224
                   vbit[0] = idcv_ary[{rd_index_d1, 2'b00}]; // way 0
225
                   vbit[1] = idcv_ary[{rd_index_d1, 2'b01}]; // way 1
226
                   vbit[2] = idcv_ary[{rd_index_d1, 2'b10}]; // way 2
227
                   vbit[3] = idcv_ary[{rd_index_d1, 2'b11}]; // way 3
228
`endif
229
                end     // if (rdreq_d1)
230
 
231
        else      // i/dcache disabled or rd disabled
232
          begin
233
             vbit[3:0] = 4'bx;
234
          end // else: !if(rdreq_d1)
235
     end // always @ (...
236
 
237
   // r-w conflict case, returns old_data & new_data
238
   // 12/06 modified to be
239
   // 0  0  0
240
   // 0  1  X
241
   // 1  0  0
242
   // 1  1  1
243
`ifdef FPGA_SYN_IDCT
244
    initial
245
    begin
246
        for(index = 5'h0; index < 5'h1f; index = index+1)
247
        begin
248
            idcv_ary_0000[index] = 1'b0;
249
            idcv_ary_0001[index] = 1'b0;
250
            idcv_ary_0010[index] = 1'b0;
251
            idcv_ary_0011[index] = 1'b0;
252
            idcv_ary_0100[index] = 1'b0;
253
            idcv_ary_0101[index] = 1'b0;
254
            idcv_ary_0110[index] = 1'b0;
255
            idcv_ary_0111[index] = 1'b0;
256
            idcv_ary_1000[index] = 1'b0;
257
            idcv_ary_1001[index] = 1'b0;
258
            idcv_ary_1010[index] = 1'b0;
259
            idcv_ary_1011[index] = 1'b0;
260
            idcv_ary_1100[index] = 1'b0;
261
            idcv_ary_1101[index] = 1'b0;
262
            idcv_ary_1110[index] = 1'b0;
263
            idcv_ary_1111[index] = 1'b0;
264
        end
265
    end
266
`endif
267
   reg [3:0] wr_data;
268
   always @ (/*AUTOSENSE*/bit_wen_d1 or rd_index_d1 or rst_all
269
             or wr_index_d1 or wrreq_d1)
270
     begin
271
        if (rd_index_d1[6:2] == wr_index_d1[6:2])
272
          case (rd_index_d1[1:0])
273
            2'b00:  wr_data = bit_wen_d1[3:0] & {4{wrreq_d1 & ~rst_all}};
274
            2'b01:  wr_data = bit_wen_d1[7:4] & {4{wrreq_d1 & ~rst_all}};
275
            2'b10:  wr_data = bit_wen_d1[11:8] & {4{wrreq_d1 & ~rst_all}};
276
            default:  wr_data = bit_wen_d1[15:12] & {4{wrreq_d1 & ~rst_all}};
277
          endcase // case(rd_index_d1[1:0])
278
        else
279
          wr_data = 4'b0;
280
     end
281
 
282
`ifdef FPGA_SYN_IDCT
283
  assign dout[3:0] = (~reset_l | ~rdreq_d1) ? 4'b0000 :
284
                     (~wr_data & vbit | wr_data & {4{din_d1}} & vbit);
285
`else
286
 
287
   // SA latch -- to make 0in happy
288
   always @ (/*AUTOSENSE*/clk or din_d1 or vbit or wr_data)
289
     begin
290
        if (clk)
291
          begin
292
             vbit_sa <= (~wr_data & vbit |
293
                         wr_data & {4{din_d1}} & (vbit | 4'bxxxx));
294
          end
295
     end
296
 
297
 
298
// bug:2776 - remove holding the last read value
299
// reset_l  rdreq_d1  dout
300
//  0       -         0
301
//  1       0         0
302
//  1       1         vbit_sa
303
 
304
   assign dout[3:0] = (~reset_l | ~rdreq_d1) ? 4'b0000 : vbit_sa[3:0] ;
305
 
306
`endif
307
 
308
 
309
   //----------------------------------------------------------------------
310
   // Write Operation
311
   //----------------------------------------------------------------------
312
   // Invalidate/Write occurs on 16B boundary.
313
   // For this purpose, 4x4 write-enables are required.
314
   // Index thus corresponds to 11:7,6:5,w[1:0], where w=way (ICache)
315
   // Index thus corresponds to 10:6,5:4,w[1:0], where w=way (DCache)
316
   // Thru data-in, vld bit can be set or cleared.
317
   always @ (negedge clk)
318
     begin
319
              if (wrreq_d1 & ~rst_all)  // should work even if rd-wr conflict
320
                begin
321
             // line 0 (5:4=00)
322
`ifdef FPGA_SYN_IDCT
323
                   if (bit_wen_d1[0]) idcv_ary_0000[{wr_index_d1[6:2]}] = din_d1;
324
                   if (bit_wen_d1[1]) idcv_ary_0001[{wr_index_d1[6:2]}] = din_d1;
325
                   if (bit_wen_d1[2]) idcv_ary_0010[{wr_index_d1[6:2]}] = din_d1;
326
                   if (bit_wen_d1[3]) idcv_ary_0011[{wr_index_d1[6:2]}] = din_d1;
327
`else
328
                   if (bit_wen_d1[0])
329
                     idcv_ary[{wr_index_d1[6:2],2'b00,2'b00}] = din_d1;
330
                   if (bit_wen_d1[1])
331
                     idcv_ary[{wr_index_d1[6:2],2'b00,2'b01}] = din_d1;
332
                   if (bit_wen_d1[2])
333
                     idcv_ary[{wr_index_d1[6:2],2'b00,2'b10}] = din_d1;
334
                   if (bit_wen_d1[3])
335
                     idcv_ary[{wr_index_d1[6:2],2'b00,2'b11}] = din_d1;
336
`endif
337
 
338
             // line 1 (5:4=01)
339
`ifdef FPGA_SYN_IDCT
340
                   if (bit_wen_d1[4]) idcv_ary_0100[{wr_index_d1[6:2]}] = din_d1;
341
                   if (bit_wen_d1[5]) idcv_ary_0101[{wr_index_d1[6:2]}] = din_d1;
342
                   if (bit_wen_d1[6]) idcv_ary_0110[{wr_index_d1[6:2]}] = din_d1;
343
                   if (bit_wen_d1[7]) idcv_ary_0111[{wr_index_d1[6:2]}] = din_d1;
344
`else
345
                   if (bit_wen_d1[4])
346
                     idcv_ary[{wr_index_d1[6:2],2'b01,2'b00}] = din_d1;
347
                   if (bit_wen_d1[5])
348
                     idcv_ary[{wr_index_d1[6:2],2'b01,2'b01}] = din_d1;
349
                   if (bit_wen_d1[6])
350
                     idcv_ary[{wr_index_d1[6:2],2'b01,2'b10}] = din_d1;
351
                   if (bit_wen_d1[7])
352
                     idcv_ary[{wr_index_d1[6:2],2'b01,2'b11}] = din_d1;
353
`endif
354
 
355
             // line 2 (5:4=10)
356
`ifdef FPGA_SYN_IDCT
357
                   if (bit_wen_d1[8]) idcv_ary_1000[{wr_index_d1[6:2]}] = din_d1;
358
                   if (bit_wen_d1[9]) idcv_ary_1001[{wr_index_d1[6:2]}] = din_d1;
359
                   if (bit_wen_d1[10]) idcv_ary_1010[{wr_index_d1[6:2]}] = din_d1;
360
                   if (bit_wen_d1[11]) idcv_ary_1011[{wr_index_d1[6:2]}] = din_d1;
361
`else
362
                   if (bit_wen_d1[8])
363
                     idcv_ary[{wr_index_d1[6:2],2'b10,2'b00}] = din_d1;
364
                   if (bit_wen_d1[9])
365
                     idcv_ary[{wr_index_d1[6:2],2'b10,2'b01}] = din_d1;
366
                   if (bit_wen_d1[10])
367
                     idcv_ary[{wr_index_d1[6:2],2'b10,2'b10}] = din_d1;
368
                   if (bit_wen_d1[11])
369
                     idcv_ary[{wr_index_d1[6:2],2'b10,2'b11}] = din_d1;
370
`endif
371
 
372
             // line 3 (5:4=11)
373
`ifdef FPGA_SYN_IDCT
374
                   if (bit_wen_d1[12]) idcv_ary_1100[{wr_index_d1[6:2]}] = din_d1;
375
                   if (bit_wen_d1[13]) idcv_ary_1101[{wr_index_d1[6:2]}] = din_d1;
376
                   if (bit_wen_d1[14]) idcv_ary_1110[{wr_index_d1[6:2]}] = din_d1;
377
                   if (bit_wen_d1[15]) idcv_ary_1111[{wr_index_d1[6:2]}] = din_d1;
378
`else
379
                   if (bit_wen_d1[12])
380
                     idcv_ary[{wr_index_d1[6:2],2'b11,2'b00}] = din_d1;
381
                   if (bit_wen_d1[13])
382
                     idcv_ary[{wr_index_d1[6:2],2'b11,2'b01}] = din_d1;
383
                   if (bit_wen_d1[14])
384
                     idcv_ary[{wr_index_d1[6:2],2'b11,2'b10}] = din_d1;
385
                   if (bit_wen_d1[15])
386
                     idcv_ary[{wr_index_d1[6:2],2'b11,2'b11}] = din_d1;
387
`endif
388
 
389
                end
390
     end // always @ (...
391
 
392
 
393
// synopsys translate_off
394
//----------------------------------------------------------------
395
// Monitors, shadow logic and other stuff not directly related to
396
// memory functionality
397
//----------------------------------------------------------------
398
`ifdef INNO_MUXEX
399
`else
400
   // Address monitor
401
   always @ (/*AUTOSENSE*/rd_index_d1 or rdreq_d1 or wr_index_d1
402
             or wrreq_d1)
403
     begin
404
        if (rdreq_d1 && (rd_index_d1 == 7'bX))
405
          begin
406
             // 0in <fire -message "FATAL ERROR: bw_r_rf16x32 read address X"
407
`ifdef DEFINE_0IN
408
`else
409
          //$error("RFRDADDR", "Error: bw_r_rf16x32 read address is %b\n", rd_index_d1);
410
`endif
411
          end
412
        else if (wrreq_d1 && (wr_index_d1 == 5'bX))
413
          begin
414
             // 0in <fire -message "FATAL ERROR: bw_r_rf16x32 write address X"
415
`ifdef DEFINE_0IN
416
`else
417
          //$error("RFWRADDR", "Error: bw_r_rf16x32 write address is %b\n", wr_index_d1);
418
`endif
419
          end
420
     end // always @ (...
421
 
422
 
423
`endif // !`ifdef INNO_MUXEX
424
 
425
 
426
//reg [127:0] w0;
427
//reg [127:0] w1;
428
//reg [127:0] w2;
429
//reg [127:0] w3;
430
//integer  i;
431
//   
432
//    always @(idcv_ary) begin
433
//       for (i=0;i<128; i=i+1) begin
434
//          w0[i] = idcv_ary[4*i];
435
//          w1[i] = idcv_ary[4*i+1];
436
//          w2[i] = idcv_ary[4*i+2];
437
//          w3[i] = idcv_ary[4*i+3];
438
//       end
439
//   end
440
//
441
//   reg [511:0] icv_ary;
442
//
443
//   always @ (idcv_ary)
444
//     icv_ary = idcv_ary;
445
 
446
// synopsys translate_on 
447
 
448
endmodule // bw_r_rf16x32
449
 
450
 
451
 
452
 
453
 
454
 
455
 
456
 
457
 
458
 
459
 
460
 

powered by: WebSVN 2.1.0

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