blob: 503da2c1ef69e6a1c7488b307f66fb789dfe3ba2 [file] [log] [blame]
// 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