[6] | 1 | // ========== Copyright Header Begin ========================================== |
---|
| 2 | // |
---|
| 3 | // OpenSPARC T1 Processor File: lsu_stb_ctl.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: Control for STB of LSU |
---|
| 24 | // - Contains control for a single STB currently. |
---|
| 25 | */ |
---|
| 26 | //////////////////////////////////////////////////////////////////////// |
---|
| 27 | // Global header file includes |
---|
| 28 | //////////////////////////////////////////////////////////////////////// |
---|
| 29 | `include "sys.h" // system level definition file which contains the |
---|
| 30 | // time scale definition |
---|
| 31 | |
---|
| 32 | `include "iop.h" |
---|
| 33 | //////////////////////////////////////////////////////////////////////// |
---|
| 34 | // Local header file includes / local defines |
---|
| 35 | //////////////////////////////////////////////////////////////////////// |
---|
| 36 | |
---|
| 37 | module lsu_stb_ctl (/*AUTOARG*/ |
---|
| 38 | // Outputs |
---|
| 39 | so, stb_clk_en_l, stb_crnt_ack_id, lsu_stb_empty, stb_l2bnk_addr, |
---|
| 40 | stb_atm_rq_type, stb_wrptr, stb_rd_for_pcx, stb_pcx_rptr, |
---|
| 41 | stb_wrptr_prev, stb_state_ced_mod, stb_state_vld_out, |
---|
| 42 | lsu_stbcnt, stb_rmo_st_issue, stb_full, st_pcx_rq_kill_w2, |
---|
| 43 | // Inputs |
---|
| 44 | rclk, grst_l, arst_l, si, se, thrd_en_g, cpx_st_ack_tid, |
---|
| 45 | pcx_rq_for_stb, st_ack_dq_stb, stb_flush_st_g, stb_cam_wvld_m, |
---|
| 46 | lsu_blk_st_m, tlb_pgnum_g, pcx_req_squash, flshinst_rst, |
---|
| 47 | lsu_stbctl_flush_pipe_w, flsh_inst_m, stb_state_si_0, |
---|
| 48 | stb_state_si_1, stb_state_si_2, stb_state_si_3, stb_state_si_4, |
---|
| 49 | stb_state_si_5, stb_state_si_6, stb_state_si_7, stb_state_rtype_0, |
---|
| 50 | stb_state_rtype_1, stb_state_rtype_2, stb_state_rtype_3, |
---|
| 51 | stb_state_rtype_4, stb_state_rtype_5, stb_state_rtype_6, |
---|
| 52 | stb_state_rtype_7, stb_state_rmo, stb_alt_sel, stb_alt_addr, |
---|
| 53 | lsu_dtlb_bypass_e, tlb_cam_hit, lsu_outstanding_rmo_st_max, |
---|
| 54 | st_dtlb_perr_g |
---|
| 55 | ) ; |
---|
| 56 | |
---|
| 57 | |
---|
| 58 | input rclk ; |
---|
| 59 | input grst_l; |
---|
| 60 | input arst_l; |
---|
| 61 | |
---|
| 62 | input si; |
---|
| 63 | input se; |
---|
| 64 | output so; |
---|
| 65 | |
---|
| 66 | input thrd_en_g ; |
---|
| 67 | input cpx_st_ack_tid ; // st ack for given thread |
---|
| 68 | input pcx_rq_for_stb ; // stb's st selected for read for pcx |
---|
| 69 | input st_ack_dq_stb ; // store dequeued from stb |
---|
| 70 | input stb_flush_st_g ; // flush stb write in cycle g |
---|
| 71 | input stb_cam_wvld_m ; // stb write in cycle m |
---|
| 72 | |
---|
| 73 | input lsu_blk_st_m ; // blk st wr |
---|
| 74 | |
---|
| 75 | //input [7:6] lsu_ldst_va_m ; // staging purposes |
---|
| 76 | //input [2:1] lsu_st_rq_type_m ; // st request type |
---|
| 77 | //input lsu_st_rmo_m ; // rmo store in m-stage |
---|
| 78 | |
---|
| 79 | input [39:37] tlb_pgnum_g ; // ldst access to io |
---|
| 80 | input pcx_req_squash ; // pcx req is squashed |
---|
| 81 | |
---|
| 82 | input flshinst_rst ; // reset by flush inst on return |
---|
| 83 | input lsu_stbctl_flush_pipe_w ; |
---|
| 84 | |
---|
| 85 | input flsh_inst_m; |
---|
| 86 | |
---|
| 87 | |
---|
| 88 | //from stb_ctldp |
---|
| 89 | input [3:2] stb_state_si_0; |
---|
| 90 | input [3:2] stb_state_si_1; |
---|
| 91 | input [3:2] stb_state_si_2; |
---|
| 92 | input [3:2] stb_state_si_3; |
---|
| 93 | input [3:2] stb_state_si_4; |
---|
| 94 | input [3:2] stb_state_si_5; |
---|
| 95 | input [3:2] stb_state_si_6; |
---|
| 96 | input [3:2] stb_state_si_7; |
---|
| 97 | |
---|
| 98 | input [2:1] stb_state_rtype_0; |
---|
| 99 | input [2:1] stb_state_rtype_1; |
---|
| 100 | input [2:1] stb_state_rtype_2; |
---|
| 101 | input [2:1] stb_state_rtype_3; |
---|
| 102 | input [2:1] stb_state_rtype_4; |
---|
| 103 | input [2:1] stb_state_rtype_5; |
---|
| 104 | input [2:1] stb_state_rtype_6; |
---|
| 105 | input [2:1] stb_state_rtype_7; |
---|
| 106 | |
---|
| 107 | //input [7:0] stb_state_io; |
---|
| 108 | input [7:0] stb_state_rmo; |
---|
| 109 | |
---|
| 110 | input stb_alt_sel ; |
---|
| 111 | input [2:0] stb_alt_addr ; |
---|
| 112 | |
---|
| 113 | input lsu_dtlb_bypass_e; |
---|
| 114 | input tlb_cam_hit; // m-cycle |
---|
| 115 | |
---|
| 116 | input st_dtlb_perr_g ; // enabled st dtlb parity err. |
---|
| 117 | |
---|
| 118 | //output stb_non_l2bnk; |
---|
| 119 | output [7:0] stb_clk_en_l; |
---|
| 120 | |
---|
| 121 | output [2:0] stb_crnt_ack_id ; // ackid for current outstanding st. |
---|
| 122 | |
---|
| 123 | output lsu_stb_empty ; // stb is empty |
---|
| 124 | |
---|
| 125 | output [2:0] stb_l2bnk_addr ; // l2bank address. |
---|
| 126 | output [2:1] stb_atm_rq_type ; // identify atomic transaction |
---|
| 127 | |
---|
| 128 | output [2:0] stb_wrptr ; // write ptr - per thread |
---|
| 129 | //output [2:0] stb_dfq_rptr ; // rptr for dfq - per thread |
---|
| 130 | output stb_rd_for_pcx ; // rd vld for pcx - per thread |
---|
| 131 | output [2:0] stb_pcx_rptr ; // rptr for pcx - per thread |
---|
| 132 | output [2:0] stb_wrptr_prev ; |
---|
| 133 | output [7:0] stb_state_ced_mod ; |
---|
| 134 | output [7:0] stb_state_vld_out ; |
---|
| 135 | |
---|
| 136 | output [3:0] lsu_stbcnt ; // # of vld entries |
---|
| 137 | |
---|
| 138 | output stb_rmo_st_issue ; // rmo store issued from thread's stb. |
---|
| 139 | |
---|
| 140 | output stb_full ; |
---|
| 141 | output st_pcx_rq_kill_w2 ; |
---|
| 142 | |
---|
| 143 | input lsu_outstanding_rmo_st_max; |
---|
| 144 | |
---|
| 145 | wire [7:0] stb_state_rst; |
---|
| 146 | |
---|
| 147 | wire [7:0] stb_state_vld; |
---|
| 148 | wire [7:0] stb_state_vld_din; |
---|
| 149 | wire [7:0] stb_state_vld_set; |
---|
| 150 | |
---|
| 151 | wire [7:0] stb_state_ced; |
---|
| 152 | wire [7:0] stb_state_ced_din; |
---|
| 153 | wire [7:0] stb_state_ced_set; |
---|
| 154 | |
---|
| 155 | wire [7:0] stb_state_ack; |
---|
| 156 | wire [7:0] stb_state_ack_din; |
---|
| 157 | wire [7:0] stb_state_ack_set; |
---|
| 158 | |
---|
| 159 | wire [3:2] stb_state_si_0; // removed 8x4 bits |
---|
| 160 | wire [3:2] stb_state_si_1; |
---|
| 161 | wire [3:2] stb_state_si_2; |
---|
| 162 | wire [3:2] stb_state_si_3; |
---|
| 163 | wire [3:2] stb_state_si_4; |
---|
| 164 | wire [3:2] stb_state_si_5; |
---|
| 165 | wire [3:2] stb_state_si_6; |
---|
| 166 | wire [3:2] stb_state_si_7; |
---|
| 167 | /* |
---|
| 168 | wire [3:2] stb_state_si_0_din; |
---|
| 169 | wire [3:2] stb_state_si_1_din; |
---|
| 170 | wire [3:2] stb_state_si_2_din; |
---|
| 171 | wire [3:2] stb_state_si_3_din; |
---|
| 172 | wire [3:2] stb_state_si_4_din; |
---|
| 173 | wire [3:2] stb_state_si_5_din; |
---|
| 174 | wire [3:2] stb_state_si_6_din; |
---|
| 175 | wire [3:2] stb_state_si_7_din; |
---|
| 176 | */ |
---|
| 177 | wire [7:0] stb_state_io; |
---|
| 178 | wire [7:0] stb_state_io_din; |
---|
| 179 | |
---|
| 180 | wire [7:0] stb_state_rmo; |
---|
| 181 | // wire [7:0] stb_state_rmo_din; |
---|
| 182 | |
---|
| 183 | wire [2:1] stb_state_rtype_0; // rm 8x1 bits |
---|
| 184 | wire [2:1] stb_state_rtype_1; |
---|
| 185 | wire [2:1] stb_state_rtype_2; |
---|
| 186 | wire [2:1] stb_state_rtype_3; |
---|
| 187 | wire [2:1] stb_state_rtype_4; |
---|
| 188 | wire [2:1] stb_state_rtype_5; |
---|
| 189 | wire [2:1] stb_state_rtype_6; |
---|
| 190 | wire [2:1] stb_state_rtype_7; |
---|
| 191 | /* |
---|
| 192 | wire [2:1] stb_state_rtype_0_din; |
---|
| 193 | wire [2:1] stb_state_rtype_1_din; |
---|
| 194 | wire [2:1] stb_state_rtype_2_din; |
---|
| 195 | wire [2:1] stb_state_rtype_3_din; |
---|
| 196 | wire [2:1] stb_state_rtype_4_din; |
---|
| 197 | wire [2:1] stb_state_rtype_5_din; |
---|
| 198 | wire [2:1] stb_state_rtype_6_din; |
---|
| 199 | wire [2:1] stb_state_rtype_7_din; |
---|
| 200 | */ |
---|
| 201 | wire [2:0] stb_l2bnk_addr; |
---|
| 202 | wire [2:1] stb_atm_rq_type; |
---|
| 203 | |
---|
| 204 | /*AUTOWIRE*/ |
---|
| 205 | // Beginning of automatic wires (for undeclared instantiated-module outputs) |
---|
| 206 | // End of automatics |
---|
| 207 | wire [3:0] stb_wptr_prev ; |
---|
| 208 | wire stb_rptr_dfq_en ; |
---|
| 209 | wire update_stb_wptr ; |
---|
| 210 | //wire [1:0] st_enc_set_way ; |
---|
| 211 | wire [3:0] stb_rptr_dfq_new, stb_rptr_dfq ; |
---|
| 212 | wire valid_entry_for_pcx ; |
---|
| 213 | wire [7:0] dec_wptr_g, dec_rptr_dfq, dec_rptr_pcx, dec_ackptr ; |
---|
| 214 | wire [7:0] dec_wptr_m ; |
---|
| 215 | //wire stb_wvld_g ; |
---|
| 216 | //wire [5:0] stb_inv_set0,stb_inv_set1; |
---|
| 217 | //wire [5:0] stb_inv_set2,stb_inv_set3; |
---|
| 218 | |
---|
| 219 | wire ack_vld ; |
---|
| 220 | wire [3:0] stb_wptr_new, stb_wptr ; |
---|
| 221 | wire stb_cam_wvld_g ; |
---|
| 222 | wire [7:0] inflight_vld_g ; |
---|
| 223 | wire dq_vld_d1,dq_vld_d2 ; |
---|
| 224 | wire [7:0] dqptr_d1,dqptr_d2; |
---|
| 225 | wire pcx_rq_for_stb_d1 ; |
---|
| 226 | wire pcx_rq_for_stb_d2,pcx_req_squash_d2 ; |
---|
| 227 | |
---|
| 228 | wire clk; |
---|
| 229 | assign clk = rclk; |
---|
| 230 | |
---|
| 231 | wire rst_l; |
---|
| 232 | wire stb_ctl_rst_l; |
---|
| 233 | |
---|
| 234 | dffrl_async rstff(.din (grst_l), |
---|
| 235 | .q (stb_ctl_rst_l), |
---|
| 236 | .clk (clk), .se(se), .si(), .so(), |
---|
| 237 | .rst_l (arst_l)); |
---|
| 238 | assign rst_l = stb_ctl_rst_l; |
---|
| 239 | |
---|
| 240 | //========================================================================================= |
---|
| 241 | // RESET |
---|
| 242 | //========================================================================================= |
---|
| 243 | |
---|
| 244 | // A flush will reset the vld bit in the stb - it should be the only one as |
---|
| 245 | // the stb has drained. |
---|
| 246 | |
---|
| 247 | wire reset; |
---|
| 248 | //waiting int 3.0 |
---|
| 249 | //assign rst_l = stb_ctl_rst_l; |
---|
| 250 | |
---|
| 251 | assign reset = ~rst_l | flshinst_rst ; |
---|
| 252 | |
---|
| 253 | //========================================================================================= |
---|
| 254 | // STB READ FOR PCX |
---|
| 255 | //========================================================================================= |
---|
| 256 | |
---|
| 257 | // Assumes that an entry can be sent to the pcx iff the next oldest |
---|
| 258 | // entry has received its ack. This pointer will not look for L2Bank |
---|
| 259 | // overlap as the ptr calculation is much more complicated. |
---|
| 260 | |
---|
| 261 | // (1)--> Entry must be valid and not already sent to pcx. |
---|
| 262 | // Includes squashing of speculative req |
---|
| 263 | // (2)--> Previous in linked list must be valid and acked (or invalid) |
---|
| 264 | // (3)--> This is to break the deadlock between oldest and youngest |
---|
| 265 | // entries when queue is full. Oldest entry can always exit to pcx. |
---|
| 266 | |
---|
| 267 | // This vector is one-hot. Assumption is that stb is a circular queue. |
---|
| 268 | // deadlock has to be broken between oldest and youngest entry when the |
---|
| 269 | // queue is full. The dfq ptr is used to mark oldest |
---|
| 270 | |
---|
| 271 | dff_s #(2) rq_stgd1 ( |
---|
| 272 | .din ({pcx_rq_for_stb_d1,pcx_req_squash}), |
---|
| 273 | .q ({pcx_rq_for_stb_d2,pcx_req_squash_d2}), |
---|
| 274 | .clk (clk), |
---|
| 275 | .se (se), .si (), .so () |
---|
| 276 | ); |
---|
| 277 | |
---|
| 278 | wire ffu_bst_wr_g ; |
---|
| 279 | dff_s #(1) ff_bstg ( |
---|
| 280 | .din (lsu_blk_st_m), |
---|
| 281 | .q (ffu_bst_wr_g), |
---|
| 282 | .clk (clk), |
---|
| 283 | .se (se), .si (), .so () |
---|
| 284 | ); |
---|
| 285 | |
---|
| 286 | wire full_flush_st_g ; |
---|
| 287 | // flush_pipe does not apply to blk st wr. |
---|
| 288 | assign full_flush_st_g = (stb_flush_st_g | (lsu_stbctl_flush_pipe_w & ~ffu_bst_wr_g)) & stb_cam_wvld_g ; |
---|
| 289 | |
---|
| 290 | // timing fix: 5/6 - begin |
---|
| 291 | // qual dec_rptr_pcx w/ tlb camhit and in qctl1 move kill qual after store pick |
---|
| 292 | wire tlb_cam_hit_g, tlb_hit_g; |
---|
| 293 | wire dtlb_bypass_m, dtlb_bypass_g ; |
---|
| 294 | |
---|
| 295 | dff_s #(1) ff_dtlb_bypass_m ( |
---|
| 296 | .din (lsu_dtlb_bypass_e), |
---|
| 297 | .q (dtlb_bypass_m), |
---|
| 298 | .clk (clk), |
---|
| 299 | .se (se), .si (), .so () |
---|
| 300 | ); |
---|
| 301 | |
---|
| 302 | dff_s #(1) ff_dtlb_bypass_g ( |
---|
| 303 | .din (dtlb_bypass_m), |
---|
| 304 | .q (dtlb_bypass_g), |
---|
| 305 | .clk (clk), |
---|
| 306 | .se (se), .si (), .so () |
---|
| 307 | ); |
---|
| 308 | |
---|
| 309 | dff_s #(1) ff_tlb_cam_hit_g ( |
---|
| 310 | .din (tlb_cam_hit), |
---|
| 311 | .q (tlb_cam_hit_g), |
---|
| 312 | .clk (clk), |
---|
| 313 | .se (se), .si (), .so () |
---|
| 314 | ); |
---|
| 315 | |
---|
| 316 | assign tlb_hit_g = tlb_cam_hit_g | dtlb_bypass_g | ffu_bst_wr_g; //bug6406/eco6610 |
---|
| 317 | // timing fix: 5/6 - end |
---|
| 318 | |
---|
| 319 | // st rq can now speculate on flush |
---|
| 320 | assign inflight_vld_g[7:0] = |
---|
| 321 | dec_wptr_g[7:0] & {8{stb_cam_wvld_g & thrd_en_g}} ; |
---|
| 322 | // the later term is for an inflight ld which gets squashed. It |
---|
| 323 | // should not effect dec_rptr_pcx. This is related to a timing fix |
---|
| 324 | // where the flush is taken out of inflight_vld_g. |
---|
| 325 | //assign inflight_vld_g[7:0] = dec_wptr_g[7:0] & {8{stb_wvld_g & thrd_en_g}} ; |
---|
| 326 | |
---|
| 327 | //timing fix: 5/6/03 - kill inflight vld if tlb_hit_g=0; dec_rptr_pcx will be 0 and hence kill_w2 will be 0 |
---|
| 328 | // leave inflight_vld_g as is, since it is used to set squash - which eventually reset state_vld |
---|
| 329 | wire [7:0] inflight_issue_g_tmp ; |
---|
| 330 | |
---|
| 331 | assign inflight_issue_g_tmp[7:0] = inflight_vld_g[7:0] & {8{tlb_hit_g}}; |
---|
| 332 | |
---|
| 333 | wire [7:0] inflight_issue_g ; |
---|
| 334 | assign inflight_issue_g[7:0] = |
---|
| 335 | inflight_issue_g_tmp[7:0] & {8{~(|(stb_state_vld[7:0] & ~stb_state_ack[7:0]))}}; |
---|
| 336 | //inflight_vld_g[7:0] & {8{~(|(stb_state_vld[7:0] & ~stb_state_ack[7:0]))}}; // timing fix : 5/6 |
---|
| 337 | |
---|
| 338 | |
---|
| 339 | // Modified state ced includes in-flight pcx sel which is not squashed. |
---|
| 340 | // Timing : pcx_req_squash delayed. A st that is squashed can then make a request 3-cycles |
---|
| 341 | // later. |
---|
| 342 | wire skid_ced, st_vld_rq_d2 ; |
---|
| 343 | assign st_vld_rq_d2 = pcx_rq_for_stb_d2 & ~pcx_req_squash_d2 ; |
---|
| 344 | assign skid_ced = pcx_rq_for_stb_d1 | st_vld_rq_d2 ; |
---|
| 345 | // For squashing rawp. |
---|
| 346 | assign stb_state_ced_mod[7:0] = |
---|
| 347 | ((dec_ackptr[7:0] & {8{st_vld_rq_d2}}) | stb_state_ced[7:0]) ; |
---|
| 348 | |
---|
| 349 | //RMO st counter satuated |
---|
| 350 | |
---|
| 351 | wire rmo_st_satuated; |
---|
| 352 | //dff #(1) rmo_st_satuated_ff ( |
---|
| 353 | // .din (lsu_outstanding_rmo_st_max), |
---|
| 354 | // .q (rmo_st_satuated), |
---|
| 355 | // .clk (clk), |
---|
| 356 | // .se (se), .si (), .so () |
---|
| 357 | //); |
---|
| 358 | |
---|
| 359 | assign rmo_st_satuated = lsu_outstanding_rmo_st_max; |
---|
| 360 | |
---|
| 361 | wire [7:0] stb_state_ced_spec ; |
---|
| 362 | assign stb_state_ced_spec[7:0] = |
---|
| 363 | ((dec_ackptr[7:0] & {8{skid_ced}}) | stb_state_ced[7:0]) | |
---|
| 364 | (stb_state_rmo[7:0] & {8{rmo_st_satuated}}); |
---|
| 365 | |
---|
| 366 | assign dec_rptr_pcx[7:0] = |
---|
| 367 | (inflight_issue_g[7:0] | stb_state_vld[7:0]) |
---|
| 368 | //(inflight_vld_g[7:0] | stb_state_vld[7:0]) |
---|
| 369 | & ~stb_state_ced_spec[7:0] & // -->(1) |
---|
| 370 | (({stb_state_vld[6:0],stb_state_vld[7]} & // |
---|
| 371 | {stb_state_ack[6:0],stb_state_ack[7]}) // |
---|
| 372 | | ~{stb_state_vld[6:0],stb_state_vld[7]} // -->(2) |
---|
| 373 | | dec_rptr_dfq[7:0]) ; // -->(3) |
---|
| 374 | |
---|
| 375 | |
---|
| 376 | // There should be only one such entry i.e., the vector is 1-hot. |
---|
| 377 | // Incorporate st dtlb parity error. It should not propagate to memory. |
---|
| 378 | // Tracing full_flush_st_g, note that the pointers will not be restored |
---|
| 379 | // correctly for timing reasons - anyway, this is considered unrecoverable. |
---|
| 380 | // Monitor ! |
---|
| 381 | assign valid_entry_for_pcx = |dec_rptr_pcx[7:0] ; |
---|
| 382 | |
---|
| 383 | wire any_inflight_iss_g,any_inflight_iss_w2 ; |
---|
| 384 | assign any_inflight_iss_g = |inflight_vld_g[7:0] ; |
---|
| 385 | wire pick_inflight_iss_g,pick_inflight_iss_w2 ; |
---|
| 386 | assign pick_inflight_iss_g = |(dec_rptr_pcx[7:0] & inflight_issue_g[7:0]) ; |
---|
| 387 | |
---|
| 388 | wire st_pcx_rq_kill_g ; |
---|
| 389 | assign st_pcx_rq_kill_g = pick_inflight_iss_g & full_flush_st_g ; |
---|
| 390 | //assign st_pcx_rq_kill_g = (|(dec_rptr_pcx[7:0] & inflight_issue_g[7:0])) & full_flush_st_g ; |
---|
| 391 | |
---|
| 392 | wire st_vld_squash_g,st_vld_squash_w2 ; |
---|
| 393 | assign st_vld_squash_g = any_inflight_iss_g & full_flush_st_g ; |
---|
| 394 | //assign st_vld_squash_g = (|inflight_vld_g[7:0]) & full_flush_st_g ; |
---|
| 395 | |
---|
| 396 | wire st_pcx_rq_kill_tmp,st_vld_squash_tmp ; |
---|
| 397 | wire st_dtlb_perr_w2 ; |
---|
| 398 | dff_s #(5) stkill_stgd1 ( |
---|
| 399 | .din ({st_pcx_rq_kill_g,st_vld_squash_g, |
---|
| 400 | any_inflight_iss_g,pick_inflight_iss_g,st_dtlb_perr_g}), |
---|
| 401 | .q ({st_pcx_rq_kill_tmp,st_vld_squash_tmp, |
---|
| 402 | any_inflight_iss_w2,pick_inflight_iss_w2,st_dtlb_perr_w2}), |
---|
| 403 | .clk (clk), |
---|
| 404 | .se (se), .si (), .so () |
---|
| 405 | ); |
---|
| 406 | |
---|
| 407 | assign st_pcx_rq_kill_w2 = |
---|
| 408 | st_pcx_rq_kill_tmp | |
---|
| 409 | (pick_inflight_iss_w2 & st_dtlb_perr_w2); |
---|
| 410 | |
---|
| 411 | assign st_vld_squash_w2 = |
---|
| 412 | st_vld_squash_tmp | |
---|
| 413 | (any_inflight_iss_w2 & st_dtlb_perr_w2); |
---|
| 414 | |
---|
| 415 | |
---|
| 416 | // Encode pcx rptr |
---|
| 417 | // ** Timing : Could put flop in rwctl. |
---|
| 418 | assign stb_pcx_rptr[0] = dec_rptr_pcx[1] | dec_rptr_pcx[3] | dec_rptr_pcx[5] | dec_rptr_pcx[7] ; |
---|
| 419 | assign stb_pcx_rptr[1] = dec_rptr_pcx[2] | dec_rptr_pcx[3] | dec_rptr_pcx[6] | dec_rptr_pcx[7] ; |
---|
| 420 | assign stb_pcx_rptr[2] = dec_rptr_pcx[4] | dec_rptr_pcx[5] | dec_rptr_pcx[6] | dec_rptr_pcx[7] ; |
---|
| 421 | |
---|
| 422 | // This is used in qctl. |
---|
| 423 | // Timing : flopped in qctl before use. |
---|
| 424 | assign stb_rd_for_pcx = valid_entry_for_pcx ; |
---|
| 425 | |
---|
| 426 | //========================================================================================= |
---|
| 427 | // STB READ FOR DFQ |
---|
| 428 | //========================================================================================= |
---|
| 429 | |
---|
| 430 | |
---|
| 431 | // Read Pointer to generate the next available entry for the dfq. |
---|
| 432 | // Timing : This should be fine as st_ack_dq_stb is decode out of dfq byp flop. |
---|
| 433 | wire incr_dfq_ptr ; |
---|
| 434 | // stb_rmo_st_issue added for rmo st bug - if critical then add flop. |
---|
| 435 | |
---|
| 436 | // bug2983: incr_dfq_ptr is set by both st_ack_dq_stb and stb_rmo_st_issue |
---|
| 437 | // in the same cycle. this results in losing a dequeue. |
---|
| 438 | // |
---|
| 439 | // fix is to detect rmo store after regular store. issue the rmo |
---|
| 440 | // store and dont reset the rmo store vld until the dequeue of the older |
---|
| 441 | // regular store. |
---|
| 442 | |
---|
| 443 | wire stb_dq_rmo ; |
---|
| 444 | |
---|
| 445 | //assign incr_dfq_ptr = st_ack_dq_stb | stb_rmo_st_issue ; //bug 2983 |
---|
| 446 | assign incr_dfq_ptr = st_ack_dq_stb | stb_dq_rmo ; |
---|
| 447 | |
---|
| 448 | assign stb_rptr_dfq_new[3:0] = stb_rptr_dfq[3:0] + {3'b0, incr_dfq_ptr} ; |
---|
| 449 | //assign stb_rptr_dfq_new[3:0] = stb_rptr_dfq[3:0] + {3'b0, st_ack_dq_stb} ; |
---|
| 450 | |
---|
| 451 | assign stb_rptr_dfq_en = st_ack_dq_stb | incr_dfq_ptr ; |
---|
| 452 | |
---|
| 453 | dffre_s #(4) rptr_d ( |
---|
| 454 | .din (stb_rptr_dfq_new[3:0]),.q (stb_rptr_dfq[3:0]), |
---|
| 455 | .en (stb_rptr_dfq_en), .rst (reset), |
---|
| 456 | .clk (clk), |
---|
| 457 | .se (se), .si (), .so () |
---|
| 458 | ); |
---|
| 459 | |
---|
| 460 | //assign stb_dfq_rptr[2:0] = stb_rptr_dfq_new[2:0] ; |
---|
| 461 | |
---|
| 462 | // Decode Read Ptr |
---|
| 463 | // Generated cycle before actual read. |
---|
| 464 | assign dec_rptr_dfq[0] = ~stb_rptr_dfq[2] & ~stb_rptr_dfq[1] & ~stb_rptr_dfq[0] ; |
---|
| 465 | assign dec_rptr_dfq[1] = ~stb_rptr_dfq[2] & ~stb_rptr_dfq[1] & stb_rptr_dfq[0] ; |
---|
| 466 | assign dec_rptr_dfq[2] = ~stb_rptr_dfq[2] & stb_rptr_dfq[1] & ~stb_rptr_dfq[0] ; |
---|
| 467 | assign dec_rptr_dfq[3] = ~stb_rptr_dfq[2] & stb_rptr_dfq[1] & stb_rptr_dfq[0] ; |
---|
| 468 | assign dec_rptr_dfq[4] = stb_rptr_dfq[2] & ~stb_rptr_dfq[1] & ~stb_rptr_dfq[0] ; |
---|
| 469 | assign dec_rptr_dfq[5] = stb_rptr_dfq[2] & ~stb_rptr_dfq[1] & stb_rptr_dfq[0] ; |
---|
| 470 | assign dec_rptr_dfq[6] = stb_rptr_dfq[2] & stb_rptr_dfq[1] & ~stb_rptr_dfq[0] ; |
---|
| 471 | assign dec_rptr_dfq[7] = stb_rptr_dfq[2] & stb_rptr_dfq[1] & stb_rptr_dfq[0] ; |
---|
| 472 | |
---|
| 473 | // Stge dfq ptr and dq vld by 2-cycles to appropriate invalidation pt |
---|
| 474 | dff_s #(9) dq_stgd1 ( |
---|
| 475 | .din ({dec_rptr_dfq[7:0],st_ack_dq_stb}), |
---|
| 476 | .q ({dqptr_d1[7:0],dq_vld_d1}), |
---|
| 477 | .clk (clk), |
---|
| 478 | .se (se), .si (), .so () |
---|
| 479 | ); |
---|
| 480 | |
---|
| 481 | dff_s #(9) dq_stgd2 ( |
---|
| 482 | .din ({dqptr_d1[7:0],dq_vld_d1}), |
---|
| 483 | .q ({dqptr_d2[7:0],dq_vld_d2}), |
---|
| 484 | .clk (clk), |
---|
| 485 | .se (se), .si (), .so () |
---|
| 486 | ); |
---|
| 487 | |
---|
| 488 | //========================================================================================= |
---|
| 489 | // WPTR FOR STB |
---|
| 490 | //========================================================================================= |
---|
| 491 | |
---|
| 492 | // It is assumed that if there is a store in the pipe, there is a |
---|
| 493 | // free entry in the corresponding stb. Otherwise, the pipe would've |
---|
| 494 | // have stalled for the thread. This is maintained locally instead of in |
---|
| 495 | // stb rw ctl. |
---|
| 496 | |
---|
| 497 | // 00(flush,wr) - no update,01 - +1,10 - d1,11 - no update |
---|
| 498 | // cam or data wr ptr would do. |
---|
| 499 | //assign update_stb_wptr = stb_cam_wvld_m | stb_flush_st_g ; |
---|
| 500 | assign update_stb_wptr = stb_cam_wvld_m ^ (full_flush_st_g | st_dtlb_perr_g); |
---|
| 501 | |
---|
| 502 | assign stb_wptr_new[3:0] = (full_flush_st_g | st_dtlb_perr_g) ? |
---|
| 503 | stb_wptr_prev[3:0] : |
---|
| 504 | stb_wptr[3:0] + {3'b0, stb_cam_wvld_m} ; |
---|
| 505 | |
---|
| 506 | dff_s wvld_stgg ( |
---|
| 507 | .din (stb_cam_wvld_m), .q (stb_cam_wvld_g), |
---|
| 508 | .clk (clk), |
---|
| 509 | .se (se), .si (), .so () |
---|
| 510 | ); |
---|
| 511 | |
---|
| 512 | |
---|
| 513 | //assign stb_wvld_g = stb_cam_wvld_g & ~full_flush_st_g ; |
---|
| 514 | |
---|
| 515 | dffre_s #(4) wptr_new ( |
---|
| 516 | .din (stb_wptr_new[3:0]), .q (stb_wptr[3:0]), |
---|
| 517 | .en (update_stb_wptr), .rst (reset), |
---|
| 518 | .clk (clk), |
---|
| 519 | .se (se), .si (), .so () |
---|
| 520 | ); |
---|
| 521 | |
---|
| 522 | assign stb_wrptr[2:0] = stb_wptr[2:0] ; |
---|
| 523 | |
---|
| 524 | wire [2:0] stb_wptr_m ; |
---|
| 525 | // flush should not be required. If the previous st is flushed then |
---|
| 526 | // the current st should be invalid. |
---|
| 527 | assign stb_wptr_m[2:0] = stb_wptr[2:0] ; |
---|
| 528 | /*assign stb_wptr_m[3:0] = (full_flush_st_g) ? |
---|
| 529 | stb_wptr_prev[3:0] : |
---|
| 530 | stb_wptr[3:0] ;*/ |
---|
| 531 | |
---|
| 532 | // Decode wptr |
---|
| 533 | assign dec_wptr_m[0] = ~stb_wptr_m[2] & ~stb_wptr_m[1] & ~stb_wptr_m[0] ; |
---|
| 534 | assign dec_wptr_m[1] = ~stb_wptr_m[2] & ~stb_wptr_m[1] & stb_wptr_m[0] ; |
---|
| 535 | assign dec_wptr_m[2] = ~stb_wptr_m[2] & stb_wptr_m[1] & ~stb_wptr_m[0] ; |
---|
| 536 | assign dec_wptr_m[3] = ~stb_wptr_m[2] & stb_wptr_m[1] & stb_wptr_m[0] ; |
---|
| 537 | assign dec_wptr_m[4] = stb_wptr_m[2] & ~stb_wptr_m[1] & ~stb_wptr_m[0] ; |
---|
| 538 | assign dec_wptr_m[5] = stb_wptr_m[2] & ~stb_wptr_m[1] & stb_wptr_m[0] ; |
---|
| 539 | assign dec_wptr_m[6] = stb_wptr_m[2] & stb_wptr_m[1] & ~stb_wptr_m[0] ; |
---|
| 540 | assign dec_wptr_m[7] = stb_wptr_m[2] & stb_wptr_m[1] & stb_wptr_m[0] ; |
---|
| 541 | |
---|
| 542 | dff_s #(8) dwptr_stgg ( |
---|
| 543 | .din (dec_wptr_m[7:0]), .q (dec_wptr_g[7:0]), |
---|
| 544 | .clk (clk), |
---|
| 545 | .se (se), .si (), .so () |
---|
| 546 | ); |
---|
| 547 | |
---|
| 548 | // stb_wptr_prev represents the latest valid entry in stb |
---|
| 549 | /*dffre #(4) wptr_prev ( |
---|
| 550 | .din (stb_wptr[3:0]), .q (stb_wptr_prev[3:0]), |
---|
| 551 | .en (update_stb_wptr), .rst (reset), |
---|
| 552 | .clk (clk), |
---|
| 553 | .se (se), .si (), .so () |
---|
| 554 | );*/ |
---|
| 555 | |
---|
| 556 | assign stb_wptr_prev[3:0] = stb_wptr[3:0] - {4'b0001} ; |
---|
| 557 | |
---|
| 558 | // Bug 2419 - In case this is a critical path, a flop can be inserted. |
---|
| 559 | assign stb_wrptr_prev[2:0] = stb_wptr_prev[2:0] ; |
---|
| 560 | |
---|
| 561 | //========================================================================================= |
---|
| 562 | // # OF STORES IN STB |
---|
| 563 | //========================================================================================= |
---|
| 564 | |
---|
| 565 | wire [3:0] stb_wptr_w2 ; |
---|
| 566 | |
---|
| 567 | // Count should not include stores in pipe-stages 'g' or before. |
---|
| 568 | dff_s #(4) wptr_stgw2 ( |
---|
| 569 | .din (stb_wptr[3:0]), .q (stb_wptr_w2[3:0]), |
---|
| 570 | .clk (clk), |
---|
| 571 | .se (se), .si (), .so () |
---|
| 572 | ); |
---|
| 573 | |
---|
| 574 | assign lsu_stbcnt[3:0] = (stb_wptr_w2[3:0] - stb_rptr_dfq[3:0]) ; |
---|
| 575 | |
---|
| 576 | // Performance Cntr Info |
---|
| 577 | wire stb_full_w2 ; |
---|
| 578 | assign stb_full_w2 = lsu_stbcnt[2] & lsu_stbcnt[1] & lsu_stbcnt[0] ; |
---|
| 579 | dff_s sfull ( |
---|
| 580 | .din (stb_full_w2), .q (stb_full), |
---|
| 581 | .clk (clk), |
---|
| 582 | .se (se), .si (), .so () |
---|
| 583 | ); |
---|
| 584 | |
---|
| 585 | //========================================================================================= |
---|
| 586 | // CONTROL STATE |
---|
| 587 | //========================================================================================= |
---|
| 588 | |
---|
| 589 | // (V) - Valid State. Initialized by write and cleared once entry |
---|
| 590 | // has written DFQ and then written the cache. If the store |
---|
| 591 | // will only bypass then it still needs to enter DFQ but |
---|
| 592 | // can be deallocated immediately on entry into DFQ. (1b) |
---|
| 593 | // (A) - (NA) Allocate. Determined on read of cache. May be modified by |
---|
| 594 | // invalidate or st mv'ing to DFQ. The load woust have to |
---|
| 595 | // have same set index and same replacement way to clear A bit. (1b) |
---|
| 596 | // (SI) - cache set index for invalidate/load cam'ing. (6b) |
---|
| 597 | // (WY) - (NA) Allocate way for store. (2b) |
---|
| 598 | // (CED) - Committed to SKB. Entry written to SKB. (1b) |
---|
| 599 | // (ACK) - Ack for store received from L2. (1b) |
---|
| 600 | // (UPD) - (NA) Entry mv'ed to DFQ. (1b) |
---|
| 601 | // (W) - (NA) Wrap bit. (1b) <--- Not used |
---|
| 602 | // * All state needs to be reset when entry is freed. |
---|
| 603 | // |
---|
| 604 | // Total - 14b. |
---|
| 605 | |
---|
| 606 | // ack_id is internally tracked. |
---|
| 607 | // There can only be one outstanding |
---|
| 608 | dffre_s #(8) ackptr_ff ( |
---|
| 609 | .din (dec_rptr_pcx[7:0]), .q (dec_ackptr[7:0]), |
---|
| 610 | .en (pcx_rq_for_stb), .rst (reset), |
---|
| 611 | .clk (clk), |
---|
| 612 | .se (se), .si (), .so () |
---|
| 613 | ); |
---|
| 614 | |
---|
| 615 | |
---|
| 616 | assign ack_vld = cpx_st_ack_tid ; |
---|
| 617 | //assign st_dc_hit_g = lsu_st_hit_g ; |
---|
| 618 | |
---|
| 619 | assign stb_crnt_ack_id[0] = dec_ackptr[1] | dec_ackptr[3] | |
---|
| 620 | dec_ackptr[5] | dec_ackptr[7] ; |
---|
| 621 | assign stb_crnt_ack_id[1] = dec_ackptr[2] | dec_ackptr[3] | |
---|
| 622 | dec_ackptr[6] | dec_ackptr[7] ; |
---|
| 623 | assign stb_crnt_ack_id[2] = dec_ackptr[4] | dec_ackptr[5] | |
---|
| 624 | dec_ackptr[6] | dec_ackptr[7] ; |
---|
| 625 | |
---|
| 626 | // Decode valid dequeue ids arriving from dfq. |
---|
| 627 | |
---|
| 628 | // pa[39:36] |
---|
| 629 | // 0x00-0x7f dram |
---|
| 630 | // 0xa0-0xbf l2csr |
---|
| 631 | // others as non l2 accsess = b39 & ~(~b38 & b37) |
---|
| 632 | // timing fix: stb_non_l2bnk is delayed 1 cycle - gen in w/g cycle |
---|
| 633 | //assign stb_non_l2bnk = stb_alt_sel ? |
---|
| 634 | // stb_alt_addr[2] & ~(~stb_alt_addr[1] & stb_alt_addr[0]) : |
---|
| 635 | // tlb_pgnum_m[39] & ~(~tlb_pgnum_m[38] & tlb_pgnum_m[37]) & ~flsh_inst_m; |
---|
| 636 | |
---|
| 637 | wire [2:0] stb_alt_addr_g; |
---|
| 638 | wire stb_alt_sel_g; |
---|
| 639 | |
---|
| 640 | dff_s #(4) ff_alt_addr_g ( |
---|
| 641 | .din ({stb_alt_sel,stb_alt_addr[2:0]}), |
---|
| 642 | .q ({stb_alt_sel_g,stb_alt_addr_g[2:0]}), |
---|
| 643 | .clk (clk), |
---|
| 644 | .se (se), .si (), .so () |
---|
| 645 | ); |
---|
| 646 | |
---|
| 647 | wire flsh_inst_g; |
---|
| 648 | dff_s #(1) ff_flsh_inst_g ( |
---|
| 649 | .din (flsh_inst_m), |
---|
| 650 | .q (flsh_inst_g), |
---|
| 651 | .clk (clk), |
---|
| 652 | .se (se), .si (), .so () |
---|
| 653 | ); |
---|
| 654 | |
---|
| 655 | wire stb_alt_io_g , tlb_pgnum_io_g ; |
---|
| 656 | |
---|
| 657 | assign stb_alt_io_g = |
---|
| 658 | stb_alt_addr_g[2] & ~(~stb_alt_addr_g[1] & stb_alt_addr_g[0]); |
---|
| 659 | assign tlb_pgnum_io_g = |
---|
| 660 | tlb_pgnum_g[39] & ~(~tlb_pgnum_g[38] & tlb_pgnum_g[37]) & ~flsh_inst_g; |
---|
| 661 | |
---|
| 662 | // used as input to state_io in stb_ctldp |
---|
| 663 | wire stb_non_l2bnk_g; |
---|
| 664 | assign stb_non_l2bnk_g = |
---|
| 665 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 666 | tlb_pgnum_io_g ; |
---|
| 667 | |
---|
| 668 | // used as output to qctl1 - this has to be qual'ed w/dec_rptr_pcx so no x's propagate |
---|
| 669 | //alt_sel_g state_vld comment |
---|
| 670 | // 0 0 select tlb_pgnum_io_g(bypass) |
---|
| 671 | // 0 1 select stb_state_io |
---|
| 672 | // 1 0 select stb_alt_io_g |
---|
| 673 | // 1 1 select stb_alt_io_g |
---|
| 674 | |
---|
| 675 | wire [7:0] stb_l2bnk_addr_b2; |
---|
| 676 | |
---|
| 677 | // inflight (stb_alt / tlb) |
---|
| 678 | // stb |
---|
| 679 | // bug3875 |
---|
| 680 | assign stb_l2bnk_addr_b2[0] = |
---|
| 681 | stb_state_vld[0] ? stb_state_io[0] : |
---|
| 682 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 683 | tlb_pgnum_io_g ; |
---|
| 684 | |
---|
| 685 | assign stb_l2bnk_addr_b2[1] = |
---|
| 686 | stb_state_vld[1] ? stb_state_io[1] : |
---|
| 687 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 688 | tlb_pgnum_io_g ; |
---|
| 689 | |
---|
| 690 | assign stb_l2bnk_addr_b2[2] = |
---|
| 691 | stb_state_vld[2] ? stb_state_io[2] : |
---|
| 692 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 693 | tlb_pgnum_io_g ; |
---|
| 694 | |
---|
| 695 | assign stb_l2bnk_addr_b2[3] = |
---|
| 696 | stb_state_vld[3] ? stb_state_io[3] : |
---|
| 697 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 698 | tlb_pgnum_io_g ; |
---|
| 699 | |
---|
| 700 | assign stb_l2bnk_addr_b2[4] = |
---|
| 701 | stb_state_vld[4] ? stb_state_io[4] : |
---|
| 702 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 703 | tlb_pgnum_io_g ; |
---|
| 704 | |
---|
| 705 | assign stb_l2bnk_addr_b2[5] = |
---|
| 706 | stb_state_vld[5] ? stb_state_io[5] : |
---|
| 707 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 708 | tlb_pgnum_io_g ; |
---|
| 709 | |
---|
| 710 | assign stb_l2bnk_addr_b2[6] = |
---|
| 711 | stb_state_vld[6] ? stb_state_io[6] : |
---|
| 712 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 713 | tlb_pgnum_io_g ; |
---|
| 714 | |
---|
| 715 | assign stb_l2bnk_addr_b2[7] = |
---|
| 716 | stb_state_vld[7] ? stb_state_io[7] : |
---|
| 717 | stb_alt_sel_g ? stb_alt_io_g : |
---|
| 718 | tlb_pgnum_io_g ; |
---|
| 719 | |
---|
| 720 | |
---|
| 721 | dff_s rqsel_stgg ( |
---|
| 722 | .din (pcx_rq_for_stb), .q (pcx_rq_for_stb_d1), |
---|
| 723 | .clk (clk), |
---|
| 724 | .se (se), .si (), .so () |
---|
| 725 | ); |
---|
| 726 | |
---|
| 727 | // Use of tlb_pgnum_m will be critical !!! |
---|
| 728 | |
---|
| 729 | //always @( posedge clk) |
---|
| 730 | // begin |
---|
| 731 | // for (i=0;i<8;i=i+1) |
---|
| 732 | // begin |
---|
| 733 | // if (reset // reset |
---|
| 734 | // | (dqptr_d2[i] & dq_vld_d2) // dequeue from stb |
---|
| 735 | // | (dec_ackptr[i] & pcx_rq_for_stb_d1 & |
---|
| 736 | // ~pcx_req_squash & stb_state_rmo[i])) |
---|
| 737 | // // write will be visible in cache. |
---|
| 738 | // begin |
---|
| 739 | // stb_state_vld[i] <= 1'b0 ; |
---|
| 740 | // stb_state_ced[i] <= 1'b0 ; |
---|
| 741 | // stb_state_ack[i] <= 1'b0 ; |
---|
| 742 | // end |
---|
| 743 | // if (dec_wptr_g[i] & stb_wvld_g & thrd_en_g ) |
---|
| 744 | // begin |
---|
| 745 | // stb_state_vld[i] <= 1'b1 ; |
---|
| 746 | // stb_state_wy[i] <= st_enc_set_way[1:0]; |
---|
| 747 | // end |
---|
| 748 | // if (dec_wptr_m[i] & stb_cam_wvld_m) // spec. write |
---|
| 749 | // begin |
---|
| 750 | // stb_state_si[i] <= lsu_ldst_va_m[9:4] ; |
---|
| 751 | // stb_state_rtype[i] <= lsu_st_rq_type_m[2:0] ; |
---|
| 752 | // stb_state_io[i] <= non_l2bnk ; |
---|
| 753 | // stb_state_rmo[i] <= lsu_st_rmo_m ; |
---|
| 754 | // end |
---|
| 755 | // // atomic will not write to cache even if it hits. |
---|
| 756 | // // rd_for_pcx needs to be gated for a cycle. |
---|
| 757 | // // This is delayed by a cycle to take into account |
---|
| 758 | // // squashing of speculative requests. |
---|
| 759 | // // rmo's will dequeue entry immediately. |
---|
| 760 | // if (dec_ackptr[i] & pcx_rq_for_stb_d1 & ~pcx_req_squash & ~stb_state_rmo[i]) |
---|
| 761 | // stb_state_ced[i] = 1'b1 ; |
---|
| 762 | // if (dec_ackptr[i] & ack_vld) |
---|
| 763 | // stb_state_ack[i] = 1'b1 ; |
---|
| 764 | |
---|
| 765 | // end |
---|
| 766 | // end |
---|
| 767 | |
---|
| 768 | // UNIFY : mux select destination address of pcx pkt |
---|
| 769 | |
---|
| 770 | // always->dff translation begin |
---|
| 771 | |
---|
| 772 | // ================================= |
---|
| 773 | // rst set din |
---|
| 774 | // 0 0 q |
---|
| 775 | // 1 0 0 (reset) |
---|
| 776 | // x 1 1 (set) |
---|
| 777 | // ================================== |
---|
| 778 | // din = set | (~r & q) |
---|
| 779 | |
---|
| 780 | //vld |
---|
| 781 | wire [7:0] stb_issue_rmo ; |
---|
| 782 | wire [7:0] flush_vld_w2 ; |
---|
| 783 | // Timing |
---|
| 784 | assign stb_issue_rmo[7:0] = |
---|
| 785 | (dec_ackptr[7:0] & {8{st_vld_rq_d2}} & stb_state_rmo[7:0]) ; |
---|
| 786 | // (dec_ackptr[7:0] & {8{pcx_rq_for_stb_d1}} & |
---|
| 787 | // {8{~pcx_req_squash}} & stb_state_rmo[7:0]) ; |
---|
| 788 | assign stb_rmo_st_issue = |stb_issue_rmo[7:0] ; |
---|
| 789 | |
---|
| 790 | //bug2983 - begin |
---|
| 791 | wire rmo_pend,rmo_pend_d1; |
---|
| 792 | wire [7:0] rmo_pend_ackptr , stb_dq_rmo_dfq_ptr; |
---|
| 793 | // this will set 1 cycle after pcx_rq_for_stb and before the corresponding ced is set(which is 2 cycles |
---|
| 794 | // after pcx_rq_for_stb |
---|
| 795 | //bug3249: dec_rptr_dfq catches up w/ dec_ackptr; i.e. dec_ackptr entry is the oldset. rmo_pend should not |
---|
| 796 | // be set in this case based on previuos entry (since it will be the youngest) |
---|
| 797 | // fix - kill pend if issue and dq ptr are same (~{8{|(dec_ackptr[7:0] & dec_rptr_dfq[7:0])}}) |
---|
| 798 | assign rmo_pend_ackptr[7:0] = |
---|
| 799 | // is the current req RMO store |
---|
| 800 | //(dec_ackptr[7:0] & stb_state_rmo[7:0]) & //bug3249 |
---|
| 801 | //(dec_ackptr[7:0] & stb_state_rmo[7:0] & ~dec_rptr_dfq[7:0]) & //bug7100 new fix, bug7117 |
---|
| 802 | (dec_ackptr[7:0] & stb_state_rmo[7:0] & ~dqptr_d2[7:0]) & |
---|
| 803 | // is the older store a regular store |
---|
| 804 | ({stb_state_vld[6:0],stb_state_vld[7]} & ~{stb_state_rmo[6:0],stb_state_rmo[7]}); |
---|
| 805 | |
---|
| 806 | assign rmo_pend = |rmo_pend_ackptr[7:0]; |
---|
| 807 | |
---|
| 808 | wire rmo_pend_rst; |
---|
| 809 | assign rmo_pend_rst = reset | stb_dq_rmo; |
---|
| 810 | |
---|
| 811 | dffre_s #(1) ff_rmo_pend ( |
---|
| 812 | .din (rmo_pend), |
---|
| 813 | .q (rmo_pend_d1), |
---|
| 814 | .en (st_vld_rq_d2), |
---|
| 815 | .rst (rmo_pend_rst), |
---|
| 816 | .clk (clk), |
---|
| 817 | .se (se), .si (), .so () |
---|
| 818 | ); |
---|
| 819 | |
---|
| 820 | // ok to use either dec_ackptr[7:0] OR dec_rptr_dfq[7:0] 'cos the stores younger to 1st RMO store |
---|
| 821 | // are not issued ('cos vld of RMO store is not reset). Hence ackptr and rptr_dfq will be the same |
---|
| 822 | // when rmo_pend=0. |
---|
| 823 | // |
---|
| 824 | // has to qual'ed w/ st_vld_rq_d2. otherwise can result in vld reset before ced is set. the next |
---|
| 825 | // time the entry is used it will have ced=1 and not issue. |
---|
| 826 | // |
---|
| 827 | // cannot use rmo_pend_ackptr[7:0] instead of dec_ackptr[7:0] 'cos the former will be reset when |
---|
| 828 | // rmo_pend=0 and will not dequeue the rmo stb entry. i.e if rmo_pend=1 when st_vld_rq_d2=1, use |
---|
| 829 | // dec_ackptr[7:0] |
---|
| 830 | |
---|
| 831 | //------------------------------------------------------------------------------------------------ |
---|
| 832 | // Case 1: NO older regular store vld dequeue pending |
---|
| 833 | //------------------------------------------------------------------------------------------------ |
---|
| 834 | // | 1 | 2 | 3 | 4 | 5 | | | |
---|
| 835 | // stb_state_vld=8'h1------------------------------------->8'h0 |
---|
| 836 | // stb_state_rmo=8'h1 |
---|
| 837 | // |
---|
| 838 | // pcx_rq_for_stb=1-------->0 |
---|
| 839 | // |
---|
| 840 | // dec_ackptr=8'h0--------->8'h1 |
---|
| 841 | // |
---|
| 842 | // st_vld_rq_d2=0--------------------->1 0 |
---|
| 843 | // stb_issue_rmo=8'h0-------------->8'h1 8'h0 |
---|
| 844 | // stb_dq_rmo_dfq_ptr=8'h0--------->8'h1 8'h0 |
---|
| 845 | // |
---|
| 846 | // rmo_pend=0 |
---|
| 847 | // rmo_pend_d1=0 |
---|
| 848 | // |
---|
| 849 | // dq_vld_d2=0 |
---|
| 850 | // dqptr_d2=8'h0 |
---|
| 851 | //------------------------------------------------------------------------------------------------ |
---|
| 852 | // Case 2: older regular store vld dequeue pending(entry0-older reg store; entry1-rmo younger store) |
---|
| 853 | //------------------------------------------------------------------------------------------------ |
---|
| 854 | // | 1 | 2 | 3 | 4 | 5 | 6 | | |
---|
| 855 | // stb_state_vld=8'h3-------------------------------------->8'h2 8'h0 |
---|
| 856 | // stb_state_rmo=8'h2 |
---|
| 857 | // stb_state_ack=8'h1-------------------------------------->8'h0 |
---|
| 858 | // |
---|
| 859 | // pcx_rq_for_stb=1-------------->0 |
---|
| 860 | // |
---|
| 861 | // dec_ackptr=8'h1------------>8'h2 |
---|
| 862 | // |
---|
| 863 | // st_vld_rq_d2=0-------------------------->1 0 |
---|
| 864 | // stb_issue_rmo=8'h0------------------->8'h1 8'h0 |
---|
| 865 | // stb_dq_rmo_dfq_ptr=8'h0--------------------------------->8'h2 8'h0 (dequeue rmo store) |
---|
| 866 | // |
---|
| 867 | // rmo_pend=0-------------------->1 0 |
---|
| 868 | // rmo_pend_d1=0--------------------------->1 0 |
---|
| 869 | // |
---|
| 870 | // dq_vld_d2=0-------------------------------------->1 0 |
---|
| 871 | // dqptr_d2=8'h0--------------------------------->8'h1 8'h0 (dequeue regular store) |
---|
| 872 | //------------------------------------------------------------------------------------------------ |
---|
| 873 | |
---|
| 874 | assign stb_dq_rmo_dfq_ptr[7:0] = |
---|
| 875 | (stb_issue_rmo[7:0] & ~rmo_pend_ackptr[7:0]) | // if rmo_pend=0 when st_vld_rq_d2=1 |
---|
| 876 | (dec_ackptr[7:0] & {8{rmo_pend_d1 & ~rmo_pend}}); // if rmo_pend=1 when st_vld_rq_d2=1 |
---|
| 877 | |
---|
| 878 | assign stb_dq_rmo = |stb_dq_rmo_dfq_ptr[7:0]; |
---|
| 879 | //bug2983 - end |
---|
| 880 | |
---|
| 881 | assign stb_state_rst[7:0] = |
---|
| 882 | {8{reset}} | (dqptr_d2[7:0] & {8{dq_vld_d2}}) |
---|
| 883 | // reset vld,ced,ack immed. on issue to pcx for rmo store. |
---|
| 884 | | stb_dq_rmo_dfq_ptr[7:0] | // fix for bug2983 |
---|
| 885 | // | stb_issue_rmo[7:0] | // bug2983 |
---|
| 886 | flush_vld_w2[7:0] ; // because of trap |
---|
| 887 | |
---|
| 888 | // vld is now speculatively written |
---|
| 889 | assign stb_state_vld_set[7:0] = dec_wptr_g[7:0] & {8{stb_cam_wvld_g & thrd_en_g}} ; |
---|
| 890 | //assign stb_state_vld_set[7:0] = dec_wptr_g[7:0] & {8{stb_wvld_g & thrd_en_g}} ; |
---|
| 891 | assign stb_state_vld_din[7:0] = stb_state_vld_set[7:0] | |
---|
| 892 | (~stb_state_rst[7:0] & stb_state_vld[7:0]); |
---|
| 893 | |
---|
| 894 | wire [7:0] stb_state_vld_tmp ; |
---|
| 895 | dff_s #(8) ff_stb_state_vld ( |
---|
| 896 | .din (stb_state_vld_din[7:0]), |
---|
| 897 | .q (stb_state_vld_tmp[7:0] ), |
---|
| 898 | .clk (clk), |
---|
| 899 | .se (se), .si (), .so () |
---|
| 900 | ); |
---|
| 901 | |
---|
| 902 | assign stb_state_vld[7:0] = stb_state_vld_tmp[7:0] & ~flush_vld_w2[7:0] ; |
---|
| 903 | |
---|
| 904 | wire [7:0] stb_state_vld_set_w2 ; |
---|
| 905 | dff_s #(8) ff_stb_state_vld_set ( |
---|
| 906 | .din (stb_state_vld_set[7:0]), |
---|
| 907 | .q (stb_state_vld_set_w2[7:0] ), |
---|
| 908 | .clk (clk), |
---|
| 909 | .se (se), .si (), .so () |
---|
| 910 | ); |
---|
| 911 | |
---|
| 912 | assign flush_vld_w2[7:0] = stb_state_vld_set_w2[7:0] & {8{st_vld_squash_w2}} ; |
---|
| 913 | |
---|
| 914 | // The stb valids for the scm need not include the intermediate flush condition |
---|
| 915 | // (flush_vld_w2). It is assumed that the flush of the store will invalidate |
---|
| 916 | // a subsequent ld. (8 extra flops). |
---|
| 917 | // Bug 3201 - rmo st are made invisible to loads. |
---|
| 918 | |
---|
| 919 | wire [7:0] st_scm_vld ; |
---|
| 920 | assign st_scm_vld[7:0] = stb_state_vld_din[7:0] & ~stb_state_rmo[7:0] ; |
---|
| 921 | |
---|
| 922 | dff_s #(8) ff_st_scm_vld ( |
---|
| 923 | .din (st_scm_vld[7:0]), |
---|
| 924 | .q (stb_state_vld_out[7:0] ), |
---|
| 925 | .clk (clk), |
---|
| 926 | .se (se), .si (), .so () |
---|
| 927 | ); |
---|
| 928 | |
---|
| 929 | //ced |
---|
| 930 | assign stb_state_ced_set[7:0] = dec_ackptr[7:0] & {8{st_vld_rq_d2}} ; |
---|
| 931 | // Timing fix. |
---|
| 932 | //assign stb_state_ced_set[7:0] = dec_ackptr[7:0] & {8{pcx_rq_for_stb_d1 & ~pcx_req_squash}}; |
---|
| 933 | // make reset dominant - specifically for coincident set and reset by rmo st. |
---|
| 934 | assign stb_state_ced_din[7:0] = ~stb_state_rst[7:0] & |
---|
| 935 | (stb_state_ced_set[7:0] | stb_state_ced[7:0]); |
---|
| 936 | //assign stb_state_ced_din[7:0] = stb_state_ced_set[7:0] | |
---|
| 937 | // (~stb_state_rst[7:0] & stb_state_ced[7:0]); |
---|
| 938 | |
---|
| 939 | dff_s #(8) ff_stb_state_ced ( |
---|
| 940 | .din (stb_state_ced_din[7:0]), |
---|
| 941 | .q (stb_state_ced[7:0] ), |
---|
| 942 | .clk (clk), |
---|
| 943 | .se (se), .si (), .so () |
---|
| 944 | ); |
---|
| 945 | |
---|
| 946 | //ack |
---|
| 947 | assign stb_state_ack_set[7:0] = dec_ackptr[7:0] & {8{ack_vld}}; |
---|
| 948 | assign stb_state_ack_din[7:0] = stb_state_ack_set[7:0] | |
---|
| 949 | (~stb_state_rst[7:0] & stb_state_ack[7:0]); |
---|
| 950 | |
---|
| 951 | dff_s #(8) ff_stb_state_ack ( |
---|
| 952 | .din (stb_state_ack_din[7:0]), |
---|
| 953 | .q (stb_state_ack[7:0] ), |
---|
| 954 | .clk (clk), |
---|
| 955 | .se (se), .si (), .so () |
---|
| 956 | ); |
---|
| 957 | |
---|
| 958 | //spec. write |
---|
| 959 | wire [7:0] spec_wrt; |
---|
| 960 | assign spec_wrt [7:0] = dec_wptr_m[7:0] & {8{stb_cam_wvld_m}}; |
---|
| 961 | assign stb_clk_en_l [7:0] = ~spec_wrt[7:0]; |
---|
| 962 | |
---|
| 963 | //spec write Ffs move to lsu_stb_ctldp to save area |
---|
| 964 | |
---|
| 965 | |
---|
| 966 | // moved state_io logic from ctldp |
---|
| 967 | |
---|
| 968 | assign stb_state_io_din[7:0] = (stb_state_vld_set[7:0] & {8{stb_non_l2bnk_g}}) | |
---|
| 969 | (~stb_state_rst[7:0] & stb_state_io[7:0]); |
---|
| 970 | |
---|
| 971 | dff_s #(8) ff_stb_state_io ( |
---|
| 972 | .din (stb_state_io_din[7:0]), |
---|
| 973 | .q (stb_state_io[7:0] ), |
---|
| 974 | .clk (clk), |
---|
| 975 | .se (se), .si (), .so () |
---|
| 976 | ); |
---|
| 977 | |
---|
| 978 | // always->dff translation end |
---|
| 979 | // streaming unit does not have to care about outstanding rmo sparc-stores. |
---|
| 980 | // membar will take care of that. spu must insert appr. delay in sampling signal. |
---|
| 981 | assign lsu_stb_empty = ~(|stb_state_vld[7:0]); |
---|
| 982 | |
---|
| 983 | //========================================================================================= |
---|
| 984 | // SELECT L2BANK ADDRESS |
---|
| 985 | //========================================================================================= |
---|
| 986 | |
---|
| 987 | //reg [5:0] temp ; |
---|
| 988 | //reg [2:0] stb_l2bnk_addr ; |
---|
| 989 | |
---|
| 990 | //// This is modelling a mux. |
---|
| 991 | //always @(/*AUTOSENSE*/ /*memory or*/ dec_rptr_pcx) |
---|
| 992 | // begin |
---|
| 993 | // for (j=0;j<8;j=j+1) |
---|
| 994 | // if (dec_rptr_pcx[j]) // 1-hot |
---|
| 995 | // begin |
---|
| 996 | // temp[5:0] = stb_state_si[j] ; |
---|
| 997 | // stb_l2bnk_addr[2:0] = {stb_state_io[j],temp[4:3]} ; |
---|
| 998 | // stb_atm_rq_type[2:0] = stb_state_rtype[j] ; |
---|
| 999 | // end |
---|
| 1000 | // end |
---|
| 1001 | |
---|
| 1002 | |
---|
| 1003 | //always->and-or translation begin |
---|
| 1004 | assign stb_l2bnk_addr[2:0] = {3{dec_rptr_pcx[0]}} & {stb_l2bnk_addr_b2[0], stb_state_si_0[3:2]} | |
---|
| 1005 | {3{dec_rptr_pcx[1]}} & {stb_l2bnk_addr_b2[1], stb_state_si_1[3:2]} | |
---|
| 1006 | {3{dec_rptr_pcx[2]}} & {stb_l2bnk_addr_b2[2], stb_state_si_2[3:2]} | |
---|
| 1007 | {3{dec_rptr_pcx[3]}} & {stb_l2bnk_addr_b2[3], stb_state_si_3[3:2]} | |
---|
| 1008 | {3{dec_rptr_pcx[4]}} & {stb_l2bnk_addr_b2[4], stb_state_si_4[3:2]} | |
---|
| 1009 | {3{dec_rptr_pcx[5]}} & {stb_l2bnk_addr_b2[5], stb_state_si_5[3:2]} | |
---|
| 1010 | {3{dec_rptr_pcx[6]}} & {stb_l2bnk_addr_b2[6], stb_state_si_6[3:2]} | |
---|
| 1011 | {3{dec_rptr_pcx[7]}} & {stb_l2bnk_addr_b2[7], stb_state_si_7[3:2]} ; |
---|
| 1012 | |
---|
| 1013 | assign stb_atm_rq_type[2:1]= {2{dec_rptr_pcx[0]}} & stb_state_rtype_0[2:1] | |
---|
| 1014 | {2{dec_rptr_pcx[1]}} & stb_state_rtype_1[2:1] | |
---|
| 1015 | {2{dec_rptr_pcx[2]}} & stb_state_rtype_2[2:1] | |
---|
| 1016 | {2{dec_rptr_pcx[3]}} & stb_state_rtype_3[2:1] | |
---|
| 1017 | {2{dec_rptr_pcx[4]}} & stb_state_rtype_4[2:1] | |
---|
| 1018 | {2{dec_rptr_pcx[5]}} & stb_state_rtype_5[2:1] | |
---|
| 1019 | {2{dec_rptr_pcx[6]}} & stb_state_rtype_6[2:1] | |
---|
| 1020 | {2{dec_rptr_pcx[7]}} & stb_state_rtype_7[2:1] ; |
---|
| 1021 | |
---|
| 1022 | //always->and-or translation end |
---|
| 1023 | |
---|
| 1024 | |
---|
| 1025 | endmodule |
---|
| 1026 | |
---|