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

Revision 6, 13.8 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_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 ============================================
21module 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
29input   [15:0]  adr_w ; // set up to +ve edge
30input   [39:0]  din;    // set up to +ve edge
31input           write_en;       // +ve edge clk; write enable
32input           rst_tri_en; // used to gate off writes during SCAN.
33input   [15:0]  adr_r;  // set up to +ve edge
34input           read_en;
35output  [39:0]  dout;
36input           lookup_en;      // set up to -ve edge
37input   [39:8]  key;    // set up to -ve edge
38output  [15:0]  match ;
39output  [15:0]  match_idx ;
40input   rclk ;
41input   sehold, se, si, rst_l;
42output  so ;
43
44reg     [39:0]  mb_cam_data[15:0] ;
45
46reg     [39:0]  dout;
47reg     [39:8]  key_d1;
48reg     lookup_en_d1 ;
49
50reg     [39:0]  tmp_addr ;
51reg     [39:0]  tmp_addr0 ;
52reg     [39:0]  tmp_addr1 ;
53reg     [39:0]  tmp_addr2 ;
54reg     [39:0]  tmp_addr3 ;
55reg     [39:0]  tmp_addr4 ;
56reg     [39:0]  tmp_addr5 ;
57reg     [39:0]  tmp_addr6 ;
58reg     [39:0]  tmp_addr7 ;
59reg     [39:0]  tmp_addr8 ;
60reg     [39:0]  tmp_addr9 ;
61reg     [39:0]  tmp_addr10 ;
62reg     [39:0]  tmp_addr11 ;
63reg     [39:0]  tmp_addr12 ;
64reg     [39:0]  tmp_addr13 ;
65reg     [39:0]  tmp_addr14 ;
66reg     [39:0]  tmp_addr15 ;
67
68reg     [15:0]  adr_w_d1 ;
69reg     [15:0]  adr_r_d1 ;
70reg             mb_wen_d1 ;     // registered write enable
71reg             mb_ren_d1 ;     // registered read enable
72
73reg     [39:0]  din_d1;
74
75wire    [15:0]  match ;
76wire    [15:0]  match_idx ;
77reg     [15:0]  match_p ;
78reg     [15:0]  match_idx_p ;
79
80reg             so ;
81reg             rst_l_d1;
82reg             rst_tri_en_d1;
83
84integer i;
85
86always  @(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       
98end
99
100assign  match = match_p ;
101assign  match_idx = match_idx_p ;
102
103// CAM OPERATION
104
105always  @( /*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
221end
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
234always  @(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
295end
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
307always  @( /*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
373end
374endmodule
Note: See TracBrowser for help on using the repository browser.