Skip to content

Conversation

@AnonymousVikram
Copy link
Contributor

Cleaned up version of the PR

@AnonymousVikram AnonymousVikram marked this pull request as ready for review December 9, 2025 22:14
Copilot AI review requested due to automatic review settings December 9, 2025 22:14
@AnonymousVikram AnonymousVikram changed the title [WIP] CSRH Implementation CSRH Implementation Dec 9, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the CSRH (Hypervisor CSR) module as part of adding support for the RISC-V Hypervisor Extension. The implementation adds a new csrh.sv module to handle hypervisor-specific control and status registers, along with virtualization mode tracking in privmode.sv and trap routing logic in trap.sv.

Key changes:

  • New csrh.sv module implementing all hypervisor CSRs (hstatus, hedeleg, hideleg, hie, hvip, hepc, hcause, htval, htinst, hgatp, etc.)
  • Virtualization mode (V-bit) state tracking in privmode.sv with proper state transitions on traps and returns
  • Trap target routing logic (TrapToM, TrapToHS, TrapToVS) added to trap.sv for determining trap destinations

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/privileged/csrh.sv New module implementing all hypervisor CSRs with read/write logic, trap handling, and access control
src/privileged/trap.sv Added trap target outputs (TrapToM, TrapToHS, TrapToVS) to support hypervisor trap delegation
src/privileged/privmode.sv Added virtualization mode (V-bit) tracking with state machine for trap and return handling
src/privileged/privileged.sv Added hypervisor signal declarations and updated module instantiations with new ports
src/privileged/csr.sv Added CSRHWriteM, HSTrapM, PrivReturnHSM signals and conditional csrh module instantiation
src/cvw.sv Added H_SUPPORTED parameter to cvw_t configuration struct
config/shared/parameter-defs.vh Added H_SUPPORTED parameter to configuration parameter list
config/rv64i/config.vh Added H_SUPPORTED parameter (set to 0)
config/rv64gc/config.vh Added H_SUPPORTED parameter (set to 0)
config/rv32imc/config.vh Added H_SUPPORTED parameter (set to 0)
config/rv32i/config.vh Added H_SUPPORTED parameter (set to 0)
config/rv32gc/config.vh Added H_SUPPORTED parameter (set to 0)
config/rv32e/config.vh Added H_SUPPORTED parameter (set to 0)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// HCAUSE: Written by CSR instructions and by hardware on traps
assign NextHCAUSE = HSTrapM ? {{(P.XLEN-5){1'b0}}, NextCauseM} : CSRWriteValM;
flopenr #(P.XLEN) HCAUSEreg (clk, reset, (WriteHCAUSSEM | HSTrapM), NextHCAUSE, HCAUSE_REGW);
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signal name WriteHCAUSSEM is inconsistent with the naming pattern. It should be WriteHCAUSEM to match the register name HCAUSE.

Suggested change
flopenr #(P.XLEN) HCAUSEreg (clk, reset, (WriteHCAUSSEM | HSTrapM), NextHCAUSE, HCAUSE_REGW);
flopenr #(P.XLEN) HCAUSEreg (clk, reset, (WriteHCAUSEM | HSTrapM), NextHCAUSE, HCAUSE_REGW);

Copilot uses AI. Check for mistakes.

if (~LegalHAccess) begin : illegalaccess
IllegalCSRHAccessM = 1'b1;
end else begin : legalacess_mux
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in block label: "legalacess_mux" should be "legalaccess_mux" (missing 'c').

Suggested change
end else begin : legalacess_mux
end else begin : legalaccess_mux

Copilot uses AI. Check for mistakes.
assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM;
assign MTrapM = TrapM & (NextPrivilegeModeM == P.M_MODE);
assign STrapM = TrapM & (NextPrivilegeModeM == P.S_MODE) & P.S_SUPPORTED;
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent use of logical NOT (!VirtModeW) versus bitwise NOT (~VirtModeW on line 212). Since VirtModeW is a single bit, both work, but for consistency with line 212 and line 217, consider using ~VirtModeW.

Suggested change
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & ~VirtModeW) & P.H_SUPPORTED;

Copilot uses AI. Check for mistakes.
Comment on lines 216 to 217
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
assign PrivReturnHSM = sretM & (PrivilegeModeW == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent use of logical NOT (!VirtModeW) versus bitwise NOT (~VirtModeW on line 212). Since VirtModeW is a single bit, both work, but for consistency with line 212, consider using ~VirtModeW.

Suggested change
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
assign PrivReturnHSM = sretM & (PrivilegeModeW == P.S_MODE & !VirtModeW) & P.H_SUPPORTED;
assign HSTrapM = TrapM & (NextPrivilegeModeM == P.S_MODE & ~VirtModeW) & P.H_SUPPORTED;
assign PrivReturnHSM = sretM & (PrivilegeModeW == P.S_MODE & ~VirtModeW) & P.H_SUPPORTED;

Copilot uses AI. Check for mistakes.

assign TrapToVS = 1'b0; // until hedeleg/hideleg are implemented
assign TrapToHS = DelegateM;
assign TrapToM = TrapM & ~TrapToHS; // and not VS
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "and not VS" but the logic only excludes TrapToHS. For future completeness when TrapToVS is implemented, this should be TrapM & ~TrapToHS & ~TrapToVS. Since TrapToVS is currently hardcoded to 1'b0, the current logic works but will need updating when hedeleg/hideleg are implemented.

Suggested change
assign TrapToM = TrapM & ~TrapToHS; // and not VS
assign TrapToM = TrapM & ~TrapToHS & ~TrapToVS; // and not VS

Copilot uses AI. Check for mistakes.
logic WriteHIEM, WriteHTIMEDELTAM, WriteHCOUNTERENM;
logic WriteHGEIEM, WriteHENVCFGM, WriteHENVCFGHM, WriteHTVALM;
logic WriteHVIPM, WriteHTINSTM, WriteHGATPM;
logic WriteHEPCM, WriteHCAUSSEM;
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signal name WriteHCAUSSEM is inconsistent with the naming pattern used for other CSRs. It should be WriteHCAUSEM to match the register name HCAUSE (following the pattern: WriteHEPCM for HEPC, WriteHSTATUSM for HSTATUS, etc.).

Suggested change
logic WriteHEPCM, WriteHCAUSSEM;
logic WriteHEPCM, WriteHCAUSEM;

Copilot uses AI. Check for mistakes.
// henvcfgh only exists and is writable for RV32
assign WriteHENVCFGHM = (P.XLEN == 32) & (ValidWrite & (CSRAdrM == HENVCFGH));
assign WriteHEPCM = ValidWrite & (CSRAdrM == HEPC);
assign WriteHCAUSSEM = ValidWrite & (CSRAdrM == HCAUSE);
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signal name WriteHCAUSSEM is inconsistent with the naming pattern. It should be WriteHCAUSEM to match the register name HCAUSE.

Suggested change
assign WriteHCAUSSEM = ValidWrite & (CSRAdrM == HCAUSE);
assign WriteHCAUSEM = ValidWrite & (CSRAdrM == HCAUSE);

Copilot uses AI. Check for mistakes.
@davidharrishmc
Copy link
Contributor

davidharrishmc commented Dec 10, 2025

Aren't you putting this work into a hypervisor branch for now, instead of main?
Did you run regression and did this break anything?
The Copilot suggestions are good.
Eventually you will need virtual-instruction exceptions on some of these accesses. Ok to defer that.

end else if (mretM) begin
NextVirtModeM = MSTATUS_MPV;
end else if (sretM) begin
NextVirtModeM = (VirtModeW == 1'b0) ? HSTATUS_SPV : 1'b1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite as HSTATUS_SPV | VirtModeW

input logic CSRHWriteM, // High if operation is a write
input logic [11:0] CSRAdrM,
input logic [P.XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW, // Current privilege mode (U, S, M)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep indenting of comments clean now that our code is pretty mature.

input logic PrivReturnHSM, // Privilege return (sret) from HS-mode
input logic [P.XLEN-1:0] NextEPCM, // Value for hepc on trap
input logic [4:0] NextCauseM, // Value for hcause on trap
input logic [P.XLEN-1:0] NextMtvalM, // Value for htval on trap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name is Mtval but comment is htval

logic WriteHVIPM, WriteHTINSTM, WriteHGATPM;
logic WriteHEPCM, WriteHCAUSSEM;

// Internal register for htimedelta
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the comment on same line with the signal declaration and delete white space to improve density.

// H-CSRs are accessible in M-Mode or HS-Mode.
// HS-Mode is S-Mode when VirtModeW is 0.
// Access is ILLEGAL in U-Mode (U/VU) and VS-Mode (S-Mode when VirtModeW=1).
assign LegalHAccess = (PrivilegeModeW == P.M_MODE) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add pipeline stage suffixes to every signal.

// Configuration & Timers
flopenr #(P.XLEN) HCOUNTERENreg(clk, reset, WriteHCOUNTERENM, CSRWriteValM, HCOUNTEREN_REGW);
flopenr #(P.XLEN) HENVCFGreg(clk, reset, WriteHENVCFGM, CSRWriteValM, HENVCFG_REGW);
flopenr #(P.XLEN) HENVCFGHreg(clk, reset, WriteHENVCFGHM, CSRWriteValM, HENVCFGH_REGW);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

64 bits.

HCOUNTEREN: CSRHReadValM = HCOUNTEREN_REGW;
HGEIE: CSRHReadValM = HGEIE_REGW;
HENVCFG: CSRHReadValM = HENVCFG_REGW;
HENVCFGH: CSRHReadValM = HENVCFGH_REGW; // Only exists for RV32, reads 0 for RV64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other CSR modules for how to handle h registers with RV32. Need to throw illegal instruction trap instead of reading 0 on RV64. Applies to all h registers.

end
end

flopenl #(1) virtmodereg(clk, reset, ~StallW, NextVirtModeM, 1'b0, VirtModeW);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a flopenr?

always_comb begin
NextVirtModeM = VirtModeW;
if (TrapM) begin
if (TrapToVS) NextVirtModeM = 1'b1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace two lines with NextVitModeM = TraptoVS;

if (P.H_SUPPORTED) begin:virtmode
always_comb begin
NextVirtModeM = VirtModeW;
if (TrapM) begin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these begin/end s and simplify the code structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants