[6] | 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... |
---|
[27] | 296 | always @( byte_overlap or ramc_entry,cam_tag or cam_bmask or ptag_hit or byte_match or stb_ramc_d) |
---|
[6] | 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 |
---|