mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-06-27 17:01:13 -04:00
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:
parent
67def6f46e
commit
9abe653e1b
15 changed files with 189 additions and 213 deletions
2
Makefile
2
Makefile
|
@ -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 \
|
||||
--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
|
||||
# Use the following targets (depending on your hardware):
|
||||
|
|
30
bhv/cve2_sim_clock_gate.sv
Normal file
30
bhv/cve2_sim_clock_gate.sv
Normal 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
|
|
@ -61,5 +61,4 @@ ${DESIGN_RTL_DIR}/cve2_top.sv
|
|||
${DESIGN_RTL_DIR}/cve2_top_tracing.sv
|
||||
${DESIGN_RTL_DIR}/cve2_tracer.sv
|
||||
|
||||
${DESIGN_RTL_DIR}/../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_buf.sv
|
||||
${DESIGN_RTL_DIR}/../vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_clock_gating.sv
|
||||
${DESIGN_RTL_DIR}/../bhv/cve2_sim_clock_gate.sv
|
||||
|
|
|
@ -12,7 +12,6 @@ filesets:
|
|||
- lowrisc:prim:clock_gating
|
||||
- lowrisc:prim:lfsr
|
||||
- lowrisc:cve2:cve2_pkg
|
||||
- lowrisc:cve2:cve2_icache
|
||||
- lowrisc:dv:dv_fcov_macros
|
||||
files:
|
||||
- rtl/cve2_alu.sv
|
||||
|
@ -33,7 +32,6 @@ filesets:
|
|||
- rtl/cve2_prefetch_buffer.sv
|
||||
- rtl/cve2_pmp.sv
|
||||
- rtl/cve2_wb_stage.sv
|
||||
- rtl/cve2_dummy_instr.sv
|
||||
- rtl/cve2_core.sv
|
||||
- rtl/cve2_pmp_reset_default.svh: {is_include_file: true}
|
||||
file_type: systemVerilogSource
|
||||
|
@ -142,6 +140,7 @@ targets:
|
|||
- tool_verilator ? (files_lint_verilator)
|
||||
- tool_veriblelint ? (files_lint_verible)
|
||||
- files_rtl
|
||||
- target_sim? (files_clk_gate)
|
||||
- files_check_tool_requirements
|
||||
toplevel: cve2_core
|
||||
parameters:
|
||||
|
|
|
@ -16,8 +16,6 @@ filesets:
|
|||
- lowrisc:prim:ram_1p_scr
|
||||
files:
|
||||
- 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
|
||||
file_type: systemVerilogSource
|
||||
|
||||
|
@ -33,6 +31,11 @@ filesets:
|
|||
depend:
|
||||
- lowrisc:tool:check_tool_requirements
|
||||
|
||||
files_clk_gate:
|
||||
files:
|
||||
- bhv/cve2_sim_clock_gate.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
parameters:
|
||||
RVFI:
|
||||
datatype: bool
|
||||
|
@ -131,6 +134,7 @@ targets:
|
|||
- tool_verilator ? (files_lint_verilator)
|
||||
- tool_veriblelint ? (files_lint_verible)
|
||||
- files_rtl
|
||||
- target_sim? (files_clk_gate)
|
||||
- files_check_tool_requirements
|
||||
toplevel: cve2_top
|
||||
parameters:
|
||||
|
@ -140,6 +144,8 @@ targets:
|
|||
parameters:
|
||||
- SYNTHESIS=true
|
||||
- RVFI=true
|
||||
filesets_append:
|
||||
- files_clk_gate
|
||||
default_tool: verilator
|
||||
tools:
|
||||
verilator:
|
||||
|
@ -149,6 +155,7 @@ targets:
|
|||
# RAM primitives wider than 64bit (required for ECC) fail to build in
|
||||
# Verilator without increasing the unroll count (see Verilator#1266)
|
||||
- "--unroll-count 72"
|
||||
|
||||
format:
|
||||
filesets:
|
||||
- files_rtl
|
||||
|
|
|
@ -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 "*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'"
|
||||
|
|
|
@ -32,6 +32,8 @@ module cve2_core import cve2_pkg::*; #(
|
|||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input logic test_en_i,
|
||||
|
||||
input logic [31:0] hart_id_i,
|
||||
input logic [31:0] boot_addr_i,
|
||||
|
||||
|
@ -102,9 +104,6 @@ module cve2_core import cve2_pkg::*; #(
|
|||
`endif
|
||||
|
||||
// CPU Control Signals
|
||||
// SEC_CM: FETCH.CTRL.LC_GATED
|
||||
output logic alert_minor_o,
|
||||
output logic alert_major_o,
|
||||
output logic core_busy_o
|
||||
);
|
||||
|
||||
|
@ -175,8 +174,6 @@ module cve2_core import cve2_pkg::*; #(
|
|||
logic [4:0] rf_waddr_id;
|
||||
logic [31:0] rf_wdata_id;
|
||||
logic rf_we_id;
|
||||
logic rf_rd_a_wb_match;
|
||||
logic rf_rd_b_wb_match;
|
||||
|
||||
// ALU Control
|
||||
alu_op_e alu_operator_ex;
|
||||
|
@ -367,10 +364,8 @@ module cve2_core import cve2_pkg::*; #(
|
|||
// available
|
||||
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
|
||||
assign instr_req_gated = instr_req_int;
|
||||
end
|
||||
// For non secure Ibex only the bottom bit of fetch enable is considered
|
||||
assign instr_req_gated = instr_req_int;
|
||||
|
||||
//////////////
|
||||
// ID stage //
|
||||
|
@ -500,8 +495,8 @@ module cve2_core import cve2_pkg::*; #(
|
|||
.rf_waddr_id_o (rf_waddr_id),
|
||||
.rf_wdata_id_o (rf_wdata_id),
|
||||
.rf_we_id_o (rf_we_id),
|
||||
.rf_rd_a_wb_match_o(rf_rd_a_wb_match),
|
||||
.rf_rd_b_wb_match_o(rf_rd_b_wb_match),
|
||||
.rf_rd_a_wb_match_o(),
|
||||
.rf_rd_b_wb_match_o(),
|
||||
|
||||
.rf_waddr_wb_i (rf_waddr_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)
|
||||
);
|
||||
|
||||
/////////////////////////////
|
||||
// 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 //
|
||||
///////////////////////
|
||||
|
@ -677,12 +663,6 @@ module cve2_core import cve2_pkg::*; #(
|
|||
assign crash_dump_o.last_data_addr = lsu_addr_last;
|
||||
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
|
||||
`ifdef INC_ASSERT
|
||||
|
@ -726,26 +706,24 @@ module cve2_core import cve2_pkg::*; #(
|
|||
////////////////////////
|
||||
// RF (Register File) //
|
||||
////////////////////////
|
||||
begin : gen_regfile_ff
|
||||
cve2_register_file_ff #(
|
||||
.RV32E (RV32E),
|
||||
.DataWidth (32),
|
||||
.WordZeroVal (32'(prim_secded_pkg::SecdedInv3932ZeroWord))
|
||||
) register_file_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni(rst_ni),
|
||||
cve2_register_file_ff #(
|
||||
.RV32E (RV32E),
|
||||
.DataWidth (32),
|
||||
.WordZeroVal (32'(prim_secded_pkg::SecdedInv3932ZeroWord))
|
||||
) register_file_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni(rst_ni),
|
||||
|
||||
.test_en_i (test_en_i),
|
||||
.test_en_i(test_en_i),
|
||||
|
||||
.raddr_a_i(rf_raddr_a),
|
||||
.rdata_a_o(rf_rdata_a),
|
||||
.raddr_b_i(rf_raddr_b),
|
||||
.rdata_b_o(rf_rdata_b),
|
||||
.waddr_a_i(rf_waddr_wb),
|
||||
.wdata_a_i(rf_wdata_wb),
|
||||
.we_a_i (rf_we_wb)
|
||||
);
|
||||
end
|
||||
.raddr_a_i(rf_raddr_a),
|
||||
.rdata_a_o(rf_rdata_a),
|
||||
.raddr_b_i(rf_raddr_b),
|
||||
.rdata_b_o(rf_rdata_b),
|
||||
.waddr_a_i(rf_waddr_wb),
|
||||
.wdata_a_i(rf_wdata_wb),
|
||||
.we_a_i (rf_we_wb)
|
||||
);
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
|
|
@ -166,7 +166,6 @@ module cve2_cs_registers #(
|
|||
// CSRs
|
||||
priv_lvl_e priv_lvl_q, priv_lvl_d;
|
||||
status_t mstatus_q, mstatus_d;
|
||||
logic mstatus_err;
|
||||
logic mstatus_en;
|
||||
irqs_t mie_q, mie_d;
|
||||
logic mie_en;
|
||||
|
@ -179,7 +178,6 @@ module cve2_cs_registers #(
|
|||
logic [31:0] mtval_q, mtval_d;
|
||||
logic mtval_en;
|
||||
logic [31:0] mtvec_q, mtvec_d;
|
||||
logic mtvec_err;
|
||||
logic mtvec_en;
|
||||
irqs_t mip;
|
||||
dcsr_t dcsr_q, dcsr_d;
|
||||
|
@ -200,7 +198,6 @@ module cve2_cs_registers #(
|
|||
// PMP Signals
|
||||
logic [31:0] pmp_addr_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;
|
||||
|
||||
// Hardware performance monitor signals
|
||||
|
@ -766,7 +763,7 @@ module cve2_cs_registers #(
|
|||
.wr_data_i ({mstatus_d}),
|
||||
.wr_en_i (mstatus_en),
|
||||
.rd_data_o (mstatus_q),
|
||||
.rd_error_o(mstatus_err)
|
||||
.rd_error_o()
|
||||
);
|
||||
|
||||
// MEPC
|
||||
|
@ -853,7 +850,7 @@ module cve2_cs_registers #(
|
|||
.wr_data_i (mtvec_d),
|
||||
.wr_en_i (mtvec_en),
|
||||
.rd_data_o (mtvec_q),
|
||||
.rd_error_o(mtvec_err)
|
||||
.rd_error_o()
|
||||
);
|
||||
|
||||
// DCSR
|
||||
|
@ -1128,7 +1125,6 @@ module cve2_cs_registers #(
|
|||
.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;
|
||||
|
||||
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_addr_o[i] = '0;
|
||||
end
|
||||
assign pmp_csr_err = 1'b0;
|
||||
assign pmp_mseccfg = '0;
|
||||
end
|
||||
|
||||
|
|
|
@ -84,12 +84,10 @@ module cve2_ex_block #(
|
|||
// branch handling
|
||||
assign branch_decision_o = alu_cmp_result;
|
||||
|
||||
begin : g_no_branch_target_alu
|
||||
// Unused bt_operand signals cause lint errors, this avoids them
|
||||
//logic [31:0] unused_bt_a_operand, unused_bt_b_operand;
|
||||
// Unused bt_operand signals cause lint errors, this avoids them
|
||||
//logic [31:0] unused_bt_a_operand, unused_bt_b_operand;
|
||||
|
||||
assign branch_target_o = alu_adder_result_ex_o;
|
||||
end
|
||||
assign branch_target_o = alu_adder_result_ex_o;
|
||||
|
||||
/////////
|
||||
// ALU //
|
||||
|
|
|
@ -148,13 +148,11 @@ module cve2_fetch_fifo #(
|
|||
assign instr_addr_d = clear_i ? in_addr_i[31:1] :
|
||||
instr_addr_next;
|
||||
|
||||
begin : g_instr_addr
|
||||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -298,32 +298,30 @@ module cve2_id_stage #(
|
|||
endcase
|
||||
end
|
||||
|
||||
begin : g_nobtalu
|
||||
op_a_sel_e unused_a_mux_sel;
|
||||
imm_b_sel_e unused_b_mux_sel;
|
||||
op_a_sel_e unused_a_mux_sel;
|
||||
imm_b_sel_e unused_b_mux_sel;
|
||||
|
||||
// Full main ALU immediate MUX for Operand B
|
||||
always_comb begin : immediate_b_mux
|
||||
unique case (imm_b_mux_sel)
|
||||
IMM_B_I: imm_b = imm_i_type;
|
||||
IMM_B_S: imm_b = imm_s_type;
|
||||
IMM_B_B: imm_b = imm_b_type;
|
||||
IMM_B_U: imm_b = imm_u_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_ADDR: imm_b = 32'h4;
|
||||
default: imm_b = 32'h4;
|
||||
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})
|
||||
// Full main ALU immediate MUX for Operand B
|
||||
always_comb begin : immediate_b_mux
|
||||
unique case (imm_b_mux_sel)
|
||||
IMM_B_I: imm_b = imm_i_type;
|
||||
IMM_B_S: imm_b = imm_s_type;
|
||||
IMM_B_B: imm_b = imm_b_type;
|
||||
IMM_B_U: imm_b = imm_u_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_ADDR: imm_b = 32'h4;
|
||||
default: imm_b = 32'h4;
|
||||
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})
|
||||
|
||||
// ALU MUX for Operand B
|
||||
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 //
|
||||
////////////////////////
|
||||
|
||||
begin : g_branch_set_flop
|
||||
// SEC_CM: CORE.DATA_REG_SW.SCA
|
||||
// Branch set flopped without branch target ALU, or in fixed time execution mode
|
||||
// (condition pass/fail used next cycle where branch target is calculated)
|
||||
logic branch_set_raw_q;
|
||||
// SEC_CM: CORE.DATA_REG_SW.SCA
|
||||
// Branch set flopped without branch target ALU, or in fixed time execution mode
|
||||
// (condition pass/fail used next cycle where branch target is calculated)
|
||||
logic branch_set_raw_q;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
branch_set_raw_q <= 1'b0;
|
||||
end else begin
|
||||
branch_set_raw_q <= branch_set_raw_d;
|
||||
end
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
branch_set_raw_q <= 1'b0;
|
||||
end else begin
|
||||
branch_set_raw_q <= branch_set_raw_d;
|
||||
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
|
||||
|
||||
// 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.
|
||||
assign branch_jump_set_done_d = (branch_set_raw | jump_set_raw | branch_jump_set_done_q) &
|
||||
~instr_valid_clear_o;
|
||||
|
|
|
@ -165,37 +165,35 @@ module cve2_if_stage import cve2_pkg::*; #(
|
|||
// tell CS register file to initialize mtvec on boot
|
||||
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
|
||||
cve2_prefetch_buffer #(
|
||||
) prefetch_buffer_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
// prefetch buffer, caches a fixed number of instructions
|
||||
cve2_prefetch_buffer #(
|
||||
) prefetch_buffer_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
||||
.req_i ( req_i ),
|
||||
.req_i ( req_i ),
|
||||
|
||||
.branch_i ( branch_req ),
|
||||
.branch_mispredict_i ( nt_branch_mispredict_i ),
|
||||
.mispredict_addr_i ( nt_branch_addr_i ),
|
||||
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
|
||||
.branch_i ( branch_req ),
|
||||
.branch_mispredict_i ( nt_branch_mispredict_i ),
|
||||
.mispredict_addr_i ( nt_branch_addr_i ),
|
||||
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
|
||||
|
||||
.ready_i ( fetch_ready ),
|
||||
.valid_o ( fetch_valid ),
|
||||
.rdata_o ( fetch_rdata ),
|
||||
.addr_o ( fetch_addr ),
|
||||
.err_o ( fetch_err ),
|
||||
.err_plus2_o ( fetch_err_plus2 ),
|
||||
.ready_i ( fetch_ready ),
|
||||
.valid_o ( fetch_valid ),
|
||||
.rdata_o ( fetch_rdata ),
|
||||
.addr_o ( fetch_addr ),
|
||||
.err_o ( fetch_err ),
|
||||
.err_plus2_o ( fetch_err_plus2 ),
|
||||
|
||||
.instr_req_o ( instr_req_o ),
|
||||
.instr_addr_o ( instr_addr_o ),
|
||||
.instr_gnt_i ( instr_gnt_i ),
|
||||
.instr_rvalid_i ( instr_rvalid_i ),
|
||||
.instr_rdata_i ( instr_rdata_i ),
|
||||
.instr_err_i ( instr_err_i ),
|
||||
.instr_req_o ( instr_req_o ),
|
||||
.instr_addr_o ( instr_addr_o ),
|
||||
.instr_gnt_i ( instr_gnt_i ),
|
||||
.instr_rvalid_i ( instr_rvalid_i ),
|
||||
.instr_rdata_i ( instr_rdata_i ),
|
||||
.instr_err_i ( instr_err_i ),
|
||||
|
||||
.busy_o ( prefetch_busy )
|
||||
);
|
||||
end
|
||||
.busy_o ( prefetch_busy )
|
||||
);
|
||||
|
||||
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
|
||||
assign if_id_pipe_reg_we = instr_new_id_d;
|
||||
|
||||
begin : g_instr_rdata
|
||||
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_decompressed;
|
||||
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
|
||||
instr_rdata_alu_id_o <= instr_decompressed;
|
||||
instr_fetch_err_o <= if_instr_err;
|
||||
instr_fetch_err_plus2_o <= if_instr_err_plus2;
|
||||
instr_rdata_c_id_o <= if_instr_rdata[15:0];
|
||||
instr_is_compressed_id_o <= instr_is_compressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
pc_id_o <= pc_if_o;
|
||||
end
|
||||
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_decompressed;
|
||||
// To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
|
||||
instr_rdata_alu_id_o <= instr_decompressed;
|
||||
instr_fetch_err_o <= if_instr_err;
|
||||
instr_fetch_err_plus2_o <= if_instr_err_plus2;
|
||||
instr_rdata_c_id_o <= if_instr_rdata[15:0];
|
||||
instr_is_compressed_id_o <= instr_is_compressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
pc_id_o <= pc_if_o;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -323,17 +319,15 @@ module cve2_if_stage import cve2_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
begin : g_instr_skid
|
||||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -154,13 +154,11 @@ module cve2_prefetch_buffer #(
|
|||
assign stored_addr_d = instr_addr;
|
||||
|
||||
// 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
|
||||
if (!rst_ni) begin
|
||||
stored_addr_q <= '0;
|
||||
end else if (stored_addr_en) begin
|
||||
stored_addr_q <= stored_addr_d;
|
||||
end
|
||||
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
|
||||
// 2. fetch_addr_q
|
||||
|
@ -174,13 +172,11 @@ module cve2_prefetch_buffer #(
|
|||
// Current address + 4
|
||||
{{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
|
||||
if (!rst_ni) begin
|
||||
fetch_addr_q <= '0;
|
||||
end else if (fetch_addr_en) begin
|
||||
fetch_addr_q <= fetch_addr_d;
|
||||
end
|
||||
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
|
||||
|
||||
|
|
|
@ -61,10 +61,8 @@ module cve2_register_file_ff #(
|
|||
end
|
||||
end
|
||||
|
||||
begin : g_normal_r0
|
||||
// R0 is nil
|
||||
assign rf_reg[0] = WordZeroVal;
|
||||
end
|
||||
// R0 is nil
|
||||
assign rf_reg[0] = WordZeroVal;
|
||||
|
||||
assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1];
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ module cve2_top import cve2_pkg::*; #(
|
|||
input logic instr_rvalid_i,
|
||||
output logic [31:0] instr_addr_o,
|
||||
input logic [31:0] instr_rdata_i,
|
||||
input logic [6:0] instr_rdata_intg_i,
|
||||
input logic instr_err_i,
|
||||
|
||||
// Data memory interface
|
||||
|
@ -49,9 +48,7 @@ module cve2_top import cve2_pkg::*; #(
|
|||
output logic [3:0] data_be_o,
|
||||
output logic [31:0] data_addr_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 [6:0] data_rdata_intg_i,
|
||||
input logic data_err_i,
|
||||
|
||||
// Interrupt inputs
|
||||
|
@ -99,18 +96,11 @@ module cve2_top import cve2_pkg::*; #(
|
|||
`endif
|
||||
|
||||
// CPU Control Signals
|
||||
output logic alert_minor_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
|
||||
output logic core_sleep_o
|
||||
);
|
||||
|
||||
// Scrambling Parameter
|
||||
localparam int unsigned NumAddrScrRounds = 0;
|
||||
localparam int unsigned NumDiffRounds = NumAddrScrRounds;
|
||||
|
||||
// Physical Memory Protection
|
||||
localparam bit PMPEnable = 1'b0;
|
||||
|
@ -129,8 +119,6 @@ module cve2_top import cve2_pkg::*; #(
|
|||
logic core_busy_d, core_busy_q;
|
||||
logic clock_en;
|
||||
logic irq_pending;
|
||||
// Alert signals
|
||||
logic core_alert_major, core_alert_minor;
|
||||
|
||||
/////////////////////
|
||||
// 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 core_sleep_o = ~clock_en;
|
||||
|
||||
prim_clock_gating core_clock_gate_i (
|
||||
cve2_clock_gate core_clock_gate_i (
|
||||
.clk_i (clk_i),
|
||||
.en_i (clock_en),
|
||||
.test_en_i(test_en_i),
|
||||
.scan_cg_en_i(test_en_i),
|
||||
.clk_o (clk)
|
||||
);
|
||||
|
||||
|
@ -176,6 +164,7 @@ module cve2_top import cve2_pkg::*; #(
|
|||
) u_cve2_core (
|
||||
.clk_i(clk),
|
||||
.rst_ni,
|
||||
.test_en_i,
|
||||
|
||||
.hart_id_i,
|
||||
.boot_addr_i,
|
||||
|
@ -237,8 +226,6 @@ module cve2_top import cve2_pkg::*; #(
|
|||
.rvfi_ext_mcycle,
|
||||
`endif
|
||||
|
||||
.alert_minor_o (core_alert_minor),
|
||||
.alert_major_o (core_alert_major),
|
||||
.core_busy_o (core_busy_d)
|
||||
);
|
||||
|
||||
|
@ -246,15 +233,12 @@ module cve2_top import cve2_pkg::*; #(
|
|||
// 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;
|
||||
logic unused_ram_inputs;
|
||||
assign unused_ram_cfg = ram_cfg_i;
|
||||
assign unused_ram_inputs = (|NumAddrScrRounds);
|
||||
|
||||
assign unused_ram_cfg = ram_cfg_i;
|
||||
assign unused_ram_inputs = (|NumAddrScrRounds);
|
||||
|
||||
end
|
||||
|
||||
// X checks for top-level outputs
|
||||
`ASSERT_KNOWN(IbexInstrReqX, instr_req_o)
|
||||
|
@ -278,11 +262,11 @@ module cve2_top import cve2_pkg::*; #(
|
|||
`ASSERT_KNOWN(IbexInstrGntX, instr_gnt_i)
|
||||
`ASSERT_KNOWN(IbexInstrRValidX, instr_rvalid_i)
|
||||
`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(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})
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue