fix verilator and add clk gating cell (#114)

* fix verilator

* add clk gating cell

* remove prim_generic_buf from manifest

* fix comment
This commit is contained in:
Davide Schiavone 2023-05-24 15:18:26 +02:00 committed by GitHub
parent 67def6f46e
commit 9abe653e1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 189 additions and 213 deletions

View file

@ -51,6 +51,8 @@ run-simple-system: sw-simple-hello | $(Vcve2_simple_system)
build/lowrisc_cve2_cve2_simple_system_0/sim-verilator/Vcve2_simple_system \ build/lowrisc_cve2_cve2_simple_system_0/sim-verilator/Vcve2_simple_system \
--raminit=$(simple-system-program) --raminit=$(simple-system-program)
compile_verilator:
fusesoc --cores-root . run --no-export --target=lint --tool=verilator --setup --build lowrisc:cve2:cve2_top:0.1 2>&1 | tee buildsim.log
# Arty A7 FPGA example # Arty A7 FPGA example
# Use the following targets (depending on your hardware): # Use the following targets (depending on your hardware):

View file

@ -0,0 +1,30 @@
// Copyright 2017 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
// !!! cve2_sim_clock_gate file is meant for simulation only !!!
// !!! It must not be used for ASIC synthesis !!!
// !!! It must not be used for FPGA synthesis !!!
module cve2_clock_gate (
input logic clk_i,
input logic en_i,
input logic scan_cg_en_i,
output logic clk_o
);
logic clk_en;
always_latch begin
if (clk_i == 1'b0) clk_en <= en_i | scan_cg_en_i;
end
assign clk_o = clk_i & clk_en;
endmodule // cve2_clock_gate

View file

@ -61,5 +61,4 @@ ${DESIGN_RTL_DIR}/cve2_top.sv
${DESIGN_RTL_DIR}/cve2_top_tracing.sv ${DESIGN_RTL_DIR}/cve2_top_tracing.sv
${DESIGN_RTL_DIR}/cve2_tracer.sv ${DESIGN_RTL_DIR}/cve2_tracer.sv
${DESIGN_RTL_DIR}/../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_buf.sv ${DESIGN_RTL_DIR}/../bhv/cve2_sim_clock_gate.sv
${DESIGN_RTL_DIR}/../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_clock_gating.sv

View file

@ -12,7 +12,6 @@ filesets:
- lowrisc:prim:clock_gating - lowrisc:prim:clock_gating
- lowrisc:prim:lfsr - lowrisc:prim:lfsr
- lowrisc:cve2:cve2_pkg - lowrisc:cve2:cve2_pkg
- lowrisc:cve2:cve2_icache
- lowrisc:dv:dv_fcov_macros - lowrisc:dv:dv_fcov_macros
files: files:
- rtl/cve2_alu.sv - rtl/cve2_alu.sv
@ -33,7 +32,6 @@ filesets:
- rtl/cve2_prefetch_buffer.sv - rtl/cve2_prefetch_buffer.sv
- rtl/cve2_pmp.sv - rtl/cve2_pmp.sv
- rtl/cve2_wb_stage.sv - rtl/cve2_wb_stage.sv
- rtl/cve2_dummy_instr.sv
- rtl/cve2_core.sv - rtl/cve2_core.sv
- rtl/cve2_pmp_reset_default.svh: {is_include_file: true} - rtl/cve2_pmp_reset_default.svh: {is_include_file: true}
file_type: systemVerilogSource file_type: systemVerilogSource
@ -142,6 +140,7 @@ targets:
- tool_verilator ? (files_lint_verilator) - tool_verilator ? (files_lint_verilator)
- tool_veriblelint ? (files_lint_verible) - tool_veriblelint ? (files_lint_verible)
- files_rtl - files_rtl
- target_sim? (files_clk_gate)
- files_check_tool_requirements - files_check_tool_requirements
toplevel: cve2_core toplevel: cve2_core
parameters: parameters:

View file

@ -16,8 +16,6 @@ filesets:
- lowrisc:prim:ram_1p_scr - lowrisc:prim:ram_1p_scr
files: files:
- rtl/cve2_register_file_ff.sv # generic FF-based - rtl/cve2_register_file_ff.sv # generic FF-based
- rtl/cve2_register_file_fpga.sv # FPGA
- rtl/cve2_register_file_latch.sv # ASIC
- rtl/cve2_top.sv - rtl/cve2_top.sv
file_type: systemVerilogSource file_type: systemVerilogSource
@ -33,6 +31,11 @@ filesets:
depend: depend:
- lowrisc:tool:check_tool_requirements - lowrisc:tool:check_tool_requirements
files_clk_gate:
files:
- bhv/cve2_sim_clock_gate.sv
file_type: systemVerilogSource
parameters: parameters:
RVFI: RVFI:
datatype: bool datatype: bool
@ -131,6 +134,7 @@ targets:
- tool_verilator ? (files_lint_verilator) - tool_verilator ? (files_lint_verilator)
- tool_veriblelint ? (files_lint_verible) - tool_veriblelint ? (files_lint_verible)
- files_rtl - files_rtl
- target_sim? (files_clk_gate)
- files_check_tool_requirements - files_check_tool_requirements
toplevel: cve2_top toplevel: cve2_top
parameters: parameters:
@ -140,6 +144,8 @@ targets:
parameters: parameters:
- SYNTHESIS=true - SYNTHESIS=true
- RVFI=true - RVFI=true
filesets_append:
- files_clk_gate
default_tool: verilator default_tool: verilator
tools: tools:
verilator: verilator:
@ -149,6 +155,7 @@ targets:
# RAM primitives wider than 64bit (required for ECC) fail to build in # RAM primitives wider than 64bit (required for ECC) fail to build in
# Verilator without increasing the unroll count (see Verilator#1266) # Verilator without increasing the unroll count (see Verilator#1266)
- "--unroll-count 72" - "--unroll-count 72"
format: format:
filesets: filesets:
- files_rtl - files_rtl

View file

@ -70,3 +70,5 @@ lint_off -file "*/lowrisc_prim_*/rtl/*.sv"
lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrSeed*" lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrSeed*"
lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrPerm*" lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrPerm*"
lint_off -rule DECLFILENAME -file "*/bhv/cve2_sim_clock_gate.sv" -match "Filename 'cve2_sim_clock_gate' does not match MODULE name: 'cve2_clock_gate'"
lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" -match "Signal unoptimizable: Feedback to clock or circular logic: 'cve2_top.u_cve2_core.irqs'"

View file

@ -32,6 +32,8 @@ module cve2_core import cve2_pkg::*; #(
input logic clk_i, input logic clk_i,
input logic rst_ni, input logic rst_ni,
input logic test_en_i,
input logic [31:0] hart_id_i, input logic [31:0] hart_id_i,
input logic [31:0] boot_addr_i, input logic [31:0] boot_addr_i,
@ -102,9 +104,6 @@ module cve2_core import cve2_pkg::*; #(
`endif `endif
// CPU Control Signals // CPU Control Signals
// SEC_CM: FETCH.CTRL.LC_GATED
output logic alert_minor_o,
output logic alert_major_o,
output logic core_busy_o output logic core_busy_o
); );
@ -175,8 +174,6 @@ module cve2_core import cve2_pkg::*; #(
logic [4:0] rf_waddr_id; logic [4:0] rf_waddr_id;
logic [31:0] rf_wdata_id; logic [31:0] rf_wdata_id;
logic rf_we_id; logic rf_we_id;
logic rf_rd_a_wb_match;
logic rf_rd_b_wb_match;
// ALU Control // ALU Control
alu_op_e alu_operator_ex; alu_op_e alu_operator_ex;
@ -367,10 +364,8 @@ module cve2_core import cve2_pkg::*; #(
// available // available
assign perf_iside_wait = id_in_ready & ~instr_valid_id; assign perf_iside_wait = id_in_ready & ~instr_valid_id;
begin : g_instr_req_gated_non_secure // For non secure Ibex only the bottom bit of fetch enable is considered
// For non secure Ibex only the bottom bit of fetch enable is considered assign instr_req_gated = instr_req_int;
assign instr_req_gated = instr_req_int;
end
////////////// //////////////
// ID stage // // ID stage //
@ -500,8 +495,8 @@ module cve2_core import cve2_pkg::*; #(
.rf_waddr_id_o (rf_waddr_id), .rf_waddr_id_o (rf_waddr_id),
.rf_wdata_id_o (rf_wdata_id), .rf_wdata_id_o (rf_wdata_id),
.rf_we_id_o (rf_we_id), .rf_we_id_o (rf_we_id),
.rf_rd_a_wb_match_o(rf_rd_a_wb_match), .rf_rd_a_wb_match_o(),
.rf_rd_b_wb_match_o(rf_rd_b_wb_match), .rf_rd_b_wb_match_o(),
.rf_waddr_wb_i (rf_waddr_wb), .rf_waddr_wb_i (rf_waddr_wb),
.rf_wdata_fwd_wb_i(rf_wdata_fwd_wb), .rf_wdata_fwd_wb_i(rf_wdata_fwd_wb),
@ -659,15 +654,6 @@ module cve2_core import cve2_pkg::*; #(
.instr_done_wb_o(instr_done_wb) .instr_done_wb_o(instr_done_wb)
); );
/////////////////////////////
// Register file interface //
/////////////////////////////
assign rf_raddr_a_o = rf_raddr_a;
assign rf_waddr_wb_o = rf_waddr_wb;
assign rf_we_wb_o = rf_we_wb;
assign rf_raddr_b_o = rf_raddr_b;
/////////////////////// ///////////////////////
// Crash dump output // // Crash dump output //
/////////////////////// ///////////////////////
@ -677,12 +663,6 @@ module cve2_core import cve2_pkg::*; #(
assign crash_dump_o.last_data_addr = lsu_addr_last; assign crash_dump_o.last_data_addr = lsu_addr_last;
assign crash_dump_o.exception_addr = csr_mepc; assign crash_dump_o.exception_addr = csr_mepc;
///////////////////
// Alert outputs //
///////////////////
// Minor alert - core is in a recoverable state
assign alert_minor_o = 1'b0;
// Explict INC_ASSERT block to avoid unused signal lint warnings were asserts are not included // Explict INC_ASSERT block to avoid unused signal lint warnings were asserts are not included
`ifdef INC_ASSERT `ifdef INC_ASSERT
@ -726,26 +706,24 @@ module cve2_core import cve2_pkg::*; #(
//////////////////////// ////////////////////////
// RF (Register File) // // RF (Register File) //
//////////////////////// ////////////////////////
begin : gen_regfile_ff cve2_register_file_ff #(
cve2_register_file_ff #( .RV32E (RV32E),
.RV32E (RV32E), .DataWidth (32),
.DataWidth (32), .WordZeroVal (32'(prim_secded_pkg::SecdedInv3932ZeroWord))
.WordZeroVal (32'(prim_secded_pkg::SecdedInv3932ZeroWord)) ) register_file_i (
) register_file_i ( .clk_i (clk_i),
.clk_i (clk_i), .rst_ni(rst_ni),
.rst_ni(rst_ni),
.test_en_i (test_en_i), .test_en_i(test_en_i),
.raddr_a_i(rf_raddr_a), .raddr_a_i(rf_raddr_a),
.rdata_a_o(rf_rdata_a), .rdata_a_o(rf_rdata_a),
.raddr_b_i(rf_raddr_b), .raddr_b_i(rf_raddr_b),
.rdata_b_o(rf_rdata_b), .rdata_b_o(rf_rdata_b),
.waddr_a_i(rf_waddr_wb), .waddr_a_i(rf_waddr_wb),
.wdata_a_i(rf_wdata_wb), .wdata_a_i(rf_wdata_wb),
.we_a_i (rf_we_wb) .we_a_i (rf_we_wb)
); );
end
///////////////////////////////////////// /////////////////////////////////////////

View file

@ -166,7 +166,6 @@ module cve2_cs_registers #(
// CSRs // CSRs
priv_lvl_e priv_lvl_q, priv_lvl_d; priv_lvl_e priv_lvl_q, priv_lvl_d;
status_t mstatus_q, mstatus_d; status_t mstatus_q, mstatus_d;
logic mstatus_err;
logic mstatus_en; logic mstatus_en;
irqs_t mie_q, mie_d; irqs_t mie_q, mie_d;
logic mie_en; logic mie_en;
@ -179,7 +178,6 @@ module cve2_cs_registers #(
logic [31:0] mtval_q, mtval_d; logic [31:0] mtval_q, mtval_d;
logic mtval_en; logic mtval_en;
logic [31:0] mtvec_q, mtvec_d; logic [31:0] mtvec_q, mtvec_d;
logic mtvec_err;
logic mtvec_en; logic mtvec_en;
irqs_t mip; irqs_t mip;
dcsr_t dcsr_q, dcsr_d; dcsr_t dcsr_q, dcsr_d;
@ -200,7 +198,6 @@ module cve2_cs_registers #(
// PMP Signals // PMP Signals
logic [31:0] pmp_addr_rdata [PMP_MAX_REGIONS]; logic [31:0] pmp_addr_rdata [PMP_MAX_REGIONS];
logic [PMP_CFG_W-1:0] pmp_cfg_rdata [PMP_MAX_REGIONS]; logic [PMP_CFG_W-1:0] pmp_cfg_rdata [PMP_MAX_REGIONS];
logic pmp_csr_err;
pmp_mseccfg_t pmp_mseccfg; pmp_mseccfg_t pmp_mseccfg;
// Hardware performance monitor signals // Hardware performance monitor signals
@ -766,7 +763,7 @@ module cve2_cs_registers #(
.wr_data_i ({mstatus_d}), .wr_data_i ({mstatus_d}),
.wr_en_i (mstatus_en), .wr_en_i (mstatus_en),
.rd_data_o (mstatus_q), .rd_data_o (mstatus_q),
.rd_error_o(mstatus_err) .rd_error_o()
); );
// MEPC // MEPC
@ -853,7 +850,7 @@ module cve2_cs_registers #(
.wr_data_i (mtvec_d), .wr_data_i (mtvec_d),
.wr_en_i (mtvec_en), .wr_en_i (mtvec_en),
.rd_data_o (mtvec_q), .rd_data_o (mtvec_q),
.rd_error_o(mtvec_err) .rd_error_o()
); );
// DCSR // DCSR
@ -1128,7 +1125,6 @@ module cve2_cs_registers #(
.rd_error_o(pmp_mseccfg_err) .rd_error_o(pmp_mseccfg_err)
); );
assign pmp_csr_err = (|pmp_cfg_err) | (|pmp_addr_err) | pmp_mseccfg_err;
assign pmp_mseccfg = pmp_mseccfg_q; assign pmp_mseccfg = pmp_mseccfg_q;
end else begin : g_no_pmp_tieoffs end else begin : g_no_pmp_tieoffs
@ -1141,7 +1137,6 @@ module cve2_cs_registers #(
assign csr_pmp_cfg_o[i] = pmp_cfg_t'(1'b0); assign csr_pmp_cfg_o[i] = pmp_cfg_t'(1'b0);
assign csr_pmp_addr_o[i] = '0; assign csr_pmp_addr_o[i] = '0;
end end
assign pmp_csr_err = 1'b0;
assign pmp_mseccfg = '0; assign pmp_mseccfg = '0;
end end

View file

@ -84,12 +84,10 @@ module cve2_ex_block #(
// branch handling // branch handling
assign branch_decision_o = alu_cmp_result; assign branch_decision_o = alu_cmp_result;
begin : g_no_branch_target_alu // Unused bt_operand signals cause lint errors, this avoids them
// Unused bt_operand signals cause lint errors, this avoids them //logic [31:0] unused_bt_a_operand, unused_bt_b_operand;
//logic [31:0] unused_bt_a_operand, unused_bt_b_operand;
assign branch_target_o = alu_adder_result_ex_o; assign branch_target_o = alu_adder_result_ex_o;
end
///////// /////////
// ALU // // ALU //

View file

@ -148,13 +148,11 @@ module cve2_fetch_fifo #(
assign instr_addr_d = clear_i ? in_addr_i[31:1] : assign instr_addr_d = clear_i ? in_addr_i[31:1] :
instr_addr_next; instr_addr_next;
begin : g_instr_addr always_ff @(posedge clk_i or negedge rst_ni) begin
always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin
if (!rst_ni) begin instr_addr_q <= '0;
instr_addr_q <= '0; end else if (instr_addr_en) begin
end else if (instr_addr_en) begin instr_addr_q <= instr_addr_d;
instr_addr_q <= instr_addr_d;
end
end end
end end

View file

@ -298,32 +298,30 @@ module cve2_id_stage #(
endcase endcase
end end
begin : g_nobtalu op_a_sel_e unused_a_mux_sel;
op_a_sel_e unused_a_mux_sel; imm_b_sel_e unused_b_mux_sel;
imm_b_sel_e unused_b_mux_sel;
// Full main ALU immediate MUX for Operand B // Full main ALU immediate MUX for Operand B
always_comb begin : immediate_b_mux always_comb begin : immediate_b_mux
unique case (imm_b_mux_sel) unique case (imm_b_mux_sel)
IMM_B_I: imm_b = imm_i_type; IMM_B_I: imm_b = imm_i_type;
IMM_B_S: imm_b = imm_s_type; IMM_B_S: imm_b = imm_s_type;
IMM_B_B: imm_b = imm_b_type; IMM_B_B: imm_b = imm_b_type;
IMM_B_U: imm_b = imm_u_type; IMM_B_U: imm_b = imm_u_type;
IMM_B_J: imm_b = imm_j_type; IMM_B_J: imm_b = imm_j_type;
IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4; IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4;
IMM_B_INCR_ADDR: imm_b = 32'h4; IMM_B_INCR_ADDR: imm_b = 32'h4;
default: imm_b = 32'h4; default: imm_b = 32'h4;
endcase endcase
end
`ASSERT(IbexImmBMuxSelValid, instr_valid_i |-> imm_b_mux_sel inside {
IMM_B_I,
IMM_B_S,
IMM_B_B,
IMM_B_U,
IMM_B_J,
IMM_B_INCR_PC,
IMM_B_INCR_ADDR})
end end
`ASSERT(IbexImmBMuxSelValid, instr_valid_i |-> imm_b_mux_sel inside {
IMM_B_I,
IMM_B_S,
IMM_B_B,
IMM_B_U,
IMM_B_J,
IMM_B_INCR_PC,
IMM_B_INCR_ADDR})
// ALU MUX for Operand B // ALU MUX for Operand B
assign alu_operand_b = (alu_op_b_mux_sel == OP_B_IMM) ? imm_b : rf_rdata_b_fwd; assign alu_operand_b = (alu_op_b_mux_sel == OP_B_IMM) ? imm_b : rf_rdata_b_fwd;
@ -598,27 +596,25 @@ module cve2_id_stage #(
// Branch set control // // Branch set control //
//////////////////////// ////////////////////////
begin : g_branch_set_flop // SEC_CM: CORE.DATA_REG_SW.SCA
// SEC_CM: CORE.DATA_REG_SW.SCA // Branch set flopped without branch target ALU, or in fixed time execution mode
// Branch set flopped without branch target ALU, or in fixed time execution mode // (condition pass/fail used next cycle where branch target is calculated)
// (condition pass/fail used next cycle where branch target is calculated) logic branch_set_raw_q;
logic branch_set_raw_q;
always_ff @(posedge clk_i or negedge rst_ni) begin always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin if (!rst_ni) begin
branch_set_raw_q <= 1'b0; branch_set_raw_q <= 1'b0;
end else begin end else begin
branch_set_raw_q <= branch_set_raw_d; branch_set_raw_q <= branch_set_raw_d;
end
end end
// Branches always take two cycles in fixed time execution mode, with or without the branch
// target ALU (to avoid a path from the branch decision into the branch target ALU operand
// muxing).
assign branch_set_raw = branch_set_raw_q;
end end
// Branches always take two cycles in fixed time execution mode, with or without the branch
// target ALU (to avoid a path from the branch decision into the branch target ALU operand
// muxing).
assign branch_set_raw = branch_set_raw_q;
// Track whether the current instruction in ID/EX has done a branch or jump set. // Track whether the current instruction in ID/EX has done a branch or jump set.
assign branch_jump_set_done_d = (branch_set_raw | jump_set_raw | branch_jump_set_done_q) & assign branch_jump_set_done_d = (branch_set_raw | jump_set_raw | branch_jump_set_done_q) &
~instr_valid_clear_o; ~instr_valid_clear_o;

View file

@ -165,37 +165,35 @@ module cve2_if_stage import cve2_pkg::*; #(
// tell CS register file to initialize mtvec on boot // tell CS register file to initialize mtvec on boot
assign csr_mtvec_init_o = (pc_mux_i == PC_BOOT) & pc_set_i; assign csr_mtvec_init_o = (pc_mux_i == PC_BOOT) & pc_set_i;
begin : gen_prefetch_buffer // prefetch buffer, caches a fixed number of instructions
// prefetch buffer, caches a fixed number of instructions cve2_prefetch_buffer #(
cve2_prefetch_buffer #( ) prefetch_buffer_i (
) prefetch_buffer_i ( .clk_i ( clk_i ),
.clk_i ( clk_i ), .rst_ni ( rst_ni ),
.rst_ni ( rst_ni ),
.req_i ( req_i ), .req_i ( req_i ),
.branch_i ( branch_req ), .branch_i ( branch_req ),
.branch_mispredict_i ( nt_branch_mispredict_i ), .branch_mispredict_i ( nt_branch_mispredict_i ),
.mispredict_addr_i ( nt_branch_addr_i ), .mispredict_addr_i ( nt_branch_addr_i ),
.addr_i ( {fetch_addr_n[31:1], 1'b0} ), .addr_i ( {fetch_addr_n[31:1], 1'b0} ),
.ready_i ( fetch_ready ), .ready_i ( fetch_ready ),
.valid_o ( fetch_valid ), .valid_o ( fetch_valid ),
.rdata_o ( fetch_rdata ), .rdata_o ( fetch_rdata ),
.addr_o ( fetch_addr ), .addr_o ( fetch_addr ),
.err_o ( fetch_err ), .err_o ( fetch_err ),
.err_plus2_o ( fetch_err_plus2 ), .err_plus2_o ( fetch_err_plus2 ),
.instr_req_o ( instr_req_o ), .instr_req_o ( instr_req_o ),
.instr_addr_o ( instr_addr_o ), .instr_addr_o ( instr_addr_o ),
.instr_gnt_i ( instr_gnt_i ), .instr_gnt_i ( instr_gnt_i ),
.instr_rvalid_i ( instr_rvalid_i ), .instr_rvalid_i ( instr_rvalid_i ),
.instr_rdata_i ( instr_rdata_i ), .instr_rdata_i ( instr_rdata_i ),
.instr_err_i ( instr_err_i ), .instr_err_i ( instr_err_i ),
.busy_o ( prefetch_busy ) .busy_o ( prefetch_busy )
); );
end
assign unused_fetch_addr_n0 = fetch_addr_n[0]; assign unused_fetch_addr_n0 = fetch_addr_n[0];
@ -256,28 +254,26 @@ module cve2_if_stage import cve2_pkg::*; #(
// IF-ID pipeline registers, frozen when the ID stage is stalled // IF-ID pipeline registers, frozen when the ID stage is stalled
assign if_id_pipe_reg_we = instr_new_id_d; assign if_id_pipe_reg_we = instr_new_id_d;
begin : g_instr_rdata always_ff @(posedge clk_i or negedge rst_ni) begin
always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin
if (!rst_ni) begin instr_rdata_id_o <= '0;
instr_rdata_id_o <= '0; instr_rdata_alu_id_o <= '0;
instr_rdata_alu_id_o <= '0; instr_fetch_err_o <= '0;
instr_fetch_err_o <= '0; instr_fetch_err_plus2_o <= '0;
instr_fetch_err_plus2_o <= '0; instr_rdata_c_id_o <= '0;
instr_rdata_c_id_o <= '0; instr_is_compressed_id_o <= '0;
instr_is_compressed_id_o <= '0; illegal_c_insn_id_o <= '0;
illegal_c_insn_id_o <= '0; pc_id_o <= '0;
pc_id_o <= '0; end else if (if_id_pipe_reg_we) begin
end else if (if_id_pipe_reg_we) begin instr_rdata_id_o <= instr_decompressed;
instr_rdata_id_o <= instr_decompressed; // To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated. instr_rdata_alu_id_o <= instr_decompressed;
instr_rdata_alu_id_o <= instr_decompressed; instr_fetch_err_o <= if_instr_err;
instr_fetch_err_o <= if_instr_err; instr_fetch_err_plus2_o <= if_instr_err_plus2;
instr_fetch_err_plus2_o <= if_instr_err_plus2; instr_rdata_c_id_o <= if_instr_rdata[15:0];
instr_rdata_c_id_o <= if_instr_rdata[15:0]; instr_is_compressed_id_o <= instr_is_compressed;
instr_is_compressed_id_o <= instr_is_compressed; illegal_c_insn_id_o <= illegal_c_insn;
illegal_c_insn_id_o <= illegal_c_insn; pc_id_o <= pc_if_o;
pc_id_o <= pc_if_o;
end
end end
end end
@ -323,17 +319,15 @@ module cve2_if_stage import cve2_pkg::*; #(
end end
end end
begin : g_instr_skid always_ff @(posedge clk_i or negedge rst_ni) begin
always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin
if (!rst_ni) begin instr_skid_bp_taken_q <= '0;
instr_skid_bp_taken_q <= '0; instr_skid_data_q <= '0;
instr_skid_data_q <= '0; instr_skid_addr_q <= '0;
instr_skid_addr_q <= '0; end else if (instr_skid_en) begin
end else if (instr_skid_en) begin instr_skid_bp_taken_q <= predict_branch_taken;
instr_skid_bp_taken_q <= predict_branch_taken; instr_skid_data_q <= fetch_rdata;
instr_skid_data_q <= fetch_rdata; instr_skid_addr_q <= fetch_addr;
instr_skid_addr_q <= fetch_addr;
end
end end
end end

View file

@ -154,13 +154,11 @@ module cve2_prefetch_buffer #(
assign stored_addr_d = instr_addr; assign stored_addr_d = instr_addr;
// CPU resets with a branch, so no need to reset these addresses // CPU resets with a branch, so no need to reset these addresses
begin : g_stored_addr always_ff @(posedge clk_i or negedge rst_ni) begin
always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin
if (!rst_ni) begin stored_addr_q <= '0;
stored_addr_q <= '0; end else if (stored_addr_en) begin
end else if (stored_addr_en) begin stored_addr_q <= stored_addr_d;
stored_addr_q <= stored_addr_d;
end
end end
end end
// 2. fetch_addr_q // 2. fetch_addr_q
@ -174,13 +172,11 @@ module cve2_prefetch_buffer #(
// Current address + 4 // Current address + 4
{{29{1'b0}},(valid_new_req & ~valid_req_q),2'b00}; {{29{1'b0}},(valid_new_req & ~valid_req_q),2'b00};
begin : g_fetch_addr always_ff @(posedge clk_i or negedge rst_ni) begin
always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin
if (!rst_ni) begin fetch_addr_q <= '0;
fetch_addr_q <= '0; end else if (fetch_addr_en) begin
end else if (fetch_addr_en) begin fetch_addr_q <= fetch_addr_d;
fetch_addr_q <= fetch_addr_d;
end
end end
end end

View file

@ -61,10 +61,8 @@ module cve2_register_file_ff #(
end end
end end
begin : g_normal_r0 // R0 is nil
// R0 is nil assign rf_reg[0] = WordZeroVal;
assign rf_reg[0] = WordZeroVal;
end
assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1]; assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1];

View file

@ -38,7 +38,6 @@ module cve2_top import cve2_pkg::*; #(
input logic instr_rvalid_i, input logic instr_rvalid_i,
output logic [31:0] instr_addr_o, output logic [31:0] instr_addr_o,
input logic [31:0] instr_rdata_i, input logic [31:0] instr_rdata_i,
input logic [6:0] instr_rdata_intg_i,
input logic instr_err_i, input logic instr_err_i,
// Data memory interface // Data memory interface
@ -49,9 +48,7 @@ module cve2_top import cve2_pkg::*; #(
output logic [3:0] data_be_o, output logic [3:0] data_be_o,
output logic [31:0] data_addr_o, output logic [31:0] data_addr_o,
output logic [31:0] data_wdata_o, output logic [31:0] data_wdata_o,
output logic [6:0] data_wdata_intg_o,
input logic [31:0] data_rdata_i, input logic [31:0] data_rdata_i,
input logic [6:0] data_rdata_intg_i,
input logic data_err_i, input logic data_err_i,
// Interrupt inputs // Interrupt inputs
@ -99,18 +96,11 @@ module cve2_top import cve2_pkg::*; #(
`endif `endif
// CPU Control Signals // CPU Control Signals
output logic alert_minor_o, output logic core_sleep_o
output logic alert_major_internal_o,
output logic alert_major_bus_o,
output logic core_sleep_o,
// DFT bypass controls
input logic scan_rst_ni
); );
// Scrambling Parameter // Scrambling Parameter
localparam int unsigned NumAddrScrRounds = 0; localparam int unsigned NumAddrScrRounds = 0;
localparam int unsigned NumDiffRounds = NumAddrScrRounds;
// Physical Memory Protection // Physical Memory Protection
localparam bit PMPEnable = 1'b0; localparam bit PMPEnable = 1'b0;
@ -129,8 +119,6 @@ module cve2_top import cve2_pkg::*; #(
logic core_busy_d, core_busy_q; logic core_busy_d, core_busy_q;
logic clock_en; logic clock_en;
logic irq_pending; logic irq_pending;
// Alert signals
logic core_alert_major, core_alert_minor;
///////////////////// /////////////////////
// Main clock gate // // Main clock gate //
@ -147,10 +135,10 @@ module cve2_top import cve2_pkg::*; #(
assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i; assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i;
assign core_sleep_o = ~clock_en; assign core_sleep_o = ~clock_en;
prim_clock_gating core_clock_gate_i ( cve2_clock_gate core_clock_gate_i (
.clk_i (clk_i), .clk_i (clk_i),
.en_i (clock_en), .en_i (clock_en),
.test_en_i(test_en_i), .scan_cg_en_i(test_en_i),
.clk_o (clk) .clk_o (clk)
); );
@ -176,6 +164,7 @@ module cve2_top import cve2_pkg::*; #(
) u_cve2_core ( ) u_cve2_core (
.clk_i(clk), .clk_i(clk),
.rst_ni, .rst_ni,
.test_en_i,
.hart_id_i, .hart_id_i,
.boot_addr_i, .boot_addr_i,
@ -237,8 +226,6 @@ module cve2_top import cve2_pkg::*; #(
.rvfi_ext_mcycle, .rvfi_ext_mcycle,
`endif `endif
.alert_minor_o (core_alert_minor),
.alert_major_o (core_alert_major),
.core_busy_o (core_busy_d) .core_busy_o (core_busy_d)
); );
@ -246,15 +233,12 @@ module cve2_top import cve2_pkg::*; #(
// Rams Instantiation // // Rams Instantiation //
//////////////////////// ////////////////////////
begin : gen_norams prim_ram_1p_pkg::ram_1p_cfg_t unused_ram_cfg;
logic unused_ram_inputs;
prim_ram_1p_pkg::ram_1p_cfg_t unused_ram_cfg; assign unused_ram_cfg = ram_cfg_i;
logic unused_ram_inputs; assign unused_ram_inputs = (|NumAddrScrRounds);
assign unused_ram_cfg = ram_cfg_i;
assign unused_ram_inputs = (|NumAddrScrRounds);
end
// X checks for top-level outputs // X checks for top-level outputs
`ASSERT_KNOWN(IbexInstrReqX, instr_req_o) `ASSERT_KNOWN(IbexInstrReqX, instr_req_o)
@ -278,11 +262,11 @@ module cve2_top import cve2_pkg::*; #(
`ASSERT_KNOWN(IbexInstrGntX, instr_gnt_i) `ASSERT_KNOWN(IbexInstrGntX, instr_gnt_i)
`ASSERT_KNOWN(IbexInstrRValidX, instr_rvalid_i) `ASSERT_KNOWN(IbexInstrRValidX, instr_rvalid_i)
`ASSERT_KNOWN_IF(IbexInstrRPayloadX, `ASSERT_KNOWN_IF(IbexInstrRPayloadX,
{instr_rdata_i, instr_rdata_intg_i, instr_err_i}, instr_rvalid_i) {instr_rdata_i, instr_err_i}, instr_rvalid_i)
`ASSERT_KNOWN(IbexDataGntX, data_gnt_i) `ASSERT_KNOWN(IbexDataGntX, data_gnt_i)
`ASSERT_KNOWN(IbexDataRValidX, data_rvalid_i) `ASSERT_KNOWN(IbexDataRValidX, data_rvalid_i)
`ASSERT_KNOWN_IF(IbexDataRPayloadX, {data_rdata_i, data_rdata_intg_i, data_err_i}, data_rvalid_i) `ASSERT_KNOWN_IF(IbexDataRPayloadX, {data_rdata_i, data_err_i}, data_rvalid_i)
`ASSERT_KNOWN(IbexIrqX, {irq_software_i, irq_timer_i, irq_external_i, irq_fast_i, irq_nm_i}) `ASSERT_KNOWN(IbexIrqX, {irq_software_i, irq_timer_i, irq_external_i, irq_fast_i, irq_nm_i})