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

Subversion Repositories sparc64soc

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

powered by: WebSVN 2.1.0

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