| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: dmu_mmu_srq_iommu.v |
| 4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved |
| 5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
| 6 | // |
| 7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 8 | // |
| 9 | // This program is free software; you can redistribute it and/or modify |
| 10 | // it under the terms of the GNU General Public License as published by |
| 11 | // the Free Software Foundation; version 2 of the License. |
| 12 | // |
| 13 | // This program is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | // GNU General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU General Public License |
| 19 | // along with this program; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | // |
| 22 | // For the avoidance of doubt, and except that if any non-GPL license |
| 23 | // choice is available it will apply instead, Sun elects to use only |
| 24 | // the General Public License version 2 (GPLv2) at this time for any |
| 25 | // software where a choice of GPL license versions is made |
| 26 | // available with the language indicating that GPLv2 or any later version |
| 27 | // may be used, or where a choice of which version of the GPL is applied is |
| 28 | // otherwise unspecified. |
| 29 | // |
| 30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 31 | // CA 95054 USA or visit www.sun.com if you need additional information or |
| 32 | // have any questions. |
| 33 | // |
| 34 | // ========== Copyright Header End ============================================ |
| 35 | module dmu_mmu_srq_iommu |
| 36 | ( |
| 37 | l2clk, // clock for ram |
| 38 | clk, // clock |
| 39 | rst_l, // synchronous reset |
| 40 | por_l, // por synchronous reset |
| 41 | scan_in, |
| 42 | tcu_array_bypass, |
| 43 | tcu_scan_en, |
| 44 | tcu_se_scancollar_in, |
| 45 | tcu_array_wr_inhibit, |
| 46 | tcu_pce_ov, |
| 47 | tcu_aclk, |
| 48 | tcu_bclk, |
| 49 | scan_out, |
| 50 | |
| 51 | ld, // load |
| 52 | ds, // data select |
| 53 | di, // data in |
| 54 | sun4v_mode, // 1 if sun4v_mode |
| 55 | do, // data out |
| 56 | srq2vab_sun4v_pgsz, // sun4v page size to vab to zero before tlb lookup |
| 57 | srq2vab_sun4v_byp_ps0, // true if sun4v mode and bypass |
| 58 | srq2tmc_sun4v_pgsz_err, // true if sun4v mode and illegal sun4v page size |
| 59 | iotsbno, // iotsb number in stage ps0 to vtb and vab |
| 60 | iotsb_basepa, // iotsb base pa for tablewalks |
| 61 | srq2vab_np, // number of pages out of iotsb for sun4v out of range calc |
| 62 | srq2vab_adva, // adjusted va after offset |
| 63 | srq2tmc_ivld, // iotsb valid bit and'ed with sun4v_mode |
| 64 | srq2tmc_ipe, // iotsb parity error or tmc block |
| 65 | csr2dev_iotsb_wd, |
| 66 | dev_iotsb2csr_rd, |
| 67 | csr2dev2iotsb_we, |
| 68 | csr2dev2iotsb_re, |
| 69 | csr2IotsbDesc_we, |
| 70 | csr2IotsbDesc_re, |
| 71 | csr2dev_iotsb_rwa, |
| 72 | busid_sel, |
| 73 | lkup_deque_en, |
| 74 | csr_done, |
| 75 | dsn_dmc_iei, // NCU can force a parity error on deviotsb reads |
| 76 | dmu_mb0_run, |
| 77 | |
| 78 | dmu_mb0_addr, |
| 79 | dmu_mb0_wdata, |
| 80 | dmu_mb0_dev_wr_en, |
| 81 | dmu_mb0_dev_rd_en, |
| 82 | dmu_mb0_tsb_wr_en, |
| 83 | dmu_mb0_tsb_rd_en, |
| 84 | //efu wires |
| 85 | efu_dmu_data, // input efu to devtsb |
| 86 | efu_dmu_xfer_en, // input efu to devtsb |
| 87 | efu_dmu_clr , // input efu to devtsb |
| 88 | dmu_efu_data, // output of devtsb to efu |
| 89 | dmu_efu_xfer_en // output of devtsb to efu |
| 90 | ); |
| 91 | |
| 92 | // ---------------------------------------------------------------------------- |
| 93 | // Parameters |
| 94 | // ---------------------------------------------------------------------------- |
| 95 | parameter QD = 4, // queue depth |
| 96 | // QW = 2; // queue width |
| 97 | QW = 85; // queue width |
| 98 | |
| 99 | // ---------------------------------------------------------------------------- |
| 100 | // Ports |
| 101 | // ---------------------------------------------------------------------------- |
| 102 | input l2clk; |
| 103 | input clk; |
| 104 | input rst_l; |
| 105 | input por_l; |
| 106 | input scan_in; |
| 107 | input tcu_array_bypass; |
| 108 | input tcu_scan_en; |
| 109 | input tcu_se_scancollar_in; |
| 110 | input tcu_array_wr_inhibit; |
| 111 | input tcu_pce_ov; |
| 112 | input tcu_aclk; |
| 113 | input tcu_bclk; |
| 114 | output scan_out; |
| 115 | |
| 116 | input [QD-1:0] ld; |
| 117 | input [QD-2:0] ds; |
| 118 | |
| 119 | input [QW-1:0] di; |
| 120 | input sun4v_mode; |
| 121 | input [`FIRE_CSR_DATA_BITS] csr2dev_iotsb_wd; |
| 122 | input csr2dev2iotsb_we; |
| 123 | input csr2dev2iotsb_re; |
| 124 | input csr2IotsbDesc_we; |
| 125 | input csr2IotsbDesc_re; |
| 126 | input [4:0] csr2dev_iotsb_rwa; |
| 127 | input busid_sel; |
| 128 | |
| 129 | output [2:0] srq2vab_sun4v_pgsz; |
| 130 | output srq2vab_sun4v_byp_ps0; |
| 131 | output srq2tmc_sun4v_pgsz_err; |
| 132 | output [QW-1:0] do; |
| 133 | output [4:0] iotsbno; |
| 134 | output [25:0] iotsb_basepa; |
| 135 | output [3:0] srq2vab_np; |
| 136 | output [27:0] srq2vab_adva; |
| 137 | output srq2tmc_ivld; |
| 138 | output srq2tmc_ipe; |
| 139 | output [`FIRE_CSR_DATA_BITS] dev_iotsb2csr_rd; |
| 140 | output lkup_deque_en; |
| 141 | output csr_done; |
| 142 | input dsn_dmc_iei; |
| 143 | |
| 144 | input dmu_mb0_run; |
| 145 | |
| 146 | input [4:0] dmu_mb0_addr; |
| 147 | input [7:0] dmu_mb0_wdata; |
| 148 | input dmu_mb0_dev_wr_en; |
| 149 | input dmu_mb0_dev_rd_en; |
| 150 | input dmu_mb0_tsb_wr_en; |
| 151 | input dmu_mb0_tsb_rd_en; |
| 152 | //efu wires |
| 153 | input efu_dmu_data ; // input efu to devtsb |
| 154 | input efu_dmu_xfer_en; // input efu to devtsb |
| 155 | input efu_dmu_clr; // input efu to devtsb |
| 156 | output dmu_efu_data; // output of devtsb to efu |
| 157 | output dmu_efu_xfer_en ; // output of devtsb to efu |
| 158 | |
| 159 | wire dmu_efu_data ; |
| 160 | wire dmu_efu_xfer_en ; |
| 161 | |
| 162 | // ---------------------------------------------------------------------------- |
| 163 | // Variables |
| 164 | // ---------------------------------------------------------------------------- |
| 165 | wire [QW-1:0] do; |
| 166 | // reg [QW-1:0] que [0:QD-1]; |
| 167 | reg [QW-1:0] que_0; |
| 168 | reg [QW-1:0] que_1; |
| 169 | reg [QW-1:0] que_2; |
| 170 | reg [QW-1:0] que_3; |
| 171 | |
| 172 | // integer i; |
| 173 | |
| 174 | wire [27:0] srq2vab_adva; |
| 175 | // SRAM header to EFU |
| 176 | wire hdr_efu_read_data; |
| 177 | wire hdr_efu_xfer_en; |
| 178 | |
| 179 | // SRAM header to SRAM |
| 180 | //wire [10:0] hdr_sram_rvalue; |
| 181 | //wire [10:0] hdr_sram_rid; |
| 182 | //wire hdr_sram_wr_en; |
| 183 | //wire hdr_sram_red_clr; |
| 184 | // ---------------------------------------------------------------------------- |
| 185 | // Combinational |
| 186 | // ---------------------------------------------------------------------------- |
| 187 | wire [27:0] adj_va; |
| 188 | reg [26:0] out_va; |
| 189 | wire [3:0] fuse; |
| 190 | wire bypass; |
| 191 | wire [2:0] page_size; |
| 192 | // NOTE: the adj_va is the full ppn but because the ptb holds 8 entries and |
| 193 | // thus align the ppn to a cacheline boundary since the tte's are fetched as cachelines |
| 194 | // and this alignment is done in dmu_mmu_vaq.v |
| 195 | assign do = (sun4v_mode & ~bypass) ? {que_0[84:38],out_va[26:0],que_0[10:0]} : que_0 ; |
| 196 | |
| 197 | always @(page_size or que_0 or adj_va) begin |
| 198 | |
| 199 | out_va[26:0] = 27'b0; |
| 200 | |
| 201 | case (page_size) |
| 202 | 3'b000: out_va = adj_va[26:0]; // 8k pages |
| 203 | 3'b001: out_va = {adj_va[23:0],que_0[13:11]}; // 64 pages |
| 204 | 3'b010: out_va = {27{1'b0}}; // invalid |
| 205 | 3'b011: out_va = {adj_va[17:0],que_0[19:11]}; // 4M pages |
| 206 | 3'b100: out_va = {27{1'b0}}; // invalid |
| 207 | 3'b101: out_va = {adj_va[11:0],que_0[25:11]}; // 4M pages |
| 208 | 3'b110: out_va = {27{1'b0}}; // invalid |
| 209 | 3'b111: out_va = {27{1'b0}}; // invalid |
| 210 | default: out_va = {27{1'b0}}; |
| 211 | endcase |
| 212 | end |
| 213 | |
| 214 | assign srq2vab_sun4v_pgsz[2:0] = page_size[2:0]; // send to vab to zero out for tlb compare |
| 215 | |
| 216 | assign srq2vab_sun4v_byp_ps0 = sun4v_mode & bypass; // used in vab for translation/bypass error |
| 217 | |
| 218 | assign srq2tmc_sun4v_pgsz_err = sun4v_mode & ( |
| 219 | (page_size==3'b010) || |
| 220 | (page_size==3'b100) || |
| 221 | (page_size==3'b110) || |
| 222 | (page_size==3'b111) ); |
| 223 | |
| 224 | // do bypass detect here, and in vab it logs the errors and does the actual bypass, |
| 225 | // this bypass just short-circuits the new iotsb translation |
| 226 | assign bypass = (que_0[61:37] == 25'h1fff800); // note que_0 adr starts at adr[2] |
| 227 | //BP n2for fire , matches value in dmu_mmu_vab.v |
| 228 | //assign bypass = (que_0[61:37] == 25'h1fff80); |
| 229 | // ---------------------------------------------------------------------------- |
| 230 | // Sequential |
| 231 | // ---------------------------------------------------------------------------- |
| 232 | // always @ (posedge clk) |
| 233 | // if(~rst_l) begin : que_rst |
| 234 | // integer j; |
| 235 | // for (j = 0; j < QD; j = j + 1) begin |
| 236 | // que[j] <= {QW{1'b0}}; |
| 237 | // end |
| 238 | // end |
| 239 | // else begin |
| 240 | // for (i = 0; i < QD-1; i = i + 1) begin |
| 241 | // if (ld[i]) que[i] <= ds[i] ? que[i+1] : di; |
| 242 | // end |
| 243 | // if (ld[QD-1]) que[QD-1] <= di; |
| 244 | // end |
| 245 | |
| 246 | always @ (posedge clk) |
| 247 | if(~rst_l) begin : que_rst |
| 248 | que_0 <= {QW{1'b0}}; |
| 249 | que_1 <= {QW{1'b0}}; |
| 250 | que_2 <= {QW{1'b0}}; |
| 251 | que_3 <= {QW{1'b0}}; |
| 252 | end |
| 253 | else begin |
| 254 | if (ld[0]) que_0 <= ds[0] ? que_1 : di; |
| 255 | if (ld[1]) que_1 <= ds[1] ? que_2 : di; |
| 256 | if (ld[2]) que_2 <= ds[2] ? que_3 : di; |
| 257 | if (ld[3]) que_3 <= di; |
| 258 | end |
| 259 | |
| 260 | |
| 261 | // ---------------------------------------------------------------------------- |
| 262 | // N2 BP 8-02-04 |
| 263 | // add the new N2 IOMMU ram here, |
| 264 | // NOTE: the flops at the input to the IOMMU ram are at the same stage in |
| 265 | // the pipeline as que[0], so que[0] has 2 purposes |
| 266 | // 1. used for SUN4U mode (old fire mode) |
| 267 | // 2. used as part of the logic to make the new IOMMU input flops |
| 268 | // appear as que[0] entry for the SUN4V mode |
| 269 | // ---------------------------------------------------------------------------- |
| 270 | // grab address bit 63 and the 8 bits of bus id to load into the new iommu ram address ff. |
| 271 | wire adr_63,q1_or_di_63,reqid_sel; |
| 272 | wire adr_0_63,adr_1_63; |
| 273 | wire [6:0] q1_or_di_req_id; |
| 274 | wire [5:0] req_id,q1_or_di_req_id_sel,req_id_in; |
| 275 | assign adr_0_63 = que_0[61]; |
| 276 | assign adr_1_63 = que_1[61]; |
| 277 | // select address bit 63 into the iommu ram address port |
| 278 | assign q1_or_di_63 = ds[0] ? adr_1_63 : di[61]; |
| 279 | assign adr_63 = ld[0] ? q1_or_di_63 : adr_0_63; |
| 280 | |
| 281 | // now select the bus_id to load into the iommu ram address port |
| 282 | // select which bus_id to load |
| 283 | assign q1_or_di_req_id[6:0] = ds[0] ? que_1[76:70] : di[76:70]; // shift or di |
| 284 | assign req_id[5:0] = reqid_sel ? que_0[75:70] : que_0[76:71]; // select which bits to hold |
| 285 | assign q1_or_di_req_id_sel[5:0] = reqid_sel ? q1_or_di_req_id[5:0] : q1_or_di_req_id[6:1]; // select which new bits to load |
| 286 | assign req_id_in[5:0] = ld[0] ? q1_or_di_req_id_sel[5:0] : req_id[5:0]; // hold term |
| 287 | |
| 288 | //temp |
| 289 | wire devtsb_csr; |
| 290 | wire [4:0] adr_r_in, devtsb_csr_adr; |
| 291 | //SV assign reqid_sel = 1'b0; |
| 292 | //SV assign devtsb_csr = 1'b0; |
| 293 | assign adr_r_in[4:0] = devtsb_csr ? devtsb_csr_adr[4:0] : {1'b0,adr_63,req_id_in[5:3]}; |
| 294 | wire [63:0] iotsb_out; |
| 295 | wire [4:0] iotsbno; |
| 296 | wire iotsb_par62,iotsb_par61; |
| 297 | |
| 298 | // SV |
| 299 | wire csrequest, dev_rd, dev_wr, tsb_rd, tsb_wr, arb_winner; |
| 300 | wire [63:0] devtsb_din; |
| 301 | |
| 302 | assign devtsb_csr_adr = csr2dev_iotsb_rwa; |
| 303 | assign dev_iotsb2csr_rd = iotsb_out; |
| 304 | assign reqid_sel = busid_sel; |
| 305 | assign devtsb_csr = ~arb_winner; |
| 306 | assign dev_rd = arb_winner ? 1'b1 : csr2dev2iotsb_re; |
| 307 | assign dev_wr = ~arb_winner & csr2dev2iotsb_we; |
| 308 | assign tsb_rd = arb_winner ? 1'b1 : csr2IotsbDesc_re; |
| 309 | assign tsb_wr = ~arb_winner & csr2IotsbDesc_we; |
| 310 | assign csrequest = csr2dev2iotsb_re | csr2dev2iotsb_we | csr2IotsbDesc_re | csr2IotsbDesc_we; |
| 311 | assign lkup_deque_en = arb_winner; |
| 312 | assign iotsb_par62 = ~(^{csr2dev_iotsb_wd[63],csr2dev_iotsb_wd[59:32]}); |
| 313 | assign iotsb_par61 = ~(^{csr2dev_iotsb_wd[31:1],(csr2dev_iotsb_wd[0] ^ dsn_dmc_iei)}); |
| 314 | assign devtsb_din = csr2dev2iotsb_we ? {3'b0,csr2dev_iotsb_wd[60:56],3'b0,csr2dev_iotsb_wd[52:48],3'b0,csr2dev_iotsb_wd[44:40],3'b0,csr2dev_iotsb_wd[36:32],3'b0,csr2dev_iotsb_wd[28:24],3'b0,csr2dev_iotsb_wd[20:16],3'b0,csr2dev_iotsb_wd[12:8],3'b0,csr2dev_iotsb_wd[4:0]} : {csr2dev_iotsb_wd[63],iotsb_par62,iotsb_par61,1'b0,csr2dev_iotsb_wd[59:0]}; |
| 315 | |
| 316 | /* arb -req csrrequest -gnt ~lkupreq |
| 317 | -round_robin |
| 318 | */ |
| 319 | dmu_mmu_arbiter_rrobin arbiter_rrobin |
| 320 | ( |
| 321 | .next_grant (arb_winner), |
| 322 | .csr_done (csr_done), |
| 323 | .clk (clk), |
| 324 | .rst_l (rst_l), |
| 325 | .csrequest (csrequest) |
| 326 | ); |
| 327 | |
| 328 | //BP n2 9-23-04 add the bypass mux |
| 329 | // note devtsb_din derives from csr2dev_iotsb_wd which comes from flops in dmu_mmu_csr_cim.v |
| 330 | // |
| 331 | wire [`FIRE_CSR_DATA_BITS] devtsb_out; |
| 332 | assign iotsb_out = tcu_array_bypass ? csr2dev_iotsb_wd : devtsb_out; |
| 333 | |
| 334 | //SV 02/24/05 added BIST logic |
| 335 | wire [63:0] din_ram ; |
| 336 | wire [4:0] rd_addr_ram, wr_addr_ram ; |
| 337 | wire tsbwr_en_ram, tsbrd_en_ram ; |
| 338 | wire devwr_en_ram, devrd_en_ram ; |
| 339 | wire devtsb_lkup_en ; |
| 340 | |
| 341 | assign din_ram = dmu_mb0_run ? ({8{dmu_mb0_wdata}}) : devtsb_din ; |
| 342 | assign rd_addr_ram = dmu_mb0_run ? dmu_mb0_addr[4:0] : adr_r_in[4:0] ; |
| 343 | assign wr_addr_ram = dmu_mb0_run ? dmu_mb0_addr[4:0] : csr2dev_iotsb_rwa ; |
| 344 | assign devwr_en_ram = dmu_mb0_run ? dmu_mb0_dev_wr_en : dev_wr ; |
| 345 | assign devrd_en_ram = dmu_mb0_run ? dmu_mb0_dev_rd_en : dev_rd ; |
| 346 | assign tsbwr_en_ram = dmu_mb0_run ? dmu_mb0_tsb_wr_en : tsb_wr ; |
| 347 | assign tsbrd_en_ram = dmu_mb0_run ? dmu_mb0_tsb_rd_en : tsb_rd ; |
| 348 | assign devtsb_lkup_en = dmu_mb0_run ? 1'b0 : arb_winner ; |
| 349 | |
| 350 | // -0in assert_follower -leader arb_winner -follower tsb_rd -max 0 -min 0 |
| 351 | // -0in assert_follower -leader arb_winner -follower dev_rd -max 0 -min 0 |
| 352 | // 0in never -var (tsb_rd & tsb_wr) -group mbist_mode |
| 353 | // 0in never -var (dev_rd & dev_wr) -group mbist_mode |
| 354 | |
| 355 | n2_iom_sp_devtsb_cust srq_iommu |
| 356 | ( |
| 357 | // address ports |
| 358 | .adr_r (rd_addr_ram), |
| 359 | .adr_bs (req_id_in[2:0]), |
| 360 | .adr_w (wr_addr_ram), |
| 361 | |
| 362 | // clock ports |
| 363 | .clk (l2clk), |
| 364 | |
| 365 | // data input ports |
| 366 | .din (din_ram), |
| 367 | |
| 368 | // data output ports |
| 369 | // .dout (iotsb_out), |
| 370 | .dout (devtsb_out), |
| 371 | .tsb_adr_r (iotsbno), |
| 372 | |
| 373 | // port enables |
| 374 | .dev_wr (devwr_en_ram), |
| 375 | .dev_rd (devrd_en_ram), |
| 376 | .tsb_wr (tsbwr_en_ram), |
| 377 | .tsb_rd (tsbrd_en_ram), |
| 378 | |
| 379 | // |
| 380 | .lkup_en (devtsb_lkup_en), |
| 381 | |
| 382 | |
| 383 | |
| 384 | |
| 385 | // scan ports |
| 386 | .scan_in (scan_in), |
| 387 | .tcu_se_scancollar_in (tcu_se_scancollar_in), |
| 388 | .tcu_scan_en (tcu_scan_en), |
| 389 | .tcu_array_wr_inhibit (tcu_array_wr_inhibit), |
| 390 | .tcu_pce_ov (tcu_pce_ov), |
| 391 | .pce (1'b1), |
| 392 | .tcu_aclk (tcu_aclk), |
| 393 | .tcu_bclk (tcu_bclk), |
| 394 | .scan_out (scan_out), |
| 395 | .efu_bits (fuse[3:0]) |
| 396 | ); |
| 397 | |
| 398 | |
| 399 | // do the SUN4V address relocation |
| 400 | |
| 401 | wire [25:0] iotsb_basepa; |
| 402 | wire [26:0] offset; |
| 403 | wire [3:0] srq2vab_np; // number of pages out of iotsb |
| 404 | reg [26:0] shft_va; |
| 405 | reg [4:0] rdcount; |
| 406 | reg [21:0] sync_read; |
| 407 | wire data_en,read_en,wr_en; |
| 408 | reg sync_clr; |
| 409 | |
| 410 | assign srq2tmc_ivld = ~iotsb_out[63] && sun4v_mode; |
| 411 | assign iotsb_basepa[25:0] = iotsb_out[59:34]; |
| 412 | assign offset[26:0] = iotsb_out[33:7]; |
| 413 | assign page_size[2:0] = iotsb_out[6:4]; |
| 414 | assign srq2vab_np[3:0] = iotsb_out[3:0]; |
| 415 | |
| 416 | wire iotsb_out_par62 = ~(^{iotsb_out[63],iotsb_out[59:32]}); |
| 417 | wire iotsb_out_par61 = ~(^{iotsb_out[31:0]}); |
| 418 | //assign srq2tmc_ipe = sun4v_mode && iotsb_out[63] && (iotsb_out_par62 ^ iotsb_out[62]) | (iotsb_out_par61 ^ iotsb_out[61]); |
| 419 | assign srq2tmc_ipe = sun4v_mode && (iotsb_out_par62 ^ iotsb_out[62]) | (iotsb_out_par61 ^ iotsb_out[61]); |
| 420 | |
| 421 | // note: that que_0 contains va[63:2] not va[61:0]!!! |
| 422 | always @( page_size or que_0 )begin |
| 423 | |
| 424 | shft_va[26:0] = 27'b0; |
| 425 | |
| 426 | case (page_size) |
| 427 | 3'b000: shft_va = que_0[37:11]; // 8k pages |
| 428 | 3'b001: shft_va = {{3{1'b0}},que_0[37:14]}; // 64k pages |
| 429 | 3'b010: shft_va = {27{1'b0}}; |
| 430 | 3'b011: shft_va = {{9{1'b0}},que_0[37:20]}; // 4M pages |
| 431 | 3'b100: shft_va = {27{1'b0}}; |
| 432 | 3'b101: shft_va = {{15{1'b0}},que_0[37:26]}; // 256M pages |
| 433 | 3'b110: shft_va = {27{1'b0}}; |
| 434 | 3'b111: shft_va = {27{1'b0}}; |
| 435 | default: shft_va = {27{1'b0}}; |
| 436 | endcase |
| 437 | end |
| 438 | |
| 439 | assign adj_va[27:0] = {1'b0,shft_va[26:0]} - {1'b0,offset[26:0]}; |
| 440 | assign srq2vab_adva[27:0] = adj_va[27:0]; |
| 441 | |
| 442 | |
| 443 | //BP N2 3-31-05 convert sv file to .v to drive devtsb ram |
| 444 | // the .sv code is located at cdmspp/libs/rtl/n2_efuhdr_ctl.sv |
| 445 | |
| 446 | //module n2_efuhdr_ctl ; |
| 447 | reg efu_dmu_xfer_en_r1,efu_dmu_data_r1,efu_dmu_clr_r1,efu_dmu_xfer_en_r2; |
| 448 | reg [21:0] instr; |
| 449 | wire [21:0] efu_instr,sram_read_data,received_instr; |
| 450 | reg [4:0] count; |
| 451 | wire [4:0] count_in; |
| 452 | wire dispatch_read_data,load_shift_reg,load_en,reset_count; |
| 453 | wire rdreset_count,ld_rd_en; |
| 454 | wire [4:0] rdcount_in; |
| 455 | reg [21:0] sync_instr; |
| 456 | |
| 457 | //msff_ctl_macro ff_input_all_enable (width=4) |
| 458 | // ( |
| 459 | // .scan_in(ff_input_all_enable_scanin), |
| 460 | // .scan_out(ff_input_all_enable_scanout), |
| 461 | // .dout ({efu_hdr_xfer_en_r1,efu_hdr_write_data_r1,efu_hdr_clr_r1,efu_hdr_xfer_en_r2}), |
| 462 | // .din ({efu_hdr_xfer_en, efu_hdr_write_data ,efu_hdr_clr, efu_hdr_xfer_en_r1}), |
| 463 | // .l1clk (l1clk_efu) |
| 464 | // ); |
| 465 | |
| 466 | always @ (posedge clk) |
| 467 | if(~por_l) begin |
| 468 | efu_dmu_xfer_en_r1 <= 1'b0; |
| 469 | efu_dmu_data_r1 <= 1'b0; |
| 470 | efu_dmu_clr_r1 <= 1'b0; |
| 471 | efu_dmu_xfer_en_r2 <= 1'b0; |
| 472 | end |
| 473 | else begin |
| 474 | efu_dmu_xfer_en_r1 <= efu_dmu_xfer_en; |
| 475 | efu_dmu_data_r1 <= efu_dmu_data; |
| 476 | efu_dmu_clr_r1 <= efu_dmu_clr; |
| 477 | efu_dmu_xfer_en_r2 <= efu_dmu_xfer_en_r1; |
| 478 | end |
| 479 | |
| 480 | |
| 481 | assign efu_instr[21:0] = {instr[20:0],efu_dmu_data_r1}; |
| 482 | |
| 483 | assign sram_read_data[21:0] = {18'b0,fuse[3:0]}; |
| 484 | |
| 485 | assign received_instr[21:0] = efu_dmu_xfer_en_r1 ? efu_instr[21:0] : |
| 486 | (rdcount==5'd23) ? sync_read : |
| 487 | dispatch_read_data ? ({instr[20:0],1'b0}) : 22'b0; |
| 488 | |
| 489 | assign load_shift_reg = efu_dmu_xfer_en_r1 | dispatch_read_data | (rdcount == 5'd23); |
| 490 | |
| 491 | //msff_ctl_macro ff_receiver_instr_slice (width=22,en=1) |
| 492 | // ( |
| 493 | // .scan_in(ff_receiver_instr_slice_scanin), |
| 494 | // .scan_out(ff_receiver_instr_slice_scanout), |
| 495 | // .dout (instr[21:0]), |
| 496 | // .din (received_instr[21:0]), |
| 497 | // .en (load_shift_reg), |
| 498 | // .l1clk (l1clk_efu) |
| 499 | // ); |
| 500 | |
| 501 | always @ (posedge clk) begin |
| 502 | if(~por_l) begin |
| 503 | instr[21:0] <= 22'b0; |
| 504 | end |
| 505 | else if (load_shift_reg) begin |
| 506 | instr[21:0] <= received_instr[21:0]; |
| 507 | end |
| 508 | else begin |
| 509 | instr[21:0] <= instr[21:0]; |
| 510 | end |
| 511 | end |
| 512 | |
| 513 | assign data_en = (count==5'd8) ; |
| 514 | assign wr_en = ((count==5'd7) | ~(sync_instr[21]) ); |
| 515 | assign read_en = (count==5'd1); |
| 516 | |
| 517 | always @ (posedge clk) begin |
| 518 | if(~por_l|| sync_clr) begin |
| 519 | sync_instr[1:0] <= 2'b0; |
| 520 | sync_instr[2] <= 1'b1; |
| 521 | sync_instr[21:3] <= 19'b0; |
| 522 | end |
| 523 | else if (data_en & |
| 524 | // (~received_instr[21] & received_instr[11] & received_instr[0]) ) begin |
| 525 | (~instr[21] & instr[11] & instr[0]) ) begin |
| 526 | sync_instr[21:0] <= instr[21:0]; |
| 527 | end |
| 528 | else begin |
| 529 | sync_instr[21:0] <= sync_instr[21:0]; |
| 530 | end |
| 531 | end |
| 532 | assign fuse[3:0] = sync_instr[4:1]; |
| 533 | |
| 534 | always @ (posedge clk) begin |
| 535 | if(~por_l) begin |
| 536 | sync_read[21:0] <= 22'b0; |
| 537 | end |
| 538 | else if (read_en) begin |
| 539 | sync_read[21:0] <= sram_read_data[21:0]; |
| 540 | end |
| 541 | else begin |
| 542 | sync_read[21:0] <= sync_read[21:0]; |
| 543 | end |
| 544 | end |
| 545 | |
| 546 | |
| 547 | always @ (posedge clk) |
| 548 | if(~por_l) begin |
| 549 | sync_clr <= 1'b0; |
| 550 | end |
| 551 | else begin |
| 552 | sync_clr <= efu_dmu_clr_r1; |
| 553 | end |
| 554 | |
| 555 | |
| 556 | // always @ (posedge clk) |
| 557 | // if(~por_l || sync_clr) begin |
| 558 | // fuse[0] <= 1'b0; |
| 559 | // fuse[1] <= 1'b1; |
| 560 | // fuse[3:2] <= 2'b0; |
| 561 | // end |
| 562 | // else if (load_en & received_instr[11] & received_instr[0]) begin |
| 563 | // else if (efu_dmu_xfer_en_r2 & ~efu_dmu_xfer_en_r1 & |
| 564 | // ~received_instr[21] & received_instr[11] & received_instr[0]) begin |
| 565 | // fuse[3:0] <= received_instr[4:1]; |
| 566 | // end |
| 567 | // else begin |
| 568 | // fuse[3:0] <= fuse[3:0]; |
| 569 | // end |
| 570 | |
| 571 | assign load_en = (~efu_dmu_xfer_en_r2 & efu_dmu_xfer_en_r1); |
| 572 | assign ld_rd_en = (count==5'd1); |
| 573 | |
| 574 | assign reset_count = ( count == 5'd0 ); |
| 575 | assign rdreset_count = ( rdcount == 5'd0 ); |
| 576 | |
| 577 | assign count_in = load_en ? 5'd29 : reset_count ? 5'b0 : (count - 5'b1); |
| 578 | assign rdcount_in = ld_rd_en ? 5'd23 : rdreset_count ? 5'b0 : (rdcount - 5'b1); |
| 579 | |
| 580 | //msff_ctl_macro ff_counter_slice (width=5,en=1) |
| 581 | // ( |
| 582 | // .scan_in(ff_counter_slice_scanin), |
| 583 | // .scan_out(ff_counter_slice_scanout), |
| 584 | // .dout (count[4:0]), |
| 585 | // .din (count_in[4:0]), |
| 586 | // .en (load_en), |
| 587 | // .l1clk (l1clk_efu) |
| 588 | // ); |
| 589 | |
| 590 | always @ (posedge clk) |
| 591 | if(~por_l) begin |
| 592 | count[4:0] <= 5'b0; |
| 593 | end |
| 594 | // else if (load_en) begin |
| 595 | // else if (efu_dmu_xfer_en_r1) begin |
| 596 | else begin |
| 597 | count[4:0] <= count_in[4:0]; |
| 598 | end |
| 599 | |
| 600 | always @ (posedge clk) |
| 601 | if(~por_l) begin |
| 602 | rdcount[4:0] <= 5'b0; |
| 603 | end |
| 604 | // else if (ld_rd_en) begin |
| 605 | else begin |
| 606 | rdcount[4:0] <= rdcount_in[4:0]; |
| 607 | end |
| 608 | |
| 609 | //assign hdr_sram_rvalue[10:0] = instr[10:0]; |
| 610 | //assign hdr_sram_rid[10:0] = instr[21:11]; |
| 611 | //assign hdr_sram_red_clr = efu_dmu_clr_r1; |
| 612 | //assign hdr_sram_wr_en = |(count[1:0]); |
| 613 | //assign hdr_sram_rvalue[10:0] = sync_instr[10:0]; |
| 614 | //assign hdr_sram_rid[10:0] = sync_instr[21:11]; |
| 615 | //assign hdr_sram_red_clr = sync_clr; |
| 616 | //assign hdr_sram_wr_en = sync_wr; |
| 617 | |
| 618 | |
| 619 | //assign dispatch_read_data = (count[4:0]<5'd23) & (rdcount[4:0]!= 5'd0); |
| 620 | assign dispatch_read_data = (rdcount[4:0]<5'd23) & (rdcount[4:0]!=5'd0); |
| 621 | |
| 622 | //assign hdr_efu_read_data = instr[21]; |
| 623 | //assign hdr_efu_xfer_en = dispatch_read_data; |
| 624 | assign dmu_efu_data = instr[21]; |
| 625 | assign dmu_efu_xfer_en = dispatch_read_data; |
| 626 | |
| 627 | endmodule // dmu_mmu_srq |
| 628 | |