1 | // ========== Copyright Header Begin ========================================== |
---|
2 | // |
---|
3 | // OpenSPARC T1 Processor File: bw_r_scm.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 | // Description: Store Buffer of Load/Store Unit (CAM Side) |
---|
24 | // - Physically divided into CAM and DATA RAMs. |
---|
25 | // - CAM RAM has a single cam port and a single |
---|
26 | // port for read/writes. The cam port is for loads, |
---|
27 | // write for stores, read for test/diagnostic purposes. |
---|
28 | // rd or write can be simultaneous with cam. can rd and cam |
---|
29 | // a single entry simultaneously. cannot write and cam |
---|
30 | // the same entry. |
---|
31 | // - DATA RAM read occurs for a load raw match in the |
---|
32 | // stb CAM RAM. DATA RAM write occurs a store. Both |
---|
33 | // actions are architecturally guaranteed to be |
---|
34 | // mutex. |
---|
35 | // - Write occurs simultaneously to both arrays. |
---|
36 | // - Reads are not necessarily simultaneous and are |
---|
37 | // controlled by individual read signals. |
---|
38 | // - Certain bits are maintained outside the array |
---|
39 | // in the stb's control section, such as the valid |
---|
40 | // bits. |
---|
41 | // |
---|
42 | */ |
---|
43 | |
---|
44 | //////////////////////////////////////////////////////////////////////// |
---|
45 | // Local header file includes / local defines |
---|
46 | //////////////////////////////////////////////////////////////////////// |
---|
47 | |
---|
48 | //FPGA_SYN enables all FPGA related modifications |
---|
49 | `ifdef FPGA_SYN |
---|
50 | `define FPGA_SYN_SCM |
---|
51 | `endif |
---|
52 | |
---|
53 | module bw_r_scm (/*AUTOARG*/ |
---|
54 | // Outputs |
---|
55 | stb_rdata_ramc, stb_ld_full_raw, stb_ld_partial_raw, |
---|
56 | stb_cam_hit_ptr, stb_cam_hit, stb_cam_mhit, |
---|
57 | // Inputs |
---|
58 | stb_cam_data, stb_alt_wr_data, stb_camwr_data, stb_alt_wsel, |
---|
59 | stb_cam_vld, stb_cam_cm_tid, stb_cam_sqsh_msk, stb_cam_rw_ptr, |
---|
60 | stb_cam_wptr_vld, stb_cam_rptr_vld, stb_cam_rw_tid, |
---|
61 | stb_quad_ld_cam, rclk, rst_tri_en |
---|
62 | ) ; |
---|
63 | |
---|
64 | parameter NUMENTRIES = 32 ; // number of entries in stb |
---|
65 | |
---|
66 | input [44:15] stb_cam_data ; // data for compare; disjoint msb |
---|
67 | input [44:15] stb_alt_wr_data ; // data for compare; disjoint msb |
---|
68 | input [14:0] stb_camwr_data ; // data for compare/write; common lsb |
---|
69 | input stb_alt_wsel ; |
---|
70 | input stb_cam_vld ; // cam is required. |
---|
71 | input [1:0] stb_cam_cm_tid ; // thread id for cam operation. |
---|
72 | input [7:0] stb_cam_sqsh_msk; // mask for squashing cam results. |
---|
73 | |
---|
74 | input [2:0] stb_cam_rw_ptr ; // wr pointer for single port. |
---|
75 | input stb_cam_wptr_vld ;// write pointer vld |
---|
76 | input stb_cam_rptr_vld ;// write pointer vld |
---|
77 | input [1:0] stb_cam_rw_tid ; // thread id for rw. |
---|
78 | input stb_quad_ld_cam ; // quad-ld cam. |
---|
79 | |
---|
80 | input rclk ; // clock |
---|
81 | |
---|
82 | //input scan_ena ; // no longer required ! |
---|
83 | //input [7:0] adj ; |
---|
84 | |
---|
85 | input rst_tri_en ; |
---|
86 | |
---|
87 | output [44:0] stb_rdata_ramc ; // rd data from CAM RAM. |
---|
88 | // raw output is muxed on a thread basis. |
---|
89 | output [7:0] stb_ld_full_raw ; // ld with full raw. |
---|
90 | output [7:0] stb_ld_partial_raw ; // ld with partial raw. |
---|
91 | output [2:0] stb_cam_hit_ptr ; |
---|
92 | output stb_cam_hit ; // any hit in stb |
---|
93 | output stb_cam_mhit ; // multiple hits in stb |
---|
94 | |
---|
95 | |
---|
96 | /*UTOREG*/ |
---|
97 | // Beginning of automatic regs (for this module's undeclared outputs) |
---|
98 | // End of automatics |
---|
99 | reg [44:0] stb_rdata_ramc ; |
---|
100 | reg [31:0] rw_wdline ; |
---|
101 | reg [44:0] stb_ramc [NUMENTRIES-1:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */; |
---|
102 | reg [44:0] ramc_entry ; |
---|
103 | reg [36:0] cam_tag ; |
---|
104 | reg [31:0] ptag_hit ; |
---|
105 | reg [7:0] cam_bmask ; |
---|
106 | reg [31:0] byte_match ; |
---|
107 | reg [31:0] byte_overlap ; |
---|
108 | reg [31:0] ld_full_raw ; |
---|
109 | reg [31:0] ld_partial_raw ; |
---|
110 | reg [44:15] alt_wr_data ; |
---|
111 | wire [44:15] pipe_wr_data ; |
---|
112 | reg [14:0] camwr_data ; |
---|
113 | reg wptr_vld ; |
---|
114 | reg rptr_vld_tmp ; |
---|
115 | reg [1:0] cam_tid ; |
---|
116 | reg [1:0] cam_vld ; |
---|
117 | reg alt_wsel ; |
---|
118 | |
---|
119 | wire rptr_vld ; |
---|
120 | wire ldq ; |
---|
121 | wire [7:0] sqsh_msk ; |
---|
122 | wire [7:0] ld_full_raw_mx ; |
---|
123 | wire [7:0] ld_partial_raw_mx ; |
---|
124 | wire [7:0] ptag_hit_mx ; |
---|
125 | wire [7:0] byte_overlap_mx ; |
---|
126 | wire [7:0] byte_match_mx ; |
---|
127 | wire [7:0] cam_hit ; |
---|
128 | wire [44:0] wdata_ramc ; |
---|
129 | wire [44:0] cam_data ; |
---|
130 | wire [44:15] wr_data ; |
---|
131 | `ifdef FPGA_SYN_SCM |
---|
132 | reg [4:0] stb_addr; |
---|
133 | `endif |
---|
134 | |
---|
135 | |
---|
136 | integer i,j,k,l ; |
---|
137 | |
---|
138 | |
---|
139 | wire scan_ena ; |
---|
140 | assign scan_ena = 1'b0 ; |
---|
141 | |
---|
142 | //========================================================================================= |
---|
143 | // generate wordlines |
---|
144 | //========================================================================================= |
---|
145 | |
---|
146 | assign sqsh_msk[7:0] = stb_cam_sqsh_msk[7:0]; |
---|
147 | |
---|
148 | // cam_vld and cam_tid_tmp are set-up a phase earlier. |
---|
149 | // Comment out - Now setup to posedge. |
---|
150 | /*always @(negedge clk) |
---|
151 | begin |
---|
152 | cam_tid_tmp[1:0] <= stb_cam_cm_tid[1:0] ; |
---|
153 | cam_vld_tmp <= stb_cam_vld ; |
---|
154 | end */ |
---|
155 | |
---|
156 | `ifdef FPGA_SYN_SCM |
---|
157 | `else |
---|
158 | // Wordlines need to be generated locally |
---|
159 | always @ (posedge rclk) |
---|
160 | begin |
---|
161 | for (i=0;i<32;i=i+1) |
---|
162 | begin |
---|
163 | if ({stb_cam_rw_tid[1:0],stb_cam_rw_ptr[2:0]} == i) |
---|
164 | rw_wdline[i] <= 1'b1; |
---|
165 | else |
---|
166 | rw_wdline[i] <= 1'b0; |
---|
167 | end |
---|
168 | end |
---|
169 | `endif |
---|
170 | |
---|
171 | assign pipe_wr_data[44:15] = stb_cam_data[44:15]; |
---|
172 | |
---|
173 | always @(posedge rclk) |
---|
174 | begin |
---|
175 | alt_wr_data[44:15] <= stb_alt_wr_data[44:15]; |
---|
176 | camwr_data[14:0] <= stb_camwr_data[14:0]; |
---|
177 | wptr_vld <= stb_cam_wptr_vld ; |
---|
178 | rptr_vld_tmp <= stb_cam_rptr_vld ; |
---|
179 | cam_tid[1:0] <= stb_cam_cm_tid[1:0] ; |
---|
180 | //cam_tid[1:0] <= cam_tid_tmp[1:0] ; |
---|
181 | //ldq <= stb_quad_ld_cam ; Bug 2870 |
---|
182 | alt_wsel <= stb_alt_wsel ; |
---|
183 | `ifdef FPGA_SYN_SCM |
---|
184 | stb_addr <= {stb_cam_rw_tid[1:0],stb_cam_rw_ptr[2:0]}; |
---|
185 | `endif |
---|
186 | end |
---|
187 | |
---|
188 | assign ldq = stb_quad_ld_cam ; |
---|
189 | assign rptr_vld = rptr_vld_tmp | rst_tri_en ; |
---|
190 | |
---|
191 | //========================================================================================= |
---|
192 | // write or read to/from memory |
---|
193 | //========================================================================================= |
---|
194 | |
---|
195 | // For blk-st, select out-of-pipe. |
---|
196 | assign wr_data[44:15] = alt_wsel ? |
---|
197 | alt_wr_data[44:15] : pipe_wr_data[44:15] ; |
---|
198 | |
---|
199 | assign wdata_ramc[44:0] = {wr_data[44:15],camwr_data[14:0]}; |
---|
200 | |
---|
201 | // Write |
---|
202 | always @ (negedge rclk) |
---|
203 | begin |
---|
204 | `ifdef FPGA_SYN_SCM |
---|
205 | if(wptr_vld) begin |
---|
206 | if(~rst_tri_en) begin |
---|
207 | stb_ramc[stb_addr] <= wdata_ramc[44:0]; |
---|
208 | stb_rdata_ramc[44:0] <= wdata_ramc[44:0]; |
---|
209 | end else begin |
---|
210 | stb_rdata_ramc[44:0] <= stb_ramc[stb_addr]; |
---|
211 | end |
---|
212 | end |
---|
213 | `else |
---|
214 | for (j=0;j<NUMENTRIES;j=j+1) |
---|
215 | begin |
---|
216 | if (rw_wdline[j] & wptr_vld) |
---|
217 | begin |
---|
218 | if (~rst_tri_en) |
---|
219 | begin |
---|
220 | stb_ramc[j] <= wdata_ramc[44:0]; |
---|
221 | // write data is write-thru |
---|
222 | stb_rdata_ramc[44:0] <= wdata_ramc[44:0]; |
---|
223 | end |
---|
224 | else |
---|
225 | begin |
---|
226 | // INNO - default rd if wr squashed by scan_ena. |
---|
227 | stb_rdata_ramc[44:0] <= stb_ramc[j]; |
---|
228 | end |
---|
229 | end |
---|
230 | end |
---|
231 | `endif |
---|
232 | // Read |
---|
233 | `ifdef FPGA_SYN_SCM |
---|
234 | if(rptr_vld & ~scan_ena) begin |
---|
235 | if (rptr_vld & wptr_vld & ~rst_tri_en) begin |
---|
236 | stb_rdata_ramc[44:0] <= wdata_ramc[44:0]; |
---|
237 | end |
---|
238 | else begin |
---|
239 | stb_rdata_ramc[44:0] <= stb_ramc[stb_addr]; |
---|
240 | end |
---|
241 | end |
---|
242 | `else |
---|
243 | for (k=0;k<NUMENTRIES;k=k+1) |
---|
244 | begin |
---|
245 | if (rw_wdline[k] & rptr_vld & ~scan_ena) |
---|
246 | begin |
---|
247 | if (rptr_vld & wptr_vld & ~rst_tri_en) // INNO - write-thru |
---|
248 | stb_rdata_ramc[44:0] <= wdata_ramc[44:0]; |
---|
249 | else |
---|
250 | stb_rdata_ramc[44:0] <= stb_ramc[k]; |
---|
251 | end |
---|
252 | end |
---|
253 | `endif |
---|
254 | end |
---|
255 | |
---|
256 | //========================================================================================= |
---|
257 | // CAM contents of CAM RAM |
---|
258 | //========================================================================================= |
---|
259 | |
---|
260 | // - Generate full/partial raw for incoming load. |
---|
261 | // - Output signals need to be qualified with per entry |
---|
262 | // vlds before causing any subsequent event, the read of |
---|
263 | // the DATA RAM specifically. |
---|
264 | // - full_raw & vld will cause rd of DATA RAM. |
---|
265 | // - partial_raw & vld will cause ld to follow corresponding |
---|
266 | // st on way out to xbar. |
---|
267 | // - logic to generate partial and full raws may be done outside |
---|
268 | // but that would require an additional signal per entry to |
---|
269 | // be output. |
---|
270 | |
---|
271 | // Mapping of cam/write data |
---|
272 | // |
---|
273 | // | 40-3=37b(pa) | 1b(stquad) | 8b(bytemask) | <- use |
---|
274 | // | 45:9 | 8 | 7:0 | <- input port |
---|
275 | // **^ stquad rm'ed |
---|
276 | |
---|
277 | reg [14:0] stb_camwr_data_d; |
---|
278 | reg ldq_d; |
---|
279 | reg stb_cam_vld_d; |
---|
280 | reg scan_ena_d; |
---|
281 | reg [44:0] stb_ramc_d [NUMENTRIES-1:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */; |
---|
282 | |
---|
283 | always @(posedge rclk) |
---|
284 | begin |
---|
285 | stb_camwr_data_d[14:0]<=stb_camwr_data[14:0]; |
---|
286 | ldq_d<=ldq; |
---|
287 | stb_cam_vld_d<=stb_cam_vld; |
---|
288 | scan_ena_d<=scan_ena; |
---|
289 | for (l=0;l<NUMENTRIES;l=l+1) |
---|
290 | stb_ramc_d[l]<=stb_ramc[l]; |
---|
291 | end |
---|
292 | |
---|
293 | assign cam_data[44:0] = {stb_cam_data[44:15],stb_camwr_data_d[14:0]}; |
---|
294 | |
---|
295 | // tolgo stb_ramc_d dalla sensitivity list... |
---|
296 | always @( byte_overlap or ramc_entry,cam_tag or cam_bmask or ptag_hit or byte_match or stb_ramc_d) |
---|
297 | begin |
---|
298 | for (l=0;l<NUMENTRIES;l=l+1) |
---|
299 | begin |
---|
300 | ramc_entry[44:0] = stb_ramc_d[l] ; |
---|
301 | cam_tag[36:0] = ramc_entry[44:8] ; |
---|
302 | cam_bmask[7:0] = ramc_entry[7:0] ; |
---|
303 | ptag_hit[l] = (cam_tag[36:1] == cam_data[44:9]) & |
---|
304 | (((cam_tag[0] == cam_data[8]) & ~ldq_d) | ldq_d) & stb_cam_vld_d & ~scan_ena_d ; |
---|
305 | byte_match[l] = |(cam_bmask[7:0] & cam_data[7:0]) & stb_cam_vld_d & ~scan_ena_d ; |
---|
306 | // Simplification : |
---|
307 | byte_overlap[l] = |(~cam_bmask[7:0] & cam_data[7:0]) & stb_cam_vld_d & ~scan_ena_d ; |
---|
308 | end |
---|
309 | end |
---|
310 | // Mux the raw signals down to 8b quantities. Squash mask comes mid-way thru cycle. |
---|
311 | |
---|
312 | assign byte_overlap_mx[7:0] = |
---|
313 | (cam_tid[1:0] == 2'b00) ? byte_overlap[7:0] : |
---|
314 | (cam_tid[1:0] == 2'b01) ? byte_overlap[15:8] : |
---|
315 | (cam_tid[1:0] == 2'b10) ? byte_overlap[23:16] : |
---|
316 | (cam_tid[1:0] == 2'b11) ? byte_overlap[31:24] : 8'bxxxx_xxxx ; |
---|
317 | |
---|
318 | assign byte_match_mx[7:0] = |
---|
319 | (cam_tid[1:0] == 2'b00) ? byte_match[7:0] : |
---|
320 | (cam_tid[1:0] == 2'b01) ? byte_match[15:8] : |
---|
321 | (cam_tid[1:0] == 2'b10) ? byte_match[23:16] : |
---|
322 | (cam_tid[1:0] == 2'b11) ? byte_match[31:24] : 8'bxxxx_xxxx ; |
---|
323 | |
---|
324 | assign ptag_hit_mx[7:0] = |
---|
325 | (cam_tid[1:0] == 2'b00) ? ptag_hit[7:0] : |
---|
326 | (cam_tid[1:0] == 2'b01) ? ptag_hit[15:8] : |
---|
327 | (cam_tid[1:0] == 2'b10) ? ptag_hit[23:16] : |
---|
328 | (cam_tid[1:0] == 2'b11) ? ptag_hit[31:24] : 8'bxxxx_xxxx ; |
---|
329 | |
---|
330 | assign stb_ld_full_raw[7:0] = |
---|
331 | ptag_hit_mx[7:0] & byte_match_mx[7:0] & ~byte_overlap_mx[7:0] & ~sqsh_msk[7:0] ; |
---|
332 | assign stb_ld_partial_raw[7:0] = |
---|
333 | ptag_hit_mx[7:0] & byte_match_mx[7:0] & byte_overlap_mx[7:0] & ~sqsh_msk[7:0] ; |
---|
334 | |
---|
335 | assign cam_hit[7:0] = |
---|
336 | ptag_hit_mx[7:0] & byte_match_mx[7:0] & ~sqsh_msk[7:0] ; |
---|
337 | assign stb_cam_hit = |(cam_hit[7:0]); |
---|
338 | |
---|
339 | // The stb data is meant to be read for single hit full raw case. It may actually be read |
---|
340 | // for full raw, partial raw or multiple hit case but the read output will be ignored for |
---|
341 | // partial and multiple hit case. Multiple hits will not cause a hazard as the ptr is first |
---|
342 | // encoded and then decoded to form the wdline for the stb-data |
---|
343 | // Use cam_hit result to void false hits. |
---|
344 | assign stb_cam_hit_ptr[0] = cam_hit[1] | cam_hit[3] | cam_hit[5] | cam_hit[7] ; |
---|
345 | assign stb_cam_hit_ptr[1] = cam_hit[2] | cam_hit[3] | cam_hit[6] | cam_hit[7] ; |
---|
346 | assign stb_cam_hit_ptr[2] = cam_hit[4] | cam_hit[5] | cam_hit[6] | cam_hit[7] ; |
---|
347 | |
---|
348 | //Generating multiple hits |
---|
349 | assign stb_cam_mhit = (cam_hit[0] & cam_hit[1]) | (cam_hit[2] & cam_hit[3]) | |
---|
350 | (cam_hit[4] & cam_hit[5]) | (cam_hit[6] & cam_hit[7]) | |
---|
351 | ((cam_hit[0] | cam_hit[1]) & (cam_hit[2] | cam_hit[3])) | |
---|
352 | ((cam_hit[4] | cam_hit[5]) & (cam_hit[6] | cam_hit[7])) | |
---|
353 | ((|cam_hit[3:0]) & (|cam_hit[7:4])); |
---|
354 | |
---|
355 | //-------------------------------------------------------------- |
---|
356 | // Error Checking. |
---|
357 | //-------------------------------------------------------------- |
---|
358 | |
---|
359 | // 1. simultaneous rd/wr on single port - terminate |
---|
360 | // 2. simultaneous cam and wr - terminate |
---|
361 | // * PUT OUTSIDE OF SRAM RTL, AS RST NOT AVAILABLE. * |
---|
362 | |
---|
363 | endmodule |
---|