mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
[rtl] Add compressed interface
This commit adds compressed interface of the RISC-V Extension Interface. This commit have passed verification with pseudo compressed accelerator.
This commit is contained in:
parent
0a9f5ed1da
commit
d533faf086
16 changed files with 364 additions and 56 deletions
|
@ -107,6 +107,12 @@ parameters:
|
|||
default: 0
|
||||
description: "Enables ICache scrambling feature (EXPERIMENTAL) [0/1]"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
sim:
|
||||
default_tool: verilator
|
||||
|
@ -128,6 +134,7 @@ targets:
|
|||
- PMPNumRegions
|
||||
- SecureIbex
|
||||
- ICacheScramble
|
||||
- XInterface
|
||||
toplevel: ibex_riscv_compliance
|
||||
tools:
|
||||
verilator:
|
||||
|
|
|
@ -29,6 +29,7 @@ module ibex_riscv_compliance (
|
|||
parameter bit BranchPredictor = 1'b0;
|
||||
parameter bit SecureIbex = 1'b0;
|
||||
parameter bit ICacheScramble = 1'b0;
|
||||
parameter bit XInterface = 1'b1;
|
||||
|
||||
logic clk_sys, rst_sys_n;
|
||||
|
||||
|
@ -150,7 +151,8 @@ module ibex_riscv_compliance (
|
|||
.SecureIbex (SecureIbex ),
|
||||
.ICacheScramble (ICacheScramble ),
|
||||
.DmHaltAddr (32'h00000000 ),
|
||||
.DmExceptionAddr (32'h00000000 )
|
||||
.DmExceptionAddr (32'h00000000 ),
|
||||
.XInterface (XInterface )
|
||||
) u_top (
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
|
@ -202,7 +204,12 @@ module ibex_riscv_compliance (
|
|||
.alert_minor_o ( ),
|
||||
.alert_major_internal_o ( ),
|
||||
.alert_major_bus_o ( ),
|
||||
.core_sleep_o ( )
|
||||
.core_sleep_o ( ),
|
||||
|
||||
.x_compressed_valid_o ( ),
|
||||
.x_compressed_ready_i (1'b0 ),
|
||||
.x_compressed_req_o ( ),
|
||||
.x_compressed_resp_i ('0 )
|
||||
);
|
||||
|
||||
// SRAM block for instruction and data storage
|
||||
|
|
|
@ -65,6 +65,7 @@ module core_ibex_tb_top;
|
|||
parameter bit BranchPredictor = 1'b0;
|
||||
parameter bit SecureIbex = 1'b0;
|
||||
parameter bit ICacheScramble = 1'b0;
|
||||
parameter bit XInterface = 1'b1;
|
||||
|
||||
ibex_top_tracing #(
|
||||
.DmHaltAddr (32'h`BOOT_ADDR + 'h0 ),
|
||||
|
@ -82,7 +83,8 @@ module core_ibex_tb_top;
|
|||
.ICacheECC (ICacheECC ),
|
||||
.SecureIbex (SecureIbex ),
|
||||
.ICacheScramble (ICacheScramble ),
|
||||
.BranchPredictor (BranchPredictor )
|
||||
.BranchPredictor (BranchPredictor ),
|
||||
.XInterface (XInterface )
|
||||
) dut (
|
||||
.clk_i (clk ),
|
||||
.rst_ni (rst_n ),
|
||||
|
@ -133,7 +135,12 @@ module core_ibex_tb_top;
|
|||
.alert_minor_o (dut_if.alert_minor ),
|
||||
.alert_major_internal_o (dut_if.alert_major_internal),
|
||||
.alert_major_bus_o (dut_if.alert_major_bus ),
|
||||
.core_sleep_o (dut_if.core_sleep )
|
||||
.core_sleep_o (dut_if.core_sleep ),
|
||||
|
||||
.x_compressed_valid_o ( ),
|
||||
.x_compressed_ready_i (1'b0 ),
|
||||
.x_compressed_req_o ( ),
|
||||
.x_compressed_resp_i ('0 )
|
||||
);
|
||||
|
||||
// We should never see any alerts triggered in normal testing
|
||||
|
|
|
@ -106,6 +106,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables ICache scrambling feature (EXPERIMENTAL) [0/1]"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -127,6 +133,7 @@ targets:
|
|||
- PMPNumRegions
|
||||
- ICacheScramble
|
||||
- SRAMInitFile
|
||||
- XInterface
|
||||
|
||||
lint:
|
||||
<<: *default_target
|
||||
|
|
|
@ -102,6 +102,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Number of PMP regions"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -123,6 +129,7 @@ targets:
|
|||
- PMPGranularity
|
||||
- PMPNumRegions
|
||||
- SRAMInitFile
|
||||
- XInterface
|
||||
|
||||
lint:
|
||||
<<: *default_target
|
||||
|
|
|
@ -50,6 +50,7 @@ module ibex_simple_system (
|
|||
parameter bit ICacheECC = 1'b0;
|
||||
parameter bit BranchPredictor = 1'b0;
|
||||
parameter SRAMInitFile = "";
|
||||
parameter bit XInterface = 1'b1;
|
||||
|
||||
logic clk_sys = 1'b0, rst_sys_n;
|
||||
|
||||
|
@ -200,7 +201,8 @@ module ibex_simple_system (
|
|||
.WritebackStage ( WritebackStage ),
|
||||
.BranchPredictor ( BranchPredictor ),
|
||||
.DmHaltAddr ( 32'h00100000 ),
|
||||
.DmExceptionAddr ( 32'h00100000 )
|
||||
.DmExceptionAddr ( 32'h00100000 ),
|
||||
.XInterface ( XInterface )
|
||||
) u_top (
|
||||
.clk_i (clk_sys),
|
||||
.rst_ni (rst_sys_n),
|
||||
|
@ -252,7 +254,12 @@ module ibex_simple_system (
|
|||
.alert_minor_o (),
|
||||
.alert_major_internal_o (),
|
||||
.alert_major_bus_o (),
|
||||
.core_sleep_o ()
|
||||
.core_sleep_o (),
|
||||
|
||||
.x_compressed_valid_o (),
|
||||
.x_compressed_ready_i (1'b0),
|
||||
.x_compressed_req_o (),
|
||||
.x_compressed_resp_i ('0)
|
||||
);
|
||||
|
||||
// SRAM block for instruction and data storage
|
||||
|
|
|
@ -22,6 +22,7 @@ small:
|
|||
PMPNumRegions : 4
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# Configuration to match that used in the OpenTitan project
|
||||
opentitan:
|
||||
|
@ -39,6 +40,7 @@ opentitan:
|
|||
PMPNumRegions : 16
|
||||
SecureIbex : 1
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# ===============================
|
||||
# * EXPERIMENTAL CONFIGURATIONS *
|
||||
|
@ -62,6 +64,7 @@ experimental-maxperf:
|
|||
PMPNumRegions : 4
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# experimental-maxperf config above plus PMP enabled with 16 regions.
|
||||
experimental-maxperf-pmp:
|
||||
|
@ -79,6 +82,7 @@ experimental-maxperf-pmp:
|
|||
PMPNumRegions : 16
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp config above with balanced bitmanip extension
|
||||
experimental-maxperf-pmp-bmbalanced:
|
||||
|
@ -96,6 +100,7 @@ experimental-maxperf-pmp-bmbalanced:
|
|||
PMPNumRegions : 16
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp config above with full bitmanip extension
|
||||
experimental-maxperf-pmp-bmfull:
|
||||
|
@ -113,6 +118,7 @@ experimental-maxperf-pmp-bmfull:
|
|||
PMPNumRegions : 16
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp-bmfull config above with icache enabled
|
||||
experimental-maxperf-pmp-bmfull-icache:
|
||||
|
@ -130,6 +136,7 @@ experimental-maxperf-pmp-bmfull-icache:
|
|||
PMPNumRegions : 16
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# experimental-maxperf with branch predictor switched on. This exists to allow
|
||||
# easy use of Ibex with the branch predictor in particular for CI runs. The
|
||||
|
@ -150,4 +157,58 @@ experimental-branch-predictor:
|
|||
PMPNumRegions : 4
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
|
||||
# Small with X-Interface
|
||||
small-cvxif:
|
||||
RV32E : 0
|
||||
RV32M : "ibex_pkg::RV32MFast"
|
||||
RV32B : "ibex_pkg::RV32BNone"
|
||||
RegFile : "ibex_pkg::RegFileFF"
|
||||
BranchTargetALU : 0
|
||||
WritebackStage : 0
|
||||
ICache : 0
|
||||
ICacheECC : 0
|
||||
BranchPredictor : 0
|
||||
PMPEnable : 0
|
||||
PMPGranularity : 0
|
||||
PMPNumRegions : 4
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
|
||||
# Opentitan with X-Interface
|
||||
opentitan-cvxif:
|
||||
RV32E : 0
|
||||
RV32M : "ibex_pkg::RV32MSingleCycle"
|
||||
RV32B : "ibex_pkg::RV32BOTEarlGrey"
|
||||
RegFile : "ibex_pkg::RegFileFF"
|
||||
BranchTargetALU : 1
|
||||
WritebackStage : 1
|
||||
ICache : 1
|
||||
ICacheECC : 1
|
||||
BranchPredictor : 0
|
||||
PMPEnable : 1
|
||||
PMPGranularity : 0
|
||||
PMPNumRegions : 16
|
||||
SecureIbex : 1
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
|
||||
# experimental-maxperf-pmp config with X-Interface
|
||||
experimental-maxperf-pmp-bmfull-cvxif:
|
||||
RV32E : 0
|
||||
RV32M : "ibex_pkg::RV32MSingleCycle"
|
||||
RV32B : "ibex_pkg::RV32BFull"
|
||||
RegFile : "ibex_pkg::RegFileFF"
|
||||
BranchTargetALU : 1
|
||||
WritebackStage : 1
|
||||
ICache : 0
|
||||
ICacheECC : 0
|
||||
BranchPredictor : 0
|
||||
PMPEnable : 1
|
||||
PMPGranularity : 0
|
||||
PMPNumRegions : 16
|
||||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
|
|
|
@ -142,6 +142,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Number of PMP regions"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
|
|
@ -132,6 +132,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Number of PMP regions"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
|
|
@ -107,6 +107,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Number of PMP regions"
|
||||
|
||||
XInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -134,6 +140,7 @@ targets:
|
|||
- PMPEnable
|
||||
- PMPGranularity
|
||||
- PMPNumRegions
|
||||
- XInterface
|
||||
default_tool: verilator
|
||||
tools:
|
||||
verilator:
|
||||
|
|
|
@ -42,7 +42,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
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 int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -148,7 +149,14 @@ module ibex_core import ibex_pkg::*; #(
|
|||
output logic alert_major_internal_o,
|
||||
output logic alert_major_bus_o,
|
||||
output logic icache_inval_o,
|
||||
output logic core_busy_o
|
||||
output logic core_busy_o,
|
||||
|
||||
// X-Interface Signals
|
||||
// Compressed Interface
|
||||
output logic x_compressed_valid_o,
|
||||
input logic x_compressed_ready_i,
|
||||
output x_compressed_req_t x_compressed_req_o,
|
||||
input x_compressed_resp_t x_compressed_resp_i
|
||||
);
|
||||
|
||||
localparam int unsigned PMP_NUM_CHAN = 3;
|
||||
|
@ -383,7 +391,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.RndCnstLfsrPerm (RndCnstLfsrPerm),
|
||||
.BranchPredictor (BranchPredictor),
|
||||
.MemECC (MemECC),
|
||||
.MemDataWidth (MemDataWidth)
|
||||
.MemDataWidth (MemDataWidth),
|
||||
.XInterface (XInterface)
|
||||
) if_stage_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni(rst_ni),
|
||||
|
@ -458,7 +467,14 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.id_in_ready_i(id_in_ready),
|
||||
|
||||
.pc_mismatch_alert_o(pc_mismatch_alert),
|
||||
.if_busy_o (if_busy)
|
||||
.if_busy_o (if_busy),
|
||||
|
||||
// commit interface signals
|
||||
.priv_mode_i (priv_mode_id),
|
||||
.x_compressed_valid_o(x_compressed_valid_o),
|
||||
.x_compressed_ready_i(x_compressed_ready_i),
|
||||
.x_compressed_req_o (x_compressed_req_o),
|
||||
.x_compressed_resp_i (x_compressed_resp_i)
|
||||
);
|
||||
|
||||
// Core is waiting for the ISide when ID/EX stage is ready for a new instruction but none are
|
||||
|
|
|
@ -27,7 +27,8 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
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 MemDataWidth = MemECC ? 32 + 7 : 32,
|
||||
parameter bit XInterface = 1'b1
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -114,7 +115,14 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
|
||||
// misc signals
|
||||
output logic pc_mismatch_alert_o,
|
||||
output logic if_busy_o // IF stage is busy fetching instr
|
||||
output logic if_busy_o, // IF stage is busy fetching instr
|
||||
|
||||
// compressed interface signals
|
||||
input priv_lvl_e priv_mode_i,
|
||||
output logic x_compressed_valid_o,
|
||||
input logic x_compressed_ready_i,
|
||||
output x_compressed_req_t x_compressed_req_o,
|
||||
input x_compressed_resp_t x_compressed_resp_i
|
||||
);
|
||||
|
||||
logic instr_valid_id_d, instr_valid_id_q;
|
||||
|
@ -139,10 +147,11 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
logic fetch_err;
|
||||
logic fetch_err_plus2;
|
||||
|
||||
logic [31:0] instr_decompressed;
|
||||
logic illegal_c_insn;
|
||||
logic [31:0] instr_decompressed, instr_decompressed_dec;
|
||||
logic illegal_c_insn, illegal_c_insn_dec;
|
||||
logic instr_is_compressed;
|
||||
|
||||
logic if_instr_comp_valid;
|
||||
logic if_instr_valid;
|
||||
logic [31:0] if_instr_rdata;
|
||||
logic [31:0] if_instr_addr;
|
||||
|
@ -173,6 +182,9 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
logic [7:0] unused_csr_mtvec;
|
||||
logic unused_exc_cause;
|
||||
|
||||
// Compressed interface offload signal
|
||||
logic stall_offl;
|
||||
|
||||
assign unused_boot_addr = boot_addr_i[7:0];
|
||||
assign unused_csr_mtvec = csr_mtvec_i[7:0];
|
||||
|
||||
|
@ -402,9 +414,9 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
.rst_ni (rst_ni),
|
||||
.valid_i (fetch_valid & ~fetch_err),
|
||||
.instr_i (if_instr_rdata),
|
||||
.instr_o (instr_decompressed),
|
||||
.instr_o (instr_decompressed_dec),
|
||||
.is_compressed_o(instr_is_compressed),
|
||||
.illegal_instr_o(illegal_c_insn)
|
||||
.illegal_instr_o(illegal_c_insn_dec)
|
||||
);
|
||||
|
||||
// Dummy instruction insertion
|
||||
|
@ -651,16 +663,17 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
// Do not branch predict on instruction errors.
|
||||
assign predict_branch_taken = predict_branch_taken_raw & ~instr_skid_valid_q & ~fetch_err;
|
||||
|
||||
assign if_instr_valid = fetch_valid | (instr_skid_valid_q & ~nt_branch_mispredict_i);
|
||||
assign if_instr_rdata = instr_skid_valid_q ? instr_skid_data_q : fetch_rdata;
|
||||
assign if_instr_addr = instr_skid_valid_q ? instr_skid_addr_q : fetch_addr;
|
||||
assign if_instr_comp_valid = fetch_valid | (instr_skid_valid_q & ~nt_branch_mispredict_i);
|
||||
assign if_instr_valid = if_instr_comp_valid & ~stall_offl;
|
||||
assign if_instr_rdata = instr_skid_valid_q ? instr_skid_data_q : fetch_rdata;
|
||||
assign if_instr_addr = instr_skid_valid_q ? instr_skid_addr_q : fetch_addr;
|
||||
|
||||
// Don't branch predict on instruction error so only instructions without errors end up in the
|
||||
// skid buffer.
|
||||
assign if_instr_bus_err = ~instr_skid_valid_q & fetch_err;
|
||||
assign instr_bp_taken_d = instr_skid_valid_q ? instr_skid_bp_taken_q : predict_branch_taken;
|
||||
|
||||
assign fetch_ready = id_in_ready_i & ~stall_dummy_instr & ~instr_skid_valid_q;
|
||||
assign fetch_ready = id_in_ready_i & ~stall_dummy_instr & ~instr_skid_valid_q & ~stall_offl;
|
||||
|
||||
assign instr_bp_taken_o = instr_bp_taken_q;
|
||||
|
||||
|
@ -671,11 +684,80 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
assign predict_branch_taken = 1'b0;
|
||||
assign predict_branch_pc = 32'b0;
|
||||
|
||||
assign if_instr_valid = fetch_valid;
|
||||
assign if_instr_rdata = fetch_rdata;
|
||||
assign if_instr_addr = fetch_addr;
|
||||
assign if_instr_bus_err = fetch_err;
|
||||
assign fetch_ready = id_in_ready_i & ~stall_dummy_instr;
|
||||
assign if_instr_comp_valid = fetch_valid;
|
||||
assign if_instr_valid = if_instr_comp_valid & ~stall_offl;
|
||||
assign if_instr_rdata = fetch_rdata;
|
||||
assign if_instr_addr = fetch_addr;
|
||||
assign if_instr_bus_err = fetch_err;
|
||||
assign fetch_ready = id_in_ready_i & ~stall_dummy_instr & ~stall_offl;
|
||||
end
|
||||
|
||||
/////////////////////////
|
||||
// X-Interface Support //
|
||||
/////////////////////////
|
||||
|
||||
if (XInterface) begin : gen_compressed_interface
|
||||
logic x_compressed_accept;
|
||||
logic x_compressed_id_bit_q, x_compressed_id_bit_d;
|
||||
logic x_compressed_id_bit_flip;
|
||||
|
||||
// Valid signal high when:
|
||||
// 1. There is a valid compressed instruction, and
|
||||
// 2. The instruction is illegal in compressed decoder.
|
||||
// According to the documentation, the handshake is a customized one.
|
||||
// When the valid signal keeps high, the accelerator should keep providing valid response.
|
||||
assign x_compressed_valid_o = if_instr_comp_valid & illegal_c_insn_dec;
|
||||
|
||||
assign stall_offl = x_compressed_valid_o & ~x_compressed_ready_i;
|
||||
assign illegal_c_insn = x_compressed_valid_o & x_compressed_ready_i &
|
||||
~x_compressed_resp_i.accept;
|
||||
assign x_compressed_accept = x_compressed_valid_o & x_compressed_ready_i &
|
||||
x_compressed_resp_i.accept;
|
||||
assign instr_decompressed = x_compressed_accept ? x_compressed_resp_i.instr :
|
||||
instr_decompressed_dec;
|
||||
|
||||
// Interface output request signals
|
||||
assign x_compressed_req_o.instr = if_instr_rdata[15:0];
|
||||
assign x_compressed_req_o.mode = priv_mode_i;
|
||||
assign x_compressed_req_o.id = {{X_ID_WIDTH-1{1'b0}}, x_compressed_id_bit_q};
|
||||
|
||||
// There will be a new instruction fetched next cycle
|
||||
// when there is a fetch handshake transaction.
|
||||
assign x_compressed_id_bit_flip = fetch_valid & fetch_ready;
|
||||
|
||||
// Next id is different from current id.
|
||||
assign x_compressed_id_bit_d = ~x_compressed_id_bit_q;
|
||||
|
||||
if (ResetAll) begin : g_xif_compressed_buffer_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
x_compressed_id_bit_q <= '0;
|
||||
end else if (x_compressed_id_bit_flip) begin
|
||||
x_compressed_id_bit_q <= x_compressed_id_bit_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_xif_compressed_buffer_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (x_compressed_id_bit_flip) begin
|
||||
x_compressed_id_bit_q <= x_compressed_id_bit_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin : gen_no_compressed_interface
|
||||
assign stall_offl = 1'b0;
|
||||
assign illegal_c_insn = illegal_c_insn_dec;
|
||||
assign instr_decompressed = instr_decompressed_dec;
|
||||
|
||||
ibex_pkg::priv_lvl_e unused_priv_mode;
|
||||
logic unused_x_compressed_ready;
|
||||
x_compressed_resp_t unused_x_compressed_resp;
|
||||
|
||||
assign unused_priv_mode = priv_mode_i;
|
||||
assign unused_x_compressed_ready = x_compressed_ready_i;
|
||||
assign unused_x_compressed_resp = x_compressed_resp_i;
|
||||
|
||||
assign x_compressed_valid_o = 1'b0;
|
||||
assign x_compressed_req_o = '0;
|
||||
end
|
||||
|
||||
////////////////
|
||||
|
|
|
@ -38,7 +38,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
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 int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -102,7 +103,12 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
input logic icache_inval_i,
|
||||
input logic core_busy_i,
|
||||
input logic test_en_i,
|
||||
input logic scan_rst_ni
|
||||
input logic scan_rst_ni,
|
||||
|
||||
input logic x_compressed_valid_i,
|
||||
input logic x_compressed_ready_i,
|
||||
input x_compressed_req_t x_compressed_req_i,
|
||||
input x_compressed_resp_t x_compressed_resp_i
|
||||
);
|
||||
|
||||
localparam int unsigned LockstepOffsetW = $clog2(LockstepOffset);
|
||||
|
@ -185,6 +191,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic debug_req;
|
||||
fetch_enable_t fetch_enable;
|
||||
logic ic_scr_key_valid;
|
||||
logic x_compressed_ready;
|
||||
x_compressed_resp_t x_compressed_resp;
|
||||
} delayed_inputs_t;
|
||||
|
||||
delayed_inputs_t [LockstepOffset-1:0] shadow_inputs_q;
|
||||
|
@ -194,24 +202,26 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic [LineSizeECC-1:0] shadow_data_rdata_q [IC_NUM_WAYS][LockstepOffset];
|
||||
|
||||
// Assign the inputs to the delay structure
|
||||
assign shadow_inputs_in.instr_gnt = instr_gnt_i;
|
||||
assign shadow_inputs_in.instr_rvalid = instr_rvalid_i;
|
||||
assign shadow_inputs_in.instr_rdata = instr_rdata_i;
|
||||
assign shadow_inputs_in.instr_err = instr_err_i;
|
||||
assign shadow_inputs_in.data_gnt = data_gnt_i;
|
||||
assign shadow_inputs_in.data_rvalid = data_rvalid_i;
|
||||
assign shadow_inputs_in.data_rdata = data_rdata_i;
|
||||
assign shadow_inputs_in.data_err = data_err_i;
|
||||
assign shadow_inputs_in.rf_rdata_a_ecc = rf_rdata_a_ecc_i;
|
||||
assign shadow_inputs_in.rf_rdata_b_ecc = rf_rdata_b_ecc_i;
|
||||
assign shadow_inputs_in.irq_software = irq_software_i;
|
||||
assign shadow_inputs_in.irq_timer = irq_timer_i;
|
||||
assign shadow_inputs_in.irq_external = irq_external_i;
|
||||
assign shadow_inputs_in.irq_fast = irq_fast_i;
|
||||
assign shadow_inputs_in.irq_nm = irq_nm_i;
|
||||
assign shadow_inputs_in.debug_req = debug_req_i;
|
||||
assign shadow_inputs_in.fetch_enable = fetch_enable_i;
|
||||
assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i;
|
||||
assign shadow_inputs_in.instr_gnt = instr_gnt_i;
|
||||
assign shadow_inputs_in.instr_rvalid = instr_rvalid_i;
|
||||
assign shadow_inputs_in.instr_rdata = instr_rdata_i;
|
||||
assign shadow_inputs_in.instr_err = instr_err_i;
|
||||
assign shadow_inputs_in.data_gnt = data_gnt_i;
|
||||
assign shadow_inputs_in.data_rvalid = data_rvalid_i;
|
||||
assign shadow_inputs_in.data_rdata = data_rdata_i;
|
||||
assign shadow_inputs_in.data_err = data_err_i;
|
||||
assign shadow_inputs_in.rf_rdata_a_ecc = rf_rdata_a_ecc_i;
|
||||
assign shadow_inputs_in.rf_rdata_b_ecc = rf_rdata_b_ecc_i;
|
||||
assign shadow_inputs_in.irq_software = irq_software_i;
|
||||
assign shadow_inputs_in.irq_timer = irq_timer_i;
|
||||
assign shadow_inputs_in.irq_external = irq_external_i;
|
||||
assign shadow_inputs_in.irq_fast = irq_fast_i;
|
||||
assign shadow_inputs_in.irq_nm = irq_nm_i;
|
||||
assign shadow_inputs_in.debug_req = debug_req_i;
|
||||
assign shadow_inputs_in.fetch_enable = fetch_enable_i;
|
||||
assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i;
|
||||
assign shadow_inputs_in.x_compressed_ready = x_compressed_ready_i;
|
||||
assign shadow_inputs_in.x_compressed_resp = x_compressed_resp_i;
|
||||
|
||||
// Delay the inputs
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
|
@ -264,6 +274,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic double_fault_seen;
|
||||
logic icache_inval;
|
||||
logic core_busy;
|
||||
logic x_compressed_valid;
|
||||
x_compressed_req_t x_compressed_req;
|
||||
} delayed_outputs_t;
|
||||
|
||||
delayed_outputs_t [OutputsOffset-1:0] core_outputs_q;
|
||||
|
@ -297,6 +309,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
assign core_outputs_in.double_fault_seen = double_fault_seen_i;
|
||||
assign core_outputs_in.icache_inval = icache_inval_i;
|
||||
assign core_outputs_in.core_busy = core_busy_i;
|
||||
assign core_outputs_in.x_compressed_valid = x_compressed_valid_i;
|
||||
assign core_outputs_in.x_compressed_req = x_compressed_req_i;
|
||||
|
||||
// Delay the outputs
|
||||
always_ff @(posedge clk_i) begin
|
||||
|
@ -341,7 +355,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.MemECC ( MemECC ),
|
||||
.MemDataWidth ( MemDataWidth ),
|
||||
.DmHaltAddr ( DmHaltAddr ),
|
||||
.DmExceptionAddr ( DmExceptionAddr )
|
||||
.DmExceptionAddr ( DmExceptionAddr ),
|
||||
.XInterface ( XInterface )
|
||||
) u_shadow_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_shadow_n),
|
||||
|
@ -433,7 +448,12 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.alert_major_internal_o (shadow_alert_major_internal),
|
||||
.alert_major_bus_o (shadow_alert_major_bus),
|
||||
.icache_inval_o (shadow_outputs_d.icache_inval),
|
||||
.core_busy_o (shadow_outputs_d.core_busy)
|
||||
.core_busy_o (shadow_outputs_d.core_busy),
|
||||
|
||||
.x_compressed_valid_o (shadow_outputs_d.x_compressed_valid),
|
||||
.x_compressed_ready_i (shadow_inputs_q[0].x_compressed_ready),
|
||||
.x_compressed_req_o (shadow_outputs_d.x_compressed_req),
|
||||
.x_compressed_resp_i (shadow_inputs_q[0].x_compressed_resp)
|
||||
);
|
||||
|
||||
// Register the shadow core outputs
|
||||
|
|
|
@ -650,4 +650,23 @@ package ibex_pkg;
|
|||
// `ibex_core` may need adjusting.
|
||||
parameter fetch_enable_t FetchEnableOn = 4'b1001;
|
||||
parameter fetch_enable_t FetchEnableOff = 4'b0110;
|
||||
|
||||
////////////////
|
||||
// CORE_V_XIF //
|
||||
////////////////
|
||||
// Documentation page: https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/en/latest/
|
||||
|
||||
parameter int X_ID_WIDTH = 4;
|
||||
|
||||
typedef struct packed {
|
||||
logic [15:0] instr;
|
||||
priv_lvl_e mode;
|
||||
logic [X_ID_WIDTH-1:0] id;
|
||||
} x_compressed_req_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [31:0] instr;
|
||||
logic accept;
|
||||
} x_compressed_resp_t;
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -35,6 +35,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1,
|
||||
// Default seed and nonce for scrambling
|
||||
parameter logic [SCRAMBLE_KEY_W-1:0] RndCnstIbexKey = RndCnstIbexKeyDefault,
|
||||
parameter logic [SCRAMBLE_NONCE_W-1:0] RndCnstIbexNonce = RndCnstIbexNonceDefault
|
||||
|
@ -130,7 +131,14 @@ module ibex_top import ibex_pkg::*; #(
|
|||
output logic core_sleep_o,
|
||||
|
||||
// DFT bypass controls
|
||||
input logic scan_rst_ni
|
||||
input logic scan_rst_ni,
|
||||
|
||||
// X-Interface Signals
|
||||
// Compressed Interface
|
||||
output logic x_compressed_valid_o,
|
||||
input logic x_compressed_ready_i,
|
||||
output x_compressed_req_t x_compressed_req_o,
|
||||
input x_compressed_resp_t x_compressed_resp_i
|
||||
);
|
||||
|
||||
localparam bit Lockstep = SecureIbex;
|
||||
|
@ -278,7 +286,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.MemECC (MemECC),
|
||||
.MemDataWidth (MemDataWidth),
|
||||
.DmHaltAddr (DmHaltAddr),
|
||||
.DmExceptionAddr (DmExceptionAddr)
|
||||
.DmExceptionAddr (DmExceptionAddr),
|
||||
.XInterface (XInterface)
|
||||
) u_ibex_core (
|
||||
.clk_i(clk),
|
||||
.rst_ni,
|
||||
|
@ -370,7 +379,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.alert_major_internal_o(core_alert_major_internal),
|
||||
.alert_major_bus_o (core_alert_major_bus),
|
||||
.icache_inval_o (icache_inval),
|
||||
.core_busy_o (core_busy_d)
|
||||
.core_busy_o (core_busy_d),
|
||||
|
||||
.x_compressed_valid_o,
|
||||
.x_compressed_ready_i,
|
||||
.x_compressed_req_o,
|
||||
.x_compressed_resp_i
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
|
@ -655,6 +669,10 @@ module ibex_top import ibex_pkg::*; #(
|
|||
double_fault_seen_o,
|
||||
fetch_enable_i,
|
||||
icache_inval,
|
||||
x_compressed_valid_o,
|
||||
x_compressed_ready_i,
|
||||
x_compressed_req_o,
|
||||
x_compressed_resp_i,
|
||||
core_busy_d
|
||||
});
|
||||
|
||||
|
@ -714,6 +732,11 @@ module ibex_top import ibex_pkg::*; #(
|
|||
logic icache_inval_local;
|
||||
logic core_busy_local;
|
||||
|
||||
logic x_compressed_valid_local;
|
||||
logic x_compressed_ready_local;
|
||||
x_compressed_req_t x_compressed_req_local;
|
||||
x_compressed_resp_t x_compressed_resp_local;
|
||||
|
||||
assign buf_in = {
|
||||
hart_id_i,
|
||||
boot_addr_i,
|
||||
|
@ -760,6 +783,10 @@ module ibex_top import ibex_pkg::*; #(
|
|||
double_fault_seen_o,
|
||||
fetch_enable_i,
|
||||
icache_inval,
|
||||
x_compressed_valid_o,
|
||||
x_compressed_ready_i,
|
||||
x_compressed_req_o,
|
||||
x_compressed_resp_i,
|
||||
core_busy_d
|
||||
};
|
||||
|
||||
|
@ -809,6 +836,10 @@ module ibex_top import ibex_pkg::*; #(
|
|||
double_fault_seen_local,
|
||||
fetch_enable_local,
|
||||
icache_inval_local,
|
||||
x_compressed_valid_local,
|
||||
x_compressed_ready_local,
|
||||
x_compressed_req_local,
|
||||
x_compressed_resp_local,
|
||||
core_busy_local
|
||||
} = buf_out;
|
||||
|
||||
|
@ -862,7 +893,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.RegFileDataWidth (RegFileDataWidth),
|
||||
.MemECC (MemECC),
|
||||
.DmHaltAddr (DmHaltAddr),
|
||||
.DmExceptionAddr (DmExceptionAddr)
|
||||
.DmExceptionAddr (DmExceptionAddr),
|
||||
.XInterface (XInterface)
|
||||
) u_ibex_lockstep (
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -926,7 +958,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.icache_inval_i (icache_inval_local),
|
||||
.core_busy_i (core_busy_local),
|
||||
.test_en_i (test_en_i),
|
||||
.scan_rst_ni (scan_rst_ni)
|
||||
.scan_rst_ni (scan_rst_ni),
|
||||
|
||||
.x_compressed_valid_i (x_compressed_valid_local),
|
||||
.x_compressed_ready_i (x_compressed_ready_local),
|
||||
.x_compressed_req_i (x_compressed_req_local),
|
||||
.x_compressed_resp_i (x_compressed_resp_local)
|
||||
);
|
||||
|
||||
prim_buf u_prim_buf_alert_minor (
|
||||
|
|
|
@ -28,7 +28,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -87,8 +88,13 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
output logic alert_minor_o,
|
||||
output logic alert_major_internal_o,
|
||||
output logic alert_major_bus_o,
|
||||
output logic core_sleep_o
|
||||
output logic core_sleep_o,
|
||||
|
||||
// X-Interface Signals
|
||||
output logic x_compressed_valid_o,
|
||||
input logic x_compressed_ready_i,
|
||||
output x_compressed_req_t x_compressed_req_o,
|
||||
input x_compressed_resp_t x_compressed_resp_i
|
||||
);
|
||||
|
||||
// ibex_tracer relies on the signals from the RISC-V Formal Interface
|
||||
|
@ -158,7 +164,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
|
||||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.DmHaltAddr ( DmHaltAddr ),
|
||||
.DmExceptionAddr ( DmExceptionAddr )
|
||||
.DmExceptionAddr ( DmExceptionAddr ),
|
||||
.XInterface ( XInterface )
|
||||
) u_ibex_top (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -237,7 +244,12 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.alert_minor_o,
|
||||
.alert_major_internal_o,
|
||||
.alert_major_bus_o,
|
||||
.core_sleep_o
|
||||
.core_sleep_o,
|
||||
|
||||
.x_compressed_valid_o,
|
||||
.x_compressed_ready_i,
|
||||
.x_compressed_req_o,
|
||||
.x_compressed_resp_i
|
||||
);
|
||||
|
||||
ibex_tracer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue