[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:
Hailin 2022-05-04 09:20:20 +02:00 committed by Pirmin Vogel
parent 0a9f5ed1da
commit d533faf086
16 changed files with 364 additions and 56 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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
////////////////

View file

@ -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

View file

@ -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

View file

@ -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 (

View file

@ -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