mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 13:17:41 -04:00
Re-model exception path on fetch front-end
This commit is contained in:
parent
7173d44bb0
commit
bec72a7c2a
10 changed files with 39 additions and 31 deletions
4
Makefile
4
Makefile
|
@ -128,8 +128,8 @@ build-tests:
|
|||
|
||||
# User Verilator to lint the target
|
||||
lint:
|
||||
verilator ${src} --lint-only \
|
||||
${list_incdir}
|
||||
verilator $(ariane_pkg) $(src) --lint-only \
|
||||
$(list_incdir) --top-module ariane
|
||||
|
||||
clean:
|
||||
rm -rf work/ *.ucdb
|
||||
|
|
|
@ -96,11 +96,12 @@ package ariane_pkg;
|
|||
// ---------------
|
||||
// store the decompressed instruction
|
||||
typedef struct packed {
|
||||
branchpredict_sbe branch_predict;
|
||||
logic [63:0] address;
|
||||
logic [31:0] instruction;
|
||||
logic is_compressed;
|
||||
logic is_illegal;
|
||||
branchpredict_sbe branch_predict; // this field contains branch prediction information regarding the forward branch path
|
||||
exception ex; // this field contains exceptions which might have happened earlier, e.g.: fetch exceptions
|
||||
logic [63:0] address; // the address of the instructions from below
|
||||
logic [31:0] instruction; // instruction word
|
||||
logic is_compressed; // bit indicating whether this instruction was previously compressed (e.g.: 16 bit)
|
||||
logic is_illegal; // bit indicating whether the instruction was an illegal compressed instructions
|
||||
} fetch_entry;
|
||||
|
||||
// ---------------
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
// University of Bologna.
|
||||
//
|
||||
import ariane_pkg::*;
|
||||
`ifndef verilator
|
||||
`ifndef SYNTHESIS
|
||||
import instruction_tracer_pkg::*;
|
||||
`endif
|
||||
`endif
|
||||
|
||||
module ariane
|
||||
#(
|
||||
|
@ -184,6 +186,7 @@ module ariane
|
|||
logic fetch_gnt_ex_if;
|
||||
logic fetch_valid_ex_if;
|
||||
logic [31:0] fetch_rdata_ex_if;
|
||||
exception fetch_ex_ex_if;
|
||||
logic fetch_err_ex_if;
|
||||
logic [63:0] fetch_vaddr_if_ex;
|
||||
// --------------
|
||||
|
@ -253,11 +256,11 @@ module ariane
|
|||
.instr_gnt_i ( fetch_gnt_ex_if ),
|
||||
.instr_rvalid_i ( fetch_valid_ex_if ),
|
||||
.instr_rdata_i ( fetch_rdata_ex_if ),
|
||||
.instr_ex_i ( fetch_ex_ex_if ), // fetch exception
|
||||
|
||||
.fetch_entry_o ( fetch_entry_if_id ),
|
||||
.fetch_entry_valid_i ( fetch_valid_if_id ),
|
||||
.instr_ack_i ( decode_ack_id_if ),
|
||||
.ex_o ( exception_if_id ),
|
||||
.*
|
||||
);
|
||||
|
||||
|
@ -276,7 +279,6 @@ module ariane
|
|||
.fetch_entry_i ( fetch_entry_if_id ),
|
||||
.fetch_entry_valid_i ( fetch_valid_if_id ),
|
||||
.decoded_instr_ack_o ( decode_ack_id_if ),
|
||||
.ex_if_i ( exception_if_id ), // exception from if
|
||||
.ready_o ( ready_id_if ),
|
||||
.priv_lvl_i ( priv_lvl ),
|
||||
.tvm_i ( tvm_csr_id ),
|
||||
|
@ -377,6 +379,7 @@ module ariane
|
|||
.fetch_err_o ( fetch_err_ex_if ),
|
||||
.fetch_vaddr_i ( fetch_vaddr_if_ex ),
|
||||
.fetch_rdata_o ( fetch_rdata_ex_if ),
|
||||
.fetch_ex_o ( fetch_ex_ex_if ), // fetch exception to IF
|
||||
.priv_lvl_i ( priv_lvl ), // from CSR
|
||||
.flag_pum_i ( flag_pum_csr_ex ), // from CSR
|
||||
.flag_mxr_i ( flag_mxr_csr_ex ), // from CSR
|
||||
|
@ -463,6 +466,7 @@ module ariane
|
|||
// Instruction Tracer
|
||||
// -------------------
|
||||
`ifndef SYNTHESIS
|
||||
`ifndef verilator
|
||||
instruction_tracer_if tracer_if (clk_i);
|
||||
// assign instruction tracer interface
|
||||
// control signals
|
||||
|
@ -494,6 +498,7 @@ module ariane
|
|||
|
||||
instr_tracer instr_tracer_i (tracer_if);
|
||||
`endif
|
||||
`endif
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
|
|
|
@ -77,6 +77,7 @@ module ex_stage #(
|
|||
output logic fetch_err_o,
|
||||
input logic [63:0] fetch_vaddr_i,
|
||||
output logic [31:0] fetch_rdata_o,
|
||||
output exception fetch_ex_o,
|
||||
input priv_lvl_t priv_lvl_i,
|
||||
input logic flag_pum_i,
|
||||
input logic flag_mxr_i,
|
||||
|
|
|
@ -29,6 +29,7 @@ module fetch_fifo
|
|||
// that we have two compressed instruction (or one compressed instruction and one unaligned instruction) so we
|
||||
// only predict on one entry and discard (or keep) the other depending on its position and prediction.
|
||||
input branchpredict_sbe branch_predict_i,
|
||||
input exception ex_i, // fetch exception in
|
||||
input logic [63:0] in_addr_i,
|
||||
input logic [31:0] in_rdata_i,
|
||||
input logic in_valid_i,
|
||||
|
@ -43,6 +44,7 @@ module fetch_fifo
|
|||
|
||||
// input registers - bounding the path from memory
|
||||
branchpredict_sbe branch_predict_n, branch_predict_q;
|
||||
exception ex_n, ex_q;
|
||||
logic [63:0] in_addr_n, in_addr_q;
|
||||
logic [31:0] in_rdata_n, in_rdata_q;
|
||||
logic in_valid_n, in_valid_q;
|
||||
|
@ -84,12 +86,14 @@ module fetch_fifo
|
|||
in_rdata_n = in_rdata_i;
|
||||
in_valid_n = in_valid_i;
|
||||
branch_predict_n = branch_predict_i;
|
||||
ex_n = ex_i;
|
||||
// otherwise stall
|
||||
end else begin
|
||||
in_addr_n = in_addr_q;
|
||||
in_rdata_n = in_rdata_q;
|
||||
in_valid_n = in_valid_q;
|
||||
branch_predict_n = branch_predict_q;
|
||||
ex_n = ex_q;
|
||||
end
|
||||
// flush the input registers
|
||||
if (flush_i) begin
|
||||
|
@ -140,7 +144,7 @@ module fetch_fifo
|
|||
if (in_rdata_q[1:0] != 2'b11) begin
|
||||
// it is compressed
|
||||
mem_n[write_pointer_q] = {
|
||||
branch_predict_q, in_addr_q, decompressed_instruction[0], 1'b1, is_illegal[0]
|
||||
branch_predict_q, ex_q, in_addr_q, decompressed_instruction[0], 1'b1, is_illegal[0]
|
||||
};
|
||||
|
||||
status_cnt++;
|
||||
|
@ -155,7 +159,7 @@ module fetch_fifo
|
|||
if (in_rdata_q[17:16] != 2'b11 && !(branch_predict_q.valid && branch_predict_q.predict_taken && branch_predict_q.is_lower_16)) begin
|
||||
|
||||
mem_n[write_pointer_q + 1'b1] = {
|
||||
branch_predict_q, {in_addr_q[63:2], 2'b10}, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
branch_predict_q, ex_q, {in_addr_q[63:2], 2'b10}, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
};
|
||||
|
||||
status_cnt++;
|
||||
|
@ -181,7 +185,7 @@ module fetch_fifo
|
|||
// | instruction [31:0] |
|
||||
// |______________________
|
||||
mem_n[write_pointer_q] = {
|
||||
branch_predict_q, in_addr_q, in_rdata_q, 1'b0, 1'b0
|
||||
branch_predict_q, ex_q, in_addr_q, in_rdata_q, 1'b0, 1'b0
|
||||
};
|
||||
status_cnt++;
|
||||
write_pointer++;
|
||||
|
@ -192,7 +196,7 @@ module fetch_fifo
|
|||
if (in_valid_q && unaligned_q) begin
|
||||
|
||||
mem_n[write_pointer_q] = {
|
||||
branch_predict_q, unaligned_address_q, {in_rdata_q[15:0], unaligned_instr_q}, 1'b0, 1'b0
|
||||
branch_predict_q, ex_q, unaligned_address_q, {in_rdata_q[15:0], unaligned_instr_q}, 1'b0, 1'b0
|
||||
};
|
||||
|
||||
status_cnt++;
|
||||
|
@ -206,7 +210,7 @@ module fetch_fifo
|
|||
// but only if we predicted it to be taken, the predict was on the lower 16 bit compressed instruction
|
||||
if (in_rdata_q[17:16] != 2'b11 && !(branch_predict_q.valid && branch_predict_q.predict_taken && branch_predict_q.is_lower_16)) begin
|
||||
mem_n[write_pointer_q + 1'b1] = {
|
||||
branch_predict_q, {in_addr_q[63:2], 2'b10}, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
branch_predict_q, ex_q, {in_addr_q[63:2], 2'b10}, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
};
|
||||
|
||||
status_cnt++;
|
||||
|
@ -240,7 +244,7 @@ module fetch_fifo
|
|||
if (in_rdata_q[17:16] != 2'b11) begin
|
||||
// it is compressed
|
||||
mem_n[write_pointer_q] = {
|
||||
branch_predict_q, in_addr_q, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
branch_predict_q, ex_q, in_addr_q, decompressed_instruction[1], 1'b1, is_illegal[1]
|
||||
};
|
||||
|
||||
status_cnt++;
|
||||
|
@ -296,6 +300,7 @@ module fetch_fifo
|
|||
in_rdata_q <= 32'b0;
|
||||
in_valid_q <= 1'b0;
|
||||
branch_predict_q <= '{default: 0};
|
||||
ex_q <= '{default: 0};
|
||||
end else begin
|
||||
status_cnt_q <= status_cnt_n;
|
||||
mem_q <= mem_n;
|
||||
|
@ -309,6 +314,7 @@ module fetch_fifo
|
|||
in_rdata_q <= in_rdata_n;
|
||||
in_valid_q <= in_valid_n;
|
||||
branch_predict_q <= branch_predict_n;
|
||||
ex_q <= ex_n;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ module id_stage #(
|
|||
input fetch_entry fetch_entry_i,
|
||||
input logic fetch_entry_valid_i,
|
||||
output logic decoded_instr_ack_o,
|
||||
input exception ex_if_i, // we already got an exception in IF
|
||||
// from CSR file
|
||||
input priv_lvl_t priv_lvl_i, // current privilege level
|
||||
input logic tvm_i,
|
||||
|
@ -99,9 +98,6 @@ module id_stage #(
|
|||
logic issue_instr_valid_sb_iro;
|
||||
logic issue_ack_iro_sb;
|
||||
// ---------------------------------------------------
|
||||
// Compressed Decoder <-> Decoder
|
||||
// ---------------------------------------------------
|
||||
// ---------------------------------------------------
|
||||
// Decoder (DC) <-> Scoreboard (SB)
|
||||
// ---------------------------------------------------
|
||||
scoreboard_entry decoded_instr_dc_sb;
|
||||
|
@ -110,9 +106,9 @@ module id_stage #(
|
|||
// ---------------------------------------------------
|
||||
logic is_control_flow_instr;
|
||||
|
||||
// -----------------
|
||||
// Branch logic
|
||||
// -----------------
|
||||
// ---------------------------------------------------
|
||||
// Branch (resolve) logic
|
||||
// ---------------------------------------------------
|
||||
// This should basically prevent the scoreboard from accepting
|
||||
// instructions past a branch. We need to resolve the branch beforehand.
|
||||
// This limitation is in place to ease the backtracking of mis-predicted branches as they
|
||||
|
@ -145,7 +141,7 @@ module id_stage #(
|
|||
.instruction_i ( fetch_entry_i.instruction ),
|
||||
.branch_predict_i ( fetch_entry_i.branch_predict ),
|
||||
.is_illegal_i ( fetch_entry_i.is_illegal ),
|
||||
.ex_i ( ex_if_i ),
|
||||
.ex_i ( fetch_entry_i.ex ),
|
||||
.instruction_o ( decoded_instr_dc_sb ),
|
||||
.is_control_flow_instr_o ( is_control_flow_instr ),
|
||||
.*
|
||||
|
|
|
@ -36,11 +36,11 @@ module if_stage (
|
|||
input logic instr_gnt_i,
|
||||
input logic instr_rvalid_i,
|
||||
input logic [31:0] instr_rdata_i,
|
||||
input exception instr_ex_i, // Instruction fetch exception, valid if rvalid is one
|
||||
// Output of IF Pipeline stage
|
||||
output fetch_entry fetch_entry_o, // fetch entry containing all relevant data for the ID stage
|
||||
output logic fetch_entry_valid_i, // instruction in IF is valid
|
||||
input logic instr_ack_i, // ID acknowledged this instruction
|
||||
output exception ex_o // pass on if an fetch-exception happened
|
||||
input logic instr_ack_i // ID acknowledged this instruction
|
||||
);
|
||||
|
||||
enum logic [1:0] {IDLE, WAIT_GNT, WAIT_RVALID, WAIT_ABORTED } CS, NS;
|
||||
|
@ -66,6 +66,7 @@ module if_stage (
|
|||
//---------------------------------
|
||||
fetch_fifo fetch_fifo_i (
|
||||
.branch_predict_i ( branchpredict_q ),
|
||||
.ex_i ( instr_ex_i ),
|
||||
.in_addr_i ( instr_addr_q ),
|
||||
.in_rdata_i ( instr_rdata_i ),
|
||||
.in_valid_i ( fifo_valid ),
|
||||
|
@ -224,16 +225,12 @@ module if_stage (
|
|||
CS <= IDLE;
|
||||
instr_addr_q <= '0;
|
||||
branchpredict_q <= '{default: 0};
|
||||
ex_o <= '{default: 0};
|
||||
end else begin
|
||||
CS <= NS;
|
||||
if (addr_valid) begin
|
||||
instr_addr_q <= fetch_address_i;
|
||||
branchpredict_q <= branch_predict_i;
|
||||
end
|
||||
ex_o.cause <= 64'b0; // TODO: Output exception
|
||||
ex_o.tval <= 64'b0; // TODO: Output exception
|
||||
ex_o.valid <= 1'b0; //illegal_compressed_instr; // TODO: Output exception
|
||||
end
|
||||
end
|
||||
//-------------
|
||||
|
|
|
@ -46,6 +46,7 @@ module lsu #(
|
|||
output logic fetch_err_o, // Instruction fetch interface
|
||||
input logic [63:0] fetch_vaddr_i, // Instruction fetch interface
|
||||
output logic [31:0] fetch_rdata_o, // Instruction fetch interface
|
||||
output logic fetch_ex_o, // Instruction fetch interface
|
||||
|
||||
input priv_lvl_t priv_lvl_i, // From CSR register file
|
||||
input logic flag_pum_i, // From CSR register file
|
||||
|
|
|
@ -36,7 +36,8 @@ module mmu #(
|
|||
output logic fetch_valid_o,
|
||||
output logic fetch_err_o,
|
||||
input logic [63:0] fetch_vaddr_i,
|
||||
output logic [31:0] fetch_rdata_o, // pass-through because of interfaces
|
||||
output logic [31:0] fetch_rdata_o, // pass-through because of interfaces
|
||||
output exception fetch_ex_o, // write-back fetch exceptions (e.g.: bus faults, page faults, etc.)
|
||||
// LSU interface
|
||||
// this is a more minimalistic interface because the actual addressing logic is handled
|
||||
// in the LSU as we distinguish load and stores, what we do here is simple address translation
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module regfile
|
||||
module regfile_ff
|
||||
#(
|
||||
parameter DATA_WIDTH = 32
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue