From d4368c97754b9b3625190112b6a29eb15b2f4435 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Wed, 11 Feb 2026 17:08:05 +0100 Subject: [PATCH] [icache/rtl] Tweak infection Before writing data and tag into the data and tag banks, XOR a tweak on top. When reading back the data and tag from the banks, un-XOR them using the tweak. Signed-off-by: Pascal Nasahl --- doc/02_user/integration.rst | 45 ++--- .../rtl/ibex_riscv_compliance.sv | 48 +++--- dv/uvm/core_ibex/tb/core_ibex_tb_top.sv | 46 ++--- dv/uvm/icache/dv/tb/tb.sv | 12 +- .../simple_system/rtl/ibex_simple_system.sv | 48 +++--- rtl/ibex_core.sv | 34 ++-- rtl/ibex_icache.sv | 111 +++++++++++- rtl/ibex_if_stage.sv | 36 ++-- rtl/ibex_lockstep.sv | 76 +++++---- rtl/ibex_pkg.sv | 2 + rtl/ibex_top.sv | 161 +++++++++--------- rtl/ibex_top_tracing.sv | 114 +++++++------ 12 files changed, 429 insertions(+), 304 deletions(-) diff --git a/doc/02_user/integration.rst b/doc/02_user/integration.rst index 7b2fa830d2..9c62f3b432 100644 --- a/doc/02_user/integration.rst +++ b/doc/02_user/integration.rst @@ -89,28 +89,29 @@ Instantiation Template .. code-block:: verilog ibex_top #( - .PMPEnable ( 0 ), - .PMPGranularity ( 0 ), - .PMPNumRegions ( 4 ), - .MHPMCounterNum ( 0 ), - .MHPMCounterWidth ( 40 ), - .RV32E ( 0 ), - .RV32M ( ibex_pkg::RV32MFast ), - .RV32B ( ibex_pkg::RV32BNone ), - .RV32ZC ( ibex_pkg::RV32ZcaZcbZcmp ), - .RegFile ( ibex_pkg::RegFileFF ), - .ICache ( 0 ), - .ICacheECC ( 0 ), - .ICacheScramble ( 0 ), - .BranchPrediction ( 0 ), - .SecureIbex ( 0 ), - .RndCnstLfsrSeed ( ibex_pkg::RndCnstLfsrSeedDefault ), - .RndCnstLfsrPerm ( ibex_pkg::RndCnstLfsrPermDefault ), - .DbgTriggerEn ( 0 ), - .DmBaseAddr ( 32'h1A110000 ), - .DmAddrMask ( 32'h00000FFF ), - .DmHaltAddr ( 32'h1A110800 ), - .DmExceptionAddr ( 32'h1A110808 ) + .PMPEnable ( 0 ), + .PMPGranularity ( 0 ), + .PMPNumRegions ( 4 ), + .MHPMCounterNum ( 0 ), + .MHPMCounterWidth ( 40 ), + .RV32E ( 0 ), + .RV32M ( ibex_pkg::RV32MFast ), + .RV32B ( ibex_pkg::RV32BNone ), + .RV32ZC ( ibex_pkg::RV32ZcaZcbZcmp ), + .RegFile ( ibex_pkg::RegFileFF ), + .ICache ( 0 ), + .ICacheECC ( 0 ), + .ICacheTweakInfection ( 0 ), + .ICacheScramble ( 0 ), + .BranchPrediction ( 0 ), + .SecureIbex ( 0 ), + .RndCnstLfsrSeed ( ibex_pkg::RndCnstLfsrSeedDefault ), + .RndCnstLfsrPerm ( ibex_pkg::RndCnstLfsrPermDefault ), + .DbgTriggerEn ( 0 ), + .DmBaseAddr ( 32'h1A110000 ), + .DmAddrMask ( 32'h00000FFF ), + .DmHaltAddr ( 32'h1A110800 ), + .DmExceptionAddr ( 32'h1A110808 ) ) u_top ( // Clock and reset .clk_i (), diff --git a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv index c3f2552ded..ea53592d21 100644 --- a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv +++ b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv @@ -29,6 +29,7 @@ module ibex_riscv_compliance ( parameter bit WritebackStage = 1'b0; parameter bit ICache = 1'b0; parameter bit ICacheECC = 1'b0; + parameter bit ICacheTweakInfection = 1'b0; parameter bit BranchPredictor = 1'b0; parameter bit SecureIbex = 1'b0; parameter int unsigned LockstepOffset = 1; @@ -140,29 +141,30 @@ module ibex_riscv_compliance ( end ibex_top_tracing #( - .PMPEnable (PMPEnable ), - .PMPGranularity (PMPGranularity ), - .PMPNumRegions (PMPNumRegions ), - .MHPMCounterNum (MHPMCounterNum ), - .MHPMCounterWidth (MHPMCounterWidth ), - .RV32E (RV32E ), - .RV32M (RV32M ), - .RV32B (RV32B ), - .RV32ZC (RV32ZC ), - .RegFile (RegFile ), - .BranchTargetALU (BranchTargetALU ), - .WritebackStage (WritebackStage ), - .ICache (ICache ), - .ICacheECC (ICacheECC ), - .BranchPredictor (BranchPredictor ), - .DbgTriggerEn (DbgTriggerEn ), - .SecureIbex (SecureIbex ), - .LockstepOffset (LockstepOffset ), - .ICacheScramble (ICacheScramble ), - .DmBaseAddr (32'h00000000 ), - .DmAddrMask (32'h00000003 ), - .DmHaltAddr (32'h00000000 ), - .DmExceptionAddr (32'h00000000 ) + .PMPEnable (PMPEnable ), + .PMPGranularity (PMPGranularity ), + .PMPNumRegions (PMPNumRegions ), + .MHPMCounterNum (MHPMCounterNum ), + .MHPMCounterWidth (MHPMCounterWidth ), + .RV32E (RV32E ), + .RV32M (RV32M ), + .RV32B (RV32B ), + .RV32ZC (RV32ZC ), + .RegFile (RegFile ), + .BranchTargetALU (BranchTargetALU ), + .WritebackStage (WritebackStage ), + .ICache (ICache ), + .ICacheECC (ICacheECC ), + .ICacheTweakInfection (ICacheTweakInfection), + .BranchPredictor (BranchPredictor ), + .DbgTriggerEn (DbgTriggerEn ), + .SecureIbex (SecureIbex ), + .LockstepOffset (LockstepOffset ), + .ICacheScramble (ICacheScramble ), + .DmBaseAddr (32'h00000000 ), + .DmAddrMask (32'h00000003 ), + .DmHaltAddr (32'h00000000 ), + .DmExceptionAddr (32'h00000000 ) ) u_top ( .clk_i (clk_sys ), .rst_ni (rst_sys_n ), diff --git a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index 61802f0325..a2658d1239 100644 --- a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -66,6 +66,7 @@ module core_ibex_tb_top; parameter bit WritebackStage = 1'b0; parameter bit ICache = 1'b0; parameter bit ICacheECC = 1'b0; + parameter bit ICacheTweakInfection = 1'b0; parameter bit BranchPredictor = 1'b0; parameter bit SecureIbex = 1'b0; parameter int unsigned LockstepOffset = 1; @@ -94,28 +95,29 @@ module core_ibex_tb_top; assign {scramble_key, scramble_nonce} = scrambling_key_if.d_data; ibex_top_tracing #( - .PMPEnable (PMPEnable ), - .PMPGranularity (PMPGranularity ), - .PMPNumRegions (PMPNumRegions ), - .MHPMCounterNum (MHPMCounterNum ), - .MHPMCounterWidth (MHPMCounterWidth ), - .RV32E (RV32E ), - .RV32M (RV32M ), - .RV32B (RV32B ), - .RegFile (RegFile ), - .BranchTargetALU (BranchTargetALU ), - .WritebackStage (WritebackStage ), - .ICache (ICache ), - .ICacheECC (ICacheECC ), - .SecureIbex (SecureIbex ), - .LockstepOffset (LockstepOffset ), - .ICacheScramble (ICacheScramble ), - .BranchPredictor (BranchPredictor ), - .DbgTriggerEn (DbgTriggerEn ), - .DmBaseAddr (DmBaseAddr ), - .DmAddrMask (DmAddrMask ), - .DmHaltAddr (DmHaltAddr ), - .DmExceptionAddr (DmExceptionAddr ) + .PMPEnable (PMPEnable ), + .PMPGranularity (PMPGranularity ), + .PMPNumRegions (PMPNumRegions ), + .MHPMCounterNum (MHPMCounterNum ), + .MHPMCounterWidth (MHPMCounterWidth ), + .RV32E (RV32E ), + .RV32M (RV32M ), + .RV32B (RV32B ), + .RegFile (RegFile ), + .BranchTargetALU (BranchTargetALU ), + .WritebackStage (WritebackStage ), + .ICache (ICache ), + .ICacheECC (ICacheECC ), + .ICacheTweakInfection (ICacheTweakInfection), + .SecureIbex (SecureIbex ), + .LockstepOffset (LockstepOffset ), + .ICacheScramble (ICacheScramble ), + .BranchPredictor (BranchPredictor ), + .DbgTriggerEn (DbgTriggerEn ), + .DmBaseAddr (DmBaseAddr ), + .DmAddrMask (DmAddrMask ), + .DmHaltAddr (DmHaltAddr ), + .DmExceptionAddr (DmExceptionAddr ) ) dut ( .clk_i (clk ), diff --git a/dv/uvm/icache/dv/tb/tb.sv b/dv/uvm/icache/dv/tb/tb.sv index 0b1d0e0018..f664192a97 100644 --- a/dv/uvm/icache/dv/tb/tb.sv +++ b/dv/uvm/icache/dv/tb/tb.sv @@ -4,7 +4,8 @@ // import ibex_pkg::*; module tb #( - parameter bit ICacheECC = 1'b1 + parameter bit ICacheECC = 1'b1, + parameter bit ICacheTweakInfection = 1'b1 ); // dep packages import uvm_pkg::*; @@ -49,10 +50,11 @@ module tb #( // DUT ibex_icache #( - .ICacheECC (ICacheECC), - .BusSizeECC (BusSizeECC), - .TagSizeECC (TagSizeECC), - .LineSizeECC (LineSizeECC) + .ICacheECC (ICacheECC), + .ICacheTweakInfection (ICacheTweakInfection), + .BusSizeECC (BusSizeECC), + .TagSizeECC (TagSizeECC), + .LineSizeECC (LineSizeECC) ) dut ( .clk_i ( clk ), .rst_ni ( rst_n ), diff --git a/examples/simple_system/rtl/ibex_simple_system.sv b/examples/simple_system/rtl/ibex_simple_system.sv index c841cd1813..1f5e086028 100644 --- a/examples/simple_system/rtl/ibex_simple_system.sv +++ b/examples/simple_system/rtl/ibex_simple_system.sv @@ -61,6 +61,7 @@ module ibex_simple_system ( parameter bit ICache = 1'b0; parameter bit DbgTriggerEn = 1'b0; parameter bit ICacheECC = 1'b0; + parameter bit ICacheTweakInfection = 1'b0; parameter bit BranchPredictor = 1'b0; parameter SRAMInitFile = ""; @@ -197,29 +198,30 @@ module ibex_simple_system ( end ibex_top_tracing #( - .SecureIbex ( SecureIbex ), - .LockstepOffset ( LockstepOffset ), - .ICacheScramble ( ICacheScramble ), - .PMPEnable ( PMPEnable ), - .PMPGranularity ( PMPGranularity ), - .PMPNumRegions ( PMPNumRegions ), - .MHPMCounterNum ( MHPMCounterNum ), - .MHPMCounterWidth( MHPMCounterWidth ), - .RV32E ( RV32E ), - .RV32M ( RV32M ), - .RV32B ( RV32B ), - .RV32ZC ( RV32ZC ), - .RegFile ( RegFile ), - .BranchTargetALU ( BranchTargetALU ), - .ICache ( ICache ), - .ICacheECC ( ICacheECC ), - .WritebackStage ( WritebackStage ), - .BranchPredictor ( BranchPredictor ), - .DbgTriggerEn ( DbgTriggerEn ), - .DmBaseAddr ( 32'h00100000 ), - .DmAddrMask ( 32'h00000003 ), - .DmHaltAddr ( 32'h00100000 ), - .DmExceptionAddr ( 32'h00100000 ) + .SecureIbex ( SecureIbex ), + .LockstepOffset ( LockstepOffset ), + .ICacheScramble ( ICacheScramble ), + .PMPEnable ( PMPEnable ), + .PMPGranularity ( PMPGranularity ), + .PMPNumRegions ( PMPNumRegions ), + .MHPMCounterNum ( MHPMCounterNum ), + .MHPMCounterWidth ( MHPMCounterWidth ), + .RV32E ( RV32E ), + .RV32M ( RV32M ), + .RV32B ( RV32B ), + .RV32ZC ( RV32ZC ), + .RegFile ( RegFile ), + .BranchTargetALU ( BranchTargetALU ), + .ICache ( ICache ), + .ICacheECC ( ICacheECC ), + .ICacheTweakInfection ( ICacheTweakInfection ), + .WritebackStage ( WritebackStage ), + .BranchPredictor ( BranchPredictor ), + .DbgTriggerEn ( DbgTriggerEn ), + .DmBaseAddr ( 32'h00100000 ), + .DmAddrMask ( 32'h00000003 ), + .DmHaltAddr ( 32'h00100000 ), + .DmExceptionAddr ( 32'h00100000 ) ) u_top ( .clk_i (clk_sys), .rst_ni (rst_sys_n), diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 8361d9fac1..79eef69769 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -30,6 +30,7 @@ module ibex_core import ibex_pkg::*; #( parameter bit WritebackStage = 1'b0, parameter bit ICache = 1'b0, parameter bit ICacheECC = 1'b0, + parameter bit ICacheTweakInfection = 1'b0, parameter int unsigned BusSizeECC = BUS_SIZE, parameter int unsigned TagSizeECC = IC_TAG_SIZE, parameter int unsigned LineSizeECC = IC_LINE_SIZE, @@ -425,22 +426,23 @@ module ibex_core import ibex_pkg::*; #( ////////////// ibex_if_stage #( - .DmHaltAddr (DmHaltAddr), - .DmExceptionAddr (DmExceptionAddr), - .DummyInstructions(DummyInstructions), - .ICache (ICache), - .RV32ZC (RV32ZC), - .ICacheECC (ICacheECC), - .BusSizeECC (BusSizeECC), - .TagSizeECC (TagSizeECC), - .LineSizeECC (LineSizeECC), - .PCIncrCheck (PCIncrCheck), - .ResetAll (ResetAll), - .RndCnstLfsrSeed (RndCnstLfsrSeed), - .RndCnstLfsrPerm (RndCnstLfsrPerm), - .BranchPredictor (BranchPredictor), - .MemECC (MemECC), - .MemDataWidth (MemDataWidth) + .DmHaltAddr (DmHaltAddr), + .DmExceptionAddr (DmExceptionAddr), + .DummyInstructions (DummyInstructions), + .ICache (ICache), + .RV32ZC (RV32ZC), + .ICacheECC (ICacheECC), + .ICacheTweakInfection (ICacheTweakInfection), + .BusSizeECC (BusSizeECC), + .TagSizeECC (TagSizeECC), + .LineSizeECC (LineSizeECC), + .PCIncrCheck (PCIncrCheck), + .ResetAll (ResetAll), + .RndCnstLfsrSeed (RndCnstLfsrSeed), + .RndCnstLfsrPerm (RndCnstLfsrPerm), + .BranchPredictor (BranchPredictor), + .MemECC (MemECC), + .MemDataWidth (MemDataWidth) ) if_stage_i ( .clk_i (clk_i), .rst_ni(rst_ni), diff --git a/rtl/ibex_icache.sv b/rtl/ibex_icache.sv index 8def4a7cae..abb16f4edc 100644 --- a/rtl/ibex_icache.sv +++ b/rtl/ibex_icache.sv @@ -17,7 +17,8 @@ module ibex_icache import ibex_pkg::*; #( parameter int unsigned TagSizeECC = IC_TAG_SIZE, parameter int unsigned LineSizeECC = IC_LINE_SIZE, // Only cache branch targets - parameter bit BranchCache = 1'b0 + parameter bit BranchCache = 1'b0, + parameter bit TweakInfection = 1'b0 ) ( // Clock and reset input logic clk_i, @@ -98,6 +99,13 @@ module ibex_icache import ibex_pkg::*; #( logic [IC_NUM_WAYS-1:0] data_banks_ic0; logic data_write_ic0; logic [LineSizeECC-1:0] data_wdata_ic0; + + // Tweak Infection signals + logic [LineSizeECC-1:0] data_tweak_lw_ic0; + logic [LineSizeECC-1:0] data_tweak_lw_ic1; + logic [TagSizeECC-1:0] tag_tweak_lw_ic0; + logic [TagSizeECC-1:0] tag_tweak_lw_ic1; + // Cache pipeline IC1 signals logic [TagSizeECC-1:0] tag_rdata_ic1 [IC_NUM_WAYS]; logic [LineSizeECC-1:0] data_rdata_ic1 [IC_NUM_WAYS]; @@ -307,6 +315,89 @@ module ibex_icache import ibex_pkg::*; #( assign data_wdata_ic0 = fill_wdata_ic0; end + ///////////////////// + // Tweak Infection // + ///////////////////// + if (TweakInfection) begin : gen_tweak_infection + // Before writing the data to the data bank, XOR the tweak on top of the data. + // When reading back the data, undo this XOR. + // Determine the full address used for the outgoing data bank request. Apply '0, wich + // effectively disabled the tweak infection, when (a) invalidating the cache and (b) + // when there is already an ECC error (we have already raised a minor alert). + logic [ADDR_W-1:0] data_address_ic0; + logic [ADDR_W-1:0] data_tweak_ic0; + assign data_address_ic0 = inval_write_req ? '0 : + ecc_write_req ? '0 : + fill_grant_ic0 ? fill_ram_req_addr : + lookup_addr_ic0; + + // Mask the IC_LINE_W LSBs to remove the offset within a cache line. + assign data_tweak_ic0 = {data_address_ic0[ADDR_W-1:IC_LINE_W], {IC_LINE_W{1'b0}}}; + + // Tie off the unused LSBs. + logic unused_data_address_ic0; + assign unused_data_address_ic0 = ^data_address_ic0[IC_LINE_W-1:0]; + + // Replicate the ADDR_W-bit tweak to match the LineSizeECC width. + if (ICacheECC) begin : gen_ecc_tweak + always_comb begin + data_tweak_lw_ic0 = '0; + for (int i = 0; i < IC_LINE_BEATS; i++) begin + data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0}) << + (i * (ADDR_W + IC_DATA_ECC_SIZE))); + end + end + end else begin: gen_no_ecc_tweak + always_comb begin + data_tweak_lw_ic0 = '0; + for (int i = 0; i < IC_LINE_BEATS; i++) begin + data_tweak_lw_ic0 |= (LineSizeECC'({data_tweak_ic0}) << (i * ADDR_W)); + end + end + end + + // Pipeline the tweak to IC1 to align with the data RAM output timing. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + data_tweak_lw_ic1 <= '0; + end else if (data_req_ic0) begin + data_tweak_lw_ic1 <= data_tweak_lw_ic0; + end + end + + // Setup the tweak for the tag bank. Here, use the tag index as a tweak. + if (ICacheECC) begin : gen_ecc_tag_tweak + always_comb begin + tag_tweak_lw_ic0 = '0; + for (int i = 0; i < IC_LINE_BEATS; i++) begin + tag_tweak_lw_ic0 |= (TagSizeECC'({tag_index_ic0}) << + (i * (IC_INDEX_W + IC_TAG_ECC_SIZE))); + end + end + end else begin: gen_no_ecc_tag_tweak + always_comb begin + tag_tweak_lw_ic0 = '0; + for (int i = 0; i < IC_LINE_BEATS; i++) begin + tag_tweak_lw_ic0 |= (TagSizeECC'({tag_index_ic0}) << (i * IC_INDEX_W)); + end + end + end + + // Pipeline the tag tweak to IC1 to align with the tag RAM output timing. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + tag_tweak_lw_ic1 <= '0; + end else if (tag_req_ic0) begin + tag_tweak_lw_ic1 <= tag_tweak_lw_ic0; + end + end + end else begin: gen_no_tweak_infection + assign data_tweak_lw_ic0 = '0; + assign data_tweak_lw_ic1 = '0; + assign tag_tweak_lw_ic0 = '0; + assign tag_tweak_lw_ic1 = '0; + end + //////////////// // IC0 -> IC1 // //////////////// @@ -315,19 +406,29 @@ module ibex_icache import ibex_pkg::*; #( assign ic_tag_req_o = {IC_NUM_WAYS{tag_req_ic0}} & tag_banks_ic0; assign ic_tag_write_o = tag_write_ic0; assign ic_tag_addr_o = tag_index_ic0; - assign ic_tag_wdata_o = tag_wdata_ic0; + + // Tweak infection, XOR the tag with the tweak. + assign ic_tag_wdata_o = tag_wdata_ic0 ^ tag_tweak_lw_ic0; // Tag RAMs inputs - assign tag_rdata_ic1 = ic_tag_rdata_i; + // Tweak infection, un-XOR the tag using the tweak. + for (genvar way = 0; way < IC_NUM_WAYS; way++) begin : gen_tag_untweak + assign tag_rdata_ic1[way] = ic_tag_rdata_i[way] ^ tag_tweak_lw_ic1; + end // Data RAMs outputs assign ic_data_req_o = {IC_NUM_WAYS{data_req_ic0}} & data_banks_ic0; assign ic_data_write_o = data_write_ic0; assign ic_data_addr_o = data_index_ic0; - assign ic_data_wdata_o = data_wdata_ic0; + + // Tweak infection, XOR the data with the tweak before writing to RAM. + assign ic_data_wdata_o = data_wdata_ic0 ^ data_tweak_lw_ic0; // Data RAMs inputs - assign data_rdata_ic1 = ic_data_rdata_i; + // Tweak infection, un-XOR the data using the tweak. + for (genvar way = 0; way < IC_NUM_WAYS; way++) begin : gen_data_untweak + assign data_rdata_ic1[way] = ic_data_rdata_i[way] ^ data_tweak_lw_ic1; + end always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin diff --git a/rtl/ibex_if_stage.sv b/rtl/ibex_if_stage.sv index ba5c0db53e..bff11bc359 100644 --- a/rtl/ibex_if_stage.sv +++ b/rtl/ibex_if_stage.sv @@ -14,22 +14,23 @@ `include "dv_fcov_macros.svh" module ibex_if_stage import ibex_pkg::*; #( - parameter int unsigned DmHaltAddr = 32'h1A110800, - parameter int unsigned DmExceptionAddr = 32'h1A110808, - parameter bit DummyInstructions = 1'b0, - parameter bit ICache = 1'b0, - parameter rv32zc_e RV32ZC = RV32ZcaZcbZcmp, - parameter bit ICacheECC = 1'b0, - parameter int unsigned BusSizeECC = BUS_SIZE, - parameter int unsigned TagSizeECC = IC_TAG_SIZE, - parameter int unsigned LineSizeECC = IC_LINE_SIZE, - parameter bit PCIncrCheck = 1'b0, - parameter bit ResetAll = 1'b0, - parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, - parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, - parameter bit BranchPredictor = 1'b0, - parameter bit MemECC = 1'b0, - parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32 + parameter int unsigned DmHaltAddr = 32'h1A110800, + parameter int unsigned DmExceptionAddr = 32'h1A110808, + parameter bit DummyInstructions = 1'b0, + parameter bit ICache = 1'b0, + parameter rv32zc_e RV32ZC = RV32ZcaZcbZcmp, + parameter bit ICacheECC = 1'b0, + parameter bit ICacheTweakInfection = 1'b0, + parameter int unsigned BusSizeECC = BUS_SIZE, + parameter int unsigned TagSizeECC = IC_TAG_SIZE, + parameter int unsigned LineSizeECC = IC_LINE_SIZE, + parameter bit PCIncrCheck = 1'b0, + parameter bit ResetAll = 1'b0, + parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, + parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, + parameter bit BranchPredictor = 1'b0, + parameter bit MemECC = 1'b0, + parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32 ) ( input logic clk_i, input logic rst_ni, @@ -276,7 +277,8 @@ module ibex_if_stage import ibex_pkg::*; #( .ResetAll (ResetAll), .BusSizeECC (BusSizeECC), .TagSizeECC (TagSizeECC), - .LineSizeECC (LineSizeECC) + .LineSizeECC (LineSizeECC), + .TweakInfection (ICacheTweakInfection) ) icache_i ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/rtl/ibex_lockstep.sv b/rtl/ibex_lockstep.sv index 4f0d484969..f83f3061f2 100644 --- a/rtl/ibex_lockstep.sv +++ b/rtl/ibex_lockstep.sv @@ -26,6 +26,7 @@ module ibex_lockstep import ibex_pkg::*; #( parameter bit WritebackStage = 1'b0, parameter bit ICache = 1'b0, parameter bit ICacheECC = 1'b0, + parameter bit ICacheTweakInfection = 1'b0, parameter int unsigned BusSizeECC = BUS_SIZE, parameter int unsigned TagSizeECC = IC_TAG_SIZE, parameter int unsigned LineSizeECC = IC_LINE_SIZE, @@ -415,43 +416,44 @@ module ibex_lockstep import ibex_pkg::*; #( logic [RegFileDataEccWidth - RegFileDataWidth - 1:0] shadow_rf_rdata_b_intg; ibex_core #( - .PMPEnable ( PMPEnable ), - .PMPGranularity ( PMPGranularity ), - .PMPNumRegions ( PMPNumRegions ), - .PMPRstCfg ( PMPRstCfg ), - .PMPRstAddr ( PMPRstAddr ), - .PMPRstMsecCfg ( PMPRstMsecCfg ), - .MHPMCounterNum ( MHPMCounterNum ), - .MHPMCounterWidth ( MHPMCounterWidth ), - .RV32E ( RV32E ), - .RV32M ( RV32M ), - .RV32B ( RV32B ), - .RV32ZC ( RV32ZC ), - .BranchTargetALU ( BranchTargetALU ), - .ICache ( ICache ), - .ICacheECC ( ICacheECC ), - .BusSizeECC ( BusSizeECC ), - .TagSizeECC ( TagSizeECC ), - .LineSizeECC ( LineSizeECC ), - .BranchPredictor ( BranchPredictor ), - .DbgTriggerEn ( DbgTriggerEn ), - .DbgHwBreakNum ( DbgHwBreakNum ), - .WritebackStage ( WritebackStage ), - .ResetAll ( ResetAll ), - .RndCnstLfsrSeed ( RndCnstLfsrSeed ), - .RndCnstLfsrPerm ( RndCnstLfsrPerm ), - .SecureIbex ( SecureIbex ), - .DummyInstructions ( DummyInstructions ), - .RegFileECC ( RegFileECC ), - .RegFileDataWidth ( RegFileDataEccWidth ), - .MemECC ( MemECC ), - .MemDataWidth ( MemDataWidth ), - .DmBaseAddr ( DmBaseAddr ), - .DmAddrMask ( DmAddrMask ), - .DmHaltAddr ( DmHaltAddr ), - .DmExceptionAddr ( DmExceptionAddr ), - .CsrMvendorId ( CsrMvendorId ), - .CsrMimpId ( CsrMimpId ) + .PMPEnable ( PMPEnable ), + .PMPGranularity ( PMPGranularity ), + .PMPNumRegions ( PMPNumRegions ), + .PMPRstCfg ( PMPRstCfg ), + .PMPRstAddr ( PMPRstAddr ), + .PMPRstMsecCfg ( PMPRstMsecCfg ), + .MHPMCounterNum ( MHPMCounterNum ), + .MHPMCounterWidth ( MHPMCounterWidth ), + .RV32E ( RV32E ), + .RV32M ( RV32M ), + .RV32B ( RV32B ), + .RV32ZC ( RV32ZC ), + .BranchTargetALU ( BranchTargetALU ), + .ICache ( ICache ), + .ICacheECC ( ICacheECC ), + .ICacheTweakInfection ( ICacheTweakInfection ), + .BusSizeECC ( BusSizeECC ), + .TagSizeECC ( TagSizeECC ), + .LineSizeECC ( LineSizeECC ), + .BranchPredictor ( BranchPredictor ), + .DbgTriggerEn ( DbgTriggerEn ), + .DbgHwBreakNum ( DbgHwBreakNum ), + .WritebackStage ( WritebackStage ), + .ResetAll ( ResetAll ), + .RndCnstLfsrSeed ( RndCnstLfsrSeed ), + .RndCnstLfsrPerm ( RndCnstLfsrPerm ), + .SecureIbex ( SecureIbex ), + .DummyInstructions ( DummyInstructions ), + .RegFileECC ( RegFileECC ), + .RegFileDataWidth ( RegFileDataEccWidth ), + .MemECC ( MemECC ), + .MemDataWidth ( MemDataWidth ), + .DmBaseAddr ( DmBaseAddr ), + .DmAddrMask ( DmAddrMask ), + .DmHaltAddr ( DmHaltAddr ), + .DmExceptionAddr ( DmExceptionAddr ), + .CsrMvendorId ( CsrMvendorId ), + .CsrMimpId ( CsrMimpId ) ) u_shadow_core ( .clk_i (clk_i), .rst_ni (rst_shadow_n), diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 58ecaea4b7..fbe63b91cf 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -394,6 +394,8 @@ package ibex_pkg; parameter int unsigned IC_INDEX_HI = IC_INDEX_W + IC_LINE_W - 1; parameter int unsigned IC_TAG_SIZE = ADDR_W - IC_INDEX_W - IC_LINE_W + 1; // 1 valid bit parameter int unsigned IC_OUTPUT_BEATS = (BUS_BYTES / 2); // number of halfwords + parameter int unsigned IC_DATA_ECC_SIZE = 7; + parameter int unsigned IC_TAG_ECC_SIZE = 6; // ICache Scrambling Parameters parameter int unsigned SCRAMBLE_KEY_W = 128; parameter int unsigned SCRAMBLE_NONCE_W = 64; diff --git a/rtl/ibex_top.sv b/rtl/ibex_top.sv index 4be4a7d7a8..1a0712c4fb 100644 --- a/rtl/ibex_top.sv +++ b/rtl/ibex_top.sv @@ -39,6 +39,7 @@ module ibex_top import ibex_pkg::*; #( parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32, parameter bit ICacheScramble = 1'b0, parameter int unsigned ICacheScrNumPrinceRoundsHalf = 2, + parameter bit ICacheTweakInfection = SecureIbex, parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, parameter int unsigned DmBaseAddr = 32'h1A110000, @@ -191,9 +192,11 @@ module ibex_top import ibex_pkg::*; #( localparam int unsigned RegFileDataWidth = 32; localparam int unsigned RegFileDataEccWidth = 32 + 7; // Icache parameters - localparam int unsigned BusSizeECC = ICacheECC ? (BUS_SIZE + 7) : BUS_SIZE; + localparam int unsigned BusSizeECC = ICacheECC ? (BUS_SIZE + IC_DATA_ECC_SIZE) : + BUS_SIZE; localparam int unsigned LineSizeECC = BusSizeECC * IC_LINE_BEATS; - localparam int unsigned TagSizeECC = ICacheECC ? (IC_TAG_SIZE + 6) : IC_TAG_SIZE; + localparam int unsigned TagSizeECC = ICacheECC ? (IC_TAG_SIZE + IC_TAG_ECC_SIZE) : + IC_TAG_SIZE; // Scrambling Parameter localparam int unsigned NumAddrScrRounds = ICacheScramble ? 2 : 0; @@ -308,43 +311,44 @@ module ibex_top import ibex_pkg::*; #( end ibex_core #( - .PMPEnable (PMPEnable), - .PMPGranularity (PMPGranularity), - .PMPNumRegions (PMPNumRegions), - .PMPRstCfg (PMPRstCfg), - .PMPRstAddr (PMPRstAddr), - .PMPRstMsecCfg (PMPRstMsecCfg), - .MHPMCounterNum (MHPMCounterNum), - .MHPMCounterWidth (MHPMCounterWidth), - .RV32E (RV32E), - .RV32M (RV32M), - .RV32B (RV32B), - .RV32ZC (RV32ZC), - .BranchTargetALU (BranchTargetALU), - .ICache (ICache), - .ICacheECC (ICacheECC), - .BusSizeECC (BusSizeECC), - .TagSizeECC (TagSizeECC), - .LineSizeECC (LineSizeECC), - .BranchPredictor (BranchPredictor), - .DbgTriggerEn (DbgTriggerEn), - .DbgHwBreakNum (DbgHwBreakNum), - .WritebackStage (WritebackStage), - .ResetAll (ResetAll), - .RndCnstLfsrSeed (RndCnstLfsrSeed), - .RndCnstLfsrPerm (RndCnstLfsrPerm), - .SecureIbex (SecureIbex), - .DummyInstructions(DummyInstructions), - .RegFileECC (RegFileECC), - .RegFileDataWidth (RegFileDataWidth), - .MemECC (MemECC), - .MemDataWidth (MemDataWidth), - .DmBaseAddr (DmBaseAddr), - .DmAddrMask (DmAddrMask), - .DmHaltAddr (DmHaltAddr), - .DmExceptionAddr (DmExceptionAddr), - .CsrMvendorId (CsrMvendorId), - .CsrMimpId (CsrMimpId) + .PMPEnable (PMPEnable), + .PMPGranularity (PMPGranularity), + .PMPNumRegions (PMPNumRegions), + .PMPRstCfg (PMPRstCfg), + .PMPRstAddr (PMPRstAddr), + .PMPRstMsecCfg (PMPRstMsecCfg), + .MHPMCounterNum (MHPMCounterNum), + .MHPMCounterWidth (MHPMCounterWidth), + .RV32E (RV32E), + .RV32M (RV32M), + .RV32B (RV32B), + .RV32ZC (RV32ZC), + .BranchTargetALU (BranchTargetALU), + .ICache (ICache), + .ICacheECC (ICacheECC), + .ICacheTweakInfection (ICacheTweakInfection), + .BusSizeECC (BusSizeECC), + .TagSizeECC (TagSizeECC), + .LineSizeECC (LineSizeECC), + .BranchPredictor (BranchPredictor), + .DbgTriggerEn (DbgTriggerEn), + .DbgHwBreakNum (DbgHwBreakNum), + .WritebackStage (WritebackStage), + .ResetAll (ResetAll), + .RndCnstLfsrSeed (RndCnstLfsrSeed), + .RndCnstLfsrPerm (RndCnstLfsrPerm), + .SecureIbex (SecureIbex), + .DummyInstructions (DummyInstructions), + .RegFileECC (RegFileECC), + .RegFileDataWidth (RegFileDataWidth), + .MemECC (MemECC), + .MemDataWidth (MemDataWidth), + .DmBaseAddr (DmBaseAddr), + .DmAddrMask (DmAddrMask), + .DmHaltAddr (DmHaltAddr), + .DmExceptionAddr (DmExceptionAddr), + .CsrMvendorId (CsrMvendorId), + .CsrMimpId (CsrMimpId) ) u_ibex_core ( .clk_i(clk), .rst_ni, @@ -987,45 +991,46 @@ module ibex_top import ibex_pkg::*; #( logic lockstep_alert_major_bus_local; ibex_lockstep #( - .PMPEnable (PMPEnable), - .PMPGranularity (PMPGranularity), - .PMPNumRegions (PMPNumRegions), - .PMPRstCfg (PMPRstCfg), - .PMPRstAddr (PMPRstAddr), - .PMPRstMsecCfg (PMPRstMsecCfg), - .MHPMCounterNum (MHPMCounterNum), - .MHPMCounterWidth (MHPMCounterWidth), - .RV32E (RV32E), - .RV32M (RV32M), - .RV32B (RV32B), - .RV32ZC (RV32ZC), - .BranchTargetALU (BranchTargetALU), - .ICache (ICache), - .ICacheECC (ICacheECC), - .BusSizeECC (BusSizeECC), - .TagSizeECC (TagSizeECC), - .LineSizeECC (LineSizeECC), - .BranchPredictor (BranchPredictor), - .DbgTriggerEn (DbgTriggerEn), - .DbgHwBreakNum (DbgHwBreakNum), - .WritebackStage (WritebackStage), - .ResetAll (ResetAll), - .RndCnstLfsrSeed (RndCnstLfsrSeed), - .RndCnstLfsrPerm (RndCnstLfsrPerm), - .SecureIbex (SecureIbex), - .LockstepOffset (LockstepOffset), - .DummyInstructions (DummyInstructions), - .RegFileECC (RegFileLockstepECC), - .RegFileDataWidth (RegFileDataWidth), - .RegFileDataEccWidth (RegFileDataEccWidth), - .RegFile (RegFile), - .MemECC (MemECC), - .DmBaseAddr (DmBaseAddr), - .DmAddrMask (DmAddrMask), - .DmHaltAddr (DmHaltAddr), - .DmExceptionAddr (DmExceptionAddr), - .CsrMvendorId (CsrMvendorId), - .CsrMimpId (CsrMimpId) + .PMPEnable (PMPEnable), + .PMPGranularity (PMPGranularity), + .PMPNumRegions (PMPNumRegions), + .PMPRstCfg (PMPRstCfg), + .PMPRstAddr (PMPRstAddr), + .PMPRstMsecCfg (PMPRstMsecCfg), + .MHPMCounterNum (MHPMCounterNum), + .MHPMCounterWidth (MHPMCounterWidth), + .RV32E (RV32E), + .RV32M (RV32M), + .RV32B (RV32B), + .RV32ZC (RV32ZC), + .BranchTargetALU (BranchTargetALU), + .ICache (ICache), + .ICacheECC (ICacheECC), + .ICacheTweakInfection (ICacheTweakInfection), + .BusSizeECC (BusSizeECC), + .TagSizeECC (TagSizeECC), + .LineSizeECC (LineSizeECC), + .BranchPredictor (BranchPredictor), + .DbgTriggerEn (DbgTriggerEn), + .DbgHwBreakNum (DbgHwBreakNum), + .WritebackStage (WritebackStage), + .ResetAll (ResetAll), + .RndCnstLfsrSeed (RndCnstLfsrSeed), + .RndCnstLfsrPerm (RndCnstLfsrPerm), + .SecureIbex (SecureIbex), + .LockstepOffset (LockstepOffset), + .DummyInstructions (DummyInstructions), + .RegFileECC (RegFileLockstepECC), + .RegFileDataWidth (RegFileDataWidth), + .RegFileDataEccWidth (RegFileDataEccWidth), + .RegFile (RegFile), + .MemECC (MemECC), + .DmBaseAddr (DmBaseAddr), + .DmAddrMask (DmAddrMask), + .DmHaltAddr (DmHaltAddr), + .DmExceptionAddr (DmExceptionAddr), + .CsrMvendorId (CsrMvendorId), + .CsrMimpId (CsrMimpId) ) u_ibex_lockstep ( .clk_i (clk), .rst_ni (rst_ni), diff --git a/rtl/ibex_top_tracing.sv b/rtl/ibex_top_tracing.sv index 84c0bbc70e..a5f37d1d61 100644 --- a/rtl/ibex_top_tracing.sv +++ b/rtl/ibex_top_tracing.sv @@ -7,34 +7,35 @@ */ module ibex_top_tracing import ibex_pkg::*; #( - parameter bit PMPEnable = 1'b0, - parameter int unsigned PMPGranularity = 0, - parameter int unsigned PMPNumRegions = 4, - parameter int unsigned MHPMCounterNum = 0, - parameter int unsigned MHPMCounterWidth = 40, - parameter bit RV32E = 1'b0, - parameter rv32m_e RV32M = RV32MFast, - parameter rv32b_e RV32B = RV32BNone, - parameter rv32zc_e RV32ZC = RV32ZcaZcbZcmp, - parameter regfile_e RegFile = RegFileFF, - parameter bit BranchTargetALU = 1'b0, - parameter bit WritebackStage = 1'b0, - parameter bit ICache = 1'b0, - parameter bit ICacheECC = 1'b0, - parameter bit BranchPredictor = 1'b0, - parameter bit DbgTriggerEn = 1'b0, - parameter int unsigned DbgHwBreakNum = 1, - parameter bit SecureIbex = 1'b0, - parameter int unsigned LockstepOffset = 1, - parameter bit MemECC = SecureIbex, - parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32, - parameter bit ICacheScramble = 1'b0, - parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, - parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, - parameter int unsigned DmBaseAddr = 32'h1A110000, - parameter int unsigned DmAddrMask = 32'h00000FFF, - parameter int unsigned DmHaltAddr = 32'h1A110800, - parameter int unsigned DmExceptionAddr = 32'h1A110808 + parameter bit PMPEnable = 1'b0, + parameter int unsigned PMPGranularity = 0, + parameter int unsigned PMPNumRegions = 4, + parameter int unsigned MHPMCounterNum = 0, + parameter int unsigned MHPMCounterWidth = 40, + parameter bit RV32E = 1'b0, + parameter rv32m_e RV32M = RV32MFast, + parameter rv32b_e RV32B = RV32BNone, + parameter rv32zc_e RV32ZC = RV32ZcaZcbZcmp, + parameter regfile_e RegFile = RegFileFF, + parameter bit BranchTargetALU = 1'b0, + parameter bit WritebackStage = 1'b0, + parameter bit ICache = 1'b0, + parameter bit ICacheECC = 1'b0, + parameter bit ICacheTweakInfection = 1'b0, + parameter bit BranchPredictor = 1'b0, + parameter bit DbgTriggerEn = 1'b0, + parameter int unsigned DbgHwBreakNum = 1, + parameter bit SecureIbex = 1'b0, + parameter int unsigned LockstepOffset = 1, + parameter bit MemECC = SecureIbex, + parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32, + parameter bit ICacheScramble = 1'b0, + parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, + parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, + parameter int unsigned DmBaseAddr = 32'h1A110000, + parameter int unsigned DmAddrMask = 32'h00000FFF, + parameter int unsigned DmHaltAddr = 32'h1A110800, + parameter int unsigned DmExceptionAddr = 32'h1A110808 ) ( // Clock and Reset input logic clk_i, @@ -194,34 +195,35 @@ module ibex_top_tracing import ibex_pkg::*; #( assign unused_rvfi_ext_expanded_insn_last = rvfi_ext_expanded_insn_last; ibex_top #( - .PMPEnable ( PMPEnable ), - .PMPGranularity ( PMPGranularity ), - .PMPNumRegions ( PMPNumRegions ), - .MHPMCounterNum ( MHPMCounterNum ), - .MHPMCounterWidth ( MHPMCounterWidth ), - .RV32E ( RV32E ), - .RV32M ( RV32M ), - .RV32B ( RV32B ), - .RV32ZC ( RV32ZC ), - .RegFile ( RegFile ), - .BranchTargetALU ( BranchTargetALU ), - .ICache ( ICache ), - .ICacheECC ( ICacheECC ), - .BranchPredictor ( BranchPredictor ), - .DbgTriggerEn ( DbgTriggerEn ), - .DbgHwBreakNum ( DbgHwBreakNum ), - .WritebackStage ( WritebackStage ), - .SecureIbex ( SecureIbex ), - .LockstepOffset ( LockstepOffset ), - .MemECC ( MemECC ), - .MemDataWidth ( MemDataWidth ), - .ICacheScramble ( ICacheScramble ), - .RndCnstLfsrSeed ( RndCnstLfsrSeed ), - .RndCnstLfsrPerm ( RndCnstLfsrPerm ), - .DmBaseAddr ( DmBaseAddr ), - .DmAddrMask ( DmAddrMask ), - .DmHaltAddr ( DmHaltAddr ), - .DmExceptionAddr ( DmExceptionAddr ) + .PMPEnable ( PMPEnable ), + .PMPGranularity ( PMPGranularity ), + .PMPNumRegions ( PMPNumRegions ), + .MHPMCounterNum ( MHPMCounterNum ), + .MHPMCounterWidth ( MHPMCounterWidth ), + .RV32E ( RV32E ), + .RV32M ( RV32M ), + .RV32B ( RV32B ), + .RV32ZC ( RV32ZC ), + .RegFile ( RegFile ), + .BranchTargetALU ( BranchTargetALU ), + .ICache ( ICache ), + .ICacheECC ( ICacheECC ), + .ICacheTweakInfection ( ICacheTweakInfection ), + .BranchPredictor ( BranchPredictor ), + .DbgTriggerEn ( DbgTriggerEn ), + .DbgHwBreakNum ( DbgHwBreakNum ), + .WritebackStage ( WritebackStage ), + .SecureIbex ( SecureIbex ), + .LockstepOffset ( LockstepOffset ), + .MemECC ( MemECC ), + .MemDataWidth ( MemDataWidth ), + .ICacheScramble ( ICacheScramble ), + .RndCnstLfsrSeed ( RndCnstLfsrSeed ), + .RndCnstLfsrPerm ( RndCnstLfsrPerm ), + .DmBaseAddr ( DmBaseAddr ), + .DmAddrMask ( DmAddrMask ), + .DmHaltAddr ( DmHaltAddr ), + .DmExceptionAddr ( DmExceptionAddr ) ) u_ibex_top ( .clk_i, .rst_ni,