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

Revision 6, 12.0 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

Line 
1// ========== 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
28module 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
36input   [15:0]  adr_w ; // set up to +ve edge
37input   [39:0]  din;    // set up to +ve edge
38input           write_en;       // +ve edge clk; write enable
39input           rst_tri_en;
40input   [15:0]  adr_r;  // set up to +ve edge
41input           read_en;
42output  [39:0]  dout;
43input           lookup_en;      // set up to -ve edge
44input   [39:8]  key;    // set up to -ve edge
45output  [15:0]  match ;
46output  [15:0]  match_idx ;
47input   rclk ;
48input   sehold, se, si, rst_l;
49output  so ;
50
51reg     [39:0]  mb_cam_data[15:0] ;
52
53reg     [39:0]  dout;
54reg     [39:8]  key_d1;
55reg     lookup_en_d1 ;
56
57reg     [39:0]  tmp_addr ;
58reg     [39:0]  tmp_addr0 ;
59reg     [39:0]  tmp_addr1 ;
60reg     [39:0]  tmp_addr2 ;
61reg     [39:0]  tmp_addr3 ;
62reg     [39:0]  tmp_addr4 ;
63reg     [39:0]  tmp_addr5 ;
64reg     [39:0]  tmp_addr6 ;
65reg     [39:0]  tmp_addr7 ;
66reg     [39:0]  tmp_addr8 ;
67reg     [39:0]  tmp_addr9 ;
68reg     [39:0]  tmp_addr10 ;
69reg     [39:0]  tmp_addr11 ;
70reg     [39:0]  tmp_addr12 ;
71reg     [39:0]  tmp_addr13 ;
72reg     [39:0]  tmp_addr14 ;
73reg     [39:0]  tmp_addr15 ;
74
75reg     [15:0]  adr_w_d1 ;
76reg     [15:0]  adr_r_d1 ;
77reg             mb_wen_d1 ;     // registered write enable
78reg             mb_ren_d1 ;     // registered read enable
79
80reg     [39:0]  din_d1;
81
82reg     [15:0]  match ;
83reg     [15:0]  match_idx ;
84reg     [15:0]  match_p ;
85reg     [15:0]  match_idx_p ;
86
87reg             so ;
88
89reg             rst_l_d1;
90reg             rst_tri_en_d1;
91
92
93always  @(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
107end
108
109
110// CAM OPERATION
111
112`ifdef DEFINE_0IN
113always  @( negedge rclk         ) begin
114`else
115always  @( 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
199end
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
211always  @(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
271end
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
284always  @( /*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
350end
351endmodule
352
353
354
Note: See TracBrowser for help on using the repository browser.