mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[rtl] Add memory and memory result interfaces
This commit adds memory interface and memory result interface of the RISC-V Extension Interface.
This commit is contained in:
parent
8ad0d7c9d4
commit
129af7a53b
21 changed files with 698 additions and 81 deletions
|
@ -113,6 +113,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
sim:
|
||||
default_tool: verilator
|
||||
|
@ -135,6 +141,7 @@ targets:
|
|||
- SecureIbex
|
||||
- ICacheScramble
|
||||
- XInterface
|
||||
- MemInterface
|
||||
toplevel: ibex_riscv_compliance
|
||||
tools:
|
||||
verilator:
|
||||
|
|
|
@ -152,7 +152,8 @@ module ibex_riscv_compliance (
|
|||
.ICacheScramble (ICacheScramble ),
|
||||
.DmHaltAddr (32'h00000000 ),
|
||||
.DmExceptionAddr (32'h00000000 ),
|
||||
.XInterface (XInterface )
|
||||
.XInterface (XInterface ),
|
||||
.MemInterface (MemInterface )
|
||||
) u_top (
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
|
@ -216,6 +217,12 @@ module ibex_riscv_compliance (
|
|||
.x_issue_resp_i ('0 ),
|
||||
.x_commit_valid_o ( ),
|
||||
.x_commit_o ( ),
|
||||
.x_mem_valid_i (1'b0 ),
|
||||
.x_mem_ready_o ( ),
|
||||
.x_mem_req_i ('0 ),
|
||||
.x_mem_resp_o ( ),
|
||||
.x_mem_result_valid_o ( ),
|
||||
.x_mem_result_o ( ),
|
||||
.x_result_valid_i (1'b0 ),
|
||||
.x_result_ready_o ( ),
|
||||
.x_result_i ('0 )
|
||||
|
|
|
@ -66,6 +66,7 @@ module core_ibex_tb_top;
|
|||
parameter bit SecureIbex = 1'b0;
|
||||
parameter bit ICacheScramble = 1'b0;
|
||||
parameter bit XInterface = 1'b1;
|
||||
parameter bit MemInterface = 1'b1;
|
||||
|
||||
ibex_top_tracing #(
|
||||
.DmHaltAddr (32'h`BOOT_ADDR + 'h0 ),
|
||||
|
@ -84,7 +85,8 @@ module core_ibex_tb_top;
|
|||
.SecureIbex (SecureIbex ),
|
||||
.ICacheScramble (ICacheScramble ),
|
||||
.BranchPredictor (BranchPredictor ),
|
||||
.XInterface (XInterface )
|
||||
.XInterface (XInterface ),
|
||||
.MemInterface (MemInterface )
|
||||
) dut (
|
||||
.clk_i (clk ),
|
||||
.rst_ni (rst_n ),
|
||||
|
@ -147,6 +149,12 @@ module core_ibex_tb_top;
|
|||
.x_issue_resp_i ('0 ),
|
||||
.x_commit_valid_o ( ),
|
||||
.x_commit_o ( ),
|
||||
.x_mem_valid_i (1'b0 ),
|
||||
.x_mem_ready_o ( ),
|
||||
.x_mem_req_i ('0 ),
|
||||
.x_mem_resp_o ( ),
|
||||
.x_mem_result_valid_o ( ),
|
||||
.x_mem_result_o ( ),
|
||||
.x_result_valid_i (1'b0 ),
|
||||
.x_result_ready_o ( ),
|
||||
.x_result_i ('0 )
|
||||
|
|
|
@ -112,6 +112,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -134,6 +140,7 @@ targets:
|
|||
- ICacheScramble
|
||||
- SRAMInitFile
|
||||
- XInterface
|
||||
- MemInterface
|
||||
|
||||
lint:
|
||||
<<: *default_target
|
||||
|
|
|
@ -108,6 +108,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -130,6 +136,7 @@ targets:
|
|||
- PMPNumRegions
|
||||
- SRAMInitFile
|
||||
- XInterface
|
||||
- MemInterface
|
||||
|
||||
lint:
|
||||
<<: *default_target
|
||||
|
|
|
@ -51,6 +51,7 @@ module ibex_simple_system (
|
|||
parameter bit BranchPredictor = 1'b0;
|
||||
parameter SRAMInitFile = "";
|
||||
parameter bit XInterface = 1'b1;
|
||||
parameter bit MemInterface = 1'b1;
|
||||
|
||||
logic clk_sys = 1'b0, rst_sys_n;
|
||||
|
||||
|
@ -202,7 +203,8 @@ module ibex_simple_system (
|
|||
.BranchPredictor ( BranchPredictor ),
|
||||
.DmHaltAddr ( 32'h00100000 ),
|
||||
.DmExceptionAddr ( 32'h00100000 ),
|
||||
.XInterface ( XInterface )
|
||||
.XInterface ( XInterface ),
|
||||
.MemInterface ( MemInterface )
|
||||
) u_top (
|
||||
.clk_i (clk_sys),
|
||||
.rst_ni (rst_sys_n),
|
||||
|
@ -266,6 +268,12 @@ module ibex_simple_system (
|
|||
.x_issue_resp_i ('0),
|
||||
.x_commit_valid_o (),
|
||||
.x_commit_o (),
|
||||
.x_mem_valid_i (1'b0),
|
||||
.x_mem_ready_o (),
|
||||
.x_mem_req_i ('0),
|
||||
.x_mem_resp_o (),
|
||||
.x_mem_result_valid_o (),
|
||||
.x_mem_result_o (),
|
||||
.x_result_valid_i (1'b0),
|
||||
.x_result_ready_o (),
|
||||
.x_result_i ('0)
|
||||
|
|
|
@ -23,6 +23,7 @@ small:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# Configuration to match that used in the OpenTitan project
|
||||
opentitan:
|
||||
|
@ -41,6 +42,7 @@ opentitan:
|
|||
SecureIbex : 1
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# ===============================
|
||||
# * EXPERIMENTAL CONFIGURATIONS *
|
||||
|
@ -65,6 +67,7 @@ experimental-maxperf:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# experimental-maxperf config above plus PMP enabled with 16 regions.
|
||||
experimental-maxperf-pmp:
|
||||
|
@ -83,6 +86,7 @@ experimental-maxperf-pmp:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp config above with balanced bitmanip extension
|
||||
experimental-maxperf-pmp-bmbalanced:
|
||||
|
@ -101,6 +105,7 @@ experimental-maxperf-pmp-bmbalanced:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp config above with full bitmanip extension
|
||||
experimental-maxperf-pmp-bmfull:
|
||||
|
@ -119,6 +124,7 @@ experimental-maxperf-pmp-bmfull:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# experimental-maxperf-pmp-bmfull config above with icache enabled
|
||||
experimental-maxperf-pmp-bmfull-icache:
|
||||
|
@ -137,6 +143,7 @@ experimental-maxperf-pmp-bmfull-icache:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 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
|
||||
|
@ -158,6 +165,7 @@ experimental-branch-predictor:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 0
|
||||
MemInterface : 0
|
||||
|
||||
# Small with X-Interface
|
||||
small-cvxif:
|
||||
|
@ -176,6 +184,7 @@ small-cvxif:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
MemInterface : 1
|
||||
|
||||
# Opentitan with X-Interface
|
||||
opentitan-cvxif:
|
||||
|
@ -194,6 +203,7 @@ opentitan-cvxif:
|
|||
SecureIbex : 1
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
MemInterface : 1
|
||||
|
||||
# experimental-maxperf-pmp config with X-Interface
|
||||
experimental-maxperf-pmp-bmfull-cvxif:
|
||||
|
@ -212,3 +222,4 @@ experimental-maxperf-pmp-bmfull-cvxif:
|
|||
SecureIbex : 0
|
||||
ICacheScramble : 0
|
||||
XInterface : 1
|
||||
MemInterface : 1
|
||||
|
|
|
@ -150,6 +150,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
|
|
@ -138,6 +138,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
|
|
@ -113,6 +113,12 @@ parameters:
|
|||
paramtype: vlogparam
|
||||
description: "Enables the RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
MemInterface:
|
||||
datatype: int
|
||||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enables Memory and Memory Result Interfaces for RISC-V Extension Interface (EXPERIMENTAL) [0/1]"
|
||||
|
||||
targets:
|
||||
default: &default_target
|
||||
filesets:
|
||||
|
@ -141,6 +147,7 @@ targets:
|
|||
- PMPGranularity
|
||||
- PMPNumRegions
|
||||
- XInterface
|
||||
- MemInterface
|
||||
default_tool: verilator
|
||||
tools:
|
||||
verilator:
|
||||
|
|
|
@ -29,7 +29,9 @@ module ibex_alu #(
|
|||
|
||||
output logic [31:0] result_o,
|
||||
output logic comparison_result_o,
|
||||
output logic is_equal_result_o
|
||||
output logic is_equal_result_o,
|
||||
|
||||
input logic x_mem_lsu_req_i
|
||||
);
|
||||
import ibex_pkg::*;
|
||||
|
||||
|
@ -82,23 +84,31 @@ module ibex_alu #(
|
|||
|
||||
// prepare operand a
|
||||
always_comb begin
|
||||
unique case(1'b1)
|
||||
multdiv_sel_i: adder_in_a = multdiv_operand_a_i;
|
||||
adder_op_a_shift1: adder_in_a = {operand_a_i[30:0],2'b01};
|
||||
adder_op_a_shift2: adder_in_a = {operand_a_i[29:0],3'b001};
|
||||
adder_op_a_shift3: adder_in_a = {operand_a_i[28:0],4'b0001};
|
||||
default: adder_in_a = {operand_a_i,1'b1};
|
||||
endcase
|
||||
if (x_mem_lsu_req_i) begin
|
||||
adder_in_a = {operand_a_i,1'b1};
|
||||
end else begin
|
||||
unique case(1'b1)
|
||||
multdiv_sel_i: adder_in_a = multdiv_operand_a_i;
|
||||
adder_op_a_shift1: adder_in_a = {operand_a_i[30:0],2'b01};
|
||||
adder_op_a_shift2: adder_in_a = {operand_a_i[29:0],3'b001};
|
||||
adder_op_a_shift3: adder_in_a = {operand_a_i[28:0],4'b0001};
|
||||
default: adder_in_a = {operand_a_i,1'b1};
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// prepare operand b
|
||||
assign operand_b_neg = {operand_b_i,1'b0} ^ {33{1'b1}};
|
||||
always_comb begin
|
||||
unique case (1'b1)
|
||||
multdiv_sel_i: adder_in_b = multdiv_operand_b_i;
|
||||
adder_op_b_negate: adder_in_b = operand_b_neg;
|
||||
default: adder_in_b = {operand_b_i, 1'b0};
|
||||
endcase
|
||||
if (x_mem_lsu_req_i) begin
|
||||
adder_in_b = {operand_b_i, 1'b0};
|
||||
end else begin
|
||||
unique case (1'b1)
|
||||
multdiv_sel_i: adder_in_b = multdiv_operand_b_i;
|
||||
adder_op_b_negate: adder_in_b = operand_b_neg;
|
||||
default: adder_in_b = {operand_b_i, 1'b0};
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// actual adder
|
||||
|
|
|
@ -43,7 +43,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1
|
||||
parameter bit XInterface = 1'b1,
|
||||
parameter bit MemInterface = 1'b0
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -165,6 +166,14 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// Commit Interface
|
||||
output logic x_commit_valid_o,
|
||||
output x_commit_t x_commit_o,
|
||||
// Memory Interface
|
||||
input logic x_mem_valid_i,
|
||||
output logic x_mem_ready_o,
|
||||
input x_mem_req_t x_mem_req_i,
|
||||
output x_mem_resp_t x_mem_resp_o,
|
||||
// Memory Result Interface
|
||||
output logic x_mem_result_valid_o,
|
||||
output x_mem_result_t x_mem_result_o,
|
||||
// Result Interface
|
||||
input logic x_result_valid_i,
|
||||
output logic x_result_ready_o,
|
||||
|
@ -226,6 +235,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// LSU signals
|
||||
logic lsu_addr_incr_req;
|
||||
logic [31:0] lsu_addr_last;
|
||||
logic [3:0] lsu_x_mem_be;
|
||||
|
||||
// Jump and branch target and decision (EX->IF)
|
||||
logic [31:0] branch_target_ex;
|
||||
|
@ -296,6 +306,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic lsu_we;
|
||||
logic [1:0] lsu_type;
|
||||
logic lsu_sign_ext;
|
||||
logic lsu_rdata_valid;
|
||||
logic lsu_req;
|
||||
logic [31:0] lsu_wdata;
|
||||
logic lsu_req_done;
|
||||
|
@ -318,6 +329,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic rf_write_wb;
|
||||
logic outstanding_load_wb;
|
||||
logic outstanding_store_wb;
|
||||
logic outstanding_xif_load_store;
|
||||
|
||||
// Interrupts
|
||||
logic nmi_mode;
|
||||
|
@ -343,6 +355,9 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic [31:0] csr_mtval;
|
||||
logic csr_mstatus_tw;
|
||||
priv_lvl_e priv_mode_id;
|
||||
priv_lvl_e priv_mode_lsu_csr;
|
||||
priv_lvl_e priv_mode_lsu_xif;
|
||||
logic priv_mode_lsu_xif_en;
|
||||
priv_lvl_e priv_mode_lsu;
|
||||
|
||||
// debug mode and dcsr configuration
|
||||
|
@ -375,6 +390,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic perf_load;
|
||||
logic perf_store;
|
||||
|
||||
logic x_mem_lsu_req;
|
||||
logic [4:0] instr_rs1;
|
||||
logic [4:0] instr_rs2;
|
||||
logic [4:0] instr_rs3;
|
||||
|
@ -538,8 +554,10 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.DataIndTiming (DataIndTiming),
|
||||
.WritebackStage (WritebackStage),
|
||||
.BranchPredictor(BranchPredictor),
|
||||
.ResetAll (ResetAll),
|
||||
.MemECC (MemECC),
|
||||
.XInterface (XInterface)
|
||||
.XInterface (XInterface),
|
||||
.MemInterface (MemInterface)
|
||||
) id_stage_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni(rst_ni),
|
||||
|
@ -625,6 +643,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.lsu_type_o (lsu_type), // to load store unit
|
||||
.lsu_sign_ext_o(lsu_sign_ext), // to load store unit
|
||||
.lsu_wdata_o (lsu_wdata), // to load store unit
|
||||
.lsu_rdata_i (rf_wdata_lsu),
|
||||
.lsu_x_mem_be_o(lsu_x_mem_be),
|
||||
.lsu_req_done_i(lsu_req_done), // from load store unit
|
||||
|
||||
.lsu_addr_incr_req_i(lsu_addr_incr_req),
|
||||
|
@ -700,6 +720,10 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.ecs_wr_o (ecs_wr),
|
||||
.ecs_wen_o(ecs_wen),
|
||||
|
||||
// X-Interface LSU privilege signal, to PMP
|
||||
.priv_mode_lsu_xif_o (priv_mode_lsu_xif),
|
||||
.priv_mode_lsu_xif_en_o(priv_mode_lsu_xif_en),
|
||||
|
||||
// Issue Interface
|
||||
.x_issue_valid_o(x_issue_valid_o),
|
||||
.x_issue_ready_i(x_issue_ready_i),
|
||||
|
@ -710,10 +734,26 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.x_commit_valid_o(x_commit_valid_o),
|
||||
.x_commit_o (x_commit_o),
|
||||
|
||||
// Memory Interface
|
||||
.x_mem_valid_i(x_mem_valid_i),
|
||||
.x_mem_ready_o(x_mem_ready_o),
|
||||
.x_mem_req_i (x_mem_req_i),
|
||||
.x_mem_resp_o (x_mem_resp_o),
|
||||
|
||||
// Memory Result Interface
|
||||
.x_mem_result_valid_o(x_mem_result_valid_o),
|
||||
.x_mem_result_o (x_mem_result_o),
|
||||
|
||||
// Result Interface
|
||||
.x_result_valid_i(x_result_valid_i),
|
||||
.x_result_ready_o(x_result_ready_o),
|
||||
.x_result_i (x_result_i)
|
||||
.x_result_i (x_result_i),
|
||||
|
||||
// To ex block
|
||||
.x_mem_lsu_req_o(x_mem_lsu_req),
|
||||
|
||||
// Only for assertion
|
||||
.outstanding_xif_load_store_o(outstanding_xif_load_store)
|
||||
);
|
||||
|
||||
assign icache_inval_o = icache_inval;
|
||||
|
@ -755,6 +795,9 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.imd_val_d_o (imd_val_d_ex),
|
||||
.imd_val_q_i (imd_val_q_ex),
|
||||
|
||||
// From ID
|
||||
.x_mem_lsu_req_i(x_mem_lsu_req),
|
||||
|
||||
// Outputs
|
||||
.alu_adder_result_ex_o(alu_adder_result_ex), // to LSU
|
||||
.result_ex_o (result_ex), // to ID
|
||||
|
@ -771,6 +814,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
|
||||
assign data_req_o = data_req_out & ~pmp_req_err[PMP_D];
|
||||
assign lsu_resp_err = lsu_load_err | lsu_store_err;
|
||||
assign rf_we_lsu = lsu_rdata_valid & ~x_mem_result_valid_o;
|
||||
|
||||
ibex_load_store_unit #(
|
||||
.MemECC(MemECC),
|
||||
|
@ -797,9 +841,10 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.lsu_type_i (lsu_type),
|
||||
.lsu_wdata_i (lsu_wdata),
|
||||
.lsu_sign_ext_i(lsu_sign_ext),
|
||||
.lsu_x_mem_be_i(lsu_x_mem_be),
|
||||
|
||||
.lsu_rdata_o (rf_wdata_lsu),
|
||||
.lsu_rdata_valid_o(rf_we_lsu),
|
||||
.lsu_rdata_valid_o(lsu_rdata_valid),
|
||||
.lsu_req_i (lsu_req),
|
||||
.lsu_req_done_o (lsu_req_done),
|
||||
|
||||
|
@ -981,9 +1026,13 @@ module ibex_core import ibex_pkg::*; #(
|
|||
end
|
||||
|
||||
`ASSERT(NoMemResponseWithoutPendingAccess,
|
||||
data_rvalid_i |-> outstanding_load_resp | outstanding_store_resp, clk_i, !rst_ni)
|
||||
data_rvalid_i |-> outstanding_load_resp | outstanding_store_resp | outstanding_xif_load_store,
|
||||
clk_i, !rst_ni)
|
||||
`endif
|
||||
|
||||
logic unused_outstanding_xif_load_store;
|
||||
assign unused_outstanding_xif_load_store = outstanding_xif_load_store;
|
||||
|
||||
////////////////////////
|
||||
// RF (Register File) //
|
||||
////////////////////////
|
||||
|
@ -1021,7 +1070,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// Hart ID from outside
|
||||
.hart_id_i (hart_id_i),
|
||||
.priv_mode_id_o (priv_mode_id),
|
||||
.priv_mode_lsu_o(priv_mode_lsu),
|
||||
.priv_mode_lsu_o(priv_mode_lsu_csr),
|
||||
|
||||
// mtvec
|
||||
.csr_mtvec_o (csr_mtvec),
|
||||
|
@ -1108,6 +1157,9 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.ecs_wen_i(ecs_wen)
|
||||
);
|
||||
|
||||
// Multiplex between external and internal signals
|
||||
assign priv_mode_lsu = priv_mode_lsu_xif_en ? priv_mode_lsu_xif : priv_mode_lsu_csr;
|
||||
|
||||
// These assertions are in top-level as instr_valid_id required as the enable term
|
||||
`ASSERT(IbexCsrOpValid, instr_valid_id |-> csr_op inside {
|
||||
CSR_OP_READ,
|
||||
|
|
|
@ -44,6 +44,9 @@ module ibex_ex_block #(
|
|||
output logic [33:0] imd_val_d_o[2],
|
||||
input logic [33:0] imd_val_q_i[2],
|
||||
|
||||
// From ID stage
|
||||
input logic x_mem_lsu_req_i,
|
||||
|
||||
// Outputs
|
||||
output logic [31:0] alu_adder_result_ex_o, // to LSU
|
||||
output logic [31:0] result_ex_o,
|
||||
|
@ -130,7 +133,8 @@ module ibex_ex_block #(
|
|||
.adder_result_ext_o (alu_adder_result_ext),
|
||||
.result_o (alu_result),
|
||||
.comparison_result_o(alu_cmp_result),
|
||||
.is_equal_result_o (alu_is_equal_result)
|
||||
.is_equal_result_o (alu_is_equal_result),
|
||||
.x_mem_lsu_req_i (x_mem_lsu_req_i)
|
||||
);
|
||||
|
||||
////////////////
|
||||
|
|
|
@ -25,8 +25,10 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
parameter bit BranchTargetALU = 0,
|
||||
parameter bit WritebackStage = 0,
|
||||
parameter bit BranchPredictor = 0,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter bit MemECC = 1'b0,
|
||||
parameter bit XInterface = 1'b1
|
||||
parameter bit XInterface = 1'b1,
|
||||
parameter bit MemInterface = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -122,6 +124,8 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
|
||||
input logic lsu_addr_incr_req_i,
|
||||
input logic [31:0] lsu_addr_last_i,
|
||||
input logic [31:0] lsu_rdata_i,
|
||||
output logic [3:0] lsu_x_mem_be_o,
|
||||
|
||||
// Interrupt signals
|
||||
input logic csr_mstatus_mie_i,
|
||||
|
@ -199,6 +203,10 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
output logic [5:0] ecs_wr_o,
|
||||
output logic [2:0] ecs_wen_o,
|
||||
|
||||
// Privilege mode output
|
||||
output ibex_pkg::priv_lvl_e priv_mode_lsu_xif_o,
|
||||
output logic priv_mode_lsu_xif_en_o,
|
||||
|
||||
// Issue Interface
|
||||
output logic x_issue_valid_o,
|
||||
input logic x_issue_ready_i,
|
||||
|
@ -209,10 +217,26 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
output logic x_commit_valid_o,
|
||||
output x_commit_t x_commit_o,
|
||||
|
||||
// Memory Interface
|
||||
input logic x_mem_valid_i,
|
||||
output logic x_mem_ready_o,
|
||||
input x_mem_req_t x_mem_req_i,
|
||||
output x_mem_resp_t x_mem_resp_o,
|
||||
|
||||
// Memory Result Interface
|
||||
output logic x_mem_result_valid_o,
|
||||
output x_mem_result_t x_mem_result_o,
|
||||
|
||||
// Result Interface
|
||||
input logic x_result_valid_i,
|
||||
output logic x_result_ready_o,
|
||||
input x_result_t x_result_i
|
||||
input x_result_t x_result_i,
|
||||
|
||||
// To ex block
|
||||
output logic x_mem_lsu_req_o,
|
||||
|
||||
// For assertion only
|
||||
output logic outstanding_xif_load_store_o
|
||||
);
|
||||
|
||||
// Decoder/Controller, ID stage internal signals
|
||||
|
@ -274,6 +298,11 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
logic x_result_err;
|
||||
logic rf_rd_a_match_xif;
|
||||
logic rf_rd_b_match_xif;
|
||||
logic x_mem_load_err;
|
||||
logic x_mem_store_err;
|
||||
logic x_mem_lsu_req;
|
||||
|
||||
assign x_mem_lsu_req_o = x_mem_lsu_req;
|
||||
|
||||
// Immediate decoding and sign extension
|
||||
logic [31:0] imm_i_type;
|
||||
|
@ -677,9 +706,9 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
|
||||
// LSU
|
||||
.lsu_addr_last_i(lsu_addr_last_i),
|
||||
.load_err_i (lsu_load_err_i),
|
||||
.load_err_i (lsu_load_err_i | x_mem_load_err),
|
||||
.load_intg_err_i(lsu_load_intg_err_i),
|
||||
.store_err_i (lsu_store_err_i),
|
||||
.store_err_i (lsu_store_err_i | x_mem_store_err),
|
||||
.wb_exception_o (wb_exception),
|
||||
.id_exception_o (id_exception),
|
||||
|
||||
|
@ -729,17 +758,13 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
.x_result_exccode_i (x_result_exccode)
|
||||
);
|
||||
|
||||
assign multdiv_en_dec = mult_en_dec | div_en_dec;
|
||||
assign multdiv_en_dec = mult_en_dec | div_en_dec;
|
||||
|
||||
assign lsu_req_o = x_mem_lsu_req | lsu_req;
|
||||
assign lsu_req = instr_executing ? data_req_allowed & lsu_req_dec : 1'b0;
|
||||
assign mult_en_id = instr_executing ? mult_en_dec : 1'b0;
|
||||
assign div_en_id = instr_executing ? div_en_dec : 1'b0;
|
||||
|
||||
assign lsu_req_o = lsu_req;
|
||||
assign lsu_we_o = lsu_we;
|
||||
assign lsu_type_o = lsu_type;
|
||||
assign lsu_sign_ext_o = lsu_sign_ext;
|
||||
assign lsu_wdata_o = rf_rdata_b_fwd;
|
||||
// csr_op_en_o is set when CSR access should actually happen.
|
||||
// csv_access_o is set when CSR access instruction is present and is used to compute whether a CSR
|
||||
// access is illegal. A combinational loop would be created if csr_op_en_o was used along (as
|
||||
|
@ -747,8 +772,6 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
assign csr_op_en_o = csr_access_o & instr_executing & instr_id_internal_done_o;
|
||||
|
||||
assign alu_operator_ex_o = alu_operator;
|
||||
assign alu_operand_a_ex_o = alu_operand_a;
|
||||
assign alu_operand_b_ex_o = alu_operand_b;
|
||||
|
||||
assign mult_en_ex_o = mult_en_id;
|
||||
assign div_en_ex_o = div_en_id;
|
||||
|
@ -1222,15 +1245,19 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
// respond signals
|
||||
logic x_issue_wb;
|
||||
logic x_issue_exc;
|
||||
logic unused_x_issue_ls;
|
||||
logic x_issue_ls;
|
||||
logic unused_x_issue_ecsw;
|
||||
logic unused_x_issue_dw;
|
||||
logic unused_x_issue_dr;
|
||||
// For candidate signal
|
||||
logic mem_xif;
|
||||
|
||||
// An valid instruction is an offload candidate for issue interface when:
|
||||
// 1. It can not be recognized by the decoder, or
|
||||
// 2. It access an illegal address in CSR.
|
||||
assign x_issue_candidate = illegal_insn_dec | illegal_csr_insn_i;
|
||||
// Both csr addr and external memory instruction use the same adder,
|
||||
// csr instruction is illegal only if there will not be any external memory instruction.
|
||||
assign x_issue_candidate = illegal_insn_dec | (illegal_csr_insn_i & ~mem_xif);
|
||||
|
||||
assign x_issue_valid_candidate = instr_valid_i & x_issue_candidate &
|
||||
~instr_fetch_err_i & ~wb_exception & controller_run;
|
||||
|
@ -1259,7 +1286,7 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
assign x_issue_reject = x_issue_handshake & ~x_issue_resp_i.accept;
|
||||
assign x_issue_wb = x_issue_resp_i.writeback;
|
||||
assign x_issue_exc = x_issue_resp_i.exc;
|
||||
assign unused_x_issue_ls = x_issue_resp_i.loadstore;
|
||||
assign x_issue_ls = x_issue_resp_i.loadstore;
|
||||
assign unused_x_issue_ecsw = x_issue_resp_i.ecswrite;
|
||||
assign unused_x_issue_dw = x_issue_resp_i.dualwrite;
|
||||
assign unused_x_issue_dr = x_issue_resp_i.dualread;
|
||||
|
@ -1364,13 +1391,275 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
|
||||
assign unused_x_result_dbg = x_result_i.dbg;
|
||||
|
||||
////////////////////////////////////////
|
||||
// Memory and Memory Result Interface //
|
||||
////////////////////////////////////////
|
||||
|
||||
// Scoreboard Signals
|
||||
logic [X_ID_WIDTH-1:0] x_mem_id_d;
|
||||
logic x_mem_commit;
|
||||
logic x_mem_result_fin;
|
||||
logic [X_ID_WIDTH-1:0] x_mem_result_id;
|
||||
logic x_mem_result_err;
|
||||
|
||||
if (MemInterface) begin : gen_mem_interface
|
||||
logic [31:0] x_mem_addr;
|
||||
logic x_mem_we;
|
||||
logic [2:0] x_mem_size;
|
||||
logic [1:0] x_mem_type;
|
||||
logic [X_MEM_WIDTH/8-1:0] x_mem_be;
|
||||
logic [1:0] unused_mem_attr;
|
||||
logic [X_MEM_WIDTH-1:0] x_mem_wdata;
|
||||
logic x_mem_last_d, x_mem_last_q;
|
||||
logic x_mem_spec;
|
||||
logic [X_ID_WIDTH-1:0] x_mem_id_q;
|
||||
logic x_mem_handshake;
|
||||
logic x_mem_size_err;
|
||||
|
||||
// State mechine for memory and memory result interface
|
||||
typedef enum logic [1:0] { MEM_IDLE, MEM_LSU_REQ, MEM_WAIT_RESULT } x_mem_fsm_e;
|
||||
x_mem_fsm_e x_mem_fsm_q, x_mem_fsm_d;
|
||||
|
||||
// Input request signals
|
||||
assign x_mem_id_d = x_mem_req_i.id;
|
||||
assign x_mem_addr = x_mem_req_i.addr;
|
||||
assign x_mem_we = x_mem_req_i.we;
|
||||
assign x_mem_size = x_mem_req_i.size;
|
||||
assign x_mem_be = x_mem_req_i.be;
|
||||
assign x_mem_wdata = x_mem_req_i.wdata;
|
||||
assign x_mem_last_d = x_mem_req_i.last;
|
||||
assign x_mem_spec = x_mem_req_i.spec;
|
||||
|
||||
assign unused_mem_attr = x_mem_req_i.attr;
|
||||
|
||||
// LSU privillege level
|
||||
assign priv_mode_lsu_xif_o = x_mem_req_i.mode;
|
||||
assign priv_mode_lsu_xif_en_o = 1'b1;
|
||||
|
||||
// Output respond signals
|
||||
// Load and store exceptions supportted now are bus errors,
|
||||
// the signals of which are transmitted through memory result interface.
|
||||
assign x_mem_resp_o.exc = x_mem_load_err | x_mem_store_err;
|
||||
assign x_mem_resp_o.exccode = x_mem_load_err ? 6'd05 : (x_mem_store_err ? 6'd07 : '0);
|
||||
assign x_mem_resp_o.dbg = 1'b0;
|
||||
|
||||
// Output memory result signals
|
||||
assign x_mem_result_id = x_mem_id_q;
|
||||
assign x_mem_result_o.id = x_mem_id_q;
|
||||
// Mux to avoid x in output, which will cause assertion failure in lockstep
|
||||
assign x_mem_result_o.rdata = x_mem_result_valid_o ? lsu_rdata_i : '0;
|
||||
assign x_mem_result_o.err = x_mem_result_err;
|
||||
assign x_mem_result_o.dbg = 1'b0;
|
||||
|
||||
// Handshake
|
||||
assign x_mem_handshake = x_mem_valid_i & x_mem_ready_o;
|
||||
|
||||
// Deal with memory request type
|
||||
always_comb begin
|
||||
x_mem_type = 2'b00;
|
||||
x_mem_size_err = 1'b0;
|
||||
unique case (x_mem_size)
|
||||
// Byte
|
||||
3'b000: begin
|
||||
x_mem_type = 2'b10;
|
||||
end
|
||||
// Half word
|
||||
3'b001: begin
|
||||
x_mem_type = 2'b01;
|
||||
end
|
||||
// Word
|
||||
3'b010: begin
|
||||
x_mem_type = 2'b00;
|
||||
end
|
||||
// Other values are illegal, raise an exception
|
||||
3'b011,
|
||||
3'b100,
|
||||
3'b101,
|
||||
3'b110,
|
||||
3'b111: begin
|
||||
x_mem_size_err = 1'b1;
|
||||
end
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// LSU signals
|
||||
assign lsu_we_o = x_mem_lsu_req ? x_mem_we : lsu_we;
|
||||
assign lsu_type_o = x_mem_lsu_req ? x_mem_type : lsu_type;
|
||||
assign lsu_sign_ext_o = x_mem_lsu_req ? 1'b0 : lsu_sign_ext;
|
||||
assign lsu_wdata_o = x_mem_lsu_req ? x_mem_wdata : rf_rdata_b_fwd;
|
||||
|
||||
// LSU address signals
|
||||
assign alu_operand_a_ex_o = x_mem_lsu_req ? x_mem_addr : alu_operand_a;
|
||||
assign alu_operand_b_ex_o = x_mem_lsu_req ? (lsu_addr_incr_req_i ? 32'h4 : 32'h0) :
|
||||
alu_operand_b;
|
||||
|
||||
always_comb begin
|
||||
x_mem_fsm_d = x_mem_fsm_q;
|
||||
x_mem_ready_o = 1'b0;
|
||||
x_mem_result_valid_o = 1'b0;
|
||||
x_mem_result_fin = 1'b0;
|
||||
x_mem_result_err = 1'b0;
|
||||
x_mem_load_err = 1'b0;
|
||||
x_mem_store_err = 1'b0;
|
||||
// x_mem_lsu_req = 1'b0;
|
||||
|
||||
unique case (x_mem_fsm_q)
|
||||
MEM_IDLE: begin
|
||||
if (x_mem_valid_i & (~x_mem_spec | x_mem_commit)) begin
|
||||
if (x_mem_size_err) begin
|
||||
x_mem_fsm_d = MEM_IDLE;
|
||||
x_mem_ready_o = 1'b1;
|
||||
x_mem_load_err = ~x_mem_we;
|
||||
x_mem_store_err = x_mem_we;
|
||||
end else begin
|
||||
x_mem_fsm_d = MEM_LSU_REQ;
|
||||
// x_mem_lsu_req = 1'b1;
|
||||
if (lsu_req_done_i) begin
|
||||
x_mem_fsm_d = MEM_WAIT_RESULT;
|
||||
x_mem_ready_o = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
MEM_LSU_REQ: begin
|
||||
// x_mem_lsu_req = 1'b1;
|
||||
if (lsu_req_done_i) begin
|
||||
x_mem_fsm_d = MEM_WAIT_RESULT;
|
||||
x_mem_ready_o = 1'b1;
|
||||
end
|
||||
end
|
||||
MEM_WAIT_RESULT: begin
|
||||
if (lsu_resp_valid_i) begin
|
||||
if (x_mem_valid_i & (~x_mem_spec | x_mem_commit)) begin
|
||||
if (x_mem_size_err) begin
|
||||
x_mem_fsm_d = MEM_IDLE;
|
||||
x_mem_ready_o = 1'b1;
|
||||
x_mem_load_err = ~x_mem_we;
|
||||
x_mem_store_err = x_mem_we;
|
||||
end else begin
|
||||
x_mem_fsm_d = MEM_LSU_REQ;
|
||||
// x_mem_lsu_req = 1'b1;
|
||||
if (lsu_req_done_i) begin
|
||||
x_mem_fsm_d = MEM_WAIT_RESULT;
|
||||
x_mem_ready_o = 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
x_mem_fsm_d = MEM_IDLE;
|
||||
end
|
||||
x_mem_result_valid_o = 1'b1;
|
||||
x_mem_result_err = lsu_load_err_i | lsu_store_err_i | lsu_load_intg_err_i;
|
||||
if (x_mem_last_q) begin
|
||||
x_mem_result_fin = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
x_mem_fsm_d = MEM_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// This code has the same function as the commented code in the state machine above.
|
||||
// Make this change because verilator cannot compile the code above.
|
||||
logic x_mem_status_idle;
|
||||
assign x_mem_status_idle = x_mem_fsm_q == MEM_IDLE |
|
||||
(x_mem_fsm_q == MEM_WAIT_RESULT & lsu_resp_valid_i);
|
||||
assign x_mem_lsu_req = (x_mem_fsm_q == MEM_LSU_REQ) |
|
||||
(x_mem_status_idle & ~x_mem_size_err &
|
||||
x_mem_valid_i & (~x_mem_spec | x_mem_commit));
|
||||
assign lsu_x_mem_be_o = x_mem_lsu_req ? x_mem_be : 4'b1111;
|
||||
|
||||
// Only for assertion.
|
||||
assign outstanding_xif_load_store_o = (x_mem_fsm_q != MEM_IDLE) | (x_mem_fsm_d != MEM_IDLE);
|
||||
|
||||
// Flip-Flops
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
x_mem_fsm_q <= '0;
|
||||
end else begin
|
||||
x_mem_fsm_q <= x_mem_fsm_d;
|
||||
end
|
||||
end
|
||||
|
||||
if (ResetAll) begin : g_x_mem_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
x_mem_last_q <= '0;
|
||||
x_mem_id_q <= '0;
|
||||
end else if (x_mem_handshake) begin
|
||||
x_mem_last_q <= x_mem_last_d;
|
||||
x_mem_id_q <= x_mem_id_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_x_mem_nr
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (x_mem_handshake) begin
|
||||
x_mem_last_q <= x_mem_last_d;
|
||||
x_mem_id_q <= x_mem_id_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end else begin : gen_no_mem_interface
|
||||
// Assign inputs
|
||||
logic unused_x_mem_valid;
|
||||
x_mem_req_t unused_x_mem_req;
|
||||
|
||||
assign unused_x_mem_valid = x_mem_valid_i;
|
||||
assign unused_x_mem_req = x_mem_req_i;
|
||||
|
||||
// Zero outputs
|
||||
assign x_mem_ready_o = '0;
|
||||
assign x_mem_resp_o = '0;
|
||||
assign x_mem_result_valid_o = '0;
|
||||
assign x_mem_result_o = '0;
|
||||
assign x_mem_lsu_req = 1'b0;
|
||||
|
||||
// Signals from/to scoreboard
|
||||
assign x_mem_id_d = '0;
|
||||
assign x_mem_result_fin = '0;
|
||||
assign x_mem_result_id = '0;
|
||||
assign x_mem_result_err = 1'b0;
|
||||
|
||||
logic unused_mem_commit;
|
||||
logic [31:0] unused_lsu_rdata;
|
||||
assign unused_mem_commit = x_mem_commit;
|
||||
assign unused_lsu_rdata = lsu_rdata_i;
|
||||
|
||||
// LSU signals
|
||||
assign lsu_we_o = lsu_we;
|
||||
assign lsu_type_o = lsu_type;
|
||||
assign lsu_sign_ext_o = lsu_sign_ext;
|
||||
assign lsu_wdata_o = rf_rdata_b_fwd;
|
||||
assign lsu_x_mem_be_o = 4'b1111;
|
||||
|
||||
// Execution block signals
|
||||
assign alu_operand_a_ex_o = alu_operand_a;
|
||||
assign alu_operand_b_ex_o = alu_operand_b;
|
||||
|
||||
// LSU privillege level
|
||||
assign priv_mode_lsu_xif_o = '0;
|
||||
assign priv_mode_lsu_xif_en_o = 1'b0;
|
||||
|
||||
// Memory interface size error signals
|
||||
assign x_mem_load_err = 1'b0;
|
||||
assign x_mem_store_err = 1'b0;
|
||||
|
||||
// Signal only for assertion
|
||||
assign outstanding_xif_load_store_o = 1'b0;
|
||||
end
|
||||
|
||||
/////////////////
|
||||
// SCORE BOARD //
|
||||
/////////////////
|
||||
|
||||
// Signal to reset scoreboard and kill requests in issue-commit buffer
|
||||
logic x_exc_err;
|
||||
assign x_exc_err = x_result_exc | x_result_err;
|
||||
assign x_exc_err = x_result_exc | x_result_err | x_mem_result_err |
|
||||
x_mem_load_err | x_mem_store_err;
|
||||
|
||||
// Scoreboard registers
|
||||
logic [31:0] scoreboard;
|
||||
|
@ -1433,6 +1722,7 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
.wb_exception_i (wb_exception),
|
||||
.mem_in_wb_i (outstanding_memory_access),
|
||||
.external_exc_o (external_exc),
|
||||
.mem_xif_o (mem_xif),
|
||||
.illegal_insn_o (illegal_insn_id),
|
||||
// issue interface
|
||||
.issue_id_o (x_issue_id),
|
||||
|
@ -1441,10 +1731,17 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
.issue_handshake_i(x_issue_handshake),
|
||||
.issue_reject_i (x_issue_reject),
|
||||
.issue_exc_i (x_issue_exc),
|
||||
.issue_ls_i (x_issue_ls),
|
||||
// commit interface
|
||||
.commit_valid_o(x_commit_valid_o),
|
||||
.commit_id_o (x_commit_id),
|
||||
.commit_kill_o (x_commit_kill),
|
||||
// memory interface
|
||||
.mem_id_i (x_mem_id_d),
|
||||
.mem_commit_o(x_mem_commit),
|
||||
// memory result interface
|
||||
.mem_result_fin_i(x_mem_result_fin),
|
||||
.mem_result_id_i (x_mem_result_id),
|
||||
// result interface
|
||||
.result_handshake_i(x_result_handshake),
|
||||
.result_id_i (x_result_id)
|
||||
|
@ -1457,27 +1754,40 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
logic [5:0] unused_ecs_rd;
|
||||
logic unused_x_issue_ready;
|
||||
x_issue_resp_t unused_x_issue_resp;
|
||||
logic unused_x_mem_valid;
|
||||
x_mem_req_t unused_x_mem_req;
|
||||
logic unused_x_result_valid;
|
||||
x_result_t unused_x_result;
|
||||
logic unused_x_issue_use_rs3;
|
||||
logic unused_outstanding_memory_access;
|
||||
logic [31:0] unused_lsu_rdata;
|
||||
|
||||
assign unused_ecs_rd = ecs_rd_i;
|
||||
assign unused_x_issue_ready = x_issue_ready_i;
|
||||
assign unused_x_issue_resp = x_issue_resp_i;
|
||||
assign unused_x_mem_valid = x_mem_valid_i;
|
||||
assign unused_x_mem_req = x_mem_req_i;
|
||||
assign unused_x_result_valid = x_result_valid_i;
|
||||
assign unused_x_result = x_result_i;
|
||||
assign unused_lsu_rdata = lsu_rdata_i;
|
||||
|
||||
assign unused_x_issue_use_rs3 = x_issue_use_rs3;
|
||||
assign unused_outstanding_memory_access = outstanding_memory_access;
|
||||
|
||||
assign ecs_wr_o = '0;
|
||||
assign ecs_wen_o = '0;
|
||||
assign x_issue_valid_o = 1'b0;
|
||||
assign x_issue_req_o = '0;
|
||||
assign x_commit_valid_o = 1'b0;
|
||||
assign x_commit_o = '0;
|
||||
assign x_result_ready_o = 1'b0;
|
||||
assign ecs_wr_o = '0;
|
||||
assign ecs_wen_o = '0;
|
||||
assign x_issue_valid_o = 1'b0;
|
||||
assign x_issue_req_o = '0;
|
||||
assign x_commit_valid_o = 1'b0;
|
||||
assign x_commit_o = '0;
|
||||
assign x_result_ready_o = 1'b0;
|
||||
assign x_mem_ready_o = 1'b0;
|
||||
assign x_mem_resp_o = '0;
|
||||
assign x_mem_result_valid_o = 1'b0;
|
||||
assign x_mem_result_o = '0;
|
||||
assign priv_mode_lsu_xif_o = '0;
|
||||
assign priv_mode_lsu_xif_en_o = 1'b0;
|
||||
assign outstanding_xif_load_store_o = 1'b0;
|
||||
|
||||
// X-Interface signals that needs to be set to 0
|
||||
assign x_issue_candidate = 1'b0;
|
||||
|
@ -1491,11 +1801,21 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
assign x_result_exc = 1'b0;
|
||||
assign x_result_exccode = '0;
|
||||
assign x_result_err = 1'b0;
|
||||
assign x_mem_load_err = 1'b0;
|
||||
assign x_mem_store_err = 1'b0;
|
||||
assign x_mem_lsu_req = 1'b0;
|
||||
|
||||
// wire connections
|
||||
assign illegal_insn_id = illegal_insn_dec | illegal_csr_insn_i;
|
||||
assign rf_waddr_id_o = rf_waddr_dec;
|
||||
assign rf_wdata_id_o = rf_wdata_mux;
|
||||
assign illegal_insn_id = illegal_insn_dec | illegal_csr_insn_i;
|
||||
assign rf_waddr_id_o = rf_waddr_dec;
|
||||
assign rf_wdata_id_o = rf_wdata_mux;
|
||||
assign lsu_we_o = lsu_we;
|
||||
assign lsu_type_o = lsu_type;
|
||||
assign lsu_sign_ext_o = lsu_sign_ext;
|
||||
assign lsu_wdata_o = rf_rdata_b_fwd;
|
||||
assign lsu_x_mem_be_o = 4'b1111;
|
||||
assign alu_operand_a_ex_o = alu_operand_a;
|
||||
assign alu_operand_b_ex_o = alu_operand_b;
|
||||
end
|
||||
|
||||
//////////
|
||||
|
@ -1555,6 +1875,10 @@ module ibex_id_stage import ibex_pkg::*; #(
|
|||
`ASSERT(IbexMulticycleStageRegEnableUnique,
|
||||
$onehot0({|imd_val_we_ex_i, imd_val_we_x_issue}))
|
||||
|
||||
// LSU enable must be unique.
|
||||
`ASSERT(LoadStoreUnitEnableUnique,
|
||||
$onehot0({x_mem_lsu_req, lsu_req}))
|
||||
|
||||
// Duplicated instruction flops must match
|
||||
// === as DV environment can produce instructions with Xs in, so must use precise match that
|
||||
// includes Xs
|
||||
|
|
|
@ -39,6 +39,7 @@ module ibex_load_store_unit #(
|
|||
input logic [1:0] lsu_type_i, // data type: word, half word, byte -> from ID/EX
|
||||
input logic [31:0] lsu_wdata_i, // data to write to memory -> from ID/EX
|
||||
input logic lsu_sign_ext_i, // sign extension -> from ID/EX
|
||||
input logic [3:0] lsu_x_mem_be_i,
|
||||
|
||||
output logic [31:0] lsu_rdata_o, // requested data -> to ID/EX
|
||||
output logic lsu_rdata_valid_o,
|
||||
|
@ -518,7 +519,7 @@ module ibex_load_store_unit #(
|
|||
// output to data interface
|
||||
assign data_addr_o = data_addr_w_aligned;
|
||||
assign data_we_o = lsu_we_i;
|
||||
assign data_be_o = data_be;
|
||||
assign data_be_o = data_be & lsu_x_mem_be_i;
|
||||
|
||||
/////////////////////////////////////
|
||||
// Write data integrity generation //
|
||||
|
|
|
@ -39,7 +39,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
parameter int unsigned MemDataWidth = MemECC ? 32 + 7 : 32,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1
|
||||
parameter bit XInterface = 1'b1,
|
||||
parameter bit MemInterface = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -115,6 +116,12 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
input x_issue_resp_t x_issue_resp_i,
|
||||
input logic x_commit_valid_i,
|
||||
input x_commit_t x_commit_i,
|
||||
input logic x_mem_valid_i,
|
||||
input logic x_mem_ready_i,
|
||||
input x_mem_req_t x_mem_req_i,
|
||||
input x_mem_resp_t x_mem_resp_i,
|
||||
input logic x_mem_result_valid_i,
|
||||
input x_mem_result_t x_mem_result_i,
|
||||
input logic x_result_valid_i,
|
||||
input logic x_result_ready_i,
|
||||
input x_result_t x_result_i
|
||||
|
@ -204,6 +211,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
x_compressed_resp_t x_compressed_resp;
|
||||
logic x_issue_ready;
|
||||
x_issue_resp_t x_issue_resp;
|
||||
logic x_mem_valid;
|
||||
x_mem_req_t x_mem_req;
|
||||
logic x_result_valid;
|
||||
x_result_t x_result;
|
||||
} delayed_inputs_t;
|
||||
|
@ -237,6 +246,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
assign shadow_inputs_in.x_compressed_resp = x_compressed_resp_i;
|
||||
assign shadow_inputs_in.x_issue_ready = x_issue_ready_i;
|
||||
assign shadow_inputs_in.x_issue_resp = x_issue_resp_i;
|
||||
assign shadow_inputs_in.x_mem_valid = x_mem_valid_i;
|
||||
assign shadow_inputs_in.x_mem_req = x_mem_req_i;
|
||||
assign shadow_inputs_in.x_result_valid = x_result_valid_i;
|
||||
assign shadow_inputs_in.x_result = x_result_i;
|
||||
|
||||
|
@ -297,6 +308,10 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
x_issue_req_t x_issue_req;
|
||||
logic x_commit_valid;
|
||||
x_commit_t x_commit;
|
||||
logic x_mem_ready;
|
||||
x_mem_resp_t x_mem_resp;
|
||||
logic x_mem_result_valid;
|
||||
x_mem_result_t x_mem_result;
|
||||
logic x_result_ready;
|
||||
} delayed_outputs_t;
|
||||
|
||||
|
@ -337,6 +352,10 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
assign core_outputs_in.x_issue_req = x_issue_req_i;
|
||||
assign core_outputs_in.x_commit_valid = x_commit_valid_i;
|
||||
assign core_outputs_in.x_commit = x_commit_i;
|
||||
assign core_outputs_in.x_mem_ready = x_mem_ready_i;
|
||||
assign core_outputs_in.x_mem_resp = x_mem_resp_i;
|
||||
assign core_outputs_in.x_mem_result_valid = x_mem_result_valid_i;
|
||||
assign core_outputs_in.x_mem_result = x_mem_result_i;
|
||||
assign core_outputs_in.x_result_ready = x_result_ready_i;
|
||||
|
||||
// Delay the outputs
|
||||
|
@ -383,7 +402,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.MemDataWidth ( MemDataWidth ),
|
||||
.DmHaltAddr ( DmHaltAddr ),
|
||||
.DmExceptionAddr ( DmExceptionAddr ),
|
||||
.XInterface ( XInterface )
|
||||
.XInterface ( XInterface ),
|
||||
.MemInterface ( MemInterface )
|
||||
) u_shadow_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_shadow_n),
|
||||
|
@ -487,6 +507,12 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.x_issue_resp_i (shadow_inputs_q[0].x_issue_resp),
|
||||
.x_commit_valid_o (shadow_outputs_d.x_commit_valid),
|
||||
.x_commit_o (shadow_outputs_d.x_commit),
|
||||
.x_mem_valid_i (shadow_inputs_q[0].x_mem_valid),
|
||||
.x_mem_ready_o (shadow_outputs_d.x_mem_ready),
|
||||
.x_mem_req_i (shadow_inputs_q[0].x_mem_req),
|
||||
.x_mem_resp_o (shadow_outputs_d.x_mem_resp),
|
||||
.x_mem_result_valid_o (shadow_outputs_d.x_mem_result_valid),
|
||||
.x_mem_result_o (shadow_outputs_d.x_mem_result),
|
||||
.x_result_valid_i (shadow_inputs_q[0].x_result_valid),
|
||||
.x_result_ready_o (shadow_outputs_d.x_result_ready),
|
||||
.x_result_i (shadow_inputs_q[0].x_result)
|
||||
|
|
|
@ -669,6 +669,7 @@ package ibex_pkg;
|
|||
parameter int unsigned XLEN = 32;
|
||||
parameter int unsigned X_NUM_RS = 3;
|
||||
parameter int unsigned X_ID_WIDTH = 4;
|
||||
parameter int unsigned X_MEM_WIDTH = 32;
|
||||
parameter int unsigned X_RFR_WIDTH = 32;
|
||||
parameter int unsigned X_RFW_WIDTH = 32;
|
||||
parameter logic [31:0] X_MISA = 32'b0;
|
||||
|
@ -712,6 +713,32 @@ package ibex_pkg;
|
|||
logic commit_kill;
|
||||
} x_commit_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [X_ID_WIDTH-1:0] id;
|
||||
logic [31:0] addr;
|
||||
priv_lvl_e mode;
|
||||
logic we;
|
||||
logic [2:0] size;
|
||||
logic [X_MEM_WIDTH/8-1:0] be;
|
||||
logic [1:0] attr;
|
||||
logic [X_MEM_WIDTH-1:0] wdata;
|
||||
logic last;
|
||||
logic spec;
|
||||
} x_mem_req_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic exc;
|
||||
logic [5:0] exccode;
|
||||
logic dbg;
|
||||
} x_mem_resp_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [X_ID_WIDTH-1:0] id;
|
||||
logic [X_MEM_WIDTH-1:0] rdata;
|
||||
logic err;
|
||||
logic dbg;
|
||||
} x_mem_result_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [X_ID_WIDTH-1:0] id;
|
||||
logic [X_RFW_WIDTH-1:0] data;
|
||||
|
|
|
@ -36,6 +36,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||
parameter bit XInterface = 1'b1,
|
||||
parameter bit MemInterface = 1'b0,
|
||||
// Default seed and nonce for scrambling
|
||||
parameter logic [SCRAMBLE_KEY_W-1:0] RndCnstIbexKey = RndCnstIbexKeyDefault,
|
||||
parameter logic [SCRAMBLE_NONCE_W-1:0] RndCnstIbexNonce = RndCnstIbexNonceDefault
|
||||
|
@ -147,6 +148,14 @@ module ibex_top import ibex_pkg::*; #(
|
|||
// Commit Interface
|
||||
output logic x_commit_valid_o,
|
||||
output x_commit_t x_commit_o,
|
||||
// Memory Interface
|
||||
input logic x_mem_valid_i,
|
||||
output logic x_mem_ready_o,
|
||||
input x_mem_req_t x_mem_req_i,
|
||||
output x_mem_resp_t x_mem_resp_o,
|
||||
// Memory Result Interface
|
||||
output logic x_mem_result_valid_o,
|
||||
output x_mem_result_t x_mem_result_o,
|
||||
// Result Interface
|
||||
input logic x_result_valid_i,
|
||||
output logic x_result_ready_o,
|
||||
|
@ -299,7 +308,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.MemDataWidth (MemDataWidth),
|
||||
.DmHaltAddr (DmHaltAddr),
|
||||
.DmExceptionAddr (DmExceptionAddr),
|
||||
.XInterface (XInterface)
|
||||
.XInterface (XInterface),
|
||||
.MemInterface (MemInterface)
|
||||
) u_ibex_core (
|
||||
.clk_i(clk),
|
||||
.rst_ni,
|
||||
|
@ -403,6 +413,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.x_issue_resp_i,
|
||||
.x_commit_valid_o,
|
||||
.x_commit_o,
|
||||
.x_mem_valid_i,
|
||||
.x_mem_ready_o,
|
||||
.x_mem_req_i,
|
||||
.x_mem_resp_o,
|
||||
.x_mem_result_valid_o,
|
||||
.x_mem_result_o,
|
||||
.x_result_valid_i,
|
||||
.x_result_ready_o,
|
||||
.x_result_i
|
||||
|
@ -700,6 +716,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
x_issue_resp_i,
|
||||
x_commit_valid_o,
|
||||
x_commit_o,
|
||||
x_mem_valid_i,
|
||||
x_mem_ready_o,
|
||||
x_mem_req_i,
|
||||
x_mem_resp_o,
|
||||
x_mem_result_valid_o,
|
||||
x_mem_result_o,
|
||||
x_result_valid_i,
|
||||
x_result_ready_o,
|
||||
x_result_i,
|
||||
|
@ -772,6 +794,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
x_issue_resp_t x_issue_resp_local;
|
||||
logic x_commit_valid_local;
|
||||
x_commit_t x_commit_local;
|
||||
logic x_mem_valid_local;
|
||||
logic x_mem_ready_local;
|
||||
x_mem_req_t x_mem_req_local;
|
||||
x_mem_resp_t x_mem_resp_local;
|
||||
logic x_mem_result_valid_local;
|
||||
x_mem_result_t x_mem_result_local;
|
||||
logic x_result_valid_local;
|
||||
logic x_result_ready_local;
|
||||
x_result_t x_result_local;
|
||||
|
@ -832,6 +860,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
x_issue_resp_i,
|
||||
x_commit_valid_o,
|
||||
x_commit_o,
|
||||
x_mem_valid_i,
|
||||
x_mem_ready_o,
|
||||
x_mem_req_i,
|
||||
x_mem_resp_o,
|
||||
x_mem_result_valid_o,
|
||||
x_mem_result_o,
|
||||
x_result_valid_i,
|
||||
x_result_ready_o,
|
||||
x_result_i,
|
||||
|
@ -894,6 +928,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
x_issue_resp_local,
|
||||
x_commit_valid_local,
|
||||
x_commit_local,
|
||||
x_mem_valid_local,
|
||||
x_mem_ready_local,
|
||||
x_mem_req_local,
|
||||
x_mem_resp_local,
|
||||
x_mem_result_valid_local,
|
||||
x_mem_result_local,
|
||||
x_result_valid_local,
|
||||
x_result_ready_local,
|
||||
x_result_local,
|
||||
|
@ -951,7 +991,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.MemECC (MemECC),
|
||||
.DmHaltAddr (DmHaltAddr),
|
||||
.DmExceptionAddr (DmExceptionAddr),
|
||||
.XInterface (XInterface)
|
||||
.XInterface (XInterface),
|
||||
.MemInterface (MemInterface)
|
||||
) u_ibex_lockstep (
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -1027,6 +1068,12 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.x_issue_resp_i (x_issue_resp_local),
|
||||
.x_commit_valid_i (x_commit_valid_local),
|
||||
.x_commit_i (x_commit_local),
|
||||
.x_mem_valid_i (x_mem_valid_local),
|
||||
.x_mem_ready_i (x_mem_ready_local),
|
||||
.x_mem_req_i (x_mem_req_local),
|
||||
.x_mem_resp_i (x_mem_resp_local),
|
||||
.x_mem_result_valid_i (x_mem_result_valid_local),
|
||||
.x_mem_result_i (x_mem_result_local),
|
||||
.x_result_valid_i (x_result_valid_local),
|
||||
.x_result_ready_i (x_result_ready_local),
|
||||
.x_result_i (x_result_local)
|
||||
|
|
|
@ -29,7 +29,8 @@ module ibex_top_tracing 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
|
||||
parameter bit XInterface = 1'b1,
|
||||
parameter bit MemInterface = 1'b0
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -101,6 +102,12 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
input x_issue_resp_t x_issue_resp_i,
|
||||
output logic x_commit_valid_o,
|
||||
output x_commit_t x_commit_o,
|
||||
input logic x_mem_valid_i,
|
||||
output logic x_mem_ready_o,
|
||||
input x_mem_req_t x_mem_req_i,
|
||||
output x_mem_resp_t x_mem_resp_o,
|
||||
output logic x_mem_result_valid_o,
|
||||
output x_mem_result_t x_mem_result_o,
|
||||
input logic x_result_valid_i,
|
||||
output logic x_result_ready_o,
|
||||
input x_result_t x_result_i
|
||||
|
@ -174,7 +181,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.DmHaltAddr ( DmHaltAddr ),
|
||||
.DmExceptionAddr ( DmExceptionAddr ),
|
||||
.XInterface ( XInterface )
|
||||
.XInterface ( XInterface ),
|
||||
.MemInterface ( MemInterface )
|
||||
) u_ibex_top (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -265,6 +273,12 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.x_issue_resp_i,
|
||||
.x_commit_valid_o,
|
||||
.x_commit_o,
|
||||
.x_mem_valid_i,
|
||||
.x_mem_ready_o,
|
||||
.x_mem_req_i,
|
||||
.x_mem_resp_o,
|
||||
.x_mem_result_valid_o,
|
||||
.x_mem_result_o,
|
||||
.x_result_valid_i,
|
||||
.x_result_ready_o,
|
||||
.x_result_i
|
||||
|
|
|
@ -50,8 +50,8 @@ module ibex_wb_stage #(
|
|||
output logic [31:0] rf_wdata_wb_o,
|
||||
output logic rf_we_wb_o,
|
||||
|
||||
input logic lsu_resp_valid_i,
|
||||
input logic lsu_resp_err_i,
|
||||
input logic lsu_resp_valid_i,
|
||||
input logic lsu_resp_err_i,
|
||||
|
||||
output logic instr_done_wb_o
|
||||
);
|
||||
|
|
|
@ -20,6 +20,7 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
input logic wb_exception_i,
|
||||
input logic mem_in_wb_i,
|
||||
output logic external_exc_o,
|
||||
output logic mem_xif_o,
|
||||
output logic illegal_insn_o,
|
||||
|
||||
// issue interface
|
||||
|
@ -30,12 +31,21 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
input logic issue_handshake_i,
|
||||
input logic issue_reject_i,
|
||||
input logic issue_exc_i,
|
||||
input logic issue_ls_i,
|
||||
|
||||
// commit interface
|
||||
output logic commit_valid_o,
|
||||
output logic [X_ID_WIDTH-1:0] commit_id_o,
|
||||
output logic commit_kill_o,
|
||||
|
||||
// memory interface
|
||||
input logic [X_ID_WIDTH-1:0] mem_id_i,
|
||||
output logic mem_commit_o,
|
||||
|
||||
// memory result interface
|
||||
input logic mem_result_fin_i, // Mem requests from a certain ID has finished.
|
||||
input logic [X_ID_WIDTH-1:0] mem_result_id_i,
|
||||
|
||||
// result interface
|
||||
input logic result_handshake_i,
|
||||
input logic [X_ID_WIDTH-1:0] result_id_i
|
||||
|
@ -43,7 +53,9 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
|
||||
// issue-commit buffer
|
||||
logic [ICB_DEPTH-1:0] icb_valid_d, icb_valid_q;
|
||||
logic [ICB_DEPTH-1:0] icb_commit_d, icb_commit_q;
|
||||
logic [ICB_DEPTH-1:0] icb_exc_d, icb_exc_q;
|
||||
logic [ICB_DEPTH-1:0] icb_mem_d, icb_mem_q;
|
||||
logic [ICB_DEPTH-1:0] icb_reject_d, icb_reject_q;
|
||||
|
||||
// IDs
|
||||
|
@ -56,7 +68,11 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
logic [ICB_ID_W-1:0] issue_id;
|
||||
logic [ICB_ID_W-1:0] commit_id;
|
||||
logic [ICB_ID_W-1:0] result_id;
|
||||
logic [ICB_ID_W-1:0] mem_id;
|
||||
logic [ICB_ID_W-1:0] mem_result_id;
|
||||
logic [X_ID_WIDTH-ICB_ID_W-1:0] unused_result_id;
|
||||
logic [X_ID_WIDTH-ICB_ID_W-1:0] unused_mem_id;
|
||||
logic [X_ID_WIDTH-ICB_ID_W-1:0] unused_mem_result_id;
|
||||
|
||||
// Control signals
|
||||
logic insn_reject;
|
||||
|
@ -85,10 +101,15 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
// ID width transfer //
|
||||
///////////////////////
|
||||
|
||||
assign issue_id_o = {{X_ID_WIDTH-ICB_ID_W{1'b0}}, issue_id};
|
||||
assign commit_id_o = {{X_ID_WIDTH-ICB_ID_W{1'b0}}, commit_id};
|
||||
assign result_id = result_id_i[ICB_ID_W-1:0];
|
||||
assign unused_result_id = result_id_i[X_ID_WIDTH-1:ICB_ID_W];
|
||||
assign issue_id_o = {{X_ID_WIDTH-ICB_ID_W{1'b0}}, issue_id};
|
||||
assign commit_id_o = {{X_ID_WIDTH-ICB_ID_W{1'b0}}, commit_id};
|
||||
assign result_id = result_id_i[ICB_ID_W-1:0];
|
||||
assign mem_id = mem_id_i[ICB_ID_W-1:0];
|
||||
assign mem_result_id = mem_result_id_i[ICB_ID_W-1:0];
|
||||
|
||||
assign unused_result_id = result_id_i[X_ID_WIDTH-1:ICB_ID_W];
|
||||
assign unused_mem_id = mem_id_i[X_ID_WIDTH-1:ICB_ID_W];
|
||||
assign unused_mem_result_id = mem_result_id_i[X_ID_WIDTH-1:ICB_ID_W];
|
||||
|
||||
///////////////
|
||||
// ID lookup //
|
||||
|
@ -143,8 +164,10 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
assign issue_icb_valid_o = issue_id_valid_q & (~issue_id_new_q | icf_push_ready) &
|
||||
~insn_reject & ~is_killing;
|
||||
assign insn_reject = |icb_reject_q;
|
||||
assign external_exc_o = |icb_exc_d | insn_reject;
|
||||
assign external_exc_o = |icb_exc_d | |icb_mem_d | insn_reject;
|
||||
assign mem_xif_o = |icb_mem_q;
|
||||
assign illegal_insn_o = icb_reject_q[commit_id] | (issue_reject_i & (issue_id == commit_id));
|
||||
assign mem_commit_o = icb_commit_d[mem_id];
|
||||
|
||||
///////////////////////
|
||||
// issue-commit FIFO //
|
||||
|
@ -190,9 +213,9 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
assign lcb_id_d = icf_pop_data;
|
||||
assign lcb_valid_d = lcb_push | (lcb_valid_q & ~lcb_pop);
|
||||
// Push committed instructions into the buffer.
|
||||
assign lcb_push = commit_valid_o & ~is_killing & ~icb_reject_q[commit_id];
|
||||
assign lcb_push = commit_valid_o & ~is_killing & ~icb_reject_q[commit_id];
|
||||
// Pop only if the instruction could not raise exception in the future.
|
||||
assign lcb_pop = ~icb_exc_q[lcb_id_q] | is_killing;
|
||||
assign lcb_pop = (~icb_exc_q[lcb_id_q] & (~icb_mem_q[lcb_id_q] | mem_result_fin_i)) | is_killing;
|
||||
|
||||
//////////////////////////
|
||||
// finite state machine //
|
||||
|
@ -230,38 +253,49 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
|
||||
always_comb begin
|
||||
icb_valid_d = icb_valid_q;
|
||||
icb_commit_d = icb_commit_q;
|
||||
icb_exc_d = icb_exc_q;
|
||||
icb_mem_d = icb_mem_q;
|
||||
icb_reject_d = icb_reject_q;
|
||||
if (icf_push) begin
|
||||
icb_valid_d[issue_id] = 1'b1;
|
||||
// Set 1 since instruction not yet acceptted could raise exception in the future.
|
||||
icb_exc_d[issue_id] = 1'b1;
|
||||
icb_exc_d[issue_id] = 1'b1;
|
||||
end
|
||||
if (issue_handshake_i) begin
|
||||
icb_valid_d[issue_id] = 1'b1;
|
||||
icb_exc_d[issue_id] = issue_exc_i;
|
||||
icb_reject_d[issue_id] = issue_reject_i;
|
||||
icb_valid_d[issue_id] = 1'b1;
|
||||
icb_exc_d[issue_id] = issue_exc_i;
|
||||
icb_mem_d[issue_id] = issue_ls_i;
|
||||
icb_reject_d[issue_id] = issue_reject_i;
|
||||
end
|
||||
// If result arrives at the same cycle, overwrite issue
|
||||
if (result_handshake_i) begin
|
||||
icb_valid_d[result_id] = 1'b0;
|
||||
icb_commit_d[result_id] = 1'b0;
|
||||
icb_exc_d[result_id] = 1'b0;
|
||||
icb_mem_d[result_id] = 1'b0;
|
||||
end
|
||||
if (commit_valid_o & icb_reject_q[commit_id]) begin
|
||||
// Clear all the bits for a rejected instruction
|
||||
icb_valid_d[commit_id] = 1'b0;
|
||||
icb_exc_d[commit_id] = 1'b0;
|
||||
icb_reject_d[commit_id] = 1'b0;
|
||||
if (mem_result_fin_i) begin
|
||||
icb_mem_d[mem_result_id] = 1'b0;
|
||||
end
|
||||
if (commit_valid_o & is_killing) begin
|
||||
// Clear all the bits for a killed instruction
|
||||
icb_valid_d[commit_id] = 1'b0;
|
||||
icb_exc_d[commit_id] = 1'b0;
|
||||
icb_reject_d[commit_id] = 1'b0;
|
||||
if (commit_valid_o) begin
|
||||
if (icb_reject_q[commit_id] | is_killing) begin
|
||||
// Clear all the bits for a rejected or killed instruction
|
||||
icb_valid_d[commit_id] = 1'b0;
|
||||
icb_commit_d[commit_id] = 1'b0;
|
||||
icb_exc_d[commit_id] = 1'b0;
|
||||
icb_mem_d[commit_id] = 1'b0;
|
||||
icb_reject_d[commit_id] = 1'b0;
|
||||
end else begin
|
||||
icb_commit_d[commit_id] = 1'b1;
|
||||
end
|
||||
end
|
||||
if (xif_exception_i) begin
|
||||
icb_valid_d[lcb_id_q] = 1'b0;
|
||||
icb_exc_d[lcb_id_q] = 1'b0;
|
||||
icb_valid_d[lcb_id_q] = 1'b0;
|
||||
icb_commit_d[lcb_id_q] = 1'b0;
|
||||
icb_exc_d[lcb_id_q] = 1'b0;
|
||||
icb_mem_d[lcb_id_q] = 1'b0;
|
||||
icb_reject_d[lcb_id_q] = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -292,7 +326,9 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
lcb_valid_q <= 1'b0;
|
||||
icb_fsm_q <= ICB_COMMIT;
|
||||
icb_valid_q <= '0;
|
||||
icb_commit_q <= '0;
|
||||
icb_exc_q <= '0;
|
||||
icb_mem_q <= '0;
|
||||
icb_reject_q <= '0;
|
||||
end else begin
|
||||
issue_id_valid_q <= issue_id_valid_d;
|
||||
|
@ -300,7 +336,9 @@ module ibex_xif_issue_commit_buffer import ibex_pkg::*; (
|
|||
lcb_valid_q <= lcb_valid_d;
|
||||
icb_fsm_q <= icb_fsm_d;
|
||||
icb_valid_q <= icb_valid_d;
|
||||
icb_commit_q <= icb_commit_d;
|
||||
icb_exc_q <= icb_exc_d;
|
||||
icb_mem_q <= icb_mem_d;
|
||||
icb_reject_q <= icb_reject_d;
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue