source: XOpenSparcT1/trunk/T1-common/srams/bw_r_rf16x32.v @ 6

Revision 6, 14.9 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
1// ========== 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
76module 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
448endmodule // bw_r_rf16x32
449
450
451
452
453
454
455
456
457
458
459
460
Note: See TracBrowser for help on using the repository browser.