@@ -173,6 +173,8 @@ module csr_regfile
173173 // TO_BE_COMPLETED - CLIC_CTRL
174174 output logic [7 : 0 ] sintthresh_o,
175175 // TO_BE_COMPLETED - CLIC_CTRL
176+ output logic [7 : 0 ] vsintthresh_o,
177+ // TO_BE_COMPLETED - CLIC_CTRL
176178 output logic clic_irq_ready_o,
177179 // we are in single-step mode - COMMIT_STAGE
178180 output logic single_step_o,
@@ -308,10 +310,12 @@ module csr_regfile
308310 logic [CVA6Cfg.XLEN - 1 : 0 ] htval_q, htval_d;
309311
310312 logic [CVA6Cfg.XLEN - 1 : 0 ] vstvec_q, vstvec_d;
313+ logic [CVA6Cfg.XLEN - 1 : 0 ] vstvt_q, vstvt_d;
311314 logic [CVA6Cfg.XLEN - 1 : 0 ] vsscratch_q, vsscratch_d;
312315 logic [CVA6Cfg.XLEN - 1 : 0 ] vsepc_q, vsepc_d;
313316 logic [CVA6Cfg.XLEN - 1 : 0 ] vscause_q, vscause_d;
314317 logic [CVA6Cfg.XLEN - 1 : 0 ] vstval_q, vstval_d;
318+ riscv :: intthresh_rv_t vsintthresh_q, vsintthresh_d;
315319
316320 logic [CVA6Cfg.XLEN - 1 : 0 ] dcache_q, dcache_d;
317321 logic [CVA6Cfg.XLEN - 1 : 0 ] icache_q, icache_d;
@@ -409,6 +413,12 @@ module csr_regfile
409413 assign clic_irq_ready_o = 1'b0 ;
410414 end
411415
416+ if (CVA6Cfg.RVXHCLIC ) begin : gen_clic_vsintthresh_signal
417+ assign vsintthresh_o = vsintthresh_q.th;
418+ end else begin : gen_dummy_clic_vsintthresh_signal
419+ assign vsintthresh_o = '0 ;
420+ end
421+
412422 always_comb begin : csr_read_process
413423 // a read access exception can only occur if we attempt to read a CSR which does not exist
414424 read_access_exception = 1'b0 ;
@@ -497,15 +507,19 @@ module csr_regfile
497507 else read_access_exception = 1'b1 ;
498508 riscv :: CSR_VSIE :
499509 if (CVA6Cfg.RVH )
500- csr_rdata = (mie_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ] & hideleg_q) >> 1 ;
510+ csr_rdata = (CVA6Cfg. RVXHCLIC && clic_mode_o) ? '0 : (( mie_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ] & hideleg_q) >> 1 ) ;
501511 else read_access_exception = 1'b1 ;
502512 riscv :: CSR_VSIP :
503513 if (CVA6Cfg.RVH )
504- csr_rdata = (mip_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ] & hideleg_q) >> 1 ;
514+ csr_rdata = (CVA6Cfg. RVXHCLIC && clic_mode_o) ? '0 : (( mip_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ] & hideleg_q) >> 1 ) ;
505515 else read_access_exception = 1'b1 ;
506516 riscv :: CSR_VSTVEC :
507517 if (CVA6Cfg.RVH ) csr_rdata = vstvec_q;
508518 else read_access_exception = 1'b1 ;
519+ riscv :: CSR_VSTVT :
520+ if (CVA6Cfg.RVXHCLIC )
521+ csr_rdata = clic_mode_o ? { vstvt_q, 8'b0 } : '0 ; // vstvt reads 0 in CLINT mode
522+ else read_access_exception = 1'b1 ;
509523 riscv :: CSR_VSSCRATCH :
510524 if (CVA6Cfg.RVH ) csr_rdata = vsscratch_q;
511525 else read_access_exception = 1'b1 ;
@@ -527,6 +541,10 @@ module csr_regfile
527541 end else begin
528542 read_access_exception = 1'b1 ;
529543 end
544+ riscv :: CSR_VSINTTHRESH :
545+ if (CVA6Cfg.RVXHCLIC )
546+ csr_rdata = clic_mode_o ? {{ CVA6Cfg.XLEN - 8 { 1'b0 }} , vsintthresh_q} : '0 ; // vsintthresh reads 0 in CLINT mode
547+ else read_access_exception = 1'b1 ;
530548 // supervisor registers
531549 riscv :: CSR_SSTATUS : begin
532550 if (CVA6Cfg.RVS ) csr_rdata = mstatus_extended & SMODE_STATUS_READ_MASK [CVA6Cfg.XLEN - 1 : 0 ];
@@ -627,13 +645,16 @@ module csr_regfile
627645 if (CVA6Cfg.RVH ) csr_rdata = hideleg_q;
628646 else read_access_exception = 1'b1 ;
629647 riscv :: CSR_HIE :
630- if (CVA6Cfg.RVH ) csr_rdata = mie_q & HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ];
648+ if (CVA6Cfg.RVH )
649+ csr_rdata = (CVA6Cfg.RVXHCLIC && clic_mode_o) ? (mie_q & riscv :: MIP_SGEIP ) : (mie_q & HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ]);
631650 else read_access_exception = 1'b1 ;
632651 riscv :: CSR_HIP :
633- if (CVA6Cfg.RVH ) csr_rdata = mip_q & HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ];
652+ if (CVA6Cfg.RVH )
653+ csr_rdata = (CVA6Cfg.RVXHCLIC && clic_mode_o) ? '0 : (mip_q & HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ]);
634654 else read_access_exception = 1'b1 ;
635655 riscv :: CSR_HVIP :
636- if (CVA6Cfg.RVH ) csr_rdata = mip_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ];
656+ if (CVA6Cfg.RVH )
657+ csr_rdata = (CVA6Cfg.RVXHCLIC && clic_mode_o) ? '0 : (mip_q & VS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ]);
637658 else read_access_exception = 1'b1 ;
638659 riscv :: CSR_HCOUNTEREN :
639660 if (CVA6Cfg.RVH ) csr_rdata = hcounteren_q;
@@ -645,7 +666,7 @@ module csr_regfile
645666 if (CVA6Cfg.RVH ) csr_rdata = htinst_q;
646667 else read_access_exception = 1'b1 ;
647668 riscv :: CSR_HGEIE :
648- if (CVA6Cfg.RVH ) csr_rdata = '0 ;
669+ if (CVA6Cfg.RVH ) csr_rdata = { hgeie_q[CVA6Cfg. XLEN - 1 : 1 ], 1'b0 } ;
649670 else read_access_exception = 1'b1 ;
650671 riscv :: CSR_HGEIP :
651672 if (CVA6Cfg.RVH ) csr_rdata = '0 ;
@@ -1191,6 +1212,11 @@ module csr_regfile
11911212 en_ld_st_g_translation_d = en_ld_st_g_translation_q;
11921213 end
11931214
1215+ if (CVA6Cfg.RVXHCLIC ) begin
1216+ vstvt_d = vstvt_q;
1217+ vsintthresh_d = vsintthresh_q;
1218+ end
1219+
11941220 if (CVA6Cfg.RVS ) begin
11951221 sepc_d = sepc_q;
11961222 scause_d = scause_q;
@@ -1360,13 +1386,19 @@ module csr_regfile
13601386 end
13611387 end
13621388 riscv :: CSR_VSIE :
1363- if (CVA6Cfg.RVH ) mie_d = (mie_q & ~ hideleg_q) | ((csr_wdata << 1 ) & hideleg_q);
1364- else update_access_exception = 1'b1 ;
1389+ if (CVA6Cfg.RVH ) begin
1390+ // Writes are legal but ignored in CLIC mode
1391+ if (! (CVA6Cfg.RVXHCLIC && clic_mode_o))
1392+ mie_d = (mie_q & ~ hideleg_q) | ((csr_wdata << 1 ) & hideleg_q);
1393+ end else update_access_exception = 1'b1 ;
13651394 riscv :: CSR_VSIP : begin
13661395 if (CVA6Cfg.RVH ) begin
1367- // only the virtual supervisor software interrupt is write-able, iff delegated
1368- mask = CVA6Cfg.XLEN ' (riscv :: MIP_VSSIP ) & hideleg_q;
1369- mip_d = (mip_q & ~ mask) | ((csr_wdata << 1 ) & mask);
1396+ // Writes are legal but ignored in CLIC mode
1397+ if (! (CVA6Cfg.RVXHCLIC && clic_mode_o)) begin
1398+ // only the virtual supervisor software interrupt is write-able, iff delegated
1399+ mask = CVA6Cfg.XLEN ' (riscv :: MIP_VSSIP ) & hideleg_q;
1400+ mip_d = (mip_q & ~ mask) | ((csr_wdata << 1 ) & mask);
1401+ end
13701402 end else begin
13711403 update_access_exception = 1'b1 ;
13721404 end
@@ -1378,6 +1410,12 @@ module csr_regfile
13781410 update_access_exception = 1'b1 ;
13791411 end
13801412 end
1413+ riscv :: CSR_VSTVT : begin
1414+ if (CVA6Cfg.RVXHCLIC ) begin
1415+ // Writes are legal but ignored in CLINT mode
1416+ if (clic_mode_o) vstvt_d = csr_wdata[CVA6Cfg.XLEN - 1 : 8 ];
1417+ end else update_access_exception = 1'b1 ;
1418+ end
13811419 riscv :: CSR_VSSCRATCH :
13821420 if (CVA6Cfg.RVH ) vsscratch_d = csr_wdata;
13831421 else update_access_exception = 1'b1 ;
@@ -1411,6 +1449,12 @@ module csr_regfile
14111449 update_access_exception = 1'b1 ;
14121450 end
14131451 end
1452+ riscv :: CSR_VSINTTHRESH : begin
1453+ if (CVA6Cfg.RVXHCLIC ) begin
1454+ // Writes are legal but ignored in CLINT mode
1455+ if (clic_mode_o) vsintthresh_d.th = csr_wdata[7 : 0 ];
1456+ end else update_access_exception = 1'b1 ;
1457+ end
14141458 // sstatus is a subset of mstatus - mask it accordingly
14151459 riscv :: CSR_SSTATUS : begin
14161460 if (CVA6Cfg.RVS ) begin
@@ -1577,16 +1621,20 @@ module csr_regfile
15771621 end
15781622 riscv :: CSR_HIE : begin
15791623 if (CVA6Cfg.RVH ) begin
1580- mask = HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ];
1624+ // In CLIC mode only SGEIE bit is writable
1625+ mask = (CVA6Cfg.RVXHCLIC && clic_mode_o) ? CVA6Cfg.XLEN ' (riscv :: MIP_SGEIP ) : HS_DELEG_INTERRUPTS [CVA6Cfg.XLEN - 1 : 0 ];
15811626 mie_d = (mie_q & ~ mask) | (csr_wdata & mask);
15821627 end else begin
15831628 update_access_exception = 1'b1 ;
15841629 end
15851630 end
15861631 riscv :: CSR_HIP : begin
15871632 if (CVA6Cfg.RVH ) begin
1588- mask = CVA6Cfg.XLEN ' (riscv :: MIP_VSSIP );
1589- mip_d = (mip_q & ~ mask) | (csr_wdata & mask);
1633+ // Writes are legal but ignored in CLIC mode
1634+ if (! (CVA6Cfg.RVXHCLIC && clic_mode_o)) begin
1635+ mask = CVA6Cfg.XLEN ' (riscv :: MIP_VSSIP );
1636+ mip_d = (mip_q & ~ mask) | (csr_wdata & mask);
1637+ end
15901638 end else begin
15911639 update_access_exception = 1'b1 ;
15921640 end
@@ -1620,12 +1668,9 @@ module csr_regfile
16201668 update_access_exception = 1'b1 ;
16211669 end
16221670 end
1623- // TODO Hyp: implement hgeie write
1624- riscv :: CSR_HGEIE : begin
1625- if (! CVA6Cfg.RVH ) begin
1626- update_access_exception = 1'b1 ;
1627- end
1628- end
1671+ riscv :: CSR_HGEIE :
1672+ if (CVA6Cfg.RVH ) hgeie_d = { csr_wdata[CVA6Cfg.XLEN - 1 : 1 ], 1'b0 } ;
1673+ else update_access_exception = 1'b1 ;
16291674 riscv :: CSR_HGATP : begin
16301675 if (CVA6Cfg.RVH ) begin
16311676 // intercept HGATP writes if in HS-Mode and TVM is enabled
@@ -2205,6 +2250,9 @@ module csr_regfile
22052250 trap_to_v = v_q;
22062251 end
22072252 end
2253+ end else if (ex_i.cause[CVA6Cfg.XLEN - 1 ] && clic_mode_o) begin
2254+ trap_to_priv_lvl = riscv :: priv_lvl_t ' (ex_i.cause[25 : 24 ]);
2255+ if (CVA6Cfg.RVXHCLIC ) trap_to_v = ex_i.cause[26 ];
22082256 end
22092257 end
22102258
@@ -2217,7 +2265,12 @@ module csr_regfile
22172265 // this can either be user or supervisor mode
22182266 vsstatus_d.spp = priv_lvl_q[0 ];
22192267 // set cause
2220- vscause_d = ex_i.cause[CVA6Cfg.XLEN - 1 ] ? { ex_i.cause[CVA6Cfg.XLEN - 1 : 2 ], 2'b01 } : ex_i.cause;
2268+ vscause_d = (~ clic_mode_o && ex_i.cause[CVA6Cfg.XLEN - 1 ]) ? { ex_i.cause[CVA6Cfg.XLEN - 1 : 2 ], 2'b01 } : ex_i.cause;
2269+ // update the current and previous interrupt level
2270+ if (CVA6Cfg.RVXHCLIC && clic_mode_o && ex_i.cause[CVA6Cfg.XLEN - 1 ]) begin
2271+ mintstatus_d.vsil = ex_i.cause[23 : 16 ];
2272+ vscause_d[23 : 16 ] = mintstatus_q.vsil;
2273+ end
22212274 // set epc
22222275 vsepc_d = {{ CVA6Cfg.XLEN - CVA6Cfg.VLEN { pc_i[CVA6Cfg.VLEN - 1 ]}} , pc_i} ;
22232276 // set vstval
@@ -2547,6 +2600,9 @@ module csr_regfile
25472600 vsstatus_d.spp = 1'b0 ;
25482601 // set spie to 1
25492602 vsstatus_d.spie = 1'b1 ;
2603+ // restore vsintstatus
2604+ if (CVA6Cfg.RVXHCLIC && clic_mode_o && vscause_q[CVA6Cfg.XLEN - 1 ])
2605+ mintstatus_d.vsil = vscause_q[23 : 16 ];
25502606 end
25512607 end
25522608
@@ -2626,6 +2682,8 @@ module csr_regfile
26262682 end
26272683 assign irq_ctrl_o.mideleg = (CVA6Cfg.RVS ) ? mideleg_q : '0 ;
26282684 assign irq_ctrl_o.hideleg = (CVA6Cfg.RVH ) ? hideleg_q : '0 ;
2685+ assign irq_ctrl_o.hgeie = (CVA6Cfg.RVH ) ? hgeie_q : '0 ;
2686+ assign irq_ctrl_o.vgein = (CVA6Cfg.RVH ) ? hstatus_q.vgein : '0 ;
26292687 assign irq_ctrl_o.global_enable = ~ (CVA6Cfg.DebugEn & debug_mode_q)
26302688 // interrupts are enabled during single step or we are not stepping
26312689 // No need to check interrupts during single step if we don't support DEBUG mode
@@ -2795,7 +2853,11 @@ module csr_regfile
27952853 // output user mode stvec
27962854 if (CVA6Cfg.RVS && trap_to_priv_lvl == riscv :: PRIV_LVL_S ) begin
27972855 if (CVA6Cfg.RVSCLIC && clic_mode_o && clic_irq_shv_i && ex_i.cause[CVA6Cfg.XLEN - 1 ]) begin
2798- trap_vector_base_o = { stvt_q[CVA6Cfg.VLEN - 1 : 8 ], 8'b0 } ;
2856+ if (CVA6Cfg.RVSCLIC && trap_to_v) begin
2857+ trap_vector_base_o = { vstvt_q[CVA6Cfg.VLEN - 1 : 8 ], 8'b0 } ;
2858+ end else begin
2859+ trap_vector_base_o = { stvt_q[CVA6Cfg.VLEN - 1 : 8 ], 8'b0 } ;
2860+ end
27992861 end else if (CVA6Cfg.RVH && trap_to_v) begin
28002862 trap_vector_base_o = { vstvec_q[CVA6Cfg.VLEN - 1 : 2 ], 2'b0 } ;
28012863 end else begin
@@ -3043,6 +3105,10 @@ module csr_regfile
30433105 hcbie_q <= riscv :: CBIE_INVAL ;
30443106 hcbcfe_q <= 1'b1 ;
30453107 end
3108+ if (CVA6Cfg.RVXHCLIC ) begin
3109+ vstvt_q <= { CVA6Cfg.XLEN { 1'b0 }} ;
3110+ vsintthresh_q <= 8'b0 ;
3111+ end
30463112 end
30473113 if (CVA6Cfg.SDTRIG ) begin
30483114 scontext_q <= '0 ;
@@ -3151,6 +3217,10 @@ module csr_regfile
31513217 hcbie_q <= hcbie_d;
31523218 hcbcfe_q <= hcbcfe_d;
31533219 end
3220+ if (CVA6Cfg.RVXHCLIC ) begin
3221+ vstvt_q <= vstvt_d;
3222+ vsintthresh_q <= vsintthresh_d;
3223+ end
31543224 end
31553225 if (CVA6Cfg.SDTRIG ) begin
31563226 scontext_q <= scontext_d;
0 commit comments