| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: fc_dft_tasks.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 | task force_pkg_pin_TRIGIN; |
| 36 | input is_forcing; // 0: release; otherwise, forcing |
| 37 | input value; |
| 38 | begin |
| 39 | release `CPU.TRIGIN; |
| 40 | if (is_forcing) |
| 41 | force `CPU.TRIGIN = value; |
| 42 | end |
| 43 | endtask |
| 44 | |
| 45 | //============================================================== |
| 46 | // WHAT: force/release cpu.tcu.tcu_*_clk_stop |
| 47 | //============================================================== |
| 48 | task force_tcu_clk_stop_at_tcu; |
| 49 | input is_forcing; // 0: release; otherwise, force |
| 50 | input value; // value for forcing (all signals) |
| 51 | begin |
| 52 | release `CPU.tcu.tcu_ccu_clk_stop; |
| 53 | release `CPU.tcu.tcu_ccu_io_clk_stop; |
| 54 | release `CPU.tcu.tcu_ccx_clk_stop; |
| 55 | release `CPU.tcu.tcu_db0_clk_stop; |
| 56 | release `CPU.tcu.tcu_db1_clk_stop; |
| 57 | release `CPU.tcu.tcu_dmu_io_clk_stop; |
| 58 | release `CPU.tcu.tcu_efu_clk_stop; |
| 59 | release `CPU.tcu.tcu_efu_io_clk_stop; |
| 60 | release `CPU.tcu.tcu_l2b0_clk_stop; |
| 61 | release `CPU.tcu.tcu_l2b1_clk_stop; |
| 62 | release `CPU.tcu.tcu_l2b2_clk_stop; |
| 63 | release `CPU.tcu.tcu_l2b3_clk_stop; |
| 64 | release `CPU.tcu.tcu_l2b4_clk_stop; |
| 65 | release `CPU.tcu.tcu_l2b5_clk_stop; |
| 66 | release `CPU.tcu.tcu_l2b6_clk_stop; |
| 67 | release `CPU.tcu.tcu_l2b7_clk_stop; |
| 68 | release `CPU.tcu.tcu_l2d0_clk_stop; |
| 69 | release `CPU.tcu.tcu_l2d1_clk_stop; |
| 70 | release `CPU.tcu.tcu_l2d2_clk_stop; |
| 71 | release `CPU.tcu.tcu_l2d3_clk_stop; |
| 72 | release `CPU.tcu.tcu_l2d4_clk_stop; |
| 73 | release `CPU.tcu.tcu_l2d5_clk_stop; |
| 74 | release `CPU.tcu.tcu_l2d6_clk_stop; |
| 75 | release `CPU.tcu.tcu_l2d7_clk_stop; |
| 76 | release `CPU.tcu.tcu_l2t0_clk_stop; |
| 77 | release `CPU.tcu.tcu_l2t0_shscan_clk_stop; |
| 78 | release `CPU.tcu.tcu_l2t1_clk_stop; |
| 79 | release `CPU.tcu.tcu_l2t1_shscan_clk_stop; |
| 80 | release `CPU.tcu.tcu_l2t2_clk_stop; |
| 81 | release `CPU.tcu.tcu_l2t2_shscan_clk_stop; |
| 82 | release `CPU.tcu.tcu_l2t3_clk_stop; |
| 83 | release `CPU.tcu.tcu_l2t3_shscan_clk_stop; |
| 84 | release `CPU.tcu.tcu_l2t4_clk_stop; |
| 85 | release `CPU.tcu.tcu_l2t4_shscan_clk_stop; |
| 86 | release `CPU.tcu.tcu_l2t5_clk_stop; |
| 87 | release `CPU.tcu.tcu_l2t5_shscan_clk_stop; |
| 88 | release `CPU.tcu.tcu_l2t6_clk_stop; |
| 89 | release `CPU.tcu.tcu_l2t6_shscan_clk_stop; |
| 90 | release `CPU.tcu.tcu_l2t7_clk_stop; |
| 91 | release `CPU.tcu.tcu_l2t7_shscan_clk_stop; |
| 92 | release `CPU.tcu.tcu_mac_io_clk_stop; |
| 93 | release `CPU.tcu.tcu_mcu0_clk_stop; |
| 94 | release `CPU.tcu.tcu_mcu0_dr_clk_stop; |
| 95 | release `CPU.tcu.tcu_mcu0_fbd_clk_stop; |
| 96 | release `CPU.tcu.tcu_mcu0_io_clk_stop; |
| 97 | release `CPU.tcu.tcu_mcu1_clk_stop; |
| 98 | release `CPU.tcu.tcu_mcu1_dr_clk_stop; |
| 99 | release `CPU.tcu.tcu_mcu1_fbd_clk_stop; |
| 100 | release `CPU.tcu.tcu_mcu1_io_clk_stop; |
| 101 | release `CPU.tcu.tcu_mcu2_clk_stop; |
| 102 | release `CPU.tcu.tcu_mcu2_dr_clk_stop; |
| 103 | release `CPU.tcu.tcu_mcu2_fbd_clk_stop; |
| 104 | release `CPU.tcu.tcu_mcu2_io_clk_stop; |
| 105 | release `CPU.tcu.tcu_mcu3_clk_stop; |
| 106 | release `CPU.tcu.tcu_mcu3_dr_clk_stop; |
| 107 | release `CPU.tcu.tcu_mcu3_fbd_clk_stop; |
| 108 | release `CPU.tcu.tcu_mcu3_io_clk_stop; |
| 109 | release `CPU.tcu.tcu_mio_clk_stop; |
| 110 | release `CPU.tcu.tcu_ncu_clk_stop; |
| 111 | release `CPU.tcu.tcu_ncu_io_clk_stop; |
| 112 | release `CPU.tcu.tcu_peu_io_clk_stop; |
| 113 | release `CPU.tcu.tcu_peu_pc_clk_stop; |
| 114 | release `CPU.tcu.tcu_rdp_io_clk_stop; |
| 115 | release `CPU.tcu.tcu_rst_clk_stop; |
| 116 | release `CPU.tcu.tcu_rst_io_clk_stop; |
| 117 | release `CPU.tcu.tcu_rtx_io_clk_stop; |
| 118 | release `CPU.tcu.tcu_sii_clk_stop; |
| 119 | release `CPU.tcu.tcu_sii_io_clk_stop; |
| 120 | release `CPU.tcu.tcu_sio_clk_stop; |
| 121 | release `CPU.tcu.tcu_sio_io_clk_stop; |
| 122 | release `CPU.tcu.tcu_spc0_clk_stop; |
| 123 | release `CPU.tcu.tcu_spc0_shscan_clk_stop; |
| 124 | release `CPU.tcu.tcu_spc1_clk_stop; |
| 125 | release `CPU.tcu.tcu_spc1_shscan_clk_stop; |
| 126 | release `CPU.tcu.tcu_spc2_clk_stop; |
| 127 | release `CPU.tcu.tcu_spc2_shscan_clk_stop; |
| 128 | release `CPU.tcu.tcu_spc3_clk_stop; |
| 129 | release `CPU.tcu.tcu_spc3_shscan_clk_stop; |
| 130 | release `CPU.tcu.tcu_spc4_clk_stop; |
| 131 | release `CPU.tcu.tcu_spc4_shscan_clk_stop; |
| 132 | release `CPU.tcu.tcu_spc5_clk_stop; |
| 133 | release `CPU.tcu.tcu_spc5_shscan_clk_stop; |
| 134 | release `CPU.tcu.tcu_spc6_clk_stop; |
| 135 | release `CPU.tcu.tcu_spc6_shscan_clk_stop; |
| 136 | release `CPU.tcu.tcu_spc7_clk_stop; |
| 137 | release `CPU.tcu.tcu_spc7_shscan_clk_stop; |
| 138 | release `CPU.tcu.tcu_tds_io_clk_stop; |
| 139 | if (is_forcing) begin |
| 140 | force `CPU.tcu.tcu_ccu_clk_stop = value; |
| 141 | force `CPU.tcu.tcu_ccu_io_clk_stop = value; |
| 142 | force `CPU.tcu.tcu_ccx_clk_stop = value; |
| 143 | force `CPU.tcu.tcu_db0_clk_stop = value; |
| 144 | force `CPU.tcu.tcu_db1_clk_stop = value; |
| 145 | force `CPU.tcu.tcu_dmu_io_clk_stop = value; |
| 146 | force `CPU.tcu.tcu_efu_clk_stop = value; |
| 147 | force `CPU.tcu.tcu_efu_io_clk_stop = value; |
| 148 | force `CPU.tcu.tcu_l2b0_clk_stop = value; |
| 149 | force `CPU.tcu.tcu_l2b1_clk_stop = value; |
| 150 | force `CPU.tcu.tcu_l2b2_clk_stop = value; |
| 151 | force `CPU.tcu.tcu_l2b3_clk_stop = value; |
| 152 | force `CPU.tcu.tcu_l2b4_clk_stop = value; |
| 153 | force `CPU.tcu.tcu_l2b5_clk_stop = value; |
| 154 | force `CPU.tcu.tcu_l2b6_clk_stop = value; |
| 155 | force `CPU.tcu.tcu_l2b7_clk_stop = value; |
| 156 | force `CPU.tcu.tcu_l2d0_clk_stop = value; |
| 157 | force `CPU.tcu.tcu_l2d1_clk_stop = value; |
| 158 | force `CPU.tcu.tcu_l2d2_clk_stop = value; |
| 159 | force `CPU.tcu.tcu_l2d3_clk_stop = value; |
| 160 | force `CPU.tcu.tcu_l2d4_clk_stop = value; |
| 161 | force `CPU.tcu.tcu_l2d5_clk_stop = value; |
| 162 | force `CPU.tcu.tcu_l2d6_clk_stop = value; |
| 163 | force `CPU.tcu.tcu_l2d7_clk_stop = value; |
| 164 | force `CPU.tcu.tcu_l2t0_clk_stop = value; |
| 165 | force `CPU.tcu.tcu_l2t0_shscan_clk_stop = value; |
| 166 | force `CPU.tcu.tcu_l2t1_clk_stop = value; |
| 167 | force `CPU.tcu.tcu_l2t1_shscan_clk_stop = value; |
| 168 | force `CPU.tcu.tcu_l2t2_clk_stop = value; |
| 169 | force `CPU.tcu.tcu_l2t2_shscan_clk_stop = value; |
| 170 | force `CPU.tcu.tcu_l2t3_clk_stop = value; |
| 171 | force `CPU.tcu.tcu_l2t3_shscan_clk_stop = value; |
| 172 | force `CPU.tcu.tcu_l2t4_clk_stop = value; |
| 173 | force `CPU.tcu.tcu_l2t4_shscan_clk_stop = value; |
| 174 | force `CPU.tcu.tcu_l2t5_clk_stop = value; |
| 175 | force `CPU.tcu.tcu_l2t5_shscan_clk_stop = value; |
| 176 | force `CPU.tcu.tcu_l2t6_clk_stop = value; |
| 177 | force `CPU.tcu.tcu_l2t6_shscan_clk_stop = value; |
| 178 | force `CPU.tcu.tcu_l2t7_clk_stop = value; |
| 179 | force `CPU.tcu.tcu_l2t7_shscan_clk_stop = value; |
| 180 | force `CPU.tcu.tcu_mac_io_clk_stop = value; |
| 181 | force `CPU.tcu.tcu_mcu0_clk_stop = value; |
| 182 | force `CPU.tcu.tcu_mcu0_dr_clk_stop = value; |
| 183 | force `CPU.tcu.tcu_mcu0_fbd_clk_stop = value; |
| 184 | force `CPU.tcu.tcu_mcu0_io_clk_stop = value; |
| 185 | force `CPU.tcu.tcu_mcu1_clk_stop = value; |
| 186 | force `CPU.tcu.tcu_mcu1_dr_clk_stop = value; |
| 187 | force `CPU.tcu.tcu_mcu1_fbd_clk_stop = value; |
| 188 | force `CPU.tcu.tcu_mcu1_io_clk_stop = value; |
| 189 | force `CPU.tcu.tcu_mcu2_clk_stop = value; |
| 190 | force `CPU.tcu.tcu_mcu2_dr_clk_stop = value; |
| 191 | force `CPU.tcu.tcu_mcu2_fbd_clk_stop = value; |
| 192 | force `CPU.tcu.tcu_mcu2_io_clk_stop = value; |
| 193 | force `CPU.tcu.tcu_mcu3_clk_stop = value; |
| 194 | force `CPU.tcu.tcu_mcu3_dr_clk_stop = value; |
| 195 | force `CPU.tcu.tcu_mcu3_fbd_clk_stop = value; |
| 196 | force `CPU.tcu.tcu_mcu3_io_clk_stop = value; |
| 197 | force `CPU.tcu.tcu_mio_clk_stop = value; |
| 198 | force `CPU.tcu.tcu_ncu_clk_stop = value; |
| 199 | force `CPU.tcu.tcu_ncu_io_clk_stop = value; |
| 200 | force `CPU.tcu.tcu_peu_io_clk_stop = value; |
| 201 | force `CPU.tcu.tcu_peu_pc_clk_stop = value; |
| 202 | force `CPU.tcu.tcu_rdp_io_clk_stop = value; |
| 203 | force `CPU.tcu.tcu_rst_clk_stop = value; |
| 204 | force `CPU.tcu.tcu_rst_io_clk_stop = value; |
| 205 | force `CPU.tcu.tcu_rtx_io_clk_stop = value; |
| 206 | force `CPU.tcu.tcu_sii_clk_stop = value; |
| 207 | force `CPU.tcu.tcu_sii_io_clk_stop = value; |
| 208 | force `CPU.tcu.tcu_sio_clk_stop = value; |
| 209 | force `CPU.tcu.tcu_sio_io_clk_stop = value; |
| 210 | force `CPU.tcu.tcu_spc0_clk_stop = value; |
| 211 | force `CPU.tcu.tcu_spc0_shscan_clk_stop = value; |
| 212 | force `CPU.tcu.tcu_spc1_clk_stop = value; |
| 213 | force `CPU.tcu.tcu_spc1_shscan_clk_stop = value; |
| 214 | force `CPU.tcu.tcu_spc2_clk_stop = value; |
| 215 | force `CPU.tcu.tcu_spc2_shscan_clk_stop = value; |
| 216 | force `CPU.tcu.tcu_spc3_clk_stop = value; |
| 217 | force `CPU.tcu.tcu_spc3_shscan_clk_stop = value; |
| 218 | force `CPU.tcu.tcu_spc4_clk_stop = value; |
| 219 | force `CPU.tcu.tcu_spc4_shscan_clk_stop = value; |
| 220 | force `CPU.tcu.tcu_spc5_clk_stop = value; |
| 221 | force `CPU.tcu.tcu_spc5_shscan_clk_stop = value; |
| 222 | force `CPU.tcu.tcu_spc6_clk_stop = value; |
| 223 | force `CPU.tcu.tcu_spc6_shscan_clk_stop = value; |
| 224 | force `CPU.tcu.tcu_spc7_clk_stop = value; |
| 225 | force `CPU.tcu.tcu_spc7_shscan_clk_stop = value; |
| 226 | force `CPU.tcu.tcu_tds_io_clk_stop = value; |
| 227 | end // if (is_forcing) |
| 228 | end // task |
| 229 | endtask |
| 230 | |
| 231 | //============================================================== |
| 232 | // WHAT: testing pll_char_out |
| 233 | //============================================================== |
| 234 | task dft_testing_pll_char_out; |
| 235 | integer i; |
| 236 | integer wait_toggle_char_in; // number of sys cycs wait before toggle pll_char_in |
| 237 | integer delay_next_char_in; |
| 238 | integer num_pll_char_in_pulse; |
| 239 | begin |
| 240 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: enter"); |
| 241 | |
| 242 | //--- process +args ----- |
| 243 | if (!($value$plusargs("wait_toggle_char_in=%d", wait_toggle_char_in))) |
| 244 | wait_toggle_char_in = 100; |
| 245 | if (!($value$plusargs("delay_next_char_in=%d", delay_next_char_in))) |
| 246 | delay_next_char_in = 100; |
| 247 | if (!($value$plusargs("num_pll_char_in_pulse=%d", num_pll_char_in_pulse))) |
| 248 | num_pll_char_in_pulse = 1; |
| 249 | |
| 250 | //---- config PKG pins for pll_testmode ------ |
| 251 | #5; // avoid race with initial blocks |
| 252 | tb_top.dbg_dq_reg[157] = 1'b0; // aka pll_char_in |
| 253 | tb_top.dbg_dq_reg[156:151] = 6'h7; // aka pll_div2[5:0]. 0x7 is divided by 8. |
| 254 | tb_top.dbg_dq_reg[150] = 1'b0; // aka pll_trst_l |
| 255 | tb_top.dbg_dq_reg[149] = 1'b0; // aka pll_clamp_fltr. Must be 0. |
| 256 | tb_top.dbg_dq_reg[146:140] = 7'h8; // aka pll_div4[6:0]. 0x8 is divided by 4.0 |
| 257 | tb_top.dbg_dq_reg[139] = 1'b0; // aka ext_dr_clk. TESTMODE is 0, so CCU not send this sig to PLL. |
| 258 | tb_top.dbg_dq_reg[138] = 1'b0; // aka ext_cmp_clk. TESTMODE is 0, so CCU not send this sig to PLL. |
| 259 | pll_testmode_reg = 1'b0; // per KC, PLL_TESTMODE must have 0->1 edge for pll_char mode to work |
| 260 | if (`CPU.PWRON_RST_L !== 1'b0) |
| 261 | @(`CPU.PWRON_RST_L); // wait for bench driving PWRON_RST_L |
| 262 | repeat (2) @(`CPU.PLL_CMP_CLK_P); // wait for 2 edges of sys clk |
| 263 | pll_testmode_reg = 1'b1; // per KC, PLL_TESTMODE must have 0->1 edge for pll_char mode to work |
| 264 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: assert PLL_TESTMODE (ie. 0->1 transition)"); |
| 265 | |
| 266 | //--- reset PLL, wait PLL locked and CCU out of reset |
| 267 | @(posedge `CPU.ccu.rst_ccu_pll_); |
| 268 | tb_top.dbg_dq_reg[150] = 1'b1; // deassert pll_trst_l |
| 269 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: detect rst_ccu_pll_ deasserted. Deassert PLL_TRST_L"); |
| 270 | @(posedge `CPU.ccu.ccu_rst_sync_stable); |
| 271 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: detect ccu_rst_sync_stable asserted"); |
| 272 | repeat (wait_toggle_char_in) @(posedge `CPU.PLL_CMP_CLK_P); |
| 273 | //--- toggle pll_char_in pin to bring out PLL internal nodes to pll_char_out[1:0] |
| 274 | for (i = 1; i <= num_pll_char_in_pulse; i= i + 1) begin |
| 275 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: pulse pll_char_in (pulse #%0d. X mod 8 = %0d)", i, i % 8); |
| 276 | tb_top.dbg_dq_reg[157] = 1'b1; |
| 277 | @(posedge `CPU.PLL_CMP_CLK_P); |
| 278 | tb_top.dbg_dq_reg[157] = 1'b0; |
| 279 | repeat (delay_next_char_in) @(posedge `CPU.PLL_CMP_CLK_P); |
| 280 | end |
| 281 | //--- terminate simulation--- |
| 282 | `PR_ALWAYS ("top", `ALWAYS, "pll_char_out test: terminate simulation"); |
| 283 | $finish; |
| 284 | end |
| 285 | endtask |
| 286 | |
| 287 | //============================================================== |
| 288 | // WHAT: force write request onto TCU-SII bus to mimic L2 write |
| 289 | // access from JTAG port. Wait for SIU's acknowledge. |
| 290 | // ARGS: see comments in the task's port list. |
| 291 | // TCU writes to L2 via SIU: |
| 292 | // - Write request is 128-bit (64-bit header and 64-bit write data). |
| 293 | // - The 64-bit header for wr req is as follows: |
| 294 | // [63:56] is 8'h82 for write req, [55:40]: reserved and are 16'h0, [39:0] is 8-byte aligned PA addr. |
| 295 | // - TCU sends write req in 128 l2clk cycles. |
| 296 | // - In cycles 0 to 63, TCU pulses tcu_sii_vld for one cycle (cycle 0) and drives 64-bit header |
| 297 | // onto tcu_sii_data for 64 cycles with LSB first. |
| 298 | // - In cycles 64 to 127, TCU pulses tcu_sii_vld for one cycle (cycle 64) and drives 64-bit data |
| 299 | // onto tcu_sii_data for 64 cycles with LSB first. |
| 300 | // - TCU then must drive tcu_sii_data to low (in active state). |
| 301 | // - When L2/SIU completes write, it sends acknowledge back to TCU by pulsing sio_tcu_vld |
| 302 | // for one cycle. Per SIU spec, SIU should drive 0 onto sio_tcu_data, but simulation showed |
| 303 | // SIU sometime toggles sio_tcu_data. |
| 304 | // NOTE: addr should be 8-byte aligned, but this task does not check it. |
| 305 | //============================================================== |
| 306 | |
| 307 | task force_tcu_siu_L2_write; |
| 308 | //--- args ---- |
| 309 | input [39:0] addr; // PA addr |
| 310 | input [63:0] data; // write data |
| 311 | //--- vars --- |
| 312 | reg [63:0] header; // wr req header |
| 313 | reg vld_reg, data_reg; // regs to drive tcu_sii_vld and tcu_sii_data signals |
| 314 | integer i; |
| 315 | |
| 316 | begin |
| 317 | header = {8'h82, 16'h0, addr}; // 8'h82: write request |
| 318 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_write(addr[39:0]=%h, wr_data[63:0]=%h)", addr, data); |
| 319 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_write(): header[63:0]=%h or %b", header, header); |
| 320 | //--- init vars --- |
| 321 | @(posedge `TCU.l2clk); |
| 322 | vld_reg = 1'b0; |
| 323 | data_reg = 1'b0; |
| 324 | force `TCU.tcu_sii_vld = vld_reg; // LHS is updated whenever RHS changed |
| 325 | force `TCU.tcu_sii_data = data_reg; // LHS is updated whenever RHS changed |
| 326 | //--- send 64-bit header with LSB first --- |
| 327 | for (i = 0; i < 64; i = i + 1) begin // TCU sends LSB first |
| 328 | @(posedge `TCU.l2clk); |
| 329 | #2 |
| 330 | vld_reg = (i == 0)? 1'b1 : 1'b0; // TCU pulses tcu_sii_vld for one cycle |
| 331 | data_reg = header[i]; |
| 332 | end |
| 333 | //--- send 64-bit write data with LSB first ---- |
| 334 | for (i = 0; i < 64; i = i + 1) begin // TCU sends LSB first |
| 335 | @(posedge `TCU.l2clk); |
| 336 | #2 |
| 337 | vld_reg = (i == 0)? 1'b1 : 1'b0; // TCU pulses tcu_sii_vld for one cycle |
| 338 | data_reg = data[i]; |
| 339 | end |
| 340 | //--- TCU must drive tcu_sii_data with 0 when it's inactive---- |
| 341 | @(posedge `TCU.l2clk); |
| 342 | #2 data_reg = 1'b0; |
| 343 | @(posedge `TCU.l2clk); |
| 344 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_write(): write req was sent. Wait for SIU acknowledge"); |
| 345 | repeat (2) @(posedge `TCU.l2clk); |
| 346 | release `TCU.tcu_sii_vld; |
| 347 | release `TCU.tcu_sii_data; |
| 348 | //--- wait for L2/SIU acks ---- |
| 349 | @(posedge `TCU.sio_tcu_vld); |
| 350 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_write(): received SIU acknowledge (ie. sio_tcu_vld pulsed). Wait for 64 l2clk cycs"); |
| 351 | repeat (64) @(posedge `TCU.l2clk); // response pkt is 64 cycles |
| 352 | repeat (2) @(posedge `TCU.l2clk); // just wait few cycles |
| 353 | end |
| 354 | endtask |
| 355 | |
| 356 | //============================================================== |
| 357 | // WHAT: force read request onto TCU-SII bus to mimic L2 read |
| 358 | // access from JTAG port. Wait for SIU sending back rd data and returns |
| 359 | // it to the caller. |
| 360 | // ARGS: see comments in the task's port list. |
| 361 | // TCU reads to L2 via SIU: |
| 362 | // - Read request is 64-bit (64-bit header). |
| 363 | // - The 64-bit header for read req is as follows: |
| 364 | // [63:56] is 8'h81 for read req, [55:40]: reserved and are 16'h0, [39:0] is 8-byte aligned PA addr. |
| 365 | // - TCU sends read req in 64 l2clk cycles. |
| 366 | // - In cycles 0 to 63, TCU pulses tcu_sii_vld for one cycle (cycle 0) and drives 64-bit header |
| 367 | // onto tcu_sii_data for 64 cycles with LSB first. |
| 368 | // - TCU then must drive tcu_sii_data to low (in active state). |
| 369 | // - When L2/SIU returns 64-bit read data, SIU pulses sio_tcu_vld for one cycle and drives |
| 370 | // 64-bit read data onto sio_tcu_data for 64 l2clk cycles with LSB first. |
| 371 | // - SIU must drive 0 onto sio_tcu_data when it is not active. |
| 372 | // NOTE: addr should be 8-byte aligned, but this task does not check it. |
| 373 | //============================================================== |
| 374 | |
| 375 | task force_tcu_siu_L2_read; |
| 376 | //--- args ---- |
| 377 | input [39:0] addr; // PA addr |
| 378 | output [63:0] data; // read data returned by SIU |
| 379 | //--- vars --- |
| 380 | reg [63:0] header; // rd req header |
| 381 | reg vld_reg, data_reg; // regs to drive tcu_sii_vld and tcu_sii_data signals |
| 382 | integer i; // bit position to be sent |
| 383 | |
| 384 | begin |
| 385 | header = {8'h81, 16'h0, addr}; // 8'h81: read request |
| 386 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_read(addr[39:0]=%h)", addr); |
| 387 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_read(): header[63:0]=%h or %b", header, header); |
| 388 | //--- init vars --- |
| 389 | @(posedge `TCU.l2clk); |
| 390 | vld_reg = 1'b0; |
| 391 | data_reg = 1'b0; |
| 392 | force `TCU.tcu_sii_vld = vld_reg; // LHS is updated whenever RHS changes |
| 393 | force `TCU.tcu_sii_data = data_reg; // LHS is updated whenever RHS changes |
| 394 | //--- send 64-bit header with LSB first --- |
| 395 | for (i = 0; i < 64; i = i + 1) begin // TCU sends LSB first |
| 396 | @(posedge `TCU.l2clk); |
| 397 | #2 |
| 398 | vld_reg = (i == 0)? 1'b1 : 1'b0; // TCU pulses tcu_sii_vld for one cycle |
| 399 | data_reg = header[i]; |
| 400 | end |
| 401 | //--- TCU must drive tcu_sii_data with 0 when it's inactive---- |
| 402 | @(posedge `TCU.l2clk); |
| 403 | #2 data_reg = 1'b0; |
| 404 | @(posedge `TCU.l2clk); |
| 405 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_read(): read req was sent. Wait for SIU sends back rd data"); |
| 406 | repeat (2) @(posedge `TCU.l2clk); // SIU cannot send back rd response in 2 l2clk cycs |
| 407 | release `TCU.tcu_sii_vld; |
| 408 | release `TCU.tcu_sii_data; |
| 409 | //--- wait for L2/SIU sends back rd response ---- |
| 410 | @(posedge `TCU.sio_tcu_vld); |
| 411 | for (i = 0; i < 64; i = i + 1) begin |
| 412 | @(posedge `TCU.l2clk); |
| 413 | data[i] = `TCU.sio_tcu_data; |
| 414 | end |
| 415 | `PR_ALWAYS ("top", `ALWAYS, "force_tcu_siu_L2_read(): addr[39:0]=%h, received rd_data[63:0]=%h with LSB first", addr, data); |
| 416 | repeat (2) @(posedge `TCU.l2clk); // just wait few cycles |
| 417 | end |
| 418 | endtask |
| 419 | |
| 420 | //============================================================== |
| 421 | //============================================================== |
| 422 | |
| 423 | task force_tlrState; |
| 424 | begin |
| 425 | `ifndef GATESIM |
| 426 | force `TCU.jtag_ctl.tap_state[3:0] = 4'hF; |
| 427 | repeat (2) @(posedge `CPU.ccu.l2clk); // this is always-running clock |
| 428 | release `TCU.jtag_ctl.tap_state; |
| 429 | `endif |
| 430 | end |
| 431 | endtask |
| 432 | task release_tlrState; |
| 433 | begin |
| 434 | `ifndef GATESIM |
| 435 | release `TCU.jtag_ctl.tap_state; |
| 436 | `endif |
| 437 | end |
| 438 | endtask |