Skip to content

Commit

Permalink
Add vCLIC support
Browse files Browse the repository at this point in the history
  • Loading branch information
ezelioli committed Jul 3, 2024
1 parent ee89dcc commit 512a5d0
Show file tree
Hide file tree
Showing 22 changed files with 240 additions and 31 deletions.
146 changes: 122 additions & 24 deletions core/csr_regfile.sv

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ module cva6
input logic [$clog2(CVA6Cfg.CLICNumInterruptSrc)-1:0] clic_irq_id_i, // interrupt source ID
input logic [7:0] clic_irq_level_i, // interrupt level is 8-bit from CLIC spec
input riscv::priv_lvl_t clic_irq_priv_i, // CLIC interrupt privilege level
input logic clic_irq_v_i, // CLIC interrupt virtualization bit (only for vCLIC)
input logic [5:0] clic_irq_vsid_i, // CLIC interrupt Virtual Supervisor ID (only for vCLIC)
input logic clic_irq_shv_i, // selective hardware vectoring bit
output logic clic_irq_ready_o, // core side interrupt hanshake (ready)
input logic clic_kill_req_i, // kill request
Expand Down Expand Up @@ -202,6 +204,7 @@ module cva6
CVA6Cfg.CvxifEn,
CVA6Cfg.ZiCondExtEn,
CVA6Cfg.RVSCLIC,
CVA6Cfg.RVVCLIC,
// Extended
bit'(RVF),
bit'(RVD),
Expand Down Expand Up @@ -427,6 +430,7 @@ module cva6
riscv::intstatus_rv_t mintstatus_csr;
logic [7:0] mintthresh_csr;
logic [7:0] sintthresh_csr;
logic [7:0] vsintthresh_csr;
logic dcache_en_csr_nbdcache;
logic csr_write_fflags_commit_cs;
logic icache_en_csr;
Expand Down Expand Up @@ -954,6 +958,8 @@ module cva6
.mintstatus_o (mintstatus_csr),
.mintthresh_o (mintthresh_csr),
.sintthresh_o (sintthresh_csr),
.vsintthresh_o (vsintthresh_csr),
.clic_irq_req_i (clic_irq_req_id),
.clic_irq_shv_i (clic_irq_shv_i),
.clic_irq_ready_o (clic_irq_ready_o),
.ld_st_priv_lvl_o (ld_st_priv_lvl_csr_ex),
Expand Down Expand Up @@ -1361,16 +1367,20 @@ module cva6
.rst_ni (rst_ni),
// from CSR file
.priv_lvl_i (priv_lvl),
.v_i (v),
.irq_ctrl_i (irq_ctrl_csr_id),
.mintthresh_i (mintthresh_csr),
.sintthresh_i (sintthresh_csr),
.vsintthresh_i (vsintthresh_csr),
.mintstatus_i (mintstatus_csr),
// from/to CLIC
.clic_irq_valid_i(clic_irq_valid_i),
.clic_irq_ready_i(clic_irq_ready_o),
.clic_irq_id_i (clic_irq_id_i),
.clic_irq_level_i(clic_irq_level_i),
.clic_irq_priv_i (clic_irq_priv_i),
.clic_irq_v_i (clic_irq_v_i),
.clic_irq_vsid_i (clic_irq_vsid_i),
.clic_kill_req_i (clic_kill_req_i),
.clic_kill_ack_o (clic_kill_ack_o),
// to ID stage
Expand Down
68 changes: 63 additions & 5 deletions core/cva6_clic_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ module cva6_clic_controller #(
input logic rst_ni,
// from CSR file
input riscv::priv_lvl_t priv_lvl_i, // current privilege level
input logic v_i, // virtualization mode bit
input ariane_pkg::irq_ctrl_t irq_ctrl_i,
input logic [7:0] mintthresh_i, // M-mode interrupt threshold
input logic [7:0] sintthresh_i, // S-mode interrupt threshold
input logic [7:0] vsintthresh_i, // VS-mode interrupt threshold
input riscv::intstatus_rv_t mintstatus_i, // interrupt status
// from/to CLIC
input logic clic_irq_valid_i, // interrupt is valid
input logic clic_irq_ready_i, // interrupt is acknowledged
input logic [$clog2(CVA6Cfg.CLICNumInterruptSrc)-1:0] clic_irq_id_i, // interrupt ID
input logic [7:0] clic_irq_level_i, // interrupt level
input riscv::priv_lvl_t clic_irq_priv_i, // interrupt privilege level
input logic clic_irq_v_i, // interrupt virtualization bit (only for vCLIC)
input logic [5:0] clic_irq_vsid_i, // interrupt Virtual Supervisor ID (only for vCLIC)
input logic clic_kill_req_i, // kill request
output logic clic_kill_ack_o, // kill acknowledge
// to ID stage
Expand All @@ -34,14 +38,22 @@ module cva6_clic_controller #(
// irq threshold and global interrupt are enabled (otherwise it won't fire).
// The effective interrupt threshold is the maximum of mintstatus.mil and
// mintthresh, because interrupts with higher level have priority.
logic [7:0] max_mthresh, max_sthresh;
logic [7:0] max_mthresh, max_sthresh, max_vsthresh;

logic clic_irq_v; // Interrupt target virtualization mode (only for vCLIC)

logic sgeie; // Guest external interrupts at hypervisor level enable (HIE register)

assign max_mthresh = mintthresh_i > mintstatus_i.mil ? mintthresh_i : mintstatus_i.mil;
assign max_sthresh = sintthresh_i > mintstatus_i.sil ? sintthresh_i : mintstatus_i.sil;
assign max_vsthresh = vsintthresh_i > mintstatus_i.vsil ? vsintthresh_i : mintstatus_i.vsil;

assign sgeie = (CVA6Cfg.RVH) ? irq_ctrl_i.mie[riscv::IRQ_HS_EXT] : 1'b0;

// Determine if CLIC interrupt shall be accepted
always_comb begin : clic_irq_accept
clic_irq_req_o = 1'b0;
clic_irq_v = 1'b0;
unique case (priv_lvl_i)
riscv::PRIV_LVL_M: begin
// Take M-mode interrupts with higher level
Expand All @@ -55,12 +67,56 @@ module cva6_clic_controller #(
clic_irq_req_o = clic_irq_valid_i;
// Take S-mode interrupts with higher level
end else if (clic_irq_priv_i == riscv::PRIV_LVL_S) begin
clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie;
if (CVA6Cfg.RVH && v_i) begin // Hart currently in VS-mode
if (CVA6Cfg.RVVCLIC && clic_irq_v_i) begin // Virtual supervisor interrrupt
if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin // VS-mode interrupt is for currently running VS
clic_irq_req_o = (clic_irq_level_i > max_vsthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie;
clic_irq_v = 1'b1;
end else begin // Received interrupt is delegated to a differet VS
// Trap to HS-mode iff HIE.sgeie is set and HGEIE[vsid] is set
clic_irq_req_o = (clic_irq_valid_i) && sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i];
end
end else begin // Hypervisor interrupt
clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i); // HS-mode sie is implicitly enabled in VS-mode
end
end else begin // Hart currently in (H)S-mode
if (CVA6Cfg.RVVCLIC && clic_irq_v_i) begin // Virtual supervisor interrrupt
// The current custom vCLIC implementation does not provide a way to the hypervisor to set interrupt levels
// to interrupts delegated to VS-mode. The incoming interrupt level is therefore ignored if the hart is running
// in HS-mode and a VS-mode interrupt is taken iff both HIE.sgeie and HGEIE[vsid] bits are set (and interrupts
// are globally enabled at supervisor level (i.e. MSTATUS.sie bit is set)
clic_irq_req_o = (clic_irq_valid_i) && sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i] && irq_ctrl_i.sie;
end else begin // (Host) Supervisor interrupt
clic_irq_req_o = (clic_irq_level_i > max_sthresh) && (clic_irq_valid_i) && irq_ctrl_i.sie;
end
end
end
end
riscv::PRIV_LVL_U: begin
// Take all M-mode and S-mode interrupts
clic_irq_req_o = clic_irq_valid_i;
// Take all M-mode interrupts
if (clic_irq_priv_i == riscv::PRIV_LVL_M) begin
clic_irq_req_o = clic_irq_valid_i;
end else if (clic_irq_priv_i == riscv::PRIV_LVL_S) begin
if (CVA6Cfg.RVH && v_i) begin // Hart currently in VU-mode
if (CVA6Cfg.RVVCLIC && clic_irq_v_i) begin // Virtual supervisor interrrupt
if (clic_irq_vsid_i == irq_ctrl_i.vgein) begin // VS-mode interrupt is for currently running VS
clic_irq_req_o = clic_irq_valid_i;
clic_irq_v = 1'b1;
end else begin // Received interrupt is delegated to a differet VS
// Trap to HS-mode iff HIE.sgeie is set and HGEIE[vsid] is set
clic_irq_req_o = (clic_irq_valid_i) && sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i];
end
end else begin // Hypervisor interrupt
clic_irq_req_o = clic_irq_valid_i; // MSTATUS.sie is implicitly enabled in VU-mode
end
end else begin // Hart currently in U-mode
if (CVA6Cfg.RVVCLIC && clic_irq_v_i) begin // Virtual supervisor interrrupt
clic_irq_req_o = (clic_irq_valid_i) && sgeie && irq_ctrl_i.hgeie[clic_irq_vsid_i]; // MSTATUS.sie is implicitly enabled in U-mode
end else begin // (Host) Supervisor interrupt
clic_irq_req_o = clic_irq_valid_i; // HS-mode sie is implicitly enabled in U-mode
end
end
end
end
default: ;
endcase
Expand All @@ -72,7 +128,9 @@ module cva6_clic_controller #(
// Pack interrupt cause to be inserted into the pipeline
assign clic_irq_cause_o = {
1'b1, // This is an irq
{riscv::XLEN - 25{1'b0}}, // XLEN-2...24
{riscv::XLEN - 28{1'b0}}, // XLEN-2...27
clic_irq_v, // 26: interrupt target virtualization mode
clic_irq_priv_i, // 25..24: interrupt target privilege level
clic_irq_level_i, // to mintstatus.mil
{16 - $clog2(CVA6Cfg.CLICNumInterruptSrc) {1'b0}}, // 15...IDWidth
clic_irq_id_i
Expand Down
6 changes: 5 additions & 1 deletion core/include/ariane_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,16 @@ package ariane_pkg;
| riscv::HSTATUS_SPV
| riscv::HSTATUS_SPVP
| riscv::HSTATUS_HU
| riscv::HSTATUS_VGEIN
| riscv::HSTATUS_VTVM
| riscv::HSTATUS_VTW
| riscv::HSTATUS_VTSR;

// hypervisor delegable interrupts
localparam logic [riscv::XLEN-1:0] HS_DELEG_INTERRUPTS = riscv::MIP_VSSIP
| riscv::MIP_VSTIP
| riscv::MIP_VSEIP;
| riscv::MIP_VSEIP
| riscv::MIP_SGEIP;
// virtual supervisor delegable interrupts
localparam logic [riscv::XLEN-1:0] VS_DELEG_INTERRUPTS = riscv::MIP_VSSIP
| riscv::MIP_VSTIP
Expand Down Expand Up @@ -288,6 +290,8 @@ package ariane_pkg;
riscv::xlen_t mip;
riscv::xlen_t mideleg;
riscv::xlen_t hideleg;
riscv::xlen_t hgeie; // Hypervisor Guest External Interrupt Enable (HGEIE) register
logic [5:0] vgein; // Virtual Guest external interrupt number (HSTATUS register)
logic sie;
logic global_enable;
} irq_ctrl_t;
Expand Down
3 changes: 3 additions & 0 deletions core/include/config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ package config_pkg;
bit ZiCondExtEn;
// CLIC extension
bit RVSCLIC;
// CLIC virtualization extension (vCLIC)
bit RVVCLIC;
// Single precision FP RISC-V extension
bit RVF;
// Double precision FP RISC-V extension
Expand Down Expand Up @@ -178,6 +180,7 @@ package config_pkg;
assert (Cfg.NrExecuteRegionRules <= NrMaxRules);
assert (Cfg.NrCachedRegionRules <= NrMaxRules);
assert (Cfg.NrPMPEntries <= 16);
assert (!(Cfg.RVVCLIC && (!Cfg.RVH || !Cfg.RVSCLIC)));
`endif
// pragma translate_on
endfunction
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a60x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 1;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
4 changes: 4 additions & 0 deletions core/include/cv32a65x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ package cva6_config_pkg;
localparam CVA6ConfigBExtEn = 1;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -94,6 +96,8 @@ package cva6_config_pkg;
XFVec: bit'(CVA6ConfigFVecEn),
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
RVF: bit'(0),
RVD: bit'(0),
FpPresent: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_embedded_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -98,6 +99,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_ima_sv32_fpga_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imac_sv0_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imac_sv32_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imafc_sv32_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 1;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 1;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ package cva6_config_pkg;
localparam CVA6ConfigHExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 1;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -106,6 +107,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package cva6_config_pkg;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigZiCondExtEn = 0;
localparam CVA6ConfigSclicExtEn = 0;
localparam CVA6ConfigVclicExtEn = 0;

localparam CVA6ConfigAxiIdWidth = 4;
localparam CVA6ConfigAxiAddrWidth = 64;
Expand Down Expand Up @@ -99,6 +100,7 @@ package cva6_config_pkg;
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
RVSCLIC: bit'(CVA6ConfigSclicExtEn),
RVVCLIC: bit'(CVA6ConfigVclicExtEn),
// Extended
RVF:
bit'(
Expand Down
Loading

0 comments on commit 512a5d0

Please sign in to comment.