diff --git a/hw/top_chip/dv/mocha_sim_cfgs.hjson b/hw/top_chip/dv/mocha_sim_cfgs.hjson index ac4878539..4a87ab6c5 100644 --- a/hw/top_chip/dv/mocha_sim_cfgs.hjson +++ b/hw/top_chip/dv/mocha_sim_cfgs.hjson @@ -27,7 +27,7 @@ "{proj_root}/hw/vendor/lowrisc_ip/ip/prim/dv/prim_esc/prim_esc_sim_cfg.hjson", "{proj_root}/hw/vendor/lowrisc_ip/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson", "{proj_root}/hw/top_chip/tmp_sim_cfg/i2c_sim_cfg.hjson", - "{proj_root}/hw/top_chip/tmp_sim_cfg/gpio_sim_cfg.hjson", + "{proj_root}/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson", "{proj_root}/hw/top_chip/tmp_sim_cfg/rom_ctrl_32kB_sim_cfg.hjson", "{proj_root}/hw/top_chip/tmp_sim_cfg/rv_dm_use_jtag_interface_sim_cfg.hjson", diff --git a/hw/top_chip/ip_autogen/gpio/data/gpio_testplan.hjson b/hw/top_chip/ip_autogen/gpio/data/gpio_testplan.hjson index fb4309d1b..8942d784a 100644 --- a/hw/top_chip/ip_autogen/gpio/data/gpio_testplan.hjson +++ b/hw/top_chip/ip_autogen/gpio/data/gpio_testplan.hjson @@ -3,11 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 { name: "gpio" - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", "gpio_sec_cm_testplan.hjson"] testpoints: [ { diff --git a/hw/top_chip/ip_autogen/gpio/dv/env/gpio_scoreboard.sv b/hw/top_chip/ip_autogen/gpio/dv/env/gpio_scoreboard.sv index 3e4885381..f593321cc 100644 --- a/hw/top_chip/ip_autogen/gpio/dv/env/gpio_scoreboard.sv +++ b/hw/top_chip/ip_autogen/gpio/dv/env/gpio_scoreboard.sv @@ -358,44 +358,29 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), end endtask : monitor_gpio_interrupt_pins - virtual task update_gpio_straps_regs(logic [NUM_GPIOS-1:0] gpio_i_sampled); - // Update data_in and data_in_valid ral register value based on result of input - `DV_CHECK_FATAL(ral.hw_straps_data_in.predict(.value(gpio_i_sampled), - .kind(UVM_PREDICT_READ))); - `DV_CHECK_FATAL(ral.hw_straps_data_in_valid.predict(.value('b1), - .kind(UVM_PREDICT_READ))); - endtask : update_gpio_straps_regs - // Task: monitor_gpio_straps // The task monitors the gpio straps enable signal // and checks the straps output signal after the first strap trigger virtual task monitor_gpio_straps(); - logic [NUM_GPIOS-1:0] gpio_i_sampled; forever begin : monitor_gpio_straps - // Wait for going out of reset operation. + // Wait to leave reset wait(!cfg.under_reset); - // Wait until the strap_en input be triggered - // if a reset comes in the middle, step-out of the loop. - while (!cfg.straps_vif_inst.tb_port.strap_en) begin - cfg.clk_rst_vif.wait_clks_or_rst(1); - if (cfg.under_reset) break; - end - // Step out to the next iteration if a reset happens. - if (cfg.under_reset) continue; - // Get the gpio_i input data from the pins interface. - gpio_i_sampled = cfg.gpio_vif.pins; - // Wait for one clock cycle to update the register model. - cfg.clk_rst_vif.wait_clks_or_rst(1); - // Step out from the loop if a reset comes. + + // Now wait until strap_en goes high, dropping out if we go back into reset + fork : isolation_fork begin + fork + wait(cfg.straps_vif_inst.tb_port.strap_en); + wait(cfg.under_reset); + join_any + disable fork; + end join if (cfg.under_reset) continue; - // Update the register model. - update_gpio_straps_regs(gpio_i_sampled); - - // Checker: Compare actual values of gpio pins with straps register. - // Check the register hw_straps_data_in against gpio_i pins - `DV_CHECK_CASE_EQ(gpio_i_sampled, cfg.straps_vif_inst.tb_port.sampled_straps.data) - // Check the register hw_straps_data_in_valid - `DV_CHECK_CASE_EQ('b1, cfg.straps_vif_inst.tb_port.sampled_straps.valid) + + // Sample the pins, storing the value and a validity bit in the register model. + if (!ral.hw_straps_data_in.predict(.value(cfg.gpio_vif.pins), .kind(UVM_PREDICT_DIRECT))) + `uvm_fatal(get_full_name(), "Failed to update HW_STRAPS_DATA_IN prediction.") + if (!ral.hw_straps_data_in_valid.predict(.value(1), .kind(UVM_PREDICT_DIRECT))) + `uvm_fatal(get_full_name(), "Failed to update HW_STRAPS_DATA_IN_VALID prediction.") // Wait for the next reset, if it happens. wait(cfg.under_reset); diff --git a/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson b/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson index cfd1b3194..86eb02ac6 100644 --- a/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson +++ b/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson @@ -12,7 +12,7 @@ tb: tb // Simulator used to sign off this block - tool: vcs + tool: xcelium // Fusesoc core file used for building the file list. fusesoc_core: lowrisc:mocha_dv:gpio_sim:0.1 @@ -26,14 +26,14 @@ // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson"] + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson"] // Add additional tops for simulation. sim_tops: ["gpio_bind", "sec_cm_prim_onehot_check_bind"] diff --git a/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr.hjson b/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr.hjson index 440903aee..553776cac 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr.hjson +++ b/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr.hjson @@ -160,9 +160,9 @@ package: "lc_ctrl_pkg", }, - { struct: "pwr_flash", + { struct: "pwr_nvm", type: "uni", - name: "pwr_flash", + name: "pwr_nvm", act: "rcv", package: "pwrmgr_pkg", }, @@ -729,7 +729,7 @@ name: "ABORT", desc: ''' The abort wakeup reason indicates that despite setting a WFI and providing a low power - hint, an active flash / lifecycle / otp transaction was ongoing when the power controller + hint, an active NVM / lifecycle / otp transaction was ongoing when the power controller attempted to initiate low power entry. The power manager detects this condition, halts low power entry and reports as a wakeup reason diff --git a/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson b/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson index aad3a73fc..745b94ee4 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson +++ b/hw/top_chip/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson @@ -106,14 +106,14 @@ Low power transitions can be aborted in two cases: - The processor gets an interrupt soon after a low power entry is triggered. - - OTP, LC, or FLASH are not idle. + - OTP, LC, or NVM are not idle. This test aborts low power transitions, and disables any wakeups, so the test would timeout if low power was entered. **Stimulus**: - Bring pwrmgr to low power. - Either disable `pwr_cpu.core_sleeping` or keep some of `lc_idle`, - `otp_idle`, or `flash_idle` inputs off. + `otp_idle`, or `nvm_idle` inputs off. - Disable all wakeup enables. - Randomly set `wakeup_info_capture_dis` CSR. diff --git a/hw/top_chip/ip_autogen/pwrmgr/dv/README.md b/hw/top_chip/ip_autogen/pwrmgr/dv/README.md index 595ce0959..37107e16a 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/dv/README.md +++ b/hw/top_chip/ip_autogen/pwrmgr/dv/README.md @@ -112,7 +112,7 @@ The test sequences besides the base are as follows: * `pwrmgr_wakeup_vseq` checks the transitions to low power and the wakeup settings. It randomizes wakeup inputs, wakeup enables, the wakeup info capture enable, and the interrupt enable. * `pwrmgr_aborted_low_power_vseq` creates scenarios that lead to aborting a low power transition. - The abort can be due to the processor waking up very soon, or otp, lc, or flash being busy. + The abort can be due to the processor waking up very soon, or otp, lc, or nvm being busy. * `pwrmgr_reset_vseq` checks the pwrmgr response to conditional resets and reset enables, and unconditional escalation and main power glitch resets. * `pwrmgr_wakeup_reset_vseq` aligns reset and wakeup from low power. * `pwrmgr_lowpower_wakeup_race_vseq` aligns a wakeup event coming in proximity to low power entry. @@ -210,8 +210,8 @@ See also the test plan for specific ways these are driven to trigger different t ##### LC The pins connecting to LC behave pretty much the same way as those to OTP. -##### FLASH -- Input `flash_idle` is handled much like `lc_idle` and `otp_idle`. +##### NVM +- Input `nvm_idle` is handled much like `lc_idle` and `otp_idle`. ##### CPU - Input `core_sleeping` is driven by sequences. diff --git a/hw/top_chip/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv b/hw/top_chip/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv index 2da8a98a2..511f4ba0e 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv @@ -36,7 +36,7 @@ interface pwrmgr_if ( lc_ctrl_pkg::pwr_lc_req_t pwr_lc_req; lc_ctrl_pkg::pwr_lc_rsp_t pwr_lc_rsp; - pwrmgr_pkg::pwr_flash_t pwr_flash; + pwrmgr_pkg::pwr_nvm_t pwr_nvm; pwrmgr_pkg::pwrmgr_cpu_t cpu_i; rv_core_ibex_pkg::cpu_pwrmgr_t pwr_cpu; @@ -152,8 +152,8 @@ interface pwrmgr_if ( pwr_lc_rsp.lc_idle = value; endfunction - function automatic void update_flash_idle(logic value); - pwr_flash.flash_idle = value; + function automatic void update_nvm_idle(logic value); + pwr_nvm.nvm_idle = value; endfunction function automatic void update_cpu_sleeping(logic value); @@ -202,7 +202,7 @@ interface pwrmgr_if ( pwr_clk_rsp = '{default: '0}; pwr_otp_rsp = '{default: '0}; pwr_lc_rsp = '{default: '0}; - pwr_flash = '{default: '0}; + pwr_nvm = '{default: '0}; pwr_cpu = rv_core_ibex_pkg::CPU_PWRMGR_DEFAULT; wakeups_i = pwrmgr_pkg::WAKEUPS_DEFAULT; rstreqs_i = pwrmgr_pkg::RSTREQS_DEFAULT; diff --git a/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv b/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv index 41222fe2a..f095f3d46 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv @@ -21,13 +21,13 @@ class pwrmgr_aborted_low_power_vseq extends pwrmgr_base_vseq; }; } - rand bit flash_idle; + rand bit nvm_idle; rand bit lc_idle; rand bit otp_idle; constraint idle_c { - solve cpu_interrupt before flash_idle, lc_idle, otp_idle; - if (!cpu_interrupt) {(flash_idle && lc_idle && otp_idle) == 1'b0;} + solve cpu_interrupt before nvm_idle, lc_idle, otp_idle; + if (!cpu_interrupt) {(nvm_idle && lc_idle && otp_idle) == 1'b0;} } constraint wakeups_c {wakeups != 0;} @@ -84,12 +84,12 @@ class pwrmgr_aborted_low_power_vseq extends pwrmgr_base_vseq; cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); end else begin `uvm_info(`gfn, $sformatf( - "Expecting an abort (0x80): fi=%b, li=%b, oi=%b", - flash_idle, + "Expecting an abort (0x80): nvm_idle=%b, lc_idle=%b, otp_idle=%b", + nvm_idle, lc_idle, otp_idle ), UVM_MEDIUM) - set_nvms_idle(flash_idle, lc_idle, otp_idle); + set_nvms_idle(nvm_idle, lc_idle, otp_idle); end end join diff --git a/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv b/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv index 041ffdb98..c73da9545 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv @@ -493,7 +493,7 @@ class pwrmgr_base_vseq extends cip_base_vseq #( local task wait_for_abort(); `DV_WAIT( - !cfg.pwrmgr_vif.pwr_flash.flash_idle || !cfg.pwrmgr_vif.pwr_otp_rsp.otp_idle || + !cfg.pwrmgr_vif.pwr_nvm.nvm_idle || !cfg.pwrmgr_vif.pwr_otp_rsp.otp_idle || !cfg.pwrmgr_vif.pwr_lc_rsp.lc_idle) exp_intr = 1'b1; `uvm_info(`gfn, "wait_for_abort succeeds", UVM_MEDIUM) @@ -562,11 +562,11 @@ class pwrmgr_base_vseq extends cip_base_vseq #( // This enables the fast fsm to transition to low power when all nvms are idle after the // transition is enabled by software and cpu WFI. When not all are idle the transition is // aborted. - virtual task set_nvms_idle(logic flash_idle = 1'b1, logic lc_idle = 1'b1, logic otp_idle = 1'b1); + virtual task set_nvms_idle(logic nvm_idle = 1'b1, logic lc_idle = 1'b1, logic otp_idle = 1'b1); `uvm_info(`gfn, $sformatf( - "Setting nvms idle: flash=%b, lc=%b, otp=%b", flash_idle, lc_idle, otp_idle), + "Setting nvms idle: nvm=%b, lc=%b, otp=%b", nvm_idle, lc_idle, otp_idle), UVM_MEDIUM) - cfg.pwrmgr_vif.update_flash_idle(flash_idle); + cfg.pwrmgr_vif.update_nvm_idle(nvm_idle); cfg.pwrmgr_vif.update_lc_idle(lc_idle); cfg.pwrmgr_vif.update_otp_idle(otp_idle); endtask diff --git a/hw/top_chip/ip_autogen/pwrmgr/dv/tb.sv b/hw/top_chip/ip_autogen/pwrmgr/dv/tb.sv index 72016790b..1a817fbed 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/dv/tb.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/dv/tb.sv @@ -90,7 +90,7 @@ module tb; .pwr_lc_i(pwrmgr_if.pwr_lc_rsp), .pwr_lc_o(pwrmgr_if.pwr_lc_req), - .pwr_flash_i(pwrmgr_if.pwr_flash), + .pwr_nvm_i(pwrmgr_if.pwr_nvm), .pwr_cpu_i (pwrmgr_if.pwr_cpu), .fetch_en_o(pwrmgr_if.fetch_en), diff --git a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr.sv b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr.sv index 22edf99f1..856f66a6d 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr.sv @@ -56,8 +56,8 @@ module pwrmgr input lc_ctrl_pkg::pwr_lc_rsp_t pwr_lc_i, output lc_ctrl_pkg::pwr_lc_req_t pwr_lc_o, - // flash interface - input pwr_flash_t pwr_flash_i, + // NVM interface + input pwr_nvm_t pwr_nvm_i, // processor interface input rv_core_ibex_pkg::cpu_pwrmgr_t pwr_cpu_i, @@ -269,7 +269,7 @@ module pwrmgr logic low_power_fall_through; logic low_power_abort; - pwr_flash_t flash_rsp; + pwr_nvm_t nvm_rsp; pwr_otp_rsp_t otp_rsp; prim_mubi_pkg::mubi4_t [NumRomInputs-1:0] rom_ctrl_done_async; @@ -453,9 +453,9 @@ module pwrmgr // peripheral signals .peri_i(peri_reqs_raw), - // flash handshake - .flash_i(pwr_flash_i), - .flash_o(flash_rsp), + // NVM handshake + .nvm_i(pwr_nvm_i), + .nvm_o(nvm_rsp), // OTP signals .otp_i(pwr_otp_i), @@ -632,8 +632,8 @@ module pwrmgr .lc_dft_en_i (lc_dft_en), .lc_hw_debug_en_i (lc_hw_debug_en), - // flash - .flash_idle_i (flash_rsp.flash_idle), + // NVM + .nvm_idle_i (nvm_rsp.nvm_idle), // rom_ctrl .rom_ctrl_done_i (rom_ctrl_done_combined), diff --git a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv index 8c6d0f6e0..c2298244e 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv @@ -52,8 +52,8 @@ module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; // peripheral inputs, mixed domains input pwr_peri_t peri_i, - input pwr_flash_t flash_i, - output pwr_flash_t flash_o, + input pwr_nvm_t nvm_i, + output pwr_nvm_t nvm_o, // otp interface input pwr_otp_rsp_t otp_i, @@ -261,11 +261,11 @@ module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; prim_flop_2sync #( .Width(1), .ResetValue(1'b1) - ) u_sync_flash_idle ( + ) u_sync_nvm_idle ( .clk_i, .rst_ni, - .d_i(flash_i.flash_idle), - .q_o(flash_o.flash_idle) + .d_i(nvm_i.nvm_idle), + .q_o(nvm_o.nvm_idle) ); prim_flop_2sync #( diff --git a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv index 1f7a426db..70f64a846 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv @@ -52,8 +52,8 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;( input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, - // flash - input flash_idle_i, + // NVM + input nvm_idle_i, // rom_ctrl input prim_mubi_pkg::mubi4_t rom_ctrl_done_i, @@ -398,7 +398,7 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;( FastPwrStateNvmIdleChk: begin - if (otp_idle_i && lc_idle_i && flash_idle_i) begin + if (otp_idle_i && lc_idle_i && nvm_idle_i) begin state_d = FastPwrStateLowPowerPrep; end else begin ip_clk_en_d = 1'b1; diff --git a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv index c69b068ee..cdc5d63ec 100644 --- a/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv +++ b/hw/top_chip/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv @@ -115,11 +115,11 @@ package pwrmgr_pkg; }; typedef struct packed { - logic flash_idle; - } pwr_flash_t; + logic nvm_idle; + } pwr_nvm_t; - parameter pwr_flash_t PWR_FLASH_DEFAULT = '{ - flash_idle: 1'b1 + parameter pwr_nvm_t PWR_NVM_DEFAULT = '{ + nvm_idle: 1'b1 }; // cpu reset requests and status diff --git a/hw/top_chip/rtl/top_chip_system.sv b/hw/top_chip/rtl/top_chip_system.sv index 06702608c..47ea44ed8 100644 --- a/hw/top_chip/rtl/top_chip_system.sv +++ b/hw/top_chip/rtl/top_chip_system.sv @@ -749,7 +749,7 @@ module top_chip_system #( .pwr_otp_o ( ), .pwr_lc_o ( ), .pwr_lc_i (lc_ctrl_pkg::PWR_LC_RSP_DEFAULT), // Default to initialised and done. - .pwr_flash_i (pwrmgr_pkg::PWR_FLASH_DEFAULT), // Default to idle. + .pwr_nvm_i (pwrmgr_pkg::PWR_NVM_DEFAULT), // Default to idle. .esc_rst_tx_i (prim_esc_pkg::ESC_RX_DEFAULT), .esc_rst_rx_o ( ), .pwr_cpu_i ('0), // Core is not sleeping. diff --git a/hw/top_chip/tmp_sim_cfg/gpio_sim_cfg.hjson b/hw/top_chip/tmp_sim_cfg/gpio_sim_cfg.hjson deleted file mode 100644 index 814a381f9..000000000 --- a/hw/top_chip/tmp_sim_cfg/gpio_sim_cfg.hjson +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - // Name of the sim cfg - typically same as the name of the DUT. - name: gpio - - // Top level dut name (sv module). - dut: gpio - - // Top level testbench name (sv module). - tb: tb - - // Simulator used to sign off this block - tool: xcelium - - // Fusesoc core file used for building the file list. - fusesoc_core: lowrisc:dv:gpio_sim:0.1 - - // Testplan hjson file. - testplan: "{proj_root}/hw/ip/gpio/data/gpio_testplan.hjson" - - // RAL spec - used to generate the RAL model. - ral_spec: "{proj_root}/hw/ip/gpio/data/gpio.hjson" - - // Import additional common sim cfg files. - import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", - // Common CIP test lists - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/intr_test.hjson", - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson"] - - // Add additional tops for simulation. - sim_tops: ["gpio_bind", "sec_cm_prim_onehot_check_bind"] - - // Default iterations for all tests - each test entry can override this. - reseed: 50 - - // Default UVM test and seq class name. - uvm_test: gpio_base_test - uvm_test_seq: gpio_base_vseq - - // Add GPIO specific exclusion files. - vcs_cov_excl_files: ["{proj_root}/hw/ip/gpio/dv/cov/gpio_cov_excl.el"] - - // Enable cdc instrumentation. - run_opts: ["+cdc_instrumentation_enabled=1"] - - // Add a second build mode to test the input synchronizers. - // Note that since the scoreboard has a cycle accurate model - // for GPIO without the synchronizers, the majority of the tests - // is run in the default build mode without the CDC prims. The en_cdc_prims - // build mode is used to run some additional smoke checks to ensure - // that the input paths through the CDC prims are connected correctly. - build_modes: [ - { - name: en_cdc_prims - build_opts: ["+define+GPIO_ASYNC_ON"] - } - ] - - en_cdc_prims_vcs_cov_cfg_file: "{default_vcs_cov_cfg_file}" - en_cdc_prims_xcelium_cov_cfg_file: "{default_xcelium_cov_cfg_file}" - - // List of test specifications. - tests: [ - { - name: gpio_smoke - uvm_test_seq: gpio_smoke_vseq - } - - { - name: gpio_smoke_no_pullup_pulldown - uvm_test_seq: gpio_smoke_vseq - run_opts: ["+no_pullup_pulldown=1"] - } - - { - name: gpio_random_dout_din - uvm_test_seq: gpio_random_dout_din_vseq - } - - { - name: gpio_random_dout_din_no_pullup_pulldown - uvm_test_seq: gpio_random_dout_din_vseq - run_opts: ["+no_pullup_pulldown=1"] - } - - { - name: gpio_dout_din_regs_random_rw - uvm_test_seq: gpio_dout_din_regs_random_rw_vseq - } - - { - name: gpio_intr_rand_pgm - uvm_test_seq: gpio_intr_rand_pgm_vseq - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_rand_intr_trigger - uvm_test_seq: gpio_rand_intr_trigger_vseq - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_intr_with_filter_rand_intr_event - uvm_test_seq: gpio_intr_with_filter_rand_intr_event_vseq - run_opts: ["+en_scb=0", "+zero_delays=1", "+do_clear_all_interrupts=0"] - } - - { - name: gpio_filter_stress - uvm_test_seq: gpio_filter_stress_vseq - run_opts: ["+en_scb=0", "+do_clear_all_interrupts=0"] - } - - { - name: gpio_random_long_reg_writes_reg_reads - uvm_test_seq: gpio_random_long_reg_writes_reg_reads_vseq - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_full_random - uvm_test_seq: gpio_full_random_vseq - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_stress_all - uvm_test_seq: gpio_stress_all_vseq - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_stress_all_with_rand_reset - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_csr_rw - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_same_csr_outstanding - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_csr_aliasing - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_csr_mem_rw_with_rand_reset - run_opts: ["+do_clear_all_interrupts=0"] - } - - { - name: gpio_tl_intg_err - run_opts: ["+do_clear_all_interrupts=0"] - } - - // Additional smoke checks for second build mode - { - name: gpio_smoke_en_cdc_prim - uvm_test_seq: gpio_smoke_vseq - build_mode: en_cdc_prims - } - - { - name: gpio_smoke_no_pullup_pulldown_en_cdc_prim - uvm_test_seq: gpio_smoke_vseq - build_mode: en_cdc_prims - run_opts: ["+no_pullup_pulldown=1"] - } - ] - - // List of regressions. - regressions: [ - { - name: smoke - tests: ["gpio_smoke", "gpio_smoke_en_cdc_prim"] - } - ] -} diff --git a/hw/vendor/lowrisc_ip.lock.hjson b/hw/vendor/lowrisc_ip.lock.hjson index d789f8cc1..0d2ba651f 100644 --- a/hw/vendor/lowrisc_ip.lock.hjson +++ b/hw/vendor/lowrisc_ip.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/lowRISC/opentitan - rev: 70e4060e8ada72db496af76b3a899268902c33f2 + rev: 4125149c87024c97825c667420d2101d96f98bc6 } } diff --git a/hw/vendor/lowrisc_ip.vendor.hjson b/hw/vendor/lowrisc_ip.vendor.hjson index 6713c2f25..da129a3f4 100644 --- a/hw/vendor/lowrisc_ip.vendor.hjson +++ b/hw/vendor/lowrisc_ip.vendor.hjson @@ -40,7 +40,7 @@ // Hardware IP templates. {from: "hw/ip_templates/alert_handler", to: "ip_templates/alert_handler"}, // Dependency of reset manager. {from: "hw/ip_templates/clkmgr", to: "ip_templates/clkmgr"}, - {from: "hw/ip_templates/gpio", to: "ip_templates/gpio"}, // General purpose I/O + {from: "hw/ip_templates/gpio", to: "ip_templates/gpio", patch_dir: "gpio"}, // General purpose I/O {from: "hw/ip_templates/pwrmgr", to: "ip_templates/pwrmgr", patch_dir: "pwrmgr"}, {from: "hw/ip_templates/rstmgr", to: "ip_templates/rstmgr"}, {from: "hw/ip_templates/rv_plic", to: "ip_templates/rv_plic"}, diff --git a/hw/vendor/lowrisc_ip/dv/dpi/gpiodpi/gpiodpi.sv b/hw/vendor/lowrisc_ip/dv/dpi/gpiodpi/gpiodpi.sv index f44caac15..8f65eaec0 100644 --- a/hw/vendor/lowrisc_ip/dv/dpi/gpiodpi/gpiodpi.sv +++ b/hw/vendor/lowrisc_ip/dv/dpi/gpiodpi/gpiodpi.sv @@ -64,8 +64,6 @@ module gpiodpi end end - logic gpio_write_pulse; - always_ff @(posedge eff_clk or negedge rst_ni) begin if (!rst_ni) begin gpio_p2d <= '0; // default value diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_env_cfg.sv b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_env_cfg.sv index bf650e718..4b9ab3b16 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_env_cfg.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_env_cfg.sv @@ -149,8 +149,8 @@ class cip_base_env_cfg #(type RAL_T = dv_base_reg_block) extends dv_base_env_cfg // Assign handle to the default `m_tl_agent_cfg` for default `RAL_T` if (ral_model_names.size > 0) begin - `DV_CHECK_FATAL(m_tl_agent_cfgs.exists(RAL_T::type_name)) - m_tl_agent_cfg = m_tl_agent_cfgs[RAL_T::type_name]; + `DV_CHECK_FATAL(m_tl_agent_cfgs.exists(ral_type_name)) + m_tl_agent_cfg = m_tl_agent_cfgs[ral_type_name]; `DV_CHECK_NE_FATAL(m_tl_agent_cfg, null) end diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_scoreboard.sv b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_scoreboard.sv index 54b6cb2ab..41258d627 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_scoreboard.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_base_scoreboard.sv @@ -509,16 +509,16 @@ class cip_base_scoreboard #(type RAL_T = dv_base_reg_block, // For flash, address has to be 8-byte aligned. bit ecc_err = ecc_error_addr.exists({item.a_addr[AddrWidth-1:3], 3'b0}); - if (unmapped_err) begin - exp_d_error = !block.get_unmapped_access_ok(); - end + // Predict an error if this is not a mapped address and the block doesn't allow unmapped + // accesses. + exp_d_error |= unmapped_err && !block.get_unmapped_access_ok(); if (mem_access_err) begin // Some memory implementations may not return an error response on invalid accesses. exp_d_error |= mem_byte_access_err | mem_wo_err | mem_ro_err | custom_err; end - if (is_mem_addr(item.a_addr, block) && cfg.tl_mem_access_gated) begin + if (is_mem_addr(item.a_addr, block)) begin exp_d_error |= cfg.tl_mem_access_gated; end @@ -546,14 +546,41 @@ class cip_base_scoreboard #(type RAL_T = dv_base_reg_block, end end - `DV_CHECK_EQ(item.d_error, exp_d_error, - $sformatf({"On interface %0s, TL item: %0s, unmapped_err: %0d, mem_access_err: %0d, ", - "bus_intg_err: %0d, byte_wr_err: %0d, csr_size_err: %0d, tl_item_err: %0d, ", - "write_w_instr_type_err: %0d, ", "cfg.tl_mem_access_gated: %0d ", - "ecc_err: %0d"}, - ral_name, item.sprint(uvm_default_line_printer), unmapped_err, mem_access_err, - bus_intg_err, byte_wr_err, csr_size_err, tl_item_err, write_w_instr_type_err, - cfg.tl_mem_access_gated, ecc_err)) + if (item.d_error != exp_d_error) begin + string reasons[$]; + + if (exp_d_error) begin + if (unmapped_err && !block.get_unmapped_access_ok()) begin + reasons.push_back("Unmapped address"); + end + if (mem_access_err) begin + if (mem_byte_access_err) reasons.push_back("Unsupported partial write"); + if (mem_wo_err) reasons.push_back("Read of write-only memory"); + if (mem_ro_err) reasons.push_back("Write to read-only memory"); + if (custom_err) reasons.push_back("'custom' error"); + end + if (is_mem_addr(item.a_addr, block) && cfg.tl_mem_access_gated) begin + reasons.push_back("Access to gated memory"); + end + if (byte_wr_err) reasons.push_back("Byte write to interface that doesn't support it"); + if (bus_intg_err) reasons.push_back("Bad A channel integrity"); + if (csr_size_err) reasons.push_back("Over-wide CSR write"); + if (tl_item_err) reasons.push_back("A-channel item should trigger error"); + if (write_w_instr_type_err) reasons.push_back("Write when instr-type is set"); + if (instr_type_err) reasons.push_back("MuBi error in instr-type"); + if (ecc_err) reasons.push_back("Access to address with known-bad ECC"); + if (csr_read_err) reasons.push_back("Fetch from CSR"); + end + + `uvm_error(get_full_name(), + $sformatf({"On interface %0s, item had unexpected d_error value", + "(predicted %0d, but saw %0d).\n", + " TL item was: %0s", + " Reasons for predicted error: %0p."}, + ral_name, exp_d_error, item.d_error, + item.sprint(uvm_default_line_printer), + reasons)) + end // In data read phase, check d_data when d_error = 1. if (item.d_error && (item.d_opcode == tlul_pkg::AccessAckData)) begin diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_macros.svh b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_macros.svh index 1ab95af3c..058fb7a0b 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_macros.svh +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/cip_macros.svh @@ -49,28 +49,49 @@ end `endif -// A macro to simplify the distribution constraint of mubi type variable -// Don't use this macro directly, use DV_MUBI4|8|16_DIST. -// The weights of both TRUE and FALSE are scaled by the number of other -// values, and this uses ":=" for the distribution of other values, so they -// are truly uniform. -// The MAX_ argument is the maximum value that VAR_ can take, which means -// (MAX_ - 1) is the scaling factor. +// Macros that expand to a ternary expression giving the smaller / larger of the two values. +// +// These make no guarantee to only evaluate arguments once. +`ifndef _DV_TERNARY_MIN +`define _DV_TERNARY_MIN(a_, b_) (((a_) < (b_)) ? (a_) : (b_)) +`endif +`ifndef _DV_TERNARY_MAX +`define _DV_TERNARY_MAX(a_, b_) (((a_) < (b_)) ? (b_) : (a_)) +`endif + +// A macro that expands to a constraint giving distribution for a mubi-type variable +// Don't use this macro directly: use DV_MUBI4|8|16_DIST instead. +// +// Arguments: +// +// VAR_ The variable whose distribution is being constrained +// TRUE_ MuBi true value +// FALSE_ MuBi false value +// MAX_ The maximum value in the bit-vector range for the value +// T_WEIGHT_ The weight to give the "true" value +// F_WEIGHT_ The weight to give the "false" value +// OTHER_WEIGHT_ The weight spread among all other values +// +// This macro uses ":=" to give weights for the other cases in order that the individual values +// won't have a weight that depends on the length of the range containing them. There are (MAX_ - 2) +// items in these other ranges, so we scale T_WEIGHT_ and F_WEIGHT_ by that value to ensure that +// T_WEIGHT_/F_WEIGHT_/OTHER_WEIGHT_ give the relative weights for true/false/something-else. For +// example, if T_WEIGHT_, F_WEIGHT_ and OTHER_WEIGHT_ are all equal then the probabilities of +// getting "true" and "false" and getting something else are all 1/3. +// +// Some tools generate a warning if there is a backwards range ([big:little]) in the distribution, +// even if an if/else check ensures that it isn't used. To avoid this warning, we use a ternary +// operator to extract the larger/smaller value. `ifndef _DV_MUBI_DIST -`define _DV_MUBI_DIST(VAR_, TRUE_, FALSE_, MAX_, T_WEIGHT_, F_WEIGHT_, OTHER_WEIGHT_) \ - if (TRUE_ > FALSE_) { \ - VAR_ dist {TRUE_ := (T_WEIGHT_) * ((MAX_) - 1), \ - FALSE_ := (F_WEIGHT_) * ((MAX_) - 1), \ - [0 : FALSE_ - 1] := (OTHER_WEIGHT_), \ - [FALSE_ + 1 : TRUE_ - 1] := (OTHER_WEIGHT_), \ - [TRUE_ + 1 : (MAX_)] := (OTHER_WEIGHT_)}; \ - } else { \ - VAR_ dist {TRUE_ := (T_WEIGHT_) * ((MAX_) - 1), \ - FALSE_ := (F_WEIGHT_) * ((MAX_) - 1), \ - [0 : TRUE_ - 1] := (OTHER_WEIGHT_), \ - [TRUE_ + 1 : FALSE_ - 1] := (OTHER_WEIGHT_), \ - [FALSE_+ 1 : (MAX_)] := (OTHER_WEIGHT_)}; \ - } +`define _DV_MUBI_DIST(VAR_, TRUE_, FALSE_, MAX_, T_WEIGHT_, F_WEIGHT_, OTHER_WEIGHT_) \ + VAR_ dist { \ + TRUE_ := (T_WEIGHT_) * ((MAX_) - 1), \ + FALSE_ := (F_WEIGHT_) * ((MAX_) - 1), \ + [0 : `_DV_TERNARY_MIN(TRUE_, FALSE_)-1] := (OTHER_WEIGHT_), \ + [(`_DV_TERNARY_MIN(TRUE_, FALSE_)+1) : \ + (`_DV_TERNARY_MAX(TRUE_, FALSE_)-1)] := (OTHER_WEIGHT_), \ + [(`_DV_TERNARY_MAX(TRUE_, FALSE_)+1):(MAX_)] := (OTHER_WEIGHT_) \ + }; `endif // inputs of these macros diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq.sv b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq.sv index f95a73b07..1b257e4a3 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq.sv @@ -626,8 +626,15 @@ task cip_base_vseq::tl_access_sub( // Now wait a bounded time to check that the bus hasn't locked up for some reason. #(tl_access_timeout_ns * 1ns); + + `uvm_fatal(get_name(), + $sformatf("Timeout (%0d ns) when trying to access address 0x%0h.", + tl_access_timeout_ns, addr)) end join_any + // This disable will only kill the timeout process. That process can never complete first + // (because it will die with a uvm_fatal instead). As a result, there is no danger of killing + // the sequence that is being run. disable fork; end join csr_utils_pkg::decrement_outstanding_access(); diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__tl_errors.svh b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__tl_errors.svh index 02b5416d4..29408bd55 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__tl_errors.svh +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__tl_errors.svh @@ -246,7 +246,9 @@ endfunction // reset), stop generating transactions and return. virtual task tl_instr_type_err(string ral_name); dv_base_reg_block ral_model = cfg.ral_models[ral_name]; - bit has_csrs = (ral_model.csr_addrs.size() > 0); + bit has_nofetch_csrs = ((ral_model.csr_addrs.size() > 0) && + !ral_model.get_allows_csr_fetch()); + repeat ($urandom_range(10, 100)) begin bit [BUS_AW-1:0] addr; bit write; @@ -271,7 +273,7 @@ virtual task tl_instr_type_err(string ral_name); write = 1'b1; instr_type = MuBi4True; end - has_csrs: begin + has_nofetch_csrs: begin write = 1'b0; instr_type = MuBi4True; addr = pick_rand_csr_addr(ral_name, ral_model); diff --git a/hw/vendor/lowrisc_ip/dv/sv/dv_base_reg/dv_base_reg_block.sv b/hw/vendor/lowrisc_ip/dv/sv/dv_base_reg/dv_base_reg_block.sv index 733c2d7a0..b7a0487e4 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/dv_base_reg/dv_base_reg_block.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/dv_base_reg/dv_base_reg_block.sv @@ -66,6 +66,11 @@ class dv_base_reg_block extends uvm_reg_block; // This is added for ease of rv_dm testbench development. protected bit supports_byte_enable = 1'b1; + // Indicates whether an instruction fetch is allowed from a CSR. This isn't something you'd + // normally expect, but it allows us to model a block that contains both registers and memory and + // doesn't make a distinction between read and fetch. + local bit allows_csr_fetch = 1'b0; + // Custom RAL models may support sub-word CSR writes smaller than CSR width. protected bit supports_sub_word_csr_writes = 1'b0; @@ -132,6 +137,14 @@ class dv_base_reg_block extends uvm_reg_block; return supports_sub_word_csr_writes; endfunction + function void set_allows_csr_fetch(bit allowed); + allows_csr_fetch = allowed; + endfunction + + function bit get_allows_csr_fetch(); + return allows_csr_fetch; + endfunction + // provide build function to supply base addr virtual function void build(uvm_reg_addr_t base_addr, csr_excl_item csr_excl = null); diff --git a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv index 2ce662fa8..65b2b4a6e 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv @@ -17,17 +17,19 @@ class dv_base_env #(type CFG_T = dv_base_env_cfg, virtual function void build_phase(uvm_phase phase); string default_ral_name; + string ral_models[$]; + super.build_phase(phase); // get dv_base_env_cfg object from uvm_config_db if (!uvm_config_db#(CFG_T)::get(this, "", "cfg", cfg)) begin `uvm_fatal(`gfn, $sformatf("failed to get %s from uvm_config_db", cfg.get_type_name())) end - // get vifs for RAL models - if (cfg.ral_model_names.size > 0) begin + ral_models = cfg.get_ral_model_names(); + if (ral_models.size() > 0) begin default_ral_name = cfg.ral.get_type_name(); - foreach (cfg.ral_model_names[i]) begin - string ral_name = cfg.ral_model_names[i]; + foreach (ral_models[i]) begin + string ral_name = ral_models[i]; string if_name; if (ral_name == default_ral_name) if_name = "clk_rst_vif"; diff --git a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv index bd6b05fcb..843e40f6c 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv @@ -43,6 +43,14 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object; // If this is true, all UVCs should run with zero delays, which creates a high bandwidth test. rand bit zero_delays; + // The type_name of the base RAL type (RAL_T). This is exposed explicitly, rather than being + // accessed through RAL_T::type_name, because this allows subclasses of dv_base_env_cfg to + // override the base RAL type without messing up the parameterized class type. + // + // This string will be prepended to ral_model_names at the start of the initialize function (which + // is after a derived class can have overridden it). + protected string ral_type_name = RAL_T::type_name; + // A queue of the names of RAL models that should be created in the `initialize` function. Related // agents and adapters will be created in the environment as well as connecting them with the // scoreboard. @@ -50,9 +58,14 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object; // To add another RAL model, a subclass of dv_base_env_cfg should implement initialize and add its // name before calling super.initialize. // - // The collection of RAL model names is used as an index in ral_models, clk_rst_vifs and - // clk_freqs_mhz. - string ral_model_names[$] = {RAL_T::type_name}; + // An index into the collection of RAL model names is used as an index in ral_models, clk_rst_vifs + // and clk_freqs_mhz. + typedef string string_queue_t[$]; + protected string_queue_t ral_model_names; + + function string_queue_t get_ral_model_names(); + return ral_model_names; + endfunction // A RAL model for each name in ral_model_names. dv_base_reg_block ral_models[string]; @@ -160,12 +173,17 @@ endfunction function void dv_base_env_cfg::post_randomize(); if (clk_freqs_mhz.size > 0) begin - `DV_CHECK_FATAL(clk_freqs_mhz.exists(RAL_T::type_name)) - clk_freqs_mhz[RAL_T::type_name] = clk_freq_mhz; + `DV_CHECK_FATAL(clk_freqs_mhz.exists(ral_type_name)) + clk_freqs_mhz[ral_type_name] = clk_freq_mhz; end endfunction function void dv_base_env_cfg::initialize(bit [BUS_AW-1:0] csr_base_addr = '1); + if (is_initialized) `uvm_fatal(`gfn, "Cannot call initialize when already initialized") + + // Prepend ral_type_name to ral_model_names (so the "default RAL" for the class gets index 0) + ral_model_names.push_front(ral_type_name); + is_initialized = 1'b1; // build the ral model @@ -197,7 +215,7 @@ endfunction function void dv_base_env_cfg::make_ral_models(bit [BUS_AW-1:0] csr_base_addr); foreach (ral_model_names[i]) make_ral_model(ral_model_names[i], csr_base_addr); - `DV_CHECK_FATAL(ral_models.exists(RAL_T::type_name)) + `DV_CHECK_FATAL(ral_models.exists(ral_type_name)) endfunction function void dv_base_env_cfg::make_ral_model(string ral_model_name, @@ -223,7 +241,7 @@ function void dv_base_env_cfg::make_ral_model(string ral_model_name, reg_blk.lock_model(); ral_models[ral_model_name] = reg_blk; - if (reg_blk.get_name() == RAL_T::type_name) `downcast(ral, reg_blk) + if (reg_blk.get_name() == ral_type_name) `downcast(ral, reg_blk) end // At this point, either the model existed already or we've just created and locked it. In diff --git a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_test.sv b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_test.sv index 58c0c894a..c6b7b470a 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_test.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_test.sv @@ -21,6 +21,9 @@ class dv_base_test #(type CFG_T = dv_base_env_cfg, `uvm_component_new virtual function void build_phase(uvm_phase phase); + uvm_object_wrapper cfg_type; + uvm_object base_cfg; + dv_report_server m_dv_report_server = new(); dv_report_catcher m_report_catcher; uvm_report_server::set_server(m_dv_report_server); @@ -35,8 +38,40 @@ class dv_base_test #(type CFG_T = dv_base_env_cfg, super.build_phase(phase); env = ENV_T::type_id::create("env", this); - cfg = CFG_T::type_id::create("cfg", this); - cfg.initialize(); + + // Check whether there is a type for the environment config that has been registered in + // config_db. Doing so is a way that a (templated) test can pass a specific type, allowing the + // test class not to depend on that type. + // + // If the class hasn't chosen to do so, we can just use the type for CFG_T (part of the type of + // this test) + if (!uvm_config_db#(uvm_object_wrapper)::get(this, "env", "cfg_type", cfg_type)) begin + cfg_type = CFG_T::get_type(); + end + + // Now we know the config type, see whether one has been created by the testbench, configured + // and supplied through uvm_config_db. + // + // Note that we do the lookup through CFG_T rather than cfg_type, because the latter is only + // known at runtime. If there isn't a cfg object that has been provided, we create one ourselves + // and call its initialize() method. + if (!uvm_config_db#(CFG_T)::get(this, "env", "cfg", cfg)) begin + base_cfg = cfg_type.create_object("cfg"); + if (!base_cfg) begin + `uvm_fatal(`gfn, $sformatf("Failed to create object of type %p", cfg_type)) + end + + // At this point, we will normally have just created an object of type CFG_T, but have a + // handle to it with a weaker type. But we might have got an instance of some extension class + // if one is passed as cfg_type. Either way, we should be able to cast the result to a CFG_T. + if (!$cast(cfg, base_cfg)) begin + `uvm_fatal(`gfn, + $sformatf("Failed to cast object of type %p to expected CFG_T class.", cfg_type)) + end + + cfg.initialize(); + end + `DV_CHECK_RANDOMIZE_FATAL(cfg) uvm_config_db#(CFG_T)::set(this, "env", "cfg", cfg); @@ -57,6 +92,11 @@ class dv_base_test #(type CFG_T = dv_base_env_cfg, uvm_top.enable_print_topology = print_topology; void'($value$plusargs("cdc_instrumentation_enabled=%d", cfg.en_dv_cdc)); + + // Register cfg in the config db. This might already have been registered, but that shouldn't + // matter. + uvm_config_db#(CFG_T)::set(this, "*", "cfg", cfg); + endfunction : build_phase virtual function void end_of_elaboration_phase(uvm_phase phase); diff --git a/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_driver.sv b/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_driver.sv index 54dd91065..b99fdf972 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_driver.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_driver.sv @@ -44,8 +44,8 @@ class jtag_driver extends dv_base_driver #(jtag_item, jtag_agent_cfg); reset_internal_state(); cfg.vif.tck_en <= 1'b0; - cfg.vif.tms <= 1'b0; - cfg.vif.tdi <= 1'b0; + cfg.vif._tms_internal <= 1'b0; + cfg.vif._tdi_internal <= 1'b0; endfunction // Turn on TCK in the jtag_if @@ -118,7 +118,7 @@ class jtag_driver extends dv_base_driver #(jtag_item, jtag_agent_cfg); // Send a TCK cycle with tms=0. If we were in Run-Test/Idle, this is a no-op. If we were in // Test-Logic-Reset, this steps to Run-Test/Idle. As a side-effect, this also lines us up // again with the negedge of tck. Drop out early if trst_n goes low. - cfg.vif.tms <= 1'b0; + cfg.vif._tms_internal <= 1'b0; @(posedge cfg.vif.tck); @(`HOST_CB); // Now drive the JTAG request itself. diff --git a/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_if.sv b/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_if.sv index db933707a..e452e6511 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_if.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/jtag_agent/jtag_if.sv @@ -12,24 +12,44 @@ `endif // interface pins - // TODO; make these wires and add `_oe` versions to internally control the driving of these - // signals. - logic tck; - logic trst_n; - logic tms; - logic tdi; - logic tdo; - // generate local tck + wire tck; + wire trst_n; + wire tms; + wire tdi; + wire tdo; + + // Is this interface being driven (through _drive_active and the clocking blocks), or is it just + // observing some signals from the wider simulation? + // + // The flag is defined as a wire with a weak pull-up. This ensures that a testbench that doesn't + // customise is_active will see the interface be driven actively, but allows a testbench that + // *does* want to customise the signal to pull it low. + wire is_active; + assign (weak0, weak1) is_active = 1'b1; + + // Should this interface generate a local tck signal? To enable that, set tck_en as well as + // is_active. bit tck_en; - int clk_hi_ps; - int clk_lo_ps; - int unsigned tck_period_ps = JtagDefaultTckPeriodPs; + + // Output-enable flags for tms, tdi, tdo (which only have an effect if is_active is true). The + // default configuration enables tms and tdi, so acts as the root of the JTAG tree plus the + // "previous device in the scan chain". + bit tms_oe = 1'b1; + bit tdi_oe = 1'b1; + bit tdo_oe = 1'b0; + + logic _tck_internal, _trst_n_internal, _tms_internal, _tdi_internal, _tdo_internal; + assign tck = (is_active === 1'b1) ? _tck_internal : 'z; + assign trst_n = (is_active === 1'b1) ? _trst_n_internal : 'z; + assign tms = ((is_active === 1'b1) && tms_oe) ? _tms_internal : 'z; + assign tdi = ((is_active === 1'b1) && tdi_oe) ? _tdi_internal : 'z; + assign tdo = ((is_active === 1'b1) && tdo_oe) ? _tdo_internal : 'z; // Use negedge to drive jtag inputs because design also use posedge clock edge to sample. clocking host_cb @(negedge tck); default output #1ns; - output tms; - output tdi; + output tms = _tms_internal; + output tdi = _tdi_internal; input tdo; endclocking modport host_mp(clocking host_cb, output trst_n); @@ -37,7 +57,7 @@ clocking device_cb @(posedge tck); input tms; input tdi; - // output tdo; TODO: add this back later once device mode is supported. + output tdo = _tdo_internal; endclocking modport device_mp(clocking device_cb, input trst_n); @@ -48,43 +68,94 @@ endclocking modport mon_mp (clocking mon_cb, input trst_n); - // debug signals + // Signals for local tck + int unsigned _tck_period_ps = JtagDefaultTckPeriodPs; + int unsigned _clk_hi_ps, _clk_lo_ps; + assign _clk_hi_ps = _tck_period_ps / 2; + assign _clk_lo_ps = _tck_period_ps - _clk_hi_ps; // Sets the TCK frequency. function automatic void set_tck_period_ps(int unsigned value); - tck_period_ps = value; + _tck_period_ps = value; endfunction - // task to wait for tck cycles + function automatic int unsigned get_tck_period_ps(); + return _tck_period_ps; + endfunction + + // Wait for one TCK cycle + // + // This waits for TCK to clear and then be asserted (so is waiting for the next posedge), but + // bounds the wait by _tck_period_ps (in case the clock has stopped). + // + // Waiting for !tck, then for tck ensures that we don't get any strange races when the clock is + // enabled: no matter what the relative phase, we will definitely wait at least a half cycle. + task automatic wait_one_tck(); + fork : isolation_fork begin + fork + begin + wait(!tck); + wait(tck); + end + #(_tck_period_ps * 1ps); + join_any + disable fork; + end join + endtask + + // Wait for the given number of cycles of TCK task automatic wait_tck(int cycles); - repeat (cycles) begin - if (tck_en) @(posedge tck); - else #(tck_period_ps * 1ps); - end + repeat (cycles) wait_one_tck(); endtask - // task to issue trst_n + // Start asserting a test reset through trst_n (no effect if the interface is not active) + function automatic void assert_test_reset(); + _trst_n_internal <= 1'b0; + endfunction + + // Clear any test reset asserted through trst_n (no effect if the interface is not active) + function automatic void clear_test_reset(); + _trst_n_internal <= 1'b1; + endfunction + + // Assert a test reset through trst_n (no effect if the interface is not active) task automatic do_trst_n(int cycles = $urandom_range(5, 20)); - trst_n <= 1'b0; + assert_test_reset(); wait_tck(cycles); - trst_n <= 1'b1; + clear_test_reset(); endtask - // Generate the tck, with UartDefaultClkPeriodNs period as default - assign clk_hi_ps = tck_period_ps / 2; - assign clk_lo_ps = tck_period_ps - clk_hi_ps; + // Drive _tck_internal with period _tck_period_ps whenever tck_en is high. If active is true, this + // gets used to drive the tck signal. + task automatic _drive_active(); + forever begin + wait(tck_en); + fork : isolation_fork begin + fork + wait(!tck_en); + forever begin + _tck_internal = 1'b1; + #(_clk_hi_ps * 1ps); + _tck_internal = 1'b0; + #(_clk_lo_ps * 1ps); + end + join_any + disable fork; + end join + end + endtask initial begin - tck = 1'b1; + _tck_internal = 1'b1; forever begin - if (tck_en) begin - #(clk_hi_ps * 1ps); - tck = ~tck; - #(clk_lo_ps * 1ps); - tck = ~tck; - end else begin - @(tck_en); - end + wait(is_active === 1'b1); + fork : isolation_fork begin + fork + wait(is_active !== 1'b1); + _drive_active(); + join_any + disable fork; + end join end end diff --git a/hw/vendor/lowrisc_ip/dv/sv/jtag_dmi_agent/jtag_rv_debugger.sv b/hw/vendor/lowrisc_ip/dv/sv/jtag_dmi_agent/jtag_rv_debugger.sv index 63c3c81bd..177c5b971 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/jtag_dmi_agent/jtag_rv_debugger.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/jtag_dmi_agent/jtag_rv_debugger.sv @@ -1116,11 +1116,8 @@ class jtag_rv_debugger extends uvm_object; wait(cfg.in_reset); begin // TODO: Make this timeout controllable. + cfg.vif.wait_tck(100000); - longint unsigned timeout_ps = cfg.vif.tck_period_ps; - timeout_ps = timeout_ps * 100000; - - #(timeout_ps * 1ps); req.timed_out = 1'b1; `uvm_info(`gfn, $sformatf("SBA req timed out: %0s", req.sprint(uvm_default_line_printer)), UVM_LOW) diff --git a/hw/vendor/lowrisc_ip/dv/tools/dvsim/sim.mk b/hw/vendor/lowrisc_ip/dv/tools/dvsim/sim.mk index c207e9d5a..2a93d3ba4 100644 --- a/hw/vendor/lowrisc_ip/dv/tools/dvsim/sim.mk +++ b/hw/vendor/lowrisc_ip/dv/tools/dvsim/sim.mk @@ -38,7 +38,7 @@ do_build: gen_sv_flist post_build: do_build @echo -e "\n[make]: post_build" ifneq (${post_build_cmds},) - cd ${build_dir} && ${post_build_cmds} + cd ${build_dir} && ${post_build_cmds} ${post_build_opts} endif build_result: post_build diff --git a/hw/vendor/lowrisc_ip/dv/tools/z01x/README.md b/hw/vendor/lowrisc_ip/dv/tools/z01x/README.md new file mode 100644 index 000000000..63b42baba --- /dev/null +++ b/hw/vendor/lowrisc_ip/dv/tools/z01x/README.md @@ -0,0 +1,21 @@ +# Synopsys VC Z01X Fault Injection Simulation + +This tool, which is integrated into OpenTitan, enables users to conduct a pre-silicon fault injection analysis. +During simulation, Z01X injects faults based on user contraints, and compares the golden vs. the faulty model. + +## Usage + +Z01X proprietary configuration files are available in the [opentitan_fi_z01x](https://github.com/lowRISC/opentitan_fi_z01x) repository. +Please contact [info@lowrisc.org](mailto:info@lowrisc.org?subject=VC-ZOIX%20access) with the email subject: "VC-ZOIX access" to request access to this repository. + +Once you have access, follow these steps: +```bash +$ git clone git@github.com:lowRISC/opentitan_fi_z01x.git +$ git clone git@github.com:lowRISC/opentitan.git +$ export Z01X_DIR= +$ export OT_DIR= +$ cd opentitan/ +$ ./util/prepare_dvsim_z01x.sh +$ ./util/dvsim/dvsim.py hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson \ + -i flash_ctrl_basic_rw -t z01x --reseed-multiplier 0.0001 --fixed-seed 1 +``` diff --git a/hw/vendor/lowrisc_ip/ip/i2c/data/i2c.hjson b/hw/vendor/lowrisc_ip/ip/i2c/data/i2c.hjson index 09309827c..0338d7b7c 100644 --- a/hw/vendor/lowrisc_ip/ip/i2c/data/i2c.hjson +++ b/hw/vendor/lowrisc_ip/ip/i2c/data/i2c.hjson @@ -9,8 +9,8 @@ one_paragraph_desc: ''' I2C Interface implements the I2C serial communication protocol. It can be configured in host (master) or device (slave) mode and supports standard data rate (100 kbaud), fast data rate (400 kbaud), and fast plus data rate (1 Mbaud). - In addition to supporting all mandatory I2C features, this block supports clock stretching in host mode and automatic clock stretching in device mode. - I2C Interface uses a 7-bit address space and is compatible with any device covered by I2C specification operating at speeds up to 1 Mbaud. + In addition to supporting all mandatory I2C features, this block supports clock stretching in host mode and automatic clock stretching in device mode. + I2C Interface uses a 7-bit address space and is compatible with any device covered by I2C specification operating at speeds up to 1 Mbaud. ''' // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. cip_id: "11", @@ -283,7 +283,7 @@ resval: "0" name: "LLPBK" desc: ''' - Enable I2C line loopback test + Enable I2C line loopback test. If line loopback is enabled, the internal design sees ACQ and RX data as "1" ''' tags: [// Exclude from write-checks: writing 1'b1 to this bit causes interrupts unexpectedly asserted @@ -635,7 +635,7 @@ { name: "TIMING0" desc: ''' - Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). + Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. These must be greater than 2 in order for the change in SCL to propagate to the input of the FSM so that acknowledgements are detected correctly. ''' @@ -660,7 +660,7 @@ } { name: "TIMING1", desc: ''' - Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). + Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. ''' swaccess: "rw" @@ -684,7 +684,7 @@ } { name: "TIMING2" desc: ''' - Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). + Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. ''' swaccess: "rw" @@ -708,7 +708,7 @@ } { name: "TIMING3" desc: ''' - Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). + Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. ''' swaccess: "rw" @@ -735,7 +735,7 @@ } { name: "TIMING4" desc: ''' - Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). + Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. ''' swaccess: "rw" @@ -872,7 +872,7 @@ name: "START", desc: ''' A START condition preceded the ABYTE to start a new transaction. - ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. + ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. ''' }, { value: "2", @@ -887,7 +887,7 @@ name: "RESTART", desc: ''' A repeated START condition preceded the ABYTE, extending the current transaction with a new transfer. - ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. + ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. ''' }, { value: "4", @@ -898,7 +898,7 @@ name: "NACK_START", desc: ''' A START condition preceded the ABYTE (including repeated START) that was part of a NACK'd transfer. - The ABYTE contains the matching I2C address and command bit. + The ABYTE contains the matching I2C address and command bit. The ABYTE was ACK'd, but the rest of the transaction was NACK'ed. ''' }, diff --git a/hw/vendor/lowrisc_ip/ip/i2c/doc/programmers_guide.md b/hw/vendor/lowrisc_ip/ip/i2c/doc/programmers_guide.md index a27230caf..da80bfb7f 100644 --- a/hw/vendor/lowrisc_ip/ip/i2c/doc/programmers_guide.md +++ b/hw/vendor/lowrisc_ip/ip/i2c/doc/programmers_guide.md @@ -18,16 +18,16 @@ The values of these parameters will depend primarily on three bus details: - The expected signal rise time, tr, in ns. - This is not a firmware-controlled parameter. Rather, it is a function of the capacitance and physical design of the bus. - The specification provides detailed guidelines on how to manage capacitance in an I2C system: - - Section 5.2 of the I2C specification indicates that Fast-mode Plus devices may operate at reduced clock speeds if the bus capacitance drives signal rise times (tr) outside the nominal 120ns limit. - Excess capacitance can also be compensated for by reducing the size of the bus pullup resistor, so long as the total open-drain current does not exceed 20mA for Fast-mode Plus devices (as described in section 7.1 of the I2C specification). + The specification provides detailed guidelines on how to manage capacitance in an I2C system: + - Section 5.2 of the I2C specification indicates that Fast-mode Plus devices may operate at reduced clock speeds if the bus capacitance drives signal rise times (tr) outside the nominal 120ns limit. + Excess capacitance can also be compensated for by reducing the size of the bus pullup resistor, so long as the total open-drain current does not exceed 20mA for Fast-mode Plus devices (as described in section 7.1 of the I2C specification). However the specification places a hard limit on rise times capping them at 1000ns. - If there are Standard- or Fast-mode target devices on the bus, the specified open-drain current limit is reduced to 3mA (section 7.1), thus further restricting the minimum value of the pull-up resistor. - In Fast-mode bus designs, where the total line capacitance exceeds 200pF, the specification recommends replacing the pull-up resistor with an active current source, supplying 3mA or less (section 5.1). Regardless of the physical construction of the bus, the rise time (tr) is a system dependent, parameter that needs to be made known to firmware for I2C initialization. - The expected fall time, tf, in ns. - Like tr, this parameter is not firmware controlled rather it is a function of the SCL driver, which in a strictly compliant device is expected to manage the slew-rate for the falling edge of the SDA and SCL signals, through proper design of the SCL output buffer. - - See table 10 of the I2C specification for more details. + - See table 10 (rev. 6) of the I2C specification for more details. - (optional) The desired SCL cycle period, tSCL,user in ns. - By default the device should operate at the maximum frequency for that mode. However, If the system developer wishes to operate at slower than the mode-specific maximum, a larger than minimum period could be allowed as an additional functional parameter when calculating the timing parameters. @@ -116,11 +116,11 @@ All other parameters in registers `TIMING2`, `TIMING3`, `TIMING4` are unchanged ### Writing `n` bytes to a device: 1. Address the device for writing by writing to: - `FDATA.START` = 1; - - `FDATA.FBYTE` = <7-bit address + write bit>. + - `FDATA.FBYTE` = < 7-bit address + write bit >. 2. Fill the FMT FIFO by writing to `FDATA.FBYTE` `n`-1 times. 3. Send last byte with the stop bit by writing to: - `FDATA.STOP` = 1; - - `FDATA.FBYTE` = . + - `FDATA.FBYTE` = < last byte >. 4. Wait for and check the result of the transaction. - If `INTR_STATE.CONTROLLER_HALT` is 1, the transaction failed. - Check `CONTROLLER_EVENTS` for the reason, reset the FMT FIFO with `FIFO_CTRL.FMTRST`, and clear the latched events. @@ -129,11 +129,11 @@ All other parameters in registers `TIMING2`, `TIMING3`, `TIMING4` are unchanged ### Reading `n` bytes from a device: 1. Address the device for reading by writing to the FMT FIFO: - `FDATA.START` = 1; - - `FDATA.FBYTE` = <7-bit address + read bit>. + - `FDATA.FBYTE` = < 7-bit address + read bit >. 2. Issue a read transfer by writing to the FMT FIFO. - - `FDATA.READ` = 1; + - `FDATA.READB` = 1; - `FDATA.STOP` = 1; - - `FDATA.FBYTE` = <`n`>. + - `FDATA.FBYTE` = < `n` >. 3. Wait for the transfer to finish or interrupt by checking: - If `STATUS.FMTEMPTY` bit is 1. - **Or** if `INTR_STATE.FMT_THRESHOLD` bit is 1 ( as long as `FIFO_CTRL.FMTILVL` is set to 1). diff --git a/hw/vendor/lowrisc_ip/ip/i2c/doc/registers.md b/hw/vendor/lowrisc_ip/ip/i2c/doc/registers.md index ff15f51d5..b5c670959 100644 --- a/hw/vendor/lowrisc_ip/ip/i2c/doc/registers.md +++ b/hw/vendor/lowrisc_ip/ip/i2c/doc/registers.md @@ -20,11 +20,11 @@ | i2c.[`TARGET_FIFO_STATUS`](#target_fifo_status) | 0x30 | 4 | Target mode FIFO status register | | i2c.[`OVRD`](#ovrd) | 0x34 | 4 | I2C Override Control Register | | i2c.[`VAL`](#val) | 0x38 | 4 | Oversampled RX values | -| i2c.[`TIMING0`](#timing0) | 0x3c | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). | -| i2c.[`TIMING1`](#timing1) | 0x40 | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). | -| i2c.[`TIMING2`](#timing2) | 0x44 | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). | -| i2c.[`TIMING3`](#timing3) | 0x48 | 4 | Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). | -| i2c.[`TIMING4`](#timing4) | 0x4c | 4 | Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). | +| i2c.[`TIMING0`](#timing0) | 0x3c | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). | +| i2c.[`TIMING1`](#timing1) | 0x40 | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). | +| i2c.[`TIMING2`](#timing2) | 0x44 | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). | +| i2c.[`TIMING3`](#timing3) | 0x48 | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). | +| i2c.[`TIMING4`](#timing4) | 0x4c | 4 | Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). | | i2c.[`TIMEOUT_CTRL`](#timeout_ctrl) | 0x50 | 4 | I2C clock stretching and bus timeout control. | | i2c.[`TARGET_ID`](#target_id) | 0x54 | 4 | I2C target address and mask pairs | | i2c.[`ACQDATA`](#acqdata) | 0x58 | 4 | I2C target acquired data | @@ -216,7 +216,7 @@ For writes, the Target module will NACK all subsequent data bytes until it recei For reads, the Target module will release SDA, causing 0xff to be returned for all data bytes until it receives a Stop. ### CTRL . LLPBK -Enable I2C line loopback test +Enable I2C line loopback test. If line loopback is enabled, the internal design sees ACQ and RX data as "1" ### CTRL . ENABLETARGET @@ -459,7 +459,7 @@ Oversampled RX values | 15:0 | ro | x | SCL_RX | Last 16 oversampled values of SCL. Most recent bit is bit 0, oldest 15. | ## TIMING0 -Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). +Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. These must be greater than 2 in order for the change in SCL to propagate to the input of the FSM so that acknowledgements are detected correctly. - Offset: `0x3c` @@ -480,7 +480,7 @@ These must be greater than 2 in order for the change in SCL to propagate to the | 12:0 | rw | 0x0 | THIGH | The actual time to hold SCL high in a given pulse. This field is sized to have a range of at least Standard Mode's 4.0 us max with a core clock at 1 GHz. | ## TIMING1 -Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). +Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. - Offset: `0x40` - Reset default: `0x0` @@ -500,7 +500,7 @@ All values are expressed in units of the input clock period. | 9:0 | rw | 0x0 | T_R | The nominal rise time to anticipate for the bus (depends on capacitance). This field is sized to have a range of at least Standard Mode's 1000 ns max with a core clock at 1 GHz. | ## TIMING2 -Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification). +Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. - Offset: `0x44` - Reset default: `0x0` @@ -520,7 +520,7 @@ All values are expressed in units of the input clock period. | 12:0 | rw | 0x0 | TSU_STA | Actual setup time for repeated start signals. This field is sized to have a range of at least Standard Mode's 4.7 us max with a core clock at 1 GHz. | ## TIMING3 -Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). +Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. - Offset: `0x48` - Reset default: `0x0` @@ -551,7 +551,7 @@ Actual setup time for data (or ack) bits. This field is sized to have a range of at least Standard Mode's 250 ns max with a core clock at 1 GHz. ## TIMING4 -Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification). +Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification (rev. 6)). All values are expressed in units of the input clock period. - Offset: `0x4c` - Reset default: `0x0` @@ -668,11 +668,11 @@ See the associated values for more information about the contents. | Value | Name | Description | |:--------|:-----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 0x0 | NONE | ABYTE contains an ordinary data byte that was received and ACK'd. | -| 0x1 | START | A START condition preceded the ABYTE to start a new transaction. ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. | +| 0x1 | START | A START condition preceded the ABYTE to start a new transaction. ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. | | 0x2 | STOP | A STOP condition was received for a transaction including a transfer that addressed this Target. No transfers addressing this Target in that transaction were NACK'd. ABYTE contains no data. | -| 0x3 | RESTART | A repeated START condition preceded the ABYTE, extending the current transaction with a new transfer. ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. | +| 0x3 | RESTART | A repeated START condition preceded the ABYTE, extending the current transaction with a new transfer. ABYTE contains the 7-bit I2C address plus R/W command bit in the order received on the bus, MSB first. | | 0x4 | NACK | ABYTE contains an ordinary data byte that was received and NACK'd. | -| 0x5 | NACK_START | A START condition preceded the ABYTE (including repeated START) that was part of a NACK'd transfer. The ABYTE contains the matching I2C address and command bit. The ABYTE was ACK'd, but the rest of the transaction was NACK'ed. | +| 0x5 | NACK_START | A START condition preceded the ABYTE (including repeated START) that was part of a NACK'd transfer. The ABYTE contains the matching I2C address and command bit. The ABYTE was ACK'd, but the rest of the transaction was NACK'ed. | | 0x6 | NACK_STOP | A transaction including a transfer that addressed this Target was ended, but the transaction ended abnormally and/or the transfer was NACK'd. The end can be due to a STOP condition or unexpected events, such as a bus timeout (if enabled). ABYTE contains no data. NACKing can occur for multiple reasons, including a stretch timeout, a SW-directed NACK, or lost arbitration. This signal is a bucket for all these error-type terminations. | Other values are reserved. diff --git a/hw/vendor/lowrisc_ip/ip/i2c/doc/theory_of_operation.md b/hw/vendor/lowrisc_ip/ip/i2c/doc/theory_of_operation.md index 01bc1a321..ab97581e1 100644 --- a/hw/vendor/lowrisc_ip/ip/i2c/doc/theory_of_operation.md +++ b/hw/vendor/lowrisc_ip/ip/i2c/doc/theory_of_operation.md @@ -6,13 +6,13 @@ ## Functional Description -I2C IP is a controller-target combo that can function as an I2C controller and/or an I2C target. +The I2C IP is a controller-target combo that can function as an I2C controller and/or an I2C target. These functional modules are enabled at runtime by setting the register fields [`CTRL.ENABLEHOST`](registers.md#ctrl) and [`CTRL.ENABLETARGET`](registers.md#ctrl). If the Controller Module is to be used in a multi-controller environment, [`CTRL.MULTI_CONTROLLER_MONITOR_EN`](registers.md#ctrl) would also need to be set. Note the ordering requirements in the register description for multi-controller configurations. The SCL and SDA outputs from the block combine the SCL and SDA outputs from the Controller Module and Target Module. -The modules operate as though they were independent devices on the same I2C bus, with any logic low value taking priority. +The modules operate as though they were independent devices on the same I2C bus, with any logic low value taking priority. On the input path, the IP's clock samples SCL and SDA after a 2-flop synchronizer. However, the IP's input pins do not reflect the start point for the full input path delay, since pads and nets from I/O buffers also contribute. @@ -39,7 +39,7 @@ To make this happen, [`HOST_TIMEOUT_CTRL`](registers.md#host_timeout_ctrl) shoul ### Controller Module -The Controller Module implements all mandatory controller features of the I2C protocol for multi-controller configurations, including clock synchronization and bus arbitration. +The Controller Module implements all mandatory controller features of the I2C protocol for multi-controller configurations, including clock synchronization and bus arbitration. It also implements support for handling clock stretching. The state-machine-controlled Controller Module allows for higher-speed operation with less frequent software interaction. @@ -75,7 +75,7 @@ Issue a STOP signal after processing this current entry in the FMT FIFO. Note that this flag is not compatible with (READB & RCONT), and will cause bus conflicts. - NAKOK (corresponds to [`FDATA.NAKOK`](registers.md#fdata), Not compatible with READB): Typically every byte transmitted must also receive an ACK signal, and the IP will raise an exception if no ACK is received. -However, there are some I2C commands which do not require an ACK. +However, there are some I2C commands which do not require an ACK. In those cases this flag should be asserted with FBYTE indicating no ACK is expected and no interrupt should be raised if the ACK is not received. The Controller Module may proceed through all commands in the FMT FIFO as long as no exceptional event occurs. @@ -123,7 +123,7 @@ All bits in [`CONTROLLER_EVENTS`](registers.md#controller_events) must be cleare ### Target Module -The Target Module implements all mandatory features for targets in multi-controller configurations, as enumerated in the I2C specification. +The Target Module implements all mandatory features for targets in multi-controller configurations, as enumerated in the I2C specification. It also supports clock stretching from that same specification. In addition, the Target Module has the necessary mechanisms to support mandatory SMBus 3.0 features, as well as dynamically-assigned addresses using the SMBus Address Resolution Protocol. @@ -183,7 +183,7 @@ The following diagram shows consecutive entries inserted into ACQ FIFO during a ![](../doc/i2c_acq_fifo_read.svg) #### Target Clock Stretching -As described in the I2C specification, a target device can pause a transaction by holding SCL low. +As described in the I2C specification, a target device can pause a transaction by holding SCL low. There are 3 cases in which this design stretches the clock: - After the target receives the address but before pushing it to the ACQ FIFO - Before the (N)ACK bit completes transmission during a write transfer @@ -262,10 +262,10 @@ This feature is intended to support protocols that require mid-transfer NACK dec ### Timing Control Registers -For Standard-mode, Fast-mode and Fast-mode Plus, the timing requirements for each transaction are detailed in Table 10 of the [I2C specification (rev. 6)](https://web.archive.org/web/20210813122132/https://www.nxp.com/docs/en/user-guide/UM10204.pdf). +For Standard-mode, Fast-mode and Fast-mode Plus, the timing requirements for each transaction are detailed in Table 10 of the [I2C specification (rev. 6)](https://web.archive.org/web/20210813122132/https://www.nxp.com/docs/en/user-guide/UM10204.pdf). To claim complete compatibility at each mode, the state machine timings need to be adapted to whether there are Standard-mode, Fast-mode and Fast-mode Plus targets on the bus. Furthermore, depending on the actual capacitance of the bus, even a bus with all Fast-mode Plus capable targets may have to operate at slower speeds than 1 Mbaud. -For example, the controller may need to run at lower frequencies, as discussed in Section 5.2 of the specification, but the computation of the nominal frequency will depend on timing specifications in Table 10, in this case particularly, the limits on tLOW, tHIGH, tr, and tf. +For example, the controller may need to run at lower frequencies, as discussed in Section 5.2 of the specification, but the computation of the nominal frequency will depend on timing specifications in Table 10 (rev. 6), in this case particularly, the limits on tLOW, tHIGH, tr, and tf. Assuming no clock stretching, for a given set of these four parameters the baud rate is then given to be: $$ 1/f\_{SCL}=t\_{LOW}+t\_{HIGH}+t\_{r}+t\_{f}. $$ @@ -278,7 +278,7 @@ Thus this parameter is largely budgetary, meaning that it tells the state machin - tf: set in register [`TIMING1.T_F`](registers.md#timing1). (Note: The fall time cannot be explicitly controlled by internal hardware, and is a function of the pin driver. Thus this parameter is also budgetary. -Given that the actual fall time cannot be controlled to stay above the minimum values set in Table 10 of the specification, and so this in this regard this module currently is not strictly compliant to the I2C spec. +Given that the actual fall time cannot be controlled to stay above the minimum values set in Table 10 of the specification (rev. 6), and so this in this regard this module currently is not strictly compliant to the I2C spec. The system design is responsible for meeting the spec's minimum fall time. ) - tSU,STA: set in register [`TIMING2.TSU_STA`](registers.md#timing2) @@ -295,7 +295,7 @@ In addition, when the IP operates as a target, the parameter specifies the requi The values programmed into the registers [`TIMING0`](registers.md#timing0) through [`TIMING4`](registers.md#timing4) are to be expressed in units of the input clock period. It is important that the internal clock is at least 50x the bus clock so that the proportions of the timings can be accurately captured. -Note in order to ensure compliance with the I2C spec, firmware must program these registers with values within the ranges laid out in Table 10 of the specification. +Note in order to ensure compliance with the I2C spec, firmware must program these registers with values within the ranges laid out in Table 10 of the specification (rev. 6). These values can be directly computed using DIFs given the desired speed standard, the desired operating frequency, and the actual line capacitance. These timing parameters are then fed directly to the I2C state machine to control the bus timing. @@ -413,7 +413,7 @@ This interrupt is suppressed, however, if [`TIMEOUT_CTRL.EN`](registers.md#timeo head: {text: 'SCL Timeout Example',tick:-3}} ``` -Except for START and STOP symbols, the I2C specification requires that the SDA signal remains constant whenever SCL is high. +Except for START and STOP symbols, the I2C specification requires that the SDA signal remains constant whenever SCL is high. The `sda_unstable` interrupt is asserted if, when receiving data or acknowledgement pulse, the value of the SDA signal does not remain constant over the duration of the SCL pulse, causing an unexpected START or STOP symbol. Transactions are terminated by a STOP signal, but individual transfers within a transaction can be completed by a STOP signal *or* a repeated START signal. @@ -569,7 +569,7 @@ For full spec compliance, the glitch filter must be added to the system design. ### Override Mode for Direct Pin Access -The I2C hardware interface consists of two external pins, SCL and SDA, whose behavior is described in the [I2C specification (rev. 6)](https://web.archive.org/web/20210813122132/https://www.nxp.com/docs/en/user-guide/UM10204.pdf). +The I2C hardware interface consists of two external pins, SCL and SDA, whose behavior is described in the [I2C specification (rev. 6)](https://web.archive.org/web/20210813122132/https://www.nxp.com/docs/en/user-guide/UM10204.pdf). These pins are typically controlled by an internal state machine. However, there is a simpler "override" mode, by which these pins can be directly manipulated by software. This override mode is useful for both troubleshooting and error recovery. @@ -586,9 +586,9 @@ Since SCL is directly decoded from the states, it can have short glitches during To counter this, the SCL and SDA outputs from the internal state machine are flopped before they are emitted. This adds a one cycle module clock delay to both signals. -If the module clock is sufficiently faster than I2C line speeds (for example 24MHz), this is not an issue. +If the module clock is sufficiently faster than I2C line speeds (for example 24MHz), this is not an issue. However if the line speeds and the module clock speeds become very close (2x), the 1 cycle delay may have an impact, as the internal state machine may mistakenly think it has sampled an SDA that has not yet been updated. Therefore, it is recommended that the internal module clock frequency is much higher than the line speeds. -Another reason to have this higher internal clock frequency is that the timing parameters can be more accurately defined, which helps attain the desired I2C clock rate. -Since there are currently also a few cycles discrepancy between the specified timings and the actual ones (as described in the [Programmer's Guide](./programmers_guide.md#timing-parameter-tuning-algorithm)), it is recommended that the internal module clock frequency is at least 24x higher than the I2C line speeds. +Another reason to have this higher internal clock frequency is that the timing parameters can be more accurately defined, which helps attain the desired I2C clock rate. +Since there are currently also a few cycles discrepancy between the specified timings and the actual ones (as described in the [Programmer's Guide](./programmers_guide.md#timing-parameter-tuning-algorithm)), it is recommended that the internal module clock frequency is at least 24x higher than the I2C line speeds. diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl.hjson b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl.hjson index 0e977f2fc..aceaa957b 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl.hjson +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl.hjson @@ -4,9 +4,9 @@ { name: "lc_ctrl", human_name: "Life Cycle Controller", - one_line_desc: "Manages device life cycle states and transitions, and controls key manager, flash, OTP, and debug access", + one_line_desc: "Manages device life cycle states and transitions, and controls key manager, NVM (flash), OTP, and debug access", one_paragraph_desc: ''' - Life Cycle Controller is responsible for handling and guarding transitions between different device life cycle states, concurrently decoding the current life cycle state and redundantly broadcasting encoded life cycle qualification signals across the system, e.g., to control the behavior of Key Manager, Flash Controller, OTP Controller, and debug infrastructure. + Life Cycle Controller is responsible for handling and guarding transitions between different device life cycle states, concurrently decoding the current life cycle state and redundantly broadcasting encoded life cycle qualification signals across the system, e.g., to control the behavior of the Key Manager, the non-volatile memory controller (e.g. Flash Controller), the OTP Controller, and the debug infrastructure. In addition, it features an escalation receiver for the alert system to invalidate the life cycle state as part of an escalation sequence. ''' // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. @@ -212,7 +212,7 @@ local: "true" } { name: "NumRmaAckSigs", - desc: "Number of Flash RMA wiping response signals", + desc: "Number of NVM RMA wiping response signals", type: "int", default: "2", local: "true", @@ -406,7 +406,7 @@ } { struct: "lc_tx" type: "uni" - name: "lc_flash_rma_req" + name: "lc_nvm_rma_req" act: "req" default: "lc_ctrl_pkg::Off" package: "lc_ctrl_pkg" @@ -418,16 +418,16 @@ # For security reasons, this signal is not daisy-chained - see #19136 for # context. This needs to be aligned with the NumRmaAckSigs parameter. width: "2" - name: "lc_flash_rma_ack" + name: "lc_nvm_rma_ack" act: "rcv" # Default to ON so that this still works even if not all channels are # connected. default: "lc_ctrl_pkg::On" package: "lc_ctrl_pkg" } - { struct: "lc_flash_rma_seed" + { struct: "lc_nvm_rma_seed" type: "uni" - name: "lc_flash_rma_seed" + name: "lc_nvm_rma_seed" act: "req" default: "'0" package: "lc_ctrl_pkg" @@ -800,9 +800,9 @@ ''' } { bits: "7" - name: "FLASH_RMA_ERROR" + name: "NVM_RMA_ERROR" desc: ''' - This bit is set to 1 if flash failed to correctly respond to an RMA request. + This bit is set to 1 if NVM failed to correctly respond to an RMA request. Note that each transition attempt increments the !!LC_TRANSITION_CNT and moves the life cycle state into POST_TRANSITION. ''' diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson index c021b5e63..1fedc5f27 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson @@ -178,16 +178,16 @@ `lc_clk_byp_ack_i` to any value other than 'ON' after the main FSM has progressed through the `ClkMuxSt` state should trigger this error. - 2) `lc_flash_rma_ack_i`: Verify that an inconsistent input value - (`lc_flash_rma_ack_i` != `lc_flash_rma_ack_o`) causes a FLASH_RMA_ERROR + 2) `lc_nvm_rma_ack_i`: Verify that an inconsistent input value + (`lc_nvm_rma_ack_i` != `lc_nvm_rma_ack_o`) causes a NVM_RMA_ERROR when a life cycle transition is initiated. There are two ways this condition can be triggered: either no RMA - transition is requested, and then setting `lc_flash_rma_ack_i` to any + transition is requested, and then setting `lc_nvm_rma_ack_i` to any value other than 'OFF' when initiating the life cycle transition should trigger this error. If an RMA transition is requested, setting - `lc_flash_rma_ack_i` to any value other than 'ON' after the main FSM - has progressed through the `FlashRmaSt` state should trigger this + `lc_nvm_rma_ack_i` to any value other than 'ON' after the main FSM + has progressed through the `NvmRmaSt` state should trigger this error. The main life cycle FSM should not progress through the `TransProgSt` if diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_testplan.hjson b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_testplan.hjson index d3ff445ea..b647ee41c 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_testplan.hjson +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/data/lc_ctrl_testplan.hjson @@ -108,7 +108,7 @@ - otp_ctrl input lc_trans_cnt reaches 16 - lc_ctrl state transition request is invalid - input LC token does not match the output from otp_ctrl - - flash rma responses to lc_ctrl request with error + - nvm rma responses to lc_ctrl request with error - lc_ctrl clock bypass responses with error - input otp_lc_data's error bit is set to 1 Note that all the above scenarios except the last one requires a reset to recover. diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/interfaces.md b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/interfaces.md index 4f178ae9e..9500a1645 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/interfaces.md +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/interfaces.md @@ -27,46 +27,46 @@ Referring to the [Comportable guideline for peripheral device functionality](htt ## [Inter-Module Signals](https://opentitan.org/book/doc/contributing/hw/comportability/index.html#inter-signal-handling) -| Port Name | Package::Struct | Type | Act | Width | Description | -|:-------------------------|:-------------------------------|:--------|:------|--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| jtag | jtag_pkg::jtag | req_rsp | rsp | 1 | | -| esc_scrap_state0_tx | prim_esc_pkg::esc_tx | uni | rcv | 1 | | -| esc_scrap_state0_rx | prim_esc_pkg::esc_rx | uni | req | 1 | | -| esc_scrap_state1_tx | prim_esc_pkg::esc_tx | uni | rcv | 1 | | -| esc_scrap_state1_rx | prim_esc_pkg::esc_rx | uni | req | 1 | | -| pwr_lc | lc_ctrl_pkg::pwr_lc | req_rsp | rsp | 1 | | -| lc_otp_vendor_test | otp_macro_pkg::otp_test | req_rsp | req | 1 | | -| otp_lc_data | otp_ctrl_pkg::otp_lc_data | uni | rcv | 1 | | -| lc_otp_program | otp_ctrl_pkg::lc_otp_program | req_rsp | req | 1 | | -| kmac_data | kmac_pkg::app | req_rsp | req | 1 | | -| lc_init_done | lc_ctrl_pkg::lc_tx | uni | req | 1 | A signal that is On after lifecycle initialization is done. This signal is On when lifecycle initialization is complete and life cycle controller broadcast signals are valid. | -| lc_raw_test_rma | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_nvm_debug_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_hw_debug_clr | lc_ctrl_pkg::lc_tx | uni | req | 1 | Clear HW debug functionality. This signal is On when `lc_hw_debug_en` turns Off outside a reset of `lc_ctrl`. Flops storing the value of `lc_hw_debug_en` (see below) must be cleared when this signal is On. | -| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | Enable HW debug functionality; see `HW_DEBUG_EN` in the Theory of Operation doc for details. This signal is Off while lc_ctrl is in reset. In order to prevent a JTAG disconnect during non-debug-module (NDM) reset, this signal should be flopped outside the NDM reset domain. Such a flop must be cleared when `lc_hw_debug_clr` is On; see above. | -| lc_cpu_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_keymgr_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_clk_byp_req | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_clk_byp_ack | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | -| lc_flash_rma_req | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_flash_rma_ack | lc_ctrl_pkg::lc_tx | uni | rcv | 2 | | -| lc_flash_rma_seed | lc_ctrl_pkg::lc_flash_rma_seed | uni | req | 1 | | -| lc_check_byp_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_creator_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_owner_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_iso_part_sw_rd_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_iso_part_sw_wr_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_seed_hw_rd_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_rma_state | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_keymgr_div | lc_ctrl_pkg::lc_keymgr_div | uni | req | 1 | | -| otp_device_id | otp_ctrl_pkg::otp_device_id | uni | rcv | 1 | | -| otp_manuf_state | otp_ctrl_pkg::otp_manuf_state | uni | rcv | 1 | | -| hw_rev | lc_ctrl_pkg::lc_hw_rev | uni | req | 1 | | -| strap_en_override | logic | uni | req | 1 | This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. The signal stays at 1 until reset. Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. Otherwise this signal is tied off to 0. | -| regs_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | -| dmi_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | +| Port Name | Package::Struct | Type | Act | Width | Description | +|:-------------------------|:------------------------------|:--------|:------|--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| jtag | jtag_pkg::jtag | req_rsp | rsp | 1 | | +| esc_scrap_state0_tx | prim_esc_pkg::esc_tx | uni | rcv | 1 | | +| esc_scrap_state0_rx | prim_esc_pkg::esc_rx | uni | req | 1 | | +| esc_scrap_state1_tx | prim_esc_pkg::esc_tx | uni | rcv | 1 | | +| esc_scrap_state1_rx | prim_esc_pkg::esc_rx | uni | req | 1 | | +| pwr_lc | lc_ctrl_pkg::pwr_lc | req_rsp | rsp | 1 | | +| lc_otp_vendor_test | otp_macro_pkg::otp_test | req_rsp | req | 1 | | +| otp_lc_data | otp_ctrl_pkg::otp_lc_data | uni | rcv | 1 | | +| lc_otp_program | otp_ctrl_pkg::lc_otp_program | req_rsp | req | 1 | | +| kmac_data | kmac_pkg::app | req_rsp | req | 1 | | +| lc_init_done | lc_ctrl_pkg::lc_tx | uni | req | 1 | A signal that is On after lifecycle initialization is done. This signal is On when lifecycle initialization is complete and life cycle controller broadcast signals are valid. | +| lc_raw_test_rma | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_nvm_debug_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_hw_debug_clr | lc_ctrl_pkg::lc_tx | uni | req | 1 | Clear HW debug functionality. This signal is On when `lc_hw_debug_en` turns Off outside a reset of `lc_ctrl`. Flops storing the value of `lc_hw_debug_en` (see below) must be cleared when this signal is On. | +| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | Enable HW debug functionality; see `HW_DEBUG_EN` in the Theory of Operation doc for details. This signal is Off while lc_ctrl is in reset. In order to prevent a JTAG disconnect during non-debug-module (NDM) reset, this signal should be flopped outside the NDM reset domain. Such a flop must be cleared when `lc_hw_debug_clr` is On; see above. | +| lc_cpu_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_keymgr_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_clk_byp_req | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_clk_byp_ack | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_nvm_rma_req | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_nvm_rma_ack | lc_ctrl_pkg::lc_tx | uni | rcv | 2 | | +| lc_nvm_rma_seed | lc_ctrl_pkg::lc_nvm_rma_seed | uni | req | 1 | | +| lc_check_byp_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_creator_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_owner_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_iso_part_sw_rd_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_iso_part_sw_wr_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_seed_hw_rd_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_rma_state | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| lc_keymgr_div | lc_ctrl_pkg::lc_keymgr_div | uni | req | 1 | | +| otp_device_id | otp_ctrl_pkg::otp_device_id | uni | rcv | 1 | | +| otp_manuf_state | otp_ctrl_pkg::otp_manuf_state | uni | rcv | 1 | | +| hw_rev | lc_ctrl_pkg::lc_hw_rev | uni | req | 1 | | +| strap_en_override | logic | uni | req | 1 | This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. The signal stays at 1 until reset. Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. Otherwise this signal is tied off to 0. | +| regs_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | +| dmi_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | ## Security Alerts @@ -117,7 +117,7 @@ Signal | Direction | Type `kmac_data_i` | `input` | `kmac_pkg::app_rsp_t` | Life cycle RAW token hashing response. `otp_lc_data_i` | `input` | `otp_ctrl_pkg::otp_lc_data_t` | Life cycle state output holding the current life cycle state, the value of the transition counter and the tokens needed for life cycle transitions. `lc_keymgr_div_o` | `output` | `lc_keymgr_div_t` | Life cycle state group diversification value. -`lc_flash_rma_seed_o` | `output` | `lc_flash_rma_seed_t` | Seed for flash RMA. +`lc_nvm_rma_seed_o` | `output` | `lc_nvm_rma_seed_t` | Seed for NVM RMA. `otp_device_id_i` | `input` | `otp_device_id_t` | HW_CFG0 bits from OTP ([`DEVICE_ID_0`](registers.md#device_id)). `otp_manuf_state_i` | `input` | `otp_manuf_state_t` | HW_CFG0 bits from OTP ([`MANUF_STATE_0`](registers.md#manuf_state)). `lc_otp_vendor_test_o` | `output` | `otp_ctrl_pkg::lc_otp_vendor_test_req_t` | Vendor-specific test bits to OTP ([`OTP_VENDOR_TEST_CTRL`](registers.md#otp_vendor_test_ctrl)). @@ -137,8 +137,8 @@ Signal | Direction | Type `lc_check_byp_en_o` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). `lc_clk_byp_req_o` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). `lc_clk_byp_ack_i` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). -`lc_flash_rma_req_o` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). -`lc_flash_rma_ack_i` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). +`lc_nvm_rma_req_o` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). +`lc_nvm_rma_ack_i` | `output` | `lc_tx_t` | [Multibit control signal](theory_of_operation.md#life-cycle-decoded-outputs-and-controls). #### Power Manager Interface diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/registers.md b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/registers.md index 3bd7cb8d3..528a670f4 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/registers.md +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/registers.md @@ -69,7 +69,7 @@ life cycle status register. Note that all errors are terminal and require a rese ### Fields ```wavejson -{"reg": [{"name": "INITIALIZED", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "READY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "EXT_CLOCK_SWITCHED", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_SUCCESSFUL", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_COUNT_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TOKEN_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FLASH_RMA_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "OTP_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "STATE_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "BUS_INTEG_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "OTP_PARTITION_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 240}} +{"reg": [{"name": "INITIALIZED", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "READY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "EXT_CLOCK_SWITCHED", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_SUCCESSFUL", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_COUNT_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TRANSITION_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TOKEN_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "NVM_RMA_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "OTP_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "STATE_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "BUS_INTEG_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "OTP_PARTITION_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 240}} ``` | Bits | Type | Reset | Name | @@ -79,7 +79,7 @@ life cycle status register. Note that all errors are terminal and require a rese | 10 | ro | x | [BUS_INTEG_ERROR](#status--bus_integ_error) | | 9 | ro | x | [STATE_ERROR](#status--state_error) | | 8 | ro | x | [OTP_ERROR](#status--otp_error) | -| 7 | ro | x | [FLASH_RMA_ERROR](#status--flash_rma_error) | +| 7 | ro | x | [NVM_RMA_ERROR](#status--nvm_rma_error) | | 6 | ro | x | [TOKEN_ERROR](#status--token_error) | | 5 | ro | x | [TRANSITION_ERROR](#status--transition_error) | | 4 | ro | x | [TRANSITION_COUNT_ERROR](#status--transition_count_error) | @@ -108,8 +108,8 @@ This bit is set to 1 if an error occurred during an OTP programming operation. This error will move the life cycle state automatically to POST_TRANSITION and raise a fatal_prog_error alert. -### STATUS . FLASH_RMA_ERROR -This bit is set to 1 if flash failed to correctly respond to an RMA request. +### STATUS . NVM_RMA_ERROR +This bit is set to 1 if NVM failed to correctly respond to an RMA request. Note that each transition attempt increments the [`LC_TRANSITION_CNT`](#lc_transition_cnt) and moves the life cycle state into POST_TRANSITION. diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/theory_of_operation.md b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/theory_of_operation.md index de33fc83e..0c23cb150 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/theory_of_operation.md +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/doc/theory_of_operation.md @@ -327,7 +327,7 @@ That augmented state vector is consumed by three combinational submodules: - `lc_ctrl_transition`: This submodule checks whether the transition target state specified via the CSRs is valid, and computes the redundantly encoded state vector of the transition target state. - `lc_ctrl_signal_decode`: This submodule is an output function only and derives the life cycle control signals (colored in blue) from the augmented state vector. -Note that the two additional life cycle control signals `lc_flash_rma_req_o` and `lc_clk_byp_req_o` are output by the main FSM, since they cannot be derived from the life cycle state alone and are reactive in nature in the sense that there is a corresponding acknowledgement signal. +Note that the two additional life cycle control signals `lc_nvm_rma_req_o` and `lc_clk_byp_req_o` are output by the main FSM, since they cannot be derived from the life cycle state alone and are reactive in nature in the sense that there is a corresponding acknowledgement signal. The life cycle controller contains a JTAG TAP that can be used to access the same CSR space that is accessible via TL-UL. In order to write to the CSRs, a [hardware mutex](#life-cycle-request-interface) has to be claimed. diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_cov_bind.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_cov_bind.sv index 20d5e323e..bc643de15 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_cov_bind.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_cov_bind.sv @@ -18,9 +18,9 @@ module lc_ctrl_cov_bind; .rst_ni(rst_ni), .val(lc_clk_byp_ack_i) ); - bind lc_ctrl lc_tx_cov_array_if #(.Count(NumRmaAckSigs)) u_lc_flash_rma_ack_i_if ( + bind lc_ctrl lc_tx_cov_array_if #(.Count(NumRmaAckSigs)) u_lc_nvm_rma_ack_i_if ( .rst_ni(rst_ni), - .val(lc_flash_rma_ack_i) + .val(lc_nvm_rma_ack_i) ); // otp_lc_data_t otp_lc_data_i struct bind lc_ctrl cip_lc_tx_cov_if u_otp_lc_data_i_secrets_valid_if ( diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_fsm_cov_if.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_fsm_cov_if.sv index 03b6628db..f475213b7 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_fsm_cov_if.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/cov/lc_ctrl_fsm_cov_if.sv @@ -30,7 +30,7 @@ interface lc_ctrl_fsm_cov_if bins CntProgSt = {CntProgSt}; bins TransCheckSt = {TransCheckSt}; bins TokenHashSt = {TokenHashSt}; - bins FlashRmaSt = {FlashRmaSt}; + bins NvmRmaSt = {NvmRmaSt}; bins TokenCheck0St = {TokenCheck0St}; bins TokenCheck1St = {TokenCheck1St}; bins TransProgSt = {TransProgSt}; @@ -47,12 +47,12 @@ interface lc_ctrl_fsm_cov_if (CntIncrSt => PostTransSt, CntProgSt), (CntProgSt => PostTransSt, TransCheckSt), (TransCheckSt => PostTransSt, TokenHashSt), - (TokenHashSt => PostTransSt, FlashRmaSt), - (FlashRmaSt => TokenCheck0St), + (TokenHashSt => PostTransSt, NvmRmaSt), + (NvmRmaSt => TokenCheck0St), (TokenCheck0St, TokenCheck1St => PostTransSt, TokenCheck1St), (TransProgSt => PostTransSt), (IdleSt, ClkMuxSt, CntIncrSt, CntProgSt, TransCheckSt, - TokenHashSt, FlashRmaSt, TokenCheck0St, TokenCheck1St, + TokenHashSt, NvmRmaSt, TokenCheck0St, TokenCheck1St, TransProgSt, PostTransSt, InvalidSt => EscalateSt); } @@ -95,7 +95,7 @@ interface lc_ctrl_fsm_cov_if covergroup sec_token_mux_idx_error_cg @(token_mux_idx_error_cov_ev); coverpoint fsm_state_q { bins fsm_states [] = {ClkMuxSt, CntIncrSt, CntProgSt, TransCheckSt, - FlashRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St}; + NvmRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St}; } endgroup diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_cov.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_cov.sv index d43422eeb..ad4dc8a60 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_cov.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_cov.sv @@ -57,7 +57,7 @@ class lc_ctrl_env_cov extends cip_base_env_cov #( } clk_byp_error_rsp_cp: coverpoint cfg.err_inj.clk_byp_error_rsp; - flash_rma_error_rsp_cp: coverpoint cfg.err_inj.flash_rma_error_rsp; + nvm_rma_error_rsp_cp: coverpoint cfg.err_inj.nvm_rma_error_rsp; otp_prog_err_cp: coverpoint cfg.err_inj.otp_prog_err; otp_partition_err_cp: coverpoint cfg.err_inj.otp_partition_err; token_mismatch_err_cp: coverpoint cfg.err_inj.token_mismatch_err; @@ -77,7 +77,7 @@ class lc_ctrl_env_cov extends cip_base_env_cov #( post_trans_err_cp: coverpoint cfg.err_inj.post_trans_err; security_escalation_err_cp: coverpoint cfg.err_inj.security_escalation_err; clk_byp_rsp_mubi_err_cp: coverpoint cfg.err_inj.clk_byp_rsp_mubi_err; - flash_rma_rsp_mubi_err_cp: coverpoint cfg.err_inj.flash_rma_rsp_mubi_err; + nvm_rma_rsp_mubi_err_cp: coverpoint cfg.err_inj.nvm_rma_rsp_mubi_err; otp_secrets_valid_mubi_err_cp: coverpoint cfg.err_inj.otp_secrets_valid_mubi_err; otp_test_tokens_valid_mubi_err_cp: coverpoint cfg.err_inj.otp_test_tokens_valid_mubi_err; otp_rma_token_valid_mubi_err_cp: coverpoint cfg.err_inj.otp_rma_token_valid_mubi_err; @@ -98,7 +98,7 @@ class lc_ctrl_env_cov extends cip_base_env_cov #( // Crosses for error injection vs CSR access type (JTAG/TL)- make sure we can detect // the error by reading the status reg via both interfaces `LC_CTRL_JTAG_ERROR_CROSS(clk_byp_error_rsp) - `LC_CTRL_JTAG_ERROR_CROSS(flash_rma_error_rsp) + `LC_CTRL_JTAG_ERROR_CROSS(nvm_rma_error_rsp) `LC_CTRL_JTAG_ERROR_CROSS(otp_prog_err) `LC_CTRL_JTAG_ERROR_CROSS(otp_partition_err) `LC_CTRL_JTAG_ERROR_CROSS(token_mismatch_err) diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv index 21c2cbcaf..b2c24b49c 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv @@ -69,8 +69,8 @@ package lc_ctrl_env_pkg; typedef struct packed { // Bad protocol on clk_byp_ack_i bit clk_byp_error_rsp; - // Bad protocol on flash_rma_ack_i - bit flash_rma_error_rsp; + // Bad protocol on nvm_rma_ack_i + bit nvm_rma_error_rsp; // OTP responds with error bit otp_prog_err; // OTP data to lc_ctrl has error bit set @@ -110,8 +110,8 @@ package lc_ctrl_env_pkg; // Use other than "Off" enum for MUBI input off values // clk_byp_rsp bit clk_byp_rsp_mubi_err; - // flash_rma_rsp - bit flash_rma_rsp_mubi_err; + // nvm_rma_rsp + bit nvm_rma_rsp_mubi_err; // OTP secrets valid bit otp_secrets_valid_mubi_err; // OTP test tokens valid diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_if.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_if.sv index 760ba3df0..68ee1fb01 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_if.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/lc_ctrl_if.sv @@ -47,11 +47,11 @@ interface lc_ctrl_if #( lc_tx_t clk_byp_req_o; lc_tx_t clk_byp_ack_i; - lc_tx_t flash_rma_req_o; - lc_tx_t [NumRmaAckSigs-1:0] flash_rma_ack_i; + lc_tx_t nvm_rma_req_o; + lc_tx_t [NumRmaAckSigs-1:0] nvm_rma_ack_i; lc_keymgr_div_t keymgr_div_o; - lc_flash_rma_seed_t flash_rma_seed_o; + lc_nvm_rma_seed_t nvm_rma_seed_o; // OTP test signals logic [CsrOtpTestCtrlWidth-1:0] otp_vendor_test_ctrl_o; @@ -96,7 +96,7 @@ interface lc_ctrl_if #( task automatic init(lc_state_e lc_state = LcStRaw, lc_cnt_e lc_cnt = LcCnt0, lc_tx_t clk_byp_ack = Off, - lc_tx_t [NumRmaAckSigs-1:0] flash_rma_ack = {NumRmaAckSigs{Off}}, + lc_tx_t [NumRmaAckSigs-1:0] nvm_rma_ack = {NumRmaAckSigs{Off}}, logic otp_partition_err = 0, otp_device_id_t otp_device_id = 0, logic otp_lc_data_i_valid = 1, @@ -118,7 +118,7 @@ interface lc_ctrl_if #( clk_byp_ack_i = clk_byp_ack; - flash_rma_ack_i = flash_rma_ack; + nvm_rma_ack_i = nvm_rma_ack; // Make sure we get a transition fork @@ -136,18 +136,18 @@ interface lc_ctrl_if #( clk_byp_ack_i = val; endtask - // Set the channels of flash_rma_ack_i to val. + // Set the channels of nvm_rma_ack_i to val. // // To allow a bit more staggering between the different channels than we already get from CDC, the // caller may pass nonzero values in wait_lens (which defaults to all zero). The task will then // wait the given number of clock cycles before updating the respective channel. - task automatic set_flash_rma_ack(lc_tx_t val, int delay_lens[NumRmaAckSigs] = '{default: 0}); + task automatic set_nvm_rma_ack(lc_tx_t val, int delay_lens[NumRmaAckSigs] = '{default: 0}); fork begin : isolation_fork for (int i = 0; i < NumRmaAckSigs; i++) begin automatic int ii = i; fork begin repeat (delay_lens[ii]) @(posedge clk); - flash_rma_ack_i[ii] = val; + nvm_rma_ack_i[ii] = val; end join_none end @@ -156,7 +156,7 @@ interface lc_ctrl_if #( end join // Check that we have correctly waited for all the channels to update - `DV_CHECK_FATAL(flash_rma_ack_i == {NumRmaAckSigs{val}}, , "lc_ctrl_if") + `DV_CHECK_FATAL(nvm_rma_ack_i == {NumRmaAckSigs{val}}, , "lc_ctrl_if") endtask function automatic void clear_static_signals(); diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv index 91375a903..54fe5bcfd 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv @@ -118,25 +118,25 @@ class lc_ctrl_base_vseq extends cip_base_vseq #( end endtask - virtual task set_flash_rma_ack(lc_ctrl_pkg::lc_tx_t val, int unsigned max_delay_cycles = 10); + virtual task set_nvm_rma_ack(lc_ctrl_pkg::lc_tx_t val, int unsigned max_delay_cycles = 10); int delay_lens[lc_ctrl_dv_utils_pkg::NUM_RMA_ACK_SIGS]; - if (cfg.lc_ctrl_vif.flash_rma_ack_i != {lc_ctrl_dv_utils_pkg::NUM_RMA_ACK_SIGS{val}}) begin + if (cfg.lc_ctrl_vif.nvm_rma_ack_i != {lc_ctrl_dv_utils_pkg::NUM_RMA_ACK_SIGS{val}}) begin for (int i = 0; i < lc_ctrl_dv_utils_pkg::NUM_RMA_ACK_SIGS; i++) begin delay_lens[i] = $urandom_range(0, max_delay_cycles); end end - cfg.lc_ctrl_vif.set_flash_rma_ack(val, delay_lens); + cfg.lc_ctrl_vif.set_nvm_rma_ack(val, delay_lens); endtask - virtual task run_flash_rma_rsp(bit has_err = 0); + virtual task run_nvm_rma_rsp(bit has_err = 0); forever begin - wait(cfg.lc_ctrl_vif.flash_rma_req_o == lc_ctrl_pkg::On); + wait(cfg.lc_ctrl_vif.nvm_rma_req_o == lc_ctrl_pkg::On); cfg.clk_rst_vif.wait_clks($urandom_range(0, 20)); - set_flash_rma_ack((has_err && ($urandom & 1)) ? lc_ctrl_pkg::Off : lc_ctrl_pkg::On); + set_nvm_rma_ack((has_err && ($urandom & 1)) ? lc_ctrl_pkg::Off : lc_ctrl_pkg::On); - wait(cfg.lc_ctrl_vif.flash_rma_req_o != lc_ctrl_pkg::On); + wait(cfg.lc_ctrl_vif.nvm_rma_req_o != lc_ctrl_pkg::On); cfg.clk_rst_vif.wait_clks($urandom_range(0, 20)); - set_flash_rma_ack((has_err && ($urandom & 1)) ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off); + set_nvm_rma_ack((has_err && ($urandom & 1)) ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off); end endtask diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_claim_transition_if_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_claim_transition_if_vseq.sv index c5d741d14..f3ae6f6e6 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_claim_transition_if_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_claim_transition_if_vseq.sv @@ -26,7 +26,7 @@ class lc_ctrl_claim_transition_if_vseq extends lc_ctrl_smoke_vseq; task body(); fork run_clk_byp_rsp(1'b0); - run_flash_rma_rsp(1'b0); + run_nvm_rma_rsp(1'b0); join_none csr_wr(ral.claim_transition_if, rand_claim_trans_val); diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv index c45928df6..db2d43eec 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv @@ -72,7 +72,7 @@ class lc_ctrl_common_vseq extends lc_ctrl_base_vseq; `DV_CHECK_EQ(cfg.lc_ctrl_vif.lc_escalate_en_o, lc_ctrl_pkg::On) `DV_CHECK_EQ(cfg.lc_ctrl_vif.lc_check_byp_en_o, lc_ctrl_pkg::Off) `DV_CHECK_EQ(cfg.lc_ctrl_vif.clk_byp_req_o, lc_ctrl_pkg::Off) - `DV_CHECK_EQ(cfg.lc_ctrl_vif.flash_rma_req_o, lc_ctrl_pkg::Off) + `DV_CHECK_EQ(cfg.lc_ctrl_vif.nvm_rma_req_o, lc_ctrl_pkg::Off) end endtask : check_sec_cm_fi_resp diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv index 1f5a8d36c..59a8ba71f 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv @@ -72,7 +72,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; err_inj.transition_err == 0; err_inj.transition_count_err == 0; err_inj.clk_byp_error_rsp == 0; - err_inj.flash_rma_error_rsp == 0; + err_inj.nvm_rma_error_rsp == 0; err_inj.token_mismatch_err == 0; err_inj.token_response_err == 0; err_inj.token_invalid_err == 0; @@ -123,7 +123,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; constraint mubi_err_inj_c { err_inj.clk_byp_rsp_mubi_err == 0; - err_inj.flash_rma_rsp_mubi_err == 0; + err_inj.nvm_rma_rsp_mubi_err == 0; err_inj.otp_secrets_valid_mubi_err == 0; err_inj.otp_test_tokens_valid_mubi_err == 0; err_inj.otp_rma_token_valid_mubi_err == 0; @@ -169,7 +169,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; disable handle_escalate; disable security_escalation_inject; disable run_clk_byp_rsp; - disable run_flash_rma_rsp; + disable run_nvm_rma_rsp; // Clear escalates cfg.escalate_injected = 0; @@ -224,7 +224,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; // Kill processes disable run_clk_byp_rsp; - disable run_flash_rma_rsp; + disable run_nvm_rma_rsp; if (i != 1) begin `DV_CHECK_RANDOMIZE_FATAL(this) @@ -250,7 +250,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; // Respawn processes fork run_clk_byp_rsp(err_inj.clk_byp_error_rsp); - run_flash_rma_rsp(err_inj.flash_rma_error_rsp); + run_nvm_rma_rsp(err_inj.nvm_rma_error_rsp); join_none `uvm_info(`gfn, $sformatf( @@ -697,7 +697,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; bit state_error_exp, state_error_act; bit count_error_exp, count_error_act; bit token_error_exp, token_error_act; - bit flash_rma_error_exp, flash_rma_error_act; + bit nvm_rma_error_exp, nvm_rma_error_act; bit otp_error_exp, otp_error_act; bit transition_error_exp, transition_error_act; bit transition_count_error_exp, transition_count_error_act; @@ -712,7 +712,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; `uvm_info(`gfn, {"wait_status: ", ral.status.sprint(uvm_default_line_printer)}, UVM_MEDIUM) if (get_field_val(ral.status.transition_successful, status_val)) break; if (get_field_val(ral.status.token_error, status_val)) break; - if (get_field_val(ral.status.flash_rma_error, status_val)) break; + if (get_field_val(ral.status.nvm_rma_error, status_val)) break; if (get_field_val(ral.status.transition_error, status_val)) break; if (get_field_val(ral.status.transition_count_error, status_val)) break; if (get_field_val(ral.status.otp_error, status_val) || @@ -741,7 +741,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; has_test_token(dec_lc_state(lc_state), next_lc_state)) || (cfg.err_inj.otp_rma_token_valid_mubi_err && has_rma_token(dec_lc_state(lc_state), next_lc_state)) || cfg.err_inj.token_mux_digest_err; - flash_rma_error_exp = cfg.err_inj.flash_rma_error_rsp || cfg.err_inj.flash_rma_rsp_mubi_err; + nvm_rma_error_exp = cfg.err_inj.nvm_rma_error_rsp || cfg.err_inj.nvm_rma_rsp_mubi_err; otp_error_exp = cfg.err_inj.otp_prog_err || cfg.err_inj.clk_byp_error_rsp || cfg.err_inj.clk_byp_rsp_mubi_err; transition_count_error_exp = cfg.err_inj.transition_count_err; @@ -751,7 +751,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; // Actual bits state_error_act = get_field_val(ral.status.state_error, status_val); token_error_act = get_field_val(ral.status.token_error, status_val); - flash_rma_error_act = get_field_val(ral.status.flash_rma_error, status_val); + nvm_rma_error_act = get_field_val(ral.status.nvm_rma_error, status_val); otp_error_act = get_field_val(ral.status.otp_error, status_val); transition_count_error_act = get_field_val(ral.status.transition_count_error, status_val); otp_partition_error_act = get_field_val(ral.status.otp_partition_error, status_val); @@ -765,7 +765,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; if (!cfg.err_inj.token_mux_ctrl_redun_err) begin `DV_CHECK_EQ(token_error_act, token_error_exp) end - `DV_CHECK_EQ(flash_rma_error_act, flash_rma_error_exp) + `DV_CHECK_EQ(nvm_rma_error_act, nvm_rma_error_exp) `DV_CHECK_EQ(otp_error_act, otp_error_exp) `DV_CHECK_EQ(transition_count_error_exp, transition_count_error_act) `DV_CHECK_EQ(otp_partition_error_exp, otp_partition_error_act) @@ -959,71 +959,71 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; endtask - virtual task run_flash_rma_rsp(bit has_err = 0); - // Number of lc_flash_rma_ack_i synchronisation FFs + virtual task run_nvm_rma_rsp(bit has_err = 0); + // Number of lc_nvm_rma_ack_i synchronisation FFs // This value can take 2 or 3 cycles after adding cdc instrumentation // and we take maximum to be conservative. - const int FLASH_RMA_ACK_SYNC_FFS = 3; + const int NVM_RMA_ACK_SYNC_FFS = 3; // Values to be driven for On and Off - lc_ctrl_pkg::lc_tx_t on_val = err_inj.flash_rma_rsp_mubi_err ? + lc_ctrl_pkg::lc_tx_t on_val = err_inj.nvm_rma_rsp_mubi_err ? // Get a random value for on cip_base_pkg::get_rand_lc_tx_val(.t_weight(0), .f_weight(0), .other_weight(1)) : // Standard On value lc_ctrl_pkg::On; - lc_ctrl_pkg::lc_tx_t off_val = err_inj.flash_rma_rsp_mubi_err ? + lc_ctrl_pkg::lc_tx_t off_val = err_inj.nvm_rma_rsp_mubi_err ? // Get a random value for off cip_base_pkg::get_rand_lc_tx_val(.t_weight(0), .f_weight(0), .other_weight(1)) : // Standard On value lc_ctrl_pkg::Off; - `uvm_info(`gfn, $sformatf("run_flash_rma_rsp started off_val=%0x, on_val=%0x", + `uvm_info(`gfn, $sformatf("run_nvm_rma_rsp started off_val=%0x, on_val=%0x", off_val,on_val), UVM_MEDIUM) - set_flash_rma_ack(off_val); + set_nvm_rma_ack(off_val); forever begin lc_ctrl_pkg::lc_tx_t rsp = off_val; - while (cfg.lc_ctrl_vif.flash_rma_req_o != lc_ctrl_pkg::On && - !err_inj.flash_rma_error_rsp) begin - @(cfg.lc_ctrl_vif.flash_rma_req_o or err_inj); - if(err_inj.flash_rma_rsp_mubi_err && - cfg.lc_ctrl_vif.flash_rma_req_o != lc_ctrl_pkg::On) begin - set_flash_rma_ack(rsp); + while (cfg.lc_ctrl_vif.nvm_rma_req_o != lc_ctrl_pkg::On && + !err_inj.nvm_rma_error_rsp) begin + @(cfg.lc_ctrl_vif.nvm_rma_req_o or err_inj); + if(err_inj.nvm_rma_rsp_mubi_err && + cfg.lc_ctrl_vif.nvm_rma_req_o != lc_ctrl_pkg::On) begin + set_nvm_rma_ack(rsp); end end - if (err_inj.flash_rma_error_rsp) begin - // Error stream just alternates flash_rma_ack_i every clock cycle. To get the timing right + if (err_inj.nvm_rma_error_rsp) begin + // Error stream just alternates nvm_rma_ack_i every clock cycle. To get the timing right // with this, we set max_delay_cycles to zero. rsp = (rsp == lc_ctrl_pkg::On) ? Off : On; - set_flash_rma_ack(rsp, .max_delay_cycles(0)); + set_nvm_rma_ack(rsp, .max_delay_cycles(0)); cfg.clk_rst_vif.wait_clks(1); end else begin // Normal behaviour rsp = On; cfg.clk_rst_vif.wait_clks($urandom_range(0, 20)); - set_flash_rma_ack(rsp); - // We can only inject error values after state FlashRmaSt starts - if(err_inj.flash_rma_rsp_mubi_err) begin - wait(cfg.lc_ctrl_vif.lc_ctrl_fsm_state inside {FlashRmaSt}); + set_nvm_rma_ack(rsp); + // We can only inject error values after state NvmRmaSt starts + if(err_inj.nvm_rma_rsp_mubi_err) begin + wait(cfg.lc_ctrl_vif.lc_ctrl_fsm_state inside {NvmRmaSt}); // Allow time to get through the synchronisation FFs - cfg.clk_rst_vif.wait_clks(FLASH_RMA_ACK_SYNC_FFS); - // Now inject the bad value. When verifying MuBi errors in the Flash RMA response, our + cfg.clk_rst_vif.wait_clks(NVM_RMA_ACK_SYNC_FFS); + // Now inject the bad value. When verifying MuBi errors in the NVM RMA response, our // sequence seems to expect the invalid MuBi signal to arrive within at most 1 clock // cycle. rsp = on_val; - set_flash_rma_ack(rsp, .max_delay_cycles(1)); + set_nvm_rma_ack(rsp, .max_delay_cycles(1)); end end - wait (cfg.lc_ctrl_vif.flash_rma_req_o != lc_ctrl_pkg::On || err_inj.flash_rma_error_rsp); - if (err_inj.flash_rma_error_rsp) begin - // Error stream just alternates flash_rma_ack_i every clock cycle. To get the timing right + wait (cfg.lc_ctrl_vif.nvm_rma_req_o != lc_ctrl_pkg::On || err_inj.nvm_rma_error_rsp); + if (err_inj.nvm_rma_error_rsp) begin + // Error stream just alternates nvm_rma_ack_i every clock cycle. To get the timing right // with this, we set max_delay_cycles to zero. rsp = (rsp == lc_ctrl_pkg::On) ? Off : On; - set_flash_rma_ack(rsp, .max_delay_cycles(0)); + set_nvm_rma_ack(rsp, .max_delay_cycles(0)); cfg.clk_rst_vif.wait_clks(1); end else begin // Normal behaviour rsp = off_val; cfg.clk_rst_vif.wait_clks($urandom_range(0, 20)); - set_flash_rma_ack(rsp); + set_nvm_rma_ack(rsp); end end endtask @@ -1067,12 +1067,12 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; // Values other than On/Off trigger assertions in the primitives if (err_inj.clk_byp_rsp_mubi_err) `DV_ASSERT_CTRL_REQ("FsmClkBypAckSync", 0) else `DV_ASSERT_CTRL_REQ("FsmClkBypAckSync", 1) - if (err_inj.flash_rma_rsp_mubi_err) begin - `DV_ASSERT_CTRL_REQ("FsmClkFlashRmaAckSync", 0) - `DV_ASSERT_CTRL_REQ("FsmClkFlashRmaAckBuf", 0) + if (err_inj.nvm_rma_rsp_mubi_err) begin + `DV_ASSERT_CTRL_REQ("FsmClkNvmRmaAckSync", 0) + `DV_ASSERT_CTRL_REQ("FsmClkNvmRmaAckBuf", 0) end else begin - `DV_ASSERT_CTRL_REQ("FsmClkFlashRmaAckSync", 1) - `DV_ASSERT_CTRL_REQ("FsmClkFlashRmaAckBuf", 1) + `DV_ASSERT_CTRL_REQ("FsmClkNvmRmaAckSync", 1) + `DV_ASSERT_CTRL_REQ("FsmClkNvmRmaAckBuf", 1) end if (err_inj.otp_test_tokens_valid_mubi_err) `DV_ASSERT_CTRL_REQ("FsmOtpTestTokensValidSync", 0) else `DV_ASSERT_CTRL_REQ("FsmOtpTestTokensValidSync", 1); @@ -1090,7 +1090,7 @@ class lc_ctrl_errors_vseq extends lc_ctrl_smoke_vseq; `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(inj_state, inj_state inside { ClkMuxSt, CntIncrSt, CntProgSt, TransCheckSt, - FlashRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St}; ) + NvmRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St}; ) // Save in config object for scoreboard cfg.token_mux_ctrl_redun_err_inj_state = inj_state; diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_lc_errors_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_lc_errors_vseq.sv index 4fae17e4d..845903b60 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_lc_errors_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_lc_errors_vseq.sv @@ -6,7 +6,7 @@ // Invalid transition // Transition count = 24 // Clock bypass invalid response -// Flash RMA invalid response +// NVM RMA invalid response // Incorrect token for transition // OTP partition error @@ -23,7 +23,7 @@ class lc_ctrl_lc_errors_vseq extends lc_ctrl_errors_vseq; err_inj.transition_err, err_inj.transition_count_err, err_inj.clk_byp_error_rsp, - err_inj.flash_rma_error_rsp, + err_inj.nvm_rma_error_rsp, err_inj.token_mismatch_err, err_inj.token_invalid_err, err_inj.token_response_err, diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_mubi_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_mubi_vseq.sv index 2745533a7..41ada7bb1 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_mubi_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_mubi_vseq.sv @@ -15,7 +15,7 @@ class lc_ctrl_sec_mubi_vseq extends lc_ctrl_errors_vseq; $onehot( { err_inj.clk_byp_rsp_mubi_err, - err_inj.flash_rma_rsp_mubi_err, + err_inj.nvm_rma_rsp_mubi_err, err_inj.otp_secrets_valid_mubi_err, err_inj.otp_test_tokens_valid_mubi_err, err_inj.otp_rma_token_valid_mubi_err diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv index c12abd0ed..3ead04eb2 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv @@ -15,7 +15,7 @@ class lc_ctrl_sec_token_digest_vseq extends lc_ctrl_errors_vseq; err_inj.transition_err == 0; err_inj.transition_count_err == 0; err_inj.clk_byp_error_rsp == 0; - err_inj.flash_rma_error_rsp == 0; + err_inj.nvm_rma_error_rsp == 0; err_inj.token_response_err == 0; err_inj.token_invalid_err == 0; err_inj.otp_partition_err == 0; diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_smoke_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_smoke_vseq.sv index e82ea2768..42df6addc 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_smoke_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_smoke_vseq.sv @@ -24,7 +24,7 @@ class lc_ctrl_smoke_vseq extends lc_ctrl_base_vseq; virtual task post_start(); // Kill sub processes disable run_clk_byp_rsp; - disable run_flash_rma_rsp; + disable run_nvm_rma_rsp; super.post_start(); endtask @@ -32,7 +32,7 @@ class lc_ctrl_smoke_vseq extends lc_ctrl_base_vseq; fork run_clk_byp_rsp(1'b0); - run_flash_rma_rsp(1'b0); + run_nvm_rma_rsp(1'b0); join_none // diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_volatile_unlock_smoke_vseq.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_volatile_unlock_smoke_vseq.sv index 2d037e444..76f0dc8eb 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_volatile_unlock_smoke_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_volatile_unlock_smoke_vseq.sv @@ -30,7 +30,7 @@ class lc_ctrl_volatile_unlock_smoke_vseq extends lc_ctrl_smoke_vseq; int lc_cnt_int; fork run_clk_byp_rsp(1'b0); - run_flash_rma_rsp(1'b0); + run_nvm_rma_rsp(1'b0); join_none `DV_CHECK_RANDOMIZE_FATAL(this) diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/tb.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/tb.sv index a9ba80853..e1baaa089 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/tb.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/dv/tb.sv @@ -203,9 +203,9 @@ module tb; .lc_clk_byp_req_o(lc_ctrl_if.clk_byp_req_o), .lc_clk_byp_ack_i(lc_ctrl_if.clk_byp_ack_i), - .lc_flash_rma_seed_o(lc_ctrl_if.flash_rma_seed_o), - .lc_flash_rma_req_o (lc_ctrl_if.flash_rma_req_o), - .lc_flash_rma_ack_i (lc_ctrl_if.flash_rma_ack_i), + .lc_nvm_rma_seed_o(lc_ctrl_if.nvm_rma_seed_o), + .lc_nvm_rma_req_o (lc_ctrl_if.nvm_rma_req_o), + .lc_nvm_rma_ack_i (lc_ctrl_if.nvm_rma_ack_i), .lc_keymgr_div_o(lc_ctrl_if.keymgr_div_o), @@ -315,16 +315,17 @@ module tb; `DV_ASSERT_CTRL("KmacIfSyncReqAckAckNeedsReq", kmac_app_if.req_data_if.ValidHighUntilReady_A) `DV_ASSERT_CTRL("FsmClkBypAckSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_clk_byp_ack) for (genvar k = 0; k < NUM_RMA_ACK_SIGS; k++) begin : gen_sync_asserts - `DV_ASSERT_CTRL("FsmClkFlashRmaAckSync", - dut.u_lc_ctrl_fsm.gen_syncs[k].u_prim_lc_sync_flash_rma_ack) + `DV_ASSERT_CTRL("FsmClkNvmRmaAckSync", + dut.u_lc_ctrl_fsm.gen_syncs[k].u_prim_lc_sync_nvm_rma_ack) end - `DV_ASSERT_CTRL("FsmClkFlashRmaAckBuf", dut.u_lc_ctrl_fsm.u_prim_lc_sync_flash_rma_ack_buf) + `DV_ASSERT_CTRL("FsmClkNvmRmaAckBuf", dut.u_lc_ctrl_fsm.u_prim_lc_sync_nvm_rma_ack_buf) `DV_ASSERT_CTRL("FsmOtpTestTokensValidSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_test_token_valid) `DV_ASSERT_CTRL("FsmOtpRmaTokenValidSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_rma_token_valid) `DV_ASSERT_CTRL("StateRegs_A", tb.dut.u_lc_ctrl_fsm.u_state_regs_A) `DV_ASSERT_CTRL("StateRegs_A", tb.dut.FpvSecCmCtrlLcStateCheck_A) `DV_ASSERT_CTRL("FsmStateRegs_A", tb.dut.u_lc_ctrl_fsm.u_fsm_state_regs_A) `DV_ASSERT_CTRL("FsmStateRegs_A", tb.dut.FpvSecCmCtrlLcFsmCheck_A) + `DV_ASSERT_CTRL("FsmStateRegs_A", tb.dut.LcInitDoneSticky_A) `DV_ASSERT_CTRL("CountRegs_A", tb.dut.u_lc_ctrl_fsm.u_cnt_regs_A) `DV_ASSERT_CTRL("CountRegs_A", tb.dut.FpvSecCmCtrlLcCntCheck_A) `DV_ASSERT_CTRL("KmacFsmStateRegs_A", tb.dut.u_lc_ctrl_kmac_if.u_state_regs_A) diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl.sv index 7e25d4ca4..76a8abef5 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl.sv @@ -109,12 +109,12 @@ module lc_ctrl // SEC_CM: INTERSIG.MUBI output lc_tx_t lc_clk_byp_req_o, input lc_tx_t lc_clk_byp_ack_i, - // Request and feedback to/from flash controller. + // Request and feedback to/from nvm controller. // The ack is synced to the lc clock domain using prim_lc_sync. - output lc_flash_rma_seed_t lc_flash_rma_seed_o, + output lc_nvm_rma_seed_t lc_nvm_rma_seed_o, // SEC_CM: INTERSIG.MUBI - output lc_tx_t lc_flash_rma_req_o, - input lc_tx_t [NumRmaAckSigs-1:0] lc_flash_rma_ack_i, + output lc_tx_t lc_nvm_rma_req_o, + input lc_tx_t [NumRmaAckSigs-1:0] lc_nvm_rma_ack_i, // State group diversification value for keymgr. output lc_keymgr_div_t lc_keymgr_div_o, // Hardware config input, needed for the DEVICE_ID field. @@ -326,7 +326,7 @@ module lc_ctrl logic trans_cnt_oflw_error_d, trans_cnt_oflw_error_q; logic trans_invalid_error_d, trans_invalid_error_q; logic token_invalid_error_d, token_invalid_error_q; - logic flash_rma_error_d, flash_rma_error_q; + logic nvm_rma_error_d, nvm_rma_error_q; logic otp_prog_error_d, fatal_prog_error_q; logic state_invalid_error_d, fatal_state_error_q; logic otp_part_error_q; @@ -342,20 +342,26 @@ module lc_ctrl logic lc_idle_d, lc_done_d; - // Assign the hardware revision constant and feed it through an anchor buffer. This ensures the - // individual bits remain visible in the netlist, thereby enabling metal fixes to be reflected - // in the hardware revision. - lc_hw_rev_t hw_rev; - assign hw_rev = '{silicon_creator_id: SiliconCreatorId, - product_id: ProductId, - revision_id: RevisionId, - reserved: '0}; - prim_sec_anchor_buf #( - .Width($bits(lc_hw_rev_t)) - ) u_hw_rev_anchor_buf ( - .in_i(hw_rev), - .out_o(hw_rev_o) + // Create the hardware revision with the anchor const that instantiates specific standard cells. + // This ensures the individual bits are not combined through logic optimization and remain visible + // in the netlist, thereby enabling metal fixes to be reflected in the hardware revision. + localparam int HwRevWidth = $bits(lc_hw_rev_t); + localparam lc_hw_rev_t HwRev = '{silicon_creator_id: SiliconCreatorId, + product_id: ProductId, + revision_id: RevisionId, + reserved: '0}; + + // We need to first cast HwRev to a logic array and then back to lc_hw_rev_t + // This explicit cast is required because some tools misinterpret packed struct parameters as + // integers, leading to MSB truncation + logic [HwRevWidth-1:0] hw_rev_raw; + prim_const #( + .Width(HwRevWidth), + .ConstVal(HwRevWidth'(HwRev)) + ) u_hw_rev_const ( + .out_o(hw_rev_raw) ); + assign hw_rev_o = lc_hw_rev_t'(hw_rev_raw); // OTP Vendor control bits logic ext_clock_switched; @@ -373,7 +379,7 @@ module lc_ctrl hw2reg.status.transition_count_error = trans_cnt_oflw_error_q; hw2reg.status.transition_error = trans_invalid_error_q; hw2reg.status.token_error = token_invalid_error_q; - hw2reg.status.flash_rma_error = flash_rma_error_q; + hw2reg.status.nvm_rma_error = nvm_rma_error_q; hw2reg.status.otp_error = fatal_prog_error_q; hw2reg.status.state_error = fatal_state_error_q; hw2reg.status.otp_partition_error = otp_part_error_q; @@ -519,7 +525,7 @@ module lc_ctrl trans_cnt_oflw_error_q <= 1'b0; trans_invalid_error_q <= 1'b0; token_invalid_error_q <= 1'b0; - flash_rma_error_q <= 1'b0; + nvm_rma_error_q <= 1'b0; fatal_prog_error_q <= 1'b0; fatal_state_error_q <= 1'b0; sw_claim_transition_if_q <= MuBi8False; @@ -548,7 +554,7 @@ module lc_ctrl trans_cnt_oflw_error_q <= trans_cnt_oflw_error_d | trans_cnt_oflw_error_q; trans_invalid_error_q <= trans_invalid_error_d | trans_invalid_error_q; token_invalid_error_q <= token_invalid_error_d | token_invalid_error_q; - flash_rma_error_q <= flash_rma_error_d | flash_rma_error_q; + nvm_rma_error_q <= nvm_rma_error_d | nvm_rma_error_q; fatal_prog_error_q <= otp_prog_error_d | fatal_prog_error_q; fatal_state_error_q <= state_invalid_error_d | fatal_state_error_q; otp_part_error_q <= otp_lc_data_i.error | otp_part_error_q; @@ -586,7 +592,7 @@ module lc_ctrl end // ----------- VOLATILE_TEST_UNLOCKED CODE SECTION END ----------- - assign lc_flash_rma_seed_o = transition_token_q[RmaSeedWidth-1:0]; + assign lc_nvm_rma_seed_o = transition_token_q[RmaSeedWidth-1:0]; // Gate the vendor specific test ctrl/status bits to zero in production states. // Buffer the enable signal to prevent optimization of the multibit signal. @@ -812,7 +818,7 @@ module lc_ctrl .trans_cnt_oflw_error_o ( trans_cnt_oflw_error_d ), .trans_invalid_error_o ( trans_invalid_error_d ), .token_invalid_error_o ( token_invalid_error_d ), - .flash_rma_error_o ( flash_rma_error_d ), + .nvm_rma_error_o ( nvm_rma_error_d ), .otp_prog_error_o ( otp_prog_error_d ), .state_invalid_error_o ( state_invalid_error_d ), .lc_raw_test_rma_o ( lc_raw_test_rma ), @@ -833,8 +839,8 @@ module lc_ctrl .lc_check_byp_en_o, .lc_clk_byp_req_o, .lc_clk_byp_ack_i, - .lc_flash_rma_req_o, - .lc_flash_rma_ack_i, + .lc_nvm_rma_req_o, + .lc_nvm_rma_ack_i, .lc_keymgr_div_o ); @@ -870,8 +876,8 @@ module lc_ctrl `ASSERT_KNOWN(LcEscalateEnKnown_A, lc_escalate_en_o ) `ASSERT_KNOWN(LcCheckBypassEnKnown_A, lc_check_byp_en_o ) `ASSERT_KNOWN(LcClkBypReqKnown_A, lc_clk_byp_req_o ) - `ASSERT_KNOWN(LcFlashRmaSeedKnown_A, lc_flash_rma_seed_o ) - `ASSERT_KNOWN(LcFlashRmaReqKnown_A, lc_flash_rma_req_o ) + `ASSERT_KNOWN(LcNvmRmaSeedKnown_A, lc_nvm_rma_seed_o ) + `ASSERT_KNOWN(LcNvmRmaReqKnown_A, lc_nvm_rma_req_o ) `ASSERT_KNOWN(LcKeymgrDiv_A, lc_keymgr_div_o ) `ASSERT_KNOWN(HwRevKnown_A, hw_rev_o ) diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv index 1a2aa14f2..b5fcef918 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv @@ -80,7 +80,7 @@ module lc_ctrl_fsm output logic trans_cnt_oflw_error_o, output logic trans_invalid_error_o, output logic token_invalid_error_o, - output logic flash_rma_error_o, + output logic nvm_rma_error_o, output logic otp_prog_error_o, output logic state_invalid_error_o, // Local life cycle signal @@ -104,9 +104,9 @@ module lc_ctrl_fsm // Request and feedback to/from clock manager and AST. output lc_tx_t lc_clk_byp_req_o, input lc_tx_t lc_clk_byp_ack_i, - // Request and feedback to/from flash controller - output lc_tx_t lc_flash_rma_req_o, - input lc_tx_t [NumRmaAckSigs-1:0] lc_flash_rma_ack_i, + // Request and feedback to/from nvm controller + output lc_tx_t lc_nvm_rma_req_o, + input lc_tx_t [NumRmaAckSigs-1:0] lc_nvm_rma_ack_i, // State group diversification value for keymgr output lc_keymgr_div_t lc_keymgr_div_o ); @@ -135,36 +135,36 @@ module lc_ctrl_fsm // multiple modules that perform wiping in parallel. For security reasons, this signal is not // daisy-chained - see #19136 for context. Synchronize ACK signals separately, combine with // bitwise LC AND function and feed into FSM. - lc_tx_t [NumRmaAckSigs-1:0] lc_flash_rma_ack; + lc_tx_t [NumRmaAckSigs-1:0] lc_nvm_rma_ack; for (genvar k = 0; k < NumRmaAckSigs; k++) begin : gen_syncs prim_lc_sync #( .NumCopies(1) - ) u_prim_lc_sync_flash_rma_ack( + ) u_prim_lc_sync_nvm_rma_ack( .clk_i, .rst_ni, - .lc_en_i(lc_flash_rma_ack_i[k]), - .lc_en_o({lc_flash_rma_ack[k]}) + .lc_en_i(lc_nvm_rma_ack_i[k]), + .lc_en_o({lc_nvm_rma_ack[k]}) ); end - lc_tx_t lc_flash_rma_ack_combined; + lc_tx_t lc_nvm_rma_ack_combined; always_comb begin - lc_flash_rma_ack_combined = On; + lc_nvm_rma_ack_combined = On; for (int k = 0; k < NumRmaAckSigs; k++) begin - lc_flash_rma_ack_combined = lc_tx_and_hi(lc_flash_rma_ack_combined, lc_flash_rma_ack[k]); + lc_nvm_rma_ack_combined = lc_tx_and_hi(lc_nvm_rma_ack_combined, lc_nvm_rma_ack[k]); end end // Make buffered copies for consumption in the FSM below. - lc_tx_t [2:0] lc_flash_rma_ack_buf; + lc_tx_t [2:0] lc_nvm_rma_ack_buf; prim_lc_sync #( .NumCopies(3), .AsyncOn(0) - ) u_prim_lc_sync_flash_rma_ack_buf ( + ) u_prim_lc_sync_nvm_rma_ack_buf ( .clk_i, .rst_ni, - .lc_en_i(lc_flash_rma_ack_combined), - .lc_en_o(lc_flash_rma_ack_buf) + .lc_en_i(lc_nvm_rma_ack_combined), + .lc_en_o(lc_nvm_rma_ack_buf) ); /////////////// @@ -185,7 +185,7 @@ module lc_ctrl_fsm assign otp_prog_lc_cnt_o = next_lc_cnt; // Conditional LC signal outputs - lc_tx_t lc_clk_byp_req, lc_flash_rma_req, lc_check_byp_en; + lc_tx_t lc_clk_byp_req, lc_nvm_rma_req, lc_check_byp_en; `ASSERT_KNOWN(LcStateKnown_A, lc_state_q ) `ASSERT_KNOWN(LcCntKnown_A, lc_cnt_q ) @@ -221,7 +221,7 @@ module lc_ctrl_fsm // Defaults for status/error signals. token_invalid_error_o = 1'b0; otp_prog_error_o = 1'b0; - flash_rma_error_o = 1'b0; + nvm_rma_error_o = 1'b0; trans_success_o = 1'b0; state_invalid_error_o = 1'b0; @@ -242,7 +242,7 @@ module lc_ctrl_fsm // Note that the remaining life cycle signals are decoded in // the lc_ctrl_signal_decode submodule. lc_clk_byp_req = lc_clk_byp_req_o; - lc_flash_rma_req = lc_flash_rma_req_o; + lc_nvm_rma_req = lc_nvm_rma_req_o; lc_check_byp_en = lc_check_byp_en_o; unique case (fsm_state_q) @@ -252,7 +252,7 @@ module lc_ctrl_fsm ResetSt: begin init_done_o = 1'b0; lc_clk_byp_req = Off; - lc_flash_rma_req = Off; + lc_nvm_rma_req = Off; lc_check_byp_en = Off; if (init_req_i && lc_state_valid_q) begin fsm_state_d = IdleSt; @@ -458,7 +458,7 @@ module lc_ctrl_fsm if (hashed_token_i == hashed_token_mux && !token_hash_err_i && &hashed_token_valid_mux) begin - fsm_state_d = FlashRmaSt; + fsm_state_d = NvmRmaSt; end else begin fsm_state_d = PostTransSt; token_invalid_error_o = 1'b1; @@ -466,12 +466,12 @@ module lc_ctrl_fsm end end /////////////////////////////////////////////////////////////////// - // Flash RMA state. Note that we check the flash response again + // NVM RMA state. Note that we check the nvm response again // two times later below. - FlashRmaSt: begin + NvmRmaSt: begin if (trans_target_i == {DecLcStateNumRep{DecLcStRma}}) begin - lc_flash_rma_req = On; - if (lc_tx_test_true_strict(lc_flash_rma_ack_buf[0])) begin + lc_nvm_rma_req = On; + if (lc_tx_test_true_strict(lc_nvm_rma_ack_buf[0])) begin fsm_state_d = TokenCheck0St; end end else begin @@ -480,7 +480,7 @@ module lc_ctrl_fsm end /////////////////////////////////////////////////////////////////// // Check again two times whether this transition and the hashed - // token are valid. Also check again whether the flash RMA + // token are valid. Also check again whether the nvm RMA // response is valid. // SEC_CM: TOKEN.DIGEST TokenCheck0St, @@ -491,11 +491,11 @@ module lc_ctrl_fsm // If any of these RMA are conditions are true, // all of them must be true at the same time. if ((trans_target_i != {DecLcStateNumRep{DecLcStRma}} && - lc_tx_test_false_strict(lc_flash_rma_req_o) && - lc_tx_test_false_strict(lc_flash_rma_ack_buf[1])) || + lc_tx_test_false_strict(lc_nvm_rma_req_o) && + lc_tx_test_false_strict(lc_nvm_rma_ack_buf[1])) || (trans_target_i == {DecLcStateNumRep{DecLcStRma}} && - lc_tx_test_true_strict(lc_flash_rma_req_o) && - lc_tx_test_true_strict(lc_flash_rma_ack_buf[1]))) begin + lc_tx_test_true_strict(lc_nvm_rma_req_o) && + lc_tx_test_true_strict(lc_nvm_rma_ack_buf[1]))) begin if (hashed_token_i == hashed_token_mux && !token_hash_err_i && &hashed_token_valid_mux) begin @@ -510,10 +510,10 @@ module lc_ctrl_fsm fsm_state_d = PostTransSt; token_invalid_error_o = 1'b1; end - // The flash RMA process failed. + // The NVM RMA process failed. end else begin fsm_state_d = PostTransSt; - flash_rma_error_o = 1'b1; + nvm_rma_error_o = 1'b1; end end end @@ -533,11 +533,11 @@ module lc_ctrl_fsm // Also double check that the RMA signals remain stable. // Otherwise abort the transition operation. end else if ((trans_target_i != {DecLcStateNumRep{DecLcStRma}} && - (lc_flash_rma_req_o != Off || lc_flash_rma_ack_buf[2] != Off)) || + (lc_nvm_rma_req_o != Off || lc_nvm_rma_ack_buf[2] != Off)) || (trans_target_i == {DecLcStateNumRep{DecLcStRma}} && - (lc_flash_rma_req_o != On || lc_flash_rma_ack_buf[2] != On))) begin + (lc_nvm_rma_req_o != On || lc_nvm_rma_ack_buf[2] != On))) begin fsm_state_d = PostTransSt; - flash_rma_error_o = 1'b1; + nvm_rma_error_o = 1'b1; end else if (otp_prog_ack_i) begin fsm_state_d = PostTransSt; otp_prog_error_o = otp_prog_err_i; @@ -830,11 +830,11 @@ module lc_ctrl_fsm .lc_en_i(lc_clk_byp_req), .lc_en_o(lc_clk_byp_req_o) ); - prim_lc_sender u_prim_lc_sender_flash_rma_req ( + prim_lc_sender u_prim_lc_sender_nvm_rma_req ( .clk_i, .rst_ni, - .lc_en_i(lc_flash_rma_req), - .lc_en_o(lc_flash_rma_req_o) + .lc_en_i(lc_nvm_rma_req), + .lc_en_o(lc_nvm_rma_req_o) ); prim_lc_sender u_prim_lc_sender_check_byp_en ( .clk_i, @@ -857,10 +857,10 @@ module lc_ctrl_fsm |=> lc_tx_test_true_strict(lc_clk_byp_req_o)) - `ASSERT(FlashRmaStaysOnOnceAsserted_A, - lc_tx_test_true_strict(lc_flash_rma_req_o) + `ASSERT(NvmRmaStaysOnOnceAsserted_A, + lc_tx_test_true_strict(lc_nvm_rma_req_o) |=> - lc_tx_test_true_strict(lc_flash_rma_req_o)) + lc_tx_test_true_strict(lc_nvm_rma_req_o)) `ASSERT(NoClkBypInProdStates_A, lc_state_q inside {LcStProd, LcStProdEnd, LcStDev} diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv index c6a314c03..1f1a72394 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv @@ -64,8 +64,8 @@ package lc_ctrl_pkg; parameter lc_tx_t LC_TX_DEFAULT = lc_tx_t'(Off); parameter int RmaSeedWidth = 32; - typedef logic [RmaSeedWidth-1:0] lc_flash_rma_seed_t; - parameter lc_flash_rma_seed_t LC_FLASH_RMA_SEED_DEFAULT = '0; + typedef logic [RmaSeedWidth-1:0] lc_nvm_rma_seed_t; + parameter lc_nvm_rma_seed_t LC_NVM_RMA_SEED_DEFAULT = '0; parameter int LcKeymgrDivWidth = 128; typedef logic [LcKeymgrDivWidth-1:0] lc_keymgr_div_t; @@ -301,7 +301,7 @@ package lc_ctrl_pkg; CntProgSt = 16'b0000110001010100, TransCheckSt = 16'b0110111010110000, TokenHashSt = 16'b1101001000111111, - FlashRmaSt = 16'b1110100010001111, + NvmRmaSt = 16'b1110100010001111, TokenCheck0St = 16'b0010000011000000, TokenCheck1St = 16'b1101010101101111, TransProgSt = 16'b1000000110101011, diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv index 91769a505..9255f0c6f 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv @@ -105,7 +105,7 @@ package lc_ctrl_reg_pkg; } otp_error; struct packed { logic d; - } flash_rma_error; + } nvm_rma_error; struct packed { logic d; } token_error; diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_regs_reg_top.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_regs_reg_top.sv index b62ea5379..4c99bf779 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_regs_reg_top.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_regs_reg_top.sv @@ -133,7 +133,7 @@ module lc_ctrl_regs_reg_top ( logic status_transition_count_error_qs; logic status_transition_error_qs; logic status_token_error_qs; - logic status_flash_rma_error_qs; + logic status_nvm_rma_error_qs; logic status_otp_error_qs; logic status_state_error_qs; logic status_bus_integ_error_qs; @@ -386,19 +386,19 @@ module lc_ctrl_regs_reg_top ( .qs (status_token_error_qs) ); - // F[flash_rma_error]: 7:7 + // F[nvm_rma_error]: 7:7 prim_subreg_ext #( .DW (1) - ) u_status_flash_rma_error ( + ) u_status_nvm_rma_error ( .re (status_re), .we (1'b0), .wd ('0), - .d (hw2reg.status.flash_rma_error.d), + .d (hw2reg.status.nvm_rma_error.d), .qre (), .qe (), .q (), .ds (), - .qs (status_flash_rma_error_qs) + .qs (status_nvm_rma_error_qs) ); // F[otp_error]: 8:8 @@ -1346,7 +1346,7 @@ module lc_ctrl_regs_reg_top ( reg_rdata_next[4] = status_transition_count_error_qs; reg_rdata_next[5] = status_transition_error_qs; reg_rdata_next[6] = status_token_error_qs; - reg_rdata_next[7] = status_flash_rma_error_qs; + reg_rdata_next[7] = status_nvm_rma_error_qs; reg_rdata_next[8] = status_otp_error_qs; reg_rdata_next[9] = status_state_error_qs; reg_rdata_next[10] = status_bus_integ_error_qs; diff --git a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_signal_decode.sv b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_signal_decode.sv index 443ef53eb..5c332292d 100644 --- a/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_signal_decode.sv +++ b/hw/vendor/lowrisc_ip/ip/lc_ctrl/rtl/lc_ctrl_signal_decode.sv @@ -94,7 +94,7 @@ module lc_ctrl_signal_decode CntIncrSt, CntProgSt, TransCheckSt, - FlashRmaSt, + NvmRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St, @@ -167,7 +167,7 @@ module lc_ctrl_signal_decode /////////////////////////////////////////////////////////////////// // Similar functions as PROD, with the following differences: // - hardware debug functionality (CPU TAP) is enabled, - // - access to the isolated flash partition is disabled. + // - access to the isolated NVM partition is disabled. LcStDev: begin lc_hw_debug_en = On; lc_cpu_en = On; @@ -405,7 +405,7 @@ module lc_ctrl_signal_decode CntIncrSt, CntProgSt, TransCheckSt, - FlashRmaSt, + NvmRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St, @@ -420,7 +420,7 @@ module lc_ctrl_signal_decode CntIncrSt, CntProgSt, TransCheckSt, - FlashRmaSt, + NvmRmaSt, TokenHashSt, TokenCheck0St, TokenCheck1St} && diff --git a/hw/vendor/lowrisc_ip/ip/prim/README.md b/hw/vendor/lowrisc_ip/ip/prim/README.md index 6698ca9f4..fc654fbe6 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/README.md +++ b/hw/vendor/lowrisc_ip/ip/prim/README.md @@ -348,9 +348,9 @@ After synthesizing the top module `prim_sdc_example` the following checks should 1. In the synthesized netlist, the following number of size_only instances must be present: -| cell names | buf | and2 | xor | xnor | flop | clock_mux2 | clock_gating | -| -----------| ---- |------|----- |------ |------|------------|--------------| -| #instances | 328 | 56 | 120 | 56 | 252 | 2 | 2 | +| cell names | buf | and2 | xor | xnor | flop | tie | clock_mux2 | clock_gating | +| -----------| ---- |------|----- |------ |------|-----|------------|--------------| +| #instances | 328 | 56 | 120 | 56 | 252 | 64 | 2 | 2 | 2. None of the test_*_o signals can be driven by a constant 0 or 1. The instantiated `size_only` instances must prevent logic optimizations and keep the output comparators. diff --git a/hw/vendor/lowrisc_ip/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson b/hw/vendor/lowrisc_ip/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson index 29a655073..840591b5c 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson +++ b/hw/vendor/lowrisc_ip/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson @@ -18,5 +18,10 @@ name: xcelium_crypto_dpi_prince_build_opts build_opts: ["-I{build_dir}/fusesoc-work/src/{crypto_prince_ref_src_dir}"] } + + { + name: z01x_crypto_dpi_prince_build_opts + build_opts: ["-CFLAGS -I{build_dir}/fusesoc-work/src/{crypto_prince_ref_src_dir}"] + } ] } diff --git a/hw/vendor/lowrisc_ip/ip/prim/prim.core b/hw/vendor/lowrisc_ip/ip/prim/prim.core index befc14071..15a25ce47 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/prim.core +++ b/hw/vendor/lowrisc_ip/ip/prim/prim.core @@ -15,6 +15,8 @@ filesets: - lowrisc:prim:pad_wrapper - lowrisc:prim:clock_mux2 - lowrisc:prim:clock_inv + - lowrisc:prim:const + - lowrisc:prim:const_sec - lowrisc:prim:buf - lowrisc:prim:flop - lowrisc:prim:flop_en diff --git a/hw/vendor/lowrisc_ip/ip/prim/prim_sec_anchor.core b/hw/vendor/lowrisc_ip/ip/prim/prim_sec_anchor.core index 12f574927..0335cc60e 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/prim_sec_anchor.core +++ b/hw/vendor/lowrisc_ip/ip/prim/prim_sec_anchor.core @@ -9,6 +9,7 @@ filesets: files_rtl: files: - rtl/prim_sec_anchor_buf.sv + - rtl/prim_sec_anchor_const.sv - rtl/prim_sec_anchor_flop.sv file_type: systemVerilogSource depend: diff --git a/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_fifo_assert.svh b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_fifo_assert.svh index 83320918e..3d9ebde44 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_fifo_assert.svh +++ b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_fifo_assert.svh @@ -44,4 +44,15 @@ MAX_CYCLES_, \ err_o) +// A version of ASSERT_PRIM_FIFO_SYNC_ERROR_TRIGGERS_ALERT1, except that it uses +// ASSERT_ERROR_TRIGGER_ALERT_IN instead of ASSERT_ERROR_TRIGGER_ALERT. See description in +// prim_assert_se_cm.svh. +`define ASSERT_PRIM_FIFO_SYNC_ERROR_TRIGGERS_ALERT1_IN(NAME_, HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = 2) \ + `ASSERT_ERROR_TRIGGER_ALERT_IN(``NAME_``FullCheck_A, \ + HIER_, \ + ALERT_, \ + GATE_, \ + MAX_CYCLES_, \ + err_o) + `endif // PRIM_FIFO_ASSERT_SVH diff --git a/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sdc_example.sv b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sdc_example.sv index 5d64d0da2..924b9c07b 100644 --- a/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sdc_example.sv +++ b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sdc_example.sv @@ -9,21 +9,21 @@ // // 1. In the synthesized netlist, the following number of size_only instances must be present: // e.g. grep -c -R u_size_only_x netlist.v (make sure the design is uniquified) -// |-------------------------------------------------------------------| -// | Test | buf | and2 | xor | xnor | flop | clock_mux2 | clock_gating | -// | -----| ----|------|-----|------|------|------------|--------------| -// | 1 | 192 | - | - | - | - | - | - | -// | 2 | - | - | 64 | - | - | - | - | -// | 3 | 48 | 48 | 48 | 48 | 144 | - | - | -// | 4 | 8 | 8 | 8 | 8 | 24 | - | - | -// | 5 | 36 | - | - | - | 24 | - | - | -// | 6 | 16 | - | - | - | 8 | - | - | -// | 7 | - | - | - | - | 32 | 2 | 2 | -// | 8 | 16 | - | - | - | 8 | - | - | -// | 9 | 12 | - | - | - | 12 | - | - | -// | -----| ----|------|-----|------|------|------------|--------------| -// |total | 328 | 56 | 120 | 56 | 252 | 2 | 2 | -// |-------------------------------------------------------------------| +// |-------------------------------------------------------------------------| +// | Test | buf | and2 | xor | xnor | flop | tie | clock_mux2 | clock_gating | +// | -----| ----|------|-----|------|------|-----|------------|--------------| +// | 1 | 192 | - | - | - | - | 64 | - | - | +// | 2 | - | - | 64 | - | - | - | - | - | +// | 3 | 48 | 48 | 48 | 48 | 144 | - | - | - | +// | 4 | 8 | 8 | 8 | 8 | 24 | - | - | - | +// | 5 | 36 | - | - | - | 24 | - | - | - | +// | 6 | 16 | - | - | - | 8 | - | - | - | +// | 7 | - | - | - | - | 32 | - | 2 | 2 | +// | 8 | 16 | - | - | - | 8 | - | - | - | +// | 9 | 12 | - | - | - | 12 | - | - | - | +// | -----| ----|------|-----|------|------|-----|------------|--------------| +// |total | 328 | 56 | 120 | 56 | 252 | 64 | 2 | 2 | +// |-------------------------------------------------------------------------| // // 2. None of the test_*_o signals can be driven by a constant 0 or 1. // The instantiated size_only instances must prevent logic optimizations and keep @@ -76,12 +76,30 @@ module prim_sdc_example #( // It is not allowed that arithmetic operations are merged across prim_bufs // The following size_only cells are expected: // 6*32 size_only_buf + // It is not allowed to combine consts: + // 2*32 size_only TIE cells are expected - localparam int unsigned NumStages = 3; - localparam int unsigned ConstA = 32'h0FF0_ABBA; + localparam int unsigned NumStages = 4; + localparam logic [31:0] ConstA = 32'h0FF0_ABBA; + localparam logic [31:0] ConstB = 32'h1234_ABCD; logic [NumStages-1:0][31:0] res, res_buf; logic [31:0] data_a, data_b, data_c; + logic [31:0] const_a, const_b; + + prim_const_sec #( + .Width(32), + .ConstVal(ConstA) + ) u_const_sec_a ( + .out_o(const_a) + ); + + prim_const #( + .Width(32), + .ConstVal(ConstB) + ) u_const_b ( + .out_o(const_b) + ); prim_buf #( .Width(32) @@ -113,7 +131,7 @@ module prim_sdc_example #( .out_o(res_buf[0]) ); - assign res[1] = res_buf[0] + ConstA; + assign res[1] = res_buf[0] + const_a; prim_buf #( .Width(32) @@ -122,7 +140,7 @@ module prim_sdc_example #( .out_o(res_buf[1]) ); - assign res[2] = res_buf[1] * data_c; + assign res[2] = res_buf[1] * const_b; prim_buf #( .Width(32) @@ -131,7 +149,16 @@ module prim_sdc_example #( .out_o(res_buf[2]) ); - assign test_res_o = res_buf[2]; + assign res[3] = res_buf[2] * data_c; + + prim_buf #( + .Width(32) + ) u_prim_buf_res3 ( + .in_i (res[3]), + .out_o(res_buf[3]) + ); + + assign test_res_o = res_buf[3]; //////////////////////////////////////////////////////////////// // Test 2: two xor operations in a row result in the identity // diff --git a/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sec_anchor_const.sv b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sec_anchor_const.sv new file mode 100644 index 000000000..c01cc2700 --- /dev/null +++ b/hw/vendor/lowrisc_ip/ip/prim/rtl/prim_sec_anchor_const.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" + +module prim_sec_anchor_const #( + parameter int Width = 1, + parameter logic [Width-1:0] ConstVal = '0 +) ( + output logic [Width-1:0] out_o +); + + prim_const_sec #( + .Width(Width), + .ConstVal(ConstVal) + ) u_secure_anchor_const ( + .out_o + ); + +endmodule diff --git a/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic.core b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic.core index e7f3a43db..7bf7dc9c1 100644 --- a/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic.core +++ b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic.core @@ -17,6 +17,8 @@ filesets: - lowrisc:prim_generic:clock_gating - lowrisc:prim_generic:clock_inv - lowrisc:prim_generic:clock_mux2 + - lowrisc:prim_generic:const + - lowrisc:prim_generic:const_sec - lowrisc:prim_generic:flop - lowrisc:prim_generic:flop_2sync - lowrisc:prim_generic:rst_sync @@ -44,6 +46,8 @@ mapping: "lowrisc:prim:clock_gating" : "lowrisc:prim_generic:clock_gating" "lowrisc:prim:clock_inv" : "lowrisc:prim_generic:clock_inv" "lowrisc:prim:clock_mux2" : "lowrisc:prim_generic:clock_mux2" + "lowrisc:prim:const" : "lowrisc:prim_generic:const" + "lowrisc:prim:const_sec" : "lowrisc:prim_generic:const_sec" "lowrisc:prim:flop" : "lowrisc:prim_generic:flop" "lowrisc:prim:flop_2sync" : "lowrisc:prim_generic:flop_2sync" "lowrisc:prim:rst_sync" : "lowrisc:prim_generic:rst_sync" diff --git a/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const.core b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const.core new file mode 100644 index 000000000..eac35a49f --- /dev/null +++ b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const.core @@ -0,0 +1,38 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:const" +description: "const instantiation" +virtual: + - lowrisc:prim:const + +filesets: + files_rtl: + files: + - rtl/prim_const.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const_sec.core b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const_sec.core new file mode 100644 index 000000000..ac9d7943e --- /dev/null +++ b/hw/vendor/lowrisc_ip/ip/prim_generic/prim_generic_const_sec.core @@ -0,0 +1,38 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:const_sec" +description: "secure const instantiation" +virtual: + - lowrisc:prim:const_sec + +filesets: + files_rtl: + files: + - rtl/prim_const_sec.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const.sv b/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const.sv new file mode 100644 index 000000000..840463686 --- /dev/null +++ b/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const.sv @@ -0,0 +1,33 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module utilizes manual instantiation of standard cells to define constant values. By +// employing dedicated TIE cells or specific logic gates and disabling tool-driven optimization, we +// ensure that constants remain accessible for modification via metal-layer engineering change +// orders (ECOs). Means of changing the value should be provisioned in the physical design, +// such as spare inverters, TIE cells of opposite value, or metal-configurable cells. +// +// Unlike prim_const_sec, this module is intended for non-critical, non-secure constants where +// hardware-level security hardening is not required. +// +// The generic implementation is done with assign statements. + +module prim_const #( + parameter int Width = 1, + parameter logic [Width-1:0] ConstVal = '0 +) ( + output logic [Width-1:0] out_o +); + + for (genvar i = 0; i < Width; i++) begin : gen_bits + if (ConstVal[i]) begin : gen_hi + // instantiate size_only TIE-HI + assign out_o[i] = 1'b1; + end else begin : gen_lo + // instantiate size_only TIE-LO + assign out_o[i] = 1'b0; + end + end + +endmodule diff --git a/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const_sec.sv b/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const_sec.sv new file mode 100644 index 000000000..8834a3370 --- /dev/null +++ b/hw/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_const_sec.sv @@ -0,0 +1,30 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module utilizes manual instantiation of standard cells to define constant values. By +// employing dedicated TIE cells or specific logic gates and disabling tool-driven optimization, we +// ensure that constants remain accessible for modification via metal-layer engineering change +// orders (ECOs). Means of changing the value should be provisioned in the physical design, +// such as spare inverters, TIE cells of opposite value, or metal-configurable cells. +// +// The generic implementation is done with assign statements. + +module prim_const_sec #( + parameter int Width = 1, + parameter logic [Width-1:0] ConstVal = '0 +) ( + output logic [Width-1:0] out_o +); + + for (genvar i = 0; i < Width; i++) begin : gen_bits + if (ConstVal[i]) begin : gen_hi + // instantiate size_only TIE-HI + assign out_o[i] = 1'b1; + end else begin : gen_lo + // instantiate size_only TIE-LO + assign out_o[i] = 1'b0; + end + end + +endmodule diff --git a/hw/vendor/lowrisc_ip/ip/prim_xilinx/prim_xilinx.core b/hw/vendor/lowrisc_ip/ip/prim_xilinx/prim_xilinx.core index c456b761e..d222605da 100644 --- a/hw/vendor/lowrisc_ip/ip/prim_xilinx/prim_xilinx.core +++ b/hw/vendor/lowrisc_ip/ip/prim_xilinx/prim_xilinx.core @@ -17,6 +17,8 @@ filesets: - lowrisc:prim_xilinx:clock_gating - lowrisc:prim_generic:clock_inv - lowrisc:prim_xilinx:clock_mux2 + - lowrisc:prim_generic:const + - lowrisc:prim_generic:const_sec - lowrisc:prim_xilinx:flop - lowrisc:prim_generic:flop_2sync - lowrisc:prim_generic:rst_sync @@ -43,6 +45,8 @@ mapping: "lowrisc:prim:clock_gating" : lowrisc:prim_xilinx:clock_gating "lowrisc:prim:clock_inv" : lowrisc:prim_generic:clock_inv "lowrisc:prim:clock_mux2" : lowrisc:prim_xilinx:clock_mux2 + "lowrisc:prim:const" : lowrisc:prim_generic:const + "lowrisc:prim:const_sec" : lowrisc:prim_generic:const_sec "lowrisc:prim:flop" : lowrisc:prim_xilinx:flop "lowrisc:prim:flop_2sync" : lowrisc:prim_generic:flop_2sync "lowrisc:prim:rst_sync" : lowrisc:prim_generic:rst_sync diff --git a/hw/vendor/lowrisc_ip/ip/rom_ctrl/dv/env/seq_lib/rom_ctrl_common_vseq.sv b/hw/vendor/lowrisc_ip/ip/rom_ctrl/dv/env/seq_lib/rom_ctrl_common_vseq.sv index fcbcc22fa..7aa33655f 100644 --- a/hw/vendor/lowrisc_ip/ip/rom_ctrl/dv/env/seq_lib/rom_ctrl_common_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip/rom_ctrl/dv/env/seq_lib/rom_ctrl_common_vseq.sv @@ -126,15 +126,13 @@ function void rom_ctrl_common_vseq::sec_cm_fi_ctrl_svas(sec_cm_base_if_proxy if_ if (touching_req_fifo) begin if (!enable) begin `uvm_info(`gfn, "Doing FI on a request fifo. Disabling related assertions", UVM_HIGH) - $assertoff(0, "tb.dut.TlAccessChk_A"); - $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.respSzEqReqSz_A"); - $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.respMustHaveReq_A"); - $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.respOpcode_A"); + $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respSzEqReqSz_A"); + $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respMustHaveReq_A"); + $assertoff(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respOpcode_A"); end else begin - $asserton(0, "tb.dut.TlAccessChk_A"); - $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.respSzEqReqSz_A"); - $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.respMustHaveReq_A"); - $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.respOpcode_A"); + $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respSzEqReqSz_A"); + $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respMustHaveReq_A"); + $asserton(0, "tb.dut.rom_tlul_assert_device.gen_device.gen_d2h.respOpcode_A"); end end end diff --git a/hw/vendor/lowrisc_ip/ip/tlul/common.core b/hw/vendor/lowrisc_ip/ip/tlul/common.core index 887110530..e3df4cc16 100644 --- a/hw/vendor/lowrisc_ip/ip/tlul/common.core +++ b/hw/vendor/lowrisc_ip/ip/tlul/common.core @@ -9,6 +9,7 @@ filesets: files_rtl: depend: - lowrisc:prim:assert + - lowrisc:prim:buf - lowrisc:prim:fifo - lowrisc:tlul:headers - lowrisc:tlul:trans_intg diff --git a/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_async.sv b/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_async.sv index db375c02c..94da5fe8b 100644 --- a/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_async.sv +++ b/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_async.sv @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // -// TL-UL fifo, used to add elasticity or an asynchronous clock crossing -// to an TL-UL bus. This instantiates two FIFOs, one for the request side, +// Asynchronous TL-UL FIFO, used to cross asynchronous clock domains. +// This instantiates two FIFOs, one for the request side, // and one for the response side. `include "prim_assert.sv" diff --git a/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_sync.sv b/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_sync.sv index e8c822cb0..22d40d136 100644 --- a/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_sync.sv +++ b/hw/vendor/lowrisc_ip/ip/tlul/rtl/tlul_fifo_sync.sv @@ -2,9 +2,10 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // -// TL-UL fifo, used to add elasticity or an asynchronous clock crossing -// to an TL-UL bus. This instantiates two FIFOs, one for the request side, -// and one for the response side. +// Synchronous TL-UL FIFO, used to add elasticity (the ability for +// transactions to stall on one side without affecting the other side) +// to a TL-UL bus. This instantiates two pairs (data + integrity) of FIFOs: +// one pair for the request side, and another pair for the response side. module tlul_fifo_sync #( parameter bit ReqPass = 1'b1, @@ -26,8 +27,14 @@ module tlul_fifo_sync #( output [SpareRspW-1:0] spare_rsp_o ); - // Put everything on the request side into one FIFO - localparam int unsigned REQFIFO_WIDTH = $bits(tlul_pkg::tl_h2d_t) -2 + SpareReqW; + // Put everything on the request side into two FIFOs. + // The first FIFO holds all data except the integrity bits of the `a_user` field. The second FIFO + // only holds the command and data integrity bits of the `a_user` field. This is a FI + // countermeasure, as a fault into one of the two FIFOs will trigger an integrity error once the + // integrity bits are checked. + localparam int unsigned REQFIFO_INTG_WIDTH = tlul_pkg::H2DCmdIntgWidth + tlul_pkg::DataIntgWidth; + localparam int unsigned REQFIFO_WIDTH = $bits(tlul_pkg::tl_h2d_t) -2 + SpareReqW - + REQFIFO_INTG_WIDTH; prim_fifo_sync #(.Width(REQFIFO_WIDTH), .Pass(ReqPass), .Depth(ReqDepth)) reqfifo ( .clk_i, @@ -35,33 +42,81 @@ module tlul_fifo_sync #( .clr_i (1'b0 ), .wvalid_i (tl_h_i.a_valid), .wready_o (tl_h_o.a_ready), - .wdata_i ({tl_h_i.a_opcode , - tl_h_i.a_param , - tl_h_i.a_size , - tl_h_i.a_source , + .wdata_i ({tl_h_i.a_opcode, + tl_h_i.a_param, + tl_h_i.a_size, + tl_h_i.a_source, tl_h_i.a_address, - tl_h_i.a_mask , - tl_h_i.a_data , - tl_h_i.a_user , + tl_h_i.a_mask, + tl_h_i.a_data, + tl_h_i.a_user.rsvd, + tl_h_i.a_user.instr_type, spare_req_i}), .rvalid_o (tl_d_o.a_valid), .rready_i (tl_d_i.a_ready), - .rdata_o ({tl_d_o.a_opcode , - tl_d_o.a_param , - tl_d_o.a_size , - tl_d_o.a_source , + .rdata_o ({tl_d_o.a_opcode, + tl_d_o.a_param, + tl_d_o.a_size, + tl_d_o.a_source, tl_d_o.a_address, - tl_d_o.a_mask , - tl_d_o.a_data , - tl_d_o.a_user , + tl_d_o.a_mask, + tl_d_o.a_data, + tl_d_o.a_user.rsvd, + tl_d_o.a_user.instr_type, spare_req_o}), .full_o (), .depth_o (), .err_o ()); - // Put everything on the response side into the other FIFO + // Buffer the inputs of the FIFO holding the integrity to avoid synthesis optimizations. + localparam int NumBufferBitsReqFifoIntg = $bits({ + tl_h_i.a_valid, + tl_d_i.a_ready + }); - localparam int unsigned RSPFIFO_WIDTH = $bits(tlul_pkg::tl_d2h_t) -2 + SpareRspW; + logic [NumBufferBitsReqFifoIntg-1:0] buf_reqfifo_intg_in, buf_reqfifo_intg_out; + logic reqfifo_intg_a_valid_buf; + logic reqfifo_intg_a_ready_buf; + + assign buf_reqfifo_intg_in = { + tl_h_i.a_valid, + tl_d_i.a_ready + }; + + assign { + reqfifo_intg_a_valid_buf, + reqfifo_intg_a_ready_buf + } = buf_reqfifo_intg_out; + + prim_buf #( + .Width(NumBufferBitsReqFifoIntg) + ) u_reqfifo_intg_prim_buf ( + .in_i(buf_reqfifo_intg_in), + .out_o(buf_reqfifo_intg_out) + ); + + prim_fifo_sync #(.Width(REQFIFO_INTG_WIDTH), .Pass(ReqPass), .Depth(ReqDepth)) reqfifo_intg ( + .clk_i, + .rst_ni, + .clr_i (1'b0 ), + .wvalid_i (reqfifo_intg_a_valid_buf), + .wready_o (), + .wdata_i ({tl_h_i.a_user.cmd_intg, + tl_h_i.a_user.data_intg}), + .rvalid_o (), + .rready_i (reqfifo_intg_a_ready_buf), + .rdata_o ({tl_d_o.a_user.cmd_intg, + tl_d_o.a_user.data_intg}), + .full_o (), + .depth_o (), + .err_o ()); + + // Put everything on the response side into the other two FIFOs. + // The integrity bits and all other bits are separated into two different FIFOs for the same + // reason as above. + localparam int unsigned RSPFIFO_INTG_WIDTH = $bits(tlul_pkg::tl_d_user_t); + localparam int unsigned RSPFIFO_WIDTH = $bits(tlul_pkg::tl_d2h_t) -2 + SpareRspW - + RSPFIFO_INTG_WIDTH; prim_fifo_sync #(.Width(RSPFIFO_WIDTH), .Pass(RspPass), .Depth(RspDepth)) rspfifo ( .clk_i, @@ -76,7 +131,6 @@ module tlul_fifo_sync #( tl_d_i.d_sink , (tl_d_i.d_opcode == tlul_pkg::AccessAckData) ? tl_d_i.d_data : {top_pkg::TL_DW{1'b0}} , - tl_d_i.d_user , tl_d_i.d_error , spare_rsp_i}), .rvalid_o (tl_h_o.d_valid), @@ -87,11 +141,51 @@ module tlul_fifo_sync #( tl_h_o.d_source, tl_h_o.d_sink , tl_h_o.d_data , - tl_h_o.d_user , tl_h_o.d_error , spare_rsp_o}), .full_o (), .depth_o (), .err_o ()); + // Buffer the inputs of the FIFO holding the integrity to avoid synthesis optimizations. + localparam int NumBufferBitsRspFifoIntg = $bits({ + tl_d_i.d_valid, + tl_h_i.d_ready + }); + + logic [NumBufferBitsRspFifoIntg-1:0] buf_rspfifo_intg_in, buf_rspfifo_intg_out; + logic rspfifo_intg_d_valid_buf; + logic rspfifo_intg_d_ready_buf; + + assign buf_rspfifo_intg_in = { + tl_d_i.d_valid, + tl_h_i.d_ready + }; + + assign { + rspfifo_intg_d_valid_buf, + rspfifo_intg_d_ready_buf + } = buf_rspfifo_intg_out; + + prim_buf #( + .Width(NumBufferBitsRspFifoIntg) + ) u_rspfifo_intg_prim_buf ( + .in_i(buf_rspfifo_intg_in), + .out_o(buf_rspfifo_intg_out) + ); + + prim_fifo_sync #(.Width(RSPFIFO_INTG_WIDTH), .Pass(RspPass), .Depth(RspDepth)) rspfifo_intg ( + .clk_i, + .rst_ni, + .clr_i (1'b0 ), + .wvalid_i (rspfifo_intg_d_valid_buf), + .wready_o (), + .wdata_i (tl_d_i.d_user), + .rvalid_o (), + .rready_i (rspfifo_intg_d_ready_buf), + .rdata_o (tl_h_o.d_user), + .full_o (), + .depth_o (), + .err_o ()); + endmodule diff --git a/hw/vendor/lowrisc_ip/ip_templates/gpio/data/gpio_testplan.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/gpio/data/gpio_testplan.hjson.tpl index c8a6fdd90..804903844 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/gpio/data/gpio_testplan.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/gpio/data/gpio_testplan.hjson.tpl @@ -3,11 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 { name: "${module_instance_name}" - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", "gpio_sec_cm_testplan.hjson"] testpoints: [ { diff --git a/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/env/gpio_scoreboard.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/env/gpio_scoreboard.sv.tpl index 6b149fdc6..684697b37 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/env/gpio_scoreboard.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/env/gpio_scoreboard.sv.tpl @@ -364,44 +364,29 @@ class ${module_instance_name}_scoreboard extends cip_base_scoreboard #(.CFG_T ($ end endtask : monitor_gpio_interrupt_pins - virtual task update_gpio_straps_regs(logic [NUM_GPIOS-1:0] gpio_i_sampled); - // Update data_in and data_in_valid ral register value based on result of input - `DV_CHECK_FATAL(ral.hw_straps_data_in.predict(.value(gpio_i_sampled), - .kind(UVM_PREDICT_READ))); - `DV_CHECK_FATAL(ral.hw_straps_data_in_valid.predict(.value('b1), - .kind(UVM_PREDICT_READ))); - endtask : update_gpio_straps_regs - // Task: monitor_gpio_straps // The task monitors the gpio straps enable signal // and checks the straps output signal after the first strap trigger virtual task monitor_gpio_straps(); - logic [NUM_GPIOS-1:0] gpio_i_sampled; forever begin : monitor_gpio_straps - // Wait for going out of reset operation. + // Wait to leave reset wait(!cfg.under_reset); - // Wait until the strap_en input be triggered - // if a reset comes in the middle, step-out of the loop. - while (!cfg.straps_vif_inst.tb_port.strap_en) begin - cfg.clk_rst_vif.wait_clks_or_rst(1); - if (cfg.under_reset) break; - end - // Step out to the next iteration if a reset happens. - if (cfg.under_reset) continue; - // Get the gpio_i input data from the pins interface. - gpio_i_sampled = cfg.gpio_vif.pins; - // Wait for one clock cycle to update the register model. - cfg.clk_rst_vif.wait_clks_or_rst(1); - // Step out from the loop if a reset comes. + + // Now wait until strap_en goes high, dropping out if we go back into reset + fork : isolation_fork begin + fork + wait(cfg.straps_vif_inst.tb_port.strap_en); + wait(cfg.under_reset); + join_any + disable fork; + end join if (cfg.under_reset) continue; - // Update the register model. - update_gpio_straps_regs(gpio_i_sampled); - - // Checker: Compare actual values of gpio pins with straps register. - // Check the register hw_straps_data_in against gpio_i pins - `DV_CHECK_CASE_EQ(gpio_i_sampled, cfg.straps_vif_inst.tb_port.sampled_straps.data) - // Check the register hw_straps_data_in_valid - `DV_CHECK_CASE_EQ('b1, cfg.straps_vif_inst.tb_port.sampled_straps.valid) + + // Sample the pins, storing the value and a validity bit in the register model. + if (!ral.hw_straps_data_in.predict(.value(cfg.gpio_vif.pins), .kind(UVM_PREDICT_DIRECT))) + `uvm_fatal(get_full_name(), "Failed to update HW_STRAPS_DATA_IN prediction.") + if (!ral.hw_straps_data_in_valid.predict(.value(1), .kind(UVM_PREDICT_DIRECT))) + `uvm_fatal(get_full_name(), "Failed to update HW_STRAPS_DATA_IN_VALID prediction.") // Wait for the next reset, if it happens. wait(cfg.under_reset); diff --git a/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/gpio_sim_cfg.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/gpio_sim_cfg.hjson.tpl index 9a24e9bc4..fd51546c6 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/gpio_sim_cfg.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/gpio/dv/gpio_sim_cfg.hjson.tpl @@ -12,7 +12,7 @@ tb: tb // Simulator used to sign off this block - tool: vcs + tool: xcelium // Fusesoc core file used for building the file list. fusesoc_core: ${instance_vlnv(f"lowrisc:dv:{module_instance_name}_sim:0.1")} @@ -26,14 +26,14 @@ // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson"] + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson"] // Add additional tops for simulation. sim_tops: ["${module_instance_name}_bind", "sec_cm_prim_onehot_check_bind"] diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr.hjson.tpl index 2fb8a5cc1..3fcd53e1a 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr.hjson.tpl @@ -193,9 +193,9 @@ package: "lc_ctrl_pkg", }, - { struct: "pwr_flash", + { struct: "pwr_nvm", type: "uni", - name: "pwr_flash", + name: "pwr_nvm", act: "rcv", package: "pwrmgr_pkg", }, @@ -770,7 +770,7 @@ desc = (usb_enabled_text if src == 'usb' else name: "ABORT", desc: ''' The abort wakeup reason indicates that despite setting a WFI and providing a low power - hint, an active flash / lifecycle / otp transaction was ongoing when the power controller + hint, an active NVM / lifecycle / otp transaction was ongoing when the power controller attempted to initiate low power entry. The power manager detects this condition, halts low power entry and reports as a wakeup reason diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson index aad3a73fc..745b94ee4 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson @@ -106,14 +106,14 @@ Low power transitions can be aborted in two cases: - The processor gets an interrupt soon after a low power entry is triggered. - - OTP, LC, or FLASH are not idle. + - OTP, LC, or NVM are not idle. This test aborts low power transitions, and disables any wakeups, so the test would timeout if low power was entered. **Stimulus**: - Bring pwrmgr to low power. - Either disable `pwr_cpu.core_sleeping` or keep some of `lc_idle`, - `otp_idle`, or `flash_idle` inputs off. + `otp_idle`, or `nvm_idle` inputs off. - Disable all wakeup enables. - Randomly set `wakeup_info_capture_dis` CSR. diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/README.md.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/README.md.tpl index dae827ea7..807adabaa 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/README.md.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/README.md.tpl @@ -118,7 +118,7 @@ The test sequences besides the base are as follows: * `pwrmgr_wakeup_vseq` checks the transitions to low power and the wakeup settings. It randomizes wakeup inputs, wakeup enables, the wakeup info capture enable, and the interrupt enable. * `pwrmgr_aborted_low_power_vseq` creates scenarios that lead to aborting a low power transition. - The abort can be due to the processor waking up very soon, or otp, lc, or flash being busy. + The abort can be due to the processor waking up very soon, or otp, lc, or nvm being busy. * `pwrmgr_reset_vseq` checks the pwrmgr response to conditional resets and reset enables, and unconditional escalation and main power glitch resets. * `pwrmgr_wakeup_reset_vseq` aligns reset and wakeup from low power. * `pwrmgr_lowpower_wakeup_race_vseq` aligns a wakeup event coming in proximity to low power entry. @@ -216,8 +216,8 @@ ${"#####"} OTP ${"#####"} LC The pins connecting to LC behave pretty much the same way as those to OTP. -${"#####"} FLASH -- Input `flash_idle` is handled much like `lc_idle` and `otp_idle`. +${"#####"} NVM +- Input `nvm_idle` is handled much like `lc_idle` and `otp_idle`. ${"#####"} CPU - Input `core_sleeping` is driven by sequences. diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/pwrmgr_if.sv b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/pwrmgr_if.sv index 2da8a98a2..511f4ba0e 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/pwrmgr_if.sv +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/pwrmgr_if.sv @@ -36,7 +36,7 @@ interface pwrmgr_if ( lc_ctrl_pkg::pwr_lc_req_t pwr_lc_req; lc_ctrl_pkg::pwr_lc_rsp_t pwr_lc_rsp; - pwrmgr_pkg::pwr_flash_t pwr_flash; + pwrmgr_pkg::pwr_nvm_t pwr_nvm; pwrmgr_pkg::pwrmgr_cpu_t cpu_i; rv_core_ibex_pkg::cpu_pwrmgr_t pwr_cpu; @@ -152,8 +152,8 @@ interface pwrmgr_if ( pwr_lc_rsp.lc_idle = value; endfunction - function automatic void update_flash_idle(logic value); - pwr_flash.flash_idle = value; + function automatic void update_nvm_idle(logic value); + pwr_nvm.nvm_idle = value; endfunction function automatic void update_cpu_sleeping(logic value); @@ -202,7 +202,7 @@ interface pwrmgr_if ( pwr_clk_rsp = '{default: '0}; pwr_otp_rsp = '{default: '0}; pwr_lc_rsp = '{default: '0}; - pwr_flash = '{default: '0}; + pwr_nvm = '{default: '0}; pwr_cpu = rv_core_ibex_pkg::CPU_PWRMGR_DEFAULT; wakeups_i = pwrmgr_pkg::WAKEUPS_DEFAULT; rstreqs_i = pwrmgr_pkg::RSTREQS_DEFAULT; diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv index 41222fe2a..f095f3d46 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv @@ -21,13 +21,13 @@ class pwrmgr_aborted_low_power_vseq extends pwrmgr_base_vseq; }; } - rand bit flash_idle; + rand bit nvm_idle; rand bit lc_idle; rand bit otp_idle; constraint idle_c { - solve cpu_interrupt before flash_idle, lc_idle, otp_idle; - if (!cpu_interrupt) {(flash_idle && lc_idle && otp_idle) == 1'b0;} + solve cpu_interrupt before nvm_idle, lc_idle, otp_idle; + if (!cpu_interrupt) {(nvm_idle && lc_idle && otp_idle) == 1'b0;} } constraint wakeups_c {wakeups != 0;} @@ -84,12 +84,12 @@ class pwrmgr_aborted_low_power_vseq extends pwrmgr_base_vseq; cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); end else begin `uvm_info(`gfn, $sformatf( - "Expecting an abort (0x80): fi=%b, li=%b, oi=%b", - flash_idle, + "Expecting an abort (0x80): nvm_idle=%b, lc_idle=%b, otp_idle=%b", + nvm_idle, lc_idle, otp_idle ), UVM_MEDIUM) - set_nvms_idle(flash_idle, lc_idle, otp_idle); + set_nvms_idle(nvm_idle, lc_idle, otp_idle); end end join diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv.tpl index ab5464533..447e5db8a 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv.tpl @@ -511,7 +511,7 @@ class pwrmgr_base_vseq extends cip_base_vseq #( local task wait_for_abort(); `DV_WAIT( - !cfg.pwrmgr_vif.pwr_flash.flash_idle || !cfg.pwrmgr_vif.pwr_otp_rsp.otp_idle || + !cfg.pwrmgr_vif.pwr_nvm.nvm_idle || !cfg.pwrmgr_vif.pwr_otp_rsp.otp_idle || !cfg.pwrmgr_vif.pwr_lc_rsp.lc_idle) exp_intr = 1'b1; `uvm_info(`gfn, "wait_for_abort succeeds", UVM_MEDIUM) @@ -587,11 +587,11 @@ class pwrmgr_base_vseq extends cip_base_vseq #( // This enables the fast fsm to transition to low power when all nvms are idle after the // transition is enabled by software and cpu WFI. When not all are idle the transition is // aborted. - virtual task set_nvms_idle(logic flash_idle = 1'b1, logic lc_idle = 1'b1, logic otp_idle = 1'b1); + virtual task set_nvms_idle(logic nvm_idle = 1'b1, logic lc_idle = 1'b1, logic otp_idle = 1'b1); `uvm_info(`gfn, $sformatf( - "Setting nvms idle: flash=%b, lc=%b, otp=%b", flash_idle, lc_idle, otp_idle), + "Setting nvms idle: nvm=%b, lc=%b, otp=%b", nvm_idle, lc_idle, otp_idle), UVM_MEDIUM) - cfg.pwrmgr_vif.update_flash_idle(flash_idle); + cfg.pwrmgr_vif.update_nvm_idle(nvm_idle); cfg.pwrmgr_vif.update_lc_idle(lc_idle); cfg.pwrmgr_vif.update_otp_idle(otp_idle); endtask diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/tb.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/tb.sv.tpl index 369d3675e..03a8b9c88 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/tb.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/dv/tb.sv.tpl @@ -96,7 +96,7 @@ module tb; .pwr_lc_i(pwrmgr_if.pwr_lc_rsp), .pwr_lc_o(pwrmgr_if.pwr_lc_req), - .pwr_flash_i(pwrmgr_if.pwr_flash), + .pwr_nvm_i(pwrmgr_if.pwr_nvm), .pwr_cpu_i (pwrmgr_if.pwr_cpu), .fetch_en_o(pwrmgr_if.fetch_en), diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr.sv.tpl index fa3e0570c..429be1e12 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr.sv.tpl @@ -57,8 +57,8 @@ module pwrmgr input lc_ctrl_pkg::pwr_lc_rsp_t pwr_lc_i, output lc_ctrl_pkg::pwr_lc_req_t pwr_lc_o, - // flash interface - input pwr_flash_t pwr_flash_i, + // NVM interface + input pwr_nvm_t pwr_nvm_i, // processor interface input rv_core_ibex_pkg::cpu_pwrmgr_t pwr_cpu_i, @@ -278,7 +278,7 @@ module pwrmgr logic low_power_fall_through; logic low_power_abort; - pwr_flash_t flash_rsp; + pwr_nvm_t nvm_rsp; pwr_otp_rsp_t otp_rsp; prim_mubi_pkg::mubi4_t [NumRomInputs-1:0] rom_ctrl_done_async; @@ -491,9 +491,9 @@ module pwrmgr // peripheral signals .peri_i(peri_reqs_raw), - // flash handshake - .flash_i(pwr_flash_i), - .flash_o(flash_rsp), + // NVM handshake + .nvm_i(pwr_nvm_i), + .nvm_o(nvm_rsp), // OTP signals .otp_i(pwr_otp_i), @@ -696,8 +696,8 @@ module pwrmgr .lc_dft_en_i (lc_dft_en), .lc_hw_debug_en_i (lc_hw_debug_en), - // flash - .flash_idle_i (flash_rsp.flash_idle), + // NVM + .nvm_idle_i (nvm_rsp.nvm_idle), // rom_ctrl .rom_ctrl_done_i (rom_ctrl_done_combined), diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_cdc.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_cdc.sv.tpl index 11d8d01fb..8c1fdcd22 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_cdc.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_cdc.sv.tpl @@ -73,8 +73,8 @@ module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; // peripheral inputs, mixed domains input pwr_peri_t peri_i, - input pwr_flash_t flash_i, - output pwr_flash_t flash_o, + input pwr_nvm_t nvm_i, + output pwr_nvm_t nvm_o, // otp interface input pwr_otp_rsp_t otp_i, @@ -314,11 +314,11 @@ module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; prim_flop_2sync #( .Width(1), .ResetValue(1'b1) - ) u_sync_flash_idle ( + ) u_sync_nvm_idle ( .clk_i, .rst_ni, - .d_i(flash_i.flash_idle), - .q_o(flash_o.flash_idle) + .d_i(nvm_i.nvm_idle), + .q_o(nvm_o.nvm_idle) ); prim_flop_2sync #( diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv.tpl index 1e85bdf0b..79f3aa923 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv.tpl @@ -61,8 +61,8 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;( input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, - // flash - input flash_idle_i, + // NVM + input nvm_idle_i, // rom_ctrl input prim_mubi_pkg::mubi4_t rom_ctrl_done_i, @@ -438,7 +438,7 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;( FastPwrStateNvmIdleChk: begin - if (otp_idle_i && lc_idle_i && flash_idle_i) begin + if (otp_idle_i && lc_idle_i && nvm_idle_i) begin state_d = FastPwrStateLowPowerPrep; end else begin ip_clk_en_d = 1'b1; diff --git a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv.tpl index 6fea5a9e5..2cd368800 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv.tpl @@ -124,11 +124,11 @@ package pwrmgr_pkg; }; typedef struct packed { - logic flash_idle; - } pwr_flash_t; + logic nvm_idle; + } pwr_nvm_t; - parameter pwr_flash_t PWR_FLASH_DEFAULT = '{ - flash_idle: 1'b1 + parameter pwr_nvm_t PWR_NVM_DEFAULT = '{ + nvm_idle: 1'b1 }; // cpu reset requests and status diff --git a/hw/vendor/lowrisc_ip/util/design/check-netlist.py b/hw/vendor/lowrisc_ip/util/design/check-netlist.py index 1947d3d1f..5081843d4 100755 --- a/hw/vendor/lowrisc_ip/util/design/check-netlist.py +++ b/hw/vendor/lowrisc_ip/util/design/check-netlist.py @@ -24,7 +24,7 @@ class Parser: "u_size_only", "u_size_only_xor", "u_size_only_xnor", "u_size_only_and", "u_size_only_mux", "u_size_only_flop", "u_size_only_buf", - "u_size_only_clock_gate" + "u_size_only_tie", "u_size_only_clock_gate" ] # Regex to find ".lc_en_i, ( ... )" and capture the content diff --git a/hw/vendor/lowrisc_ip/util/design/gen-flash-img.py b/hw/vendor/lowrisc_ip/util/design/gen-flash-img.py index fd9e44332..3ce28cc99 100755 --- a/hw/vendor/lowrisc_ip/util/design/gen-flash-img.py +++ b/hw/vendor/lowrisc_ip/util/design/gen-flash-img.py @@ -154,12 +154,12 @@ def _get_otp_ctrl_netlist_consts(top_secret_cfg: dict, scrambling_configs: Flash if key["name"] == "Secret1Key": scrambling_configs.otp_secret1_key = check_int(key["value"]) - # Extract OTP flash scrambling key IVs. + # Extract OTP NVM scrambling key IVs. for digest in otp_map["scrambling"]["digests"]: - if digest["name"] == "FlashAddrKey": + if digest["name"] == "NvmAddrKey": scrambling_configs.addr_key_iv = check_int(digest["iv_value"]) scrambling_configs.addr_key_final_const = check_int(digest["cnst_value"]) - if digest["name"] == "FlashDataKey": + if digest["name"] == "NvmDataKey": scrambling_configs.data_key_iv = check_int(digest["iv_value"]) scrambling_configs.data_key_final_const = check_int(digest["cnst_value"]) diff --git a/hw/vendor/lowrisc_ip/util/version_file.py b/hw/vendor/lowrisc_ip/util/version_file.py index 6a6be9197..94a2327f5 100644 --- a/hw/vendor/lowrisc_ip/util/version_file.py +++ b/hw/vendor/lowrisc_ip/util/version_file.py @@ -33,3 +33,6 @@ def scm_revision(self, default: Union[str, None] = None) -> Union[str, None]: def scm_status(self, default: Union[str, None] = None) -> Union[str, None]: return self.version_stamp.get('BUILD_SCM_STATUS', default) + + def cryptolib_scm_revision(self, default: Union[str, None] = None) -> Union[str, None]: + return self.version_stamp.get('BUILD_CRYPTOLIB_SCM_REVISION', default) diff --git a/hw/vendor/patches/lowrisc_ip/gpio/0001_fix_paths_and_tool.patch b/hw/vendor/patches/lowrisc_ip/gpio/0001_fix_paths_and_tool.patch new file mode 100644 index 000000000..e4adf3644 --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/gpio/0001_fix_paths_and_tool.patch @@ -0,0 +1,56 @@ +diff --git a/data/gpio_testplan.hjson.tpl b/data/gpio_testplan.hjson.tpl +index c8a6fdd..8049038 100644 +--- a/data/gpio_testplan.hjson.tpl ++++ b/data/gpio_testplan.hjson.tpl +@@ -3,11 +3,11 @@ + // SPDX-License-Identifier: Apache-2.0 + { + name: "${module_instance_name}" +- import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", ++ import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + "gpio_sec_cm_testplan.hjson"] + testpoints: [ + { +diff --git a/dv/gpio_sim_cfg.hjson.tpl b/dv/gpio_sim_cfg.hjson.tpl +index 9a24e9b..fd51546 100644 +--- a/dv/gpio_sim_cfg.hjson.tpl ++++ b/dv/gpio_sim_cfg.hjson.tpl +@@ -12,7 +12,7 @@ + tb: tb + + // Simulator used to sign off this block +- tool: vcs ++ tool: xcelium + + // Fusesoc core file used for building the file list. + fusesoc_core: ${instance_vlnv(f"lowrisc:dv:{module_instance_name}_sim:0.1")} +@@ -26,14 +26,14 @@ + + // Import additional common sim cfg files. + import_cfgs: [// Project wide common sim cfg file +- "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", + // Common CIP test lists +- "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson"] ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/intr_test.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson"] + + // Add additional tops for simulation. + sim_tops: ["${module_instance_name}_bind", "sec_cm_prim_onehot_check_bind"]