blob: c8f8c4fdd928532caf088ba80f13a91143b78361 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// this is the base vseq that uses stub mode, this vseq can be extended for these tests
// 1. CSR tests
// 2. IP tests which run in chip-level and send TL items on ibex output
class chip_stub_cpu_base_vseq extends chip_base_vseq;
`uvm_object_utils(chip_stub_cpu_base_vseq)
`uvm_object_new
virtual task pre_start();
// In top-level uart RX pin may be selected in pinmux. CSR tests may randomly enable line
// loopback, which will connect TX with RX. If RX isn't enabled in pinmux, it will be 0.
// moniter will start to check the TX data when it changes from 1 to 0. But the length of 0 may
// be not right in CSR test, which causes a protocal error on TX
// In block-level, we always tie RX to 1 (idle) in CSR test so that we don't need to disable TX
// monitor in block-level
foreach (cfg.m_uart_agent_cfgs[i]) cfg.m_uart_agent_cfgs[i].en_tx_monitor = 0;
// Select/Deselect JTAG interface.
if (cfg.jtag_riscv_map != null || cfg.use_jtag_dmi == 1) begin
`DV_GET_ENUM_PLUSARG(chip_common_pkg::chip_jtag_tap_e, cfg.select_jtag, select_jtag)
cfg.chip_vif.tap_straps_if.drive(cfg.select_jtag);
end
enable_asserts_in_hw_reset_rand_wr = 0;
super.pre_start();
endtask
task post_start();
super.post_start();
if (cfg.use_jtag_dmi == 0) begin
// Random CSR rw might trigger alert. Some alerts will conintuously be triggered until reset
// applied, which will cause alert_monitor phase_ready_to_end timeout.
apply_reset();
end
endtask
virtual task apply_reset(string kind = "HARD");
super.apply_reset(kind);
`DV_SPINWAIT(cfg.chip_vif.cpu_clk_rst_if.wait_for_reset();)
endtask
virtual task post_apply_reset(string reset_kind = "HARD");
super.post_apply_reset(reset_kind);
// Wait until rom_ctrl and lc_ctrl have finished to ensure stub_cpu
// does not conflict with any background power-up activity
`uvm_info(`gfn, "Wait for ROM check to complete", UVM_MEDIUM)
wait_rom_check_done();
endtask
virtual task dut_init(string reset_kind = "HARD");
super.dut_init(reset_kind);
// Program the AST with the configuration data loaded in OTP creator SW config region.
`uvm_info(`gfn, "Perform AST configuration", UVM_MEDIUM)
if (cfg.use_jtag_dmi == 0) do_ast_cfg();
endtask
// Write AST registers with the configuration data backdoor loaded into OTP creator SW cfg region.
//
// This mimics what the test ROM / ROM does in SW based tests, but for non-SW tests. Invoked
// in dut_init(), which is called in pre_start().
virtual task do_ast_cfg();
logic [31:0] data;
// The AST registers are defined differently between the open source and closed source repos.
// Hence, we make no references to the AST registers defined in ral.ast. We instead find the
// base address of the AST configuration space, and start writing what was dumped in the
// corresponding OTP locations. The number of registers to program is provided by
// ast_pkg::AstRegsNum, which includes the last AST register which "finalizes" the AST
// initialization and asserts the `ast_init_done_o` signal.
uvm_reg_addr_t ast_addr = ral.ast.default_map.get_base_addr();
if (cfg.mem_bkdr_util_h[Otp].read32(otp_ctrl_reg_pkg::CreatorSwCfgAstInitEnOffset) ==
prim_mubi_pkg::MuBi4True) begin
for (int i = 0; i < ast_pkg::AstRegsNum; i++) begin
data = cfg.mem_bkdr_util_h[Otp].read32(otp_ctrl_reg_pkg::CreatorSwCfgAstCfgOffset + i * 4);
`uvm_info(`gfn, $sformatf("Writing 0x%0h to 0x%0h", data, ast_addr), UVM_MEDIUM)
tl_access(.addr(ast_addr), .write(1), .data(data));
predict_csr_wr(ral.get_default_map(), ast_addr, data);
ast_addr += 4;
end
end
endtask
// Finds the register associated with the given address in the given map, and updates the
// mirrored value with the data written.
function void predict_csr_wr(uvm_reg_map map, uvm_reg_addr_t addr, uvm_reg_data_t data);
uvm_reg rg = map.get_reg_by_offset(addr);
if (rg != null) begin
void'(rg.predict(.value(data), .kind(UVM_PREDICT_WRITE)));
end else begin
`uvm_error(`gfn, $sformatf("No register found at address 0x%0h in %0s", addr, map.`gfn))
end
endfunction
endclass