Skip to content

Commit 9a1d8be

Browse files
Merge pull request #833 from silabs-oysteink/silabs-oysteink-issue-766
Partial fix for issue #766
2 parents 0a65b7f + abd8355 commit 9a1d8be

File tree

3 files changed

+71
-33
lines changed

3 files changed

+71
-33
lines changed

rtl/cv32e40x_cs_registers.sv

+31-25
Original file line numberDiff line numberDiff line change
@@ -659,30 +659,31 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
659659
always_comb
660660
begin
661661

662-
jvt_n = csr_wdata_int & CSR_JVT_MASK;
662+
jvt_n = csr_next_value(csr_wdata_int, CSR_JVT_MASK, JVT_RESET_VAL);
663663
jvt_we = 1'b0;
664664

665-
mscratch_n = csr_wdata_int;
665+
mscratch_n = csr_next_value(csr_wdata_int, CSR_MSCRATCH_MASK, MSCRATCH_RESET_VAL);
666666
mscratch_we = 1'b0;
667667

668-
mepc_n = csr_wdata_int & CSR_MEPC_MASK;
668+
mepc_n = csr_next_value(csr_wdata_int, CSR_MEPC_MASK, MEPC_RESET_VAL);
669669
mepc_we = 1'b0;
670670

671-
dpc_n = csr_wdata_int & CSR_DPC_MASK;
671+
dpc_n = csr_next_value(csr_wdata_int, CSR_DPC_MASK, DPC_RESET_VAL);
672672
dpc_we = 1'b0;
673673

674-
dcsr_n = '{
675-
xdebugver : dcsr_rdata.xdebugver,
676-
ebreakm : csr_wdata_int[15],
677-
ebreaku : dcsr_ebreaku_resolve(dcsr_rdata.ebreaku, csr_wdata_int[DCSR_EBREAKU_BIT]),
678-
stepie : csr_wdata_int[11],
679-
stopcount : csr_wdata_int[10],
680-
mprven : dcsr_rdata.mprven,
681-
step : csr_wdata_int[2],
682-
prv : dcsr_prv_resolve(dcsr_rdata.prv, csr_wdata_int[DCSR_PRV_BIT_HIGH:DCSR_PRV_BIT_LOW]),
683-
cause : dcsr_rdata.cause,
684-
default : 'd0
685-
};
674+
dcsr_n = csr_next_value(dcsr_t'{
675+
xdebugver : dcsr_rdata.xdebugver,
676+
ebreakm : csr_wdata_int[15],
677+
ebreaku : dcsr_ebreaku_resolve(dcsr_rdata.ebreaku, csr_wdata_int[DCSR_EBREAKU_BIT]),
678+
stepie : csr_wdata_int[11],
679+
stopcount : csr_wdata_int[10],
680+
mprven : dcsr_rdata.mprven,
681+
step : csr_wdata_int[2],
682+
prv : dcsr_prv_resolve(dcsr_rdata.prv, csr_wdata_int[DCSR_PRV_BIT_HIGH:DCSR_PRV_BIT_LOW]),
683+
cause : dcsr_rdata.cause,
684+
default : 'd0
685+
},
686+
CSR_DCSR_MASK, DCSR_RESET_VAL);
686687
dcsr_we = 1'b0;
687688

688689
dscratch0_n = csr_wdata_int;
@@ -1224,8 +1225,9 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
12241225

12251226
cv32e40x_csr
12261227
#(
1227-
.WIDTH (32),
1228-
.RESETVALUE (32'd0)
1228+
.WIDTH (32 ),
1229+
.MASK (CSR_JVT_MASK ),
1230+
.RESETVALUE (JVT_RESET_VAL )
12291231
)
12301232
jvt_csr_i
12311233
(
@@ -1268,7 +1270,8 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
12681270

12691271
cv32e40x_csr
12701272
#(
1271-
.WIDTH (32),
1273+
.WIDTH (32 ),
1274+
.MASK (CSR_DCSR_MASK ),
12721275
.RESETVALUE (DCSR_RESET_VAL)
12731276
)
12741277
dcsr_csr_i
@@ -1282,8 +1285,9 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
12821285

12831286
cv32e40x_csr
12841287
#(
1285-
.WIDTH (32),
1286-
.RESETVALUE (32'd0)
1288+
.WIDTH (32 ),
1289+
.MASK (CSR_DPC_MASK ),
1290+
.RESETVALUE (DPC_RESET_VAL)
12871291
)
12881292
dpc_csr_i
12891293
(
@@ -1303,8 +1307,9 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
13031307

13041308
cv32e40x_csr
13051309
#(
1306-
.WIDTH (32),
1307-
.RESETVALUE (32'd0)
1310+
.WIDTH (32 ),
1311+
.MASK (CSR_MEPC_MASK ),
1312+
.RESETVALUE (MEPC_RESET_VAL)
13081313
)
13091314
mepc_csr_i
13101315
(
@@ -1317,8 +1322,9 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
13171322

13181323
cv32e40x_csr
13191324
#(
1320-
.WIDTH (32),
1321-
.RESETVALUE (32'd0)
1325+
.WIDTH (32 ),
1326+
.MASK (CSR_MSCRATCH_MASK ),
1327+
.RESETVALUE (MSCRATCH_RESET_VAL)
13221328
)
13231329
mscratch_csr_i
13241330
(

rtl/cv32e40x_csr.sv

+21-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
module cv32e40x_csr #(
1111
parameter int unsigned WIDTH = 32,
12-
parameter bit [WIDTH-1:0] RESETVALUE = '0
12+
parameter bit [WIDTH-1:0] RESETVALUE = '0,
13+
parameter bit [WIDTH-1:0] MASK = '1
1314
) (
1415
input logic clk,
1516
input logic rst_n,
@@ -21,14 +22,26 @@ module cv32e40x_csr #(
2122

2223
logic [WIDTH-1:0] rdata_q;
2324

24-
always_ff @(posedge clk or negedge rst_n) begin
25-
if (!rst_n) begin
26-
rdata_q <= RESETVALUE;
27-
end else if (wr_en_i) begin
28-
rdata_q <= wr_data_i;
29-
end
30-
end
25+
generate
26+
for (genvar i = 0; i < WIDTH; i++) begin : gen_csr
27+
if (MASK[i]) begin : gen_unmasked
28+
// Bits with mask set are actual flipflops
29+
always_ff @(posedge clk or negedge rst_n) begin
30+
if (!rst_n) begin
31+
rdata_q[i] <= RESETVALUE[i];
32+
end else if (wr_en_i) begin
33+
rdata_q[i] <= wr_data_i[i];
34+
end
35+
end
36+
end else begin : gen_masked
37+
// Bits with mask cleared are tied off to the reset value
38+
assign rdata_q[i] = RESETVALUE[i];
39+
end
40+
end // for
41+
endgenerate
3142

3243
assign rd_data_o = rdata_q;
3344

45+
46+
3447
endmodule

rtl/include/cv32e40x_pkg.sv

+19
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,12 @@ typedef enum logic[11:0] {
428428
} csr_num_e;
429429

430430
// CSR Bit Implementation Masks
431+
// A mask bit of '1' means a flipflop is implemented.
431432
parameter CSR_JVT_MASK = 32'hFFFFFFC0;
432433
parameter CSR_MEPC_MASK = 32'hFFFFFFFE;
433434
parameter CSR_DPC_MASK = 32'hFFFFFFFE;
435+
parameter CSR_MSCRATCH_MASK = 32'hFFFFFFFF;
436+
parameter CSR_DCSR_MASK = 32'b0000_0000_0000_0000_1000_1101_1100_0100; // NMI bit taken from ctrl_fsm
434437

435438
// CSR operations
436439

@@ -660,6 +663,11 @@ parameter mcause_t MCAUSE_CLIC_RESET_VAL = '{
660663
parameter mcause_t MCAUSE_BASIC_RESET_VAL = '{
661664
default: 'b0};
662665

666+
parameter JVT_RESET_VAL = 32'd0;
667+
parameter MSCRATCH_RESET_VAL = 32'd0;
668+
parameter MEPC_RESET_VAL = 32'd0;
669+
parameter DPC_RESET_VAL = 32'd0;
670+
663671
parameter logic [31:0] TDATA1_RST_VAL = {
664672
TTYPE_MCONTROL, // type : address/data match
665673
1'b1, // dmode : access from D mode only
@@ -1461,6 +1469,17 @@ typedef struct packed {
14611469
// mtvec.mode is WARL(0x3) in CLIC mode
14621470
return 2'b11;
14631471
endfunction
1472+
1473+
// Function for setting next-value for CSRs
1474+
// Uses a mask and reset value to allow nom-implemented (no flipflop) bits to be either 0 or 1.
1475+
function automatic logic [31:0] csr_next_value
1476+
(
1477+
logic [31:0] wdata,
1478+
logic [31:0] mask,
1479+
logic [31:0] reset_value
1480+
);
1481+
return (wdata & mask) | (reset_value & ~mask);
1482+
endfunction
14641483
///////////////////////////
14651484
// //
14661485
// /\/\ (_)___ ___ //

0 commit comments

Comments
 (0)