Skip to content

Commit

Permalink
Merge pull request #472 from silabs-oivind/cv32e40x_merge
Browse files Browse the repository at this point in the history
Cv32e40x merge
  • Loading branch information
Silabs-ArjanB authored Jun 28, 2023
2 parents 1e9167f + b02cc2b commit 28f9e2b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 23 deletions.
2 changes: 1 addition & 1 deletion bhv/cv32e40s_wrapper.sv
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ module cv32e40s_wrapper
.lsu_trans_valid (core_i.load_store_unit_i.trans_valid),
.last_op_id_i (core_i.id_stage_i.last_op_o),
.first_op_if_i (core_i.if_stage_i.first_op),
.first_op_ex_i (core_i.first_op_ex),
.first_op_ex_i (core_i.ex_stage_i.first_op),
.prefetch_valid_if_i (core_i.if_stage_i.prefetch_valid),
.prefetch_is_tbljmp_ptr_if_i (core_i.if_stage_i.prefetch_is_tbljmp_ptr),
.prefetch_is_mret_ptr_if_i (core_i.if_stage_i.prefetch_is_mret_ptr),
Expand Down
31 changes: 27 additions & 4 deletions rtl/cv32e40s_alignment_buffer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,13 @@ module cv32e40s_alignment_buffer import cv32e40s_pkg::*;
// Write response and update valid bit and write pointer
if (resp_valid_gated) begin
// Increase write pointer, wrap to zero if at last entry
wptr_n = wptr < (ALBUF_DEPTH-1) ? wptr + ALBUF_CNT_WIDTH'(1) : ALBUF_CNT_WIDTH'(0);
if (wptr < (ALBUF_DEPTH-1)) begin
wptr_n = wptr + ALBUF_CNT_WIDTH'(1);
end
else begin
wptr_n = ALBUF_CNT_WIDTH'(0);
end

// Set fifo and valid write data
resp_n = resp_i;
valid_int[wptr] = 1'b1;
Expand All @@ -390,7 +396,12 @@ module cv32e40s_alignment_buffer import cv32e40s_pkg::*;
end

// Advance FIFO one step, wrap if at last entry
rptr_n = rptr < (ALBUF_DEPTH-1) ? rptr + ALBUF_CNT_WIDTH'(1) : ALBUF_CNT_WIDTH'(0);
if (rptr < (ALBUF_DEPTH-1)) begin
rptr_n = rptr + ALBUF_CNT_WIDTH'(1);
end
else begin
rptr_n = ALBUF_CNT_WIDTH'(0);
end
end else begin
// aligned case
if (aligned_is_compressed) begin
Expand All @@ -402,7 +413,12 @@ module cv32e40s_alignment_buffer import cv32e40s_pkg::*;
addr_n = {addr_incr[31:2], 2'b00};

// Advance FIFO one step, wrap if at last entry
rptr_n = rptr < (ALBUF_DEPTH-1) ? rptr + ALBUF_CNT_WIDTH'(1) : ALBUF_CNT_WIDTH'(0);
if (rptr < (ALBUF_DEPTH-1)) begin
rptr_n = rptr + ALBUF_CNT_WIDTH'(1);
end
else begin
rptr_n = ALBUF_CNT_WIDTH'(0);
end
end
end

Expand All @@ -415,7 +431,14 @@ module cv32e40s_alignment_buffer import cv32e40s_pkg::*;
end

// rptr2 will always be one higher than rptr
assign rptr2 = (rptr < (ALBUF_DEPTH-1)) ? rptr + ALBUF_CNT_WIDTH'(1) : ALBUF_CNT_WIDTH'(0);
always_comb begin
if (rptr < (ALBUF_DEPTH-1)) begin
rptr2 = rptr + ALBUF_CNT_WIDTH'(1);
end
else begin
rptr2 = ALBUF_CNT_WIDTH'(0);
end
end

// Counting instructions in FIFO
always_comb begin
Expand Down
8 changes: 5 additions & 3 deletions rtl/cv32e40s_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ module cv32e40s_core import cv32e40s_pkg::*;

// First op bits
logic first_op_id;
logic first_op_ex;

// Register file signals from ID/decoder to controller
logic [REGFILE_NUM_READ_PORTS-1:0] rf_re_id;
Expand Down Expand Up @@ -727,8 +726,7 @@ module cv32e40s_core import cv32e40s_pkg::*;
.ex_ready_o ( ex_ready ),
.ex_valid_o ( ex_valid ),
.wb_ready_i ( wb_ready ),
.last_op_o ( last_op_ex ),
.first_op_o ( first_op_ex )
.last_op_o ( last_op_ex )
);

////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1159,6 +1157,10 @@ module cv32e40s_core import cv32e40s_pkg::*;
.mnxti_irq_id_o ( mnxti_irq_id ),
.mnxti_irq_level_o ( mnxti_irq_level )
);

logic unused_clic_signals;
assign unused_clic_signals = |mie;

end else begin : gen_basic_interrupt
cv32e40s_int_controller
int_controller_i
Expand Down
7 changes: 6 additions & 1 deletion rtl/cv32e40s_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,8 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
.rd_error_o ( mintthresh_rd_error )
);

logic unused_clic_signals;
assign unused_clic_signals = mie_we | (|mie_n);

end else begin : basic_mode_csrs

Expand Down Expand Up @@ -2883,7 +2885,10 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
if( (evt_gidx < 3) ||
(evt_gidx >= (NUM_MHPMCOUNTERS+3) ) )
begin : gen_non_implemented_mhpmevent
assign mhpmevent_q[evt_gidx] = 'b0;
assign mhpmevent_q[evt_gidx] = 'b0;

logic unused_mhpmevent_signals;
assign unused_mhpmevent_signals = (|mhpmevent_n[evt_gidx]) | (|mhpmevent_q[evt_gidx]) | (|mhpmevent_rdata[evt_gidx]);
end
else begin : gen_implemented_mhpmevent
if (NUM_HPM_EVENTS < 32) begin : gen_tie_off
Expand Down
6 changes: 3 additions & 3 deletions rtl/cv32e40s_debug_triggers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ import cv32e40s_pkg::*;
tdata2_rdata_o = tdata2_rdata[0];

// Iterate through triggers and set tdata1/tdata2 rdata for the currently selected trigger
for (int i=0; i<DBG_NUM_TRIGGERS; i++) begin
for (int unsigned i=0; i<DBG_NUM_TRIGGERS; i++) begin
if(tselect_rdata_o == i) begin
tdata1_rdata_o = tdata1_rdata[i];
tdata2_rdata_o = tdata2_rdata[i];
Expand All @@ -477,7 +477,7 @@ import cv32e40s_pkg::*;

// Iterate over all triggers and pick tdata1_n_r and tdata1_we_r for the
// currently selected trigger.
for (int i=0; i<DBG_NUM_TRIGGERS; i++) begin
for (int unsigned i=0; i<DBG_NUM_TRIGGERS; i++) begin
if(tselect_rdata_o == i) begin
tdata1_n_r = tdata1_n[i];
// Using tdata1_we_int to include HW writes to mcontrol6
Expand All @@ -488,7 +488,7 @@ import cv32e40s_pkg::*;
// Make sure to update SW visible trigger CSRs on RVFI
// when tselect is written
if (tselect_we_i) begin
for (int i=0; i<DBG_NUM_TRIGGERS; i++) begin
for (int unsigned i=0; i<DBG_NUM_TRIGGERS; i++) begin
if(tselect_n == i) begin
tdata1_n_r = tdata1_rdata[i];
tdata2_n_r = tdata2_rdata[i];
Expand Down
32 changes: 25 additions & 7 deletions rtl/cv32e40s_div.sv
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module cv32e40s_div import cv32e40s_pkg::*;

// In case of negative op_b, invert op_b_i to count leading ones
// and shift one less to preserve sign bit
assign op_b_alt = (~op_b_i << 1);
assign op_b_alt = {~op_b_i, 1'b0};

always_comb
begin
Expand Down Expand Up @@ -165,10 +165,19 @@ module cv32e40s_div import cv32e40s_pkg::*;
assign comp_out = ((remainder_q == divisor_q) || ((remainder_q > divisor_q) ^ comp_inv_q)) &&
((|remainder_q) || op_b_is_zero);

// Main adder and adder input muxes
// Adder input muxes
assign add_b_mux = init_en ? 0 : remainder_q;
assign add_a_mux = init_en ? op_a_i : divisor_q;
assign add_out = init_remainder_pos ? add_b_mux + add_a_mux : add_b_mux - $signed(add_a_mux);

// Main adder
always_comb begin
if (init_remainder_pos) begin
add_out = add_b_mux + add_a_mux;
end
else begin
add_out = add_b_mux - $signed(add_a_mux);
end
end

// Result mux, negate if necessary
assign res_mux = div_rem_q ? remainder_q : quotient_q;
Expand All @@ -180,10 +189,19 @@ module cv32e40s_div import cv32e40s_pkg::*;

assign cnt_d_dummy = 6'd32 - alu_shift_amt_o;

assign cnt_d = init_en ? alu_shift_amt_o :
init_dummy_cnt ? cnt_d_dummy - 6'd1 : /*-1 because one cycle is used to update the counter*/
!cnt_q_is_zero ? cnt_q - 6'd1 :
cnt_q;
always_comb begin
cnt_d = cnt_q;

if (init_en) begin
cnt_d = alu_shift_amt_o;
end
else if (init_dummy_cnt) begin
cnt_d = cnt_d_dummy - 6'd1; /*-1 because one cycle is used to update the counter*/
end
else if (!cnt_q_is_zero) begin
cnt_d = cnt_q - 6'd1;
end
end

assign cnt_q_is_zero = !(|cnt_q);

Expand Down
9 changes: 5 additions & 4 deletions rtl/cv32e40s_ex_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ module cv32e40s_ex_stage import cv32e40s_pkg::*;
output logic ex_valid_o, // EX stage has valid (non-bubble) data for next stage
input logic wb_ready_i, // WB stage is ready for new data

output logic last_op_o,
output logic first_op_o
output logic last_op_o
);

// Ready and valid signals
Expand Down Expand Up @@ -117,7 +116,9 @@ module cv32e40s_ex_stage import cv32e40s_pkg::*;
logic [5:0] div_shift_amt;
logic [31:0] div_op_b_shifted;

// Misc signals
logic previous_exception;
logic first_op;

assign instr_valid = id_ex_pipe_i.instr_valid && !ctrl_fsm_i.kill_ex && !ctrl_fsm_i.halt_ex;

Expand Down Expand Up @@ -190,7 +191,7 @@ module cv32e40s_ex_stage import cv32e40s_pkg::*;
// Both parts of a split misaligned load/store will reach WB, but only the second half will be marked with "last_op"
assign last_op_o = id_ex_pipe_i.lsu_en ? (lsu_last_op_i && id_ex_pipe_i.last_op) : id_ex_pipe_i.last_op;

assign first_op_o = id_ex_pipe_i.lsu_en ? (lsu_first_op_i && id_ex_pipe_i.first_op) : id_ex_pipe_i.first_op;
assign first_op = id_ex_pipe_i.lsu_en ? (lsu_first_op_i && id_ex_pipe_i.first_op) : id_ex_pipe_i.first_op;

////////////////////////////
// _ _ _ _ //
Expand Down Expand Up @@ -384,7 +385,7 @@ module cv32e40s_ex_stage import cv32e40s_pkg::*;
ex_wb_pipe_o.priv_lvl <= id_ex_pipe_i.priv_lvl;
ex_wb_pipe_o.last_op <= last_op_o;
ex_wb_pipe_o.last_sec_op <= id_ex_pipe_i.last_sec_op;
ex_wb_pipe_o.first_op <= first_op_o;
ex_wb_pipe_o.first_op <= first_op;
ex_wb_pipe_o.abort_op <= id_ex_pipe_i.abort_op; // MPU exceptions and watchpoint triggers have WB timing and will not impact ex_wb_pipe.abort_op
// Deassert rf_we in case of illegal csr instruction or when the first half of a misaligned/split LSU goes to WB.
// Also deassert if CSR was accepted both by eXtension if and pipeline
Expand Down

0 comments on commit 28f9e2b

Please sign in to comment.