Skip to content

Commit 243bb9c

Browse files
Merge pull request #485 from silabs-oysteink/silabs-oysteink_clic-1
CLIC: Spec chapter 5.1
2 parents 8738b71 + 2e66627 commit 243bb9c

File tree

2 files changed

+69
-33
lines changed

2 files changed

+69
-33
lines changed

rtl/cv32e40x_cs_registers.sv

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
5353
// MTVEC
5454
output logic [24:0] mtvec_addr_o,
5555
output logic [1:0] mtvec_mode_o,
56-
56+
5757
// Cycle Count
5858
output logic [MHPMCOUNTER_WIDTH-1:0] mcycle_o,
5959

6060
// Used for mtvec address
6161
input logic [31:0] mtvec_addr_i,
6262
input logic csr_mtvec_init_i,
6363

64-
// ID/EX pipeline
64+
// ID/EX pipeline
6565
input id_ex_pipe_t id_ex_pipe_i,
6666

6767
// EX/WB pipeline
@@ -72,7 +72,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
7272

7373
// To controller bypass logic
7474
output logic csr_counter_read_o,
75-
75+
7676
// Interface to registers (SRAM like)
7777
output logic [31:0] csr_rdata_o,
7878

@@ -83,7 +83,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
8383
output logic [31:0] mie_o,
8484
input logic [31:0] mip_i,
8585
output logic m_irq_enable_o,
86-
86+
8787
output logic [31:0] mepc_o,
8888

8989
// debug
@@ -93,7 +93,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
9393

9494
input logic [31:0] pc_if_i
9595
);
96-
96+
9797
localparam logic [31:0] CORE_MISA =
9898
(32'(A_EXT) << 0) // A - Atomic Instructions extension
9999
| (32'(1) << 2) // C - Compressed extension
@@ -224,7 +224,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
224224

225225
// CSR write operations in WB, actual csr_we_int may still become 1'b0 in case of CSR_OP_READ
226226
assign csr_en_gated = ex_wb_pipe_i.csr_en && instr_valid;
227-
227+
228228
// mip CSR
229229
assign mip = mip_i;
230230

@@ -306,7 +306,21 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
306306
CSR_MEPC: csr_rdata_int = mepc_q;
307307

308308
// mcause: exception cause
309-
CSR_MCAUSE: csr_rdata_int = mcause_q;
309+
CSR_MCAUSE: begin
310+
if (SMCLIC) begin
311+
// CLIC mode is assumed when SMCLIC = 1
312+
// For CLIC, the mpp and mpie bits from mstatus
313+
// are readable via mcause
314+
csr_rdata_int = {
315+
mcause_q[31:30],
316+
mstatus_q.mpp, // 29:28
317+
mstatus_q.mpie, // 27
318+
mcause_q[26:0]
319+
};
320+
end else begin
321+
csr_rdata_int = mcause_q;
322+
end
323+
end
310324

311325
// mip: interrupt pending
312326
CSR_MIP: csr_rdata_int = mip;
@@ -503,7 +517,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
503517
mepc_n = csr_wdata_int & ~32'b1;
504518
mepc_we = 1'b0;
505519
dpc_n = csr_wdata_int & ~32'b1;
506-
dpc_we = 1'b0;
520+
dpc_we = 1'b0;
507521

508522
dcsr_n = '{
509523
xdebugver : dcsr_q.xdebugver,
@@ -521,16 +535,30 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
521535
dscratch1_n = csr_wdata_int;
522536
dscratch1_we = 1'b0;
523537

538+
// TODO: add support for SD/XS/FS/VS
524539
mstatus_n = '{
525-
tw: 1'b0,
526-
mprv: 1'b0,
527-
mpp: PRIV_LVL_M,
528-
mpie: csr_wdata_int[MSTATUS_MPIE_BIT],
529-
mie: csr_wdata_int[MSTATUS_MIE_BIT],
530-
default: 'b0
531-
};
540+
tw: 1'b0,
541+
mprv: 1'b0,
542+
mpp: PRIV_LVL_M,
543+
mpie: csr_wdata_int[MSTATUS_MPIE_BIT],
544+
mie: csr_wdata_int[MSTATUS_MIE_BIT],
545+
default: 'b0
546+
};
547+
// CLIC mode is assumed when SMCLIC = 1
548+
// In CLIC mode, writes to mcause.mpp/mpie is aliased to mstatus.mpp/mpie
549+
if (SMCLIC) begin
550+
if (mcause_we) begin
551+
mstatus_n = mstatus_q; // Preserve all fields
552+
553+
// Write mpie and mpp as aliased through mcause
554+
mstatus_n.mpie = csr_wdata_int[MCAUSE_MPIE_BIT];
555+
mstatus_n.mpp = PRIV_LVL_M; // todo: handle priv mode for E40S
556+
end
557+
end
558+
532559
mstatus_we = 1'b0;
533560

561+
// SMCLIC: Not setting mpp or mpie, as these are stored in mstatus
534562
mcause_n = '{
535563
irq: csr_wdata_int[31],
536564
exception_code: csr_wdata_int[10:0],
@@ -559,7 +587,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
559587
mscratchcswl_we = 1'b0;
560588
mie_n = csr_wdata_int & IRQ_MASK;
561589
mie_we = 1'b0;
562-
590+
563591
if (csr_we_int) begin
564592
case (csr_waddr)
565593
// jvt: Jump vector table
@@ -598,8 +626,14 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
598626
mepc_we = 1'b1;
599627
end
600628
// mcause
601-
CSR_MCAUSE: begin
602-
mcause_we = 1'b1;
629+
CSR_MCAUSE: begin
630+
mcause_we = 1'b1;
631+
// CLIC mode is assumed when SMCLIC = 1
632+
// For CLIC, a write to mcause.mpp or mcause.mpie will write to the
633+
// corresponding bits in mstatus as well.
634+
if (SMCLIC) begin
635+
mstatus_we = 1'b1;
636+
end
603637
end
604638
CSR_MNXTI: begin
605639
if (SMCLIC) begin
@@ -638,7 +672,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
638672
CSR_DSCRATCH1: begin
639673
dscratch1_we = 1'b1;
640674
end
641-
675+
642676
endcase
643677
end
644678

@@ -842,7 +876,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
842876
.rd_error_o (mcause_rd_error)
843877
);
844878

845-
879+
846880

847881
cv32e40x_csr #(
848882
.WIDTH (32),
@@ -953,16 +987,16 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
953987

954988
// IRQ enable
955989
assign m_irq_enable_o = mstatus_q.mie;
956-
990+
957991
assign mtvec_addr_o = mtvec_q.addr;
958992
assign mtvec_mode_o = mtvec_q.mode;
959-
993+
960994
assign mepc_o = mepc_q;
961995
assign dpc_o = dpc_q;
962996
assign dcsr_o = dcsr_q;
963997

964998
assign mie_o = mie_q;
965-
999+
9661000
// dcsr_rdata factors in the flop outputs and the nmip bit from the controller
9671001
assign dcsr_rdata = {dcsr_q[31:4], ctrl_fsm_i.pending_nmi, dcsr_q[2:0]};
9681002

@@ -975,7 +1009,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
9751009
// |___/ |___/ |___/ //
9761010
////////////////////////////////////////////////////////////////////////
9771011

978-
1012+
9791013
// Write select
9801014
assign tmatch_control_we = csr_we_int && ctrl_fsm_i.debug_mode && (csr_waddr == CSR_TDATA1);
9811015
assign tmatch_value_we = csr_we_int && ctrl_fsm_i.debug_mode && (csr_waddr == CSR_TDATA2);
@@ -1005,7 +1039,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
10051039
1'b0, // store : not supported
10061040
1'b0}; // load : not supported
10071041

1008-
assign tmatch_value_n = csr_wdata_int;
1042+
assign tmatch_value_n = csr_wdata_int;
10091043

10101044
cv32e40x_csr #(
10111045
.WIDTH (32),
@@ -1018,8 +1052,8 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
10181052
.wr_en_i (tmatch_control_we),
10191053
.rd_data_o (tmatch_control_q),
10201054
.rd_error_o (tmatch_control_rd_error)
1021-
);
1022-
1055+
);
1056+
10231057
cv32e40x_csr #(
10241058
.WIDTH (32),
10251059
.SHADOWCOPY (1'b0),
@@ -1031,7 +1065,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
10311065
.wr_en_i (tmatch_value_we),
10321066
.rd_data_o (tmatch_value_q),
10331067
.rd_error_o (tmatch_value_rd_error)
1034-
);
1068+
);
10351069

10361070

10371071
// Breakpoint matching
@@ -1060,10 +1094,10 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
10601094
// Flop certain events to ease timing
10611095
localparam bit [15:0] HPM_EVENT_FLOP = 16'b1111_1111_1100_0000;
10621096
localparam bit [31:0] MCOUNTINHIBIT_MASK = {{(29-NUM_MHPMCOUNTERS){1'b0}},{(NUM_MHPMCOUNTERS){1'b1}},3'b101};
1063-
1097+
10641098
logic [15:0] hpm_events_raw;
10651099
logic all_counters_disabled;
1066-
1100+
10671101
assign all_counters_disabled = &(mcountinhibit_n | ~MCOUNTINHIBIT_MASK);
10681102

10691103
genvar hpm_idx;
@@ -1159,7 +1193,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
11591193
mcountinhibit_n = mcountinhibit_q;
11601194
mhpmevent_n = mhpmevent_q;
11611195

1162-
1196+
11631197
// Inhibit Control
11641198
if(mcountinhibit_we)
11651199
mcountinhibit_n = csr_wdata_int & MCOUNTINHIBIT_MASK;
@@ -1181,7 +1215,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
11811215
csr_we_int && (csr_waddr == (CSR_MCYCLEH + wcnt_gidx)) && (MHPMCOUNTER_WIDTH == 64);
11821216

11831217
// Increment counter
1184-
1218+
11851219
if (wcnt_gidx == 0) begin : gen_mhpmcounter_mcycle
11861220
// mcycle = mhpmcounter[0] : count every cycle (if not inhibited)
11871221
assign mhpmcounter_write_increment[wcnt_gidx] = !mhpmcounter_write_lower[wcnt_gidx] &&
@@ -1202,7 +1236,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
12021236
end else begin : gen_mhpmcounter_not_implemented
12031237
assign mhpmcounter_write_increment[wcnt_gidx] = 1'b0;
12041238
end
1205-
1239+
12061240
end
12071241
endgenerate
12081242

rtl/include/cv32e40x_pkg.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ parameter NUM_HPM_EVENTS = 16;
468468
parameter MSTATUS_MIE_BIT = 3;
469469
parameter MSTATUS_MPIE_BIT = 7;
470470

471+
parameter MCAUSE_MPIE_BIT = 27;
472+
471473
// misa
472474
parameter logic [1:0] MXL = 2'd1; // M-XLEN: XLEN in M-Mode for RV32
473475

0 commit comments

Comments
 (0)