Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/remove writeback stage #56

Merged
merged 10 commits into from
May 31, 2023
2 changes: 1 addition & 1 deletion cv32e20_manifest.flist
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ${DESIGN_RTL_DIR}/cve2_multdiv_slow.sv
${DESIGN_RTL_DIR}/cve2_prefetch_buffer.sv
${DESIGN_RTL_DIR}/cve2_pmp.sv
${DESIGN_RTL_DIR}/cve2_register_file_ff.sv
${DESIGN_RTL_DIR}/cve2_wb_stage.sv
${DESIGN_RTL_DIR}/cve2_wb.sv
${DESIGN_RTL_DIR}/cve2_core.sv
${DESIGN_RTL_DIR}/cve2_top.sv
${DESIGN_RTL_DIR}/cve2_top_tracing.sv
Expand Down
2 changes: 1 addition & 1 deletion cve2_core.core
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ filesets:
- rtl/cve2_multdiv_slow.sv
- rtl/cve2_prefetch_buffer.sv
- rtl/cve2_pmp.sv
- rtl/cve2_wb_stage.sv
- rtl/cve2_wb.sv
- rtl/cve2_core.sv
- rtl/cve2_pmp_reset_default.svh: {is_include_file: true}
file_type: systemVerilogSource
Expand Down
3 changes: 0 additions & 3 deletions doc/02_user/integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ Parameters
| | | | "cve2_pkg::RV32MFast": 3-4 cycle multiplier, iterative divider |
| | | | "cve2_pkg::RV32MSingleCycle": 1-2 cycle multiplier, iterative divider |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``WritebackStage`` | bit | 0 | *EXPERIMENTAL* - Enables third pipeline stage (writeback) |
| | | | improving performance of loads and stores |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``BranchPrediction`` | bit | 0 | *EXPERIMENTAL* Enable Static branch prediction |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``DmHaltAddr`` | int | 0x1A110800 | Address to jump to when entering Debug Mode |
Expand Down
7 changes: 0 additions & 7 deletions dv/riscv_compliance/cve2_riscv_compliance.core
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ parameters:
paramtype: vlogparam
description: "Enable ECC protection in instruction cache"

WritebackStage:
datatype: int
paramtype: vlogparam
default: 0
description: "Enables third pipeline stage (EXPERIMENTAL)"

BranchPredictor:
datatype: int
paramtype: vlogparam
Expand Down Expand Up @@ -114,7 +108,6 @@ targets:
- RegFile
- ICache
- ICacheECC
- WritebackStage
- BranchPredictor
- PMPEnable
- PMPGranularity
Expand Down
2 changes: 0 additions & 2 deletions dv/riscv_compliance/rtl/cve2_riscv_compliance.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module cve2_riscv_compliance (
parameter cve2_pkg::rv32m_e RV32M = cve2_pkg::RV32MFast;
parameter cve2_pkg::rv32b_e RV32B = cve2_pkg::RV32BNone;
parameter cve2_pkg::regfile_e RegFile = cve2_pkg::RegFileFF;
parameter bit WritebackStage = 1'b0;
parameter bit ICache = 1'b0;
parameter bit ICacheECC = 1'b0;
parameter bit BranchPredictor = 1'b0;
Expand Down Expand Up @@ -120,7 +119,6 @@ module cve2_riscv_compliance (
.RV32M (RV32M ),
.RV32B (RV32B ),
.RegFile (RegFile ),
.WritebackStage (WritebackStage ),
.ICache (ICache ),
.ICacheECC (ICacheECC ),
.BranchPredictor (BranchPredictor ),
Expand Down
7 changes: 0 additions & 7 deletions examples/simple_system/cve2_simple_system.core
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ parameters:
paramtype: vlogparam
description: "Path to a vmem file to initialize the RAM with"

WritebackStage:
datatype: int
paramtype: vlogparam
default: 0
description: "Enables third pipeline stage (EXPERIMENTAL)"

SecureIbex:
datatype: int
default: 0
Expand Down Expand Up @@ -109,7 +103,6 @@ targets:
- ICache
- ICacheScramble
- ICacheECC
- WritebackStage
- SecureIbex
- BranchPredictor
- PMPEnable
Expand Down
2 changes: 0 additions & 2 deletions examples/simple_system/rtl/cve2_simple_system.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ module cve2_simple_system (
parameter cve2_pkg::rv32m_e RV32M = `RV32M;
parameter cve2_pkg::rv32b_e RV32B = `RV32B;
parameter cve2_pkg::regfile_e RegFile = `RegFile;
parameter bit WritebackStage = 1'b0;
parameter bit ICache = 1'b0;
parameter bit ICacheECC = 1'b0;
parameter bit BranchPredictor = 1'b0;
Expand Down Expand Up @@ -174,7 +173,6 @@ module cve2_simple_system (
.RegFile ( RegFile ),
.ICache ( ICache ),
.ICacheECC ( ICacheECC ),
.WritebackStage ( WritebackStage ),
.BranchPredictor ( BranchPredictor ),
.DmHaltAddr ( 32'h00100000 ),
.DmExceptionAddr ( 32'h00100000 )
Expand Down
5 changes: 1 addition & 4 deletions formal/riscv-formal/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
# Provide a convenient way to create a Verilog source of Ibex.
# This is used by riscv-formal. See README.md for more details.

CVE2_ENABLE_WB ?= 0

# Name of the output file
IBEX_OUT := ibex.v
# Build folder name
Expand Down Expand Up @@ -45,7 +43,7 @@ SRCS_SV ?= \
$(SRC_DIR)/cve2_prefetch_buffer.sv \
$(SRC_DIR)/cve2_pmp.sv \
$(SRC_DIR)/cve2_register_file_ff.sv \
$(SRC_DIR)/cve2_wb_stage.sv \
$(SRC_DIR)/cve2_wb.sv \
$(SRC_DIR)/cve2_core.sv \
$(SRC_DIR)/cve2_top.sv

Expand Down Expand Up @@ -74,7 +72,6 @@ $(GEN_V): $(OUTDIR)%.v: $(SRC_DIR)%.sv $(PKGS) | $(OUTDIR)
$(IBEX_OUT): $(GEN_V) $(PRIM_CLOCK)
yosys -p "read_verilog $(PRIM_CLOCK) $(GEN_V)" \
-p "chparam -set RV32M 0 cve2_top" \
-p "chparam -set WritebackStage $(CVE2_ENABLE_WB) cve2_top" \
-p "synth -top cve2_top" \
-p "write_verilog $(IBEX_OUT)"

Expand Down
71 changes: 8 additions & 63 deletions rtl/cve2_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
`include "dv_fcov_macros.svh"

module cve2_controller #(
parameter bit WritebackStage = 0,
parameter bit BranchPredictor = 0
) (
input logic clk_i,
Expand Down Expand Up @@ -58,7 +57,6 @@ module cve2_controller #(
input logic [31:0] lsu_addr_last_i, // for mtval
input logic load_err_i,
input logic store_err_i,
output logic wb_exception_o, // Instruction in WB taking an exception
output logic id_exception_o, // Instruction in ID taking an exception

// jump/branch signals
Expand Down Expand Up @@ -87,7 +85,6 @@ module cve2_controller #(

output logic csr_save_if_o,
output logic csr_save_id_o,
output logic csr_save_wb_o,
output logic csr_restore_mret_id_o,
output logic csr_restore_dret_id_o,
output logic csr_save_cause_o,
Expand All @@ -97,9 +94,7 @@ module cve2_controller #(

// stall & flush signals
input logic stall_id_i,
input logic stall_wb_i,
output logic flush_id_o,
input logic ready_wb_i,

// performance monitors
output logic perf_jump_o, // we are executing a jump
Expand Down Expand Up @@ -150,7 +145,6 @@ module cve2_controller #(
logic enter_debug_mode;
logic ebreak_into_debug;
logic handle_irq;
logic id_wb_pending;

logic [3:0] mfip_id;
logic unused_irq_timer;
Expand Down Expand Up @@ -236,40 +230,7 @@ module cve2_controller #(
// generic special request signal, applies to all instructions
assign special_req = special_req_pc_change | special_req_flush_only;

// Is there an instruction in ID or WB that has yet to complete?
assign id_wb_pending = instr_valid_i | ~ready_wb_i;

// Exception/fault prioritisation is taken from Table 3.7 of Priviledged Spec v1.11
if (WritebackStage) begin : g_wb_exceptions
always_comb begin
instr_fetch_err_prio = 0;
illegal_insn_prio = 0;
ecall_insn_prio = 0;
ebrk_insn_prio = 0;
store_err_prio = 0;
load_err_prio = 0;

// Note that with the writeback stage store/load errors occur on the instruction in writeback,
// all other exception/faults occur on the instruction in ID/EX. The faults from writeback
// must take priority as that instruction is architecurally ordered before the one in ID/EX.
if (store_err_q) begin
store_err_prio = 1'b1;
end else if (load_err_q) begin
load_err_prio = 1'b1;
end else if (instr_fetch_err) begin
instr_fetch_err_prio = 1'b1;
end else if (illegal_insn_q) begin
illegal_insn_prio = 1'b1;
end else if (ecall_insn) begin
ecall_insn_prio = 1'b1;
end else if (ebrk_insn) begin
ebrk_insn_prio = 1'b1;
end
end

// Instruction in writeback is generating an exception so instruction in ID must not execute
assign wb_exception_o = load_err_q | store_err_q | load_err_i | store_err_i;
end else begin : g_no_wb_exceptions
always_comb begin
instr_fetch_err_prio = 0;
illegal_insn_prio = 0;
Expand All @@ -292,8 +253,6 @@ module cve2_controller #(
load_err_prio = 1'b1;
end
end
assign wb_exception_o = 1'b0;
end

`ASSERT_IF(IbexExceptionPrioOnehot,
$onehot({instr_fetch_err_prio,
Expand Down Expand Up @@ -370,7 +329,6 @@ module cve2_controller #(

csr_save_if_o = 1'b0;
csr_save_id_o = 1'b0;
csr_save_wb_o = 1'b0;
csr_restore_mret_id_o = 1'b0;
csr_restore_dret_id_o = 1'b0;
csr_save_cause_o = 1'b0;
Expand Down Expand Up @@ -494,15 +452,9 @@ module cve2_controller #(
// FLUSH state.
retain_id = 1'b1;

// Wait for the writeback stage to either be ready for a new instruction or raise its own
// exception before going to FLUSH. If the instruction in writeback raises an exception it
// must take priority over any exception from an instruction in ID/EX. Only once the
// writeback stage is ready can we be certain that won't happen. Without a writeback
// stage ready_wb_i == 1 so the FSM will always go directly to FLUSH.
// The FSM will always go directly to FLUSH.

if (ready_wb_i | wb_exception_o) begin
ctrl_fsm_ns = FLUSH;
end
ctrl_fsm_ns = FLUSH;
end

if (branch_set_i || jump_set_i) begin
Expand All @@ -522,12 +474,12 @@ module cve2_controller #(
end

// If entering debug mode or handling an IRQ the core needs to wait until any instruction in
// ID or WB has finished executing. Stall IF during that time.
if ((enter_debug_mode || handle_irq) && (stall || id_wb_pending)) begin
// ID has finished executing. Stall IF during that time.
if ((enter_debug_mode || handle_irq) && (stall || instr_valid_i)) begin
halt_if = 1'b1;
end

if (!stall && !special_req && !id_wb_pending) begin
if (!stall && !special_req && !instr_valid_i) begin
if (enter_debug_mode) begin
// enter debug mode
ctrl_fsm_ns = DBG_TAKEN_IF;
Expand Down Expand Up @@ -654,13 +606,7 @@ module cve2_controller #(
pc_mux_o = PC_EXC;
exc_pc_mux_o = debug_mode_q ? EXC_PC_DBG_EXC : EXC_PC_EXC;

if (WritebackStage) begin : g_writeback_mepc_save
// With the writeback stage present whether an instruction accessing memory will cause
// an exception is only known when it is in writeback. So when taking such an exception
// epc must come from writeback.
csr_save_id_o = ~(store_err_q | load_err_q);
csr_save_wb_o = store_err_q | load_err_q;
end else begin : g_no_writeback_mepc_save
begin : g_no_writeback_mepc_save
csr_save_id_o = 1'b0;
end

Expand Down Expand Up @@ -776,9 +722,8 @@ module cve2_controller #(
///////////////////

// If high current instruction cannot complete this cycle. Either because it needs more cycles to
// finish (stall_id_i) or because the writeback stage cannot accept it yet (stall_wb_i). If there
// is no writeback stage stall_wb_i is a constant 0.
assign stall = stall_id_i | stall_wb_i;
// finish (stall_id_i)
assign stall = stall_id_i;

// signal to IF stage that ID stage is ready for next instr
assign id_in_ready_o = ~stall & ~halt_if & ~retain_id;
Expand Down
Loading