Skip to content

Commit

Permalink
New: Implement U-mode RTL
Browse files Browse the repository at this point in the history
  • Loading branch information
dpretet committed Sep 10, 2023
1 parent 90cc3e1 commit efb73ca
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 43 deletions.
25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@

FRISCV is a SystemVerilog implementation of the [RISCV ISA](https://riscv.org):

- Support RV32I & RV32E architecture
- Support Zifencei
- Support Zicsr
- Support Zicntr
- Support Zihpm
- Support M extension (multiply/divide)
- Machine-mode only
- Implement a 3-stage pipeline
- Support global and software interrupts
- Clint extension
- Built around a 3-stage pipeline
- In-order execution
- AXI4-lite for instruction and data bus
- Instruction & data cache units
- Privilege modes:
- Machine-mode only for simple embedded system
- User-mode for secure for secure embedded system
- Physical memory protection (PMP)
- Physical memory attribute (PMA)
- External, software and timer interrupts
- Support multiple (optional) extensions:
- RV32I & RV32E architecture
- Zifencei
- Zicsr
- Zicntr
- Zihpm
- M extension (multiply/divide)
- Clint extension

The core is [compliant](./test/riscv-tests/README.md) with the official RISCV
testsuite.
Expand Down
25 changes: 14 additions & 11 deletions doc/privilege.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Privilege Modes Support

## Overview

FRISCV supports machine mode as default mode. it's always implemented as required by the
specification. The core can also support user, supervisor and hypervisor modes, activable
all by paramters, `USER_MODE`, `SUPERVISOR_MODE`, `HYPERVISOR_MODE`.
Expand Down Expand Up @@ -46,25 +48,19 @@ Bits [9:8]:
- `10`: Hypervisor
- `11`: Machine

The privilege modes support have been designed based on RISC-V ISA specification version 20211203

# TODO

Plan:
- 1. user mode + PMP
- 2. supervisor mode + virtual memory support
- 3. hypervisor mode
- 4. debug mode

1. User mode
# User Mode

- Implement MSTATUS based on latest spec
- Support U-mode:
- Previous privilege mode interrupt is stored in xPP to support nested trap
- Ecall move to M-mode
- Mret move to U-mode
- Support exceptions
- M-mode instructions executed in U-mode must raise an illegal instruction exception
- Access to M-mode only registers must raise an illegal instruction exception
- ecall code when coming from U-mode in mcause
- Support PMP (Physical Memory Protection)
- Instruction read or data R/W access are checked against PMP to secure the hart
- Address is checked with CSRs pmpcfg
Expand All @@ -73,9 +69,12 @@ Plan:
- PMP checks are applied to all accesses whose effective privilege mode is S or U, including
instruction fetches and data accesses in S and U mode, and data accesses in M-mode when the
MPRV bit in mstatus is set and the MPP field in mstatus contains S or U (page 56)
- Study PMA (section 3.6)
- Study PMA (Physical Memory Attribute) (section 3.6)
- Support cycle registers per mode


## Supervisor

2. Supervisor
- Support interrupts
- disable them for lower mode. If is SUPERVISOR, USER interrupts are disabled
- interrupts for higher mode are enabled, whatever xIE bit. If is SUPERVISOR,
Expand All @@ -88,3 +87,7 @@ Plan:
- Support priv mode in cache stages
- Support TW (section 3.1.6.5)
- V & F extensions support: XS, FS, VS fields

## Hypervisor

TBD
10 changes: 7 additions & 3 deletions doc/project_mgt_hw.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# DOING

- [ ] Support U-mode
- [ ] Support PMP
- [ ] Support PMA


# BACKLOG
Expand Down Expand Up @@ -40,13 +43,13 @@ Cache Stages
Misc.

- [ ] Create a HW test platform
- [ ] Cloud
- [ ] Analogue pocket
- [C] Cloud
- [ ] Add registers to configure the core in platform
- [ ] Support completly a profile
- [ ] 64 bits support
- [ ] Atomic operations for single core
- [ ] Support privileged instructions, supervisor mode & user mode
- [ ] Support privileged instructions & supervisor mode
- voir les CSRs dans la privileged mode, implementer les compteurs par mode
- https://danielmangum.com/posts/risc-v-bytes-privilege-levels/
- https://mobile.twitter.com/hasheddan/status/1514581031092899843?s=12&t=MMNTY_iRC48CjykLQBdTkQ
Expand All @@ -66,9 +69,10 @@ Misc.
- [ ] Multi-core platform:
- [ ] Counters and timers should be reworked
- [ ] Nb core configurable
- [ ] Support PLIC
- [ ] PLIC controller
- [ ] Extended atomic operation support
- [ ] Implement a L2 cache stage
- [ ] Deactivate the core with WFI (clock gating)


AXI4 Infrastructure
Expand Down
49 changes: 40 additions & 9 deletions rtl/friscv_control.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ module friscv_control
parameter XLEN = 32,
// Reduced RV32 arch
parameter RV32E = 0,
// Support hypervisor mode
parameter HYPERVISOR_MODE = 0,
// Support supervisor mode
parameter SUPERVISOR_MODE = 0,
// Support user mode
parameter USER_MODE = 0,
// Address bus width defined for both control and AXI4 address signals
parameter AXI_ADDR_W = ILEN,
// AXI ID width, setup by default to 8 and unused
Expand Down Expand Up @@ -193,11 +199,13 @@ module friscv_control
logic [XLEN -1:0] mtval_info;
logic load_misaligned;
logic store_misaligned;
logic illegal_instruction;
logic wfi_not_allowed;
logic trap_occuring;
logic sync_trap_occuring;
logic async_trap_occuring;

logic ecall_umode;
logic ecall_mmode;
logic [2 -1:0] priv_mode;

// Logger setup
Expand Down Expand Up @@ -524,7 +532,6 @@ module friscv_control

assign pc_val = pc_reg;

assign priv_mode = `MMODE;

assign flush_reqs = flush_pipe;

Expand All @@ -541,6 +548,7 @@ module friscv_control
arid <= {AXI_ID_W{1'b0}};
flush_blocks <= 1'b0;
flush_pipe <= 1'b0;
priv_mode <= `MMODE;
end else if (srst == 1'b1) begin
cfsm <= BOOT;
arvalid <= 1'b0;
Expand All @@ -552,6 +560,7 @@ module friscv_control
arid <= {AXI_ID_W{1'b0}};
flush_blocks <= 1'b0;
flush_pipe <= 1'b0;
priv_mode <= `MMODE;
end else begin

case (cfsm)
Expand All @@ -561,6 +570,7 @@ module friscv_control
///////////////////////////////////////////////////////////////
default: begin

priv_mode <= `MMODE;
arid <= AXI_ID_MASK;
araddr <= BOOT_ADDR;
pc_reg <= BOOT_ADDR;
Expand Down Expand Up @@ -699,6 +709,7 @@ module friscv_control
status[0] <= 1'b1;
flush_pipe <= 1'b1;
pc_reg <= mtvec;
if (USER_MODE) priv_mode <= `MMODE;

// Reach an EBREAK instruction, need to stall the core
end else if (sys[`IS_EBREAK]) begin
Expand All @@ -719,6 +730,7 @@ module friscv_control
status[2] <= 1'b1;
flush_pipe <= 1'b1;
pc_reg <= sb_mepc;
if (USER_MODE) priv_mode <= `UMODE;

// Reach a FENCE.i instruction, need to flush the cache
// the instruction pipeline
Expand Down Expand Up @@ -1074,6 +1086,24 @@ module friscv_control
assign load_misaligned = proc_exceptions[`LD_MA];
assign store_misaligned = proc_exceptions[`ST_MA];

assign inst_dec_error = dec_error & (cfsm==FETCH) & inst_ready;

generate
if (USER_MODE) begin: UMODE_EXPEC
assign illegal_instruction = (priv_mode==`MMODE) ? '0 :
(sys[`IS_MRET]) ? inst_ready :
(sys[`IS_CSR] && csr[9:8] != 2'b00) ? inst_ready :
// Check if WFI must be trapped or not
(sys[`IS_WFI] ) ? inst_ready :
'0;
end else begin : NO_UMODE
assign illegal_instruction = '0;
end
endgenerate

assign ecall_umode = sys[`ECALL] && priv_mode==`UMODE;
assign ecall_mmode = sys[`ECALL] && priv_mode==`MMODE;

///////////////////////////////////////////////////////////////////////////
//
// Asynchronous exceptions code:
Expand Down Expand Up @@ -1108,12 +1138,11 @@ module friscv_control
// Highest | 3 | Instruction address breakpoint
// ------------------------------------------------------------------------
// | 12 | Instruction page fault
// ------------------------------------------------------------------------
// | 1 | Instruction access fault
// ------------------------------------------------------------------------
// | 2 | Illegal instruction
// | 0 | Instruction address misaligned
// | 8,9,11 | Environment call (U/S/M modes)
// | 8,9,11 | Environment call from U/S/M modes
// | 3 | Environment break
// | 3 | Load/Store/AMO address breakpoint
// ------------------------------------------------------------------------
Expand All @@ -1135,10 +1164,12 @@ module friscv_control
(csr_sb[`MTIP]) ? {1'b1, {XLEN-5{1'b0}}, 4'h7} :
(csr_sb[`MEIP]) ? {1'b1, {XLEN-5{1'b0}}, 4'hB} :
// then follow sync exceptions
(inst_addr_misaligned) ? {XLEN{1'b0}} :
(csr_ro_wr) ? {{XLEN-4{1'b0}}, 4'h1} :
(illegal_instruction) ? {{XLEN-4{1'b0}}, 4'h2} :
(csr_ro_wr) ? {{XLEN-4{1'b0}}, 4'h2} :
(inst_dec_error) ? {{XLEN-4{1'b0}}, 4'h2} :
(sys[`IS_ECALL]) ? {{XLEN-4{1'b0}}, 4'hB} :
(inst_addr_misaligned) ? {XLEN{1'b0}} :
(ecall_umode) ? {{XLEN-4{1'b0}}, 4'h8} :
(ecall_mmode) ? {{XLEN-4{1'b0}}, 4'hB} :
(sys[`IS_EBREAK]) ? {{XLEN-4{1'b0}}, 4'h3} :
(store_misaligned) ? {{XLEN-4{1'b0}}, 4'h6} :
(load_misaligned) ? {{XLEN-4{1'b0}}, 4'h4} :
Expand All @@ -1147,6 +1178,8 @@ module friscv_control
// MTVAL: exception-specific information
assign mtval_info = (inst_dec_error) ? instruction :
(wfi_not_allowed) ? instruction :
(illegal_instruction) ? instruction :
(csr_ro_wr) ? instruction :
(inst_addr_misaligned) ? pc_reg :
(sys[`IS_ECALL]) ? pc_reg :
(sys[`IS_EBREAK]) ? pc_reg :
Expand All @@ -1166,8 +1199,6 @@ module friscv_control

assign trap_occuring = async_trap_occuring | sync_trap_occuring;

assign inst_dec_error = dec_error & (cfsm==FETCH) & inst_ready;

endmodule

`resetall
7 changes: 6 additions & 1 deletion rtl/friscv_csr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ module friscv_csr
logic sw_irq_sync;


///////////////////////////////////////////////////////////////////////////
// Build mstatus content
// @data: the new value to write into the CSR
// @returns the formatted register based on spec and extension supported
///////////////////////////////////////////////////////////////////////////
function automatic logic [XLEN-1:0] get_mstatus (
input logic [XLEN-1:0] data
);
Expand Down Expand Up @@ -274,7 +279,7 @@ module friscv_csr
logic [XLEN-1:0] mtval; // 0x343 MRW
logic [XLEN-1:0] mip; // 0x344 MRW

// Machine Memory Protection
// Physical Memory Protection (PMP)
// logic [XLEN-1:0] pmpcfg0; // 0x3A0 MRW (not implemented)
// logic [XLEN-1:0] pmpcfg1; // 0x3A1 MRW (not implemented)
// logic [XLEN-1:0] pmpcfg2; // 0x3A2 MRW (not implemented)
Expand Down
21 changes: 12 additions & 9 deletions rtl/friscv_rv32i_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -371,17 +371,20 @@ module friscv_rv32i_core

friscv_control
#(
.ILEN (ILEN),
.XLEN (XLEN),
.RV32E (RV32E),
.AXI_ADDR_W (AXI_ADDR_W),
.AXI_ID_W (AXI_ID_W),
.AXI_ID_MASK (AXI_IMEM_MASK),
.AXI_DATA_W (XLEN),
.ILEN (ILEN),
.XLEN (XLEN),
.RV32E (RV32E),
.HYPERVISOR_MODE (HYPERVISOR_MODE),
.SUPERVISOR_MODE (SUPERVISOR_MODE),
.USER_MODE (USER_MODE),
.AXI_ADDR_W (AXI_ADDR_W),
.AXI_ID_W (AXI_ID_W),
.AXI_ID_MASK (AXI_IMEM_MASK),
.AXI_DATA_W (XLEN),
// No OR in control, so no internal FIFO, reducing latency
.OSTDREQ_NUM (0),
.OSTDREQ_NUM (0),
// .OSTDREQ_NUM (INST_OSTDREQ_NUM),
.BOOT_ADDR (BOOT_ADDR)
.BOOT_ADDR (BOOT_ADDR)
)
control
(
Expand Down

0 comments on commit efb73ca

Please sign in to comment.