mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 13:07:46 -04:00
[secded] Switch to inverted ECC codes
Signed-off-by: Michael Schaffner <msf@google.com>
This commit is contained in:
parent
4df2221dee
commit
169785d071
10 changed files with 54 additions and 37 deletions
|
@ -58,7 +58,7 @@ Bus Integrity Checking
|
|||
----------------------
|
||||
|
||||
The core can optionally generate and verify check bits sent alongside the data for memory accesses.
|
||||
Checkbits are generated and checked using a 39/32 Hsaio code (see :file:`vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_enc.sv`).
|
||||
Checkbits are generated and checked using an inverted 39/32 Hsaio code (see :file:`vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_enc.sv`).
|
||||
When this feature is used, any mismatch in checkbits will generate a major alert.
|
||||
|
||||
This feature is only used if the core is configured with the SecureIbex parameter set.
|
||||
|
|
|
@ -72,7 +72,7 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
end
|
||||
end
|
||||
// Add correct integrity bits
|
||||
{req.intg, req.data} = prim_secded_pkg::prim_secded_39_32_enc(req.data);
|
||||
{req.intg, req.data} = prim_secded_pkg::prim_secded_inv_39_32_enc(req.data);
|
||||
`uvm_info(get_full_name(), $sformatf("Response transfer:\n%0s", req.sprint()), UVM_HIGH)
|
||||
start_item(req);
|
||||
finish_item(req);
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_assert.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_cipher_pkg.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_lfsr.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_28_22_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_28_22_dec.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_dec.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_72_64_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_72_64_dec.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_28_22_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_28_22_dec.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_dec.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_72_64_enc.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_72_64_dec.sv
|
||||
|
||||
// Until this list is generated by FuseSoC, we have to use manually generated
|
||||
// wrappers around the prim_* modules to instantiate the prim_generic_* ones,
|
||||
|
|
|
@ -779,19 +779,19 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic rf_ecc_err_a_id, rf_ecc_err_b_id;
|
||||
|
||||
// ECC checkbit generation for regiter file wdata
|
||||
prim_secded_39_32_enc regfile_ecc_enc (
|
||||
prim_secded_inv_39_32_enc regfile_ecc_enc (
|
||||
.data_i(rf_wdata_wb),
|
||||
.data_o(rf_wdata_wb_ecc_o)
|
||||
);
|
||||
|
||||
// ECC checking on register file rdata
|
||||
prim_secded_39_32_dec regfile_ecc_dec_a (
|
||||
prim_secded_inv_39_32_dec regfile_ecc_dec_a (
|
||||
.data_i (rf_rdata_a_ecc_i),
|
||||
.data_o (),
|
||||
.syndrome_o(),
|
||||
.err_o (rf_ecc_err_a)
|
||||
);
|
||||
prim_secded_39_32_dec regfile_ecc_dec_b (
|
||||
prim_secded_inv_39_32_dec regfile_ecc_dec_b (
|
||||
.data_i (rf_rdata_b_ecc_i),
|
||||
.data_o (),
|
||||
.syndrome_o(),
|
||||
|
|
|
@ -290,7 +290,7 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
assign tag_ecc_input_padded = {{22-IC_TAG_SIZE{1'b0}},fill_tag_ic0};
|
||||
assign tag_ecc_output_unused = tag_ecc_output_padded[21:IC_TAG_SIZE-1];
|
||||
|
||||
prim_secded_28_22_enc tag_ecc_enc (
|
||||
prim_secded_inv_28_22_enc tag_ecc_enc (
|
||||
.data_i (tag_ecc_input_padded),
|
||||
.data_o (tag_ecc_output_padded)
|
||||
);
|
||||
|
@ -299,7 +299,7 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
|
||||
// Dataram ECC
|
||||
for (genvar bank = 0; bank < IC_LINE_BEATS; bank++) begin : gen_ecc_banks
|
||||
prim_secded_39_32_enc data_ecc_enc (
|
||||
prim_secded_inv_39_32_enc data_ecc_enc (
|
||||
.data_i (fill_wdata_ic0[bank*BUS_SIZE+:BUS_SIZE]),
|
||||
.data_o (data_wdata_ic0[bank*BusSizeECC+:BusSizeECC])
|
||||
);
|
||||
|
@ -421,7 +421,7 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
{22-IC_TAG_SIZE{1'b0}},
|
||||
tag_rdata_ic1[way][IC_TAG_SIZE-1:0]};
|
||||
|
||||
prim_secded_28_22_dec data_ecc_dec (
|
||||
prim_secded_inv_28_22_dec data_ecc_dec (
|
||||
.data_i (tag_rdata_padded_ic1),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
|
@ -433,7 +433,7 @@ module ibex_icache import ibex_pkg::*; #(
|
|||
// Data ECC checking
|
||||
// Note - could generate for all ways and mux after
|
||||
for (genvar bank = 0; bank < IC_LINE_BEATS; bank++) begin : gen_ecc_banks
|
||||
prim_secded_39_32_dec data_ecc_dec (
|
||||
prim_secded_inv_39_32_dec data_ecc_dec (
|
||||
.data_i (hit_data_ecc_ic1[bank*BusSizeECC+:BusSizeECC]),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
|
|
|
@ -216,14 +216,14 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic [31:0] unused_wdata;
|
||||
|
||||
// Checks on incoming data
|
||||
prim_secded_39_32_dec u_instr_intg_dec (
|
||||
prim_secded_inv_39_32_dec u_instr_intg_dec (
|
||||
.data_i ({instr_rdata_intg_q, shadow_inputs_q[LockstepOffset-1].instr_rdata}),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
.err_o (instr_intg_err)
|
||||
);
|
||||
|
||||
prim_secded_39_32_dec u_data_intg_dec (
|
||||
prim_secded_inv_39_32_dec u_data_intg_dec (
|
||||
.data_i ({data_rdata_intg_q, shadow_inputs_q[LockstepOffset-1].data_rdata}),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
|
@ -234,7 +234,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
(shadow_inputs_q[LockstepOffset-1].data_rvalid & |data_intg_err);
|
||||
|
||||
// Generate integrity bits
|
||||
prim_secded_39_32_enc u_data_gen (
|
||||
prim_secded_inv_39_32_enc u_data_gen (
|
||||
.data_i (data_wdata_i),
|
||||
.data_o ({data_wdata_intg_o, unused_wdata})
|
||||
);
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
* targeting FPGA synthesis or Verilator simulation.
|
||||
*/
|
||||
module ibex_register_file_ff #(
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0,
|
||||
parameter logic [DataWidth-1:0] WordZeroVal = '0
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -55,7 +56,7 @@ module ibex_register_file_ff #(
|
|||
for (genvar i = 1; i < NUM_WORDS; i++) begin : g_rf_flops
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rf_reg_q[i] <= '0;
|
||||
rf_reg_q[i] <= WordZeroVal;
|
||||
end else if (we_a_dec[i]) begin
|
||||
rf_reg_q[i] <= wdata_a_i;
|
||||
end
|
||||
|
@ -73,21 +74,21 @@ module ibex_register_file_ff #(
|
|||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rf_r0_q <= '0;
|
||||
rf_r0_q <= WordZeroVal;
|
||||
end else if (we_r0_dummy) begin
|
||||
rf_r0_q <= wdata_a_i;
|
||||
end
|
||||
end
|
||||
|
||||
// Output the dummy data for dummy instructions, otherwise R0 reads as zero
|
||||
assign rf_reg[0] = dummy_instr_id_i ? rf_r0_q : '0;
|
||||
assign rf_reg[0] = dummy_instr_id_i ? rf_r0_q : WordZeroVal;
|
||||
|
||||
end else begin : g_normal_r0
|
||||
logic unused_dummy_instr_id;
|
||||
assign unused_dummy_instr_id = dummy_instr_id_i;
|
||||
|
||||
// R0 is nil
|
||||
assign rf_reg[0] = '0;
|
||||
assign rf_reg[0] = WordZeroVal;
|
||||
end
|
||||
|
||||
assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1];
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
* FPGA architectures, it will produce RAM32M primitives. Other vendors have not yet been tested.
|
||||
*/
|
||||
module ibex_register_file_fpga #(
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0,
|
||||
parameter logic [DataWidth-1:0] WordZeroVal = '0
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -56,6 +57,13 @@ module ibex_register_file_fpga #(
|
|||
end
|
||||
end : sync_write
|
||||
|
||||
// Make sure we initialize the BRAM with the correct register reset value.
|
||||
initial begin
|
||||
for (int k = 0; k < NUM_WORDS; k++) begin
|
||||
mem[k] = WordZeroVal;
|
||||
end
|
||||
end
|
||||
|
||||
// Reset not used in this register file version
|
||||
logic unused_rst_ni;
|
||||
assign unused_rst_ni = rst_ni;
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
* register file when targeting ASIC synthesis or event-based simulators.
|
||||
*/
|
||||
module ibex_register_file_latch #(
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32,
|
||||
parameter bit DummyInstructions = 0,
|
||||
parameter logic [DataWidth-1:0] WordZeroVal = '0
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -78,7 +79,7 @@ module ibex_register_file_latch #(
|
|||
// Use clk_int here, since otherwise we don't want to write anything anyway.
|
||||
always_ff @(posedge clk_int or negedge rst_ni) begin : sample_wdata
|
||||
if (!rst_ni) begin
|
||||
wdata_a_q <= '0;
|
||||
wdata_a_q <= WordZeroVal;
|
||||
end else begin
|
||||
if (we_a_i) begin
|
||||
wdata_a_q <= wdata_a_i;
|
||||
|
@ -143,13 +144,13 @@ module ibex_register_file_latch #(
|
|||
end
|
||||
|
||||
// Output the dummy data for dummy instructions, otherwise R0 reads as zero
|
||||
assign mem[0] = dummy_instr_id_i ? mem_r0 : '0;
|
||||
assign mem[0] = dummy_instr_id_i ? mem_r0 : WordZeroVal;
|
||||
|
||||
end else begin : g_normal_r0
|
||||
logic unused_dummy_instr_id;
|
||||
assign unused_dummy_instr_id = dummy_instr_id_i;
|
||||
|
||||
assign mem[0] = '0;
|
||||
assign mem[0] = WordZeroVal;
|
||||
end
|
||||
|
||||
`ifdef VERILATOR
|
||||
|
|
|
@ -308,11 +308,16 @@ module ibex_top import ibex_pkg::*; #(
|
|||
// Register file Instantiation //
|
||||
/////////////////////////////////
|
||||
|
||||
// We're using an inverted Hsiao code, hence we need to reset
|
||||
// the regfile ECC bits to 1.
|
||||
localparam logic [RegFileDataWidth-1:0] WordZeroVal = RegFileDataWidth'({7'h7f, 32'h0});
|
||||
|
||||
if (RegFile == RegFileFF) begin : gen_regfile_ff
|
||||
ibex_register_file_ff #(
|
||||
.RV32E (RV32E),
|
||||
.DataWidth (RegFileDataWidth),
|
||||
.DummyInstructions(DummyInstructions)
|
||||
.DummyInstructions(DummyInstructions),
|
||||
.WordZeroVal (WordZeroVal)
|
||||
) register_file_i (
|
||||
.clk_i (clk),
|
||||
.rst_ni(rst_ni),
|
||||
|
@ -332,7 +337,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
ibex_register_file_fpga #(
|
||||
.RV32E (RV32E),
|
||||
.DataWidth (RegFileDataWidth),
|
||||
.DummyInstructions(DummyInstructions)
|
||||
.DummyInstructions(DummyInstructions),
|
||||
.WordZeroVal (WordZeroVal)
|
||||
) register_file_i (
|
||||
.clk_i (clk),
|
||||
.rst_ni(rst_ni),
|
||||
|
@ -352,7 +358,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
ibex_register_file_latch #(
|
||||
.RV32E (RV32E),
|
||||
.DataWidth (RegFileDataWidth),
|
||||
.DummyInstructions(DummyInstructions)
|
||||
.DummyInstructions(DummyInstructions),
|
||||
.WordZeroVal (WordZeroVal)
|
||||
) register_file_i (
|
||||
.clk_i (clk),
|
||||
.rst_ni(rst_ni),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue