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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-common/] [srams/] [bw_r_cm16x40.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_cm16x40.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
module bw_r_cm16x40( /*AUTOARG*/
22
   // Outputs
23
   dout, match, match_idx, so,
24
   // Inputs
25
   adr_w, din, write_en, rst_tri_en, adr_r, read_en, lookup_en, key,
26
   rclk, sehold, se, si, rst_l
27
   );
28
 
29
input   [15:0]  adr_w ; // set up to +ve edge
30
input   [39:0]  din;    // set up to +ve edge
31
input           write_en;       // +ve edge clk; write enable
32
input           rst_tri_en; // used to gate off writes during SCAN.
33
input   [15:0]  adr_r;  // set up to +ve edge
34
input           read_en;
35
output  [39:0]  dout;
36
input           lookup_en;      // set up to -ve edge
37
input   [39:8]  key;    // set up to -ve edge
38
output  [15:0]  match ;
39
output  [15:0]  match_idx ;
40
input   rclk ;
41
input   sehold, se, si, rst_l;
42
output  so ;
43
 
44
reg     [39:0]  mb_cam_data[15:0] ;
45
 
46
reg     [39:0]  dout;
47
reg     [39:8]  key_d1;
48
reg     lookup_en_d1 ;
49
 
50
reg     [39:0]  tmp_addr ;
51
reg     [39:0]  tmp_addr0 ;
52
reg     [39:0]  tmp_addr1 ;
53
reg     [39:0]  tmp_addr2 ;
54
reg     [39:0]  tmp_addr3 ;
55
reg     [39:0]  tmp_addr4 ;
56
reg     [39:0]  tmp_addr5 ;
57
reg     [39:0]  tmp_addr6 ;
58
reg     [39:0]  tmp_addr7 ;
59
reg     [39:0]  tmp_addr8 ;
60
reg     [39:0]  tmp_addr9 ;
61
reg     [39:0]  tmp_addr10 ;
62
reg     [39:0]  tmp_addr11 ;
63
reg     [39:0]  tmp_addr12 ;
64
reg     [39:0]  tmp_addr13 ;
65
reg     [39:0]  tmp_addr14 ;
66
reg     [39:0]  tmp_addr15 ;
67
 
68
reg     [15:0]  adr_w_d1 ;
69
reg     [15:0]  adr_r_d1 ;
70
reg             mb_wen_d1 ;     // registered write enable
71
reg             mb_ren_d1 ;     // registered read enable
72
 
73
reg     [39:0]  din_d1;
74
 
75
wire    [15:0]  match ;
76
wire    [15:0]  match_idx ;
77
reg     [15:0]  match_p ;
78
reg     [15:0]  match_idx_p ;
79
 
80
reg             so ;
81
reg             rst_l_d1;
82
reg             rst_tri_en_d1;
83
 
84
integer i;
85
 
86
always  @(posedge rclk) begin
87
        adr_w_d1 <= (sehold)? adr_w_d1: adr_w ;
88
        adr_r_d1 <= (sehold)? adr_r_d1: adr_r;
89
        din_d1 <= ( sehold)? din_d1: din ;
90
        mb_wen_d1 <= ( sehold)? mb_wen_d1: write_en ;
91
        mb_ren_d1 <= ( sehold)? mb_ren_d1 : read_en  ;
92
        lookup_en_d1 <= ( sehold)? lookup_en_d1 :lookup_en ;
93
        key_d1 <= ( sehold)? key_d1 : key;
94
 
95
        rst_l_d1 <= rst_l ; // this is not a real flop
96
        rst_tri_en_d1 <= rst_tri_en ; // this is not a real flop
97
 
98
end
99
 
100
assign  match = match_p ;
101
assign  match_idx = match_idx_p ;
102
 
103
// CAM OPERATION
104
 
105
always  @( /*AUTOSENSE*/ /*memory or*/ adr_w_d1 or key_d1
106
          or lookup_en_d1 or mb_wen_d1 or rst_l ) begin
107
 
108
 
109
 
110
        if(~rst_l)      begin
111
                match_p = 16'b0 ;
112
                match_idx_p = 16'b0;
113
        end
114
 
115
 
116
        else if( lookup_en_d1 ) begin
117
 
118
 
119
                tmp_addr0 = mb_cam_data[0];
120
                match_p[0] =  ( mb_wen_d1 & adr_w_d1[0] ) ? 1'bx :
121
                               ( tmp_addr0[39:8] == key_d1[39:8] ) ;
122
                match_idx_p[0] = ( mb_wen_d1 & adr_w_d1[0] ) ? 1'bx :
123
                                 ( tmp_addr0[17:8] == key_d1[17:8] ) ;
124
 
125
                tmp_addr1 = mb_cam_data[1];
126
                match_p[1] =  ( mb_wen_d1 & adr_w_d1[1] ) ? 1'bx :
127
                               ( tmp_addr1[39:8] == key_d1[39:8] ) ;
128
                match_idx_p[1] = ( mb_wen_d1 & adr_w_d1[1] ) ? 1'bx :
129
                                 ( tmp_addr1[17:8] == key_d1[17:8] ) ;
130
 
131
                tmp_addr2 = mb_cam_data[2];
132
                match_p[2] =  ( mb_wen_d1 & adr_w_d1[2] ) ? 1'bx :
133
                               ( tmp_addr2[39:8] == key_d1[39:8] ) ;
134
                match_idx_p[2] = ( mb_wen_d1 & adr_w_d1[2] ) ? 1'bx :
135
                                 ( tmp_addr2[17:8] == key_d1[17:8] ) ;
136
 
137
                tmp_addr3 = mb_cam_data[3];
138
                match_p[3] =  ( mb_wen_d1 & adr_w_d1[3] ) ? 1'bx :
139
                               ( tmp_addr3[39:8] == key_d1[39:8] ) ;
140
                match_idx_p[3] = ( mb_wen_d1 & adr_w_d1[3] ) ? 1'bx :
141
                                 ( tmp_addr3[17:8] == key_d1[17:8] ) ;
142
 
143
                tmp_addr4 = mb_cam_data[4];
144
                match_p[4] =  ( mb_wen_d1 & adr_w_d1[4] ) ? 1'bx :
145
                               ( tmp_addr4[39:8] == key_d1[39:8] ) ;
146
                match_idx_p[4] = ( mb_wen_d1 & adr_w_d1[4] ) ? 1'bx :
147
                                 ( tmp_addr4[17:8] == key_d1[17:8] ) ;
148
 
149
                tmp_addr5 = mb_cam_data[5];
150
                match_p[5] =  ( mb_wen_d1 & adr_w_d1[5] ) ? 1'bx :
151
                               ( tmp_addr5[39:8] == key_d1[39:8] ) ;
152
                match_idx_p[5] = ( mb_wen_d1 & adr_w_d1[5] ) ? 1'bx :
153
                                 ( tmp_addr5[17:8] == key_d1[17:8] ) ;
154
 
155
                tmp_addr6 = mb_cam_data[6];
156
                match_p[6] =  ( mb_wen_d1 & adr_w_d1[6] ) ? 1'bx :
157
                               ( tmp_addr6[39:8] == key_d1[39:8] ) ;
158
                match_idx_p[6] = ( mb_wen_d1 & adr_w_d1[6] ) ? 1'bx :
159
                                 ( tmp_addr6[17:8] == key_d1[17:8] ) ;
160
 
161
                tmp_addr7 = mb_cam_data[7];
162
                match_p[7] =  ( mb_wen_d1 & adr_w_d1[7] ) ? 1'bx :
163
                               ( tmp_addr7[39:8] == key_d1[39:8] ) ;
164
                match_idx_p[7] = ( mb_wen_d1 & adr_w_d1[7] ) ? 1'bx :
165
                                 ( tmp_addr7[17:8] == key_d1[17:8] ) ;
166
 
167
                tmp_addr8 = mb_cam_data[8];
168
                match_p[8] =  ( mb_wen_d1 & adr_w_d1[8] ) ? 1'bx :
169
                               ( tmp_addr8[39:8] == key_d1[39:8] ) ;
170
                match_idx_p[8] = ( mb_wen_d1 & adr_w_d1[8] ) ? 1'bx :
171
                                 ( tmp_addr8[17:8] == key_d1[17:8] ) ;
172
 
173
                tmp_addr9 = mb_cam_data[9];
174
                match_p[9] =  ( mb_wen_d1 & adr_w_d1[9] ) ? 1'bx :
175
                               ( tmp_addr9[39:8] == key_d1[39:8] ) ;
176
                match_idx_p[9] = ( mb_wen_d1 & adr_w_d1[9] ) ? 1'bx :
177
                                 ( tmp_addr9[17:8] == key_d1[17:8] ) ;
178
 
179
                tmp_addr10 = mb_cam_data[10];
180
                match_p[10] =  ( mb_wen_d1 & adr_w_d1[10] ) ? 1'bx :
181
                               ( tmp_addr10[39:8] == key_d1[39:8] ) ;
182
                match_idx_p[10] = ( mb_wen_d1 & adr_w_d1[10] ) ? 1'bx :
183
                                 ( tmp_addr10[17:8] == key_d1[17:8] ) ;
184
 
185
                tmp_addr11 = mb_cam_data[11];
186
                match_p[11] =  ( mb_wen_d1 & adr_w_d1[11] ) ? 1'bx :
187
                               ( tmp_addr11[39:8] == key_d1[39:8] ) ;
188
                match_idx_p[11] = ( mb_wen_d1 & adr_w_d1[11] ) ? 1'bx :
189
                                 ( tmp_addr11[17:8] == key_d1[17:8] ) ;
190
 
191
                tmp_addr12 = mb_cam_data[12];
192
                match_p[12] =  ( mb_wen_d1 & adr_w_d1[12] ) ? 1'bx :
193
                               ( tmp_addr12[39:8] == key_d1[39:8] ) ;
194
                match_idx_p[12] = ( mb_wen_d1 & adr_w_d1[12] ) ? 1'bx :
195
                                 ( tmp_addr12[17:8] == key_d1[17:8] ) ;
196
 
197
                tmp_addr13 = mb_cam_data[13];
198
                match_p[13] =  ( mb_wen_d1 & adr_w_d1[13] ) ? 1'bx :
199
                               ( tmp_addr13[39:8] == key_d1[39:8] ) ;
200
                match_idx_p[13] = ( mb_wen_d1 & adr_w_d1[13] ) ? 1'bx :
201
                                 ( tmp_addr13[17:8] == key_d1[17:8] ) ;
202
 
203
                tmp_addr14 = mb_cam_data[14];
204
                match_p[14] =  ( mb_wen_d1 & adr_w_d1[14] ) ? 1'bx :
205
                               ( tmp_addr14[39:8] == key_d1[39:8] ) ;
206
                match_idx_p[14] = ( mb_wen_d1 & adr_w_d1[14] ) ? 1'bx :
207
                                 ( tmp_addr14[17:8] == key_d1[17:8] ) ;
208
 
209
                tmp_addr15 = mb_cam_data[15];
210
                match_p[15] =  ( mb_wen_d1 & adr_w_d1[15] ) ? 1'bx :
211
                               ( tmp_addr15[39:8] == key_d1[39:8] ) ;
212
                match_idx_p[15] = ( mb_wen_d1 & adr_w_d1[15] ) ? 1'bx :
213
                                 ( tmp_addr15[17:8] == key_d1[17:8] ) ;
214
        end
215
 
216
        else begin
217
                match_p = 16'b0;
218
                match_idx_p = 16'b0;
219
        end
220
 
221
end
222
 
223
 
224
// READ AND WRITE HAPPEN in Phase 1.
225
 
226
// rst_tri_en_d1 & rst_l_d1 are part of the 
227
// list because we want to enter the following
228
// always block under the following condition:
229
// - adr_w_d1 , din_d1 , mb_wen_d1 remain the same across the
230
// rising edge of the clock
231
// - rst_tri_en or rst_l change across the rising edge of the
232
// clock from high to low.
233
 
234
always  @(adr_w_d1 or din_d1 or mb_wen_d1  or rst_tri_en_d1 or rst_l_d1 ) begin
235
  begin
236
    if (mb_wen_d1  & ~rst_tri_en & rst_l ) begin
237
        case(adr_w_d1 )
238
          16'b0000_0000_0000_0000: ;  // do nothing
239
          16'b0000_0000_0000_0001: mb_cam_data[0] = din_d1 ;
240
          16'b0000_0000_0000_0010: mb_cam_data[1] = din_d1 ;
241
          16'b0000_0000_0000_0100: mb_cam_data[2] = din_d1 ;
242
          16'b0000_0000_0000_1000: mb_cam_data[3] = din_d1 ;
243
          16'b0000_0000_0001_0000: mb_cam_data[4] = din_d1;
244
          16'b0000_0000_0010_0000: mb_cam_data[5] = din_d1 ;
245
          16'b0000_0000_0100_0000: mb_cam_data[6] = din_d1 ;
246
          16'b0000_0000_1000_0000: mb_cam_data[7] = din_d1 ;
247
          16'b0000_0001_0000_0000: mb_cam_data[8] = din_d1 ;
248
          16'b0000_0010_0000_0000: mb_cam_data[9] = din_d1 ;
249
          16'b0000_0100_0000_0000: mb_cam_data[10] = din_d1 ;
250
          16'b0000_1000_0000_0000: mb_cam_data[11] = din_d1 ;
251
          16'b0001_0000_0000_0000: mb_cam_data[12] = din_d1 ;
252
          16'b0010_0000_0000_0000: mb_cam_data[13] = din_d1 ;
253
          16'b0100_0000_0000_0000: mb_cam_data[14] = din_d1 ;
254
          16'b1000_0000_0000_0000: mb_cam_data[15] = din_d1 ;
255
          //
256
          //16'b1111_1111_1111_1111:
257
           //     begin
258
           //             mb_cam_data[15] = din_d1 ;
259
           //             mb_cam_data[14] = din_d1 ;
260
           //             mb_cam_data[13] = din_d1 ;
261
           //             mb_cam_data[12] = din_d1 ;
262
           //             mb_cam_data[11] = din_d1 ;
263
           //             mb_cam_data[10] = din_d1 ;
264
           //             mb_cam_data[9] = din_d1 ;
265
           //             mb_cam_data[8] = din_d1 ;
266
           //             mb_cam_data[7] = din_d1 ;
267
           //             mb_cam_data[6] = din_d1 ;
268
           //             mb_cam_data[5] = din_d1 ;
269
           //             mb_cam_data[4] = din_d1 ;
270
           //             mb_cam_data[3] = din_d1 ;
271
           //             mb_cam_data[2] = din_d1 ;
272
           //             mb_cam_data[1] = din_d1 ;
273
           //             mb_cam_data[0] = din_d1 ;
274
           //     end
275
          default:
276
             // 0in <fire -message "FATAL ERROR: incorrect write wordline"
277
`ifdef DEFINE_0IN
278
             ;
279
`else
280
`ifdef  INNO_MUXEX
281
             ;
282
`else
283
                `ifdef MODELSIM
284
            $display("PH1_CAM2_ERROR"," incorrect write wordline %h ", adr_w_d1);
285
                `else
286
            $error("PH1_CAM2_ERROR"," incorrect write wordline %h ", adr_w_d1);
287
                `endif
288
`endif
289
`endif
290
 
291
        endcase
292
      end
293
  end
294
 
295
end
296
 
297
 
298
// rst_l_d1 has purely been added so that we enter the always 
299
// block when the wordline/wr_en does not change across clk cycles
300
// but the rst_l does.  
301
// Notice rst_l_d1 is not used in any of the "if" statements.
302
// Notice that the renable is qualified with rclk to take 
303
// care that we do not read from the array if rst_l goes high
304
// during the negative phase of rclk. 
305
// 
306
 
307
always  @( /*memory or*/ adr_r_d1 or adr_w_d1
308
          or mb_ren_d1 or mb_wen_d1 or rst_l_d1 or rst_l or rst_tri_en_d1) begin
309
  if(~rst_l ) begin
310
        dout = 40'b0 ;
311
  end
312
  else if (mb_ren_d1 & rclk & rst_tri_en ) begin
313
                dout = 40'hff_ffff_ffff ;
314
  end
315
  else if (mb_ren_d1 & rclk & ~rst_tri_en ) begin
316
    if ((mb_wen_d1) && (adr_r_d1 == adr_w_d1) && (adr_r_d1) )
317
      begin
318
             dout = 40'bx ;
319
 
320
`ifdef DEFINE_0IN
321
`else
322
`ifdef  INNO_MUXEX
323
`else
324
                `ifdef MODELSIM
325
             $display("PH1_CAM2_ERROR"," read write conflict %h ", adr_r_d1);
326
                `else
327
             $error("PH1_CAM2_ERROR"," read write conflict %h ", adr_r_d1);
328
                `endif
329
`endif
330
`endif
331
      end
332
    else
333
      begin
334
        case(adr_r_d1)
335
          // match sense amp ckt behavior when no read wl is selected
336
          16'b0000_0000_0000_0000: dout = 40'hff_ffff_ffff ;
337
          16'b0000_0000_0000_0001: dout = mb_cam_data[0] ;
338
          16'b0000_0000_0000_0010: dout = mb_cam_data[1] ;
339
          16'b0000_0000_0000_0100: dout = mb_cam_data[2] ;
340
          16'b0000_0000_0000_1000: dout = mb_cam_data[3] ;
341
          16'b0000_0000_0001_0000: dout = mb_cam_data[4] ;
342
          16'b0000_0000_0010_0000: dout = mb_cam_data[5] ;
343
          16'b0000_0000_0100_0000: dout = mb_cam_data[6] ;
344
          16'b0000_0000_1000_0000: dout = mb_cam_data[7] ;
345
          16'b0000_0001_0000_0000: dout = mb_cam_data[8] ;
346
          16'b0000_0010_0000_0000: dout = mb_cam_data[9] ;
347
          16'b0000_0100_0000_0000: dout = mb_cam_data[10] ;
348
          16'b0000_1000_0000_0000: dout = mb_cam_data[11] ;
349
          16'b0001_0000_0000_0000: dout = mb_cam_data[12] ;
350
          16'b0010_0000_0000_0000: dout = mb_cam_data[13] ;
351
          16'b0100_0000_0000_0000: dout = mb_cam_data[14] ;
352
          16'b1000_0000_0000_0000: dout = mb_cam_data[15] ;
353
          default:
354
             // 0in <fire -message "FATAL ERROR: incorrect read wordline"
355
`ifdef DEFINE_0IN
356
             ;
357
`else
358
`ifdef  INNO_MUXEX
359
             ;
360
`else
361
                `ifdef MODELSIM
362
             $display("PH1_CAM2_ERROR"," incorrect read wordline %h ", adr_r_d1);
363
                `else
364
             $error("PH1_CAM2_ERROR"," incorrect read wordline %h ", adr_r_d1);
365
                `endif
366
`endif
367
`endif
368
 
369
        endcase
370
      end
371
 
372
        end // of else if
373
end
374
endmodule

powered by: WebSVN 2.1.0

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