mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
[rtl] Add ResetAll parameter
This parameter forces a reset of all registers inside the core. This is required to guarantee a common starting point for lockstep and thus prevent spurious lockstep failure alerts. Another minor change in this commit rearranges the writeback stage multiplexing to gate incoming lsu write data when not valid. This stops any X values from the data bus propagating to the register file signalling (and thus to the lockstep comparison) which would cause the lockstep alert to be X. It has the side effect of possibly reducing power consumption in the register file. Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
44777dc16d
commit
a1902004f9
9 changed files with 347 additions and 90 deletions
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
`include "prim_assert.sv"
|
||||
|
||||
module core_ibex_tb_top;
|
||||
|
||||
import uvm_pkg::*;
|
||||
|
@ -117,6 +119,9 @@ module core_ibex_tb_top;
|
|||
.core_sleep_o (dut_if.core_sleep )
|
||||
);
|
||||
|
||||
// We should never see any alerts triggered in normal testing
|
||||
`ASSERT(NoAlertsTriggered, clk, !rst_n, !dut_if.alert_minor && !dut_if.alert_major)
|
||||
|
||||
// Data load/store vif connection
|
||||
assign data_mem_vif.reset = ~rst_n;
|
||||
// Instruction fetch vif connnection
|
||||
|
|
|
@ -31,6 +31,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter bit DummyInstructions = 1'b0,
|
||||
parameter bit RegFileECC = 1'b0,
|
||||
|
@ -396,6 +397,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.TagSizeECC ( TagSizeECC ),
|
||||
.LineSizeECC ( LineSizeECC ),
|
||||
.PCIncrCheck ( PCIncrCheck ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.BranchPredictor ( BranchPredictor )
|
||||
) if_stage_i (
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -742,6 +744,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
);
|
||||
|
||||
ibex_wb_stage #(
|
||||
.ResetAll ( ResetAll ),
|
||||
.WritebackStage ( WritebackStage )
|
||||
) wb_stage_i (
|
||||
.clk_i ( clk_i ),
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
`include "prim_assert.sv"
|
||||
|
||||
module ibex_fetch_fifo #(
|
||||
parameter int unsigned NUM_REQS = 2
|
||||
parameter int unsigned NUM_REQS = 2,
|
||||
parameter bit ResetAll = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -149,9 +150,19 @@ module ibex_fetch_fifo #(
|
|||
assign instr_addr_d = clear_i ? in_addr_i[31:1] :
|
||||
instr_addr_next;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (instr_addr_en) begin
|
||||
instr_addr_q <= instr_addr_d;
|
||||
if (ResetAll) begin : g_instr_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
instr_addr_q <= '0;
|
||||
end else if (instr_addr_en) begin
|
||||
instr_addr_q <= instr_addr_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_instr_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (instr_addr_en) begin
|
||||
instr_addr_q <= instr_addr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -227,10 +238,22 @@ module ibex_fetch_fifo #(
|
|||
end
|
||||
|
||||
for (genvar i = 0; i < DEPTH; i++) begin : g_fifo_regs
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (entry_en[i]) begin
|
||||
rdata_q[i] <= rdata_d[i];
|
||||
err_q[i] <= err_d[i];
|
||||
if (ResetAll) begin : g_rdata_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rdata_q[i] <= '0;
|
||||
err_q[i] <= '0;
|
||||
end else if (entry_en[i]) begin
|
||||
rdata_q[i] <= rdata_d[i];
|
||||
err_q[i] <= err_d[i];
|
||||
end
|
||||
end
|
||||
end else begin : g_rdata_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (entry_en[i]) begin
|
||||
rdata_q[i] <= rdata_d[i];
|
||||
err_q[i] <= err_d[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
module ibex_icache import ibex_pkg::*; #(
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit ICacheECC = 1'b0,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter int unsigned BusSizeECC = BUS_SIZE,
|
||||
parameter int unsigned TagSizeECC = IC_TAG_SIZE,
|
||||
parameter int unsigned LineSizeECC = IC_LINE_SIZE,
|
||||
|
@ -206,9 +207,19 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
|
||||
assign branch_mispredict_addr_en = branch_i & predicted_branch_i;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= {output_addr_incr, 1'b0};
|
||||
if (ResetAll) begin : g_branch_misp_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
branch_mispredict_addr_q <= '0;
|
||||
end else if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= {output_addr_incr, 1'b0};
|
||||
end
|
||||
end
|
||||
end else begin : g_branch_misp_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= {output_addr_incr, 1'b0};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -240,9 +251,19 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
|
||||
assign prefetch_addr_en = branch_or_mispredict | lookup_grant_ic0;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (prefetch_addr_en) begin
|
||||
prefetch_addr_q <= prefetch_addr_d;
|
||||
if (ResetAll) begin : g_prefetch_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
prefetch_addr_q <= '0;
|
||||
end else if (prefetch_addr_en) begin
|
||||
prefetch_addr_q <= prefetch_addr_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_prefetch_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (prefetch_addr_en) begin
|
||||
prefetch_addr_q <= prefetch_addr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -356,10 +377,22 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (lookup_grant_ic0) begin
|
||||
lookup_addr_ic1 <= lookup_addr_ic0[ADDR_W-1:IC_INDEX_HI+1];
|
||||
fill_in_ic1 <= fill_alloc_sel;
|
||||
if (ResetAll) begin : g_lookup_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
lookup_addr_ic1 <= '0;
|
||||
fill_in_ic1 <= '0;
|
||||
end else if (lookup_grant_ic0) begin
|
||||
lookup_addr_ic1 <= lookup_addr_ic0[ADDR_W-1:IC_INDEX_HI+1];
|
||||
fill_in_ic1 <= fill_alloc_sel;
|
||||
end
|
||||
end
|
||||
end else begin : g_lookup_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (lookup_grant_ic0) begin
|
||||
lookup_addr_ic1 <= lookup_addr_ic0[ADDR_W-1:IC_INDEX_HI+1];
|
||||
fill_in_ic1 <= fill_alloc_sel;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -468,17 +501,39 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
end
|
||||
|
||||
// The index is required in IC1 only when ECC is configured so is registered here
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (lookup_grant_ic0) begin
|
||||
lookup_index_ic1 <= lookup_addr_ic0[IC_INDEX_HI-:IC_INDEX_W];
|
||||
if (ResetAll) begin : g_lookup_ind_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
lookup_index_ic1 <= '0;
|
||||
end else if (lookup_grant_ic0) begin
|
||||
lookup_index_ic1 <= lookup_addr_ic0[IC_INDEX_HI-:IC_INDEX_W];
|
||||
end
|
||||
end
|
||||
end else begin : g_lookup_ind_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (lookup_grant_ic0) begin
|
||||
lookup_index_ic1 <= lookup_addr_ic0[IC_INDEX_HI-:IC_INDEX_W];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Store the ways with errors to be invalidated
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (ecc_err_ic1) begin
|
||||
ecc_correction_ways_q <= ecc_correction_ways_d;
|
||||
ecc_correction_index_q <= lookup_index_ic1;
|
||||
if (ResetAll) begin : g_ecc_correction_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
ecc_correction_ways_q <= '0;
|
||||
ecc_correction_index_q <= '0;
|
||||
end else if (ecc_err_ic1) begin
|
||||
ecc_correction_ways_q <= ecc_correction_ways_d;
|
||||
ecc_correction_index_q <= lookup_index_ic1;
|
||||
end
|
||||
end
|
||||
end else begin : g_ecc_correction_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (ecc_err_ic1) begin
|
||||
ecc_correction_ways_q <= ecc_correction_ways_d;
|
||||
ecc_correction_index_q <= lookup_index_ic1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -765,15 +820,35 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
assign fill_addr_en[fb] = fill_alloc[fb];
|
||||
assign fill_way_en[fb] = (lookup_valid_ic1 & fill_in_ic1[fb]);
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_addr_en[fb]) begin
|
||||
fill_addr_q[fb] <= lookup_addr_ic0;
|
||||
if (ResetAll) begin : g_fill_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
fill_addr_q[fb] <= '0;
|
||||
end else if (fill_addr_en[fb]) begin
|
||||
fill_addr_q[fb] <= lookup_addr_ic0;
|
||||
end
|
||||
end
|
||||
end else begin : g_fill_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_addr_en[fb]) begin
|
||||
fill_addr_q[fb] <= lookup_addr_ic0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_way_en[fb]) begin
|
||||
fill_way_q[fb] <= sel_way_ic1;
|
||||
if (ResetAll) begin : g_fill_way_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
fill_way_q[fb] <= '0;
|
||||
end else if (fill_way_en[fb]) begin
|
||||
fill_way_q[fb] <= sel_way_ic1;
|
||||
end
|
||||
end
|
||||
end else begin : g_fill_way_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_way_en[fb]) begin
|
||||
fill_way_q[fb] <= sel_way_ic1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -811,9 +886,19 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
(fill_rvd_arb[fb] & ~fill_hit_q[fb] &
|
||||
(fill_rvd_off[fb] == b[IC_LINE_BEATS_W-1:0]));
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_data_en[fb][b]) begin
|
||||
fill_data_q[fb][b*BUS_SIZE+:BUS_SIZE] <= fill_data_d[fb][b*BUS_SIZE+:BUS_SIZE];
|
||||
if (ResetAll) begin : g_fill_data_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
fill_data_q[fb][b*BUS_SIZE+:BUS_SIZE] <= '0;
|
||||
end else if (fill_data_en[fb][b]) begin
|
||||
fill_data_q[fb][b*BUS_SIZE+:BUS_SIZE] <= fill_data_d[fb][b*BUS_SIZE+:BUS_SIZE];
|
||||
end
|
||||
end
|
||||
end else begin : g_fill_data_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fill_data_en[fb][b]) begin
|
||||
fill_data_q[fb][b*BUS_SIZE+:BUS_SIZE] <= fill_data_d[fb][b*BUS_SIZE+:BUS_SIZE];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -910,10 +995,22 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
|
||||
assign skid_en = data_valid & (ready_i | skid_ready);
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (skid_en) begin
|
||||
skid_data_q <= skid_data_d;
|
||||
skid_err_q <= output_err;
|
||||
if (ResetAll) begin : g_skid_data_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
skid_data_q <= '0;
|
||||
skid_err_q <= '0;
|
||||
end else if (skid_en) begin
|
||||
skid_data_q <= skid_data_d;
|
||||
skid_err_q <= output_err;
|
||||
end
|
||||
end
|
||||
end else begin : g_skid_data_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (skid_en) begin
|
||||
skid_data_q <= skid_data_d;
|
||||
skid_err_q <= output_err;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -974,9 +1071,19 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
branch_mispredict_i ? branch_mispredict_addr[31:1] :
|
||||
output_addr_incr;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (output_addr_en) begin
|
||||
output_addr_q <= output_addr_d;
|
||||
if (ResetAll) begin : g_output_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
output_addr_q <= '0;
|
||||
end else if (output_addr_en) begin
|
||||
output_addr_q <= output_addr_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_output_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (output_addr_en) begin
|
||||
output_addr_q <= output_addr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1036,9 +1143,19 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (inval_prog_d) begin
|
||||
inval_index_q <= inval_index_d;
|
||||
if (ResetAll) begin : g_inval_index_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
inval_index_q <= '0;
|
||||
end else if (inval_prog_d) begin
|
||||
inval_index_q <= inval_index_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_inval_index_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (inval_prog_d) begin
|
||||
inval_index_q <= inval_index_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
parameter int unsigned TagSizeECC = IC_TAG_SIZE,
|
||||
parameter int unsigned LineSizeECC = IC_LINE_SIZE,
|
||||
parameter bit PCIncrCheck = 1'b0,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter bit BranchPredictor = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
|
@ -199,6 +200,7 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
ibex_icache #(
|
||||
.BranchPredictor (BranchPredictor),
|
||||
.ICacheECC (ICacheECC),
|
||||
.ResetAll (ResetAll),
|
||||
.BusSizeECC (BusSizeECC),
|
||||
.TagSizeECC (TagSizeECC),
|
||||
.LineSizeECC (LineSizeECC)
|
||||
|
@ -247,7 +249,8 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
end else begin : gen_prefetch_buffer
|
||||
// prefetch buffer, caches a fixed number of instructions
|
||||
ibex_prefetch_buffer #(
|
||||
.BranchPredictor (BranchPredictor)
|
||||
.BranchPredictor (BranchPredictor),
|
||||
.ResetAll (ResetAll)
|
||||
) prefetch_buffer_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -402,17 +405,42 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
// IF-ID pipeline registers, frozen when the ID stage is stalled
|
||||
assign if_id_pipe_reg_we = instr_new_id_d;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (if_id_pipe_reg_we) begin
|
||||
instr_rdata_id_o <= instr_out;
|
||||
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
|
||||
instr_rdata_alu_id_o <= instr_out;
|
||||
instr_fetch_err_o <= instr_err_out;
|
||||
instr_fetch_err_plus2_o <= fetch_err_plus2;
|
||||
instr_rdata_c_id_o <= if_instr_rdata[15:0];
|
||||
instr_is_compressed_id_o <= instr_is_compressed_out;
|
||||
illegal_c_insn_id_o <= illegal_c_instr_out;
|
||||
pc_id_o <= pc_if_o;
|
||||
if (ResetAll) begin : g_instr_rdata_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
instr_rdata_id_o <= '0;
|
||||
instr_rdata_alu_id_o <= '0;
|
||||
instr_fetch_err_o <= '0;
|
||||
instr_fetch_err_plus2_o <= '0;
|
||||
instr_rdata_c_id_o <= '0;
|
||||
instr_is_compressed_id_o <= '0;
|
||||
illegal_c_insn_id_o <= '0;
|
||||
pc_id_o <= '0;
|
||||
end else if (if_id_pipe_reg_we) begin
|
||||
instr_rdata_id_o <= instr_out;
|
||||
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
|
||||
instr_rdata_alu_id_o <= instr_out;
|
||||
instr_fetch_err_o <= instr_err_out;
|
||||
instr_fetch_err_plus2_o <= fetch_err_plus2;
|
||||
instr_rdata_c_id_o <= if_instr_rdata[15:0];
|
||||
instr_is_compressed_id_o <= instr_is_compressed_out;
|
||||
illegal_c_insn_id_o <= illegal_c_instr_out;
|
||||
pc_id_o <= pc_if_o;
|
||||
end
|
||||
end
|
||||
end else begin : g_instr_rdata_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (if_id_pipe_reg_we) begin
|
||||
instr_rdata_id_o <= instr_out;
|
||||
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
|
||||
instr_rdata_alu_id_o <= instr_out;
|
||||
instr_fetch_err_o <= instr_err_out;
|
||||
instr_fetch_err_plus2_o <= fetch_err_plus2;
|
||||
instr_rdata_c_id_o <= if_instr_rdata[15:0];
|
||||
instr_is_compressed_id_o <= instr_is_compressed_out;
|
||||
illegal_c_insn_id_o <= illegal_c_instr_out;
|
||||
pc_id_o <= pc_if_o;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -455,9 +483,19 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
logic predict_branch_taken_raw;
|
||||
|
||||
// ID stages needs to know if branch was predicted taken so it can signal mispredicts
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (if_id_pipe_reg_we) begin
|
||||
instr_bp_taken_q <= instr_bp_taken_d;
|
||||
if (ResetAll) begin : g_bp_taken_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
instr_bp_taken_q <= '0;
|
||||
end else if (if_id_pipe_reg_we) begin
|
||||
instr_bp_taken_q <= instr_bp_taken_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_bp_taken_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (if_id_pipe_reg_we) begin
|
||||
instr_bp_taken_q <= instr_bp_taken_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -482,11 +520,25 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (instr_skid_en) begin
|
||||
instr_skid_bp_taken_q <= predict_branch_taken;
|
||||
instr_skid_data_q <= fetch_rdata;
|
||||
instr_skid_addr_q <= fetch_addr;
|
||||
if (ResetAll) begin : g_instr_skid_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
instr_skid_bp_taken_q <= '0;
|
||||
instr_skid_data_q <= '0;
|
||||
instr_skid_addr_q <= '0;
|
||||
end else if (instr_skid_en) begin
|
||||
instr_skid_bp_taken_q <= predict_branch_taken;
|
||||
instr_skid_data_q <= fetch_rdata;
|
||||
instr_skid_addr_q <= fetch_addr;
|
||||
end
|
||||
end
|
||||
end else begin : g_instr_skid_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (instr_skid_en) begin
|
||||
instr_skid_bp_taken_q <= predict_branch_taken;
|
||||
instr_skid_data_q <= fetch_rdata;
|
||||
instr_skid_addr_q <= fetch_addr;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter bit DummyInstructions = 1'b0,
|
||||
parameter bit RegFileECC = 1'b0,
|
||||
|
@ -285,6 +286,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.DbgTriggerEn ( DbgTriggerEn ),
|
||||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* paths to the instruction cache.
|
||||
*/
|
||||
module ibex_prefetch_buffer #(
|
||||
parameter bit BranchPredictor = 1'b0
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit ResetAll = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -109,7 +110,8 @@ module ibex_prefetch_buffer #(
|
|||
assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev);
|
||||
|
||||
ibex_fetch_fifo #(
|
||||
.NUM_REQS (NUM_REQS)
|
||||
.NUM_REQS (NUM_REQS),
|
||||
.ResetAll (ResetAll)
|
||||
) fifo_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -181,9 +183,19 @@ module ibex_prefetch_buffer #(
|
|||
assign stored_addr_d = instr_addr;
|
||||
|
||||
// CPU resets with a branch, so no need to reset these addresses
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (stored_addr_en) begin
|
||||
stored_addr_q <= stored_addr_d;
|
||||
if (ResetAll) begin : g_stored_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
stored_addr_q <= '0;
|
||||
end else if (stored_addr_en) begin
|
||||
stored_addr_q <= stored_addr_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_stored_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (stored_addr_en) begin
|
||||
stored_addr_q <= stored_addr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -196,9 +208,19 @@ module ibex_prefetch_buffer #(
|
|||
|
||||
assign branch_mispredict_addr_en = branch_i & predicted_branch_i;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= addr_next;
|
||||
if (ResetAll) begin : g_branch_misp_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
branch_mispredict_addr_q <= '0;
|
||||
end else if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= addr_next;
|
||||
end
|
||||
end
|
||||
end else begin : g_branch_misp_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (branch_mispredict_addr_en) begin
|
||||
branch_mispredict_addr_q <= addr_next;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -224,9 +246,19 @@ module ibex_prefetch_buffer #(
|
|||
// Current address + 4
|
||||
{{29{1'b0}},(valid_new_req & ~valid_req_q),2'b00};
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fetch_addr_en) begin
|
||||
fetch_addr_q <= fetch_addr_d;
|
||||
if (ResetAll) begin : g_fetch_addr_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
fetch_addr_q <= '0;
|
||||
end else if (fetch_addr_en) begin
|
||||
fetch_addr_q <= fetch_addr_d;
|
||||
end
|
||||
end
|
||||
end else begin : g_fetch_addr_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (fetch_addr_en) begin
|
||||
fetch_addr_q <= fetch_addr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ module ibex_top #(
|
|||
import ibex_pkg::*;
|
||||
|
||||
localparam bit Lockstep = SecureIbex;
|
||||
localparam bit ResetAll = Lockstep;
|
||||
localparam bit DummyInstructions = SecureIbex;
|
||||
localparam bit RegFileECC = SecureIbex;
|
||||
localparam int unsigned RegFileDataWidth = RegFileECC ? 32 + 7 : 32;
|
||||
|
@ -197,6 +198,7 @@ module ibex_top #(
|
|||
.DbgTriggerEn ( DbgTriggerEn ),
|
||||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
@ -651,6 +653,7 @@ module ibex_top #(
|
|||
.DbgTriggerEn ( DbgTriggerEn ),
|
||||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
@ -737,11 +740,7 @@ module ibex_top #(
|
|||
assign unused_scan = scan_rst_ni;
|
||||
end
|
||||
|
||||
// TODO - need a config to reset all registers before the lockstep alert can be used
|
||||
logic unused_lockstep_alert_major;
|
||||
assign unused_lockstep_alert_major = lockstep_alert_major;
|
||||
|
||||
assign alert_major_o = core_alert_major;// | lockstep_alert_major;
|
||||
assign alert_major_o = core_alert_major | lockstep_alert_major;
|
||||
assign alert_minor_o = core_alert_minor | lockstep_alert_minor;
|
||||
|
||||
`ASSERT_KNOWN(IbexAlertMinorX, alert_minor_o)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
`include "dv_fcov_macros.svh"
|
||||
|
||||
module ibex_wb_stage #(
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter bit WritebackStage = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
|
@ -92,15 +93,37 @@ module ibex_wb_stage #(
|
|||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if(en_wb_i) begin
|
||||
rf_we_wb_q <= rf_we_id_i;
|
||||
rf_waddr_wb_q <= rf_waddr_id_i;
|
||||
rf_wdata_wb_q <= rf_wdata_id_i;
|
||||
wb_instr_type_q <= instr_type_wb_i;
|
||||
wb_pc_q <= pc_id_i;
|
||||
wb_compressed_q <= instr_is_compressed_id_i;
|
||||
wb_count_q <= instr_perf_count_id_i;
|
||||
if (ResetAll) begin : g_wb_regs_ra
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rf_we_wb_q <= '0;
|
||||
rf_waddr_wb_q <= '0;
|
||||
rf_wdata_wb_q <= '0;
|
||||
wb_instr_type_q <= '0;
|
||||
wb_pc_q <= '0;
|
||||
wb_compressed_q <= '0;
|
||||
wb_count_q <= '0;
|
||||
end else if (en_wb_i) begin
|
||||
rf_we_wb_q <= rf_we_id_i;
|
||||
rf_waddr_wb_q <= rf_waddr_id_i;
|
||||
rf_wdata_wb_q <= rf_wdata_id_i;
|
||||
wb_instr_type_q <= instr_type_wb_i;
|
||||
wb_pc_q <= pc_id_i;
|
||||
wb_compressed_q <= instr_is_compressed_id_i;
|
||||
wb_count_q <= instr_perf_count_id_i;
|
||||
end
|
||||
end
|
||||
end else begin : g_wb_regs_nr
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (en_wb_i) begin
|
||||
rf_we_wb_q <= rf_we_id_i;
|
||||
rf_waddr_wb_q <= rf_waddr_id_i;
|
||||
rf_wdata_wb_q <= rf_wdata_id_i;
|
||||
wb_instr_type_q <= instr_type_wb_i;
|
||||
wb_pc_q <= pc_id_i;
|
||||
wb_compressed_q <= instr_is_compressed_id_i;
|
||||
wb_count_q <= instr_perf_count_id_i;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -170,7 +193,8 @@ module ibex_wb_stage #(
|
|||
|
||||
// RF write data can come from ID results (all RF writes that aren't because of loads will come
|
||||
// from here) or the LSU (RF writes for load data)
|
||||
assign rf_wdata_wb_o = rf_wdata_wb_mux_we[0] ? rf_wdata_wb_mux[0] : rf_wdata_wb_mux[1];
|
||||
assign rf_wdata_wb_o = ({32{rf_wdata_wb_mux_we[0]}} & rf_wdata_wb_mux[0]) |
|
||||
({32{rf_wdata_wb_mux_we[1]}} & rf_wdata_wb_mux[1]);
|
||||
assign rf_we_wb_o = |rf_wdata_wb_mux_we;
|
||||
|
||||
`DV_FCOV_SIGNAL_GEN_IF(logic, wb_valid, g_writeback_stage.wb_valid_q, WritebackStage)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue