| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| package chip_env_pkg; |
| |
| // dep packages |
| import uvm_pkg::*; |
| import top_pkg::*; |
| |
| import ast_pkg::AstRegsNum, ast_pkg::AstLastRegOffset; |
| import bus_params_pkg::*; |
| import chip_ral_pkg::*; |
| import cip_base_pkg::*; |
| import csr_utils_pkg::*; |
| import digestpp_dpi_pkg::*; |
| import dv_base_reg_pkg::*; |
| import dv_lib_pkg::*; |
| import dv_utils_pkg::*; |
| import flash_ctrl_pkg::*; |
| import jtag_pkg::*; |
| import jtag_agent_pkg::*; |
| import jtag_riscv_agent_pkg::*; |
| import jtag_dmi_agent_pkg::*; |
| import rv_dm_regs_ral_pkg::*; |
| import rv_dm_debug_mem_ral_pkg::*; |
| import rv_dm_reg_pkg::NrHarts; |
| import rv_dm_reg_pkg::NumAlerts; |
| import kmac_pkg::*; |
| import lc_ctrl_state_pkg::*; |
| import mem_bkdr_util_pkg::*; |
| import otp_ctrl_pkg::*; |
| import spi_agent_pkg::*; |
| import sram_ctrl_pkg::*; |
| import str_utils_pkg::*; |
| import sw_test_status_pkg::*; |
| import tl_agent_pkg::*; |
| import uart_agent_pkg::*; |
| import xbar_env_pkg::*; |
| import top_earlgrey_pkg::*; |
| import top_earlgrey_rnd_cnst_pkg::*; |
| import pwm_monitor_pkg::*; |
| import pwm_reg_pkg::NOutputs; |
| import tl_main_pkg::ADDR_SPACE_RV_CORE_IBEX__CFG; |
| import rv_core_ibex_reg_pkg::RV_CORE_IBEX_DV_SIM_WINDOW_OFFSET; |
| |
| // macro includes |
| `include "uvm_macros.svh" |
| `include "dv_macros.svh" |
| `include "chip_hier_macros.svh" |
| |
| // include auto-generated alert related parameters |
| `include "autogen/chip_env_pkg__params.sv" |
| |
| // local parameters and types |
| parameter uint NUM_GPIOS = 16; |
| parameter uint NUM_UARTS = 4; |
| parameter uint NUM_PWM_CHANNELS = pwm_reg_pkg::NOutputs; |
| |
| // Buffer is half of SPI_DEVICE Dual Port SRAM |
| parameter uint SPI_FRAME_BYTE_SIZE = spi_device_reg_pkg::SPI_DEVICE_BUFFER_SIZE/2; |
| |
| // SW constants - use unmapped address space with at least 32 bytes. |
| |
| parameter bit [TL_AW-1:0] SW_DV_START_ADDR = ADDR_SPACE_RV_CORE_IBEX__CFG + |
| RV_CORE_IBEX_DV_SIM_WINDOW_OFFSET; |
| parameter bit [TL_AW-1:0] SW_DV_TEST_STATUS_ADDR = SW_DV_START_ADDR + 0; |
| parameter bit [TL_AW-1:0] SW_DV_LOG_ADDR = SW_DV_START_ADDR + 4; |
| |
| // LC token paramters |
| // LC sends two 64-bit msg as input token. |
| localparam uint TokenWidthBit = kmac_pkg::MsgWidth * 2; |
| localparam uint TokenWidthByte = TokenWidthBit / 8; |
| |
| typedef virtual pins_if #(NUM_GPIOS) gpio_vif; |
| typedef virtual sw_logger_if sw_logger_vif; |
| typedef virtual sw_test_status_if sw_test_status_vif; |
| typedef virtual alerts_if alerts_vif; |
| typedef virtual ast_supply_if ast_supply_vif; |
| typedef virtual ast_ext_clk_if ast_ext_clk_vif; |
| |
| // Types of memories in the chip. |
| // |
| typedef enum { |
| // external clock is still on, but the source of all IP clocks is the internal clock |
| UseInternalClk, |
| // 48Mhz, same for Life cycle transition mode |
| ExtClkLowSpeed, |
| // 96Mhz |
| ExtClkHighSpeed |
| } ext_clk_type_e; |
| |
| // RAM instances have support for up to 16 tiles. Actual number of tiles in use in the design is a |
| // runtime setting in chip_env_cfg. |
| typedef enum { |
| FlashBank0Data, |
| FlashBank1Data, |
| FlashBank0Info, |
| FlashBank1Info, |
| OtbnDmem[16], |
| OtbnImem, |
| Otp, |
| RamMain[16], |
| RamRet[16], |
| Rom |
| } chip_mem_e; |
| |
| // On OpenTitan, we deal with 4 types of SW - ROM, the main test, the OTBN test and the OTP image. |
| // This basically puts these SW types into 'slots' that the external regression tool can set. |
| typedef enum { |
| SwTypeRom, // Ibex SW - first stage boot ROM. |
| SwTypeTest, // Ibex SW - actual test SW. |
| SwTypeOtbn // Otbn SW. |
| } sw_type_e; |
| |
| typedef enum bit [1:0] { |
| DeselectJtagTap = 2'b00, |
| SelectLCJtagTap = 2'b01, |
| SelectRVJtagTap = 2'b10, |
| SelectDftJtagTap = 2'b11 |
| } chip_tap_type_e; |
| |
| // Two status for LC JTAG to identify if LC state transition is successful. |
| typedef enum int { |
| LcReady, |
| LcTransitionSuccessful, |
| LcTransitionCntError, |
| LcTransitionError, |
| LcTokenError, |
| LcFlashRmaError, |
| LcOtpError |
| } lc_ctrl_status_e; |
| |
| // enumeration for lc_ctrl broadcasts |
| typedef enum int { |
| DftEn = 0, |
| NvmDebugEn, |
| HwDebugEn, |
| CpuEn, |
| CreatorSeedEn, |
| OwnerSeedEn, |
| IsoRdEn, |
| IsoWrEn, |
| SeedRdEn, |
| KeyMgrEn, |
| EscEn, |
| CheckBypEn, |
| LcBroadcastLast |
| } lc_broadcast_e; |
| |
| // hierarchy paths for lc_ctrl broadcast signals |
| string lc_broadcast_paths[LcBroadcastLast] = '{ |
| 0 : "lc_dft_en_o", |
| 1 : "lc_nvm_debug_en_o", |
| 2 : "lc_hw_debug_en_o", |
| 3 : "lc_cpu_en_o", |
| 4 : "lc_creator_seed_sw_rw_en_o", |
| 5 : "lc_owner_seed_sw_rw_en_o", |
| 6 : "lc_iso_part_sw_rd_en_o", |
| 7 : "lc_iso_part_sw_wr_en_o", |
| 8 : "lc_seed_hw_rd_en_o", |
| 9 : "lc_keymgr_en_o", |
| 10 : "lc_escalate_en_o", |
| 11 : "lc_check_byp_en_o" |
| }; |
| |
| |
| // Extracts the address and size of a const symbol in a SW test (supplied as an ELF file). |
| // |
| // Used by a testbench to modify the given symbol in an executable (elf) generated for an embedded |
| // CPU within the DUT. This function only returns the extracted address and size of the symbol |
| // using the readelf utility. Readelf comes with binutils, a package typically available on user |
| // / corp machines. If not available, the assumption is, it can be relatively easily installed. |
| // The actual job of writing the new value into the symbol is handled externally (often via a |
| // backdoor mechanism to write the memory). |
| // Return 1 on success and 0 on failure. |
| function automatic bit sw_symbol_get_addr_size(input string elf_file, |
| input string symbol, |
| input bit does_not_exist_ok, |
| output longint unsigned addr, |
| output longint unsigned size); |
| |
| string msg_id = "sw_symbol_get_addr_size"; |
| `DV_CHECK_STRNE_FATAL(elf_file, "", "Input arg \"elf_file\" cannot be an empty string", msg_id) |
| `DV_CHECK_STRNE_FATAL(symbol, "", "Input arg \"symbol\" cannot be an empty string", msg_id) |
| |
| begin |
| int ret; |
| string line; |
| int out_file_d = 0; |
| string out_file = $sformatf("%0s.dat", symbol); |
| string cmd = $sformatf( |
| // use `--wide` to avoid truncating the output, in case of long symbol name |
| "/usr/bin/readelf -s --wide %0s | grep %0s | awk \'{print $2\" \"$3}\' > %0s", |
| elf_file, symbol, out_file); |
| |
| // TODO #3838: shell pipes are bad 'mkay? |
| ret = $system(cmd); |
| `DV_CHECK_EQ_FATAL(ret, 0, $sformatf("Command \"%0s\" failed with exit code %0d", cmd, ret), |
| msg_id) |
| |
| out_file_d = $fopen(out_file, "r"); |
| `DV_CHECK_FATAL(out_file_d, $sformatf("Failed to open \"%0s\"", out_file), msg_id) |
| |
| ret = $fgets(line, out_file_d); |
| |
| // If the symbol did not exist in the elf (empty file), and we are ok with that, then return. |
| if (!ret && does_not_exist_ok) return 0; |
| |
| `DV_CHECK_FATAL(ret, $sformatf("Failed to read line from \"%0s\"", out_file), msg_id) |
| |
| // The first line should have the addr in hex followed by its size as integer. |
| ret = $sscanf(line, "%h %d", addr, size); |
| `DV_CHECK_EQ_FATAL(ret, 2, $sformatf("Failed to extract {addr size} from line \"%0s\"", line), |
| msg_id) |
| |
| // Attempt to read the next line should be met with EOF. |
| void'($fgets(line, out_file_d)); |
| ret = $feof(out_file_d); |
| `DV_CHECK_FATAL(ret, $sformatf("EOF expected to be reached for \"%0s\"", out_file), msg_id) |
| $fclose(out_file_d); |
| |
| ret = $system($sformatf("rm -rf %0s", out_file)); |
| `DV_CHECK_EQ_FATAL(ret, 0, $sformatf("Failed to delete \"%0s\"", out_file), msg_id) |
| return 1; |
| end |
| endfunction |
| |
| // package sources |
| `include "chip_env_cfg.sv" |
| `include "chip_env_cov.sv" |
| `include "chip_virtual_sequencer.sv" |
| `include "chip_scoreboard.sv" |
| `include "chip_env.sv" |
| `include "chip_vseq_list.sv" |
| |
| endpackage |