@@ -53,15 +53,15 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
53
53
// MTVEC
54
54
output logic [24 : 0 ] mtvec_addr_o,
55
55
output logic [1 : 0 ] mtvec_mode_o,
56
-
56
+
57
57
// Cycle Count
58
58
output logic [MHPMCOUNTER_WIDTH - 1 : 0 ] mcycle_o,
59
59
60
60
// Used for mtvec address
61
61
input logic [31 : 0 ] mtvec_addr_i,
62
62
input logic csr_mtvec_init_i,
63
63
64
- // ID/EX pipeline
64
+ // ID/EX pipeline
65
65
input id_ex_pipe_t id_ex_pipe_i,
66
66
67
67
// EX/WB pipeline
@@ -72,7 +72,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
72
72
73
73
// To controller bypass logic
74
74
output logic csr_counter_read_o,
75
-
75
+
76
76
// Interface to registers (SRAM like)
77
77
output logic [31 : 0 ] csr_rdata_o,
78
78
@@ -83,7 +83,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
83
83
output logic [31 : 0 ] mie_o,
84
84
input logic [31 : 0 ] mip_i,
85
85
output logic m_irq_enable_o,
86
-
86
+
87
87
output logic [31 : 0 ] mepc_o,
88
88
89
89
// debug
@@ -93,7 +93,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
93
93
94
94
input logic [31 : 0 ] pc_if_i
95
95
);
96
-
96
+
97
97
localparam logic [31 : 0 ] CORE_MISA =
98
98
(32 '(A_EXT ) << 0 ) // A - Atomic Instructions extension
99
99
| (32 '(1 ) << 2 ) // C - Compressed extension
@@ -224,7 +224,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
224
224
225
225
// CSR write operations in WB, actual csr_we_int may still become 1'b0 in case of CSR_OP_READ
226
226
assign csr_en_gated = ex_wb_pipe_i.csr_en && instr_valid;
227
-
227
+
228
228
// mip CSR
229
229
assign mip = mip_i;
230
230
@@ -306,7 +306,21 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
306
306
CSR_MEPC : csr_rdata_int = mepc_q;
307
307
308
308
// 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
310
324
311
325
// mip: interrupt pending
312
326
CSR_MIP : csr_rdata_int = mip;
@@ -503,7 +517,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
503
517
mepc_n = csr_wdata_int & ~ 32'b1 ;
504
518
mepc_we = 1'b0 ;
505
519
dpc_n = csr_wdata_int & ~ 32'b1 ;
506
- dpc_we = 1'b0 ;
520
+ dpc_we = 1'b0 ;
507
521
508
522
dcsr_n = '{
509
523
xdebugver : dcsr_q.xdebugver,
@@ -521,16 +535,30 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
521
535
dscratch1_n = csr_wdata_int;
522
536
dscratch1_we = 1'b0 ;
523
537
538
+ // TODO: add support for SD/XS/FS/VS
524
539
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
+
532
559
mstatus_we = 1'b0 ;
533
560
561
+ // SMCLIC: Not setting mpp or mpie, as these are stored in mstatus
534
562
mcause_n = '{
535
563
irq : csr_wdata_int[31 ],
536
564
exception_code : csr_wdata_int[10 : 0 ],
@@ -559,7 +587,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
559
587
mscratchcswl_we = 1'b0 ;
560
588
mie_n = csr_wdata_int & IRQ_MASK ;
561
589
mie_we = 1'b0 ;
562
-
590
+
563
591
if (csr_we_int) begin
564
592
case (csr_waddr)
565
593
// jvt: Jump vector table
@@ -598,8 +626,14 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
598
626
mepc_we = 1'b1 ;
599
627
end
600
628
// 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
603
637
end
604
638
CSR_MNXTI : begin
605
639
if (SMCLIC ) begin
@@ -638,7 +672,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
638
672
CSR_DSCRATCH1 : begin
639
673
dscratch1_we = 1'b1 ;
640
674
end
641
-
675
+
642
676
endcase
643
677
end
644
678
@@ -842,7 +876,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
842
876
.rd_error_o (mcause_rd_error)
843
877
);
844
878
845
-
879
+
846
880
847
881
cv32e40x_csr # (
848
882
.WIDTH (32 ),
@@ -953,16 +987,16 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
953
987
954
988
// IRQ enable
955
989
assign m_irq_enable_o = mstatus_q.mie;
956
-
990
+
957
991
assign mtvec_addr_o = mtvec_q.addr;
958
992
assign mtvec_mode_o = mtvec_q.mode;
959
-
993
+
960
994
assign mepc_o = mepc_q;
961
995
assign dpc_o = dpc_q;
962
996
assign dcsr_o = dcsr_q;
963
997
964
998
assign mie_o = mie_q;
965
-
999
+
966
1000
// dcsr_rdata factors in the flop outputs and the nmip bit from the controller
967
1001
assign dcsr_rdata = { dcsr_q[31 : 4 ], ctrl_fsm_i.pending_nmi, dcsr_q[2 : 0 ]} ;
968
1002
@@ -975,7 +1009,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
975
1009
// |___/ |___/ |___/ //
976
1010
// //////////////////////////////////////////////////////////////////////
977
1011
978
-
1012
+
979
1013
// Write select
980
1014
assign tmatch_control_we = csr_we_int && ctrl_fsm_i.debug_mode && (csr_waddr == CSR_TDATA1 );
981
1015
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::*;
1005
1039
1'b0 , // store : not supported
1006
1040
1'b0 } ; // load : not supported
1007
1041
1008
- assign tmatch_value_n = csr_wdata_int;
1042
+ assign tmatch_value_n = csr_wdata_int;
1009
1043
1010
1044
cv32e40x_csr # (
1011
1045
.WIDTH (32 ),
@@ -1018,8 +1052,8 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1018
1052
.wr_en_i (tmatch_control_we),
1019
1053
.rd_data_o (tmatch_control_q),
1020
1054
.rd_error_o (tmatch_control_rd_error)
1021
- );
1022
-
1055
+ );
1056
+
1023
1057
cv32e40x_csr # (
1024
1058
.WIDTH (32 ),
1025
1059
.SHADOWCOPY (1'b0 ),
@@ -1031,7 +1065,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1031
1065
.wr_en_i (tmatch_value_we),
1032
1066
.rd_data_o (tmatch_value_q),
1033
1067
.rd_error_o (tmatch_value_rd_error)
1034
- );
1068
+ );
1035
1069
1036
1070
1037
1071
// Breakpoint matching
@@ -1060,10 +1094,10 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1060
1094
// Flop certain events to ease timing
1061
1095
localparam bit [15 : 0 ] HPM_EVENT_FLOP = 16'b1111_1111_1100_0000 ;
1062
1096
localparam bit [31 : 0 ] MCOUNTINHIBIT_MASK = {{ (29 - NUM_MHPMCOUNTERS ){ 1'b0 }} ,{ (NUM_MHPMCOUNTERS ){ 1'b1 }} ,3'b101 } ;
1063
-
1097
+
1064
1098
logic [15 : 0 ] hpm_events_raw;
1065
1099
logic all_counters_disabled;
1066
-
1100
+
1067
1101
assign all_counters_disabled = & (mcountinhibit_n | ~ MCOUNTINHIBIT_MASK );
1068
1102
1069
1103
genvar hpm_idx;
@@ -1159,7 +1193,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1159
1193
mcountinhibit_n = mcountinhibit_q;
1160
1194
mhpmevent_n = mhpmevent_q;
1161
1195
1162
-
1196
+
1163
1197
// Inhibit Control
1164
1198
if (mcountinhibit_we)
1165
1199
mcountinhibit_n = csr_wdata_int & MCOUNTINHIBIT_MASK ;
@@ -1181,7 +1215,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1181
1215
csr_we_int && (csr_waddr == (CSR_MCYCLEH + wcnt_gidx)) && (MHPMCOUNTER_WIDTH == 64 );
1182
1216
1183
1217
// Increment counter
1184
-
1218
+
1185
1219
if (wcnt_gidx == 0 ) begin : gen_mhpmcounter_mcycle
1186
1220
// mcycle = mhpmcounter[0] : count every cycle (if not inhibited)
1187
1221
assign mhpmcounter_write_increment[wcnt_gidx] = ! mhpmcounter_write_lower[wcnt_gidx] &&
@@ -1202,7 +1236,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
1202
1236
end else begin : gen_mhpmcounter_not_implemented
1203
1237
assign mhpmcounter_write_increment[wcnt_gidx] = 1'b0 ;
1204
1238
end
1205
-
1239
+
1206
1240
end
1207
1241
endgenerate
1208
1242
0 commit comments