feat: implement privileged mode support

This commit is contained in:
abnerhexu
2026-06-29 07:00:55 +00:00
parent a32db39c80
commit b6afa61e66
89 changed files with 49571 additions and 43647 deletions

View File

@@ -0,0 +1,542 @@
# Privileged Test Fixes Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make `rv64mi-p-instret_overflow`, `rv64mi-p-mcsr`, `rv64si-p-dirty`, and `rv64si-p-icache-alias` behave according to the privileged tests instead of failing or timing out.
**Architecture:** Fix the small M-mode CSR gaps first, then make address translation privilege-aware for data accesses, then add an instruction-side translation path. Keep the implementation minimal for these tests: Sv39 only, no ASIDs, no speculative PTW sharing, and no broader cache redesign.
**Tech Stack:** Scala 2.13, Chisel 7.7, ScalaTest, generated SystemVerilog, Verilator RISC-V testbench.
---
## File Structure
- Modify `src/main/scala/common/Privileged.scala`: add missing machine CSR constants and mstatus bit constants used by translation logic.
- Modify `src/main/scala/csr/CSRPermission.scala`: classify read-only ID CSRs and writable machine counters correctly.
- Modify `src/main/scala/csr/CSRFile.scala`: implement `mvendorid/marchid/mimpid`, `minstret`, `mcountinhibit.IR`, and instret/minstret write semantics.
- Modify `src/main/scala/common/Bundles.scala`: carry privilege and mstatus-derived access controls into translation requests.
- Modify `src/main/scala/memory/MMU.scala`: enforce Sv39 permissions for S/U/MPRV, A/D, SUM, and superpage alignment.
- Modify `src/main/scala/memory/LSU.scala`: decide effective privilege for loads/stores using `mstatus.MPRV/MPP`, and run translation only when effective privilege is S/U with non-Bare `satp`.
- Modify `src/main/scala/OoOBackend.scala`: pass `currentPriv` and `mstatus` into LSU.
- Modify `src/main/scala/frontend/Frontend.scala`: add `satp/currentPriv` inputs and an instruction PTW path.
- Modify `src/main/scala/Core.scala`: wire frontend `satp/currentPriv` from backend/privilege state.
- Test `src/test/scala/csr/CSRPermissionSpec.scala`: cover missing CSR permissions.
- Test `src/test/scala/csr/CSRFileSpec.scala`: cover generated CSR read/write behavior.
- Test `src/test/scala/memory/Sv39Spec.scala`: cover the generated MMU/LSU/Frontend ports and key permission expressions.
- Verify with `sim/scripts/run_privileged_tests.sh`.
## Task 1: Fix Machine CSR Address Map
**Files:**
- Modify: `src/main/scala/common/Privileged.scala`
- Modify: `src/main/scala/csr/CSRPermission.scala`
- Test: `src/test/scala/csr/CSRPermissionSpec.scala`
- [ ] **Step 1: Add constants for missing machine CSRs**
In `src/main/scala/common/Privileged.scala`, add these constants near the existing machine CSR constants:
```scala
val CSR_MVENDORID = "hf11".U(12.W)
val CSR_MARCHID = "hf12".U(12.W)
val CSR_MIMPID = "hf13".U(12.W)
val CSR_MHARTID = "hf14".U(12.W)
val CSR_MCOUNTINHIBIT = "h320".U(12.W)
val CSR_MINSTRET = "hb02".U(12.W)
```
Keep `CSR_CYCLE`, `CSR_TIME`, and `CSR_INSTRET` as user-visible read-only counter aliases at `0xc00` through `0xc02`.
- [ ] **Step 2: Update CSR permission sets**
In `CSRPermission.scala`, include the missing machine CSRs in `machineCsrs`, and treat ID CSRs as read-only:
```scala
private val machineCsrs = Set(
0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x320,
0x340, 0x341, 0x342, 0x343, 0x344,
0x3a0, 0x3b0, 0x744, 0x7a0, 0x7a1, 0x7a2, 0x7a5,
0xb02, 0xf11, 0xf12, 0xf13, 0xf14)
private val counterCsrs = Set(0xc00, 0xc01, 0xc02)
private val readOnlyCsrs = Set(0xf11, 0xf12, 0xf13, 0xf14) ++ counterCsrs
```
Update `isMachine` to include `CSR_MCOUNTINHIBIT`, `CSR_MINSTRET`, `CSR_MVENDORID`, `CSR_MARCHID`, and `CSR_MIMPID`.
- [ ] **Step 3: Add permission regression tests**
Append these cases to `CSRPermissionSpec.scala`:
```scala
it should "allow machine-mode reads of implementation ID CSRs and reject writes" in {
val ids = Seq(Privileged.CSR_MVENDORID, Privileged.CSR_MARCHID, Privileged.CSR_MIMPID, Privileged.CSR_MHARTID)
ids.foreach { csr =>
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(false)
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_S.litValue) should be(false)
}
}
it should "allow machine-mode writes to minstret and mcountinhibit" in {
CSRPermission.readAllowedLit(Privileged.CSR_MINSTRET.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(Privileged.CSR_MINSTRET.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.readAllowedLit(Privileged.CSR_MCOUNTINHIBIT.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(Privileged.CSR_MCOUNTINHIBIT.litValue, Privileged.PRV_M.litValue) should be(true)
}
```
- [ ] **Step 4: Run the targeted test**
Run:
```bash
sbt "testOnly CSRPermissionSpec"
```
Expected before implementation: failures for missing constants or denied CSRs. Expected after implementation: `CSRPermissionSpec` passes.
## Task 2: Implement `mcsr` and `instret_overflow` CSR Semantics
**Files:**
- Modify: `src/main/scala/csr/CSRFile.scala`
- Test: `src/test/scala/csr/CSRFileSpec.scala`
- [ ] **Step 1: Add CSR state**
In `CSRFile.scala`, add:
```scala
val mcountinhibit = RegInit(0.U(p.xlen.W))
val suppressInstretIncrement = WireDefault(false.B)
```
The existing `instret` register should serve both `minstret` and `instret`.
- [ ] **Step 2: Increment `instret` unless inhibited or just written**
Replace the unconditional counter update region with:
```scala
cycle := cycle + 1.U
when(!mcountinhibit(2) && !suppressInstretIncrement) {
instret := instret + 1.U
}
```
This matches the test expectation that a write to `minstret` suppresses the increment observed by the immediately following read.
- [ ] **Step 3: Add CSR reads**
Add to both the read switch and `writeOld` switch:
```scala
is(Privileged.CSR_MCOUNTINHIBIT) { r := mcountinhibit }
is(Privileged.CSR_MINSTRET) { r := instret }
is(Privileged.CSR_MVENDORID) { r := 0.U }
is(Privileged.CSR_MARCHID) { r := 0.U }
is(Privileged.CSR_MIMPID) { r := 0.U }
```
For the `writeOld` switch, use `writeOld := ...` instead of `r := ...`.
- [ ] **Step 4: Add CSR writes**
Inside the CSR write switch:
```scala
is(Privileged.CSR_MCOUNTINHIBIT) { mcountinhibit := next & 4.U }
is(Privileged.CSR_MINSTRET) {
instret := next
suppressInstretIncrement := true.B
}
```
Do not make `mvendorid/marchid/mimpid/mhartid` writable.
- [ ] **Step 5: Add generated-Verilog smoke tests**
Append to `CSRFileSpec.scala`:
```scala
it should "contain machine counter and ID CSR decode paths" in {
val verilog = ChiselStage.emitSystemVerilog(new CSRFile())
verilog should include("mcountinhibit")
verilog should include("12'hB02")
verilog should include("12'hF11")
verilog should include("12'hF12")
verilog should include("12'hF13")
}
```
- [ ] **Step 6: Run targeted tests and two privileged binaries**
Run:
```bash
sbt "testOnly CSRPermissionSpec CSRFileSpec"
make -C sim/verilator compile
timeout 5s sim/verilator/obj_dir/VCore ../../riscv-tests/isa/rv64mi-p-mcsr
timeout 5s sim/verilator/obj_dir/VCore ../../riscv-tests/isa/rv64mi-p-instret_overflow
```
Expected: both Verilator commands exit `0`.
## Task 3: Make Data Translation Privilege-Aware
**Files:**
- Modify: `src/main/scala/common/Privileged.scala`
- Modify: `src/main/scala/common/Bundles.scala`
- Modify: `src/main/scala/memory/MMU.scala`
- Modify: `src/main/scala/memory/LSU.scala`
- Modify: `src/main/scala/OoOBackend.scala`
- Test: `src/test/scala/memory/Sv39Spec.scala`
- [ ] **Step 1: Add mstatus bit constants**
In `Privileged.scala`, add:
```scala
val MSTATUS_MPRV_BIT = 17
val MSTATUS_SUM_BIT = 18
val MSTATUS_MXR_BIT = 19
val MSTATUS_MPP_HI = 12
val MSTATUS_MPP_LO = 11
```
- [ ] **Step 2: Extend TLB request metadata**
In `Bundles.scala`, extend `TlbReq`:
```scala
class TlbReq(p: CoreParams = CoreParams()) extends Bundle {
val valid = Bool()
val vaddr = UInt(p.xlen.W)
val isStore = Bool()
val isFetch = Bool()
val priv = UInt(2.W)
val sum = Bool()
val mxr = Bool()
}
```
- [ ] **Step 3: Enforce Sv39 permissions in the page walker**
In `MMU.scala`, register `priv/sum/mxr` alongside request state:
```scala
val privReg = Reg(UInt(2.W))
val sumReg = Reg(Bool())
val mxrReg = Reg(Bool())
```
Set them in `sIdle` when accepting a request:
```scala
privReg := io.req.priv
sumReg := io.req.sum
mxrReg := io.req.mxr
```
Replace the existing `permFault` with:
```scala
val userPage = pteU
val supervisorAccessToUser = privReg === Privileged.PRV_S && userPage && !sumReg && !isFetchReg
val supervisorFetchUser = privReg === Privileged.PRV_S && userPage && isFetchReg
val userAccessSupervisor = privReg === Privileged.PRV_U && !userPage
val readAllowed = pteR || (mxrReg && pteX)
val accessPermFault = Mux(isFetchReg, !pteX, Mux(isStoreReg, !pteW || !pteD, !readAllowed))
val adFault = !pteA || (isStoreReg && !pteD)
val permFault = accessPermFault || adFault || supervisorAccessToUser || supervisorFetchUser || userAccessSupervisor
```
Add superpage PPN alignment checks in the leaf case:
```scala
val misalignedSuperpage =
(level === 2.U && ptePpn(17, 0) =/= 0.U) ||
(level === 1.U && ptePpn(8, 0) =/= 0.U)
when(permFault || misalignedSuperpage) {
walkFault := true.B
}
```
- [ ] **Step 4: Make LSU choose effective privilege**
Add LSU IO inputs:
```scala
val currentPriv = Input(UInt(2.W))
val mstatus = Input(UInt(p.xlen.W))
```
In `LSU.scala`, replace `bare` with effective-mode logic:
```scala
val mprv = io.mstatus(Privileged.MSTATUS_MPRV_BIT)
val mpp = io.mstatus(Privileged.MSTATUS_MPP_HI, Privileged.MSTATUS_MPP_LO)
val effectivePriv = Mux(io.currentPriv === Privileged.PRV_M && mprv, mpp, io.currentPriv)
val translate = io.satp(63, 60) =/= 0.U && effectivePriv =/= Privileged.PRV_M
val bare = !translate
```
Populate DTLB/MMU request metadata:
```scala
dtlb.io.req.priv := effectivePriv
dtlb.io.req.sum := io.mstatus(Privileged.MSTATUS_SUM_BIT)
dtlb.io.req.mxr := io.mstatus(Privileged.MSTATUS_MXR_BIT)
mmu.io.req.priv := effectivePriv
mmu.io.req.sum := io.mstatus(Privileged.MSTATUS_SUM_BIT)
mmu.io.req.mxr := io.mstatus(Privileged.MSTATUS_MXR_BIT)
```
- [ ] **Step 5: Wire backend to LSU**
In `OoOBackend.scala`, add:
```scala
lsu.io.currentPriv := io.currentPriv
lsu.io.mstatus := csr.io.mstatus
```
- [ ] **Step 6: Update tests**
Append to `Sv39Spec.scala`:
```scala
it should "generate LSU effective privilege translation controls" in {
val verilog = ChiselStage.emitSystemVerilog(new LSU())
verilog should include("io_currentPriv")
verilog should include("io_mstatus")
verilog should include("io_mstatus[17]")
}
```
- [ ] **Step 7: Run tests and dirty binary**
Run:
```bash
sbt "testOnly Sv39Spec"
make -C sim/verilator compile
timeout 5s sim/verilator/obj_dir/VCore ../../riscv-tests/isa/rv64si-p-dirty
```
Expected: `rv64si-p-dirty` exits `0`. If it still fails, inspect whether the first `TESTNUM=2` store raises store page fault and whether the M-mode handler reads `page_table_1` physically.
## Task 4: Add Instruction-Side Sv39 Translation
**Files:**
- Modify: `src/main/scala/frontend/ITLB.scala`
- Modify: `src/main/scala/frontend/Frontend.scala`
- Modify: `src/main/scala/OoOBackend.scala`
- Modify: `src/main/scala/Core.scala`
- Test: `src/test/scala/memory/Sv39Spec.scala`
- [ ] **Step 1: Extend Frontend IO**
Add to `Frontend` IO:
```scala
val satp = Input(UInt(p.xlen.W))
val currentPriv = Input(UInt(2.W))
```
- [ ] **Step 2: Add an instruction MMU instance**
In `Frontend.scala`, instantiate MMU:
```scala
val immu = Module(new MMU(p))
val fetchTranslate = io.satp(63, 60) =/= 0.U && io.currentPriv =/= Privileged.PRV_M
```
Set ITLB request valid only when translation is active:
```scala
itlb.io.req.valid := fetchTranslate
itlb.io.req.vaddr := pc
itlb.io.req.isStore := false.B
itlb.io.req.isFetch := true.B
itlb.io.req.priv := io.currentPriv
itlb.io.req.sum := false.B
itlb.io.req.mxr := false.B
```
Drive `immu` for ITLB misses:
```scala
immu.io.satp := io.satp
immu.io.req.valid := fetchTranslate && itlb.io.resp.miss
immu.io.req.vaddr := pc
immu.io.req.isStore := false.B
immu.io.req.isFetch := true.B
immu.io.req.priv := io.currentPriv
immu.io.req.sum := false.B
immu.io.req.mxr := false.B
itlb.io.refill := immu.io.refill
```
- [ ] **Step 3: Add instruction PTW memory port**
Add frontend IO:
```scala
val ptwMemReqValid = Output(Bool())
val ptwMemReqAddr = Output(UInt(p.xlen.W))
val ptwMemRespValid = Input(Bool())
val ptwMemRespData = Input(UInt(p.xlen.W))
```
Wire:
```scala
io.ptwMemReqValid := immu.io.ptwMemReq.valid
io.ptwMemReqAddr := immu.io.ptwMemReq.addr
immu.io.ptwMemResp.valid := io.ptwMemRespValid
immu.io.ptwMemResp.data := io.ptwMemRespData
```
In `Core.scala`, arbitrate instruction-side PTW reads onto the existing data memory read path. Add a one-bit outstanding register so the frontend only consumes the memory response that belongs to its PTW request:
```scala
val frontendPtwOutstanding = RegInit(false.B)
val frontendPtwFire = frontend.io.ptwMemReqValid
when(frontendPtwFire) {
frontendPtwOutstanding := true.B
}.elsewhen(io.dmem_resp_valid && frontendPtwOutstanding) {
frontendPtwOutstanding := false.B
}
io.dmem_req_valid := frontend.io.ptwMemReqValid || backend.io.dmemReqValid
io.dmem_req_bits_addr := Mux(frontend.io.ptwMemReqValid, frontend.io.ptwMemReqAddr, backend.io.dmemReq.addr)
io.dmem_req_bits_data := Mux(frontend.io.ptwMemReqValid, 0.U, backend.io.dmemReq.data)
io.dmem_req_bits_isStore := Mux(frontend.io.ptwMemReqValid, false.B, backend.io.dmemReq.isStore)
io.dmem_req_bits_size := Mux(frontend.io.ptwMemReqValid, 3.U, backend.io.dmemReq.size)
frontend.io.ptwMemRespValid := io.dmem_resp_valid && frontendPtwOutstanding
frontend.io.ptwMemRespData := io.dmem_resp_bits
```
- [ ] **Step 4: Gate fetch while instruction translation is pending**
Use translated physical address only when translation is ready:
```scala
val fetchTranslationReady = !fetchTranslate || itlb.io.resp.hit
val fetchTranslationFault = fetchTranslate && (itlb.io.resp.pageFault || immu.io.resp.pageFault)
val fetchPaddr = Mux(fetchTranslate, itlb.io.resp.paddr, pc)
icache.io.reqValid := fetchTranslationReady && !fetchTranslationFault && !instMisaligned && !faultPending
icache.io.reqAddr := fetchPaddr
```
Update `fetchFault` to include `fetchTranslationFault`.
- [ ] **Step 5: Expose backend CSR `satp`**
In `OoOBackend.scala`, add an output:
```scala
val satpOut = Output(UInt(p.xlen.W))
```
Drive it from the CSR file:
```scala
io.satpOut := csr.io.satp
```
Keep the existing LSU connection:
```scala
lsu.io.satp := csr.io.satp
```
- [ ] **Step 6: Wire frontend privilege inputs**
In `Core.scala`:
```scala
frontend.io.satp := backend.io.satpOut
frontend.io.currentPriv := privCtrl.io.priv
```
- [ ] **Step 7: Add generated-Verilog frontend test**
Append to `Sv39Spec.scala`:
```scala
it should "generate frontend instruction-side translation ports" in {
val verilog = ChiselStage.emitSystemVerilog(new Frontend())
verilog should include("io_satp")
verilog should include("io_currentPriv")
verilog should include("ptwMemReq")
}
```
- [ ] **Step 8: Run icache-alias**
Run:
```bash
sbt "testOnly Sv39Spec"
make -C sim/verilator compile
timeout 5s sim/verilator/obj_dir/VCore ../../riscv-tests/isa/rv64si-p-icache-alias
```
Expected: no `Bad imem fetch pc=0x0`, no out-of-bounds fetch stream, exit `0`.
## Task 5: Full Privileged Regression
**Files:**
- No source edits.
- Verify: `sim/results/privileged_test_results.txt`
- [ ] **Step 1: Rebuild generated RTL/testbench**
Run:
```bash
sbt "runMain CoreOoO"
make -C sim/verilator compile
```
Expected: both commands exit `0`.
- [ ] **Step 2: Run privileged suite**
Run:
```bash
cd sim/scripts
TIMEOUT_SECONDS=10 ./run_privileged_tests.sh
```
Expected:
```text
rv64mi-p-instret_overflow: exit=0 PASS
rv64mi-p-mcsr: exit=0 PASS
rv64si-p-dirty: exit=0 PASS
rv64si-p-icache-alias: exit=0 PASS
```
`rv64ui-p-ma_data` is not in this privileged script and remains acceptable as a known aligned-access limitation in the base UI suite.
- [ ] **Step 3: Run base ISA suite**
Run:
```bash
cd sim/scripts
./run_tests.sh
```
Expected: existing PASS count is preserved, with only `rv64ui-p-ma_data` failing if the processor intentionally does not support misaligned data access.
## Self-Review
- Spec coverage: `rv64mi-p-instret_overflow` is covered by Task 1 and Task 2; `rv64mi-p-mcsr` is covered by Task 1 and Task 2; `rv64si-p-dirty` is covered by Task 3; `rv64si-p-icache-alias` is covered by Task 4.
- Placeholder scan: no deferred design items are left in the plan; every task has concrete files, code snippets, commands, and expected outcomes.
- Type consistency: new `TlbReq` fields are populated in LSU and Frontend; MMU consumes the same field names; Core/OoOBackend wiring is explicitly called out where ownership of `satp` crosses module boundaries.

View File

@@ -8,37 +8,203 @@ module CSRFile(
input [63:0] io_cmd_rs1, input [63:0] io_cmd_rs1,
input [4:0] io_cmd_zimm, input [4:0] io_cmd_zimm,
input [11:0] io_readAddr, input [11:0] io_readAddr,
input [1:0] io_currentPriv,
output [63:0] io_rdata, output [63:0] io_rdata,
output io_readIllegal,
input io_trap, input io_trap,
input [63:0] io_trapPc, input [63:0] io_trapPc,
io_trapCause, io_trapCause,
io_trapTval,
input [1:0] io_trapTargetPriv,
output [63:0] io_trapVector,
input io_xret,
io_xretIsMret,
output [63:0] io_satp, output [63:0] io_satp,
io_mtvec, io_mepc,
io_mepc io_sepc,
io_medeleg,
io_mstatus
); );
reg [63:0] cycle; reg [63:0] cycle;
reg [63:0] mstatus; reg [63:0] instret;
reg [63:0] mtvecReg; reg [63:0] mcountinhibit;
reg [63:0] mepcReg; reg suppressInstretAfterWrite;
reg [63:0] mcause; reg [63:0] mstatus;
reg [63:0] mtval; reg [63:0] mtvecReg;
reg [63:0] medeleg; reg [63:0] mscratch;
reg [63:0] mideleg; reg [63:0] mepcReg;
reg [63:0] mie; reg [63:0] mcause;
reg [63:0] mip; reg [63:0] mtval;
reg [63:0] sstatus; reg [63:0] medeleg;
reg [63:0] stvec; reg [63:0] mideleg;
reg [63:0] sepc; reg [63:0] mie;
reg [63:0] scause; reg [63:0] mip;
reg [63:0] stval; reg [63:0] mcounteren;
reg [63:0] sscratch; reg [63:0] pmpcfg0;
reg [63:0] satpReg; reg [63:0] pmpaddr0;
reg [63:0] tdata1;
reg [63:0] tdata2;
reg [63:0] tcontrol;
reg [63:0] mnstatus;
reg [63:0] scounteren;
reg [63:0] stvec;
reg [63:0] sepc;
reg [63:0] scause;
reg [63:0] stval;
reg [63:0] sscratch;
reg [63:0] satpReg;
wire _readAllowed_T_75 = io_readAddr == 12'h300;
wire _readAllowed_T_76 = io_readAddr == 12'h301;
wire _readAllowed_T_78 = io_readAddr == 12'h302;
wire _readAllowed_T_80 = io_readAddr == 12'h303;
wire _readAllowed_T_82 = io_readAddr == 12'h304;
wire _readAllowed_T_84 = io_readAddr == 12'h305;
wire _readAllowed_T_86 = io_readAddr == 12'h306;
wire _readAllowed_T_88 = io_readAddr == 12'h340;
wire _readAllowed_T_90 = io_readAddr == 12'h341;
wire _readAllowed_T_92 = io_readAddr == 12'h342;
wire _readAllowed_T_94 = io_readAddr == 12'h343;
wire _readAllowed_T_96 = io_readAddr == 12'h344;
wire _readAllowed_T_98 = io_readAddr == 12'h3A0;
wire _readAllowed_T_100 = io_readAddr == 12'h3B0;
wire _readAllowed_T_102 = io_readAddr == 12'h7A0;
wire _readAllowed_T_104 = io_readAddr == 12'h7A1;
wire _readAllowed_T_106 = io_readAddr == 12'h7A2;
wire _readAllowed_T_108 = io_readAddr == 12'h7A5;
wire _readAllowed_T_110 = io_readAddr == 12'h744;
wire _readAllowed_T_112 = io_readAddr == 12'h320;
wire _readAllowed_T_114 = io_readAddr == 12'hB02;
wire _readAllowed_T_116 = io_readAddr == 12'hF11;
wire _readAllowed_T_118 = io_readAddr == 12'hF12;
wire _readAllowed_T_120 = io_readAddr == 12'hF13;
wire _readAllowed_T_122 = io_readAddr == 12'hF14;
wire _readAllowed_T_125 = io_readAddr == 12'h100;
wire _readAllowed_T_126 = io_readAddr == 12'h104;
wire _readAllowed_T_128 = io_readAddr == 12'h105;
wire _readAllowed_T_130 = io_readAddr == 12'h140;
wire _readAllowed_T_132 = io_readAddr == 12'h106;
wire _readAllowed_T_134 = io_readAddr == 12'h141;
wire _readAllowed_T_136 = io_readAddr == 12'h142;
wire _readAllowed_T_138 = io_readAddr == 12'h143;
wire _readAllowed_T_140 = io_readAddr == 12'h144;
wire _readAllowed_T_142 = io_readAddr == 12'h180;
wire _readAllowed_T_69 = io_readAddr == 12'hC00;
wire _readAllowed_T_70 = io_readAddr == 12'hC01;
wire _readAllowed_T_72 = io_readAddr == 12'hC02;
wire readAllowed =
(_readAllowed_T_75 | _readAllowed_T_76 | _readAllowed_T_78 | _readAllowed_T_80
| _readAllowed_T_82 | _readAllowed_T_84 | _readAllowed_T_86 | _readAllowed_T_88
| _readAllowed_T_90 | _readAllowed_T_92 | _readAllowed_T_94 | _readAllowed_T_96
| _readAllowed_T_98 | _readAllowed_T_100 | _readAllowed_T_102 | _readAllowed_T_104
| _readAllowed_T_106 | _readAllowed_T_108 | _readAllowed_T_110 | _readAllowed_T_112
| _readAllowed_T_114 | _readAllowed_T_116 | _readAllowed_T_118 | _readAllowed_T_120
| _readAllowed_T_122 | _readAllowed_T_125 | _readAllowed_T_126 | _readAllowed_T_128
| _readAllowed_T_130 | _readAllowed_T_132 | _readAllowed_T_134 | _readAllowed_T_136
| _readAllowed_T_138 | _readAllowed_T_140 | _readAllowed_T_142 | _readAllowed_T_69
| _readAllowed_T_70 | _readAllowed_T_72)
& (_readAllowed_T_75 | _readAllowed_T_76 | _readAllowed_T_78 | _readAllowed_T_80
| _readAllowed_T_82 | _readAllowed_T_84 | _readAllowed_T_86 | _readAllowed_T_88
| _readAllowed_T_90 | _readAllowed_T_92 | _readAllowed_T_94 | _readAllowed_T_96
| _readAllowed_T_98 | _readAllowed_T_100 | _readAllowed_T_102 | _readAllowed_T_104
| _readAllowed_T_106 | _readAllowed_T_108 | _readAllowed_T_110 | _readAllowed_T_112
| _readAllowed_T_114 | _readAllowed_T_116 | _readAllowed_T_118 | _readAllowed_T_120
| _readAllowed_T_122
? (&io_currentPriv)
: ~(_readAllowed_T_125 | _readAllowed_T_126 | _readAllowed_T_128
| _readAllowed_T_130 | _readAllowed_T_132 | _readAllowed_T_134
| _readAllowed_T_136 | _readAllowed_T_138 | _readAllowed_T_140
| _readAllowed_T_142) | (|io_currentPriv));
wire _writeAllowed_T_75 = io_cmd_addr == 12'h300;
wire _writeAllowed_T_76 = io_cmd_addr == 12'h301;
wire _writeAllowed_T_78 = io_cmd_addr == 12'h302;
wire _writeAllowed_T_80 = io_cmd_addr == 12'h303;
wire _writeAllowed_T_82 = io_cmd_addr == 12'h304;
wire _writeAllowed_T_84 = io_cmd_addr == 12'h305;
wire _writeAllowed_T_86 = io_cmd_addr == 12'h306;
wire _writeAllowed_T_88 = io_cmd_addr == 12'h340;
wire _writeAllowed_T_90 = io_cmd_addr == 12'h341;
wire _writeAllowed_T_92 = io_cmd_addr == 12'h342;
wire _writeAllowed_T_94 = io_cmd_addr == 12'h343;
wire _writeAllowed_T_96 = io_cmd_addr == 12'h344;
wire _writeAllowed_T_98 = io_cmd_addr == 12'h3A0;
wire _writeAllowed_T_100 = io_cmd_addr == 12'h3B0;
wire _writeAllowed_T_102 = io_cmd_addr == 12'h7A0;
wire _writeAllowed_T_104 = io_cmd_addr == 12'h7A1;
wire _writeAllowed_T_106 = io_cmd_addr == 12'h7A2;
wire _writeAllowed_T_108 = io_cmd_addr == 12'h7A5;
wire _writeAllowed_T_110 = io_cmd_addr == 12'h744;
wire _writeAllowed_T_112 = io_cmd_addr == 12'h320;
wire _writeAllowed_T_114 = io_cmd_addr == 12'hB02;
wire _writeAllowed_T_148 = io_cmd_addr == 12'hF11;
wire _writeAllowed_T_149 = io_cmd_addr == 12'hF12;
wire _writeAllowed_T_151 = io_cmd_addr == 12'hF13;
wire _writeAllowed_T_153 = io_cmd_addr == 12'hF14;
wire _writeAllowed_T_125 = io_cmd_addr == 12'h100;
wire _writeAllowed_T_126 = io_cmd_addr == 12'h104;
wire _writeAllowed_T_128 = io_cmd_addr == 12'h105;
wire _writeAllowed_T_130 = io_cmd_addr == 12'h140;
wire _writeAllowed_T_132 = io_cmd_addr == 12'h106;
wire _writeAllowed_T_134 = io_cmd_addr == 12'h141;
wire _writeAllowed_T_136 = io_cmd_addr == 12'h142;
wire _writeAllowed_T_138 = io_cmd_addr == 12'h143;
wire _writeAllowed_T_140 = io_cmd_addr == 12'h144;
wire _writeAllowed_T_142 = io_cmd_addr == 12'h180;
wire _writeAllowed_T_155 = io_cmd_addr == 12'hC00;
wire _writeAllowed_T_156 = io_cmd_addr == 12'hC01;
wire _writeAllowed_T_158 = io_cmd_addr == 12'hC02;
wire [63:0] mstatusView = mstatus & 64'hFFFFFFF0FFFFFFFF | 64'hA00000000;
wire [63:0] sstatusView = {30'h0, mstatusView[33:1] & 33'h10006F0B1, 1'h0};
wire _GEN =
io_cmd_valid & (|io_cmd_cmd)
& (_writeAllowed_T_75 | _writeAllowed_T_76 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86 | _writeAllowed_T_88
| _writeAllowed_T_90 | _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_102
| _writeAllowed_T_104 | _writeAllowed_T_106 | _writeAllowed_T_108
| _writeAllowed_T_110 | _writeAllowed_T_112 | _writeAllowed_T_114
| _writeAllowed_T_148 | _writeAllowed_T_149 | _writeAllowed_T_151
| _writeAllowed_T_153 | _writeAllowed_T_125 | _writeAllowed_T_126
| _writeAllowed_T_128 | _writeAllowed_T_130 | _writeAllowed_T_132
| _writeAllowed_T_134 | _writeAllowed_T_136 | _writeAllowed_T_138
| _writeAllowed_T_140 | _writeAllowed_T_142 | _writeAllowed_T_155
| _writeAllowed_T_156 | _writeAllowed_T_158)
& (_writeAllowed_T_75 | _writeAllowed_T_76 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86 | _writeAllowed_T_88
| _writeAllowed_T_90 | _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_102
| _writeAllowed_T_104 | _writeAllowed_T_106 | _writeAllowed_T_108
| _writeAllowed_T_110 | _writeAllowed_T_112 | _writeAllowed_T_114
| _writeAllowed_T_148 | _writeAllowed_T_149 | _writeAllowed_T_151
| _writeAllowed_T_153
? (&io_currentPriv)
: ~(_writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_130 | _writeAllowed_T_132 | _writeAllowed_T_134
| _writeAllowed_T_136 | _writeAllowed_T_138 | _writeAllowed_T_140
| _writeAllowed_T_142) | (|io_currentPriv))
& ~(_writeAllowed_T_148 | _writeAllowed_T_149 | _writeAllowed_T_151
| _writeAllowed_T_153 | _writeAllowed_T_155 | _writeAllowed_T_156
| _writeAllowed_T_158);
wire _GEN_0 =
_writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80 | _writeAllowed_T_82
| _writeAllowed_T_84 | _writeAllowed_T_86 | _writeAllowed_T_112 | _writeAllowed_T_88
| _writeAllowed_T_90 | _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104 | _writeAllowed_T_106
| _writeAllowed_T_108 | _writeAllowed_T_110 | _writeAllowed_T_125
| _writeAllowed_T_126 | _writeAllowed_T_128 | _writeAllowed_T_132
| _writeAllowed_T_130 | _writeAllowed_T_134 | _writeAllowed_T_136
| _writeAllowed_T_138 | _writeAllowed_T_140 | _writeAllowed_T_142;
wire suppressInstretIncrement = _GEN & ~_GEN_0 & _writeAllowed_T_114;
wire trapToS = io_trapTargetPriv == 2'h1;
always @(posedge clock) begin always @(posedge clock) begin
if (reset) begin if (reset) begin
cycle <= 64'h0; cycle <= 64'h0;
instret <= 64'h0;
mcountinhibit <= 64'h0;
suppressInstretAfterWrite <= 1'h0;
mstatus <= 64'h0; mstatus <= 64'h0;
mtvecReg <= 64'h0; mtvecReg <= 64'h0;
mscratch <= 64'h0;
mepcReg <= 64'h0; mepcReg <= 64'h0;
mcause <= 64'h0; mcause <= 64'h0;
mtval <= 64'h0; mtval <= 64'h0;
@@ -46,7 +212,14 @@ module CSRFile(
mideleg <= 64'h0; mideleg <= 64'h0;
mie <= 64'h0; mie <= 64'h0;
mip <= 64'h0; mip <= 64'h0;
sstatus <= 64'h0; mcounteren <= 64'h0;
pmpcfg0 <= 64'h0;
pmpaddr0 <= 64'h0;
tdata1 <= 64'h0;
tdata2 <= 64'h0;
tcontrol <= 64'h0;
mnstatus <= 64'h0;
scounteren <= 64'h0;
stvec <= 64'h0; stvec <= 64'h0;
sepc <= 64'h0; sepc <= 64'h0;
scause <= 64'h0; scause <= 64'h0;
@@ -55,206 +228,466 @@ module CSRFile(
satpReg <= 64'h0; satpReg <= 64'h0;
end end
else begin else begin
automatic logic _GEN; automatic logic [63:0] writeOld =
automatic logic _GEN_0; _writeAllowed_T_75
automatic logic _GEN_1; ? mstatusView
automatic logic _GEN_2; : _writeAllowed_T_76
automatic logic _GEN_3; ? 64'h8000000000141101
automatic logic _GEN_4; : _writeAllowed_T_78
automatic logic _GEN_5; ? medeleg
automatic logic _GEN_6 = io_cmd_addr == 12'h343; : _writeAllowed_T_80
automatic logic _GEN_7 = io_cmd_addr == 12'h344; ? mideleg
automatic logic _GEN_8 = io_cmd_addr == 12'h100; : _writeAllowed_T_82
automatic logic _GEN_9 = io_cmd_addr == 12'h105; ? mie
automatic logic _GEN_10 = io_cmd_addr == 12'h140; : _writeAllowed_T_84
automatic logic _GEN_11 = io_cmd_addr == 12'h141; ? mtvecReg
automatic logic _GEN_12 = io_cmd_addr == 12'h142; : _writeAllowed_T_86
automatic logic _GEN_13 = io_cmd_addr == 12'h143; ? mcounteren
automatic logic _GEN_14 = io_cmd_addr == 12'h180; : _writeAllowed_T_112
automatic logic [63:0] _GEN_15; ? mcountinhibit
automatic logic [63:0] writeOld; : _writeAllowed_T_88
? mscratch
: _writeAllowed_T_90
? mepcReg
: _writeAllowed_T_92
? mcause
: _writeAllowed_T_94
? mtval
: _writeAllowed_T_96
? mip
: _writeAllowed_T_98
? pmpcfg0
: _writeAllowed_T_100
? pmpaddr0
: _writeAllowed_T_102
? 64'h1
: _writeAllowed_T_104
? tdata1
: _writeAllowed_T_106
? tdata2
: _writeAllowed_T_108
? tcontrol
: _writeAllowed_T_110
? mnstatus
: _writeAllowed_T_125
? sstatusView
: _writeAllowed_T_126
? mie
& mideleg
: _writeAllowed_T_128
? stvec
: _writeAllowed_T_132
? scounteren
: _writeAllowed_T_130
? sscratch
: _writeAllowed_T_134
? sepc
: _writeAllowed_T_136
? scause
: _writeAllowed_T_138
? stval
: _writeAllowed_T_140
? mip
& mideleg
: _writeAllowed_T_142
? satpReg
: _writeAllowed_T_148
| _writeAllowed_T_149
| _writeAllowed_T_151
| _writeAllowed_T_153
? 64'h0
: _writeAllowed_T_114
? instret
: _writeAllowed_T_155
| _writeAllowed_T_156
? cycle
: _writeAllowed_T_158
? instret
: 64'h0;
automatic logic [63:0] operand; automatic logic [63:0] operand;
automatic logic [63:0] _next_T_1; automatic logic [63:0] _next_T_1;
automatic logic [63:0] _next_T_3; automatic logic [63:0] _next_T_3;
automatic logic [3:0][63:0] _GEN_16; automatic logic [3:0][63:0] _GEN_1;
automatic logic [63:0] next; automatic logic [63:0] next;
automatic logic _GEN_17;
_GEN = io_cmd_addr == 12'h300;
_GEN_0 = io_cmd_addr == 12'h302;
_GEN_1 = io_cmd_addr == 12'h303;
_GEN_2 = io_cmd_addr == 12'h304;
_GEN_3 = io_cmd_addr == 12'h305;
_GEN_4 = io_cmd_addr == 12'h341;
_GEN_5 = io_cmd_addr == 12'h342;
_GEN_15 =
io_cmd_addr == 12'h301
? 64'h800000000014112D
: _GEN_0
? medeleg
: _GEN_1
? mideleg
: _GEN_2
? mie
: _GEN_3
? mtvecReg
: _GEN_4
? mepcReg
: _GEN_5
? mcause
: _GEN_6
? mtval
: _GEN_7
? mip
: _GEN_8
? sstatus
: _GEN_9
? stvec
: _GEN_10
? sscratch
: _GEN_11
? sepc
: _GEN_12
? scause
: _GEN_13
? stval
: _GEN_14
? satpReg
: io_cmd_addr == 12'hF14
| io_cmd_addr != 12'hC00
? 64'h0
: cycle;
writeOld = _GEN ? mstatus : _GEN_15;
operand = io_cmd_cmd[2] ? {59'h0, io_cmd_zimm} : io_cmd_rs1; operand = io_cmd_cmd[2] ? {59'h0, io_cmd_zimm} : io_cmd_rs1;
_next_T_1 = writeOld | operand; _next_T_1 = writeOld | operand;
_next_T_3 = writeOld & ~operand; _next_T_3 = writeOld & ~operand;
_GEN_16 = {{_next_T_3}, {_next_T_1}, {operand}, {writeOld}}; _GEN_1 = {{_next_T_3}, {_next_T_1}, {operand}, {writeOld}};
next = _GEN_16[io_cmd_cmd[1:0]]; next = _GEN_1[io_cmd_cmd[1:0]];
_GEN_17 = io_cmd_valid & (|io_cmd_cmd);
cycle <= cycle + 64'h1; cycle <= cycle + 64'h1;
if (_GEN_17 & _GEN) if (~_GEN | _GEN_0 | ~_writeAllowed_T_114) begin
mstatus <= next; if (mcountinhibit[2] | suppressInstretIncrement | suppressInstretAfterWrite) begin
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | ~_GEN_3) begin end
else
instret <= instret + 64'h1;
end
else
instret <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| ~_writeAllowed_T_112) begin
end
else
mcountinhibit <= {61'h0, next[2], 2'h0};
suppressInstretAfterWrite <=
~suppressInstretAfterWrite
& (suppressInstretIncrement | suppressInstretAfterWrite);
if (io_trap) begin
automatic logic [63:0] _GEN_2 =
mstatus[1] ? mstatus | 64'h20 : mstatus & 64'hFFFFFFFFFFFFFFDF;
mstatus <=
trapToS
? (io_currentPriv == 2'h1
? _GEN_2 & 64'hFFFFFFFFFFFFFFFD | 64'h100
: _GEN_2 & 64'hFFFFFFFFFFFFFEFD)
: (mstatus[3] ? mstatus | 64'h80 : mstatus & 64'hFFFFFFFFFFFFFF7F)
& 64'hFFFFFFFFFFFFE7F7 | {51'h0, io_currentPriv, 11'h0};
end
else if (io_xret)
mstatus <=
io_xretIsMret
? ((mstatus[7] ? mstatus | 64'h8 : mstatus & 64'hFFFFFFFFFFFFFFF7) | 64'h80)
& 64'hFFFFFFFFFFFFE7FF
: ((mstatus[5] ? mstatus | 64'h2 : mstatus & 64'hFFFFFFFFFFFFFFFD) | 64'h20)
& 64'hFFFFFFFFFFFFFEFF;
else if (_GEN) begin
if (_writeAllowed_T_75) begin
automatic logic [3:0][63:0] _GEN_3;
_GEN_3 = {{_next_T_3}, {_next_T_1}, {operand}, {mstatusView}};
mstatus <= _GEN_3[io_cmd_cmd[1:0]];
end
else if (_writeAllowed_T_78 | _writeAllowed_T_80 | _writeAllowed_T_82
| _writeAllowed_T_84 | _writeAllowed_T_86 | _writeAllowed_T_112
| _writeAllowed_T_88 | _writeAllowed_T_90 | _writeAllowed_T_92
| _writeAllowed_T_94 | _writeAllowed_T_96 | _writeAllowed_T_98
| _writeAllowed_T_100 | _writeAllowed_T_104 | _writeAllowed_T_106
| _writeAllowed_T_108 | _writeAllowed_T_110 | ~_writeAllowed_T_125) begin
end
else
mstatus <=
mstatus & 64'hFFFFFFFDFFF21E9D | {30'h0, next[33:1] & 33'h10006F0B1, 1'h0};
end
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | ~_writeAllowed_T_84) begin
end end
else else
mtvecReg <= next; mtvecReg <= next;
if (io_trap) begin if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
mepcReg <= io_trapPc; | _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
mcause <= io_trapCause; | _writeAllowed_T_112 | ~_writeAllowed_T_88) begin
end end
else begin else
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | ~_GEN_4) begin mscratch <= next;
if (~io_trap | trapToS) begin
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | ~_writeAllowed_T_90) begin
end end
else else
mepcReg <= next; mepcReg <= next;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | ~_GEN_5) begin if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| ~_writeAllowed_T_92) begin
end end
else else
mcause <= next; mcause <= next;
end if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| ~_GEN_6) begin | _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
end | _writeAllowed_T_92 | ~_writeAllowed_T_94) begin
else end
mtval <= next; else
if (~_GEN_17 | _GEN | ~_GEN_0) begin mtval <= next;
end end
else begin else begin
automatic logic [3:0][63:0] _GEN_18; mepcReg <= io_trapPc;
_GEN_18 = {{_next_T_3}, {_next_T_1}, {operand}, {_GEN_15}}; mcause <= io_trapCause;
medeleg <= _GEN_18[io_cmd_cmd[1:0]]; mtval <= io_trapTval;
end end
if (~_GEN_17 | _GEN | _GEN_0 | ~_GEN_1) begin if (~_GEN | _writeAllowed_T_75 | ~_writeAllowed_T_78) begin
end end
else else begin
mideleg <= next; automatic logic [3:0][63:0] _GEN_4;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | ~_GEN_2) begin _GEN_4 =
{{_next_T_3},
{_next_T_1},
{operand},
{_writeAllowed_T_76 ? 64'h8000000000141101 : medeleg}};
medeleg <= _GEN_4[io_cmd_cmd[1:0]];
end end
else if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | ~_writeAllowed_T_80) begin
end
else begin
automatic logic [3:0][63:0] _GEN_5;
_GEN_5 =
{{_next_T_3},
{_next_T_1},
{operand},
{_writeAllowed_T_75
? mstatusView
: _writeAllowed_T_76
? 64'h8000000000141101
: _writeAllowed_T_78 ? medeleg : mideleg}};
mideleg <= _GEN_5[io_cmd_cmd[1:0]];
end
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80) begin
end
else if (_writeAllowed_T_82)
mie <= next; mie <= next;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 else if (_writeAllowed_T_84 | _writeAllowed_T_86 | _writeAllowed_T_112
| ~_GEN_7) begin | _writeAllowed_T_88 | _writeAllowed_T_90 | _writeAllowed_T_92
| _writeAllowed_T_94 | _writeAllowed_T_96 | _writeAllowed_T_98
| _writeAllowed_T_100 | _writeAllowed_T_104 | _writeAllowed_T_106
| _writeAllowed_T_108 | _writeAllowed_T_110 | _writeAllowed_T_125
| ~_writeAllowed_T_126) begin
end end
else else
mie <= mie & ~mideleg | next & mideleg;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94) begin
end
else if (_writeAllowed_T_96)
mip <= next; mip <= next;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 else if (_writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _GEN_7 | ~_GEN_8) begin | _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_132 | _writeAllowed_T_130 | _writeAllowed_T_134
| _writeAllowed_T_136 | _writeAllowed_T_138 | ~_writeAllowed_T_140) begin
end end
else else
sstatus <= next; mip <= mip & ~mideleg | next & mideleg;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _GEN_7 | _GEN_8 | ~_GEN_9) begin | _writeAllowed_T_82 | _writeAllowed_T_84 | ~_writeAllowed_T_86) begin
end
else
mcounteren <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| ~_writeAllowed_T_98) begin
end
else
pmpcfg0 <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | ~_writeAllowed_T_100) begin
end
else
pmpaddr0 <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | ~_writeAllowed_T_104) begin
end
else
tdata1 <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| ~_writeAllowed_T_106) begin
end
else
tdata2 <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | ~_writeAllowed_T_108) begin
end
else
tcontrol <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | ~_writeAllowed_T_110) begin
end
else
mnstatus <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| ~_writeAllowed_T_132) begin
end
else
scounteren <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | ~_writeAllowed_T_128) begin
end end
else else
stvec <= next; stvec <= next;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 if (io_trap & trapToS) begin
| _GEN_7 | _GEN_8 | _GEN_9 | _GEN_10 | ~_GEN_11) begin sepc <= io_trapPc;
scause <= io_trapCause;
stval <= io_trapTval;
end end
else else begin
sepc <= next; if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 | _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _GEN_7 | _GEN_8 | _GEN_9 | _GEN_10 | _GEN_11 | ~_GEN_12) begin | _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_132 | _writeAllowed_T_130 | ~_writeAllowed_T_134) begin
end
else
sepc <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_132 | _writeAllowed_T_130 | _writeAllowed_T_134
| ~_writeAllowed_T_136) begin
end
else
scause <= next;
if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_132 | _writeAllowed_T_130 | _writeAllowed_T_134
| _writeAllowed_T_136 | ~_writeAllowed_T_138) begin
end
else
stval <= next;
end end
else if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
scause <= next; | _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 | _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _GEN_7 | _GEN_8 | _GEN_9 | _GEN_10 | _GEN_11 | _GEN_12 | ~_GEN_13) begin | _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
end | _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
else | _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
stval <= next; | _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 | _writeAllowed_T_132 | ~_writeAllowed_T_130) begin
| _GEN_7 | _GEN_8 | _GEN_9 | ~_GEN_10) begin
end end
else else
sscratch <= next; sscratch <= next;
if (~_GEN_17 | _GEN | _GEN_0 | _GEN_1 | _GEN_2 | _GEN_3 | _GEN_4 | _GEN_5 | _GEN_6 if (~_GEN | _writeAllowed_T_75 | _writeAllowed_T_78 | _writeAllowed_T_80
| _GEN_7 | _GEN_8 | _GEN_9 | _GEN_10 | _GEN_11 | _GEN_12 | _GEN_13 | _writeAllowed_T_82 | _writeAllowed_T_84 | _writeAllowed_T_86
| ~_GEN_14) begin | _writeAllowed_T_112 | _writeAllowed_T_88 | _writeAllowed_T_90
| _writeAllowed_T_92 | _writeAllowed_T_94 | _writeAllowed_T_96
| _writeAllowed_T_98 | _writeAllowed_T_100 | _writeAllowed_T_104
| _writeAllowed_T_106 | _writeAllowed_T_108 | _writeAllowed_T_110
| _writeAllowed_T_125 | _writeAllowed_T_126 | _writeAllowed_T_128
| _writeAllowed_T_132 | _writeAllowed_T_130 | _writeAllowed_T_134
| _writeAllowed_T_136 | _writeAllowed_T_138 | _writeAllowed_T_140
| ~_writeAllowed_T_142) begin
end end
else else
satpReg <= next; satpReg <= next;
end end
end // always @(posedge) end // always @(posedge)
assign io_rdata = assign io_rdata =
io_readAddr == 12'h300 readAllowed
? mstatus ? (_readAllowed_T_75
: io_readAddr == 12'h301 ? mstatusView
? 64'h800000000014112D : _readAllowed_T_76
: io_readAddr == 12'h302 ? 64'h8000000000141101
? medeleg : _readAllowed_T_78
: io_readAddr == 12'h303 ? medeleg
? mideleg : _readAllowed_T_80
: io_readAddr == 12'h304 ? mideleg
? mie : _readAllowed_T_82
: io_readAddr == 12'h305 ? mie
? mtvecReg : _readAllowed_T_84
: io_readAddr == 12'h341 ? mtvecReg
? mepcReg : _readAllowed_T_86
: io_readAddr == 12'h342 ? mcounteren
? mcause : _readAllowed_T_112
: io_readAddr == 12'h343 ? mcountinhibit
? mtval : _readAllowed_T_88
: io_readAddr == 12'h344 ? mscratch
? mip : _readAllowed_T_90
: io_readAddr == 12'h100 ? mepcReg
? sstatus : _readAllowed_T_92
: io_readAddr == 12'h105 ? mcause
? stvec : _readAllowed_T_94
: io_readAddr == 12'h140 ? mtval
? sscratch : _readAllowed_T_96
: io_readAddr == 12'h141 ? mip
? sepc : _readAllowed_T_98
: io_readAddr == 12'h142 ? pmpcfg0
? scause : _readAllowed_T_100
: io_readAddr == 12'h143 ? pmpaddr0
? stval : _readAllowed_T_102
: io_readAddr == 12'h180 ? 64'h1
? satpReg : _readAllowed_T_104
: io_readAddr == 12'hF14 ? tdata1
| io_readAddr != 12'hC00 : _readAllowed_T_106
? 64'h0 ? tdata2
: cycle; : _readAllowed_T_108
? tcontrol
: _readAllowed_T_110
? mnstatus
: _readAllowed_T_125
? sstatusView
: _readAllowed_T_126
? mie
& mideleg
: _readAllowed_T_128
? stvec
: _readAllowed_T_132
? scounteren
: _readAllowed_T_130
? sscratch
: _readAllowed_T_134
? sepc
: _readAllowed_T_136
? scause
: _readAllowed_T_138
? stval
: _readAllowed_T_140
? mip
& mideleg
: _readAllowed_T_142
? satpReg
: _readAllowed_T_116
| _readAllowed_T_118
| _readAllowed_T_120
| _readAllowed_T_122
? 64'h0
: _readAllowed_T_114
? instret
: _readAllowed_T_69
| _readAllowed_T_70
? cycle
: _readAllowed_T_72
? instret
: 64'h0)
: 64'h0;
assign io_readIllegal = ~readAllowed;
assign io_trapVector = trapToS ? stvec : mtvecReg;
assign io_satp = satpReg; assign io_satp = satpReg;
assign io_mtvec = mtvecReg;
assign io_mepc = mepcReg; assign io_mepc = mepcReg;
assign io_sepc = sepc;
assign io_medeleg = medeleg;
assign io_mstatus = mstatus;
endmodule endmodule

View File

@@ -2,6 +2,7 @@
module CommitStage( module CommitStage(
input io_robValid_0, input io_robValid_0,
io_robValid_1, io_robValid_1,
input [63:0] io_robEntry_0_pc,
input [4:0] io_robEntry_0_archDest, input [4:0] io_robEntry_0_archDest,
input io_robEntry_0_writesDest, input io_robEntry_0_writesDest,
input [3:0] io_robEntry_0_opClass, input [3:0] io_robEntry_0_opClass,
@@ -14,6 +15,10 @@ module CommitStage(
input [63:0] io_robEntry_0_redirectPc, input [63:0] io_robEntry_0_redirectPc,
input io_robEntry_0_csrValid, input io_robEntry_0_csrValid,
io_robEntry_0_fenceI, io_robEntry_0_fenceI,
io_robEntry_0_sfenceVma,
io_robEntry_0_xret,
io_robEntry_0_xretIsMret,
input [63:0] io_robEntry_1_pc,
input [4:0] io_robEntry_1_archDest, input [4:0] io_robEntry_1_archDest,
input io_robEntry_1_writesDest, input io_robEntry_1_writesDest,
input [5:0] io_robEntry_1_dest, input [5:0] io_robEntry_1_dest,
@@ -25,6 +30,9 @@ module CommitStage(
input [63:0] io_robEntry_1_redirectPc, input [63:0] io_robEntry_1_redirectPc,
input io_robEntry_1_csrValid, input io_robEntry_1_csrValid,
io_robEntry_1_fenceI, io_robEntry_1_fenceI,
io_robEntry_1_sfenceVma,
io_robEntry_1_xret,
io_robEntry_1_xretIsMret,
output io_commitReady_0, output io_commitReady_0,
io_commitReady_1, io_commitReady_1,
io_freeOldPhys_0, io_freeOldPhys_0,
@@ -42,38 +50,53 @@ module CommitStage(
output io_exception, output io_exception,
output [63:0] io_exceptionCause, output [63:0] io_exceptionCause,
io_badAddr, io_badAddr,
output io_fenceI io_trapPc,
output io_fenceI,
io_sfenceVma,
io_xret,
io_xretIsMret,
io_setPriv
); );
wire firstTrap = wire firstTrap =
io_robValid_0 & (io_robEntry_0_exception | io_robEntry_0_branchMispredict); io_robValid_0
& (io_robEntry_0_exception | io_robEntry_0_branchMispredict | io_robEntry_0_xret
| io_robEntry_0_sfenceVma | io_robEntry_0_fenceI);
wire secondTrap = wire secondTrap =
io_robValid_1 & (io_robEntry_1_exception | io_robEntry_1_branchMispredict); io_robValid_1
& (io_robEntry_1_exception | io_robEntry_1_branchMispredict | io_robEntry_1_xret
| io_robEntry_1_sfenceVma | io_robEntry_1_fenceI);
wire io_commitReady_1_0 = wire io_commitReady_1_0 =
io_robValid_1 & ~firstTrap & ~secondTrap io_robValid_1 & ~firstTrap & ~secondTrap
& ~(io_robValid_0 & io_robValid_1 & io_robEntry_0_csrValid & io_robEntry_1_csrValid) & ~(io_robValid_0 & io_robValid_1 & io_robEntry_0_csrValid & io_robEntry_1_csrValid)
& ~(io_robValid_0 & io_robEntry_0_opClass == 4'h4); & ~(io_robValid_0 & io_robEntry_0_opClass == 4'h4);
wire _io_commitMapValid_0_T = io_robValid_0 & io_robEntry_0_writesDest; wire commitWritesDest =
wire _io_commitMapValid_1_T = io_commitReady_1_0 & io_robEntry_1_writesDest; io_robValid_0 & ~io_robEntry_0_exception & io_robEntry_0_writesDest;
wire commitWritesDest_1 =
io_commitReady_1_0 & ~io_robEntry_1_exception & io_robEntry_1_writesDest;
wire secondTrapSelected = ~io_robValid_0 & secondTrap; wire secondTrapSelected = ~io_robValid_0 & secondTrap;
wire selectedTrap = firstTrap | secondTrapSelected;
wire io_exception_0 =
firstTrap ? io_robEntry_0_exception : secondTrapSelected & io_robEntry_1_exception;
wire io_xret_0 =
io_robValid_0 & io_robEntry_0_xret | io_commitReady_1_0 & io_robEntry_1_xret;
assign io_commitReady_0 = io_robValid_0; assign io_commitReady_0 = io_robValid_0;
assign io_commitReady_1 = io_commitReady_1_0; assign io_commitReady_1 = io_commitReady_1_0;
assign io_freeOldPhys_0 = assign io_freeOldPhys_0 =
_io_commitMapValid_0_T & io_robEntry_0_oldDest != io_robEntry_0_dest; commitWritesDest & io_robEntry_0_oldDest != io_robEntry_0_dest;
assign io_freeOldPhys_1 = assign io_freeOldPhys_1 =
_io_commitMapValid_1_T & io_robEntry_1_oldDest != io_robEntry_1_dest; commitWritesDest_1 & io_robEntry_1_oldDest != io_robEntry_1_dest;
assign io_oldPhys_0 = io_robEntry_0_oldDest; assign io_oldPhys_0 = io_robEntry_0_oldDest;
assign io_oldPhys_1 = io_robEntry_1_oldDest; assign io_oldPhys_1 = io_robEntry_1_oldDest;
assign io_commitMapValid_0 = _io_commitMapValid_0_T & (|io_robEntry_0_archDest); assign io_commitMapValid_0 = commitWritesDest & (|io_robEntry_0_archDest);
assign io_commitMapValid_1 = _io_commitMapValid_1_T & (|io_robEntry_1_archDest); assign io_commitMapValid_1 = commitWritesDest_1 & (|io_robEntry_1_archDest);
assign io_commitArch_0 = io_robEntry_0_archDest; assign io_commitArch_0 = io_robEntry_0_archDest;
assign io_commitArch_1 = io_robEntry_1_archDest; assign io_commitArch_1 = io_robEntry_1_archDest;
assign io_commitPhys_0 = io_robEntry_0_dest; assign io_commitPhys_0 = io_robEntry_0_dest;
assign io_commitPhys_1 = io_robEntry_1_dest; assign io_commitPhys_1 = io_robEntry_1_dest;
assign io_flush = firstTrap | secondTrapSelected; assign io_flush = selectedTrap;
assign io_redirectPc = firstTrap ? io_robEntry_0_redirectPc : io_robEntry_1_redirectPc; assign io_redirectPc = firstTrap ? io_robEntry_0_redirectPc : io_robEntry_1_redirectPc;
assign io_exception = assign io_exception = io_exception_0;
firstTrap ? io_robEntry_0_exception : secondTrapSelected & io_robEntry_1_exception;
assign io_exceptionCause = assign io_exceptionCause =
firstTrap firstTrap
? io_robEntry_0_exceptionCause ? io_robEntry_0_exceptionCause
@@ -82,7 +105,16 @@ module CommitStage(
firstTrap firstTrap
? io_robEntry_0_badAddr ? io_robEntry_0_badAddr
: secondTrapSelected ? io_robEntry_1_badAddr : 64'h0; : secondTrapSelected ? io_robEntry_1_badAddr : 64'h0;
assign io_trapPc =
firstTrap ? io_robEntry_0_pc : secondTrapSelected ? io_robEntry_1_pc : 64'h0;
assign io_fenceI = assign io_fenceI =
io_robValid_0 & io_robEntry_0_fenceI | io_commitReady_1_0 & io_robEntry_1_fenceI; io_robValid_0 & io_robEntry_0_fenceI | io_commitReady_1_0 & io_robEntry_1_fenceI;
assign io_sfenceVma =
io_robValid_0 & io_robEntry_0_sfenceVma | io_commitReady_1_0
& io_robEntry_1_sfenceVma;
assign io_xret = io_xret_0;
assign io_xretIsMret =
firstTrap ? io_robEntry_0_xretIsMret : ~secondTrapSelected | io_robEntry_1_xretIsMret;
assign io_setPriv = selectedTrap & (io_exception_0 | io_xret_0);
endmodule endmodule

View File

@@ -16,10 +16,20 @@ module Core(
input [63:0] io_dmem_resp_bits input [63:0] io_dmem_resp_bits
); );
wire [1:0] _privCtrl_io_priv;
wire _backend_io_decodeReady; wire _backend_io_decodeReady;
wire _backend_io_flush; wire _backend_io_flush;
wire [63:0] _backend_io_redirectPc; wire [63:0] _backend_io_redirectPc;
wire _backend_io_invalidateICache; wire _backend_io_invalidateICache;
wire _backend_io_sfenceVma;
wire _backend_io_setPriv;
wire [1:0] _backend_io_targetPriv;
wire _backend_io_dmemReqValid;
wire [63:0] _backend_io_dmemReq_addr;
wire [63:0] _backend_io_dmemReq_data;
wire _backend_io_dmemReq_isStore;
wire [2:0] _backend_io_dmemReq_size;
wire [63:0] _backend_io_satpOut;
wire _id_io_outValid_0; wire _id_io_outValid_0;
wire _id_io_outValid_1; wire _id_io_outValid_1;
wire [63:0] _id_io_out_0_pc; wire [63:0] _id_io_out_0_pc;
@@ -48,10 +58,20 @@ module Core(
wire _id_io_out_0_isWord; wire _id_io_out_0_isWord;
wire _id_io_out_0_isSystem; wire _id_io_out_0_isSystem;
wire _id_io_out_0_isFenceI; wire _id_io_out_0_isFenceI;
wire _id_io_out_0_isEcall;
wire _id_io_out_0_isEbreak;
wire _id_io_out_0_isMret;
wire _id_io_out_0_isSret;
wire _id_io_out_0_isSfenceVma;
wire _id_io_out_0_isXret;
wire _id_io_out_0_isWfi;
wire _id_io_out_0_isAmo; wire _id_io_out_0_isAmo;
wire [4:0] _id_io_out_0_amoOp; wire [4:0] _id_io_out_0_amoOp;
wire _id_io_out_0_writesRd; wire _id_io_out_0_writesRd;
wire _id_io_out_0_illegal; wire _id_io_out_0_illegal;
wire _id_io_out_0_fetchException;
wire [63:0] _id_io_out_0_fetchExceptionCause;
wire [63:0] _id_io_out_0_fetchExceptionTval;
wire [63:0] _id_io_out_1_pc; wire [63:0] _id_io_out_1_pc;
wire [31:0] _id_io_out_1_inst; wire [31:0] _id_io_out_1_inst;
wire [4:0] _id_io_out_1_rs1; wire [4:0] _id_io_out_1_rs1;
@@ -78,29 +98,70 @@ module Core(
wire _id_io_out_1_isWord; wire _id_io_out_1_isWord;
wire _id_io_out_1_isSystem; wire _id_io_out_1_isSystem;
wire _id_io_out_1_isFenceI; wire _id_io_out_1_isFenceI;
wire _id_io_out_1_isEcall;
wire _id_io_out_1_isEbreak;
wire _id_io_out_1_isMret;
wire _id_io_out_1_isSret;
wire _id_io_out_1_isSfenceVma;
wire _id_io_out_1_isXret;
wire _id_io_out_1_isWfi;
wire _id_io_out_1_isAmo; wire _id_io_out_1_isAmo;
wire [4:0] _id_io_out_1_amoOp; wire [4:0] _id_io_out_1_amoOp;
wire _id_io_out_1_writesRd; wire _id_io_out_1_writesRd;
wire _id_io_out_1_illegal; wire _id_io_out_1_illegal;
wire _id_io_out_1_fetchException;
wire [63:0] _id_io_out_1_fetchExceptionCause;
wire [63:0] _id_io_out_1_fetchExceptionTval;
wire _frontend_io_ptwMemReqValid;
wire [63:0] _frontend_io_ptwMemReqAddr;
wire _frontend_io_outValid; wire _frontend_io_outValid;
wire [63:0] _frontend_io_out_pc; wire [63:0] _frontend_io_out_pc;
wire [31:0] _frontend_io_out_inst_0; wire [31:0] _frontend_io_out_inst_0;
wire [31:0] _frontend_io_out_inst_1; wire [31:0] _frontend_io_out_inst_1;
wire _frontend_io_out_laneValid_0; wire _frontend_io_out_laneValid_0;
wire _frontend_io_out_laneValid_1; wire _frontend_io_out_laneValid_1;
wire _frontend_io_out_exception;
wire [63:0] _frontend_io_out_exceptionCause;
wire [63:0] _frontend_io_out_exceptionTval;
reg fetchValid; reg fetchValid;
reg [63:0] fetchReg_pc; reg [63:0] fetchReg_pc;
reg [31:0] fetchReg_inst_0; reg [31:0] fetchReg_inst_0;
reg [31:0] fetchReg_inst_1; reg [31:0] fetchReg_inst_1;
reg fetchReg_laneValid_0; reg fetchReg_laneValid_0;
reg fetchReg_laneValid_1; reg fetchReg_laneValid_1;
reg fetchReg_exception;
reg [63:0] fetchReg_exceptionCause;
reg [63:0] fetchReg_exceptionTval;
wire fetchReady = ~fetchValid | _backend_io_decodeReady; wire fetchReady = ~fetchValid | _backend_io_decodeReady;
reg frontendPtwOutstanding;
reg backendReadOutstanding;
wire frontendPtwCanIssue =
_frontend_io_ptwMemReqValid & ~frontendPtwOutstanding & ~backendReadOutstanding
& ~_backend_io_dmemReqValid;
wire _io_dmem_req_bits_isStore_T =
_backend_io_dmemReqValid & ~frontendPtwOutstanding;
wire frontendPtwRespValid =
io_dmem_resp_valid & (frontendPtwOutstanding | frontendPtwCanIssue);
wire backendRespValid =
io_dmem_resp_valid & ~frontendPtwOutstanding & ~frontendPtwCanIssue;
always @(posedge clock) begin always @(posedge clock) begin
if (reset) if (reset) begin
fetchValid <= 1'h0; fetchValid <= 1'h0;
else frontendPtwOutstanding <= 1'h0;
backendReadOutstanding <= 1'h0;
end
else begin
automatic logic backendReadIssue =
_io_dmem_req_bits_isStore_T & ~_backend_io_dmemReq_isStore
& ~backendReadOutstanding;
fetchValid <= fetchValid <=
~_backend_io_flush & (fetchReady ? _frontend_io_outValid : fetchValid); ~_backend_io_flush & (fetchReady ? _frontend_io_outValid : fetchValid);
frontendPtwOutstanding <=
~frontendPtwRespValid & (frontendPtwCanIssue | frontendPtwOutstanding);
backendReadOutstanding <=
~(backendRespValid & (backendReadOutstanding | backendReadIssue))
& (backendReadIssue & ~backendRespValid | backendReadOutstanding);
end
if (_backend_io_flush | ~fetchReady) begin if (_backend_io_flush | ~fetchReady) begin
end end
else begin else begin
@@ -109,173 +170,248 @@ module Core(
fetchReg_inst_1 <= _frontend_io_out_inst_1; fetchReg_inst_1 <= _frontend_io_out_inst_1;
fetchReg_laneValid_0 <= _frontend_io_out_laneValid_0; fetchReg_laneValid_0 <= _frontend_io_out_laneValid_0;
fetchReg_laneValid_1 <= _frontend_io_out_laneValid_1; fetchReg_laneValid_1 <= _frontend_io_out_laneValid_1;
fetchReg_exception <= _frontend_io_out_exception;
fetchReg_exceptionCause <= _frontend_io_out_exceptionCause;
fetchReg_exceptionTval <= _frontend_io_out_exceptionTval;
end end
end // always @(posedge) end // always @(posedge)
Frontend frontend ( Frontend frontend (
.clock (clock),
.reset (reset),
.io_redirectValid (_backend_io_flush),
.io_redirectPc (_backend_io_redirectPc),
.io_invalidateICache (_backend_io_invalidateICache),
.io_imemReqValid (io_imem_req_valid),
.io_imemReqAddr (io_imem_req_bits),
.io_imemRespValid (io_imem_resp_valid),
.io_imemRespBits_0 (io_imem_resp_bits_0),
.io_imemRespBits_1 (io_imem_resp_bits_1),
.io_outReady (fetchReady),
.io_outValid (_frontend_io_outValid),
.io_out_pc (_frontend_io_out_pc),
.io_out_inst_0 (_frontend_io_out_inst_0),
.io_out_inst_1 (_frontend_io_out_inst_1),
.io_out_laneValid_0 (_frontend_io_out_laneValid_0),
.io_out_laneValid_1 (_frontend_io_out_laneValid_1)
);
IDStage id (
.io_inValid (fetchValid),
.io_in_pc (fetchReg_pc),
.io_in_inst_0 (fetchReg_inst_0),
.io_in_inst_1 (fetchReg_inst_1),
.io_in_laneValid_0 (fetchReg_laneValid_0),
.io_in_laneValid_1 (fetchReg_laneValid_1),
.io_outValid_0 (_id_io_outValid_0),
.io_outValid_1 (_id_io_outValid_1),
.io_out_0_pc (_id_io_out_0_pc),
.io_out_0_inst (_id_io_out_0_inst),
.io_out_0_rs1 (_id_io_out_0_rs1),
.io_out_0_rs2 (_id_io_out_0_rs2),
.io_out_0_rd (_id_io_out_0_rd),
.io_out_0_funct3 (_id_io_out_0_funct3),
.io_out_0_immI (_id_io_out_0_immI),
.io_out_0_immS (_id_io_out_0_immS),
.io_out_0_immB (_id_io_out_0_immB),
.io_out_0_immU (_id_io_out_0_immU),
.io_out_0_immJ (_id_io_out_0_immJ),
.io_out_0_opClass (_id_io_out_0_opClass),
.io_out_0_aluFn (_id_io_out_0_aluFn),
.io_out_0_memWidth (_id_io_out_0_memWidth),
.io_out_0_memSigned (_id_io_out_0_memSigned),
.io_out_0_isLoad (_id_io_out_0_isLoad),
.io_out_0_isStore (_id_io_out_0_isStore),
.io_out_0_isBranch (_id_io_out_0_isBranch),
.io_out_0_isJal (_id_io_out_0_isJal),
.io_out_0_isJalr (_id_io_out_0_isJalr),
.io_out_0_isLui (_id_io_out_0_isLui),
.io_out_0_isAuipc (_id_io_out_0_isAuipc),
.io_out_0_isOpImm (_id_io_out_0_isOpImm),
.io_out_0_isWord (_id_io_out_0_isWord),
.io_out_0_isSystem (_id_io_out_0_isSystem),
.io_out_0_isFenceI (_id_io_out_0_isFenceI),
.io_out_0_isAmo (_id_io_out_0_isAmo),
.io_out_0_amoOp (_id_io_out_0_amoOp),
.io_out_0_writesRd (_id_io_out_0_writesRd),
.io_out_0_illegal (_id_io_out_0_illegal),
.io_out_1_pc (_id_io_out_1_pc),
.io_out_1_inst (_id_io_out_1_inst),
.io_out_1_rs1 (_id_io_out_1_rs1),
.io_out_1_rs2 (_id_io_out_1_rs2),
.io_out_1_rd (_id_io_out_1_rd),
.io_out_1_funct3 (_id_io_out_1_funct3),
.io_out_1_immI (_id_io_out_1_immI),
.io_out_1_immS (_id_io_out_1_immS),
.io_out_1_immB (_id_io_out_1_immB),
.io_out_1_immU (_id_io_out_1_immU),
.io_out_1_immJ (_id_io_out_1_immJ),
.io_out_1_opClass (_id_io_out_1_opClass),
.io_out_1_aluFn (_id_io_out_1_aluFn),
.io_out_1_memWidth (_id_io_out_1_memWidth),
.io_out_1_memSigned (_id_io_out_1_memSigned),
.io_out_1_isLoad (_id_io_out_1_isLoad),
.io_out_1_isStore (_id_io_out_1_isStore),
.io_out_1_isBranch (_id_io_out_1_isBranch),
.io_out_1_isJal (_id_io_out_1_isJal),
.io_out_1_isJalr (_id_io_out_1_isJalr),
.io_out_1_isLui (_id_io_out_1_isLui),
.io_out_1_isAuipc (_id_io_out_1_isAuipc),
.io_out_1_isOpImm (_id_io_out_1_isOpImm),
.io_out_1_isWord (_id_io_out_1_isWord),
.io_out_1_isSystem (_id_io_out_1_isSystem),
.io_out_1_isFenceI (_id_io_out_1_isFenceI),
.io_out_1_isAmo (_id_io_out_1_isAmo),
.io_out_1_amoOp (_id_io_out_1_amoOp),
.io_out_1_writesRd (_id_io_out_1_writesRd),
.io_out_1_illegal (_id_io_out_1_illegal)
);
OoOBackend backend (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_decodeValid_0 (_id_io_outValid_0), .io_redirectValid (_backend_io_flush),
.io_decodeValid_1 (_id_io_outValid_1),
.io_decode_0_pc (_id_io_out_0_pc),
.io_decode_0_inst (_id_io_out_0_inst),
.io_decode_0_rs1 (_id_io_out_0_rs1),
.io_decode_0_rs2 (_id_io_out_0_rs2),
.io_decode_0_rd (_id_io_out_0_rd),
.io_decode_0_funct3 (_id_io_out_0_funct3),
.io_decode_0_immI (_id_io_out_0_immI),
.io_decode_0_immS (_id_io_out_0_immS),
.io_decode_0_immB (_id_io_out_0_immB),
.io_decode_0_immU (_id_io_out_0_immU),
.io_decode_0_immJ (_id_io_out_0_immJ),
.io_decode_0_opClass (_id_io_out_0_opClass),
.io_decode_0_aluFn (_id_io_out_0_aluFn),
.io_decode_0_memWidth (_id_io_out_0_memWidth),
.io_decode_0_memSigned (_id_io_out_0_memSigned),
.io_decode_0_isLoad (_id_io_out_0_isLoad),
.io_decode_0_isStore (_id_io_out_0_isStore),
.io_decode_0_isBranch (_id_io_out_0_isBranch),
.io_decode_0_isJal (_id_io_out_0_isJal),
.io_decode_0_isJalr (_id_io_out_0_isJalr),
.io_decode_0_isLui (_id_io_out_0_isLui),
.io_decode_0_isAuipc (_id_io_out_0_isAuipc),
.io_decode_0_isOpImm (_id_io_out_0_isOpImm),
.io_decode_0_isWord (_id_io_out_0_isWord),
.io_decode_0_isSystem (_id_io_out_0_isSystem),
.io_decode_0_isFenceI (_id_io_out_0_isFenceI),
.io_decode_0_isAmo (_id_io_out_0_isAmo),
.io_decode_0_amoOp (_id_io_out_0_amoOp),
.io_decode_0_writesRd (_id_io_out_0_writesRd),
.io_decode_0_illegal (_id_io_out_0_illegal),
.io_decode_1_pc (_id_io_out_1_pc),
.io_decode_1_inst (_id_io_out_1_inst),
.io_decode_1_rs1 (_id_io_out_1_rs1),
.io_decode_1_rs2 (_id_io_out_1_rs2),
.io_decode_1_rd (_id_io_out_1_rd),
.io_decode_1_funct3 (_id_io_out_1_funct3),
.io_decode_1_immI (_id_io_out_1_immI),
.io_decode_1_immS (_id_io_out_1_immS),
.io_decode_1_immB (_id_io_out_1_immB),
.io_decode_1_immU (_id_io_out_1_immU),
.io_decode_1_immJ (_id_io_out_1_immJ),
.io_decode_1_opClass (_id_io_out_1_opClass),
.io_decode_1_aluFn (_id_io_out_1_aluFn),
.io_decode_1_memWidth (_id_io_out_1_memWidth),
.io_decode_1_memSigned (_id_io_out_1_memSigned),
.io_decode_1_isLoad (_id_io_out_1_isLoad),
.io_decode_1_isStore (_id_io_out_1_isStore),
.io_decode_1_isBranch (_id_io_out_1_isBranch),
.io_decode_1_isJal (_id_io_out_1_isJal),
.io_decode_1_isJalr (_id_io_out_1_isJalr),
.io_decode_1_isLui (_id_io_out_1_isLui),
.io_decode_1_isAuipc (_id_io_out_1_isAuipc),
.io_decode_1_isOpImm (_id_io_out_1_isOpImm),
.io_decode_1_isWord (_id_io_out_1_isWord),
.io_decode_1_isSystem (_id_io_out_1_isSystem),
.io_decode_1_isFenceI (_id_io_out_1_isFenceI),
.io_decode_1_isAmo (_id_io_out_1_isAmo),
.io_decode_1_amoOp (_id_io_out_1_amoOp),
.io_decode_1_writesRd (_id_io_out_1_writesRd),
.io_decode_1_illegal (_id_io_out_1_illegal),
.io_decodeReady (_backend_io_decodeReady),
.io_flush (_backend_io_flush),
.io_redirectPc (_backend_io_redirectPc), .io_redirectPc (_backend_io_redirectPc),
.io_invalidateICache (_backend_io_invalidateICache), .io_invalidateICache (_backend_io_invalidateICache),
.io_dmemReqValid (io_dmem_req_valid), .io_sfenceVma (_backend_io_sfenceVma),
.io_dmemReq_addr (io_dmem_req_bits_addr), .io_satp (_backend_io_satpOut),
.io_dmemReq_data (io_dmem_req_bits_data), .io_currentPriv (_privCtrl_io_priv),
.io_dmemReq_isStore (io_dmem_req_bits_isStore), .io_imemReqValid (io_imem_req_valid),
.io_dmemReq_size (io_dmem_req_bits_size), .io_imemReqAddr (io_imem_req_bits),
.io_dmemRespValid (io_dmem_resp_valid), .io_imemRespValid (io_imem_resp_valid),
.io_dmemRespData (io_dmem_resp_bits) .io_imemRespBits_0 (io_imem_resp_bits_0),
.io_imemRespBits_1 (io_imem_resp_bits_1),
.io_ptwMemReqValid (_frontend_io_ptwMemReqValid),
.io_ptwMemReqAddr (_frontend_io_ptwMemReqAddr),
.io_ptwMemRespValid (frontendPtwRespValid),
.io_ptwMemRespData (io_dmem_resp_bits),
.io_outReady (fetchReady),
.io_outValid (_frontend_io_outValid),
.io_out_pc (_frontend_io_out_pc),
.io_out_inst_0 (_frontend_io_out_inst_0),
.io_out_inst_1 (_frontend_io_out_inst_1),
.io_out_laneValid_0 (_frontend_io_out_laneValid_0),
.io_out_laneValid_1 (_frontend_io_out_laneValid_1),
.io_out_exception (_frontend_io_out_exception),
.io_out_exceptionCause (_frontend_io_out_exceptionCause),
.io_out_exceptionTval (_frontend_io_out_exceptionTval)
); );
IDStage id (
.io_inValid (fetchValid),
.io_in_pc (fetchReg_pc),
.io_in_inst_0 (fetchReg_inst_0),
.io_in_inst_1 (fetchReg_inst_1),
.io_in_laneValid_0 (fetchReg_laneValid_0),
.io_in_laneValid_1 (fetchReg_laneValid_1),
.io_in_exception (fetchReg_exception),
.io_in_exceptionCause (fetchReg_exceptionCause),
.io_in_exceptionTval (fetchReg_exceptionTval),
.io_outValid_0 (_id_io_outValid_0),
.io_outValid_1 (_id_io_outValid_1),
.io_out_0_pc (_id_io_out_0_pc),
.io_out_0_inst (_id_io_out_0_inst),
.io_out_0_rs1 (_id_io_out_0_rs1),
.io_out_0_rs2 (_id_io_out_0_rs2),
.io_out_0_rd (_id_io_out_0_rd),
.io_out_0_funct3 (_id_io_out_0_funct3),
.io_out_0_immI (_id_io_out_0_immI),
.io_out_0_immS (_id_io_out_0_immS),
.io_out_0_immB (_id_io_out_0_immB),
.io_out_0_immU (_id_io_out_0_immU),
.io_out_0_immJ (_id_io_out_0_immJ),
.io_out_0_opClass (_id_io_out_0_opClass),
.io_out_0_aluFn (_id_io_out_0_aluFn),
.io_out_0_memWidth (_id_io_out_0_memWidth),
.io_out_0_memSigned (_id_io_out_0_memSigned),
.io_out_0_isLoad (_id_io_out_0_isLoad),
.io_out_0_isStore (_id_io_out_0_isStore),
.io_out_0_isBranch (_id_io_out_0_isBranch),
.io_out_0_isJal (_id_io_out_0_isJal),
.io_out_0_isJalr (_id_io_out_0_isJalr),
.io_out_0_isLui (_id_io_out_0_isLui),
.io_out_0_isAuipc (_id_io_out_0_isAuipc),
.io_out_0_isOpImm (_id_io_out_0_isOpImm),
.io_out_0_isWord (_id_io_out_0_isWord),
.io_out_0_isSystem (_id_io_out_0_isSystem),
.io_out_0_isFenceI (_id_io_out_0_isFenceI),
.io_out_0_isEcall (_id_io_out_0_isEcall),
.io_out_0_isEbreak (_id_io_out_0_isEbreak),
.io_out_0_isMret (_id_io_out_0_isMret),
.io_out_0_isSret (_id_io_out_0_isSret),
.io_out_0_isSfenceVma (_id_io_out_0_isSfenceVma),
.io_out_0_isXret (_id_io_out_0_isXret),
.io_out_0_isWfi (_id_io_out_0_isWfi),
.io_out_0_isAmo (_id_io_out_0_isAmo),
.io_out_0_amoOp (_id_io_out_0_amoOp),
.io_out_0_writesRd (_id_io_out_0_writesRd),
.io_out_0_illegal (_id_io_out_0_illegal),
.io_out_0_fetchException (_id_io_out_0_fetchException),
.io_out_0_fetchExceptionCause (_id_io_out_0_fetchExceptionCause),
.io_out_0_fetchExceptionTval (_id_io_out_0_fetchExceptionTval),
.io_out_1_pc (_id_io_out_1_pc),
.io_out_1_inst (_id_io_out_1_inst),
.io_out_1_rs1 (_id_io_out_1_rs1),
.io_out_1_rs2 (_id_io_out_1_rs2),
.io_out_1_rd (_id_io_out_1_rd),
.io_out_1_funct3 (_id_io_out_1_funct3),
.io_out_1_immI (_id_io_out_1_immI),
.io_out_1_immS (_id_io_out_1_immS),
.io_out_1_immB (_id_io_out_1_immB),
.io_out_1_immU (_id_io_out_1_immU),
.io_out_1_immJ (_id_io_out_1_immJ),
.io_out_1_opClass (_id_io_out_1_opClass),
.io_out_1_aluFn (_id_io_out_1_aluFn),
.io_out_1_memWidth (_id_io_out_1_memWidth),
.io_out_1_memSigned (_id_io_out_1_memSigned),
.io_out_1_isLoad (_id_io_out_1_isLoad),
.io_out_1_isStore (_id_io_out_1_isStore),
.io_out_1_isBranch (_id_io_out_1_isBranch),
.io_out_1_isJal (_id_io_out_1_isJal),
.io_out_1_isJalr (_id_io_out_1_isJalr),
.io_out_1_isLui (_id_io_out_1_isLui),
.io_out_1_isAuipc (_id_io_out_1_isAuipc),
.io_out_1_isOpImm (_id_io_out_1_isOpImm),
.io_out_1_isWord (_id_io_out_1_isWord),
.io_out_1_isSystem (_id_io_out_1_isSystem),
.io_out_1_isFenceI (_id_io_out_1_isFenceI),
.io_out_1_isEcall (_id_io_out_1_isEcall),
.io_out_1_isEbreak (_id_io_out_1_isEbreak),
.io_out_1_isMret (_id_io_out_1_isMret),
.io_out_1_isSret (_id_io_out_1_isSret),
.io_out_1_isSfenceVma (_id_io_out_1_isSfenceVma),
.io_out_1_isXret (_id_io_out_1_isXret),
.io_out_1_isWfi (_id_io_out_1_isWfi),
.io_out_1_isAmo (_id_io_out_1_isAmo),
.io_out_1_amoOp (_id_io_out_1_amoOp),
.io_out_1_writesRd (_id_io_out_1_writesRd),
.io_out_1_illegal (_id_io_out_1_illegal),
.io_out_1_fetchException (_id_io_out_1_fetchException),
.io_out_1_fetchExceptionCause (_id_io_out_1_fetchExceptionCause),
.io_out_1_fetchExceptionTval (_id_io_out_1_fetchExceptionTval)
);
OoOBackend backend (
.clock (clock),
.reset (reset),
.io_decodeValid_0 (_id_io_outValid_0),
.io_decodeValid_1 (_id_io_outValid_1),
.io_decode_0_pc (_id_io_out_0_pc),
.io_decode_0_inst (_id_io_out_0_inst),
.io_decode_0_rs1 (_id_io_out_0_rs1),
.io_decode_0_rs2 (_id_io_out_0_rs2),
.io_decode_0_rd (_id_io_out_0_rd),
.io_decode_0_funct3 (_id_io_out_0_funct3),
.io_decode_0_immI (_id_io_out_0_immI),
.io_decode_0_immS (_id_io_out_0_immS),
.io_decode_0_immB (_id_io_out_0_immB),
.io_decode_0_immU (_id_io_out_0_immU),
.io_decode_0_immJ (_id_io_out_0_immJ),
.io_decode_0_opClass (_id_io_out_0_opClass),
.io_decode_0_aluFn (_id_io_out_0_aluFn),
.io_decode_0_memWidth (_id_io_out_0_memWidth),
.io_decode_0_memSigned (_id_io_out_0_memSigned),
.io_decode_0_isLoad (_id_io_out_0_isLoad),
.io_decode_0_isStore (_id_io_out_0_isStore),
.io_decode_0_isBranch (_id_io_out_0_isBranch),
.io_decode_0_isJal (_id_io_out_0_isJal),
.io_decode_0_isJalr (_id_io_out_0_isJalr),
.io_decode_0_isLui (_id_io_out_0_isLui),
.io_decode_0_isAuipc (_id_io_out_0_isAuipc),
.io_decode_0_isOpImm (_id_io_out_0_isOpImm),
.io_decode_0_isWord (_id_io_out_0_isWord),
.io_decode_0_isSystem (_id_io_out_0_isSystem),
.io_decode_0_isFenceI (_id_io_out_0_isFenceI),
.io_decode_0_isEcall (_id_io_out_0_isEcall),
.io_decode_0_isEbreak (_id_io_out_0_isEbreak),
.io_decode_0_isMret (_id_io_out_0_isMret),
.io_decode_0_isSret (_id_io_out_0_isSret),
.io_decode_0_isSfenceVma (_id_io_out_0_isSfenceVma),
.io_decode_0_isXret (_id_io_out_0_isXret),
.io_decode_0_isWfi (_id_io_out_0_isWfi),
.io_decode_0_isAmo (_id_io_out_0_isAmo),
.io_decode_0_amoOp (_id_io_out_0_amoOp),
.io_decode_0_writesRd (_id_io_out_0_writesRd),
.io_decode_0_illegal (_id_io_out_0_illegal),
.io_decode_0_fetchException (_id_io_out_0_fetchException),
.io_decode_0_fetchExceptionCause (_id_io_out_0_fetchExceptionCause),
.io_decode_0_fetchExceptionTval (_id_io_out_0_fetchExceptionTval),
.io_decode_1_pc (_id_io_out_1_pc),
.io_decode_1_inst (_id_io_out_1_inst),
.io_decode_1_rs1 (_id_io_out_1_rs1),
.io_decode_1_rs2 (_id_io_out_1_rs2),
.io_decode_1_rd (_id_io_out_1_rd),
.io_decode_1_funct3 (_id_io_out_1_funct3),
.io_decode_1_immI (_id_io_out_1_immI),
.io_decode_1_immS (_id_io_out_1_immS),
.io_decode_1_immB (_id_io_out_1_immB),
.io_decode_1_immU (_id_io_out_1_immU),
.io_decode_1_immJ (_id_io_out_1_immJ),
.io_decode_1_opClass (_id_io_out_1_opClass),
.io_decode_1_aluFn (_id_io_out_1_aluFn),
.io_decode_1_memWidth (_id_io_out_1_memWidth),
.io_decode_1_memSigned (_id_io_out_1_memSigned),
.io_decode_1_isLoad (_id_io_out_1_isLoad),
.io_decode_1_isStore (_id_io_out_1_isStore),
.io_decode_1_isBranch (_id_io_out_1_isBranch),
.io_decode_1_isJal (_id_io_out_1_isJal),
.io_decode_1_isJalr (_id_io_out_1_isJalr),
.io_decode_1_isLui (_id_io_out_1_isLui),
.io_decode_1_isAuipc (_id_io_out_1_isAuipc),
.io_decode_1_isOpImm (_id_io_out_1_isOpImm),
.io_decode_1_isWord (_id_io_out_1_isWord),
.io_decode_1_isSystem (_id_io_out_1_isSystem),
.io_decode_1_isFenceI (_id_io_out_1_isFenceI),
.io_decode_1_isEcall (_id_io_out_1_isEcall),
.io_decode_1_isEbreak (_id_io_out_1_isEbreak),
.io_decode_1_isMret (_id_io_out_1_isMret),
.io_decode_1_isSret (_id_io_out_1_isSret),
.io_decode_1_isSfenceVma (_id_io_out_1_isSfenceVma),
.io_decode_1_isXret (_id_io_out_1_isXret),
.io_decode_1_isWfi (_id_io_out_1_isWfi),
.io_decode_1_isAmo (_id_io_out_1_isAmo),
.io_decode_1_amoOp (_id_io_out_1_amoOp),
.io_decode_1_writesRd (_id_io_out_1_writesRd),
.io_decode_1_illegal (_id_io_out_1_illegal),
.io_decode_1_fetchException (_id_io_out_1_fetchException),
.io_decode_1_fetchExceptionCause (_id_io_out_1_fetchExceptionCause),
.io_decode_1_fetchExceptionTval (_id_io_out_1_fetchExceptionTval),
.io_decodeReady (_backend_io_decodeReady),
.io_flush (_backend_io_flush),
.io_redirectPc (_backend_io_redirectPc),
.io_invalidateICache (_backend_io_invalidateICache),
.io_sfenceVma (_backend_io_sfenceVma),
.io_setPriv (_backend_io_setPriv),
.io_targetPriv (_backend_io_targetPriv),
.io_dmemReqValid (_backend_io_dmemReqValid),
.io_dmemReq_addr (_backend_io_dmemReq_addr),
.io_dmemReq_data (_backend_io_dmemReq_data),
.io_dmemReq_isStore (_backend_io_dmemReq_isStore),
.io_dmemReq_size (_backend_io_dmemReq_size),
.io_dmemRespValid (backendRespValid),
.io_dmemRespData (io_dmem_resp_bits),
.io_satpOut (_backend_io_satpOut),
.io_currentPriv (_privCtrl_io_priv)
);
PrivilegeControl privCtrl (
.clock (clock),
.reset (reset),
.io_nextPriv (_backend_io_targetPriv),
.io_setPriv (_backend_io_setPriv),
.io_priv (_privCtrl_io_priv)
);
assign io_dmem_req_valid = _io_dmem_req_bits_isStore_T | frontendPtwCanIssue;
assign io_dmem_req_bits_addr =
frontendPtwCanIssue ? _frontend_io_ptwMemReqAddr : _backend_io_dmemReq_addr;
assign io_dmem_req_bits_data = frontendPtwCanIssue ? 64'h0 : _backend_io_dmemReq_data;
assign io_dmem_req_bits_isStore =
_io_dmem_req_bits_isStore_T & _backend_io_dmemReq_isStore;
assign io_dmem_req_bits_size = frontendPtwCanIssue ? 3'h3 : _backend_io_dmemReq_size;
endmodule endmodule

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,13 @@ module Decoder(
io_out_isWord, io_out_isWord,
io_out_isSystem, io_out_isSystem,
io_out_isFenceI, io_out_isFenceI,
io_out_isEcall,
io_out_isEbreak,
io_out_isMret,
io_out_isSret,
io_out_isSfenceVma,
io_out_isXret,
io_out_isWfi,
io_out_isAmo, io_out_isAmo,
output [4:0] io_out_amoOp, output [4:0] io_out_amoOp,
output io_out_writesRd, output io_out_writesRd,
@@ -36,7 +43,16 @@ module Decoder(
wire [7:0][4:0] _GEN = '{5'hE, 5'hD, 5'hC, 5'hB, 5'h12, 5'h11, 5'h10, 5'hA}; wire [7:0][4:0] _GEN = '{5'hE, 5'hD, 5'hC, 5'hB, 5'h12, 5'h11, 5'h10, 5'hA};
wire [7:0][1:0] _GEN_0 = '{2'h3, 2'h2, 2'h1, 2'h0, 2'h3, 2'h2, 2'h1, 2'h0}; wire [7:0][1:0] _GEN_0 = '{2'h3, 2'h2, 2'h1, 2'h0, 2'h3, 2'h2, 2'h1, 2'h0};
wire _isSfenceVma_T = io_inst[14:12] == 3'h0;
wire _d_isFenceI_T = io_inst[14:12] == 3'h1; wire _d_isFenceI_T = io_inst[14:12] == 3'h1;
wire isSystemOpcode = io_inst[6:0] == 7'h73;
wire isFenceOpcode = io_inst[6:0] == 7'hF;
wire isEcall = io_inst == 32'h73;
wire isEbreak = io_inst == 32'h100073;
wire isMret = io_inst == 32'h30200073;
wire isSret = io_inst == 32'h10200073;
wire isWfi = io_inst == 32'h10500073;
wire isSfenceVma = isSystemOpcode & _isSfenceVma_T & io_inst[31:25] == 7'h9;
wire d_isLui = io_inst[6:0] == 7'h37; wire d_isLui = io_inst[6:0] == 7'h37;
wire _GEN_1 = io_inst[6:0] == 7'h17; wire _GEN_1 = io_inst[6:0] == 7'h17;
wire _GEN_2 = io_inst[6:0] == 7'h6F; wire _GEN_2 = io_inst[6:0] == 7'h6F;
@@ -70,15 +86,15 @@ module Decoder(
{5'h3}, {5'h3},
{5'h2}, {5'h2},
{{4'h0, io_inst[30]}}}; {{4'h0, io_inst[30]}}};
wire _GEN_14 = io_inst[6:0] == 7'hF; wire _GEN_14 = _GEN_8 | _GEN_12;
wire _GEN_15 = _GEN_8 | _GEN_12; wire _GEN_15 =
wire _GEN_16 = io_inst[6:0] == 7'h73; d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_7 | _GEN_14;
wire _GEN_17 = io_inst[6:0] == 7'h2F; wire _GEN_16 = io_inst[6:0] == 7'h2F;
wire _GEN_18 = _GEN_14 | _GEN_16; wire _GEN_17 = isFenceOpcode | isSystemOpcode;
wire _GEN_19 = _GEN_7 | _GEN_8 | _GEN_12 | _GEN_18; wire _GEN_18 = _GEN_7 | _GEN_8 | _GEN_12 | _GEN_17;
wire _GEN_20 = _GEN_2 | _GEN_4 | _GEN_5; wire _GEN_19 = _GEN_2 | _GEN_4 | _GEN_5;
wire _GEN_21 = wire _GEN_20 =
d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_19; d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_18;
assign io_out_pc = io_pc; assign io_out_pc = io_pc;
assign io_out_inst = io_inst; assign io_out_inst = io_inst;
assign io_out_rs1 = io_inst[19:15]; assign io_out_rs1 = io_inst[19:15];
@@ -95,11 +111,11 @@ module Decoder(
assign io_out_opClass = assign io_out_opClass =
_GEN_3 _GEN_3
? 4'h1 ? 4'h1
: _GEN_20 : _GEN_19
? 4'h2 ? 4'h2
: _GEN_6 : _GEN_6
? 4'h3 ? 4'h3
: _GEN_7 ? 4'h4 : _GEN_15 ? 4'h1 : _GEN_18 ? 4'h5 : _GEN_17 ? 4'h3 : 4'h0; : _GEN_7 ? 4'h4 : _GEN_14 ? 4'h1 : _GEN_17 ? 4'h5 : _GEN_16 ? 4'h3 : 4'h0;
assign io_out_aluFn = assign io_out_aluFn =
d_isLui d_isLui
? 5'hF ? 5'hF
@@ -113,9 +129,9 @@ module Decoder(
: _GEN_13[io_inst[14:12]]) : _GEN_13[io_inst[14:12]])
: 5'h0; : 5'h0;
assign io_out_memWidth = assign io_out_memWidth =
_GEN_21 | ~_GEN_17 ? {1'h0, _GEN_0[io_inst[14:12]]} : {2'h1, io_inst[14:12] != 3'h2}; _GEN_20 | ~_GEN_16 ? {1'h0, _GEN_0[io_inst[14:12]]} : {2'h1, io_inst[14:12] != 3'h2};
assign io_out_memSigned = ~(io_inst[14]); assign io_out_memSigned = ~(io_inst[14]);
assign io_out_isLoad = ~(d_isLui | _GEN_1 | _GEN_20) & (_GEN_6 | ~_GEN_19 & _GEN_17); assign io_out_isLoad = ~(d_isLui | _GEN_1 | _GEN_19) & (_GEN_6 | ~_GEN_18 & _GEN_16);
assign io_out_isStore = assign io_out_isStore =
~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6) & _GEN_7; ~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6) & _GEN_7;
assign io_out_isBranch = ~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4) & _GEN_5; assign io_out_isBranch = ~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4) & _GEN_5;
@@ -127,11 +143,16 @@ module Decoder(
assign io_out_isWord = ~_GEN_10 & (_GEN_8 ? _d_isWord_T : _GEN_12 & _d_isWord_T_1); assign io_out_isWord = ~_GEN_10 & (_GEN_8 ? _d_isWord_T : _GEN_12 & _d_isWord_T_1);
assign io_out_isSystem = assign io_out_isSystem =
~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_7 | _GEN_8 | _GEN_12 ~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_7 | _GEN_8 | _GEN_12
| _GEN_14) & _GEN_16; | isFenceOpcode) & isSystemOpcode;
assign io_out_isFenceI = assign io_out_isFenceI = ~_GEN_15 & isFenceOpcode & _d_isFenceI_T;
~(d_isLui | _GEN_1 | _GEN_2 | _GEN_4 | _GEN_5 | _GEN_6 | _GEN_7 | _GEN_15) & _GEN_14 assign io_out_isEcall = isEcall;
& _d_isFenceI_T; assign io_out_isEbreak = isEbreak;
assign io_out_isAmo = ~_GEN_21 & _GEN_17; assign io_out_isMret = isMret;
assign io_out_isSret = isSret;
assign io_out_isSfenceVma = isSfenceVma;
assign io_out_isXret = isMret | isSret;
assign io_out_isWfi = isWfi;
assign io_out_isAmo = ~_GEN_20 & _GEN_16;
assign io_out_amoOp = io_inst[31:27]; assign io_out_amoOp = io_inst[31:27];
assign io_out_writesRd = assign io_out_writesRd =
d_isLui d_isLui
@@ -150,15 +171,20 @@ module Decoder(
? (|(io_inst[11:7])) ? (|(io_inst[11:7]))
: _GEN_12 : _GEN_12
? (|(io_inst[11:7])) ? (|(io_inst[11:7]))
: ~_GEN_14 : ~isFenceOpcode
& (_GEN_16 & (isSystemOpcode
? (|(io_inst[11:7])) & (|(io_inst[14:12])) ? (|(io_inst[11:7])) & (|(io_inst[14:12]))
: _GEN_17 & (|(io_inst[11:7]))))); : _GEN_16 & (|(io_inst[11:7])))));
assign io_out_illegal = assign io_out_illegal =
io_inst[6:0] != 7'h37 & io_inst[6:0] != 7'h17 & io_inst[6:0] != 7'h6F isSystemOpcode & io_inst == 32'h200073 | io_inst[6:0] != 7'h37 & io_inst[6:0] != 7'h17
& io_inst[6:0] != 7'h67 & io_inst[6:0] != 7'h63 & io_inst[6:0] != 7'h3 & io_inst[6:0] != 7'h6F & io_inst[6:0] != 7'h67 & io_inst[6:0] != 7'h63
& io_inst[6:0] != 7'h23 & io_inst[6:0] != 7'h13 & io_inst[6:0] != 7'h1B & io_inst[6:0] != 7'h3 & io_inst[6:0] != 7'h23 & io_inst[6:0] != 7'h13
& io_inst[6:0] != 7'h33 & io_inst[6:0] != 7'h3B & io_inst[6:0] != 7'hF & io_inst[6:0] != 7'h1B & io_inst[6:0] != 7'h33 & io_inst[6:0] != 7'h3B
& io_inst[6:0] != 7'h73 & io_inst[6:0] != 7'h2F; & io_inst[6:0] != 7'hF & io_inst[6:0] != 7'h73 & io_inst[6:0] != 7'h2F | ~_GEN_15
& (isFenceOpcode
? (|(io_inst[14:12])) & io_inst[14:12] != 3'h1
: isSystemOpcode & _isSfenceVma_T
& ~((isEcall | isEbreak | isMret | isSret | isSfenceVma | isWfi)
& io_inst != 32'h200073));
endmodule endmodule

View File

@@ -5,60 +5,163 @@ module Frontend(
io_redirectValid, io_redirectValid,
input [63:0] io_redirectPc, input [63:0] io_redirectPc,
input io_invalidateICache, input io_invalidateICache,
io_sfenceVma,
input [63:0] io_satp,
input [1:0] io_currentPriv,
output io_imemReqValid, output io_imemReqValid,
output [63:0] io_imemReqAddr, output [63:0] io_imemReqAddr,
input io_imemRespValid, input io_imemRespValid,
input [31:0] io_imemRespBits_0, input [31:0] io_imemRespBits_0,
io_imemRespBits_1, io_imemRespBits_1,
output io_ptwMemReqValid,
output [63:0] io_ptwMemReqAddr,
input io_ptwMemRespValid,
input [63:0] io_ptwMemRespData,
input io_outReady, input io_outReady,
output io_outValid, output io_outValid,
output [63:0] io_out_pc, output [63:0] io_out_pc,
output [31:0] io_out_inst_0, output [31:0] io_out_inst_0,
io_out_inst_1, io_out_inst_1,
output io_out_laneValid_0, output io_out_laneValid_0,
io_out_laneValid_1 io_out_laneValid_1,
io_out_exception,
output [63:0] io_out_exceptionCause,
io_out_exceptionTval
); );
wire _icache_io_respValid; wire _icache_io_respValid;
wire [63:0] _icache_io_resp_pc; wire [63:0] _icache_io_resp_pc;
wire [31:0] _icache_io_resp_inst_0;
wire [31:0] _icache_io_resp_inst_1;
wire _icache_io_resp_laneValid_0; wire _icache_io_resp_laneValid_0;
wire _icache_io_resp_laneValid_1; wire _icache_io_resp_laneValid_1;
wire _icache_io_resp_exception;
wire [63:0] _icache_io_resp_exceptionCause;
wire [63:0] _icache_io_resp_exceptionTval;
wire _immu_io_resp_pageFault;
wire _immu_io_refill_valid;
wire [26:0] _immu_io_refill_vpn;
wire [43:0] _immu_io_refill_ppn;
wire [1:0] _immu_io_refill_level;
wire [7:0] _immu_io_refill_flags;
wire _itlb_io_resp_hit;
wire _itlb_io_resp_miss;
wire [63:0] _itlb_io_resp_paddr;
wire _itlb_io_resp_pageFault;
reg [63:0] pc; reg [63:0] pc;
reg faultPending;
reg [63:0] faultPc;
reg [63:0] faultCause;
wire fetchTranslate = (|(io_satp[63:60])) & io_currentPriv != 2'h3;
wire itlbMiss = fetchTranslate & _itlb_io_resp_miss;
wire instPageFault =
fetchTranslate & (_itlb_io_resp_pageFault | _immu_io_resp_pageFault);
wire fetchFault = (|(pc[1:0])) | instPageFault;
wire translationReady = ~fetchTranslate | _itlb_io_resp_hit | instPageFault;
wire [63:0] translatedFetchAddr = fetchTranslate ? _itlb_io_resp_paddr : pc;
always @(posedge clock) begin always @(posedge clock) begin
if (reset) automatic logic _GEN;
_GEN = fetchFault & ~faultPending;
if (reset) begin
pc <= 64'h80000000; pc <= 64'h80000000;
else if (io_redirectValid) faultPending <= 1'h0;
pc <= io_redirectPc; end
else if (_icache_io_respValid & io_outReady) else begin
pc <= automatic logic _GEN_0;
_icache_io_resp_pc _GEN_0 = faultPending & io_outReady;
+ {60'h0, if (io_redirectValid)
{1'h0, _icache_io_resp_laneValid_0} + {1'h0, _icache_io_resp_laneValid_1}, pc <= io_redirectPc;
2'h0}; else if (~_GEN) begin
if (_GEN_0)
pc <= pc + 64'h4;
else if (_icache_io_respValid & io_outReady)
pc <=
_icache_io_resp_pc
+ {60'h0,
{1'h0, _icache_io_resp_laneValid_0} + {1'h0, _icache_io_resp_laneValid_1},
2'h0};
end
faultPending <= ~io_redirectValid & (_GEN | ~_GEN_0 & faultPending);
end
if (io_redirectValid | ~_GEN) begin
end
else begin
faultPc <= pc;
faultCause <= {56'h0, (|(pc[1:0])) ? 8'h0 : 8'hC};
end
end // always @(posedge) end // always @(posedge)
ICache icache ( ITLB itlb (
.clock (clock),
.reset (reset),
.io_req_valid (fetchTranslate & ~faultPending),
.io_req_vaddr (pc),
.io_req_priv (io_currentPriv),
.io_resp_hit (_itlb_io_resp_hit),
.io_resp_miss (_itlb_io_resp_miss),
.io_resp_paddr (_itlb_io_resp_paddr),
.io_resp_pageFault (_itlb_io_resp_pageFault),
.io_refill_valid (_immu_io_refill_valid),
.io_refill_vpn (_immu_io_refill_vpn),
.io_refill_ppn (_immu_io_refill_ppn),
.io_refill_level (_immu_io_refill_level),
.io_refill_flags (_immu_io_refill_flags),
.io_flush (io_redirectValid | io_invalidateICache | io_sfenceVma)
);
MMU immu (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_reqAddr (pc), .io_satp (io_satp),
.io_reqPc (pc), .io_req_valid (itlbMiss),
.io_flush (io_redirectValid), .io_req_vaddr (pc),
.io_invalidate (io_invalidateICache), .io_req_isStore (1'h0),
.io_respReady (io_outReady), .io_req_isFetch (1'h1),
.io_memReqValid (io_imemReqValid), .io_req_priv (io_currentPriv),
.io_memReqAddr (io_imemReqAddr), .io_req_sum (1'h0),
.io_memRespValid (io_imemRespValid), .io_req_mxr (1'h0),
.io_memRespBits_0 (io_imemRespBits_0), .io_resp_pageFault (_immu_io_resp_pageFault),
.io_memRespBits_1 (io_imemRespBits_1), .io_ptwMemReq_valid (io_ptwMemReqValid),
.io_respValid (_icache_io_respValid), .io_ptwMemReq_addr (io_ptwMemReqAddr),
.io_resp_pc (_icache_io_resp_pc), .io_ptwMemResp_valid (io_ptwMemRespValid),
.io_resp_inst_0 (io_out_inst_0), .io_ptwMemResp_data (io_ptwMemRespData),
.io_resp_inst_1 (io_out_inst_1), .io_refill_valid (_immu_io_refill_valid),
.io_resp_laneValid_0 (_icache_io_resp_laneValid_0), .io_refill_vpn (_immu_io_refill_vpn),
.io_resp_laneValid_1 (_icache_io_resp_laneValid_1) .io_refill_ppn (_immu_io_refill_ppn),
.io_refill_level (_immu_io_refill_level),
.io_refill_flags (_immu_io_refill_flags)
); );
assign io_outValid = _icache_io_respValid; ICache icache (
assign io_out_pc = _icache_io_resp_pc; .clock (clock),
assign io_out_laneValid_0 = _icache_io_resp_laneValid_0; .reset (reset),
assign io_out_laneValid_1 = _icache_io_resp_laneValid_1; .io_reqValid (~fetchFault & ~faultPending & translationReady),
.io_reqAddr (translatedFetchAddr),
.io_reqPc (pc),
.io_flush (io_redirectValid),
.io_invalidate (io_invalidateICache),
.io_respReady (io_outReady),
.io_memReqValid (io_imemReqValid),
.io_memReqAddr (io_imemReqAddr),
.io_memRespValid (io_imemRespValid),
.io_memRespBits_0 (io_imemRespBits_0),
.io_memRespBits_1 (io_imemRespBits_1),
.io_respValid (_icache_io_respValid),
.io_resp_pc (_icache_io_resp_pc),
.io_resp_inst_0 (_icache_io_resp_inst_0),
.io_resp_inst_1 (_icache_io_resp_inst_1),
.io_resp_laneValid_0 (_icache_io_resp_laneValid_0),
.io_resp_laneValid_1 (_icache_io_resp_laneValid_1),
.io_resp_exception (_icache_io_resp_exception),
.io_resp_exceptionCause (_icache_io_resp_exceptionCause),
.io_resp_exceptionTval (_icache_io_resp_exceptionTval)
);
assign io_outValid = faultPending | _icache_io_respValid;
assign io_out_pc = faultPending ? faultPc : _icache_io_resp_pc;
assign io_out_inst_0 = faultPending ? 32'h0 : _icache_io_resp_inst_0;
assign io_out_inst_1 = faultPending ? 32'h0 : _icache_io_resp_inst_1;
assign io_out_laneValid_0 = faultPending | _icache_io_resp_laneValid_0;
assign io_out_laneValid_1 = ~faultPending & _icache_io_resp_laneValid_1;
assign io_out_exception = faultPending | _icache_io_resp_exception;
assign io_out_exceptionCause =
faultPending ? faultCause : _icache_io_resp_exceptionCause;
assign io_out_exceptionTval = faultPending ? faultPc : _icache_io_resp_exceptionTval;
endmodule endmodule

View File

@@ -2,6 +2,7 @@
module ICache( module ICache(
input clock, input clock,
reset, reset,
io_reqValid,
input [63:0] io_reqAddr, input [63:0] io_reqAddr,
io_reqPc, io_reqPc,
input io_flush, input io_flush,
@@ -17,7 +18,10 @@ module ICache(
output [31:0] io_resp_inst_0, output [31:0] io_resp_inst_0,
io_resp_inst_1, io_resp_inst_1,
output io_resp_laneValid_0, output io_resp_laneValid_0,
io_resp_laneValid_1 io_resp_laneValid_1,
io_resp_exception,
output [63:0] io_resp_exceptionCause,
io_resp_exceptionTval
); );
wire [31:0] dataWrite_3_1; wire [31:0] dataWrite_3_1;
@@ -9295,8 +9299,9 @@ module ICache(
reg [31:0] respReg_inst_1; reg [31:0] respReg_inst_1;
reg respReg_laneValid_0; reg respReg_laneValid_0;
reg respReg_laneValid_1; reg respReg_laneValid_1;
reg respReg_exception;
wire _readFire_T = state == 2'h0; wire _readFire_T = state == 2'h0;
wire readFire = _readFire_T & ~io_flush; wire readFire = _readFire_T & io_reqValid & ~io_flush;
wire tagHitVec_0 = wire tagHitVec_0 =
(|{lookupValidRow_0_1, lookupValidRow_0_0}) (|{lookupValidRow_0_1, lookupValidRow_0_0})
& _tags_ext_R0_data[50:0] == lookupAddr[63:13]; & _tags_ext_R0_data[50:0] == lookupAddr[63:13];
@@ -38132,7 +38137,7 @@ module ICache(
{{_GEN_18 ? _GEN_2082 : state}, {{_GEN_18 ? _GEN_2082 : state},
{io_respReady ? 2'h0 : state}, {io_respReady ? 2'h0 : state},
{(|_hitWay_T) ? _GEN_2082 : 2'h3}, {(|_hitWay_T) ? _GEN_2082 : 2'h3},
{2'h1}}; {io_reqValid ? 2'h1 : state}};
state <= _GEN_2083[state]; state <= _GEN_2083[state];
end end
missReqSent <= missReqSent <=
@@ -38143,7 +38148,7 @@ module ICache(
? (|_hitWay_T) & missReqSent ? (|_hitWay_T) & missReqSent
: ~_io_resp_T & (&state) & ~missReqSent | missReqSent); : ~_io_resp_T & (&state) & ~missReqSent | missReqSent);
end end
if (_GEN_16 | ~_readFire_T) begin if (_GEN_16 | ~(_readFire_T & io_reqValid)) begin
end end
else begin else begin
automatic logic [1023:0] _GEN_2084 = automatic logic [1023:0] _GEN_2084 =
@@ -47420,8 +47425,12 @@ module ICache(
missValidRow_3_1 <= lookupValidRow_3_1; missValidRow_3_1 <= lookupValidRow_3_1;
end end
if (~_GEN_17) begin if (~_GEN_17) begin
automatic logic _GEN_2093;
automatic logic _GEN_2094;
_GEN_2093 = ~(|_hitWay_T) | io_respReady;
_GEN_2094 = _io_resp_T | ~_GEN_18 | io_respReady;
if (_io_miss_T) begin if (_io_miss_T) begin
if (~(|_hitWay_T) | io_respReady) begin if (_GEN_2093) begin
end end
else begin else begin
respReg_pc <= lookupPc; respReg_pc <= lookupPc;
@@ -47430,7 +47439,7 @@ module ICache(
respReg_laneValid_1 <= lookupLane1Valid; respReg_laneValid_1 <= lookupLane1Valid;
end end
end end
else if (_io_resp_T | ~_GEN_18 | io_respReady) begin else if (_GEN_2094) begin
end end
else begin else begin
respReg_pc <= missPc; respReg_pc <= missPc;
@@ -47442,6 +47451,8 @@ module ICache(
_io_miss_T _io_miss_T
? (|_hitWay_T) & ~io_respReady | respReg_laneValid_0 ? (|_hitWay_T) & ~io_respReady | respReg_laneValid_0
: ~_io_resp_T & _GEN_18 & ~io_respReady | respReg_laneValid_0; : ~_io_resp_T & _GEN_18 & ~io_respReady | respReg_laneValid_0;
respReg_exception <=
_io_miss_T ? _GEN_2093 & respReg_exception : _GEN_2094 & respReg_exception;
end end
end // always @(posedge) end // always @(posedge)
tags_1024x204 tags_ext ( tags_1024x204 tags_ext (
@@ -47487,5 +47498,8 @@ module ICache(
assign io_resp_laneValid_0 = ~_io_resp_T | respReg_laneValid_0; assign io_resp_laneValid_0 = ~_io_resp_T | respReg_laneValid_0;
assign io_resp_laneValid_1 = assign io_resp_laneValid_1 =
_io_resp_T ? respReg_laneValid_1 : _io_resp_T_2 ? ~missInst : lookupLane1Valid; _io_resp_T ? respReg_laneValid_1 : _io_resp_T_2 ? ~missInst : lookupLane1Valid;
assign io_resp_exception = _io_resp_T & respReg_exception;
assign io_resp_exceptionCause = 64'h0;
assign io_resp_exceptionTval = 64'h0;
endmodule endmodule

View File

@@ -6,6 +6,9 @@ module IDStage(
io_in_inst_1, io_in_inst_1,
input io_in_laneValid_0, input io_in_laneValid_0,
io_in_laneValid_1, io_in_laneValid_1,
io_in_exception,
input [63:0] io_in_exceptionCause,
io_in_exceptionTval,
output io_outValid_0, output io_outValid_0,
io_outValid_1, io_outValid_1,
output [63:0] io_out_0_pc, output [63:0] io_out_0_pc,
@@ -34,11 +37,21 @@ module IDStage(
io_out_0_isWord, io_out_0_isWord,
io_out_0_isSystem, io_out_0_isSystem,
io_out_0_isFenceI, io_out_0_isFenceI,
io_out_0_isEcall,
io_out_0_isEbreak,
io_out_0_isMret,
io_out_0_isSret,
io_out_0_isSfenceVma,
io_out_0_isXret,
io_out_0_isWfi,
io_out_0_isAmo, io_out_0_isAmo,
output [4:0] io_out_0_amoOp, output [4:0] io_out_0_amoOp,
output io_out_0_writesRd, output io_out_0_writesRd,
io_out_0_illegal, io_out_0_illegal,
output [63:0] io_out_1_pc, io_out_0_fetchException,
output [63:0] io_out_0_fetchExceptionCause,
io_out_0_fetchExceptionTval,
io_out_1_pc,
output [31:0] io_out_1_inst, output [31:0] io_out_1_inst,
output [4:0] io_out_1_rs1, output [4:0] io_out_1_rs1,
io_out_1_rs2, io_out_1_rs2,
@@ -64,81 +77,111 @@ module IDStage(
io_out_1_isWord, io_out_1_isWord,
io_out_1_isSystem, io_out_1_isSystem,
io_out_1_isFenceI, io_out_1_isFenceI,
io_out_1_isEcall,
io_out_1_isEbreak,
io_out_1_isMret,
io_out_1_isSret,
io_out_1_isSfenceVma,
io_out_1_isXret,
io_out_1_isWfi,
io_out_1_isAmo, io_out_1_isAmo,
output [4:0] io_out_1_amoOp, output [4:0] io_out_1_amoOp,
output io_out_1_writesRd, output io_out_1_writesRd,
io_out_1_illegal io_out_1_illegal,
io_out_1_fetchException,
output [63:0] io_out_1_fetchExceptionCause,
io_out_1_fetchExceptionTval
); );
Decoder decoders_0 ( Decoder decoders_0 (
.io_pc (io_in_pc), .io_pc (io_in_pc),
.io_inst (io_in_inst_0), .io_inst (io_in_inst_0),
.io_out_pc (io_out_0_pc), .io_out_pc (io_out_0_pc),
.io_out_inst (io_out_0_inst), .io_out_inst (io_out_0_inst),
.io_out_rs1 (io_out_0_rs1), .io_out_rs1 (io_out_0_rs1),
.io_out_rs2 (io_out_0_rs2), .io_out_rs2 (io_out_0_rs2),
.io_out_rd (io_out_0_rd), .io_out_rd (io_out_0_rd),
.io_out_funct3 (io_out_0_funct3), .io_out_funct3 (io_out_0_funct3),
.io_out_immI (io_out_0_immI), .io_out_immI (io_out_0_immI),
.io_out_immS (io_out_0_immS), .io_out_immS (io_out_0_immS),
.io_out_immB (io_out_0_immB), .io_out_immB (io_out_0_immB),
.io_out_immU (io_out_0_immU), .io_out_immU (io_out_0_immU),
.io_out_immJ (io_out_0_immJ), .io_out_immJ (io_out_0_immJ),
.io_out_opClass (io_out_0_opClass), .io_out_opClass (io_out_0_opClass),
.io_out_aluFn (io_out_0_aluFn), .io_out_aluFn (io_out_0_aluFn),
.io_out_memWidth (io_out_0_memWidth), .io_out_memWidth (io_out_0_memWidth),
.io_out_memSigned (io_out_0_memSigned), .io_out_memSigned (io_out_0_memSigned),
.io_out_isLoad (io_out_0_isLoad), .io_out_isLoad (io_out_0_isLoad),
.io_out_isStore (io_out_0_isStore), .io_out_isStore (io_out_0_isStore),
.io_out_isBranch (io_out_0_isBranch), .io_out_isBranch (io_out_0_isBranch),
.io_out_isJal (io_out_0_isJal), .io_out_isJal (io_out_0_isJal),
.io_out_isJalr (io_out_0_isJalr), .io_out_isJalr (io_out_0_isJalr),
.io_out_isLui (io_out_0_isLui), .io_out_isLui (io_out_0_isLui),
.io_out_isAuipc (io_out_0_isAuipc), .io_out_isAuipc (io_out_0_isAuipc),
.io_out_isOpImm (io_out_0_isOpImm), .io_out_isOpImm (io_out_0_isOpImm),
.io_out_isWord (io_out_0_isWord), .io_out_isWord (io_out_0_isWord),
.io_out_isSystem (io_out_0_isSystem), .io_out_isSystem (io_out_0_isSystem),
.io_out_isFenceI (io_out_0_isFenceI), .io_out_isFenceI (io_out_0_isFenceI),
.io_out_isAmo (io_out_0_isAmo), .io_out_isEcall (io_out_0_isEcall),
.io_out_amoOp (io_out_0_amoOp), .io_out_isEbreak (io_out_0_isEbreak),
.io_out_writesRd (io_out_0_writesRd), .io_out_isMret (io_out_0_isMret),
.io_out_illegal (io_out_0_illegal) .io_out_isSret (io_out_0_isSret),
.io_out_isSfenceVma (io_out_0_isSfenceVma),
.io_out_isXret (io_out_0_isXret),
.io_out_isWfi (io_out_0_isWfi),
.io_out_isAmo (io_out_0_isAmo),
.io_out_amoOp (io_out_0_amoOp),
.io_out_writesRd (io_out_0_writesRd),
.io_out_illegal (io_out_0_illegal)
); );
Decoder decoders_1 ( Decoder decoders_1 (
.io_pc (io_in_pc + 64'h4), .io_pc (io_in_pc + 64'h4),
.io_inst (io_in_inst_1), .io_inst (io_in_inst_1),
.io_out_pc (io_out_1_pc), .io_out_pc (io_out_1_pc),
.io_out_inst (io_out_1_inst), .io_out_inst (io_out_1_inst),
.io_out_rs1 (io_out_1_rs1), .io_out_rs1 (io_out_1_rs1),
.io_out_rs2 (io_out_1_rs2), .io_out_rs2 (io_out_1_rs2),
.io_out_rd (io_out_1_rd), .io_out_rd (io_out_1_rd),
.io_out_funct3 (io_out_1_funct3), .io_out_funct3 (io_out_1_funct3),
.io_out_immI (io_out_1_immI), .io_out_immI (io_out_1_immI),
.io_out_immS (io_out_1_immS), .io_out_immS (io_out_1_immS),
.io_out_immB (io_out_1_immB), .io_out_immB (io_out_1_immB),
.io_out_immU (io_out_1_immU), .io_out_immU (io_out_1_immU),
.io_out_immJ (io_out_1_immJ), .io_out_immJ (io_out_1_immJ),
.io_out_opClass (io_out_1_opClass), .io_out_opClass (io_out_1_opClass),
.io_out_aluFn (io_out_1_aluFn), .io_out_aluFn (io_out_1_aluFn),
.io_out_memWidth (io_out_1_memWidth), .io_out_memWidth (io_out_1_memWidth),
.io_out_memSigned (io_out_1_memSigned), .io_out_memSigned (io_out_1_memSigned),
.io_out_isLoad (io_out_1_isLoad), .io_out_isLoad (io_out_1_isLoad),
.io_out_isStore (io_out_1_isStore), .io_out_isStore (io_out_1_isStore),
.io_out_isBranch (io_out_1_isBranch), .io_out_isBranch (io_out_1_isBranch),
.io_out_isJal (io_out_1_isJal), .io_out_isJal (io_out_1_isJal),
.io_out_isJalr (io_out_1_isJalr), .io_out_isJalr (io_out_1_isJalr),
.io_out_isLui (io_out_1_isLui), .io_out_isLui (io_out_1_isLui),
.io_out_isAuipc (io_out_1_isAuipc), .io_out_isAuipc (io_out_1_isAuipc),
.io_out_isOpImm (io_out_1_isOpImm), .io_out_isOpImm (io_out_1_isOpImm),
.io_out_isWord (io_out_1_isWord), .io_out_isWord (io_out_1_isWord),
.io_out_isSystem (io_out_1_isSystem), .io_out_isSystem (io_out_1_isSystem),
.io_out_isFenceI (io_out_1_isFenceI), .io_out_isFenceI (io_out_1_isFenceI),
.io_out_isAmo (io_out_1_isAmo), .io_out_isEcall (io_out_1_isEcall),
.io_out_amoOp (io_out_1_amoOp), .io_out_isEbreak (io_out_1_isEbreak),
.io_out_writesRd (io_out_1_writesRd), .io_out_isMret (io_out_1_isMret),
.io_out_illegal (io_out_1_illegal) .io_out_isSret (io_out_1_isSret),
.io_out_isSfenceVma (io_out_1_isSfenceVma),
.io_out_isXret (io_out_1_isXret),
.io_out_isWfi (io_out_1_isWfi),
.io_out_isAmo (io_out_1_isAmo),
.io_out_amoOp (io_out_1_amoOp),
.io_out_writesRd (io_out_1_writesRd),
.io_out_illegal (io_out_1_illegal)
); );
assign io_outValid_0 = io_inValid & io_in_laneValid_0; assign io_outValid_0 = io_inValid & io_in_laneValid_0;
assign io_outValid_1 = io_inValid & io_in_laneValid_1; assign io_outValid_1 = io_inValid & io_in_laneValid_1;
assign io_out_0_fetchException = io_in_exception;
assign io_out_0_fetchExceptionCause = io_in_exceptionCause;
assign io_out_0_fetchExceptionTval = io_in_exceptionTval;
assign io_out_1_fetchException = io_in_exception;
assign io_out_1_fetchExceptionCause = io_in_exceptionCause;
assign io_out_1_fetchExceptionTval = io_in_exceptionTval;
endmodule endmodule

1319
generated-ooo/ITLB.sv Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -28,10 +28,20 @@ module IssueQueue(
io_enq_0_decoded_isWord, io_enq_0_decoded_isWord,
io_enq_0_decoded_isSystem, io_enq_0_decoded_isSystem,
io_enq_0_decoded_isFenceI, io_enq_0_decoded_isFenceI,
io_enq_0_decoded_isEcall,
io_enq_0_decoded_isEbreak,
io_enq_0_decoded_isMret,
io_enq_0_decoded_isSret,
io_enq_0_decoded_isSfenceVma,
io_enq_0_decoded_isXret,
io_enq_0_decoded_isWfi,
io_enq_0_decoded_isAmo, io_enq_0_decoded_isAmo,
input [4:0] io_enq_0_decoded_amoOp, input [4:0] io_enq_0_decoded_amoOp,
input io_enq_0_decoded_writesRd, input io_enq_0_decoded_writesRd,
io_enq_0_decoded_illegal, io_enq_0_decoded_illegal,
io_enq_0_decoded_fetchException,
input [63:0] io_enq_0_decoded_fetchExceptionCause,
io_enq_0_decoded_fetchExceptionTval,
input [5:0] io_enq_0_prs1, input [5:0] io_enq_0_prs1,
io_enq_0_prs2, io_enq_0_prs2,
input io_enq_0_src1Ready, input io_enq_0_src1Ready,
@@ -62,10 +72,20 @@ module IssueQueue(
io_enq_1_decoded_isWord, io_enq_1_decoded_isWord,
io_enq_1_decoded_isSystem, io_enq_1_decoded_isSystem,
io_enq_1_decoded_isFenceI, io_enq_1_decoded_isFenceI,
io_enq_1_decoded_isEcall,
io_enq_1_decoded_isEbreak,
io_enq_1_decoded_isMret,
io_enq_1_decoded_isSret,
io_enq_1_decoded_isSfenceVma,
io_enq_1_decoded_isXret,
io_enq_1_decoded_isWfi,
io_enq_1_decoded_isAmo, io_enq_1_decoded_isAmo,
input [4:0] io_enq_1_decoded_amoOp, input [4:0] io_enq_1_decoded_amoOp,
input io_enq_1_decoded_writesRd, input io_enq_1_decoded_writesRd,
io_enq_1_decoded_illegal, io_enq_1_decoded_illegal,
io_enq_1_decoded_fetchException,
input [63:0] io_enq_1_decoded_fetchExceptionCause,
io_enq_1_decoded_fetchExceptionTval,
input [5:0] io_enq_1_prs1, input [5:0] io_enq_1_prs1,
io_enq_1_prs2, io_enq_1_prs2,
input io_enq_1_src1Ready, input io_enq_1_src1Ready,
@@ -103,10 +123,20 @@ module IssueQueue(
io_issue_0_decoded_isWord, io_issue_0_decoded_isWord,
io_issue_0_decoded_isSystem, io_issue_0_decoded_isSystem,
io_issue_0_decoded_isFenceI, io_issue_0_decoded_isFenceI,
io_issue_0_decoded_isEcall,
io_issue_0_decoded_isEbreak,
io_issue_0_decoded_isMret,
io_issue_0_decoded_isSret,
io_issue_0_decoded_isSfenceVma,
io_issue_0_decoded_isXret,
io_issue_0_decoded_isWfi,
io_issue_0_decoded_isAmo, io_issue_0_decoded_isAmo,
output [4:0] io_issue_0_decoded_amoOp, output [4:0] io_issue_0_decoded_amoOp,
output io_issue_0_decoded_writesRd, output io_issue_0_decoded_writesRd,
io_issue_0_decoded_illegal, io_issue_0_decoded_illegal,
io_issue_0_decoded_fetchException,
output [63:0] io_issue_0_decoded_fetchExceptionCause,
io_issue_0_decoded_fetchExceptionTval,
output [5:0] io_issue_0_prs1, output [5:0] io_issue_0_prs1,
io_issue_0_prs2, io_issue_0_prs2,
io_issue_0_prd, io_issue_0_prd,
@@ -134,165 +164,219 @@ module IssueQueue(
io_issue_1_decoded_isWord, io_issue_1_decoded_isWord,
io_issue_1_decoded_isSystem, io_issue_1_decoded_isSystem,
io_issue_1_decoded_isFenceI, io_issue_1_decoded_isFenceI,
io_issue_1_decoded_isEcall,
io_issue_1_decoded_isEbreak,
io_issue_1_decoded_isMret,
io_issue_1_decoded_isSret,
io_issue_1_decoded_isSfenceVma,
io_issue_1_decoded_isXret,
io_issue_1_decoded_isWfi,
io_issue_1_decoded_isAmo, io_issue_1_decoded_isAmo,
output [4:0] io_issue_1_decoded_amoOp, output [4:0] io_issue_1_decoded_amoOp,
output io_issue_1_decoded_writesRd, output io_issue_1_decoded_writesRd,
io_issue_1_decoded_illegal, io_issue_1_decoded_illegal,
io_issue_1_decoded_fetchException,
output [63:0] io_issue_1_decoded_fetchExceptionCause,
io_issue_1_decoded_fetchExceptionTval,
output [5:0] io_issue_1_prs1, output [5:0] io_issue_1_prs1,
io_issue_1_prs2, io_issue_1_prs2,
io_issue_1_prd, io_issue_1_prd,
io_issue_1_robIdx, io_issue_1_robIdx,
input io_issueReady_0, input io_issueReady_0,
io_issueReady_1, io_issueReady_1,
io_flush io_robHeadValid,
input [5:0] io_robHeadIdx,
input io_flush
); );
ReservationStation intRs ( ReservationStation intRs (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_enqValid_0 (io_enqValid_0), .io_enqValid_0 (io_enqValid_0),
.io_enqValid_1 (io_enqValid_1), .io_enqValid_1 (io_enqValid_1),
.io_enq_0_decoded_pc (io_enq_0_decoded_pc), .io_enq_0_decoded_pc (io_enq_0_decoded_pc),
.io_enq_0_decoded_inst (io_enq_0_decoded_inst), .io_enq_0_decoded_inst (io_enq_0_decoded_inst),
.io_enq_0_decoded_rs1 (io_enq_0_decoded_rs1), .io_enq_0_decoded_rs1 (io_enq_0_decoded_rs1),
.io_enq_0_decoded_rs2 (io_enq_0_decoded_rs2), .io_enq_0_decoded_rs2 (io_enq_0_decoded_rs2),
.io_enq_0_decoded_funct3 (io_enq_0_decoded_funct3), .io_enq_0_decoded_funct3 (io_enq_0_decoded_funct3),
.io_enq_0_decoded_immI (io_enq_0_decoded_immI), .io_enq_0_decoded_immI (io_enq_0_decoded_immI),
.io_enq_0_decoded_immS (io_enq_0_decoded_immS), .io_enq_0_decoded_immS (io_enq_0_decoded_immS),
.io_enq_0_decoded_immB (io_enq_0_decoded_immB), .io_enq_0_decoded_immB (io_enq_0_decoded_immB),
.io_enq_0_decoded_immU (io_enq_0_decoded_immU), .io_enq_0_decoded_immU (io_enq_0_decoded_immU),
.io_enq_0_decoded_immJ (io_enq_0_decoded_immJ), .io_enq_0_decoded_immJ (io_enq_0_decoded_immJ),
.io_enq_0_decoded_aluFn (io_enq_0_decoded_aluFn), .io_enq_0_decoded_aluFn (io_enq_0_decoded_aluFn),
.io_enq_0_decoded_memWidth (io_enq_0_decoded_memWidth), .io_enq_0_decoded_memWidth (io_enq_0_decoded_memWidth),
.io_enq_0_decoded_memSigned (io_enq_0_decoded_memSigned), .io_enq_0_decoded_memSigned (io_enq_0_decoded_memSigned),
.io_enq_0_decoded_isLoad (io_enq_0_decoded_isLoad), .io_enq_0_decoded_isLoad (io_enq_0_decoded_isLoad),
.io_enq_0_decoded_isStore (io_enq_0_decoded_isStore), .io_enq_0_decoded_isStore (io_enq_0_decoded_isStore),
.io_enq_0_decoded_isBranch (io_enq_0_decoded_isBranch), .io_enq_0_decoded_isBranch (io_enq_0_decoded_isBranch),
.io_enq_0_decoded_isJal (io_enq_0_decoded_isJal), .io_enq_0_decoded_isJal (io_enq_0_decoded_isJal),
.io_enq_0_decoded_isJalr (io_enq_0_decoded_isJalr), .io_enq_0_decoded_isJalr (io_enq_0_decoded_isJalr),
.io_enq_0_decoded_isLui (io_enq_0_decoded_isLui), .io_enq_0_decoded_isLui (io_enq_0_decoded_isLui),
.io_enq_0_decoded_isAuipc (io_enq_0_decoded_isAuipc), .io_enq_0_decoded_isAuipc (io_enq_0_decoded_isAuipc),
.io_enq_0_decoded_isOpImm (io_enq_0_decoded_isOpImm), .io_enq_0_decoded_isOpImm (io_enq_0_decoded_isOpImm),
.io_enq_0_decoded_isWord (io_enq_0_decoded_isWord), .io_enq_0_decoded_isWord (io_enq_0_decoded_isWord),
.io_enq_0_decoded_isSystem (io_enq_0_decoded_isSystem), .io_enq_0_decoded_isSystem (io_enq_0_decoded_isSystem),
.io_enq_0_decoded_isFenceI (io_enq_0_decoded_isFenceI), .io_enq_0_decoded_isFenceI (io_enq_0_decoded_isFenceI),
.io_enq_0_decoded_isAmo (io_enq_0_decoded_isAmo), .io_enq_0_decoded_isEcall (io_enq_0_decoded_isEcall),
.io_enq_0_decoded_amoOp (io_enq_0_decoded_amoOp), .io_enq_0_decoded_isEbreak (io_enq_0_decoded_isEbreak),
.io_enq_0_decoded_writesRd (io_enq_0_decoded_writesRd), .io_enq_0_decoded_isMret (io_enq_0_decoded_isMret),
.io_enq_0_decoded_illegal (io_enq_0_decoded_illegal), .io_enq_0_decoded_isSret (io_enq_0_decoded_isSret),
.io_enq_0_prs1 (io_enq_0_prs1), .io_enq_0_decoded_isSfenceVma (io_enq_0_decoded_isSfenceVma),
.io_enq_0_prs2 (io_enq_0_prs2), .io_enq_0_decoded_isXret (io_enq_0_decoded_isXret),
.io_enq_0_src1Ready (io_enq_0_src1Ready), .io_enq_0_decoded_isWfi (io_enq_0_decoded_isWfi),
.io_enq_0_src2Ready (io_enq_0_src2Ready), .io_enq_0_decoded_isAmo (io_enq_0_decoded_isAmo),
.io_enq_0_prd (io_enq_0_prd), .io_enq_0_decoded_amoOp (io_enq_0_decoded_amoOp),
.io_enq_0_robIdx (io_enq_0_robIdx), .io_enq_0_decoded_writesRd (io_enq_0_decoded_writesRd),
.io_enq_1_decoded_pc (io_enq_1_decoded_pc), .io_enq_0_decoded_illegal (io_enq_0_decoded_illegal),
.io_enq_1_decoded_inst (io_enq_1_decoded_inst), .io_enq_0_decoded_fetchException (io_enq_0_decoded_fetchException),
.io_enq_1_decoded_rs1 (io_enq_1_decoded_rs1), .io_enq_0_decoded_fetchExceptionCause (io_enq_0_decoded_fetchExceptionCause),
.io_enq_1_decoded_rs2 (io_enq_1_decoded_rs2), .io_enq_0_decoded_fetchExceptionTval (io_enq_0_decoded_fetchExceptionTval),
.io_enq_1_decoded_funct3 (io_enq_1_decoded_funct3), .io_enq_0_prs1 (io_enq_0_prs1),
.io_enq_1_decoded_immI (io_enq_1_decoded_immI), .io_enq_0_prs2 (io_enq_0_prs2),
.io_enq_1_decoded_immS (io_enq_1_decoded_immS), .io_enq_0_src1Ready (io_enq_0_src1Ready),
.io_enq_1_decoded_immB (io_enq_1_decoded_immB), .io_enq_0_src2Ready (io_enq_0_src2Ready),
.io_enq_1_decoded_immU (io_enq_1_decoded_immU), .io_enq_0_prd (io_enq_0_prd),
.io_enq_1_decoded_immJ (io_enq_1_decoded_immJ), .io_enq_0_robIdx (io_enq_0_robIdx),
.io_enq_1_decoded_aluFn (io_enq_1_decoded_aluFn), .io_enq_1_decoded_pc (io_enq_1_decoded_pc),
.io_enq_1_decoded_memWidth (io_enq_1_decoded_memWidth), .io_enq_1_decoded_inst (io_enq_1_decoded_inst),
.io_enq_1_decoded_memSigned (io_enq_1_decoded_memSigned), .io_enq_1_decoded_rs1 (io_enq_1_decoded_rs1),
.io_enq_1_decoded_isLoad (io_enq_1_decoded_isLoad), .io_enq_1_decoded_rs2 (io_enq_1_decoded_rs2),
.io_enq_1_decoded_isStore (io_enq_1_decoded_isStore), .io_enq_1_decoded_funct3 (io_enq_1_decoded_funct3),
.io_enq_1_decoded_isBranch (io_enq_1_decoded_isBranch), .io_enq_1_decoded_immI (io_enq_1_decoded_immI),
.io_enq_1_decoded_isJal (io_enq_1_decoded_isJal), .io_enq_1_decoded_immS (io_enq_1_decoded_immS),
.io_enq_1_decoded_isJalr (io_enq_1_decoded_isJalr), .io_enq_1_decoded_immB (io_enq_1_decoded_immB),
.io_enq_1_decoded_isLui (io_enq_1_decoded_isLui), .io_enq_1_decoded_immU (io_enq_1_decoded_immU),
.io_enq_1_decoded_isAuipc (io_enq_1_decoded_isAuipc), .io_enq_1_decoded_immJ (io_enq_1_decoded_immJ),
.io_enq_1_decoded_isOpImm (io_enq_1_decoded_isOpImm), .io_enq_1_decoded_aluFn (io_enq_1_decoded_aluFn),
.io_enq_1_decoded_isWord (io_enq_1_decoded_isWord), .io_enq_1_decoded_memWidth (io_enq_1_decoded_memWidth),
.io_enq_1_decoded_isSystem (io_enq_1_decoded_isSystem), .io_enq_1_decoded_memSigned (io_enq_1_decoded_memSigned),
.io_enq_1_decoded_isFenceI (io_enq_1_decoded_isFenceI), .io_enq_1_decoded_isLoad (io_enq_1_decoded_isLoad),
.io_enq_1_decoded_isAmo (io_enq_1_decoded_isAmo), .io_enq_1_decoded_isStore (io_enq_1_decoded_isStore),
.io_enq_1_decoded_amoOp (io_enq_1_decoded_amoOp), .io_enq_1_decoded_isBranch (io_enq_1_decoded_isBranch),
.io_enq_1_decoded_writesRd (io_enq_1_decoded_writesRd), .io_enq_1_decoded_isJal (io_enq_1_decoded_isJal),
.io_enq_1_decoded_illegal (io_enq_1_decoded_illegal), .io_enq_1_decoded_isJalr (io_enq_1_decoded_isJalr),
.io_enq_1_prs1 (io_enq_1_prs1), .io_enq_1_decoded_isLui (io_enq_1_decoded_isLui),
.io_enq_1_prs2 (io_enq_1_prs2), .io_enq_1_decoded_isAuipc (io_enq_1_decoded_isAuipc),
.io_enq_1_src1Ready (io_enq_1_src1Ready), .io_enq_1_decoded_isOpImm (io_enq_1_decoded_isOpImm),
.io_enq_1_src2Ready (io_enq_1_src2Ready), .io_enq_1_decoded_isWord (io_enq_1_decoded_isWord),
.io_enq_1_prd (io_enq_1_prd), .io_enq_1_decoded_isSystem (io_enq_1_decoded_isSystem),
.io_enq_1_robIdx (io_enq_1_robIdx), .io_enq_1_decoded_isFenceI (io_enq_1_decoded_isFenceI),
.io_enqReady_0 (io_enqReady_0), .io_enq_1_decoded_isEcall (io_enq_1_decoded_isEcall),
.io_enqReady_1 (io_enqReady_1), .io_enq_1_decoded_isEbreak (io_enq_1_decoded_isEbreak),
.io_wakeup_0_valid (io_wakeup_0_valid), .io_enq_1_decoded_isMret (io_enq_1_decoded_isMret),
.io_wakeup_0_phys (io_wakeup_0_phys), .io_enq_1_decoded_isSret (io_enq_1_decoded_isSret),
.io_wakeup_1_valid (io_wakeup_1_valid), .io_enq_1_decoded_isSfenceVma (io_enq_1_decoded_isSfenceVma),
.io_wakeup_1_phys (io_wakeup_1_phys), .io_enq_1_decoded_isXret (io_enq_1_decoded_isXret),
.io_issueValid_0 (io_issueValid_0), .io_enq_1_decoded_isWfi (io_enq_1_decoded_isWfi),
.io_issueValid_1 (io_issueValid_1), .io_enq_1_decoded_isAmo (io_enq_1_decoded_isAmo),
.io_issue_0_decoded_pc (io_issue_0_decoded_pc), .io_enq_1_decoded_amoOp (io_enq_1_decoded_amoOp),
.io_issue_0_decoded_inst (io_issue_0_decoded_inst), .io_enq_1_decoded_writesRd (io_enq_1_decoded_writesRd),
.io_issue_0_decoded_rs1 (io_issue_0_decoded_rs1), .io_enq_1_decoded_illegal (io_enq_1_decoded_illegal),
.io_issue_0_decoded_funct3 (io_issue_0_decoded_funct3), .io_enq_1_decoded_fetchException (io_enq_1_decoded_fetchException),
.io_issue_0_decoded_immI (io_issue_0_decoded_immI), .io_enq_1_decoded_fetchExceptionCause (io_enq_1_decoded_fetchExceptionCause),
.io_issue_0_decoded_immS (io_issue_0_decoded_immS), .io_enq_1_decoded_fetchExceptionTval (io_enq_1_decoded_fetchExceptionTval),
.io_issue_0_decoded_immB (io_issue_0_decoded_immB), .io_enq_1_prs1 (io_enq_1_prs1),
.io_issue_0_decoded_immU (io_issue_0_decoded_immU), .io_enq_1_prs2 (io_enq_1_prs2),
.io_issue_0_decoded_immJ (io_issue_0_decoded_immJ), .io_enq_1_src1Ready (io_enq_1_src1Ready),
.io_issue_0_decoded_aluFn (io_issue_0_decoded_aluFn), .io_enq_1_src2Ready (io_enq_1_src2Ready),
.io_issue_0_decoded_memWidth (io_issue_0_decoded_memWidth), .io_enq_1_prd (io_enq_1_prd),
.io_issue_0_decoded_memSigned (io_issue_0_decoded_memSigned), .io_enq_1_robIdx (io_enq_1_robIdx),
.io_issue_0_decoded_isLoad (io_issue_0_decoded_isLoad), .io_enqReady_0 (io_enqReady_0),
.io_issue_0_decoded_isStore (io_issue_0_decoded_isStore), .io_enqReady_1 (io_enqReady_1),
.io_issue_0_decoded_isBranch (io_issue_0_decoded_isBranch), .io_wakeup_0_valid (io_wakeup_0_valid),
.io_issue_0_decoded_isJal (io_issue_0_decoded_isJal), .io_wakeup_0_phys (io_wakeup_0_phys),
.io_issue_0_decoded_isJalr (io_issue_0_decoded_isJalr), .io_wakeup_1_valid (io_wakeup_1_valid),
.io_issue_0_decoded_isLui (io_issue_0_decoded_isLui), .io_wakeup_1_phys (io_wakeup_1_phys),
.io_issue_0_decoded_isAuipc (io_issue_0_decoded_isAuipc), .io_issueValid_0 (io_issueValid_0),
.io_issue_0_decoded_isOpImm (io_issue_0_decoded_isOpImm), .io_issueValid_1 (io_issueValid_1),
.io_issue_0_decoded_isWord (io_issue_0_decoded_isWord), .io_issue_0_decoded_pc (io_issue_0_decoded_pc),
.io_issue_0_decoded_isSystem (io_issue_0_decoded_isSystem), .io_issue_0_decoded_inst (io_issue_0_decoded_inst),
.io_issue_0_decoded_isFenceI (io_issue_0_decoded_isFenceI), .io_issue_0_decoded_rs1 (io_issue_0_decoded_rs1),
.io_issue_0_decoded_isAmo (io_issue_0_decoded_isAmo), .io_issue_0_decoded_funct3 (io_issue_0_decoded_funct3),
.io_issue_0_decoded_amoOp (io_issue_0_decoded_amoOp), .io_issue_0_decoded_immI (io_issue_0_decoded_immI),
.io_issue_0_decoded_writesRd (io_issue_0_decoded_writesRd), .io_issue_0_decoded_immS (io_issue_0_decoded_immS),
.io_issue_0_decoded_illegal (io_issue_0_decoded_illegal), .io_issue_0_decoded_immB (io_issue_0_decoded_immB),
.io_issue_0_prs1 (io_issue_0_prs1), .io_issue_0_decoded_immU (io_issue_0_decoded_immU),
.io_issue_0_prs2 (io_issue_0_prs2), .io_issue_0_decoded_immJ (io_issue_0_decoded_immJ),
.io_issue_0_prd (io_issue_0_prd), .io_issue_0_decoded_aluFn (io_issue_0_decoded_aluFn),
.io_issue_0_robIdx (io_issue_0_robIdx), .io_issue_0_decoded_memWidth (io_issue_0_decoded_memWidth),
.io_issue_1_decoded_pc (io_issue_1_decoded_pc), .io_issue_0_decoded_memSigned (io_issue_0_decoded_memSigned),
.io_issue_1_decoded_inst (io_issue_1_decoded_inst), .io_issue_0_decoded_isLoad (io_issue_0_decoded_isLoad),
.io_issue_1_decoded_rs1 (io_issue_1_decoded_rs1), .io_issue_0_decoded_isStore (io_issue_0_decoded_isStore),
.io_issue_1_decoded_funct3 (io_issue_1_decoded_funct3), .io_issue_0_decoded_isBranch (io_issue_0_decoded_isBranch),
.io_issue_1_decoded_immI (io_issue_1_decoded_immI), .io_issue_0_decoded_isJal (io_issue_0_decoded_isJal),
.io_issue_1_decoded_immS (io_issue_1_decoded_immS), .io_issue_0_decoded_isJalr (io_issue_0_decoded_isJalr),
.io_issue_1_decoded_immB (io_issue_1_decoded_immB), .io_issue_0_decoded_isLui (io_issue_0_decoded_isLui),
.io_issue_1_decoded_immU (io_issue_1_decoded_immU), .io_issue_0_decoded_isAuipc (io_issue_0_decoded_isAuipc),
.io_issue_1_decoded_immJ (io_issue_1_decoded_immJ), .io_issue_0_decoded_isOpImm (io_issue_0_decoded_isOpImm),
.io_issue_1_decoded_aluFn (io_issue_1_decoded_aluFn), .io_issue_0_decoded_isWord (io_issue_0_decoded_isWord),
.io_issue_1_decoded_memWidth (io_issue_1_decoded_memWidth), .io_issue_0_decoded_isSystem (io_issue_0_decoded_isSystem),
.io_issue_1_decoded_memSigned (io_issue_1_decoded_memSigned), .io_issue_0_decoded_isFenceI (io_issue_0_decoded_isFenceI),
.io_issue_1_decoded_isLoad (io_issue_1_decoded_isLoad), .io_issue_0_decoded_isEcall (io_issue_0_decoded_isEcall),
.io_issue_1_decoded_isStore (io_issue_1_decoded_isStore), .io_issue_0_decoded_isEbreak (io_issue_0_decoded_isEbreak),
.io_issue_1_decoded_isBranch (io_issue_1_decoded_isBranch), .io_issue_0_decoded_isMret (io_issue_0_decoded_isMret),
.io_issue_1_decoded_isJal (io_issue_1_decoded_isJal), .io_issue_0_decoded_isSret (io_issue_0_decoded_isSret),
.io_issue_1_decoded_isJalr (io_issue_1_decoded_isJalr), .io_issue_0_decoded_isSfenceVma (io_issue_0_decoded_isSfenceVma),
.io_issue_1_decoded_isLui (io_issue_1_decoded_isLui), .io_issue_0_decoded_isXret (io_issue_0_decoded_isXret),
.io_issue_1_decoded_isAuipc (io_issue_1_decoded_isAuipc), .io_issue_0_decoded_isWfi (io_issue_0_decoded_isWfi),
.io_issue_1_decoded_isOpImm (io_issue_1_decoded_isOpImm), .io_issue_0_decoded_isAmo (io_issue_0_decoded_isAmo),
.io_issue_1_decoded_isWord (io_issue_1_decoded_isWord), .io_issue_0_decoded_amoOp (io_issue_0_decoded_amoOp),
.io_issue_1_decoded_isSystem (io_issue_1_decoded_isSystem), .io_issue_0_decoded_writesRd (io_issue_0_decoded_writesRd),
.io_issue_1_decoded_isFenceI (io_issue_1_decoded_isFenceI), .io_issue_0_decoded_illegal (io_issue_0_decoded_illegal),
.io_issue_1_decoded_isAmo (io_issue_1_decoded_isAmo), .io_issue_0_decoded_fetchException (io_issue_0_decoded_fetchException),
.io_issue_1_decoded_amoOp (io_issue_1_decoded_amoOp), .io_issue_0_decoded_fetchExceptionCause (io_issue_0_decoded_fetchExceptionCause),
.io_issue_1_decoded_writesRd (io_issue_1_decoded_writesRd), .io_issue_0_decoded_fetchExceptionTval (io_issue_0_decoded_fetchExceptionTval),
.io_issue_1_decoded_illegal (io_issue_1_decoded_illegal), .io_issue_0_prs1 (io_issue_0_prs1),
.io_issue_1_prs1 (io_issue_1_prs1), .io_issue_0_prs2 (io_issue_0_prs2),
.io_issue_1_prs2 (io_issue_1_prs2), .io_issue_0_prd (io_issue_0_prd),
.io_issue_1_prd (io_issue_1_prd), .io_issue_0_robIdx (io_issue_0_robIdx),
.io_issue_1_robIdx (io_issue_1_robIdx), .io_issue_1_decoded_pc (io_issue_1_decoded_pc),
.io_issueReady_0 (io_issueReady_0), .io_issue_1_decoded_inst (io_issue_1_decoded_inst),
.io_issueReady_1 (io_issueReady_1), .io_issue_1_decoded_rs1 (io_issue_1_decoded_rs1),
.io_flush (io_flush) .io_issue_1_decoded_funct3 (io_issue_1_decoded_funct3),
.io_issue_1_decoded_immI (io_issue_1_decoded_immI),
.io_issue_1_decoded_immS (io_issue_1_decoded_immS),
.io_issue_1_decoded_immB (io_issue_1_decoded_immB),
.io_issue_1_decoded_immU (io_issue_1_decoded_immU),
.io_issue_1_decoded_immJ (io_issue_1_decoded_immJ),
.io_issue_1_decoded_aluFn (io_issue_1_decoded_aluFn),
.io_issue_1_decoded_memWidth (io_issue_1_decoded_memWidth),
.io_issue_1_decoded_memSigned (io_issue_1_decoded_memSigned),
.io_issue_1_decoded_isLoad (io_issue_1_decoded_isLoad),
.io_issue_1_decoded_isStore (io_issue_1_decoded_isStore),
.io_issue_1_decoded_isBranch (io_issue_1_decoded_isBranch),
.io_issue_1_decoded_isJal (io_issue_1_decoded_isJal),
.io_issue_1_decoded_isJalr (io_issue_1_decoded_isJalr),
.io_issue_1_decoded_isLui (io_issue_1_decoded_isLui),
.io_issue_1_decoded_isAuipc (io_issue_1_decoded_isAuipc),
.io_issue_1_decoded_isOpImm (io_issue_1_decoded_isOpImm),
.io_issue_1_decoded_isWord (io_issue_1_decoded_isWord),
.io_issue_1_decoded_isSystem (io_issue_1_decoded_isSystem),
.io_issue_1_decoded_isFenceI (io_issue_1_decoded_isFenceI),
.io_issue_1_decoded_isEcall (io_issue_1_decoded_isEcall),
.io_issue_1_decoded_isEbreak (io_issue_1_decoded_isEbreak),
.io_issue_1_decoded_isMret (io_issue_1_decoded_isMret),
.io_issue_1_decoded_isSret (io_issue_1_decoded_isSret),
.io_issue_1_decoded_isSfenceVma (io_issue_1_decoded_isSfenceVma),
.io_issue_1_decoded_isXret (io_issue_1_decoded_isXret),
.io_issue_1_decoded_isWfi (io_issue_1_decoded_isWfi),
.io_issue_1_decoded_isAmo (io_issue_1_decoded_isAmo),
.io_issue_1_decoded_amoOp (io_issue_1_decoded_amoOp),
.io_issue_1_decoded_writesRd (io_issue_1_decoded_writesRd),
.io_issue_1_decoded_illegal (io_issue_1_decoded_illegal),
.io_issue_1_decoded_fetchException (io_issue_1_decoded_fetchException),
.io_issue_1_decoded_fetchExceptionCause (io_issue_1_decoded_fetchExceptionCause),
.io_issue_1_decoded_fetchExceptionTval (io_issue_1_decoded_fetchExceptionTval),
.io_issue_1_prs1 (io_issue_1_prs1),
.io_issue_1_prs2 (io_issue_1_prs2),
.io_issue_1_prd (io_issue_1_prd),
.io_issue_1_robIdx (io_issue_1_robIdx),
.io_issueReady_0 (io_issueReady_0),
.io_issueReady_1 (io_issueReady_1),
.io_robHeadValid (io_robHeadValid),
.io_robHeadIdx (io_robHeadIdx),
.io_flush (io_flush)
); );
endmodule endmodule

View File

@@ -28,10 +28,20 @@ module IssueStage(
io_in_0_decoded_isWord, io_in_0_decoded_isWord,
io_in_0_decoded_isSystem, io_in_0_decoded_isSystem,
io_in_0_decoded_isFenceI, io_in_0_decoded_isFenceI,
io_in_0_decoded_isEcall,
io_in_0_decoded_isEbreak,
io_in_0_decoded_isMret,
io_in_0_decoded_isSret,
io_in_0_decoded_isSfenceVma,
io_in_0_decoded_isXret,
io_in_0_decoded_isWfi,
io_in_0_decoded_isAmo, io_in_0_decoded_isAmo,
input [4:0] io_in_0_decoded_amoOp, input [4:0] io_in_0_decoded_amoOp,
input io_in_0_decoded_writesRd, input io_in_0_decoded_writesRd,
io_in_0_decoded_illegal, io_in_0_decoded_illegal,
io_in_0_decoded_fetchException,
input [63:0] io_in_0_decoded_fetchExceptionCause,
io_in_0_decoded_fetchExceptionTval,
input [5:0] io_in_0_prs1, input [5:0] io_in_0_prs1,
io_in_0_prs2, io_in_0_prs2,
input io_in_0_src1Ready, input io_in_0_src1Ready,
@@ -62,10 +72,20 @@ module IssueStage(
io_in_1_decoded_isWord, io_in_1_decoded_isWord,
io_in_1_decoded_isSystem, io_in_1_decoded_isSystem,
io_in_1_decoded_isFenceI, io_in_1_decoded_isFenceI,
io_in_1_decoded_isEcall,
io_in_1_decoded_isEbreak,
io_in_1_decoded_isMret,
io_in_1_decoded_isSret,
io_in_1_decoded_isSfenceVma,
io_in_1_decoded_isXret,
io_in_1_decoded_isWfi,
io_in_1_decoded_isAmo, io_in_1_decoded_isAmo,
input [4:0] io_in_1_decoded_amoOp, input [4:0] io_in_1_decoded_amoOp,
input io_in_1_decoded_writesRd, input io_in_1_decoded_writesRd,
io_in_1_decoded_illegal, io_in_1_decoded_illegal,
io_in_1_decoded_fetchException,
input [63:0] io_in_1_decoded_fetchExceptionCause,
io_in_1_decoded_fetchExceptionTval,
input [5:0] io_in_1_prs1, input [5:0] io_in_1_prs1,
io_in_1_prs2, io_in_1_prs2,
input io_in_1_src1Ready, input io_in_1_src1Ready,
@@ -103,10 +123,20 @@ module IssueStage(
io_out_0_decoded_isWord, io_out_0_decoded_isWord,
io_out_0_decoded_isSystem, io_out_0_decoded_isSystem,
io_out_0_decoded_isFenceI, io_out_0_decoded_isFenceI,
io_out_0_decoded_isEcall,
io_out_0_decoded_isEbreak,
io_out_0_decoded_isMret,
io_out_0_decoded_isSret,
io_out_0_decoded_isSfenceVma,
io_out_0_decoded_isXret,
io_out_0_decoded_isWfi,
io_out_0_decoded_isAmo, io_out_0_decoded_isAmo,
output [4:0] io_out_0_decoded_amoOp, output [4:0] io_out_0_decoded_amoOp,
output io_out_0_decoded_writesRd, output io_out_0_decoded_writesRd,
io_out_0_decoded_illegal, io_out_0_decoded_illegal,
io_out_0_decoded_fetchException,
output [63:0] io_out_0_decoded_fetchExceptionCause,
io_out_0_decoded_fetchExceptionTval,
output [5:0] io_out_0_prs1, output [5:0] io_out_0_prs1,
io_out_0_prs2, io_out_0_prs2,
io_out_0_prd, io_out_0_prd,
@@ -134,165 +164,219 @@ module IssueStage(
io_out_1_decoded_isWord, io_out_1_decoded_isWord,
io_out_1_decoded_isSystem, io_out_1_decoded_isSystem,
io_out_1_decoded_isFenceI, io_out_1_decoded_isFenceI,
io_out_1_decoded_isEcall,
io_out_1_decoded_isEbreak,
io_out_1_decoded_isMret,
io_out_1_decoded_isSret,
io_out_1_decoded_isSfenceVma,
io_out_1_decoded_isXret,
io_out_1_decoded_isWfi,
io_out_1_decoded_isAmo, io_out_1_decoded_isAmo,
output [4:0] io_out_1_decoded_amoOp, output [4:0] io_out_1_decoded_amoOp,
output io_out_1_decoded_writesRd, output io_out_1_decoded_writesRd,
io_out_1_decoded_illegal, io_out_1_decoded_illegal,
io_out_1_decoded_fetchException,
output [63:0] io_out_1_decoded_fetchExceptionCause,
io_out_1_decoded_fetchExceptionTval,
output [5:0] io_out_1_prs1, output [5:0] io_out_1_prs1,
io_out_1_prs2, io_out_1_prs2,
io_out_1_prd, io_out_1_prd,
io_out_1_robIdx, io_out_1_robIdx,
input io_outReady_0, input io_outReady_0,
io_outReady_1, io_outReady_1,
io_flush io_robHeadValid,
input [5:0] io_robHeadIdx,
input io_flush
); );
IssueQueue queue ( IssueQueue queue (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_enqValid_0 (io_inValid_0), .io_enqValid_0 (io_inValid_0),
.io_enqValid_1 (io_inValid_1), .io_enqValid_1 (io_inValid_1),
.io_enq_0_decoded_pc (io_in_0_decoded_pc), .io_enq_0_decoded_pc (io_in_0_decoded_pc),
.io_enq_0_decoded_inst (io_in_0_decoded_inst), .io_enq_0_decoded_inst (io_in_0_decoded_inst),
.io_enq_0_decoded_rs1 (io_in_0_decoded_rs1), .io_enq_0_decoded_rs1 (io_in_0_decoded_rs1),
.io_enq_0_decoded_rs2 (io_in_0_decoded_rs2), .io_enq_0_decoded_rs2 (io_in_0_decoded_rs2),
.io_enq_0_decoded_funct3 (io_in_0_decoded_funct3), .io_enq_0_decoded_funct3 (io_in_0_decoded_funct3),
.io_enq_0_decoded_immI (io_in_0_decoded_immI), .io_enq_0_decoded_immI (io_in_0_decoded_immI),
.io_enq_0_decoded_immS (io_in_0_decoded_immS), .io_enq_0_decoded_immS (io_in_0_decoded_immS),
.io_enq_0_decoded_immB (io_in_0_decoded_immB), .io_enq_0_decoded_immB (io_in_0_decoded_immB),
.io_enq_0_decoded_immU (io_in_0_decoded_immU), .io_enq_0_decoded_immU (io_in_0_decoded_immU),
.io_enq_0_decoded_immJ (io_in_0_decoded_immJ), .io_enq_0_decoded_immJ (io_in_0_decoded_immJ),
.io_enq_0_decoded_aluFn (io_in_0_decoded_aluFn), .io_enq_0_decoded_aluFn (io_in_0_decoded_aluFn),
.io_enq_0_decoded_memWidth (io_in_0_decoded_memWidth), .io_enq_0_decoded_memWidth (io_in_0_decoded_memWidth),
.io_enq_0_decoded_memSigned (io_in_0_decoded_memSigned), .io_enq_0_decoded_memSigned (io_in_0_decoded_memSigned),
.io_enq_0_decoded_isLoad (io_in_0_decoded_isLoad), .io_enq_0_decoded_isLoad (io_in_0_decoded_isLoad),
.io_enq_0_decoded_isStore (io_in_0_decoded_isStore), .io_enq_0_decoded_isStore (io_in_0_decoded_isStore),
.io_enq_0_decoded_isBranch (io_in_0_decoded_isBranch), .io_enq_0_decoded_isBranch (io_in_0_decoded_isBranch),
.io_enq_0_decoded_isJal (io_in_0_decoded_isJal), .io_enq_0_decoded_isJal (io_in_0_decoded_isJal),
.io_enq_0_decoded_isJalr (io_in_0_decoded_isJalr), .io_enq_0_decoded_isJalr (io_in_0_decoded_isJalr),
.io_enq_0_decoded_isLui (io_in_0_decoded_isLui), .io_enq_0_decoded_isLui (io_in_0_decoded_isLui),
.io_enq_0_decoded_isAuipc (io_in_0_decoded_isAuipc), .io_enq_0_decoded_isAuipc (io_in_0_decoded_isAuipc),
.io_enq_0_decoded_isOpImm (io_in_0_decoded_isOpImm), .io_enq_0_decoded_isOpImm (io_in_0_decoded_isOpImm),
.io_enq_0_decoded_isWord (io_in_0_decoded_isWord), .io_enq_0_decoded_isWord (io_in_0_decoded_isWord),
.io_enq_0_decoded_isSystem (io_in_0_decoded_isSystem), .io_enq_0_decoded_isSystem (io_in_0_decoded_isSystem),
.io_enq_0_decoded_isFenceI (io_in_0_decoded_isFenceI), .io_enq_0_decoded_isFenceI (io_in_0_decoded_isFenceI),
.io_enq_0_decoded_isAmo (io_in_0_decoded_isAmo), .io_enq_0_decoded_isEcall (io_in_0_decoded_isEcall),
.io_enq_0_decoded_amoOp (io_in_0_decoded_amoOp), .io_enq_0_decoded_isEbreak (io_in_0_decoded_isEbreak),
.io_enq_0_decoded_writesRd (io_in_0_decoded_writesRd), .io_enq_0_decoded_isMret (io_in_0_decoded_isMret),
.io_enq_0_decoded_illegal (io_in_0_decoded_illegal), .io_enq_0_decoded_isSret (io_in_0_decoded_isSret),
.io_enq_0_prs1 (io_in_0_prs1), .io_enq_0_decoded_isSfenceVma (io_in_0_decoded_isSfenceVma),
.io_enq_0_prs2 (io_in_0_prs2), .io_enq_0_decoded_isXret (io_in_0_decoded_isXret),
.io_enq_0_src1Ready (io_in_0_src1Ready), .io_enq_0_decoded_isWfi (io_in_0_decoded_isWfi),
.io_enq_0_src2Ready (io_in_0_src2Ready), .io_enq_0_decoded_isAmo (io_in_0_decoded_isAmo),
.io_enq_0_prd (io_in_0_prd), .io_enq_0_decoded_amoOp (io_in_0_decoded_amoOp),
.io_enq_0_robIdx (io_in_0_robIdx), .io_enq_0_decoded_writesRd (io_in_0_decoded_writesRd),
.io_enq_1_decoded_pc (io_in_1_decoded_pc), .io_enq_0_decoded_illegal (io_in_0_decoded_illegal),
.io_enq_1_decoded_inst (io_in_1_decoded_inst), .io_enq_0_decoded_fetchException (io_in_0_decoded_fetchException),
.io_enq_1_decoded_rs1 (io_in_1_decoded_rs1), .io_enq_0_decoded_fetchExceptionCause (io_in_0_decoded_fetchExceptionCause),
.io_enq_1_decoded_rs2 (io_in_1_decoded_rs2), .io_enq_0_decoded_fetchExceptionTval (io_in_0_decoded_fetchExceptionTval),
.io_enq_1_decoded_funct3 (io_in_1_decoded_funct3), .io_enq_0_prs1 (io_in_0_prs1),
.io_enq_1_decoded_immI (io_in_1_decoded_immI), .io_enq_0_prs2 (io_in_0_prs2),
.io_enq_1_decoded_immS (io_in_1_decoded_immS), .io_enq_0_src1Ready (io_in_0_src1Ready),
.io_enq_1_decoded_immB (io_in_1_decoded_immB), .io_enq_0_src2Ready (io_in_0_src2Ready),
.io_enq_1_decoded_immU (io_in_1_decoded_immU), .io_enq_0_prd (io_in_0_prd),
.io_enq_1_decoded_immJ (io_in_1_decoded_immJ), .io_enq_0_robIdx (io_in_0_robIdx),
.io_enq_1_decoded_aluFn (io_in_1_decoded_aluFn), .io_enq_1_decoded_pc (io_in_1_decoded_pc),
.io_enq_1_decoded_memWidth (io_in_1_decoded_memWidth), .io_enq_1_decoded_inst (io_in_1_decoded_inst),
.io_enq_1_decoded_memSigned (io_in_1_decoded_memSigned), .io_enq_1_decoded_rs1 (io_in_1_decoded_rs1),
.io_enq_1_decoded_isLoad (io_in_1_decoded_isLoad), .io_enq_1_decoded_rs2 (io_in_1_decoded_rs2),
.io_enq_1_decoded_isStore (io_in_1_decoded_isStore), .io_enq_1_decoded_funct3 (io_in_1_decoded_funct3),
.io_enq_1_decoded_isBranch (io_in_1_decoded_isBranch), .io_enq_1_decoded_immI (io_in_1_decoded_immI),
.io_enq_1_decoded_isJal (io_in_1_decoded_isJal), .io_enq_1_decoded_immS (io_in_1_decoded_immS),
.io_enq_1_decoded_isJalr (io_in_1_decoded_isJalr), .io_enq_1_decoded_immB (io_in_1_decoded_immB),
.io_enq_1_decoded_isLui (io_in_1_decoded_isLui), .io_enq_1_decoded_immU (io_in_1_decoded_immU),
.io_enq_1_decoded_isAuipc (io_in_1_decoded_isAuipc), .io_enq_1_decoded_immJ (io_in_1_decoded_immJ),
.io_enq_1_decoded_isOpImm (io_in_1_decoded_isOpImm), .io_enq_1_decoded_aluFn (io_in_1_decoded_aluFn),
.io_enq_1_decoded_isWord (io_in_1_decoded_isWord), .io_enq_1_decoded_memWidth (io_in_1_decoded_memWidth),
.io_enq_1_decoded_isSystem (io_in_1_decoded_isSystem), .io_enq_1_decoded_memSigned (io_in_1_decoded_memSigned),
.io_enq_1_decoded_isFenceI (io_in_1_decoded_isFenceI), .io_enq_1_decoded_isLoad (io_in_1_decoded_isLoad),
.io_enq_1_decoded_isAmo (io_in_1_decoded_isAmo), .io_enq_1_decoded_isStore (io_in_1_decoded_isStore),
.io_enq_1_decoded_amoOp (io_in_1_decoded_amoOp), .io_enq_1_decoded_isBranch (io_in_1_decoded_isBranch),
.io_enq_1_decoded_writesRd (io_in_1_decoded_writesRd), .io_enq_1_decoded_isJal (io_in_1_decoded_isJal),
.io_enq_1_decoded_illegal (io_in_1_decoded_illegal), .io_enq_1_decoded_isJalr (io_in_1_decoded_isJalr),
.io_enq_1_prs1 (io_in_1_prs1), .io_enq_1_decoded_isLui (io_in_1_decoded_isLui),
.io_enq_1_prs2 (io_in_1_prs2), .io_enq_1_decoded_isAuipc (io_in_1_decoded_isAuipc),
.io_enq_1_src1Ready (io_in_1_src1Ready), .io_enq_1_decoded_isOpImm (io_in_1_decoded_isOpImm),
.io_enq_1_src2Ready (io_in_1_src2Ready), .io_enq_1_decoded_isWord (io_in_1_decoded_isWord),
.io_enq_1_prd (io_in_1_prd), .io_enq_1_decoded_isSystem (io_in_1_decoded_isSystem),
.io_enq_1_robIdx (io_in_1_robIdx), .io_enq_1_decoded_isFenceI (io_in_1_decoded_isFenceI),
.io_enqReady_0 (io_inReady_0), .io_enq_1_decoded_isEcall (io_in_1_decoded_isEcall),
.io_enqReady_1 (io_inReady_1), .io_enq_1_decoded_isEbreak (io_in_1_decoded_isEbreak),
.io_wakeup_0_valid (io_wakeup_0_valid), .io_enq_1_decoded_isMret (io_in_1_decoded_isMret),
.io_wakeup_0_phys (io_wakeup_0_phys), .io_enq_1_decoded_isSret (io_in_1_decoded_isSret),
.io_wakeup_1_valid (io_wakeup_1_valid), .io_enq_1_decoded_isSfenceVma (io_in_1_decoded_isSfenceVma),
.io_wakeup_1_phys (io_wakeup_1_phys), .io_enq_1_decoded_isXret (io_in_1_decoded_isXret),
.io_issueValid_0 (io_outValid_0), .io_enq_1_decoded_isWfi (io_in_1_decoded_isWfi),
.io_issueValid_1 (io_outValid_1), .io_enq_1_decoded_isAmo (io_in_1_decoded_isAmo),
.io_issue_0_decoded_pc (io_out_0_decoded_pc), .io_enq_1_decoded_amoOp (io_in_1_decoded_amoOp),
.io_issue_0_decoded_inst (io_out_0_decoded_inst), .io_enq_1_decoded_writesRd (io_in_1_decoded_writesRd),
.io_issue_0_decoded_rs1 (io_out_0_decoded_rs1), .io_enq_1_decoded_illegal (io_in_1_decoded_illegal),
.io_issue_0_decoded_funct3 (io_out_0_decoded_funct3), .io_enq_1_decoded_fetchException (io_in_1_decoded_fetchException),
.io_issue_0_decoded_immI (io_out_0_decoded_immI), .io_enq_1_decoded_fetchExceptionCause (io_in_1_decoded_fetchExceptionCause),
.io_issue_0_decoded_immS (io_out_0_decoded_immS), .io_enq_1_decoded_fetchExceptionTval (io_in_1_decoded_fetchExceptionTval),
.io_issue_0_decoded_immB (io_out_0_decoded_immB), .io_enq_1_prs1 (io_in_1_prs1),
.io_issue_0_decoded_immU (io_out_0_decoded_immU), .io_enq_1_prs2 (io_in_1_prs2),
.io_issue_0_decoded_immJ (io_out_0_decoded_immJ), .io_enq_1_src1Ready (io_in_1_src1Ready),
.io_issue_0_decoded_aluFn (io_out_0_decoded_aluFn), .io_enq_1_src2Ready (io_in_1_src2Ready),
.io_issue_0_decoded_memWidth (io_out_0_decoded_memWidth), .io_enq_1_prd (io_in_1_prd),
.io_issue_0_decoded_memSigned (io_out_0_decoded_memSigned), .io_enq_1_robIdx (io_in_1_robIdx),
.io_issue_0_decoded_isLoad (io_out_0_decoded_isLoad), .io_enqReady_0 (io_inReady_0),
.io_issue_0_decoded_isStore (io_out_0_decoded_isStore), .io_enqReady_1 (io_inReady_1),
.io_issue_0_decoded_isBranch (io_out_0_decoded_isBranch), .io_wakeup_0_valid (io_wakeup_0_valid),
.io_issue_0_decoded_isJal (io_out_0_decoded_isJal), .io_wakeup_0_phys (io_wakeup_0_phys),
.io_issue_0_decoded_isJalr (io_out_0_decoded_isJalr), .io_wakeup_1_valid (io_wakeup_1_valid),
.io_issue_0_decoded_isLui (io_out_0_decoded_isLui), .io_wakeup_1_phys (io_wakeup_1_phys),
.io_issue_0_decoded_isAuipc (io_out_0_decoded_isAuipc), .io_issueValid_0 (io_outValid_0),
.io_issue_0_decoded_isOpImm (io_out_0_decoded_isOpImm), .io_issueValid_1 (io_outValid_1),
.io_issue_0_decoded_isWord (io_out_0_decoded_isWord), .io_issue_0_decoded_pc (io_out_0_decoded_pc),
.io_issue_0_decoded_isSystem (io_out_0_decoded_isSystem), .io_issue_0_decoded_inst (io_out_0_decoded_inst),
.io_issue_0_decoded_isFenceI (io_out_0_decoded_isFenceI), .io_issue_0_decoded_rs1 (io_out_0_decoded_rs1),
.io_issue_0_decoded_isAmo (io_out_0_decoded_isAmo), .io_issue_0_decoded_funct3 (io_out_0_decoded_funct3),
.io_issue_0_decoded_amoOp (io_out_0_decoded_amoOp), .io_issue_0_decoded_immI (io_out_0_decoded_immI),
.io_issue_0_decoded_writesRd (io_out_0_decoded_writesRd), .io_issue_0_decoded_immS (io_out_0_decoded_immS),
.io_issue_0_decoded_illegal (io_out_0_decoded_illegal), .io_issue_0_decoded_immB (io_out_0_decoded_immB),
.io_issue_0_prs1 (io_out_0_prs1), .io_issue_0_decoded_immU (io_out_0_decoded_immU),
.io_issue_0_prs2 (io_out_0_prs2), .io_issue_0_decoded_immJ (io_out_0_decoded_immJ),
.io_issue_0_prd (io_out_0_prd), .io_issue_0_decoded_aluFn (io_out_0_decoded_aluFn),
.io_issue_0_robIdx (io_out_0_robIdx), .io_issue_0_decoded_memWidth (io_out_0_decoded_memWidth),
.io_issue_1_decoded_pc (io_out_1_decoded_pc), .io_issue_0_decoded_memSigned (io_out_0_decoded_memSigned),
.io_issue_1_decoded_inst (io_out_1_decoded_inst), .io_issue_0_decoded_isLoad (io_out_0_decoded_isLoad),
.io_issue_1_decoded_rs1 (io_out_1_decoded_rs1), .io_issue_0_decoded_isStore (io_out_0_decoded_isStore),
.io_issue_1_decoded_funct3 (io_out_1_decoded_funct3), .io_issue_0_decoded_isBranch (io_out_0_decoded_isBranch),
.io_issue_1_decoded_immI (io_out_1_decoded_immI), .io_issue_0_decoded_isJal (io_out_0_decoded_isJal),
.io_issue_1_decoded_immS (io_out_1_decoded_immS), .io_issue_0_decoded_isJalr (io_out_0_decoded_isJalr),
.io_issue_1_decoded_immB (io_out_1_decoded_immB), .io_issue_0_decoded_isLui (io_out_0_decoded_isLui),
.io_issue_1_decoded_immU (io_out_1_decoded_immU), .io_issue_0_decoded_isAuipc (io_out_0_decoded_isAuipc),
.io_issue_1_decoded_immJ (io_out_1_decoded_immJ), .io_issue_0_decoded_isOpImm (io_out_0_decoded_isOpImm),
.io_issue_1_decoded_aluFn (io_out_1_decoded_aluFn), .io_issue_0_decoded_isWord (io_out_0_decoded_isWord),
.io_issue_1_decoded_memWidth (io_out_1_decoded_memWidth), .io_issue_0_decoded_isSystem (io_out_0_decoded_isSystem),
.io_issue_1_decoded_memSigned (io_out_1_decoded_memSigned), .io_issue_0_decoded_isFenceI (io_out_0_decoded_isFenceI),
.io_issue_1_decoded_isLoad (io_out_1_decoded_isLoad), .io_issue_0_decoded_isEcall (io_out_0_decoded_isEcall),
.io_issue_1_decoded_isStore (io_out_1_decoded_isStore), .io_issue_0_decoded_isEbreak (io_out_0_decoded_isEbreak),
.io_issue_1_decoded_isBranch (io_out_1_decoded_isBranch), .io_issue_0_decoded_isMret (io_out_0_decoded_isMret),
.io_issue_1_decoded_isJal (io_out_1_decoded_isJal), .io_issue_0_decoded_isSret (io_out_0_decoded_isSret),
.io_issue_1_decoded_isJalr (io_out_1_decoded_isJalr), .io_issue_0_decoded_isSfenceVma (io_out_0_decoded_isSfenceVma),
.io_issue_1_decoded_isLui (io_out_1_decoded_isLui), .io_issue_0_decoded_isXret (io_out_0_decoded_isXret),
.io_issue_1_decoded_isAuipc (io_out_1_decoded_isAuipc), .io_issue_0_decoded_isWfi (io_out_0_decoded_isWfi),
.io_issue_1_decoded_isOpImm (io_out_1_decoded_isOpImm), .io_issue_0_decoded_isAmo (io_out_0_decoded_isAmo),
.io_issue_1_decoded_isWord (io_out_1_decoded_isWord), .io_issue_0_decoded_amoOp (io_out_0_decoded_amoOp),
.io_issue_1_decoded_isSystem (io_out_1_decoded_isSystem), .io_issue_0_decoded_writesRd (io_out_0_decoded_writesRd),
.io_issue_1_decoded_isFenceI (io_out_1_decoded_isFenceI), .io_issue_0_decoded_illegal (io_out_0_decoded_illegal),
.io_issue_1_decoded_isAmo (io_out_1_decoded_isAmo), .io_issue_0_decoded_fetchException (io_out_0_decoded_fetchException),
.io_issue_1_decoded_amoOp (io_out_1_decoded_amoOp), .io_issue_0_decoded_fetchExceptionCause (io_out_0_decoded_fetchExceptionCause),
.io_issue_1_decoded_writesRd (io_out_1_decoded_writesRd), .io_issue_0_decoded_fetchExceptionTval (io_out_0_decoded_fetchExceptionTval),
.io_issue_1_decoded_illegal (io_out_1_decoded_illegal), .io_issue_0_prs1 (io_out_0_prs1),
.io_issue_1_prs1 (io_out_1_prs1), .io_issue_0_prs2 (io_out_0_prs2),
.io_issue_1_prs2 (io_out_1_prs2), .io_issue_0_prd (io_out_0_prd),
.io_issue_1_prd (io_out_1_prd), .io_issue_0_robIdx (io_out_0_robIdx),
.io_issue_1_robIdx (io_out_1_robIdx), .io_issue_1_decoded_pc (io_out_1_decoded_pc),
.io_issueReady_0 (io_outReady_0), .io_issue_1_decoded_inst (io_out_1_decoded_inst),
.io_issueReady_1 (io_outReady_1), .io_issue_1_decoded_rs1 (io_out_1_decoded_rs1),
.io_flush (io_flush) .io_issue_1_decoded_funct3 (io_out_1_decoded_funct3),
.io_issue_1_decoded_immI (io_out_1_decoded_immI),
.io_issue_1_decoded_immS (io_out_1_decoded_immS),
.io_issue_1_decoded_immB (io_out_1_decoded_immB),
.io_issue_1_decoded_immU (io_out_1_decoded_immU),
.io_issue_1_decoded_immJ (io_out_1_decoded_immJ),
.io_issue_1_decoded_aluFn (io_out_1_decoded_aluFn),
.io_issue_1_decoded_memWidth (io_out_1_decoded_memWidth),
.io_issue_1_decoded_memSigned (io_out_1_decoded_memSigned),
.io_issue_1_decoded_isLoad (io_out_1_decoded_isLoad),
.io_issue_1_decoded_isStore (io_out_1_decoded_isStore),
.io_issue_1_decoded_isBranch (io_out_1_decoded_isBranch),
.io_issue_1_decoded_isJal (io_out_1_decoded_isJal),
.io_issue_1_decoded_isJalr (io_out_1_decoded_isJalr),
.io_issue_1_decoded_isLui (io_out_1_decoded_isLui),
.io_issue_1_decoded_isAuipc (io_out_1_decoded_isAuipc),
.io_issue_1_decoded_isOpImm (io_out_1_decoded_isOpImm),
.io_issue_1_decoded_isWord (io_out_1_decoded_isWord),
.io_issue_1_decoded_isSystem (io_out_1_decoded_isSystem),
.io_issue_1_decoded_isFenceI (io_out_1_decoded_isFenceI),
.io_issue_1_decoded_isEcall (io_out_1_decoded_isEcall),
.io_issue_1_decoded_isEbreak (io_out_1_decoded_isEbreak),
.io_issue_1_decoded_isMret (io_out_1_decoded_isMret),
.io_issue_1_decoded_isSret (io_out_1_decoded_isSret),
.io_issue_1_decoded_isSfenceVma (io_out_1_decoded_isSfenceVma),
.io_issue_1_decoded_isXret (io_out_1_decoded_isXret),
.io_issue_1_decoded_isWfi (io_out_1_decoded_isWfi),
.io_issue_1_decoded_isAmo (io_out_1_decoded_isAmo),
.io_issue_1_decoded_amoOp (io_out_1_decoded_amoOp),
.io_issue_1_decoded_writesRd (io_out_1_decoded_writesRd),
.io_issue_1_decoded_illegal (io_out_1_decoded_illegal),
.io_issue_1_decoded_fetchException (io_out_1_decoded_fetchException),
.io_issue_1_decoded_fetchExceptionCause (io_out_1_decoded_fetchExceptionCause),
.io_issue_1_decoded_fetchExceptionTval (io_out_1_decoded_fetchExceptionTval),
.io_issue_1_prs1 (io_out_1_prs1),
.io_issue_1_prs2 (io_out_1_prs2),
.io_issue_1_prd (io_out_1_prd),
.io_issue_1_robIdx (io_out_1_robIdx),
.io_issueReady_0 (io_outReady_0),
.io_issueReady_1 (io_outReady_1),
.io_robHeadValid (io_robHeadValid),
.io_robHeadIdx (io_robHeadIdx),
.io_flush (io_flush)
); );
endmodule endmodule

View File

@@ -10,6 +10,10 @@ module LSU(
io_req_isAmo, io_req_isAmo,
input [4:0] io_req_amoOp, input [4:0] io_req_amoOp,
input [2:0] io_req_size, input [2:0] io_req_size,
input io_checkOnly,
io_sfenceVma,
input [1:0] io_currentPriv,
input [63:0] io_mstatus,
output io_reqReady, output io_reqReady,
input [63:0] io_satp, input [63:0] io_satp,
output io_dmemReqValid, output io_dmemReqValid,
@@ -21,7 +25,10 @@ module LSU(
input [63:0] io_dmemRespData, input [63:0] io_dmemRespData,
output io_respValid, output io_respValid,
output [63:0] io_respData, output [63:0] io_respData,
output io_pageFault output io_pageFault,
io_misaligned,
output [63:0] io_faultCause,
io_faultAddr
); );
wire _dcache_io_reqReady; wire _dcache_io_reqReady;
@@ -37,26 +44,96 @@ module LSU(
wire _mmu_io_refill_valid; wire _mmu_io_refill_valid;
wire [26:0] _mmu_io_refill_vpn; wire [26:0] _mmu_io_refill_vpn;
wire [43:0] _mmu_io_refill_ppn; wire [43:0] _mmu_io_refill_ppn;
wire [1:0] _mmu_io_refill_level;
wire [7:0] _mmu_io_refill_flags; wire [7:0] _mmu_io_refill_flags;
wire _dtlb_io_resp_hit; wire _dtlb_io_resp_hit;
wire _dtlb_io_resp_miss; wire _dtlb_io_resp_miss;
wire [63:0] _dtlb_io_resp_paddr; wire [63:0] _dtlb_io_resp_paddr;
wire _dtlb_io_resp_pageFault; wire _dtlb_io_resp_pageFault;
wire [1:0] effectivePriv =
(&io_currentPriv) & io_mstatus[17] ? io_mstatus[12:11] : io_currentPriv;
reg pendingValid;
reg [63:0] pendingReq_addr;
reg [63:0] pendingReq_data;
reg pendingReq_isStore;
reg pendingReq_isSigned;
reg pendingReq_isAmo;
reg [4:0] pendingReq_amoOp;
reg [2:0] pendingReq_size;
reg pendingCheckOnly;
reg [1:0] pendingPriv;
reg [63:0] pendingMstatus;
reg [63:0] pendingSatp;
wire io_reqReady_0 = _dcache_io_reqReady & ~pendingValid;
wire acceptCurrent = io_reqValid & io_reqReady_0;
wire activeValid = pendingValid | acceptCurrent;
wire [2:0] activeReq_size = pendingValid ? pendingReq_size : io_req_size;
wire activeReq_isStore = pendingValid ? pendingReq_isStore : io_req_isStore;
wire [63:0] io_faultAddr_0 = pendingValid ? pendingReq_addr : io_req_addr;
wire activeCheckOnly = pendingValid ? pendingCheckOnly : io_checkOnly;
wire [1:0] activePriv = pendingValid ? pendingPriv : effectivePriv;
wire [1:0] activeMstatus = pendingValid ? pendingMstatus[19:18] : io_mstatus[19:18];
wire [63:0] activeSatp = pendingValid ? pendingSatp : io_satp;
wire translate = (|(activeSatp[63:60])) & activePriv != 2'h3;
wire dtlb_io_req_valid = activeValid & translate;
reg ptwOutstanding; reg ptwOutstanding;
wire ptwReqFire = _mmu_io_ptwMemReq_valid & ~ptwOutstanding;
wire ptwRespFire = io_dmemRespValid & (ptwOutstanding | ptwReqFire);
wire translationReady = ~translate | _dtlb_io_resp_hit;
wire translationFault = _dtlb_io_resp_pageFault | _mmu_io_resp_pageFault; wire translationFault = _dtlb_io_resp_pageFault | _mmu_io_resp_pageFault;
wire misaligned =
activeValid
& (|((activeReq_size == 3'h3
? 3'h0
: activeReq_size == 3'h2
? 3'h4
: activeReq_size == 3'h1 ? 3'h2 : {2'h0, activeReq_size == 3'h0}) - 3'h1
& io_faultAddr_0[2:0]));
wire newFault = activeValid & (translationFault | misaligned);
wire checkOnlyDispatch =
activeValid & activeCheckOnly & translationReady & ~translationFault & ~misaligned;
wire dcacheDispatch =
activeValid & ~activeCheckOnly & translationReady & ~translationFault & ~misaligned
& _dcache_io_reqReady;
wire storeComplete = dcacheDispatch & activeReq_isStore | checkOnlyDispatch;
always @(posedge clock) begin always @(posedge clock) begin
if (reset) automatic logic latchPending;
automatic logic clearPending;
latchPending = acceptCurrent & ~dcacheDispatch & ~newFault;
clearPending = pendingValid & (dcacheDispatch | checkOnlyDispatch | newFault);
if (reset) begin
pendingValid <= 1'h0;
ptwOutstanding <= 1'h0; ptwOutstanding <= 1'h0;
else end
ptwOutstanding <= else begin
_mmu_io_ptwMemReq_valid | ~(io_dmemRespValid & ptwOutstanding) & ptwOutstanding; pendingValid <= ~clearPending & (latchPending | pendingValid);
ptwOutstanding <= ~ptwRespFire & (ptwReqFire | ptwOutstanding);
end
if (clearPending | ~latchPending) begin
end
else begin
pendingReq_addr <= io_req_addr;
pendingReq_data <= io_req_data;
pendingReq_isStore <= io_req_isStore;
pendingReq_isSigned <= io_req_isSigned;
pendingReq_isAmo <= io_req_isAmo;
pendingReq_amoOp <= io_req_amoOp;
pendingReq_size <= io_req_size;
pendingCheckOnly <= io_checkOnly;
pendingPriv <= effectivePriv;
pendingMstatus <= io_mstatus;
pendingSatp <= io_satp;
end
end // always @(posedge) end // always @(posedge)
DTLB dtlb ( DTLB dtlb (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_req_valid (io_reqValid & (|(io_satp[63:60]))), .io_req_valid (dtlb_io_req_valid),
.io_req_vaddr (io_req_addr), .io_req_vaddr (io_faultAddr_0),
.io_req_isStore (io_req_isStore), .io_req_isStore (activeReq_isStore),
.io_req_priv (activePriv),
.io_req_sum (activeMstatus[0]),
.io_req_mxr (activeMstatus[1]),
.io_resp_hit (_dtlb_io_resp_hit), .io_resp_hit (_dtlb_io_resp_hit),
.io_resp_miss (_dtlb_io_resp_miss), .io_resp_miss (_dtlb_io_resp_miss),
.io_resp_paddr (_dtlb_io_resp_paddr), .io_resp_paddr (_dtlb_io_resp_paddr),
@@ -64,56 +141,68 @@ module LSU(
.io_refill_valid (_mmu_io_refill_valid), .io_refill_valid (_mmu_io_refill_valid),
.io_refill_vpn (_mmu_io_refill_vpn), .io_refill_vpn (_mmu_io_refill_vpn),
.io_refill_ppn (_mmu_io_refill_ppn), .io_refill_ppn (_mmu_io_refill_ppn),
.io_refill_flags (_mmu_io_refill_flags) .io_refill_level (_mmu_io_refill_level),
.io_refill_flags (_mmu_io_refill_flags),
.io_flush (io_sfenceVma)
); );
MMU mmu ( MMU mmu (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_satp (io_satp), .io_satp (activeSatp),
.io_req_valid (io_reqValid & (|(io_satp[63:60])) & _dtlb_io_resp_miss), .io_req_valid (dtlb_io_req_valid & _dtlb_io_resp_miss),
.io_req_vaddr (io_req_addr), .io_req_vaddr (io_faultAddr_0),
.io_req_isStore (io_req_isStore), .io_req_isStore (activeReq_isStore),
.io_req_isFetch (1'h0),
.io_req_priv (activePriv),
.io_req_sum (activeMstatus[0]),
.io_req_mxr (activeMstatus[1]),
.io_resp_pageFault (_mmu_io_resp_pageFault), .io_resp_pageFault (_mmu_io_resp_pageFault),
.io_ptwMemReq_valid (_mmu_io_ptwMemReq_valid), .io_ptwMemReq_valid (_mmu_io_ptwMemReq_valid),
.io_ptwMemReq_addr (_mmu_io_ptwMemReq_addr), .io_ptwMemReq_addr (_mmu_io_ptwMemReq_addr),
.io_ptwMemResp_valid (io_dmemRespValid & ptwOutstanding), .io_ptwMemResp_valid (ptwRespFire),
.io_ptwMemResp_data (io_dmemRespData), .io_ptwMemResp_data (io_dmemRespData),
.io_refill_valid (_mmu_io_refill_valid), .io_refill_valid (_mmu_io_refill_valid),
.io_refill_vpn (_mmu_io_refill_vpn), .io_refill_vpn (_mmu_io_refill_vpn),
.io_refill_ppn (_mmu_io_refill_ppn), .io_refill_ppn (_mmu_io_refill_ppn),
.io_refill_level (_mmu_io_refill_level),
.io_refill_flags (_mmu_io_refill_flags) .io_refill_flags (_mmu_io_refill_flags)
); );
DCache dcache ( DCache dcache (
.clock (clock), .clock (clock),
.reset (reset), .reset (reset),
.io_reqValid .io_reqValid (dcacheDispatch),
(io_reqValid & (~(|(io_satp[63:60])) | _dtlb_io_resp_hit) & ~translationFault), .io_req_addr (translate ? _dtlb_io_resp_paddr : io_faultAddr_0),
.io_req_addr ((|(io_satp[63:60])) ? _dtlb_io_resp_paddr : io_req_addr), .io_req_data (pendingValid ? pendingReq_data : io_req_data),
.io_req_data (io_req_data), .io_req_isStore (activeReq_isStore),
.io_req_isStore (io_req_isStore), .io_req_isSigned (pendingValid ? pendingReq_isSigned : io_req_isSigned),
.io_req_isSigned (io_req_isSigned), .io_req_isAmo (pendingValid ? pendingReq_isAmo : io_req_isAmo),
.io_req_isAmo (io_req_isAmo), .io_req_amoOp (pendingValid ? pendingReq_amoOp : io_req_amoOp),
.io_req_amoOp (io_req_amoOp), .io_req_size (activeReq_size),
.io_req_size (io_req_size),
.io_reqReady (_dcache_io_reqReady), .io_reqReady (_dcache_io_reqReady),
.io_memReqValid (_dcache_io_memReqValid), .io_memReqValid (_dcache_io_memReqValid),
.io_memReq_addr (_dcache_io_memReq_addr), .io_memReq_addr (_dcache_io_memReq_addr),
.io_memReq_data (_dcache_io_memReq_data), .io_memReq_data (_dcache_io_memReq_data),
.io_memReq_isStore (_dcache_io_memReq_isStore), .io_memReq_isStore (_dcache_io_memReq_isStore),
.io_memReq_size (_dcache_io_memReq_size), .io_memReq_size (_dcache_io_memReq_size),
.io_memRespValid (io_dmemRespValid & ~ptwOutstanding), .io_memRespValid (io_dmemRespValid & ~ptwOutstanding & ~ptwReqFire),
.io_memRespData (io_dmemRespData), .io_memRespData (io_dmemRespData),
.io_respValid (_dcache_io_respValid), .io_respValid (_dcache_io_respValid),
.io_respData (io_respData) .io_respData (io_respData)
); );
assign io_reqReady = _dcache_io_reqReady & ~ptwOutstanding; assign io_reqReady = io_reqReady_0;
assign io_dmemReqValid = _mmu_io_ptwMemReq_valid | _dcache_io_memReqValid; assign io_dmemReqValid = ptwReqFire | _dcache_io_memReqValid;
assign io_dmemReq_addr = assign io_dmemReq_addr = ptwReqFire ? _mmu_io_ptwMemReq_addr : _dcache_io_memReq_addr;
_mmu_io_ptwMemReq_valid ? _mmu_io_ptwMemReq_addr : _dcache_io_memReq_addr; assign io_dmemReq_data = ptwReqFire ? 64'h0 : _dcache_io_memReq_data;
assign io_dmemReq_data = _mmu_io_ptwMemReq_valid ? 64'h0 : _dcache_io_memReq_data; assign io_dmemReq_isStore = ~ptwReqFire & _dcache_io_memReq_isStore;
assign io_dmemReq_isStore = ~_mmu_io_ptwMemReq_valid & _dcache_io_memReq_isStore; assign io_dmemReq_size = ptwReqFire ? 3'h3 : _dcache_io_memReq_size;
assign io_dmemReq_size = _mmu_io_ptwMemReq_valid ? 3'h3 : _dcache_io_memReq_size; assign io_respValid = _dcache_io_respValid | newFault | storeComplete;
assign io_respValid = _dcache_io_respValid | translationFault;
assign io_pageFault = translationFault; assign io_pageFault = translationFault;
assign io_misaligned = misaligned;
assign io_faultCause =
{56'h0,
misaligned
? {6'h1, activeReq_isStore, 1'h0}
: {4'h0, translationFault, 1'h1, activeReq_isStore, 1'h1}};
assign io_faultAddr = io_faultAddr_0;
endmodule endmodule

View File

@@ -6,6 +6,10 @@ module MMU(
input io_req_valid, input io_req_valid,
input [63:0] io_req_vaddr, input [63:0] io_req_vaddr,
input io_req_isStore, input io_req_isStore,
io_req_isFetch,
input [1:0] io_req_priv,
input io_req_sum,
io_req_mxr,
output io_resp_pageFault, output io_resp_pageFault,
io_ptwMemReq_valid, io_ptwMemReq_valid,
output [63:0] io_ptwMemReq_addr, output [63:0] io_ptwMemReq_addr,
@@ -14,6 +18,7 @@ module MMU(
output io_refill_valid, output io_refill_valid,
output [26:0] io_refill_vpn, output [26:0] io_refill_vpn,
output [43:0] io_refill_ppn, output [43:0] io_refill_ppn,
output [1:0] io_refill_level,
output [7:0] io_refill_flags output [7:0] io_refill_flags
); );
@@ -25,6 +30,10 @@ module MMU(
.io_reqValid (io_req_valid & (|(io_satp[63:60]))), .io_reqValid (io_req_valid & (|(io_satp[63:60]))),
.io_reqVpn (io_req_vaddr[38:12]), .io_reqVpn (io_req_vaddr[38:12]),
.io_isStore (io_req_isStore), .io_isStore (io_req_isStore),
.io_isFetch (io_req_isFetch),
.io_priv (io_req_priv),
.io_sum (io_req_sum),
.io_mxr (io_req_mxr),
.io_satp (io_satp), .io_satp (io_satp),
.io_memReq_valid (io_ptwMemReq_valid), .io_memReq_valid (io_ptwMemReq_valid),
.io_memReq_addr (io_ptwMemReq_addr), .io_memReq_addr (io_ptwMemReq_addr),
@@ -34,6 +43,7 @@ module MMU(
.io_refill_valid (io_refill_valid), .io_refill_valid (io_refill_valid),
.io_refill_vpn (io_refill_vpn), .io_refill_vpn (io_refill_vpn),
.io_refill_ppn (io_refill_ppn), .io_refill_ppn (io_refill_ppn),
.io_refill_level (io_refill_level),
.io_refill_flags (io_refill_flags), .io_refill_flags (io_refill_flags),
.io_pageFault (_walker_io_pageFault) .io_pageFault (_walker_io_pageFault)
); );

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,10 @@ module PageTableWalker(
io_reqValid, io_reqValid,
input [26:0] io_reqVpn, input [26:0] io_reqVpn,
input io_isStore, input io_isStore,
io_isFetch,
input [1:0] io_priv,
input io_sum,
io_mxr,
input [63:0] io_satp, input [63:0] io_satp,
output io_memReq_valid, output io_memReq_valid,
output [63:0] io_memReq_addr, output [63:0] io_memReq_addr,
@@ -14,6 +18,7 @@ module PageTableWalker(
io_refill_valid, io_refill_valid,
output [26:0] io_refill_vpn, output [26:0] io_refill_vpn,
output [43:0] io_refill_ppn, output [43:0] io_refill_ppn,
output [1:0] io_refill_level,
output [7:0] io_refill_flags, output [7:0] io_refill_flags,
output io_pageFault output io_pageFault
); );
@@ -21,20 +26,28 @@ module PageTableWalker(
reg [2:0] state; reg [2:0] state;
reg [26:0] vpnReg; reg [26:0] vpnReg;
reg isStoreReg; reg isStoreReg;
reg walkFault; reg isFetchReg;
reg [43:0] nextPpn; reg [1:0] privReg;
reg sumReg;
reg mxrReg;
wire _io_memReq_addr_T = state == 3'h1; wire _io_memReq_addr_T = state == 3'h1;
wire _io_memReq_addr_T_1 = state == 3'h2; wire _io_memReq_addr_T_1 = state == 3'h2;
reg walkFault;
reg [43:0] nextPpn;
reg [7:0] leafFlagsReg;
reg [1:0] leafLevelReg;
reg [43:0] curPpn; reg [43:0] curPpn;
wire _io_memReq_valid_T_3 = state == 3'h3; wire _io_memReq_valid_T_3 = state == 3'h3;
wire io_respValid_0 = state == 3'h4; wire io_respValid_0 = state == 3'h4;
always @(posedge clock) begin always @(posedge clock) begin
automatic logic pteIsLeaf; automatic logic [1:0] level;
automatic logic invalidPte; automatic logic pteIsLeaf;
automatic logic _GEN; automatic logic invalidPte;
automatic logic _GEN_0; automatic logic _GEN;
automatic logic _GEN_1; automatic logic _GEN_0;
automatic logic _GEN_2; automatic logic _GEN_1;
automatic logic _GEN_2;
level = _io_memReq_addr_T ? 2'h2 : {1'h0, _io_memReq_addr_T_1};
pteIsLeaf = io_memResp_data[1] | io_memResp_data[3]; pteIsLeaf = io_memResp_data[1] | io_memResp_data[3];
invalidPte = ~(io_memResp_data[0]) | ~(io_memResp_data[1]) & io_memResp_data[2]; invalidPte = ~(io_memResp_data[0]) | ~(io_memResp_data[1]) & io_memResp_data[2];
_GEN = state == 3'h0; _GEN = state == 3'h0;
@@ -60,25 +73,36 @@ module PageTableWalker(
& (_GEN_1 & (_GEN_1
? invalidPte ? invalidPte
| (pteIsLeaf | (pteIsLeaf
? (isStoreReg ? privReg == 2'h1 & io_memResp_data[4] & (isFetchReg | ~sumReg)
? ~(io_memResp_data[2]) | ~(io_memResp_data[7]) | privReg == 2'h0 & ~(io_memResp_data[4])
: ~(io_memResp_data[1])) | ~(io_memResp_data[6]) | walkFault | ~(isFetchReg
? io_memResp_data[3]
: isStoreReg
? io_memResp_data[2] & io_memResp_data[7]
: io_memResp_data[1] | mxrReg & io_memResp_data[3])
| ~(io_memResp_data[6]) | level == 2'h2
& (|(io_memResp_data[27:10])) | level == 2'h1
& (|(io_memResp_data[18:10])) | walkFault
: ~_GEN_0 | walkFault) : ~_GEN_0 | walkFault)
: walkFault); : walkFault);
end end
if (_GEN & io_reqValid) begin if (_GEN & io_reqValid) begin
vpnReg <= io_reqVpn; vpnReg <= io_reqVpn;
isStoreReg <= io_isStore; isStoreReg <= io_isStore;
isFetchReg <= io_isFetch;
privReg <= io_priv;
sumReg <= io_sum;
mxrReg <= io_mxr;
end end
if (_GEN | ~_GEN_1 | invalidPte | ~pteIsLeaf) begin if (_GEN | ~_GEN_1 | invalidPte | ~pteIsLeaf) begin
end end
else begin else begin
automatic logic [1:0] level =
_io_memReq_addr_T ? 2'h2 : {1'h0, _io_memReq_addr_T_1};
nextPpn <= nextPpn <=
{io_memResp_data[53:28], {io_memResp_data[53:28],
level[1] ? vpnReg[17:9] : io_memResp_data[27:19], level[1] ? vpnReg[17:9] : io_memResp_data[27:19],
level == 2'h0 ? io_memResp_data[18:10] : vpnReg[8:0]}; level == 2'h0 ? io_memResp_data[18:10] : vpnReg[8:0]};
leafFlagsReg <= io_memResp_data[7:0];
leafLevelReg <= level;
end end
if (_GEN | ~_GEN_1 | _GEN_2) begin if (_GEN | ~_GEN_1 | _GEN_2) begin
end end
@@ -96,7 +120,8 @@ module PageTableWalker(
assign io_refill_valid = io_respValid_0 & ~walkFault; assign io_refill_valid = io_respValid_0 & ~walkFault;
assign io_refill_vpn = vpnReg; assign io_refill_vpn = vpnReg;
assign io_refill_ppn = nextPpn; assign io_refill_ppn = nextPpn;
assign io_refill_flags = io_memResp_data[7:0]; assign io_refill_level = leafLevelReg;
assign io_refill_flags = leafFlagsReg;
assign io_pageFault = walkFault; assign io_pageFault = walkFault;
endmodule endmodule

View File

@@ -0,0 +1,19 @@
// Generated by CIRCT firtool-1.139.0
module PrivilegeControl(
input clock,
reset,
input [1:0] io_nextPriv,
input io_setPriv,
output [1:0] io_priv
);
reg [1:0] privReg;
always @(posedge clock) begin
if (reset)
privReg <= 2'h3;
else if (io_setPriv)
privReg <= io_nextPriv;
end // always @(posedge)
assign io_priv = privReg;
endmodule

File diff suppressed because it is too large Load Diff

View File

@@ -30,11 +30,21 @@ module RenameStage(
io_in_0_isWord, io_in_0_isWord,
io_in_0_isSystem, io_in_0_isSystem,
io_in_0_isFenceI, io_in_0_isFenceI,
io_in_0_isEcall,
io_in_0_isEbreak,
io_in_0_isMret,
io_in_0_isSret,
io_in_0_isSfenceVma,
io_in_0_isXret,
io_in_0_isWfi,
io_in_0_isAmo, io_in_0_isAmo,
input [4:0] io_in_0_amoOp, input [4:0] io_in_0_amoOp,
input io_in_0_writesRd, input io_in_0_writesRd,
io_in_0_illegal, io_in_0_illegal,
input [63:0] io_in_1_pc, io_in_0_fetchException,
input [63:0] io_in_0_fetchExceptionCause,
io_in_0_fetchExceptionTval,
io_in_1_pc,
input [31:0] io_in_1_inst, input [31:0] io_in_1_inst,
input [4:0] io_in_1_rs1, input [4:0] io_in_1_rs1,
io_in_1_rs2, io_in_1_rs2,
@@ -60,10 +70,20 @@ module RenameStage(
io_in_1_isWord, io_in_1_isWord,
io_in_1_isSystem, io_in_1_isSystem,
io_in_1_isFenceI, io_in_1_isFenceI,
io_in_1_isEcall,
io_in_1_isEbreak,
io_in_1_isMret,
io_in_1_isSret,
io_in_1_isSfenceVma,
io_in_1_isXret,
io_in_1_isWfi,
io_in_1_isAmo, io_in_1_isAmo,
input [4:0] io_in_1_amoOp, input [4:0] io_in_1_amoOp,
input io_in_1_writesRd, input io_in_1_writesRd,
io_in_1_illegal, io_in_1_illegal,
io_in_1_fetchException,
input [63:0] io_in_1_fetchExceptionCause,
io_in_1_fetchExceptionTval,
output io_outValid_0, output io_outValid_0,
io_outValid_1, io_outValid_1,
output [63:0] io_out_0_decoded_pc, output [63:0] io_out_0_decoded_pc,
@@ -90,10 +110,20 @@ module RenameStage(
io_out_0_decoded_isWord, io_out_0_decoded_isWord,
io_out_0_decoded_isSystem, io_out_0_decoded_isSystem,
io_out_0_decoded_isFenceI, io_out_0_decoded_isFenceI,
io_out_0_decoded_isEcall,
io_out_0_decoded_isEbreak,
io_out_0_decoded_isMret,
io_out_0_decoded_isSret,
io_out_0_decoded_isSfenceVma,
io_out_0_decoded_isXret,
io_out_0_decoded_isWfi,
io_out_0_decoded_isAmo, io_out_0_decoded_isAmo,
output [4:0] io_out_0_decoded_amoOp, output [4:0] io_out_0_decoded_amoOp,
output io_out_0_decoded_writesRd, output io_out_0_decoded_writesRd,
io_out_0_decoded_illegal, io_out_0_decoded_illegal,
io_out_0_decoded_fetchException,
output [63:0] io_out_0_decoded_fetchExceptionCause,
io_out_0_decoded_fetchExceptionTval,
output [5:0] io_out_0_prs1, output [5:0] io_out_0_prs1,
io_out_0_prs2, io_out_0_prs2,
output io_out_0_src1Ready, output io_out_0_src1Ready,
@@ -124,10 +154,20 @@ module RenameStage(
io_out_1_decoded_isWord, io_out_1_decoded_isWord,
io_out_1_decoded_isSystem, io_out_1_decoded_isSystem,
io_out_1_decoded_isFenceI, io_out_1_decoded_isFenceI,
io_out_1_decoded_isEcall,
io_out_1_decoded_isEbreak,
io_out_1_decoded_isMret,
io_out_1_decoded_isSret,
io_out_1_decoded_isSfenceVma,
io_out_1_decoded_isXret,
io_out_1_decoded_isWfi,
io_out_1_decoded_isAmo, io_out_1_decoded_isAmo,
output [4:0] io_out_1_decoded_amoOp, output [4:0] io_out_1_decoded_amoOp,
output io_out_1_decoded_writesRd, output io_out_1_decoded_writesRd,
io_out_1_decoded_illegal, io_out_1_decoded_illegal,
io_out_1_decoded_fetchException,
output [63:0] io_out_1_decoded_fetchExceptionCause,
io_out_1_decoded_fetchExceptionTval,
output [5:0] io_out_1_prs1, output [5:0] io_out_1_prs1,
io_out_1_prs2, io_out_1_prs2,
output io_out_1_src1Ready, output io_out_1_src1Ready,
@@ -163,11 +203,21 @@ module RenameStage(
io_completeCsrRs1_1, io_completeCsrRs1_1,
input [4:0] io_completeCsrZimm_0, input [4:0] io_completeCsrZimm_0,
io_completeCsrZimm_1, io_completeCsrZimm_1,
input io_commitReady_0, input io_completeFenceI_0,
io_completeFenceI_1,
io_completeSfenceVma_0,
io_completeSfenceVma_1,
io_completeXret_0,
io_completeXret_1,
io_completeXretIsMret_0,
io_completeXretIsMret_1,
io_commitReady_0,
io_commitReady_1, io_commitReady_1,
output io_commitValid_0, output io_commitValid_0,
io_commitValid_1, io_commitValid_1,
io_commitEntry_0_valid,
output [5:0] io_commitEntry_0_robIdx, output [5:0] io_commitEntry_0_robIdx,
output [63:0] io_commitEntry_0_pc,
output [4:0] io_commitEntry_0_archDest, output [4:0] io_commitEntry_0_archDest,
output io_commitEntry_0_writesDest, output io_commitEntry_0_writesDest,
output [3:0] io_commitEntry_0_opClass, output [3:0] io_commitEntry_0_opClass,
@@ -184,7 +234,11 @@ module RenameStage(
output [63:0] io_commitEntry_0_csrRs1, output [63:0] io_commitEntry_0_csrRs1,
output [4:0] io_commitEntry_0_csrZimm, output [4:0] io_commitEntry_0_csrZimm,
output io_commitEntry_0_fenceI, output io_commitEntry_0_fenceI,
io_commitEntry_0_sfenceVma,
io_commitEntry_0_xret,
io_commitEntry_0_xretIsMret,
output [5:0] io_commitEntry_1_robIdx, output [5:0] io_commitEntry_1_robIdx,
output [63:0] io_commitEntry_1_pc,
output [4:0] io_commitEntry_1_archDest, output [4:0] io_commitEntry_1_archDest,
output io_commitEntry_1_writesDest, output io_commitEntry_1_writesDest,
output [3:0] io_commitEntry_1_opClass, output [3:0] io_commitEntry_1_opClass,
@@ -201,6 +255,9 @@ module RenameStage(
output [63:0] io_commitEntry_1_csrRs1, output [63:0] io_commitEntry_1_csrRs1,
output [4:0] io_commitEntry_1_csrZimm, output [4:0] io_commitEntry_1_csrZimm,
output io_commitEntry_1_fenceI, output io_commitEntry_1_fenceI,
io_commitEntry_1_sfenceVma,
io_commitEntry_1_xret,
io_commitEntry_1_xretIsMret,
input io_commitMapValid_0, input io_commitMapValid_0,
io_commitMapValid_1, io_commitMapValid_1,
input [4:0] io_commitArch_0, input [4:0] io_commitArch_0,
@@ -893,18 +950,26 @@ module RenameStage(
.reset (reset), .reset (reset),
.io_allocateValid_0 (e_valid), .io_allocateValid_0 (e_valid),
.io_allocateValid_1 (e_1_valid), .io_allocateValid_1 (e_1_valid),
.io_allocateEntry_0_pc (io_in_0_pc),
.io_allocateEntry_0_archDest (io_in_0_rd), .io_allocateEntry_0_archDest (io_in_0_rd),
.io_allocateEntry_0_writesDest (io_in_0_writesRd), .io_allocateEntry_0_writesDest (io_in_0_writesRd),
.io_allocateEntry_0_opClass (io_in_0_opClass), .io_allocateEntry_0_opClass (io_in_0_opClass),
.io_allocateEntry_0_dest (e_dest), .io_allocateEntry_0_dest (e_dest),
.io_allocateEntry_0_oldDest (_table_io_oldPrd_0), .io_allocateEntry_0_oldDest (_table_io_oldPrd_0),
.io_allocateEntry_0_fenceI (io_in_0_isFenceI), .io_allocateEntry_0_fenceI (io_in_0_isFenceI),
.io_allocateEntry_0_sfenceVma (io_in_0_isSfenceVma),
.io_allocateEntry_0_xret (io_in_0_isXret),
.io_allocateEntry_0_xretIsMret (io_in_0_isMret),
.io_allocateEntry_1_pc (io_in_1_pc),
.io_allocateEntry_1_archDest (io_in_1_rd), .io_allocateEntry_1_archDest (io_in_1_rd),
.io_allocateEntry_1_writesDest (io_in_1_writesRd), .io_allocateEntry_1_writesDest (io_in_1_writesRd),
.io_allocateEntry_1_opClass (io_in_1_opClass), .io_allocateEntry_1_opClass (io_in_1_opClass),
.io_allocateEntry_1_dest (e_1_dest), .io_allocateEntry_1_dest (e_1_dest),
.io_allocateEntry_1_oldDest (_table_io_oldPrd_1), .io_allocateEntry_1_oldDest (_table_io_oldPrd_1),
.io_allocateEntry_1_fenceI (io_in_1_isFenceI), .io_allocateEntry_1_fenceI (io_in_1_isFenceI),
.io_allocateEntry_1_sfenceVma (io_in_1_isSfenceVma),
.io_allocateEntry_1_xret (io_in_1_isXret),
.io_allocateEntry_1_xretIsMret (io_in_1_isMret),
.io_allocateIdx_0 (io_out_0_robIdx), .io_allocateIdx_0 (io_out_0_robIdx),
.io_allocateIdx_1 (io_out_1_robIdx), .io_allocateIdx_1 (io_out_1_robIdx),
.io_canAllocate (_rob_io_canAllocate), .io_canAllocate (_rob_io_canAllocate),
@@ -932,9 +997,19 @@ module RenameStage(
.io_completeCsrRs1_1 (io_completeCsrRs1_1), .io_completeCsrRs1_1 (io_completeCsrRs1_1),
.io_completeCsrZimm_0 (io_completeCsrZimm_0), .io_completeCsrZimm_0 (io_completeCsrZimm_0),
.io_completeCsrZimm_1 (io_completeCsrZimm_1), .io_completeCsrZimm_1 (io_completeCsrZimm_1),
.io_completeFenceI_0 (io_completeFenceI_0),
.io_completeFenceI_1 (io_completeFenceI_1),
.io_completeSfenceVma_0 (io_completeSfenceVma_0),
.io_completeSfenceVma_1 (io_completeSfenceVma_1),
.io_completeXret_0 (io_completeXret_0),
.io_completeXret_1 (io_completeXret_1),
.io_completeXretIsMret_0 (io_completeXretIsMret_0),
.io_completeXretIsMret_1 (io_completeXretIsMret_1),
.io_commitValid_0 (io_commitValid_0), .io_commitValid_0 (io_commitValid_0),
.io_commitValid_1 (io_commitValid_1), .io_commitValid_1 (io_commitValid_1),
.io_commit_0_valid (io_commitEntry_0_valid),
.io_commit_0_robIdx (io_commitEntry_0_robIdx), .io_commit_0_robIdx (io_commitEntry_0_robIdx),
.io_commit_0_pc (io_commitEntry_0_pc),
.io_commit_0_archDest (io_commitEntry_0_archDest), .io_commit_0_archDest (io_commitEntry_0_archDest),
.io_commit_0_writesDest (io_commitEntry_0_writesDest), .io_commit_0_writesDest (io_commitEntry_0_writesDest),
.io_commit_0_opClass (io_commitEntry_0_opClass), .io_commit_0_opClass (io_commitEntry_0_opClass),
@@ -951,7 +1026,11 @@ module RenameStage(
.io_commit_0_csrRs1 (io_commitEntry_0_csrRs1), .io_commit_0_csrRs1 (io_commitEntry_0_csrRs1),
.io_commit_0_csrZimm (io_commitEntry_0_csrZimm), .io_commit_0_csrZimm (io_commitEntry_0_csrZimm),
.io_commit_0_fenceI (io_commitEntry_0_fenceI), .io_commit_0_fenceI (io_commitEntry_0_fenceI),
.io_commit_0_sfenceVma (io_commitEntry_0_sfenceVma),
.io_commit_0_xret (io_commitEntry_0_xret),
.io_commit_0_xretIsMret (io_commitEntry_0_xretIsMret),
.io_commit_1_robIdx (io_commitEntry_1_robIdx), .io_commit_1_robIdx (io_commitEntry_1_robIdx),
.io_commit_1_pc (io_commitEntry_1_pc),
.io_commit_1_archDest (io_commitEntry_1_archDest), .io_commit_1_archDest (io_commitEntry_1_archDest),
.io_commit_1_writesDest (io_commitEntry_1_writesDest), .io_commit_1_writesDest (io_commitEntry_1_writesDest),
.io_commit_1_opClass (io_commitEntry_1_opClass), .io_commit_1_opClass (io_commitEntry_1_opClass),
@@ -968,6 +1047,9 @@ module RenameStage(
.io_commit_1_csrRs1 (io_commitEntry_1_csrRs1), .io_commit_1_csrRs1 (io_commitEntry_1_csrRs1),
.io_commit_1_csrZimm (io_commitEntry_1_csrZimm), .io_commit_1_csrZimm (io_commitEntry_1_csrZimm),
.io_commit_1_fenceI (io_commitEntry_1_fenceI), .io_commit_1_fenceI (io_commitEntry_1_fenceI),
.io_commit_1_sfenceVma (io_commitEntry_1_sfenceVma),
.io_commit_1_xret (io_commitEntry_1_xret),
.io_commit_1_xretIsMret (io_commitEntry_1_xretIsMret),
.io_commitReady_0 (io_commitReady_0), .io_commitReady_0 (io_commitReady_0),
.io_commitReady_1 (io_commitReady_1), .io_commitReady_1 (io_commitReady_1),
.io_flush (io_flush) .io_flush (io_flush)
@@ -998,10 +1080,20 @@ module RenameStage(
assign io_out_0_decoded_isWord = io_in_0_isWord; assign io_out_0_decoded_isWord = io_in_0_isWord;
assign io_out_0_decoded_isSystem = io_in_0_isSystem; assign io_out_0_decoded_isSystem = io_in_0_isSystem;
assign io_out_0_decoded_isFenceI = io_in_0_isFenceI; assign io_out_0_decoded_isFenceI = io_in_0_isFenceI;
assign io_out_0_decoded_isEcall = io_in_0_isEcall;
assign io_out_0_decoded_isEbreak = io_in_0_isEbreak;
assign io_out_0_decoded_isMret = io_in_0_isMret;
assign io_out_0_decoded_isSret = io_in_0_isSret;
assign io_out_0_decoded_isSfenceVma = io_in_0_isSfenceVma;
assign io_out_0_decoded_isXret = io_in_0_isXret;
assign io_out_0_decoded_isWfi = io_in_0_isWfi;
assign io_out_0_decoded_isAmo = io_in_0_isAmo; assign io_out_0_decoded_isAmo = io_in_0_isAmo;
assign io_out_0_decoded_amoOp = io_in_0_amoOp; assign io_out_0_decoded_amoOp = io_in_0_amoOp;
assign io_out_0_decoded_writesRd = io_in_0_writesRd; assign io_out_0_decoded_writesRd = io_in_0_writesRd;
assign io_out_0_decoded_illegal = io_in_0_illegal; assign io_out_0_decoded_illegal = io_in_0_illegal;
assign io_out_0_decoded_fetchException = io_in_0_fetchException;
assign io_out_0_decoded_fetchExceptionCause = io_in_0_fetchExceptionCause;
assign io_out_0_decoded_fetchExceptionTval = io_in_0_fetchExceptionTval;
assign io_out_0_prs1 = _table_io_prs1_0; assign io_out_0_prs1 = _table_io_prs1_0;
assign io_out_0_prs2 = _table_io_prs2_0; assign io_out_0_prs2 = _table_io_prs2_0;
assign io_out_0_src1Ready = assign io_out_0_src1Ready =
@@ -1039,10 +1131,20 @@ module RenameStage(
assign io_out_1_decoded_isWord = io_in_1_isWord; assign io_out_1_decoded_isWord = io_in_1_isWord;
assign io_out_1_decoded_isSystem = io_in_1_isSystem; assign io_out_1_decoded_isSystem = io_in_1_isSystem;
assign io_out_1_decoded_isFenceI = io_in_1_isFenceI; assign io_out_1_decoded_isFenceI = io_in_1_isFenceI;
assign io_out_1_decoded_isEcall = io_in_1_isEcall;
assign io_out_1_decoded_isEbreak = io_in_1_isEbreak;
assign io_out_1_decoded_isMret = io_in_1_isMret;
assign io_out_1_decoded_isSret = io_in_1_isSret;
assign io_out_1_decoded_isSfenceVma = io_in_1_isSfenceVma;
assign io_out_1_decoded_isXret = io_in_1_isXret;
assign io_out_1_decoded_isWfi = io_in_1_isWfi;
assign io_out_1_decoded_isAmo = io_in_1_isAmo; assign io_out_1_decoded_isAmo = io_in_1_isAmo;
assign io_out_1_decoded_amoOp = io_in_1_amoOp; assign io_out_1_decoded_amoOp = io_in_1_amoOp;
assign io_out_1_decoded_writesRd = io_in_1_writesRd; assign io_out_1_decoded_writesRd = io_in_1_writesRd;
assign io_out_1_decoded_illegal = io_in_1_illegal; assign io_out_1_decoded_illegal = io_in_1_illegal;
assign io_out_1_decoded_fetchException = io_in_1_fetchException;
assign io_out_1_decoded_fetchExceptionCause = io_in_1_fetchExceptionCause;
assign io_out_1_decoded_fetchExceptionTval = io_in_1_fetchExceptionTval;
assign io_out_1_prs1 = _table_io_prs1_1; assign io_out_1_prs1 = _table_io_prs1_1;
assign io_out_1_prs2 = _table_io_prs2_1; assign io_out_1_prs2 = _table_io_prs2_1;
assign io_out_1_src1Ready = assign io_out_1_src1Ready =

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,6 @@
ITLB.sv
PageTableWalker.sv
MMU.sv
tags_1024x204.sv tags_1024x204.sv
data_1024x256.sv data_1024x256.sv
ICache.sv ICache.sv
@@ -20,12 +23,12 @@ CommitStage.sv
LoadQueue.sv LoadQueue.sv
StoreQueue.sv StoreQueue.sv
DTLB.sv DTLB.sv
PageTableWalker.sv verification/assert/DCache_Verification_Assert.sv
MMU.sv
tags_64x416.sv tags_64x416.sv
data_64x4096.sv data_64x4096.sv
DCache.sv DCache.sv
LSU.sv LSU.sv
CSRFile.sv CSRFile.sv
OoOBackend.sv OoOBackend.sv
PrivilegeControl.sv
Core.sv Core.sv

View File

@@ -0,0 +1,38 @@
// Generated by CIRCT firtool-1.139.0
// Users can define 'STOP_COND' to add an extra gate to stop conditions.
`ifndef STOP_COND_
`ifdef STOP_COND
`define STOP_COND_ (`STOP_COND)
`else // STOP_COND
`define STOP_COND_ 1
`endif // STOP_COND
`endif // not def STOP_COND_
// Users can define 'ASSERT_VERBOSE_COND' to add an extra gate to assert error printing.
`ifndef ASSERT_VERBOSE_COND_
`ifdef ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ (`ASSERT_VERBOSE_COND)
`else // ASSERT_VERBOSE_COND
`define ASSERT_VERBOSE_COND_ 1
`endif // ASSERT_VERBOSE_COND
`endif // not def ASSERT_VERBOSE_COND_
module DCache_Verification_Assert();
`ifndef SYNTHESIS
always @(posedge DCache.clock) begin
if (~DCache.reset & DCache.io_reqValid
& (|((DCache._storeEndSet_T_6
? 3'h0
: DCache._storeEndSet_T_4
? 3'h4
: DCache._storeEndSet_T_2 ? 3'h2 : {2'h0, DCache._storeEndSet_T})
- 3'h1 & DCache.io_req_addr[2:0]))) begin
if (`ASSERT_VERBOSE_COND_)
$error("Assertion failed: DCache received misaligned request; LSU must trap before DCache\n");
if (`STOP_COND_)
$fatal;
end
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule

View File

@@ -2,4 +2,5 @@
`ifndef layers_Core_Verification_Assert `ifndef layers_Core_Verification_Assert
`define layers_Core_Verification_Assert `define layers_Core_Verification_Assert
`include "layers-Core-Verification.sv" `include "layers-Core-Verification.sv"
`include "layers-OoOBackend-Verification-Assert.sv"
`endif // not def layers_Core_Verification_Assert `endif // not def layers_Core_Verification_Assert

View File

@@ -0,0 +1,6 @@
// Generated by CIRCT firtool-1.139.0
`ifndef layers_DCache_Verification_Assert
`define layers_DCache_Verification_Assert
`include "layers-DCache-Verification.sv"
bind DCache DCache_Verification_Assert verification_assert ();
`endif // not def layers_DCache_Verification_Assert

View File

@@ -0,0 +1,6 @@
// Generated by CIRCT firtool-1.139.0
`ifndef layers_LSU_Verification_Assert
`define layers_LSU_Verification_Assert
`include "layers-LSU-Verification.sv"
`include "layers-DCache-Verification-Assert.sv"
`endif // not def layers_LSU_Verification_Assert

View File

@@ -0,0 +1,6 @@
// Generated by CIRCT firtool-1.139.0
`ifndef layers_OoOBackend_Verification_Assert
`define layers_OoOBackend_Verification_Assert
`include "layers-OoOBackend-Verification.sv"
`include "layers-LSU-Verification-Assert.sv"
`endif // not def layers_OoOBackend_Verification_Assert

View File

@@ -1,4 +1,5 @@
// Generated by CIRCT firtool-1.139.0 // Generated by CIRCT firtool-1.139.0
`ifndef layers_Core_Verification `ifndef layers_Core_Verification
`define layers_Core_Verification `define layers_Core_Verification
`include "layers-OoOBackend-Verification.sv"
`endif // not def layers_Core_Verification `endif // not def layers_Core_Verification

View File

@@ -0,0 +1,4 @@
// Generated by CIRCT firtool-1.139.0
`ifndef layers_DCache_Verification
`define layers_DCache_Verification
`endif // not def layers_DCache_Verification

View File

@@ -0,0 +1,5 @@
// Generated by CIRCT firtool-1.139.0
`ifndef layers_LSU_Verification
`define layers_LSU_Verification
`include "layers-DCache-Verification.sv"
`endif // not def layers_LSU_Verification

View File

@@ -1,6 +1,5 @@
// Generated by CIRCT firtool-1.139.0 // Generated by CIRCT firtool-1.139.0
`ifndef layers_OoOBackend_Verification `ifndef layers_OoOBackend_Verification
`define layers_OoOBackend_Verification `define layers_OoOBackend_Verification
`include "layers-RenameStage-Verification.sv" `include "layers-LSU-Verification.sv"
bind OoOBackend OoOBackend_Verification verification ();
`endif // not def layers_OoOBackend_Verification `endif // not def layers_OoOBackend_Verification

View File

@@ -0,0 +1,93 @@
Running privileged RISC-V tests...
=================================
rv64mi-p-breakpoint: exit=0 PASS
rv64mi-p-csr: exit=0 PASS
rv64mi-p-illegal: exit=0 PASS
rv64mi-p-instret_overflow: exit=1 FAIL
[5] FLUSH exception=0 mtvec=0x0 mepc=0x0 mcause=0x0 frontend_pc=0x80000008
[65] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x0
[66] CSR commit slot0=1 slot1=0 addr=0x744 cmd=5 next=0x800000e8 mtvec=0x800000e8
[71] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000e8
[72] CSR commit slot0=1 slot1=0 addr=0x180 cmd=5 next=0x800000f8 mtvec=0x800000f8
[77] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000f8
[83] CSR commit slot0=1 slot1=0 addr=0x3b0 cmd=1 next=0x0 mtvec=0x8000011c
[86] CSR commit slot0=1 slot1=0 addr=0x3a0 cmd=1 next=0x0 mtvec=0x8000011c
[87] CSR commit slot0=1 slot1=0 addr=0x304 cmd=5 next=0x1f mtvec=0x8000011c
[92] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x8000011c
[93] CSR commit slot0=1 slot1=0 addr=0x302 cmd=5 next=0x80000134 mtvec=0x80000134
[95] CSR commit slot0=1 slot1=0 addr=0x303 cmd=5 next=0x0 mtvec=0x80000134
[101] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000134
[105] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000158
[114] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000170
[120] CSR commit slot0=1 slot1=0 addr=0x300 cmd=5 next=0x0 mtvec=0x80000004
[126] CSR commit slot0=1 slot1=0 addr=0x300 cmd=2 next=0x0 mtvec=0x80000004
[130] CSR commit slot0=1 slot1=0 addr=0x341 cmd=1 next=0x0 mtvec=0x80000004
[133] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001a0 mcause=0x0 frontend_pc=0x800001a8
[141] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000004
[142] FLUSH exception=1 mtvec=0x800001b0 mepc=0x800001a0 mcause=0x0 frontend_pc=0x800001b8
[147] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800001b0
[150] FLUSH exception=1 mtvec=0x80000004 mepc=0x800001ac mcause=0x2 frontend_pc=0x800001c0
[171] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x80000038
[177] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x80000200
[193] FLUSH exception=1 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x800001f0
[205] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001e4 mcause=0xb frontend_pc=0x80000028
[213] STORE addr=0x80001000 data=0x5 size=2
Loaded segment: paddr=0x80000000 size=576
Loaded segment: paddr=0x80001000 size=72
ELF loaded: entry=0x80000000
[213] TEST FAILED: error code 2
rv64mi-p-ld-misaligned: exit=0 PASS
rv64mi-p-lh-misaligned: exit=0 PASS
rv64mi-p-lw-misaligned: exit=0 PASS
rv64mi-p-ma_addr: exit=0 PASS
rv64mi-p-ma_fetch: exit=0 PASS
rv64mi-p-mcsr: exit=1 FAIL
[5] FLUSH exception=0 mtvec=0x0 mepc=0x0 mcause=0x0 frontend_pc=0x80000008
[63] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x0
[65] CSR commit slot0=1 slot1=0 addr=0x744 cmd=5 next=0x0 mtvec=0x800000e4
[69] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000e4
[71] CSR commit slot0=1 slot1=0 addr=0x180 cmd=5 next=0x0 mtvec=0x800000f4
[75] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000f4
[81] CSR commit slot0=1 slot1=0 addr=0x3b0 cmd=1 next=0x0 mtvec=0x80000118
[84] CSR commit slot0=1 slot1=0 addr=0x3a0 cmd=1 next=0x0 mtvec=0x80000118
[86] CSR commit slot0=1 slot1=0 addr=0x304 cmd=5 next=0x0 mtvec=0x80000118
[90] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000118
[92] CSR commit slot0=1 slot1=0 addr=0x302 cmd=5 next=0x0 mtvec=0x80000130
[93] CSR commit slot0=1 slot1=0 addr=0x303 cmd=5 next=0x0 mtvec=0x80000130
[99] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000130
[104] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000150
[111] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000170
[117] CSR commit slot0=1 slot1=0 addr=0x300 cmd=5 next=0x0 mtvec=0x80000004
[121] CSR commit slot0=1 slot1=0 addr=0x300 cmd=2 next=0x0 mtvec=0x80000004
[126] CSR commit slot0=1 slot1=0 addr=0x341 cmd=1 next=0x0 mtvec=0x80000004
[129] FLUSH exception=0 mtvec=0x80000004 mepc=0x8000019c mcause=0x0 frontend_pc=0x800001a0
[149] FLUSH exception=1 mtvec=0x80000004 mepc=0x8000019c mcause=0x0 frontend_pc=0x800001c8
[167] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001c0 mcause=0x2 frontend_pc=0x80000030
[175] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001c0 mcause=0x2 frontend_pc=0x80000038
[185] STORE addr=0x80001000 data=0x53b size=2
Loaded segment: paddr=0x80000000 size=572
Loaded segment: paddr=0x80001000 size=72
ELF loaded: entry=0x80000000
[185] TEST FAILED: error code 669
rv64mi-p-pmpaddr: exit=0 PASS
rv64mi-p-sbreak: exit=0 PASS
rv64mi-p-scall: exit=0 PASS
rv64mi-p-sd-misaligned: exit=0 PASS
rv64mi-p-sh-misaligned: exit=0 PASS
rv64mi-p-sw-misaligned: exit=0 PASS
rv64mi-p-zicntr: exit=0 PASS
rv64si-p-csr: exit=0 PASS
rv64si-p-dirty: exit=124 TIMEOUT
rv64si-p-icache-alias: exit=124 TIMEOUT
rv64si-p-ma_fetch: exit=0 PASS
rv64si-p-sbreak: exit=0 PASS
rv64si-p-scall: exit=0 PASS
rv64si-p-wfi: exit=0 PASS
rv64ui-p-fence_i: exit=0 PASS
=================================
Summary:
PASS: 21
FAIL: 2
TIMEOUT: 2
TOTAL: 25

View File

@@ -0,0 +1,95 @@
Running RISC-V tests...
====================
rv64ui-p-add: PASS
rv64ui-p-addi: PASS
rv64ui-p-addiw: PASS
rv64ui-p-addw: PASS
rv64ui-p-and: PASS
rv64ui-p-andi: PASS
rv64ui-p-auipc: PASS
rv64ui-p-beq: PASS
rv64ui-p-bge: PASS
rv64ui-p-bgeu: PASS
rv64ui-p-blt: PASS
rv64ui-p-bltu: PASS
rv64ui-p-bne: PASS
rv64ui-p-fence_i: PASS
rv64ui-p-jal: PASS
rv64ui-p-jalr: PASS
rv64ui-p-lb: PASS
rv64ui-p-lbu: PASS
rv64ui-p-ld: PASS
rv64ui-p-ld_st: PASS
rv64ui-p-lh: PASS
rv64ui-p-lhu: PASS
rv64ui-p-lui: PASS
rv64ui-p-lw: PASS
rv64ui-p-lwu: PASS
rv64ui-p-ma_data: FAIL
rv64ui-p-or: PASS
rv64ui-p-ori: PASS
rv64ui-p-sb: PASS
rv64ui-p-sd: PASS
rv64ui-p-sh: PASS
rv64ui-p-simple: PASS
rv64ui-p-sll: PASS
rv64ui-p-slli: PASS
rv64ui-p-slliw: PASS
rv64ui-p-sllw: PASS
rv64ui-p-slt: PASS
rv64ui-p-slti: PASS
rv64ui-p-sltiu: PASS
rv64ui-p-sltu: PASS
rv64ui-p-sra: PASS
rv64ui-p-srai: PASS
rv64ui-p-sraiw: PASS
rv64ui-p-sraw: PASS
rv64ui-p-srl: PASS
rv64ui-p-srli: PASS
rv64ui-p-srliw: PASS
rv64ui-p-srlw: PASS
rv64ui-p-st_ld: PASS
rv64ui-p-sub: PASS
rv64ui-p-subw: PASS
rv64ui-p-sw: PASS
rv64ui-p-xor: PASS
rv64ui-p-xori: PASS
rv64um-p-div: PASS
rv64um-p-divu: PASS
rv64um-p-divuw: PASS
rv64um-p-divw: PASS
rv64um-p-mul: PASS
rv64um-p-mulh: PASS
rv64um-p-mulhsu: PASS
rv64um-p-mulhu: PASS
rv64um-p-mulw: PASS
rv64um-p-rem: PASS
rv64um-p-remu: PASS
rv64um-p-remuw: PASS
rv64um-p-remw: PASS
rv64ua-p-amoadd_d: PASS
rv64ua-p-amoadd_w: PASS
rv64ua-p-amoand_d: PASS
rv64ua-p-amoand_w: PASS
rv64ua-p-amomax_d: PASS
rv64ua-p-amomaxu_d: PASS
rv64ua-p-amomaxu_w: PASS
rv64ua-p-amomax_w: PASS
rv64ua-p-amomin_d: PASS
rv64ua-p-amominu_d: PASS
rv64ua-p-amominu_w: PASS
rv64ua-p-amomin_w: PASS
rv64ua-p-amoor_d: PASS
rv64ua-p-amoor_w: PASS
rv64ua-p-amoswap_d: PASS
rv64ua-p-amoswap_w: PASS
rv64ua-p-amoxor_d: PASS
rv64ua-p-amoxor_w: PASS
rv64ua-p-lrsc: PASS
====================
Summary:
PASS: 85
FAIL: 1
TIMEOUT: 0
TOTAL: 86

28
sim/scripts/run_opensbi.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
set -u
TESTBENCH="../verilator/obj_dir/VCore"
OPENSBI_BIN="${OPENSBI_BIN:-../../opensbi/build/platform/generic/firmware/fw_payload.elf}"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-10}"
if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make -C sim/verilator compile' first."
exit 1
fi
if [ ! -f "$OPENSBI_BIN" ]; then
echo "Error: OpenSBI payload not found: $OPENSBI_BIN"
echo "Set OPENSBI_BIN to a firmware ELF path."
exit 2
fi
echo "Running OpenSBI payload: $OPENSBI_BIN"
timeout "${TIMEOUT_SECONDS}s" "$TESTBENCH" "$OPENSBI_BIN"
exitcode=$?
if [ "$exitcode" -eq 124 ]; then
echo "OpenSBI run timed out"
exit 124
fi
exit "$exitcode"

View File

@@ -0,0 +1,75 @@
#!/bin/bash
set -u
TESTBENCH="../verilator/obj_dir/VCore"
TESTS_DIR="../../riscv-tests/isa"
RESULTS_DIR="../results"
RESULTS_FILE="$RESULTS_DIR/privileged_test_results.txt"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-5}"
mkdir -p "$RESULTS_DIR"
if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make -C sim/verilator compile' first."
exit 1
fi
echo "Running privileged RISC-V tests..." > "$RESULTS_FILE"
echo "=================================" >> "$RESULTS_FILE"
PASS=0
FAIL=0
TIMEOUT=0
shopt -s nullglob
tests=(
"$TESTS_DIR"/rv64mi-p-*
"$TESTS_DIR"/rv64si-p-*
"$TESTS_DIR"/rv64ui-p-fence_i
)
for test in "${tests[@]}"; do
[[ "$test" == *.dump ]] && continue
[ ! -f "$test" ] && continue
testname=$(basename "$test")
printf "Running %s... " "$testname"
output=$(timeout "${TIMEOUT_SECONDS}s" "$TESTBENCH" "$test" 2>&1)
exitcode=$?
if [ "$exitcode" -eq 0 ]; then
echo "PASS"
echo "$testname: exit=0 PASS" >> "$RESULTS_FILE"
PASS=$((PASS + 1))
elif [ "$exitcode" -eq 124 ]; then
echo "TIMEOUT"
echo "$testname: exit=124 TIMEOUT" >> "$RESULTS_FILE"
TIMEOUT=$((TIMEOUT + 1))
else
echo "FAIL (exit code $exitcode)"
echo "$testname: exit=$exitcode FAIL" >> "$RESULTS_FILE"
printf '%s\n' "$output" >> "$RESULTS_FILE"
FAIL=$((FAIL + 1))
fi
done
TOTAL=$((PASS + FAIL + TIMEOUT))
{
echo ""
echo "================================="
echo "Summary:"
echo " PASS: $PASS"
echo " FAIL: $FAIL"
echo " TIMEOUT: $TIMEOUT"
echo " TOTAL: $TOTAL"
} >> "$RESULTS_FILE"
echo ""
echo "Summary:"
echo " PASS: $PASS"
echo " FAIL: $FAIL"
echo " TIMEOUT: $TIMEOUT"
echo " TOTAL: $TOTAL"
echo ""
echo "Results saved to $RESULTS_FILE"

View File

@@ -2,7 +2,7 @@
TESTBENCH="../verilator/obj_dir/VCore" TESTBENCH="../verilator/obj_dir/VCore"
TESTS_DIR="../../riscv-tests/isa" TESTS_DIR="../../riscv-tests/isa"
RESULTS_FILE="test_results.txt" RESULTS_FILE="../results/test_results.txt"
if [ ! -x "$TESTBENCH" ]; then if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make compile' first." echo "Error: Testbench not found. Run 'make compile' first."

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Set medeleg bit 8 and execute ecall from U-mode.
// 2. Expect delegation to S-mode handler when S support is enabled.
// 3. Clear delegation and verify ecall from U-mode traps to M-mode.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Toggle MSI, MTI, and MEI pending sources.
// 2. Verify enable bits gate interrupt injection.
// 3. Verify MEI > MTI > MSI priority and S-mode delegation bits.

View File

@@ -0,0 +1,5 @@
// Verilator scenario checklist:
// 1. Start in M-mode after reset.
// 2. Configure mstatus.MPP=S and mepc to an S-mode entry point.
// 3. Execute mret and verify the redirected PC equals mepc.
// 4. Execute an S-mode ecall path and verify trap state is recoverable.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. sfence.vma in U-mode raises illegal instruction.
// 2. sfence.vma in S/M-mode flushes DTLB state.
// 3. fence.i invalidates ICache and flushes younger instructions.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Execute mret and sret with younger instructions in flight.
// 2. Verify commit emits flush and redirect.
// 3. Verify younger side effects are squashed.

View File

@@ -0,0 +1,3 @@
// Verilator scenario checklist:
// 1. Instruction fetch with pc[1:0] != 0 raises instruction address misaligned.
// 2. Load/store addresses not aligned to access size raise load/store address misaligned.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Unmapped instruction fetch raises instruction page fault.
// 2. Unmapped load/store raises load/store page fault.
// 3. U/S permission violations raise page fault instead of access fault.

View File

@@ -20,7 +20,7 @@ endif
SBT = env SBT_OPTS="-Dsbt.boot.directory=/tmp/sbt-boot -Dsbt.ivy.home=/tmp/sbt-ivy" COURSIER_CACHE=/tmp/coursier-cache sbt SBT = env SBT_OPTS="-Dsbt.boot.directory=/tmp/sbt-boot -Dsbt.ivy.home=/tmp/sbt-ivy" COURSIER_CACHE=/tmp/coursier-cache sbt
CHISEL_DIR = ../.. CHISEL_DIR = ../..
OOO ?= 0 OOO ?= 1
ifeq ($(OOO),1) ifeq ($(OOO),1)
RUN_MAIN = CoreOoO RUN_MAIN = CoreOoO
GENERATED_DIR = $(CHISEL_DIR)/generated-ooo GENERATED_DIR = $(CHISEL_DIR)/generated-ooo

View File

@@ -206,7 +206,8 @@ int main(int argc, char** argv) {
core->rootp->Core__DOT__frontend__DOT__icache__DOT__missAddr, core->rootp->Core__DOT__frontend__DOT__icache__DOT__missAddr,
(unsigned)core->rootp->Core__DOT__fetchValid, (unsigned)core->rootp->Core__DOT__fetchValid,
(unsigned)core->rootp->Core__DOT__fetchReady, (unsigned)core->rootp->Core__DOT__fetchReady,
(unsigned)core->rootp->Core__DOT___frontend_io_outValid, (unsigned)(core->rootp->Core__DOT__frontend__DOT__faultPending |
core->rootp->Core__DOT__frontend__DOT___icache_io_respValid),
(unsigned)core->rootp->Core__DOT__backend__DOT___issue_io_inReady_0, (unsigned)core->rootp->Core__DOT__backend__DOT___issue_io_inReady_0,
(unsigned)core->rootp->Core__DOT__backend__DOT__rename__DOT__rob__DOT__count, (unsigned)core->rootp->Core__DOT__backend__DOT__rename__DOT__rob__DOT__count,
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__freeMask, (unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__freeMask,
@@ -255,18 +256,16 @@ int main(int argc, char** argv) {
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue0OH, (unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue0OH,
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue1OH); (unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue1OH);
fprintf(stderr, fprintf(stderr,
"complete: valid=%u/%u idx0=%u exc=%u/%u mis=%u/%u cause=0x%lx/0x%lx redirect=0x%lx/0x%lx\n", "complete: valid=%u/%u idx0=%u exc=%u/%u cause=0x%lx/0x%lx redirect=0x%lx/0x%lx\n",
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeValid_0, (unsigned)core->rootp->Core__DOT__backend__DOT__completeValid_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeValid_1, (unsigned)core->rootp->Core__DOT__backend__DOT__completeValid_1,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeIdx_0, (unsigned)core->rootp->Core__DOT__backend__DOT__completeIdx_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeException_0, (unsigned)core->rootp->Core__DOT__backend__DOT__completeException_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeException_1, (unsigned)core->rootp->Core__DOT__backend__DOT__completeException_1,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeMispredict_0, (uint64_t)core->rootp->Core__DOT__backend__DOT__completeCause_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeMispredict_1, (uint64_t)core->rootp->Core__DOT__backend__DOT__completeCause_1,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeCause_0, (uint64_t)core->rootp->Core__DOT__backend__DOT__completeRedirectPc_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeCause_1, (uint64_t)core->rootp->Core__DOT__backend__DOT__completeRedirectPc_1);
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeRedirectPc_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeRedirectPc_1);
exit_code = 2; exit_code = 2;
} }

View File

@@ -23,14 +23,22 @@ class Core(p: CoreParams = CoreParams()) extends Module {
val frontend = Module(new Frontend(p)) val frontend = Module(new Frontend(p))
val id = Module(new IDStage(p)) val id = Module(new IDStage(p))
val backend = Module(new OoOBackend(p)) val backend = Module(new OoOBackend(p))
val privCtrl = Module(new PrivilegeControl(p))
privCtrl.io.setPriv := backend.io.setPriv
privCtrl.io.nextPriv := backend.io.targetPriv
frontend.io.redirectValid := backend.io.flush frontend.io.redirectValid := backend.io.flush
frontend.io.redirectPc := backend.io.redirectPc frontend.io.redirectPc := backend.io.redirectPc
frontend.io.invalidateICache := backend.io.invalidateICache frontend.io.invalidateICache := backend.io.invalidateICache
frontend.io.sfenceVma := backend.io.sfenceVma
frontend.io.satp := backend.io.satpOut
frontend.io.currentPriv := privCtrl.io.priv
frontend.io.imemRespValid := io.imem_resp_valid frontend.io.imemRespValid := io.imem_resp_valid
frontend.io.imemRespBits(0) := io.imem_resp_bits_0 frontend.io.imemRespBits(0) := io.imem_resp_bits_0
frontend.io.imemRespBits(1) := io.imem_resp_bits_1 frontend.io.imemRespBits(1) := io.imem_resp_bits_1
frontend.io.branchUpdate := 0.U.asTypeOf(new BranchUpdate(p)) frontend.io.branchUpdate := 0.U.asTypeOf(new BranchUpdate(p))
dontTouch(frontend.io.outValid)
val fetchValid = RegInit(false.B) val fetchValid = RegInit(false.B)
val fetchReg = Reg(new FetchPacket(p)) val fetchReg = Reg(new FetchPacket(p))
@@ -48,17 +56,41 @@ class Core(p: CoreParams = CoreParams()) extends Module {
backend.io.decodeValid := id.io.outValid backend.io.decodeValid := id.io.outValid
backend.io.decode := id.io.out backend.io.decode := id.io.out
backend.io.dmemRespValid := io.dmem_resp_valid val frontendPtwOutstanding = RegInit(false.B)
val backendReadOutstanding = RegInit(false.B)
val frontendPtwCanIssue = frontend.io.ptwMemReqValid && !frontendPtwOutstanding &&
!backendReadOutstanding && !backend.io.dmemReqValid
val backendCanIssue = !frontendPtwOutstanding
val backendReadIssue = backend.io.dmemReqValid && backendCanIssue && !backend.io.dmemReq.isStore && !backendReadOutstanding
val frontendPtwRespValid = io.dmem_resp_valid && (frontendPtwOutstanding || frontendPtwCanIssue)
val backendRespValid = io.dmem_resp_valid && !frontendPtwOutstanding && !frontendPtwCanIssue
when(frontendPtwRespValid) {
frontendPtwOutstanding := false.B
}.elsewhen(frontendPtwCanIssue) {
frontendPtwOutstanding := true.B
}
when(backendRespValid && (backendReadOutstanding || backendReadIssue)) {
backendReadOutstanding := false.B
}.elsewhen(backendReadIssue && !backendRespValid) {
backendReadOutstanding := true.B
}
backend.io.dmemRespValid := backendRespValid
backend.io.dmemRespData := io.dmem_resp_bits backend.io.dmemRespData := io.dmem_resp_bits
backend.io.satp := 0.U backend.io.satp := 0.U
backend.io.currentPriv := privCtrl.io.priv
frontend.io.ptwMemRespValid := frontendPtwRespValid
frontend.io.ptwMemRespData := io.dmem_resp_bits
io.imem_req_valid := frontend.io.imemReqValid io.imem_req_valid := frontend.io.imemReqValid
io.imem_req_bits := frontend.io.imemReqAddr io.imem_req_bits := frontend.io.imemReqAddr
io.dmem_req_valid := backend.io.dmemReqValid io.dmem_req_valid := (backend.io.dmemReqValid && backendCanIssue) || frontendPtwCanIssue
io.dmem_req_bits_addr := backend.io.dmemReq.addr io.dmem_req_bits_addr := Mux(frontendPtwCanIssue, frontend.io.ptwMemReqAddr, backend.io.dmemReq.addr)
io.dmem_req_bits_data := backend.io.dmemReq.data io.dmem_req_bits_data := Mux(frontendPtwCanIssue, 0.U, backend.io.dmemReq.data)
io.dmem_req_bits_isStore := backend.io.dmemReq.isStore io.dmem_req_bits_isStore := backend.io.dmemReqValid && backendCanIssue && backend.io.dmemReq.isStore
io.dmem_req_bits_size := backend.io.dmemReq.size io.dmem_req_bits_size := Mux(frontendPtwCanIssue, 3.U, backend.io.dmemReq.size)
} else { } else {
val sFetch :: sExec :: sLoadWait :: Nil = Enum(3) val sFetch :: sExec :: sLoadWait :: Nil = Enum(3)
@@ -77,6 +109,10 @@ class Core(p: CoreParams = CoreParams()) extends Module {
val alu = Module(new ALU(p)) val alu = Module(new ALU(p))
val branch = Module(new BranchUnit(p)) val branch = Module(new BranchUnit(p))
val csr = Module(new CSRFile(p)) val csr = Module(new CSRFile(p))
val privCtrl = Module(new PrivilegeControl(p))
privCtrl.io.setPriv := false.B
privCtrl.io.nextPriv := Privileged.PRV_M
def regRead(addr: UInt): UInt = Mux(addr === 0.U, 0.U, regs(addr)) def regRead(addr: UInt): UInt = Mux(addr === 0.U, 0.U, regs(addr))
def lowLoad(data: UInt, size: UInt, signed: Bool): UInt = { def lowLoad(data: UInt, size: UInt, signed: Bool): UInt = {
@@ -110,13 +146,35 @@ class Core(p: CoreParams = CoreParams()) extends Module {
csr.io.cmd.rs1 := src1 csr.io.cmd.rs1 := src1
csr.io.cmd.zimm := dec.rs1 csr.io.cmd.zimm := dec.rs1
csr.io.readAddr := instReg(31, 20) csr.io.readAddr := instReg(31, 20)
csr.io.currentPriv := privCtrl.io.priv
val isEcall = instReg === "h00000073".U val isEcall = instReg === "h00000073".U
val isEbreak = instReg === "h00100073".U val isEbreak = instReg === "h00100073".U
val isMret = instReg === "h30200073".U val isMret = instReg === "h30200073".U
val takeTrap = state === sExec && (isEcall || isEbreak) val illegalPriv = (dec.isMret && privCtrl.io.priv =/= Privileged.PRV_M) ||
(dec.isSret && privCtrl.io.priv === Privileged.PRV_U) ||
(dec.isSfenceVma && privCtrl.io.priv === Privileged.PRV_U)
val csrAccess = dec.isSystem && dec.funct3 =/= 0.U
val csrWrites = csrAccess && !(dec.funct3(1) && dec.rs1 === 0.U)
val takeIllegal = state === sExec && (dec.illegal || illegalPriv ||
(csrAccess && csr.io.readIllegal) || (csrWrites && csr.io.writeIllegal))
val takeTrap = state === sExec && (isEcall || isEbreak) || takeIllegal
val takeMret = state === sExec && isMret
val takeSret = state === sExec && dec.isSret
val trapTargetPriv = PrivilegeTransitions.trapTargetPriv(
privCtrl.io.priv, csr.io.trapCause, false.B, csr.io.medeleg, csr.io.mideleg)
privCtrl.io.setPriv := takeTrap || takeMret || takeSret
privCtrl.io.nextPriv := Mux(takeMret || takeSret,
PrivilegeTransitions.xretNextPriv(takeMret, csr.io.mstatus),
trapTargetPriv)
csr.io.trap := takeTrap csr.io.trap := takeTrap
csr.io.trapPc := pcReg csr.io.trapPc := pcReg
csr.io.trapCause := Mux(isEbreak, 3.U, 11.U) csr.io.trapCause := Mux(takeIllegal, Privileged.CAUSE_ILLEGAL_INSTRUCTION,
Mux(isEbreak, Privileged.CAUSE_BREAKPOINT, Privileged.CAUSE_ECALL_FROM_M))
csr.io.trapTval := 0.U
csr.io.trapTargetPriv := trapTargetPriv
csr.io.trapIsInterrupt := false.B
csr.io.xret := takeMret || takeSret
csr.io.xretIsMret := takeMret
val loadAddr = src1 + dec.immI val loadAddr = src1 + dec.immI
val storeAddr = src1 + dec.immS val storeAddr = src1 + dec.immS
@@ -166,10 +224,10 @@ class Core(p: CoreParams = CoreParams()) extends Module {
} }
}.elsewhen(state === sExec) { }.elsewhen(state === sExec) {
when(takeTrap) { when(takeTrap) {
pc := csr.io.mtvec pc := csr.io.trapVector
state := sFetch state := sFetch
}.elsewhen(isMret) { }.elsewhen(isMret || dec.isSret) {
pc := csr.io.mepc pc := PrivilegeTransitions.xretTargetPc(isMret, csr.io.mepc, csr.io.sepc)
state := sFetch state := sFetch
}.elsewhen(dec.isLoad && !amoStoreLike) { }.elsewhen(dec.isLoad && !amoStoreLike) {
when(io.dmem_resp_valid) { when(io.dmem_resp_valid) {

View File

@@ -16,12 +16,17 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
val flush = Output(Bool()) val flush = Output(Bool())
val redirectPc = Output(UInt(p.xlen.W)) val redirectPc = Output(UInt(p.xlen.W))
val invalidateICache = Output(Bool()) val invalidateICache = Output(Bool())
val sfenceVma = Output(Bool())
val setPriv = Output(Bool())
val targetPriv = Output(UInt(2.W))
val dmemReqValid = Output(Bool()) val dmemReqValid = Output(Bool())
val dmemReq = Output(new MemRequest(p)) val dmemReq = Output(new MemRequest(p))
val dmemRespValid = Input(Bool()) val dmemRespValid = Input(Bool())
val dmemRespData = Input(UInt(p.xlen.W)) val dmemRespData = Input(UInt(p.xlen.W))
val satp = Input(UInt(p.xlen.W)) val satp = Input(UInt(p.xlen.W))
val satpOut = Output(UInt(p.xlen.W))
val currentPriv = Input(UInt(2.W))
}) })
val rename = Module(new RenameStage(p)) val rename = Module(new RenameStage(p))
@@ -47,9 +52,18 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
val completeCsrCmd = Wire(Vec(p.issueWidth, UInt(3.W))) val completeCsrCmd = Wire(Vec(p.issueWidth, UInt(3.W)))
val completeCsrRs1 = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val completeCsrRs1 = Wire(Vec(p.issueWidth, UInt(p.xlen.W)))
val completeCsrZimm = Wire(Vec(p.issueWidth, UInt(5.W))) val completeCsrZimm = Wire(Vec(p.issueWidth, UInt(5.W)))
val completeFenceI = Wire(Vec(p.issueWidth, Bool()))
val completeSfenceVma = Wire(Vec(p.issueWidth, Bool()))
val completeXret = Wire(Vec(p.issueWidth, Bool()))
val completeXretIsMret = Wire(Vec(p.issueWidth, Bool()))
val wakeup = Wire(Vec(p.issueWidth, new Wakeup(p))) val wakeup = Wire(Vec(p.issueWidth, new Wakeup(p)))
val wakeupReg = RegInit(VecInit(Seq.fill(p.issueWidth)(0.U.asTypeOf(new Wakeup(p))))) val wakeupReg = RegInit(VecInit(Seq.fill(p.issueWidth)(0.U.asTypeOf(new Wakeup(p)))))
val csrRData = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val csrRData = Wire(Vec(p.issueWidth, UInt(p.xlen.W)))
dontTouch(completeValid)
dontTouch(completeIdx)
dontTouch(completeException)
dontTouch(completeCause)
dontTouch(completeRedirectPc)
rename.io.inValid := VecInit((0 until p.issueWidth).map(i => io.decodeValid(i) && issue.io.inReady(i))) rename.io.inValid := VecInit((0 until p.issueWidth).map(i => io.decodeValid(i) && issue.io.inReady(i)))
rename.io.in := io.decode rename.io.in := io.decode
@@ -67,6 +81,10 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
rename.io.completeCsrCmd := completeCsrCmd rename.io.completeCsrCmd := completeCsrCmd
rename.io.completeCsrRs1 := completeCsrRs1 rename.io.completeCsrRs1 := completeCsrRs1
rename.io.completeCsrZimm := completeCsrZimm rename.io.completeCsrZimm := completeCsrZimm
rename.io.completeFenceI := completeFenceI
rename.io.completeSfenceVma := completeSfenceVma
rename.io.completeXret := completeXret
rename.io.completeXretIsMret := completeXretIsMret
rename.io.commitReady := commit.io.commitReady rename.io.commitReady := commit.io.commitReady
rename.io.commitMapValid := commit.io.commitMapValid rename.io.commitMapValid := commit.io.commitMapValid
rename.io.commitArch := commit.io.commitArch rename.io.commitArch := commit.io.commitArch
@@ -78,6 +96,8 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
issue.io.inValid := rename.io.outValid issue.io.inValid := rename.io.outValid
issue.io.in := rename.io.out issue.io.in := rename.io.out
issue.io.wakeup := wakeupReg issue.io.wakeup := wakeupReg
issue.io.robHeadValid := rename.io.commitEntry(0).valid
issue.io.robHeadIdx := rename.io.commitEntry(0).robIdx
val loadPending = RegInit(false.B) val loadPending = RegInit(false.B)
val loadPendingRob = Reg(UInt(robBits.W)) val loadPendingRob = Reg(UInt(robBits.W))
val loadPendingPhys = Reg(UInt(physBits.W)) val loadPendingPhys = Reg(UInt(physBits.W))
@@ -89,7 +109,14 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
val forwardPendingData = Reg(UInt(p.xlen.W)) val forwardPendingData = Reg(UInt(p.xlen.W))
val loadRespValid = (lsu.io.respValid && loadPending) || forwardPending val loadRespValid = (lsu.io.respValid && loadPending) || forwardPending
val loadRespData = Mux(forwardPending, forwardPendingData, lsu.io.respData) val loadRespData = Mux(forwardPending, forwardPendingData, lsu.io.respData)
val loadRespPageFault = !forwardPending && lsu.io.pageFault val loadRespFault = !forwardPending && (lsu.io.pageFault || lsu.io.accessFault || lsu.io.misaligned)
val storeCheckPending = RegInit(false.B)
val storeCheckPendingRob = Reg(UInt(robBits.W))
dontTouch(storeCheckPending)
val storeCheckRespNow = Wire(Bool())
val storeCheckRespPending = storeCheckPending && lsu.io.respValid
val storeCheckResp = storeCheckRespNow || storeCheckRespPending
val storeCheckFault = storeCheckResp && (lsu.io.pageFault || lsu.io.accessFault || lsu.io.misaligned)
val memIssue = Wire(Vec(p.issueWidth, Bool())) val memIssue = Wire(Vec(p.issueWidth, Bool()))
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
memIssue(i) := issue.io.outValid(i) && (issue.io.out(i).decoded.isLoad || issue.io.out(i).decoded.isStore) memIssue(i) := issue.io.outValid(i) && (issue.io.out(i).decoded.isLoad || issue.io.out(i).decoded.isStore)
@@ -103,22 +130,47 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
val memSlot0 = memIssue(0) val memSlot0 = memIssue(0)
val memSlot1 = !memSlot0 && memIssue(1) val memSlot1 = !memSlot0 && memIssue(1)
val memSlot = Mux(memSlot0, 0.U, 1.U) val memSlot = Mux(memSlot0, 0.U, 1.U)
val canIssueMem = !loadPending && !forwardPending val canIssueMem = !loadPending && !forwardPending && !storeCheckPending
val issue_io_outReady_0 = Wire(Bool()) val issue_io_outReady_0 = Wire(Bool())
val issue_io_outReady_1 = Wire(Bool()) val issue_io_outReady_1 = Wire(Bool())
dontTouch(issue_io_outReady_0) dontTouch(issue_io_outReady_0)
dontTouch(issue_io_outReady_1) dontTouch(issue_io_outReady_1)
val isMem0 = issue.io.out(0).decoded.isLoad || issue.io.out(0).decoded.isStore val isMem0 = issue.io.out(0).decoded.isLoad || issue.io.out(0).decoded.isStore
val isMem1 = issue.io.out(1).decoded.isLoad || issue.io.out(1).decoded.isStore val isMem1 = issue.io.out(1).decoded.isLoad || issue.io.out(1).decoded.isStore
val serializing0 = issue.io.out(0).decoded.isSystem || issue.io.out(0).decoded.isFenceI ||
issue.io.out(0).decoded.isSfenceVma || issue.io.out(0).decoded.isWfi
val serializing1 = issue.io.out(1).decoded.isSystem || issue.io.out(1).decoded.isFenceI ||
issue.io.out(1).decoded.isSfenceVma || issue.io.out(1).decoded.isWfi
val serializingReady0 = !serializing0 ||
(rename.io.commitEntry(0).valid && rename.io.commitEntry(0).robIdx === issue.io.out(0).robIdx)
val serializingReady1 = !serializing1 ||
(rename.io.commitEntry(0).valid && rename.io.commitEntry(0).robIdx === issue.io.out(1).robIdx)
dontTouch(serializingReady0)
dontTouch(serializingReady1)
val loadBlocked0 = issue.io.out(0).decoded.isLoad && sq.io.forwardBlock val loadBlocked0 = issue.io.out(0).decoded.isLoad && sq.io.forwardBlock
val loadBlocked1 = issue.io.out(1).decoded.isLoad && sq.io.forwardBlock val loadBlocked1 = issue.io.out(1).decoded.isLoad && sq.io.forwardBlock
val amoBlocked0 = issue.io.out(0).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid) val amoBlocked0 = issue.io.out(0).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid)
val amoBlocked1 = issue.io.out(1).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid) val amoBlocked1 = issue.io.out(1).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid)
val robHeadValid = rename.io.commitEntry(0).valid
val issue0AtHead = robHeadValid && rename.io.commitEntry(0).robIdx === issue.io.out(0).robIdx
val issue1AtHead = robHeadValid && rename.io.commitEntry(0).robIdx === issue.io.out(1).robIdx
val olderSerializingAtHead0 = robHeadValid && !issue0AtHead &&
(rename.io.commitEntry(0).csrValid || rename.io.commitEntry(0).fenceI ||
rename.io.commitEntry(0).sfenceVma || rename.io.commitEntry(0).xret)
val olderSerializingAtHead1 = robHeadValid && !issue1AtHead &&
(rename.io.commitEntry(0).csrValid || rename.io.commitEntry(0).fenceI ||
rename.io.commitEntry(0).sfenceVma || rename.io.commitEntry(0).xret)
val memReady0 = (!isMem0 || (lsu.io.reqReady && canIssueMem && !amoBlocked0 && !loadBlocked0)) && val memReady0 = (!isMem0 || (lsu.io.reqReady && canIssueMem && !amoBlocked0 && !loadBlocked0)) &&
!loadPending && !forwardPending !loadPending && !forwardPending && serializingReady0 && !olderSerializingAtHead0
val memReady1 = !isMem1 || (lsu.io.reqReady && canIssueMem && !memSlot0 && !amoBlocked1 && !loadBlocked1) val memReady1 = (!isMem1 || (lsu.io.reqReady && canIssueMem && !memSlot0 && !amoBlocked1 && !loadBlocked1)) &&
issue_io_outReady_0 := memReady0 serializingReady1 && !olderSerializingAtHead1
issue_io_outReady_1 := memReady1 && !stallSecondCsrRead val baseIssueReady0 = memReady0 && !storeCheckPending
val baseIssueReady1 = memReady1 && !storeCheckPending
val slot0WouldIssueSerializing = issue.io.outValid(0) && baseIssueReady0 && serializing0
val slot1WouldIssueSerializing = issue.io.outValid(1) && baseIssueReady1 && serializing1
issue_io_outReady_0 := baseIssueReady0 && !slot1WouldIssueSerializing
issue_io_outReady_1 := baseIssueReady1 && !slot0WouldIssueSerializing &&
!(stallSecondCsrRead && issue_io_outReady_0)
issue.io.outReady := VecInit(Seq(issue_io_outReady_0, issue_io_outReady_1)) issue.io.outReady := VecInit(Seq(issue_io_outReady_0, issue_io_outReady_1))
val issueFire = Wire(Vec(p.issueWidth, Bool())) val issueFire = Wire(Vec(p.issueWidth, Bool()))
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
@@ -132,12 +184,19 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
val memSrc1 = Mux(memSlot0, prf.io.rdata(0), prf.io.rdata(2)) val memSrc1 = Mux(memSlot0, prf.io.rdata(0), prf.io.rdata(2))
val memSrc2 = Mux(memSlot0, prf.io.rdata(1), prf.io.rdata(3)) val memSrc2 = Mux(memSlot0, prf.io.rdata(1), prf.io.rdata(3))
val memAddr = memSrc1 + Mux(memDecoded.isAmo, 0.U, Mux(memDecoded.isStore, memDecoded.immS, memDecoded.immI)) val memAddr = memSrc1 + Mux(memDecoded.isAmo, 0.U, Mux(memDecoded.isStore, memDecoded.immS, memDecoded.immI))
def accessBytes(size: UInt): UInt = MuxLookup(size, 8.U(4.W))(Seq(
0.U -> 1.U(4.W),
1.U -> 2.U(4.W),
2.U -> 4.U(4.W),
3.U -> 8.U(4.W)
))
val loadEnq = (memSlot0 || memSlot1) && memDecoded.isLoad && issue.io.outReady(memSlot) val loadEnq = (memSlot0 || memSlot1) && memDecoded.isLoad && issue.io.outReady(memSlot)
val storeEnq = (memSlot0 || memSlot1) && memDecoded.isStore && issue.io.outReady(memSlot) val storeEnq = (memSlot0 || memSlot1) && memDecoded.isStore && issue.io.outReady(memSlot)
val sqForwardValid = sq.io.forwardValid && !memDecoded.isAmo val sqForwardValid = sq.io.forwardValid && !memDecoded.isAmo
val forwardLoad = loadEnq && sqForwardValid val forwardLoad = loadEnq && sqForwardValid
val lsuLoadReq = loadEnq && !sqForwardValid val lsuLoadReq = loadEnq && !sqForwardValid
val lsuStoreCheckReq = storeEnq
val forwardByte = sq.io.forwardData(7, 0) val forwardByte = sq.io.forwardData(7, 0)
val forwardHalf = sq.io.forwardData(15, 0) val forwardHalf = sq.io.forwardData(15, 0)
val forwardWord = sq.io.forwardData(31, 0) val forwardWord = sq.io.forwardData(31, 0)
@@ -183,10 +242,15 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
rename.io.commitEntry(1).opClass === Consts.OP_STORE rename.io.commitEntry(1).opClass === Consts.OP_STORE
sq.io.commitValid := commitStore0 || commitStore1 sq.io.commitValid := commitStore0 || commitStore1
sq.io.commitRobIdx := Mux(commitStore0, rename.io.commitEntry(0).robIdx, rename.io.commitEntry(1).robIdx) sq.io.commitRobIdx := Mux(commitStore0, rename.io.commitEntry(0).robIdx, rename.io.commitEntry(1).robIdx)
sq.io.drainReady := !lsuLoadReq && lsu.io.reqReady val storeDrainFire = sq.io.drainValid && !lsuLoadReq && !lsuStoreCheckReq && lsu.io.reqReady
sq.io.drainReady := storeDrainFire
sq.io.flush := commit.io.flush sq.io.flush := commit.io.flush
lsu.io.reqValid := lsuLoadReq || sq.io.drainValid lsu.io.reqValid := lsuLoadReq || lsuStoreCheckReq || storeDrainFire
lsu.io.checkOnly := lsuStoreCheckReq
lsu.io.sfenceVma := commit.io.sfenceVma
lsu.io.currentPriv := io.currentPriv
lsu.io.mstatus := csr.io.mstatus
val loadReq = WireDefault(0.U.asTypeOf(new MemRequest(p))) val loadReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
loadReq.addr := memAddr loadReq.addr := memAddr
loadReq.data := memSrc2 loadReq.data := memSrc2
@@ -195,20 +259,42 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
loadReq.isAmo := memDecoded.isAmo loadReq.isAmo := memDecoded.isAmo
loadReq.amoOp := memDecoded.amoOp loadReq.amoOp := memDecoded.amoOp
loadReq.size := memDecoded.memWidth loadReq.size := memDecoded.memWidth
lsu.io.req := Mux(lsuLoadReq, loadReq, sq.io.drain) val storeCheckReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
storeCheckReq.addr := memAddr
storeCheckReq.data := memSrc2
storeCheckReq.isStore := true.B
storeCheckReq.isSigned := false.B
storeCheckReq.isAmo := false.B
storeCheckReq.amoOp := 0.U
storeCheckReq.size := memDecoded.memWidth
lsu.io.req := Mux(lsuLoadReq, loadReq, Mux(lsuStoreCheckReq, storeCheckReq, sq.io.drain))
storeCheckRespNow := lsuStoreCheckReq && lsu.io.respValid
lsu.io.dmemRespValid := io.dmemRespValid lsu.io.dmemRespValid := io.dmemRespValid
lsu.io.dmemRespData := io.dmemRespData lsu.io.dmemRespData := io.dmemRespData
lsu.io.satp := csr.io.satp lsu.io.satp := csr.io.satp
io.satpOut := csr.io.satp
io.dmemReqValid := lsu.io.dmemReqValid io.dmemReqValid := lsu.io.dmemReqValid
io.dmemReq := lsu.io.dmemReq io.dmemReq := lsu.io.dmemReq
val csrReadFire = VecInit((0 until p.issueWidth).map(i => csrReadReq(i) && issue.io.outReady(i))) val csrReadFire = VecInit((0 until p.issueWidth).map(i => csrReadReq(i) && issue.io.outReady(i)))
csr.io.readAddr := Mux(csrReadFire(0), issue.io.out(0).decoded.inst(31, 20), issue.io.out(1).decoded.inst(31, 20)) csr.io.readAddr := Mux(csrReadFire(0), issue.io.out(0).decoded.inst(31, 20), issue.io.out(1).decoded.inst(31, 20))
csr.io.currentPriv := io.currentPriv
csrRData(0) := csr.io.rdata csrRData(0) := csr.io.rdata
csrRData(1) := csr.io.rdata csrRData(1) := csr.io.rdata
csr.io.trap := commit.io.flush && commit.io.exception csr.io.trap := commit.io.flush && commit.io.exception
csr.io.trapPc := commit.io.badAddr csr.io.trapPc := commit.io.trapPc
csr.io.trapCause := commit.io.exceptionCause csr.io.trapCause := commit.io.exceptionCause
csr.io.trapTval := commit.io.badAddr
val trapTargetPriv = PrivilegeTransitions.trapTargetPriv(
io.currentPriv,
commit.io.exceptionCause,
false.B,
csr.io.medeleg,
csr.io.mideleg)
csr.io.trapTargetPriv := trapTargetPriv
csr.io.trapIsInterrupt := false.B
csr.io.xret := commit.io.flush && commit.io.xret
csr.io.xretIsMret := commit.io.xretIsMret
val commitCsr0 = commit.io.commitReady(0) && rename.io.commitValid(0) && rename.io.commitEntry(0).csrValid val commitCsr0 = commit.io.commitReady(0) && rename.io.commitValid(0) && rename.io.commitEntry(0).csrValid
val commitCsr1 = commit.io.commitReady(1) && rename.io.commitValid(1) && rename.io.commitEntry(1).csrValid val commitCsr1 = commit.io.commitReady(1) && rename.io.commitValid(1) && rename.io.commitEntry(1).csrValid
val commitCsrEntry = Mux(commitCsr0, rename.io.commitEntry(0), rename.io.commitEntry(1)) val commitCsrEntry = Mux(commitCsr0, rename.io.commitEntry(0), rename.io.commitEntry(1))
@@ -221,6 +307,7 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
when(commit.io.flush) { when(commit.io.flush) {
loadPending := false.B loadPending := false.B
forwardPending := false.B forwardPending := false.B
storeCheckPending := false.B
}.elsewhen(forwardLoad) { }.elsewhen(forwardLoad) {
forwardPending := true.B forwardPending := true.B
forwardPendingRob := issue.io.out(memSlot).robIdx forwardPendingRob := issue.io.out(memSlot).robIdx
@@ -237,6 +324,14 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
}.elsewhen(loadRespValid) { }.elsewhen(loadRespValid) {
loadPending := false.B loadPending := false.B
} }
when(!commit.io.flush) {
when(storeCheckRespPending) {
storeCheckPending := false.B
}.elsewhen(lsuStoreCheckReq && !storeCheckRespNow) {
storeCheckPending := true.B
storeCheckPendingRob := issue.io.out(memSlot).robIdx
}
}
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
prf.io.raddr(2 * i) := issue.io.out(i).prs1 prf.io.raddr(2 * i) := issue.io.out(i).prs1
@@ -245,8 +340,12 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
val decoded = issue.io.out(i).decoded val decoded = issue.io.out(i).decoded
val src1 = prf.io.rdata(2 * i) val src1Raw = prf.io.rdata(2 * i)
val rs2Val = prf.io.rdata(2 * i + 1) val rs2Raw = prf.io.rdata(2 * i + 1)
val src1 = MuxCase(src1Raw, (0 until p.issueWidth).map(w =>
(wakeupReg(w).valid && wakeupReg(w).phys =/= 0.U && wakeupReg(w).phys === issue.io.out(i).prs1) -> wakeupReg(w).data))
val rs2Val = MuxCase(rs2Raw, (0 until p.issueWidth).map(w =>
(wakeupReg(w).valid && wakeupReg(w).phys =/= 0.U && wakeupReg(w).phys === issue.io.out(i).prs2) -> wakeupReg(w).data))
val src2 = Mux(decoded.isOpImm || decoded.isLoad || decoded.isJalr, decoded.immI, rs2Val) val src2 = Mux(decoded.isOpImm || decoded.isLoad || decoded.isJalr, decoded.immI, rs2Val)
exec(i).io.inValid := issueFire(i) exec(i).io.inValid := issueFire(i)
@@ -254,8 +353,40 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
exec(i).io.src1 := src1 exec(i).io.src1 := src1
exec(i).io.src2 := src2 exec(i).io.src2 := src2
val isLoadRespSlot = i.U === 0.U && loadRespValid val branchTarget = decoded.pc + decoded.immB
val useExecWb = exec(i).io.outValid && decoded.writesRd && !decoded.isLoad val jalTarget = decoded.pc + decoded.immJ
val jalrTarget = (src1 + decoded.immI) & (~1.U(p.xlen.W))
val controlTarget = Mux(decoded.isJal, jalTarget,
Mux(decoded.isJalr, jalrTarget, branchTarget))
val controlTargetMisaligned = issueFire(i) &&
(decoded.isJal || decoded.isJalr || (decoded.isBranch && exec(i).io.branchTaken)) &&
controlTarget(1, 0) =/= 0.U
dontTouch(controlTargetMisaligned)
val branchRedirect = Mux(decoded.isJal, jalTarget,
Mux(decoded.isJalr, jalrTarget,
Mux(decoded.isBranch && exec(i).io.branchTaken, branchTarget, decoded.pc + 4.U)))
val isEcall = decoded.isEcall
val isEbreak = decoded.isEbreak
val isMret = decoded.isMret
val illegalPriv = (decoded.isMret && io.currentPriv =/= Privileged.PRV_M) ||
(decoded.isSret && io.currentPriv === Privileged.PRV_U) ||
(decoded.isSfenceVma && io.currentPriv === Privileged.PRV_U)
val csrReadIllegal = csrReadFire(i) && csr.io.readIllegal
val csrWrites = decoded.isSystem && decoded.funct3 =/= 0.U &&
!(decoded.funct3(1) && decoded.rs1 === 0.U)
val csrWriteIllegal = csrWrites && !CSRPermission.writeAllowed(decoded.inst(31, 20), io.currentPriv)
val illegalInst = !decoded.fetchException && (decoded.illegal || illegalPriv || csrReadIllegal || csrWriteIllegal)
val dataAddr = src1 + Mux(decoded.isStore, decoded.immS, decoded.immI)
val dataMisaligned = (dataAddr(2, 0) & (accessBytes(decoded.memWidth) - 1.U)) =/= 0.U
val storeMisaligned = issueFire(i) && decoded.isStore && dataMisaligned
val loadFaultNow = lsuLoadReq && lsu.io.respValid && (lsu.io.misaligned || lsu.io.pageFault || lsu.io.accessFault)
val issueRaisesException = issueFire(i) &&
(decoded.fetchException || illegalInst || isEcall || isEbreak || lq.io.violation || storeMisaligned ||
controlTargetMisaligned)
val loadRespHasFault = loadRespFault || loadFaultNow
val isLoadRespSlot = i.U === 0.U && loadRespValid && !loadRespHasFault
val useExecWb = exec(i).io.outValid && decoded.writesRd && !decoded.isLoad && !issueRaisesException
wb(i).io.valid := useExecWb || isLoadRespSlot wb(i).io.valid := useExecWb || isLoadRespSlot
wb(i).io.physDest := Mux(isLoadRespSlot, Mux(forwardPending, forwardPendingPhys, loadPendingPhys), issue.io.out(i).prd) wb(i).io.physDest := Mux(isLoadRespSlot, Mux(forwardPending, forwardPendingPhys, loadPendingPhys), issue.io.out(i).prd)
wb(i).io.data := Mux(isLoadRespSlot, loadRespData, Mux(decoded.isLui, decoded.immU, wb(i).io.data := Mux(isLoadRespSlot, loadRespData, Mux(decoded.isLui, decoded.immU,
@@ -271,36 +402,47 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
wakeup(i).phys := wb(i).io.waddr wakeup(i).phys := wb(i).io.waddr
wakeup(i).data := wb(i).io.wdata wakeup(i).data := wb(i).io.wdata
val branchTarget = decoded.pc + decoded.immB val completeLoadResp = i.U === 0.U && (loadRespValid || loadFaultNow)
val jalTarget = decoded.pc + decoded.immJ val completeStoreResp = (i.U === 0.U && storeCheckRespPending) ||
val jalrTarget = (src1 + decoded.immI) & (~1.U(p.xlen.W)) (storeCheckRespNow && issueFire(i) && decoded.isStore)
val branchRedirect = Mux(decoded.isJal, jalTarget, completeValid(i) := (issueFire(i) && !decoded.isLoad && !decoded.isStore) || completeLoadResp || completeStoreResp
Mux(decoded.isJalr, jalrTarget, val storeCompleteIdx = Mux(storeCheckRespPending, storeCheckPendingRob, issue.io.out(i).robIdx)
Mux(decoded.isBranch && exec(i).io.branchTaken, branchTarget, decoded.pc + 4.U))) completeIdx(i) := Mux(completeStoreResp, storeCompleteIdx,
val isEcall = decoded.inst === "h00000073".U Mux(completeLoadResp, Mux(loadFaultNow, issue.io.out(memSlot).robIdx, Mux(forwardPending, forwardPendingRob, loadPendingRob)),
val isEbreak = decoded.inst === "h00100073".U issue.io.out(i).robIdx))
val isMret = decoded.inst === "h30200073".U val issueException = issueRaisesException
val thisStoreCheckFault = completeStoreResp && storeCheckFault
val completeLoadResp = i.U === 0.U && loadRespValid completeException(i) := issueException || (completeLoadResp && (loadRespFault || loadFaultNow)) || thisStoreCheckFault
completeValid(i) := (issueFire(i) && !decoded.isLoad) || completeLoadResp completeCause(i) := Mux(thisStoreCheckFault || (completeLoadResp && (loadRespFault || loadFaultNow)), lsu.io.faultCause,
completeIdx(i) := Mux(completeLoadResp, Mux(forwardPending, forwardPendingRob, loadPendingRob), issue.io.out(i).robIdx) Mux(issueFire(i) && decoded.fetchException, decoded.fetchExceptionCause,
completeException(i) := (issueFire(i) && (decoded.illegal || isEcall || isEbreak || lq.io.violation)) || Mux(issueFire(i) && isEbreak, Privileged.CAUSE_BREAKPOINT,
(completeLoadResp && loadRespPageFault) Mux(issueFire(i) && isEcall, ExceptionSource.ecallCause(io.currentPriv),
completeCause(i) := Mux(completeLoadResp && loadRespPageFault, 13.U, Mux(storeMisaligned, Privileged.CAUSE_STORE_ADDR_MISALIGNED,
Mux(issueFire(i) && isEbreak, 3.U, Mux(controlTargetMisaligned, Privileged.CAUSE_INSTR_ADDR_MISALIGNED,
Mux(issueFire(i) && isEcall, 11.U, Mux(issueFire(i) && illegalInst, Privileged.CAUSE_ILLEGAL_INSTRUCTION, 0.U)))))))
Mux(issueFire(i) && decoded.illegal, 2.U, 0.U)))) completeBadAddr(i) := Mux(thisStoreCheckFault || (completeLoadResp && (loadRespFault || loadFaultNow)), lsu.io.faultAddr,
completeBadAddr(i) := decoded.pc Mux(storeMisaligned, dataAddr,
Mux(issueFire(i) && decoded.fetchException, decoded.fetchExceptionTval,
Mux(controlTargetMisaligned, controlTarget,
Mux(issueFire(i) && illegalInst, decoded.inst.pad(p.xlen), 0.U)))))
completeMispredict(i) := issueFire(i) && completeMispredict(i) := issueFire(i) &&
(decoded.isJal || decoded.isJalr || isMret || decoded.isFenceI || (decoded.isJal || decoded.isJalr || decoded.isXret || decoded.isFenceI || decoded.isSfenceVma || decoded.isWfi ||
(decoded.isBranch && exec(i).io.branchTaken)) (decoded.isBranch && exec(i).io.branchTaken))
completeRedirectPc(i) := Mux(isEcall || isEbreak, csr.io.mtvec, Mux(isMret, csr.io.mepc, branchRedirect)) completeRedirectPc(i) := Mux(isEcall || isEbreak,
csr.io.trapVector,
Mux(decoded.isXret,
PrivilegeTransitions.xretTargetPc(decoded.isMret, csr.io.mepc, csr.io.sepc),
Mux(decoded.isWfi, decoded.pc + 4.U, branchRedirect)))
completeCsrValid(i) := issueFire(i) && decoded.isSystem && decoded.funct3 =/= 0.U && completeCsrValid(i) := issueFire(i) && decoded.isSystem && decoded.funct3 =/= 0.U &&
!(decoded.funct3(1) && decoded.rs1 === 0.U) !(decoded.funct3(1) && decoded.rs1 === 0.U) && !illegalInst
completeCsrAddr(i) := decoded.inst(31, 20) completeCsrAddr(i) := decoded.inst(31, 20)
completeCsrCmd(i) := decoded.funct3 completeCsrCmd(i) := decoded.funct3
completeCsrRs1(i) := src1 completeCsrRs1(i) := src1
completeCsrZimm(i) := decoded.rs1 completeCsrZimm(i) := decoded.rs1
completeFenceI(i) := issueFire(i) && decoded.isFenceI
completeSfenceVma(i) := issueFire(i) && decoded.isSfenceVma
completeXret(i) := issueFire(i) && decoded.isXret
completeXretIsMret(i) := issueFire(i) && decoded.isMret
} }
wakeupReg := wakeup wakeupReg := wakeup
@@ -310,8 +452,16 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
io.commitValid := VecInit((0 until p.issueWidth).map(i => rename.io.commitValid(i) && commit.io.commitReady(i))) io.commitValid := VecInit((0 until p.issueWidth).map(i => rename.io.commitValid(i) && commit.io.commitReady(i)))
io.commitEntry := rename.io.commitEntry io.commitEntry := rename.io.commitEntry
io.flush := commit.io.flush io.flush := commit.io.flush
io.redirectPc := Mux(commit.io.exception, csr.io.mtvec, commit.io.redirectPc) val xretRedirectPc = PrivilegeTransitions.xretTargetPc(commit.io.xretIsMret, csr.io.mepc, csr.io.sepc)
dontTouch(xretRedirectPc)
io.redirectPc := Mux(commit.io.exception, csr.io.trapVector,
Mux(commit.io.xret, xretRedirectPc, commit.io.redirectPc))
io.invalidateICache := commit.io.fenceI io.invalidateICache := commit.io.fenceI
io.sfenceVma := commit.io.sfenceVma
io.setPriv := commit.io.setPriv
io.targetPriv := Mux(commit.io.exception,
trapTargetPriv,
Mux(commit.io.xret, PrivilegeTransitions.xretNextPriv(commit.io.xretIsMret, csr.io.mstatus), io.currentPriv))
} }
object OoOBackend extends App { object OoOBackend extends App {

View File

@@ -18,11 +18,18 @@ class CommitStage(p: CoreParams = CoreParams()) extends Module {
val exception = Output(Bool()) val exception = Output(Bool())
val exceptionCause = Output(UInt(p.xlen.W)) val exceptionCause = Output(UInt(p.xlen.W))
val badAddr = Output(UInt(p.xlen.W)) val badAddr = Output(UInt(p.xlen.W))
val trapPc = Output(UInt(p.xlen.W))
val fenceI = Output(Bool()) val fenceI = Output(Bool())
val sfenceVma = Output(Bool())
val xret = Output(Bool())
val xretIsMret = Output(Bool())
val setPriv = Output(Bool())
}) })
val firstTrap = io.robValid(0) && (io.robEntry(0).exception || io.robEntry(0).branchMispredict) val firstTrap = io.robValid(0) && (io.robEntry(0).exception || io.robEntry(0).branchMispredict ||
val secondTrap = io.robValid(1) && (io.robEntry(1).exception || io.robEntry(1).branchMispredict) io.robEntry(0).xret || io.robEntry(0).sfenceVma || io.robEntry(0).fenceI)
val secondTrap = io.robValid(1) && (io.robEntry(1).exception || io.robEntry(1).branchMispredict ||
io.robEntry(1).xret || io.robEntry(1).sfenceVma || io.robEntry(1).fenceI)
val twoCsrWrites = io.robValid(0) && io.robValid(1) && val twoCsrWrites = io.robValid(0) && io.robValid(1) &&
io.robEntry(0).csrValid && io.robEntry(1).csrValid io.robEntry(0).csrValid && io.robEntry(1).csrValid
val firstStore = io.robValid(0) && io.robEntry(0).opClass === Consts.OP_STORE val firstStore = io.robValid(0) && io.robEntry(0).opClass === Consts.OP_STORE
@@ -31,10 +38,11 @@ class CommitStage(p: CoreParams = CoreParams()) extends Module {
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
val doCommit = io.commitReady(i) val doCommit = io.commitReady(i)
io.freeOldPhys(i) := doCommit && io.robEntry(i).writesDest && val commitWritesDest = doCommit && !io.robEntry(i).exception && io.robEntry(i).writesDest
io.freeOldPhys(i) := commitWritesDest &&
io.robEntry(i).oldDest =/= io.robEntry(i).dest io.robEntry(i).oldDest =/= io.robEntry(i).dest
io.oldPhys(i) := io.robEntry(i).oldDest io.oldPhys(i) := io.robEntry(i).oldDest
io.commitMapValid(i) := doCommit && io.robEntry(i).writesDest && io.commitMapValid(i) := commitWritesDest &&
io.robEntry(i).archDest =/= 0.U io.robEntry(i).archDest =/= 0.U
io.commitArch(i) := io.robEntry(i).archDest io.commitArch(i) := io.robEntry(i).archDest
io.commitPhys(i) := io.robEntry(i).dest io.commitPhys(i) := io.robEntry(i).dest
@@ -50,6 +58,15 @@ class CommitStage(p: CoreParams = CoreParams()) extends Module {
Mux(secondTrapSelected, io.robEntry(1).exceptionCause, 0.U)) Mux(secondTrapSelected, io.robEntry(1).exceptionCause, 0.U))
io.badAddr := Mux(firstTrap, io.robEntry(0).badAddr, io.badAddr := Mux(firstTrap, io.robEntry(0).badAddr,
Mux(secondTrapSelected, io.robEntry(1).badAddr, 0.U)) Mux(secondTrapSelected, io.robEntry(1).badAddr, 0.U))
io.trapPc := Mux(firstTrap, io.robEntry(0).pc,
Mux(secondTrapSelected, io.robEntry(1).pc, 0.U))
io.fenceI := io.commitReady(0) && io.robEntry(0).fenceI || io.fenceI := io.commitReady(0) && io.robEntry(0).fenceI ||
io.commitReady(1) && io.robEntry(1).fenceI io.commitReady(1) && io.robEntry(1).fenceI
io.sfenceVma := io.commitReady(0) && io.robEntry(0).sfenceVma ||
io.commitReady(1) && io.robEntry(1).sfenceVma
io.xret := io.commitReady(0) && io.robEntry(0).xret ||
io.commitReady(1) && io.robEntry(1).xret
io.xretIsMret := Mux(firstTrap, io.robEntry(0).xretIsMret,
Mux(secondTrapSelected, io.robEntry(1).xretIsMret, true.B))
io.setPriv := selectedTrap && (io.exception || io.xret)
} }

View File

@@ -7,6 +7,9 @@ class FetchPacket(p: CoreParams = CoreParams()) extends Bundle {
val laneValid = Vec(p.fetchWidth, Bool()) val laneValid = Vec(p.fetchWidth, Bool())
val predictedTaken = Bool() val predictedTaken = Bool()
val predictedTarget = UInt(p.xlen.W) val predictedTarget = UInt(p.xlen.W)
val exception = Bool()
val exceptionCause = UInt(p.xlen.W)
val exceptionTval = UInt(p.xlen.W)
} }
class BranchUpdate(p: CoreParams = CoreParams()) extends Bundle { class BranchUpdate(p: CoreParams = CoreParams()) extends Bundle {
@@ -48,10 +51,21 @@ class DecodedInst(p: CoreParams = CoreParams()) extends Bundle {
val isWord = Bool() val isWord = Bool()
val isSystem = Bool() val isSystem = Bool()
val isFenceI = Bool() val isFenceI = Bool()
val isEcall = Bool()
val isEbreak = Bool()
val isMret = Bool()
val isSret = Bool()
val isUret = Bool()
val isSfenceVma = Bool()
val isXret = Bool()
val isWfi = Bool()
val isAmo = Bool() val isAmo = Bool()
val amoOp = UInt(5.W) val amoOp = UInt(5.W)
val writesRd = Bool() val writesRd = Bool()
val illegal = Bool() val illegal = Bool()
val fetchException = Bool()
val fetchExceptionCause = UInt(p.xlen.W)
val fetchExceptionTval = UInt(p.xlen.W)
} }
class RenamePacket(p: CoreParams = CoreParams()) extends Bundle { class RenamePacket(p: CoreParams = CoreParams()) extends Bundle {
@@ -90,11 +104,23 @@ class CsrCommand(p: CoreParams = CoreParams()) extends Bundle {
val zimm = UInt(5.W) val zimm = UInt(5.W)
} }
class TrapInfo(p: CoreParams = CoreParams()) extends Bundle {
val valid = Bool()
val isInterrupt = Bool()
val cause = UInt(p.xlen.W)
val tval = UInt(p.xlen.W)
val epc = UInt(p.xlen.W)
val originPriv = UInt(2.W)
}
class TlbReq(p: CoreParams = CoreParams()) extends Bundle { class TlbReq(p: CoreParams = CoreParams()) extends Bundle {
val valid = Bool() val valid = Bool()
val vaddr = UInt(p.xlen.W) val vaddr = UInt(p.xlen.W)
val isStore = Bool() val isStore = Bool()
val isFetch = Bool() val isFetch = Bool()
val priv = UInt(2.W)
val sum = Bool()
val mxr = Bool()
} }
class TlbResp(p: CoreParams = CoreParams()) extends Bundle { class TlbResp(p: CoreParams = CoreParams()) extends Bundle {

View File

@@ -0,0 +1,77 @@
import chisel3._
object Privileged {
val MISA_RV64_IMASU = "h8000000000141101".U(64.W)
val PRV_U = 0.U(2.W)
val PRV_S = 1.U(2.W)
val PRV_M = 3.U(2.W)
val MSTATUS_MPRV_BIT = 17
val MSTATUS_SUM_BIT = 18
val MSTATUS_MXR_BIT = 19
val MSTATUS_MPP_HI = 12
val MSTATUS_MPP_LO = 11
val CAUSE_INSTR_ADDR_MISALIGNED = 0.U(8.W)
val CAUSE_INSTR_ACCESS_FAULT = 1.U(8.W)
val CAUSE_ILLEGAL_INSTRUCTION = 2.U(8.W)
val CAUSE_BREAKPOINT = 3.U(8.W)
val CAUSE_LOAD_ADDR_MISALIGNED = 4.U(8.W)
val CAUSE_LOAD_ACCESS_FAULT = 5.U(8.W)
val CAUSE_STORE_ADDR_MISALIGNED = 6.U(8.W)
val CAUSE_STORE_ACCESS_FAULT = 7.U(8.W)
val CAUSE_ECALL_FROM_U = 8.U(8.W)
val CAUSE_ECALL_FROM_S = 9.U(8.W)
val CAUSE_ECALL_FROM_M = 11.U(8.W)
val CAUSE_INSTR_PAGE_FAULT = 12.U(8.W)
val CAUSE_LOAD_PAGE_FAULT = 13.U(8.W)
val CAUSE_STORE_PAGE_FAULT = 15.U(8.W)
val CAUSE_SUPERVISOR_SOFTWARE_INTERRUPT = 1.U(8.W)
val CAUSE_MACHINE_SOFTWARE_INTERRUPT = 3.U(8.W)
val CAUSE_SUPERVISOR_TIMER_INTERRUPT = 5.U(8.W)
val CAUSE_MACHINE_TIMER_INTERRUPT = 7.U(8.W)
val CAUSE_SUPERVISOR_EXTERNAL_INTERRUPT = 9.U(8.W)
val CAUSE_MACHINE_EXTERNAL_INTERRUPT = 11.U(8.W)
val CSR_SSTATUS = "h100".U(12.W)
val CSR_SIE = "h104".U(12.W)
val CSR_STVEC = "h105".U(12.W)
val CSR_SCOUNTEREN = "h106".U(12.W)
val CSR_SSCRATCH = "h140".U(12.W)
val CSR_SEPC = "h141".U(12.W)
val CSR_SCAUSE = "h142".U(12.W)
val CSR_STVAL = "h143".U(12.W)
val CSR_SIP = "h144".U(12.W)
val CSR_SATP = "h180".U(12.W)
val CSR_MSTATUS = "h300".U(12.W)
val CSR_MISA = "h301".U(12.W)
val CSR_MEDELEG = "h302".U(12.W)
val CSR_MIDELEG = "h303".U(12.W)
val CSR_MIE = "h304".U(12.W)
val CSR_MTVEC = "h305".U(12.W)
val CSR_MCOUNTEREN = "h306".U(12.W)
val CSR_MCOUNTINHIBIT = "h320".U(12.W)
val CSR_MSCRATCH = "h340".U(12.W)
val CSR_MEPC = "h341".U(12.W)
val CSR_MCAUSE = "h342".U(12.W)
val CSR_MTVAL = "h343".U(12.W)
val CSR_MIP = "h344".U(12.W)
val CSR_PMPCFG0 = "h3a0".U(12.W)
val CSR_PMPADDR0 = "h3b0".U(12.W)
val CSR_TSELECT = "h7a0".U(12.W)
val CSR_TDATA1 = "h7a1".U(12.W)
val CSR_TDATA2 = "h7a2".U(12.W)
val CSR_TCONTROL = "h7a5".U(12.W)
val CSR_MNSTATUS = "h744".U(12.W)
val CSR_MINSTRET = "hb02".U(12.W)
val CSR_MVENDORID = "hf11".U(12.W)
val CSR_MARCHID = "hf12".U(12.W)
val CSR_MIMPID = "hf13".U(12.W)
val CSR_MHARTID = "hf14".U(12.W)
val CSR_CYCLE = "hc00".U(12.W)
val CSR_TIME = "hc01".U(12.W)
val CSR_INSTRET = "hc02".U(12.W)
}

View File

@@ -5,20 +5,42 @@ class CSRFile(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val cmd = Input(new CsrCommand(p)) val cmd = Input(new CsrCommand(p))
val readAddr = Input(UInt(12.W)) val readAddr = Input(UInt(12.W))
val currentPriv = Input(UInt(2.W))
val rdata = Output(UInt(p.xlen.W)) val rdata = Output(UInt(p.xlen.W))
val readIllegal = Output(Bool())
val writeIllegal = Output(Bool())
val illegal = Output(Bool())
val trap = Input(Bool()) val trap = Input(Bool())
val trapPc = Input(UInt(p.xlen.W)) val trapPc = Input(UInt(p.xlen.W))
val trapCause = Input(UInt(p.xlen.W)) val trapCause = Input(UInt(p.xlen.W))
val trapTval = Input(UInt(p.xlen.W))
val trapTargetPriv = Input(UInt(2.W))
val trapIsInterrupt = Input(Bool())
val trapVector = Output(UInt(p.xlen.W))
val xret = Input(Bool())
val xretIsMret = Input(Bool())
val satp = Output(UInt(p.xlen.W)) val satp = Output(UInt(p.xlen.W))
val mtvec = Output(UInt(p.xlen.W)) val mtvec = Output(UInt(p.xlen.W))
val mepc = Output(UInt(p.xlen.W)) val mepc = Output(UInt(p.xlen.W))
val stvec = Output(UInt(p.xlen.W))
val sepc = Output(UInt(p.xlen.W))
val medeleg = Output(UInt(p.xlen.W))
val mideleg = Output(UInt(p.xlen.W))
val mie = Output(UInt(p.xlen.W))
val mip = Output(UInt(p.xlen.W))
val mstatus = Output(UInt(p.xlen.W))
}) })
val cycle = RegInit(0.U(p.xlen.W)) val cycle = RegInit(0.U(p.xlen.W))
val instret = RegInit(0.U(p.xlen.W)) val instret = RegInit(0.U(p.xlen.W))
val mcountinhibit = RegInit(0.U(p.xlen.W))
val suppressInstretIncrement = WireDefault(false.B)
val suppressInstretAfterWrite = RegInit(false.B)
dontTouch(suppressInstretIncrement)
val mstatus = RegInit(0.U(p.xlen.W)) val mstatus = RegInit(0.U(p.xlen.W))
val misa = RegInit("h800000000014112d".U(p.xlen.W)) val misa = RegInit(Privileged.MISA_RV64_IMASU)
val mtvecReg = RegInit(0.U(p.xlen.W)) val mtvecReg = RegInit(0.U(p.xlen.W))
val mscratch = RegInit(0.U(p.xlen.W))
val mepcReg = RegInit(0.U(p.xlen.W)) val mepcReg = RegInit(0.U(p.xlen.W))
val mcause = RegInit(0.U(p.xlen.W)) val mcause = RegInit(0.U(p.xlen.W))
val mtval = RegInit(0.U(p.xlen.W)) val mtval = RegInit(0.U(p.xlen.W))
@@ -26,7 +48,14 @@ class CSRFile(p: CoreParams = CoreParams()) extends Module {
val mideleg = RegInit(0.U(p.xlen.W)) val mideleg = RegInit(0.U(p.xlen.W))
val mie = RegInit(0.U(p.xlen.W)) val mie = RegInit(0.U(p.xlen.W))
val mip = RegInit(0.U(p.xlen.W)) val mip = RegInit(0.U(p.xlen.W))
val sstatus = RegInit(0.U(p.xlen.W)) val mcounteren = RegInit(0.U(p.xlen.W))
val pmpcfg0 = RegInit(0.U(p.xlen.W))
val pmpaddr0 = RegInit(0.U(p.xlen.W))
val tdata1 = RegInit(0.U(p.xlen.W))
val tdata2 = RegInit(0.U(p.xlen.W))
val tcontrol = RegInit(0.U(p.xlen.W))
val mnstatus = RegInit(0.U(p.xlen.W))
val scounteren = RegInit(0.U(p.xlen.W))
val stvec = RegInit(0.U(p.xlen.W)) val stvec = RegInit(0.U(p.xlen.W))
val sepc = RegInit(0.U(p.xlen.W)) val sepc = RegInit(0.U(p.xlen.W))
val scause = RegInit(0.U(p.xlen.W)) val scause = RegInit(0.U(p.xlen.W))
@@ -35,59 +64,116 @@ class CSRFile(p: CoreParams = CoreParams()) extends Module {
val satpReg = RegInit(0.U(p.xlen.W)) val satpReg = RegInit(0.U(p.xlen.W))
cycle := cycle + 1.U cycle := cycle + 1.U
when(!mcountinhibit(2) && !suppressInstretIncrement && !suppressInstretAfterWrite) {
instret := instret + 1.U
}
io.satp := satpReg io.satp := satpReg
io.mtvec := mtvecReg io.mtvec := mtvecReg
io.mepc := mepcReg io.mepc := mepcReg
io.stvec := stvec
io.sepc := sepc
io.medeleg := medeleg
io.mideleg := mideleg
io.mie := mie
io.mip := mip
io.mstatus := mstatus
val readAllowed = CSRPermission.readAllowed(io.readAddr, io.currentPriv)
val writeAllowed = CSRPermission.writeAllowed(io.cmd.addr, io.currentPriv)
val readIllegal = !readAllowed
val writeIllegal = io.cmd.valid && io.cmd.cmd =/= 0.U && !writeAllowed
val xlenStatusMask = "h0000000f00000000".U(p.xlen.W)
val rv64XlenStatus = "h0000000a00000000".U(p.xlen.W)
val mstatusView = (mstatus & ~xlenStatusMask) | rv64XlenStatus
val sstatusMask = "h00000002000de162".U(p.xlen.W)
val sstatusView = mstatusView & sstatusMask
val r = WireDefault(0.U(p.xlen.W)) val r = WireDefault(0.U(p.xlen.W))
switch(io.readAddr) { switch(io.readAddr) {
is("h300".U) { r := mstatus } is(Privileged.CSR_MSTATUS) { r := mstatusView }
is("h301".U) { r := misa } is(Privileged.CSR_MISA) { r := misa }
is("h302".U) { r := medeleg } is(Privileged.CSR_MEDELEG) { r := medeleg }
is("h303".U) { r := mideleg } is(Privileged.CSR_MIDELEG) { r := mideleg }
is("h304".U) { r := mie } is(Privileged.CSR_MIE) { r := mie }
is("h305".U) { r := mtvecReg } is(Privileged.CSR_MTVEC) { r := mtvecReg }
is("h341".U) { r := mepcReg } is(Privileged.CSR_MCOUNTEREN) { r := mcounteren }
is("h342".U) { r := mcause } is(Privileged.CSR_MCOUNTINHIBIT) { r := mcountinhibit }
is("h343".U) { r := mtval } is(Privileged.CSR_MSCRATCH) { r := mscratch }
is("h344".U) { r := mip } is(Privileged.CSR_MEPC) { r := mepcReg }
is("h100".U) { r := sstatus } is(Privileged.CSR_MCAUSE) { r := mcause }
is("h105".U) { r := stvec } is(Privileged.CSR_MTVAL) { r := mtval }
is("h140".U) { r := sscratch } is(Privileged.CSR_MIP) { r := mip }
is("h141".U) { r := sepc } is(Privileged.CSR_PMPCFG0) { r := pmpcfg0 }
is("h142".U) { r := scause } is(Privileged.CSR_PMPADDR0) { r := pmpaddr0 }
is("h143".U) { r := stval } is(Privileged.CSR_TSELECT) { r := 1.U }
is("h180".U) { r := satpReg } is(Privileged.CSR_TDATA1) { r := tdata1 }
is("hf14".U) { r := 0.U } is(Privileged.CSR_TDATA2) { r := tdata2 }
is("hc00".U) { r := cycle } is(Privileged.CSR_TCONTROL) { r := tcontrol }
is("hc01".U) { r := 0.U } is(Privileged.CSR_MNSTATUS) { r := mnstatus }
is("hc02".U) { r := instret } is(Privileged.CSR_SSTATUS) { r := sstatusView }
is(Privileged.CSR_SIE) { r := mie & mideleg }
is(Privileged.CSR_STVEC) { r := stvec }
is(Privileged.CSR_SCOUNTEREN) { r := scounteren }
is(Privileged.CSR_SSCRATCH) { r := sscratch }
is(Privileged.CSR_SEPC) { r := sepc }
is(Privileged.CSR_SCAUSE) { r := scause }
is(Privileged.CSR_STVAL) { r := stval }
is(Privileged.CSR_SIP) { r := mip & mideleg }
is(Privileged.CSR_SATP) { r := satpReg }
is(Privileged.CSR_MVENDORID) { r := 0.U }
is(Privileged.CSR_MARCHID) { r := 0.U }
is(Privileged.CSR_MIMPID) { r := 0.U }
is(Privileged.CSR_MHARTID) { r := 0.U }
is(Privileged.CSR_MINSTRET) { r := instret }
is(Privileged.CSR_CYCLE) { r := cycle }
is(Privileged.CSR_TIME) { r := cycle }
is(Privileged.CSR_INSTRET) { r := instret }
} }
io.rdata := r io.rdata := Mux(readAllowed, r, 0.U)
io.readIllegal := readIllegal
io.writeIllegal := writeIllegal
io.illegal := readIllegal || writeIllegal
val writeOld = WireDefault(0.U(p.xlen.W)) val writeOld = WireDefault(0.U(p.xlen.W))
switch(io.cmd.addr) { switch(io.cmd.addr) {
is("h300".U) { writeOld := mstatus } is(Privileged.CSR_MSTATUS) { writeOld := mstatusView }
is("h301".U) { writeOld := misa } is(Privileged.CSR_MISA) { writeOld := misa }
is("h302".U) { writeOld := medeleg } is(Privileged.CSR_MEDELEG) { writeOld := medeleg }
is("h303".U) { writeOld := mideleg } is(Privileged.CSR_MIDELEG) { writeOld := mideleg }
is("h304".U) { writeOld := mie } is(Privileged.CSR_MIE) { writeOld := mie }
is("h305".U) { writeOld := mtvecReg } is(Privileged.CSR_MTVEC) { writeOld := mtvecReg }
is("h341".U) { writeOld := mepcReg } is(Privileged.CSR_MCOUNTEREN) { writeOld := mcounteren }
is("h342".U) { writeOld := mcause } is(Privileged.CSR_MCOUNTINHIBIT) { writeOld := mcountinhibit }
is("h343".U) { writeOld := mtval } is(Privileged.CSR_MSCRATCH) { writeOld := mscratch }
is("h344".U) { writeOld := mip } is(Privileged.CSR_MEPC) { writeOld := mepcReg }
is("h100".U) { writeOld := sstatus } is(Privileged.CSR_MCAUSE) { writeOld := mcause }
is("h105".U) { writeOld := stvec } is(Privileged.CSR_MTVAL) { writeOld := mtval }
is("h140".U) { writeOld := sscratch } is(Privileged.CSR_MIP) { writeOld := mip }
is("h141".U) { writeOld := sepc } is(Privileged.CSR_PMPCFG0) { writeOld := pmpcfg0 }
is("h142".U) { writeOld := scause } is(Privileged.CSR_PMPADDR0) { writeOld := pmpaddr0 }
is("h143".U) { writeOld := stval } is(Privileged.CSR_TSELECT) { writeOld := 1.U }
is("h180".U) { writeOld := satpReg } is(Privileged.CSR_TDATA1) { writeOld := tdata1 }
is("hf14".U) { writeOld := 0.U } is(Privileged.CSR_TDATA2) { writeOld := tdata2 }
is("hc00".U) { writeOld := cycle } is(Privileged.CSR_TCONTROL) { writeOld := tcontrol }
is("hc01".U) { writeOld := 0.U } is(Privileged.CSR_MNSTATUS) { writeOld := mnstatus }
is("hc02".U) { writeOld := instret } is(Privileged.CSR_SSTATUS) { writeOld := sstatusView }
is(Privileged.CSR_SIE) { writeOld := mie & mideleg }
is(Privileged.CSR_STVEC) { writeOld := stvec }
is(Privileged.CSR_SCOUNTEREN) { writeOld := scounteren }
is(Privileged.CSR_SSCRATCH) { writeOld := sscratch }
is(Privileged.CSR_SEPC) { writeOld := sepc }
is(Privileged.CSR_SCAUSE) { writeOld := scause }
is(Privileged.CSR_STVAL) { writeOld := stval }
is(Privileged.CSR_SIP) { writeOld := mip & mideleg }
is(Privileged.CSR_SATP) { writeOld := satpReg }
is(Privileged.CSR_MVENDORID) { writeOld := 0.U }
is(Privileged.CSR_MARCHID) { writeOld := 0.U }
is(Privileged.CSR_MIMPID) { writeOld := 0.U }
is(Privileged.CSR_MHARTID) { writeOld := 0.U }
is(Privileged.CSR_MINSTRET) { writeOld := instret }
is(Privileged.CSR_CYCLE) { writeOld := cycle }
is(Privileged.CSR_TIME) { writeOld := cycle }
is(Privileged.CSR_INSTRET) { writeOld := instret }
} }
val operand = Mux(io.cmd.cmd(2), io.cmd.zimm, io.cmd.rs1) val operand = Mux(io.cmd.cmd(2), io.cmd.zimm, io.cmd.rs1)
@@ -97,29 +183,82 @@ class CSRFile(p: CoreParams = CoreParams()) extends Module {
3.U -> (writeOld & ~operand) 3.U -> (writeOld & ~operand)
)) ))
when(io.cmd.valid && io.cmd.cmd =/= 0.U) { when(io.cmd.valid && io.cmd.cmd =/= 0.U && writeAllowed) {
switch(io.cmd.addr) { switch(io.cmd.addr) {
is("h300".U) { mstatus := next } is(Privileged.CSR_MSTATUS) { mstatus := next }
is("h302".U) { medeleg := next } is(Privileged.CSR_MEDELEG) { medeleg := next }
is("h303".U) { mideleg := next } is(Privileged.CSR_MIDELEG) { mideleg := next }
is("h304".U) { mie := next } is(Privileged.CSR_MIE) { mie := next }
is("h305".U) { mtvecReg := next } is(Privileged.CSR_MTVEC) { mtvecReg := next }
is("h341".U) { mepcReg := next } is(Privileged.CSR_MCOUNTEREN) { mcounteren := next }
is("h342".U) { mcause := next } is(Privileged.CSR_MCOUNTINHIBIT) { mcountinhibit := next & 4.U }
is("h343".U) { mtval := next } is(Privileged.CSR_MSCRATCH) { mscratch := next }
is("h344".U) { mip := next } is(Privileged.CSR_MEPC) { mepcReg := next }
is("h100".U) { sstatus := next } is(Privileged.CSR_MCAUSE) { mcause := next }
is("h105".U) { stvec := next } is(Privileged.CSR_MTVAL) { mtval := next }
is("h140".U) { sscratch := next } is(Privileged.CSR_MIP) { mip := next }
is("h141".U) { sepc := next } is(Privileged.CSR_PMPCFG0) { pmpcfg0 := next }
is("h142".U) { scause := next } is(Privileged.CSR_PMPADDR0) { pmpaddr0 := next }
is("h143".U) { stval := next } is(Privileged.CSR_TDATA1) { tdata1 := next }
is("h180".U) { satpReg := next } is(Privileged.CSR_TDATA2) { tdata2 := next }
is(Privileged.CSR_TCONTROL) { tcontrol := next }
is(Privileged.CSR_MNSTATUS) { mnstatus := next }
is(Privileged.CSR_SSTATUS) { mstatus := (mstatus & ~sstatusMask) | (next & sstatusMask) }
is(Privileged.CSR_SIE) { mie := (mie & ~mideleg) | (next & mideleg) }
is(Privileged.CSR_STVEC) { stvec := next }
is(Privileged.CSR_SCOUNTEREN) { scounteren := next }
is(Privileged.CSR_SSCRATCH) { sscratch := next }
is(Privileged.CSR_SEPC) { sepc := next }
is(Privileged.CSR_SCAUSE) { scause := next }
is(Privileged.CSR_STVAL) { stval := next }
is(Privileged.CSR_SIP) { mip := (mip & ~mideleg) | (next & mideleg) }
is(Privileged.CSR_SATP) { satpReg := next }
is(Privileged.CSR_MINSTRET) {
instret := next
suppressInstretIncrement := true.B
suppressInstretAfterWrite := true.B
}
} }
} }
when(suppressInstretAfterWrite) {
suppressInstretAfterWrite := false.B
}
val trapToS = io.trapTargetPriv === Privileged.PRV_S
io.trapVector := Mux(trapToS, stvec, mtvecReg)
val bitMie = 1.U(p.xlen.W) << 3
val bitMpie = 1.U(p.xlen.W) << 7
val mppMask = 3.U(p.xlen.W) << 11
val bitSie = 1.U(p.xlen.W) << 1
val bitSpie = 1.U(p.xlen.W) << 5
val bitSpp = 1.U(p.xlen.W) << 8
when(io.trap) { when(io.trap) {
mepcReg := io.trapPc when(trapToS) {
mcause := io.trapCause sepc := io.trapPc
scause := io.trapCause
stval := io.trapTval
val withSpie = Mux((mstatus & bitSie) =/= 0.U, mstatus | bitSpie, mstatus & ~bitSpie)
val withSieCleared = withSpie & ~bitSie
val withSpp = Mux(io.currentPriv === Privileged.PRV_S, withSieCleared | bitSpp, withSieCleared & ~bitSpp)
mstatus := withSpp
}.otherwise {
mepcReg := io.trapPc
mcause := io.trapCause
mtval := io.trapTval
val withMpie = Mux((mstatus & bitMie) =/= 0.U, mstatus | bitMpie, mstatus & ~bitMpie)
val withMieCleared = withMpie & ~bitMie
mstatus := (withMieCleared & ~mppMask) | (io.currentPriv.pad(p.xlen) << 11)
}
}.elsewhen(io.xret) {
when(io.xretIsMret) {
val withMie = Mux((mstatus & bitMpie) =/= 0.U, mstatus | bitMie, mstatus & ~bitMie)
val withMpie = withMie | bitMpie
mstatus := withMpie & ~mppMask
}.otherwise {
val withSie = Mux((mstatus & bitSpie) =/= 0.U, mstatus | bitSie, mstatus & ~bitSie)
val withSpie = withSie | bitSpie
mstatus := withSpie & ~bitSpp
}
} }
} }

View File

@@ -0,0 +1,63 @@
import chisel3._
object CSRPermission {
private val machineCsrs = Set(
0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x340, 0x341, 0x342, 0x343, 0x344,
0x320, 0x3a0, 0x3b0, 0x744, 0x7a0, 0x7a1, 0x7a2, 0x7a5, 0xb02,
0xf11, 0xf12, 0xf13, 0xf14)
private val supervisorCsrs = Set(0x100, 0x104, 0x105, 0x106, 0x140, 0x141, 0x142, 0x143, 0x144, 0x180)
private val counterCsrs = Set(0xc00, 0xc01, 0xc02)
private val readOnlyCsrs = Set(0xf11, 0xf12, 0xf13, 0xf14) ++ counterCsrs
def implementedLit(addr: BigInt): Boolean =
machineCsrs(addr.toInt) || supervisorCsrs(addr.toInt) || counterCsrs(addr.toInt)
def readAllowedLit(addr: BigInt, priv: BigInt): Boolean =
implementedLit(addr) && {
if (machineCsrs(addr.toInt)) priv == 3
else if (supervisorCsrs(addr.toInt)) priv != 0
else true
}
def writeAllowedLit(addr: BigInt, priv: BigInt): Boolean =
readAllowedLit(addr, priv) && !readOnlyCsrs(addr.toInt)
private def isMachine(addr: UInt): Bool =
addr === Privileged.CSR_MSTATUS || addr === Privileged.CSR_MISA ||
addr === Privileged.CSR_MEDELEG || addr === Privileged.CSR_MIDELEG ||
addr === Privileged.CSR_MIE || addr === Privileged.CSR_MTVEC ||
addr === Privileged.CSR_MCOUNTEREN || addr === Privileged.CSR_MSCRATCH || addr === Privileged.CSR_MEPC ||
addr === Privileged.CSR_MCAUSE || addr === Privileged.CSR_MTVAL ||
addr === Privileged.CSR_MIP || addr === Privileged.CSR_PMPCFG0 ||
addr === Privileged.CSR_PMPADDR0 || addr === Privileged.CSR_TSELECT ||
addr === Privileged.CSR_TDATA1 || addr === Privileged.CSR_TDATA2 ||
addr === Privileged.CSR_TCONTROL || addr === Privileged.CSR_MNSTATUS ||
addr === Privileged.CSR_MCOUNTINHIBIT || addr === Privileged.CSR_MINSTRET ||
addr === Privileged.CSR_MVENDORID || addr === Privileged.CSR_MARCHID ||
addr === Privileged.CSR_MIMPID || addr === Privileged.CSR_MHARTID
private def isSupervisor(addr: UInt): Bool =
addr === Privileged.CSR_SSTATUS || addr === Privileged.CSR_SIE ||
addr === Privileged.CSR_STVEC || addr === Privileged.CSR_SSCRATCH ||
addr === Privileged.CSR_SCOUNTEREN || addr === Privileged.CSR_SEPC || addr === Privileged.CSR_SCAUSE ||
addr === Privileged.CSR_STVAL || addr === Privileged.CSR_SIP ||
addr === Privileged.CSR_SATP
private def isCounter(addr: UInt): Bool =
addr === Privileged.CSR_CYCLE || addr === Privileged.CSR_TIME ||
addr === Privileged.CSR_INSTRET
private def isReadOnly(addr: UInt): Bool =
addr === Privileged.CSR_MVENDORID || addr === Privileged.CSR_MARCHID ||
addr === Privileged.CSR_MIMPID || addr === Privileged.CSR_MHARTID ||
isCounter(addr)
def implemented(addr: UInt): Bool = isMachine(addr) || isSupervisor(addr) || isCounter(addr)
def readAllowed(addr: UInt, priv: UInt): Bool =
implemented(addr) && Mux(isMachine(addr), priv === Privileged.PRV_M,
Mux(isSupervisor(addr), priv =/= Privileged.PRV_U, true.B))
def writeAllowed(addr: UInt, priv: UInt): Bool =
readAllowed(addr, priv) && !isReadOnly(addr)
}

View File

@@ -2,20 +2,14 @@ import chisel3._
class PrivilegeControl(p: CoreParams = CoreParams()) extends Module { class PrivilegeControl(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val trap = Input(Bool()) val nextPriv = Input(UInt(2.W))
val mret = Input(Bool()) val setPriv = Input(Bool())
val sret = Input(Bool()) val priv = Output(UInt(2.W))
val privilege = Output(UInt(2.W))
}) })
val mode = RegInit(3.U(2.W)) val privReg = RegInit(Privileged.PRV_M)
when(io.trap) { when(io.setPriv) {
mode := 3.U privReg := io.nextPriv
}.elsewhen(io.mret) {
mode := 0.U
}.elsewhen(io.sret) {
mode := 0.U
} }
io.privilege := mode io.priv := privReg
} }

View File

@@ -0,0 +1,47 @@
import chisel3._
import chisel3.util._
object PrivilegeTransitions {
private def delegated(cause: UInt, delegation: UInt): Bool = delegation(cause(5, 0))
def trapTargetPriv(
currentPriv: UInt,
cause: UInt,
isInterrupt: Bool,
medeleg: UInt,
mideleg: UInt): UInt = {
val delegation = Mux(isInterrupt, mideleg, medeleg)
val toSupervisor = currentPriv =/= Privileged.PRV_M && delegated(cause, delegation)
Mux(toSupervisor, Privileged.PRV_S, Privileged.PRV_M)
}
def mretNextPriv(mstatus: UInt): UInt = mstatus(12, 11)
def sretNextPriv(mstatus: UInt): UInt = Mux(mstatus(8), Privileged.PRV_S, Privileged.PRV_U)
def xretTargetPc(isMret: Bool, mepc: UInt, sepc: UInt): UInt =
Mux(isMret, mepc, sepc)
def xretNextPriv(isMret: Bool, mstatus: UInt): UInt =
Mux(isMret, mretNextPriv(mstatus), sretNextPriv(mstatus))
def trapTargetPrivLit(
currentPriv: BigInt,
cause: BigInt,
isInterrupt: Boolean,
medeleg: BigInt,
mideleg: BigInt): BigInt = {
val delegation = if (isInterrupt) mideleg else medeleg
val delegated = ((delegation >> cause.toInt) & 1) == 1
if (currentPriv != Privileged.PRV_M.litValue && delegated) Privileged.PRV_S.litValue
else Privileged.PRV_M.litValue
}
def mretNextPrivLit(mstatus: BigInt): BigInt = (mstatus >> 11) & 3
def sretNextPrivLit(mstatus: BigInt): BigInt =
if (((mstatus >> 8) & 1) == 1) Privileged.PRV_S.litValue else Privileged.PRV_U.litValue
def xretTargetPcLit(isMret: Boolean, mepc: BigInt, sepc: BigInt): BigInt =
if (isMret) mepc else sepc
}

View File

@@ -47,6 +47,24 @@ class Decoder(p: CoreParams = CoreParams()) extends Module {
)) ))
d.memSigned := !funct3(2) d.memSigned := !funct3(2)
d.illegal := false.B d.illegal := false.B
val isSystemOpcode = opcode === "b1110011".U
val isFenceOpcode = opcode === "b0001111".U
val isEcall = io.inst === "h00000073".U
val isEbreak = io.inst === "h00100073".U
val isMret = io.inst === "h30200073".U
val isSret = io.inst === "h10200073".U
val isUret = io.inst === "h00200073".U
val isWfi = io.inst === "h10500073".U
val isSfenceVma = isSystemOpcode && funct3 === 0.U && funct7 === "b0001001".U
val isKnownPrivInst = isEcall || isEbreak || isMret || isSret || isSfenceVma || isWfi
d.isEcall := isEcall
d.isEbreak := isEbreak
d.isMret := isMret
d.isSret := isSret
d.isUret := isUret
d.isSfenceVma := isSfenceVma
d.isXret := isMret || isSret
d.isWfi := isWfi
switch(opcode) { switch(opcode) {
is("b0110111".U) { is("b0110111".U) {
@@ -128,11 +146,15 @@ class Decoder(p: CoreParams = CoreParams()) extends Module {
is("b0001111".U) { is("b0001111".U) {
d.opClass := Consts.OP_SYSTEM d.opClass := Consts.OP_SYSTEM
d.isFenceI := funct3 === "b001".U d.isFenceI := funct3 === "b001".U
d.illegal := funct3 =/= 0.U && funct3 =/= "b001".U
} }
is("b1110011".U) { is("b1110011".U) {
d.isSystem := true.B d.isSystem := true.B
d.writesRd := rd =/= 0.U && funct3 =/= 0.U d.writesRd := rd =/= 0.U && funct3 =/= 0.U
d.opClass := Consts.OP_SYSTEM d.opClass := Consts.OP_SYSTEM
when(funct3 === 0.U) {
d.illegal := !(isKnownPrivInst && !isUret)
}
} }
is("b0101111".U) { is("b0101111".U) {
d.isLoad := true.B d.isLoad := true.B
@@ -151,5 +173,9 @@ class Decoder(p: CoreParams = CoreParams()) extends Module {
d.illegal := true.B d.illegal := true.B
} }
when(isSystemOpcode && isUret) {
d.illegal := true.B
}
io.out := d io.out := d
} }

View File

@@ -14,6 +14,9 @@ class IDStage(p: CoreParams = CoreParams()) extends Module {
decoders(i).io.inst := io.in.inst(i) decoders(i).io.inst := io.in.inst(i)
io.out(i) := decoders(i).io.out io.out(i) := decoders(i).io.out
io.out(i).valid := io.inValid && io.in.laneValid(i) io.out(i).valid := io.inValid && io.in.laneValid(i)
io.out(i).fetchException := io.in.exception
io.out(i).fetchExceptionCause := io.in.exceptionCause
io.out(i).fetchExceptionTval := io.in.exceptionTval
io.outValid(i) := io.inValid && io.in.laneValid(i) io.outValid(i) := io.inValid && io.in.laneValid(i)
} }
} }

View File

@@ -0,0 +1,35 @@
import chisel3._
import chisel3.util._
object ExceptionSource {
private val priorityTable = Map(
12 -> 0,
1 -> 1,
2 -> 2,
0 -> 3,
3 -> 4,
8 -> 5,
9 -> 5,
11 -> 5,
13 -> 6,
5 -> 7,
4 -> 8,
15 -> 9,
7 -> 10,
6 -> 11
)
def priorityOf(cause: UInt): Int =
priorityTable.getOrElse(cause.litValue.toInt, 100)
def ecallCause(priv: UInt): UInt = MuxLookup(priv, Privileged.CAUSE_ECALL_FROM_M)(Seq(
Privileged.PRV_U -> Privileged.CAUSE_ECALL_FROM_U,
Privileged.PRV_S -> Privileged.CAUSE_ECALL_FROM_S,
Privileged.PRV_M -> Privileged.CAUSE_ECALL_FROM_M
))
def ecallCauseLit(priv: BigInt): BigInt =
if (priv == BigInt(0)) Privileged.CAUSE_ECALL_FROM_U.litValue
else if (priv == BigInt(1)) Privileged.CAUSE_ECALL_FROM_S.litValue
else Privileged.CAUSE_ECALL_FROM_M.litValue
}

View File

@@ -6,35 +6,78 @@ class Frontend(p: CoreParams = CoreParams()) extends Module {
val redirectValid = Input(Bool()) val redirectValid = Input(Bool())
val redirectPc = Input(UInt(p.xlen.W)) val redirectPc = Input(UInt(p.xlen.W))
val invalidateICache = Input(Bool()) val invalidateICache = Input(Bool())
val sfenceVma = Input(Bool())
val satp = Input(UInt(p.xlen.W))
val currentPriv = Input(UInt(2.W))
val imemReqValid = Output(Bool()) val imemReqValid = Output(Bool())
val imemReqAddr = Output(UInt(p.xlen.W)) val imemReqAddr = Output(UInt(p.xlen.W))
val imemRespValid = Input(Bool()) val imemRespValid = Input(Bool())
val imemRespBits = Input(Vec(p.fetchWidth, UInt(32.W))) val imemRespBits = Input(Vec(p.fetchWidth, UInt(32.W)))
val ptwMemReqValid = Output(Bool())
val ptwMemReqAddr = Output(UInt(p.xlen.W))
val ptwMemRespValid = Input(Bool())
val ptwMemRespData = Input(UInt(p.xlen.W))
val outReady = Input(Bool()) val outReady = Input(Bool())
val outValid = Output(Bool()) val outValid = Output(Bool())
val out = Output(new FetchPacket(p)) val out = Output(new FetchPacket(p))
val instMisaligned = Output(Bool())
val instPageFault = Output(Bool())
val faultPc = Output(UInt(p.xlen.W))
val branchUpdate = Input(new BranchUpdate(p)) val branchUpdate = Input(new BranchUpdate(p))
}) })
val pc = RegInit(Consts.ResetVector) val pc = RegInit(Consts.ResetVector)
val predictor = Module(new BranchPredictor(p)) val predictor = Module(new BranchPredictor(p))
val itlb = Module(new ITLB(p)) val itlb = Module(new ITLB(p))
val immu = Module(new MMU(p))
val icache = Module(new ICache(p)) val icache = Module(new ICache(p))
val faultPending = RegInit(false.B)
val faultPc = Reg(UInt(p.xlen.W))
val faultCause = Reg(UInt(p.xlen.W))
predictor.io.pc := pc predictor.io.pc := pc
predictor.io.update := io.branchUpdate predictor.io.update := io.branchUpdate
itlb.io.req.valid := true.B
val fetchTranslate = io.satp(63, 60) =/= 0.U && io.currentPriv =/= Privileged.PRV_M
dontTouch(fetchTranslate)
val itlbReqValid = fetchTranslate && !faultPending
itlb.io.req.valid := itlbReqValid
itlb.io.req.vaddr := pc itlb.io.req.vaddr := pc
itlb.io.req.isStore := false.B itlb.io.req.isStore := false.B
itlb.io.req.isFetch := true.B itlb.io.req.isFetch := true.B
itlb.io.refill.valid := false.B itlb.io.req.priv := io.currentPriv
itlb.io.refill.vpn := 0.U itlb.io.req.sum := false.B
itlb.io.refill.ppn := 0.U itlb.io.req.mxr := false.B
itlb.io.refill.level := 0.U itlb.io.flush := io.redirectValid || io.invalidateICache || io.sfenceVma
itlb.io.refill.flags := 0.U
icache.io.reqValid := true.B val itlbMiss = fetchTranslate && itlb.io.resp.miss
icache.io.reqAddr := Mux(itlb.io.resp.hit, itlb.io.resp.paddr, pc) dontTouch(itlbMiss)
immu.io.satp := io.satp
immu.io.req.valid := itlbMiss
immu.io.req.vaddr := pc
immu.io.req.isStore := false.B
immu.io.req.isFetch := true.B
immu.io.req.priv := io.currentPriv
immu.io.req.sum := false.B
immu.io.req.mxr := false.B
immu.io.ptwMemResp.valid := io.ptwMemRespValid
immu.io.ptwMemResp.data := io.ptwMemRespData
itlb.io.refill := immu.io.refill
io.ptwMemReqValid := immu.io.ptwMemReq.valid
io.ptwMemReqAddr := immu.io.ptwMemReq.addr
val instMisaligned = pc(1, 0) =/= 0.U
val instPageFault = fetchTranslate && (itlb.io.resp.pageFault || immu.io.resp.pageFault)
val fetchFault = instMisaligned || instPageFault
val translationFault = instPageFault
val translationReady = !fetchTranslate || itlb.io.resp.hit || translationFault
dontTouch(translationReady)
val translatedFetchAddr = Mux(fetchTranslate, itlb.io.resp.paddr, pc)
dontTouch(translatedFetchAddr)
icache.io.reqValid := !fetchFault && !faultPending && translationReady
icache.io.reqAddr := translatedFetchAddr
icache.io.reqPc := pc icache.io.reqPc := pc
icache.io.flush := io.redirectValid icache.io.flush := io.redirectValid
icache.io.invalidate := io.invalidateICache icache.io.invalidate := io.invalidateICache
@@ -44,15 +87,33 @@ class Frontend(p: CoreParams = CoreParams()) extends Module {
io.imemReqValid := icache.io.memReqValid io.imemReqValid := icache.io.memReqValid
io.imemReqAddr := icache.io.memReqAddr io.imemReqAddr := icache.io.memReqAddr
io.outValid := icache.io.respValid val faultPacket = WireDefault(0.U.asTypeOf(new FetchPacket(p)))
io.out := icache.io.resp faultPacket.pc := faultPc
faultPacket.laneValid(0) := true.B
faultPacket.exception := true.B
faultPacket.exceptionCause := faultCause
faultPacket.exceptionTval := faultPc
io.outValid := faultPending || icache.io.respValid
io.out := Mux(faultPending, faultPacket, icache.io.resp)
io.out.predictedTaken := predictor.io.taken io.out.predictedTaken := predictor.io.taken
io.out.predictedTarget := predictor.io.target io.out.predictedTarget := predictor.io.target
io.instMisaligned := instMisaligned
io.instPageFault := instPageFault
io.faultPc := pc
val sequentialNextPc = icache.io.resp.pc + (PopCount(icache.io.resp.laneValid) << 2) val sequentialNextPc = icache.io.resp.pc + (PopCount(icache.io.resp.laneValid) << 2)
when(io.redirectValid) { when(io.redirectValid) {
faultPending := false.B
pc := io.redirectPc pc := io.redirectPc
}.elsewhen(fetchFault && !faultPending) {
faultPending := true.B
faultPc := pc
faultCause := Mux(instMisaligned, Privileged.CAUSE_INSTR_ADDR_MISALIGNED, Privileged.CAUSE_INSTR_PAGE_FAULT)
}.elsewhen(faultPending && io.outReady) {
faultPending := false.B
pc := pc + 4.U
}.elsewhen(icache.io.respValid && io.outReady) { }.elsewhen(icache.io.respValid && io.outReady) {
pc := Mux(predictor.io.taken, predictor.io.target, sequentialNextPc) pc := Mux(predictor.io.taken, predictor.io.target, sequentialNextPc)
} }

View File

@@ -10,6 +10,7 @@ class ITLB(p: CoreParams = CoreParams()) extends Module {
val req = Input(new TlbReq(p)) val req = Input(new TlbReq(p))
val resp = Output(new TlbResp(p)) val resp = Output(new TlbResp(p))
val refill = Input(new TlbRefill(p)) val refill = Input(new TlbRefill(p))
val flush = Input(Bool())
val missVpn = Output(UInt(vpnBits.W)) val missVpn = Output(UInt(vpnBits.W))
}) })
@@ -22,20 +23,34 @@ class ITLB(p: CoreParams = CoreParams()) extends Module {
val reqVpn = io.req.vaddr(38, 12) val reqVpn = io.req.vaddr(38, 12)
val pageOff = io.req.vaddr(11, 0) val pageOff = io.req.vaddr(11, 0)
val hitVec = VecInit((0 until p.itlbEntries).map(i => valid(i) && vpn(i) === reqVpn)) val hitVec = VecInit((0 until p.itlbEntries).map { i =>
val samePage = Mux(level(i) === 2.U, vpn(i)(26, 18) === reqVpn(26, 18),
Mux(level(i) === 1.U, vpn(i)(26, 9) === reqVpn(26, 9), vpn(i) === reqVpn))
valid(i) && samePage
})
val hit = io.req.valid && hitVec.asUInt.orR val hit = io.req.valid && hitVec.asUInt.orR
val hitIdx = OHToUInt(hitVec) val hitIdx = OHToUInt(hitVec)
val hitLevel = level(hitIdx)
val paddrPpn0 = Mux(hitLevel === 0.U, ppn(hitIdx)(8, 0), reqVpn(8, 0))
val paddrPpn1 = Mux(hitLevel <= 1.U, ppn(hitIdx)(17, 9), reqVpn(17, 9))
val paddrPpn2 = ppn(hitIdx)(43, 18)
val x = flags(hitIdx)(3) val x = flags(hitIdx)(3)
val pageFault = hit && !x val u = flags(hitIdx)(4)
val a = flags(hitIdx)(6)
val sModeToUserFault = io.req.priv === Privileged.PRV_S && u
val uModeToSupervisorFault = io.req.priv === Privileged.PRV_U && !u
val pageFault = hit && (sModeToUserFault || uModeToSupervisorFault || !x || !a)
io.resp.hit := hit && !pageFault io.resp.hit := hit && !pageFault
io.resp.miss := io.req.valid && !hit io.resp.miss := io.req.valid && !hit
io.resp.paddr := Cat(ppn(hitIdx), pageOff) io.resp.paddr := Cat(paddrPpn2, paddrPpn1, paddrPpn0, pageOff)
io.resp.pageFault := pageFault io.resp.pageFault := pageFault
io.resp.accessFault := false.B io.resp.accessFault := false.B
io.missVpn := reqVpn io.missVpn := reqVpn
when(io.refill.valid) { when(io.flush) {
valid := VecInit(Seq.fill(p.itlbEntries)(false.B))
}.elsewhen(io.refill.valid) {
valid(repl) := true.B valid(repl) := true.B
vpn(repl) := io.refill.vpn vpn(repl) := io.refill.vpn
ppn(repl) := io.refill.ppn ppn(repl) := io.refill.ppn

View File

@@ -0,0 +1,34 @@
import chisel3._
class Clint(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle {
val addr = Input(UInt(p.xlen.W))
val wen = Input(Bool())
val wdata = Input(UInt(p.xlen.W))
val ren = Input(Bool())
val rdata = Output(UInt(p.xlen.W))
val mipMSIP = Output(Bool())
val mipMTIP = Output(Bool())
})
val msip = RegInit(false.B)
val mtime = RegInit(0.U(p.xlen.W))
val mtimecmp = RegInit(~0.U(p.xlen.W))
mtime := mtime + 1.U
when(io.wen) {
when(io.addr === "h0".U) {
msip := io.wdata(0)
}.elsewhen(io.addr === "h4000".U) {
mtimecmp := io.wdata
}.elsewhen(io.addr === "hbff8".U) {
mtime := io.wdata
}
}
io.rdata := Mux(io.addr === "h0".U, msip,
Mux(io.addr === "h4000".U, mtimecmp,
Mux(io.addr === "hbff8".U, mtime, 0.U)))
io.mipMSIP := msip
io.mipMTIP := mtime >= mtimecmp
}

View File

@@ -0,0 +1,45 @@
import chisel3._
import chisel3.util._
class InterruptController(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle {
val currentPriv = Input(UInt(2.W))
val mstatus = Input(UInt(p.xlen.W))
val mie = Input(UInt(p.xlen.W))
val mip = Input(UInt(p.xlen.W))
val mideleg = Input(UInt(p.xlen.W))
val interruptValid = Output(Bool())
val interruptCause = Output(UInt(p.xlen.W))
val targetPriv = Output(UInt(2.W))
})
val pendingEnabled = io.mie & io.mip
val mei = pendingEnabled(11)
val mti = pendingEnabled(7)
val msi = pendingEnabled(3)
val sei = pendingEnabled(9) && io.mideleg(9)
val sti = pendingEnabled(5) && io.mideleg(5)
val ssi = pendingEnabled(1) && io.mideleg(1)
val machineCause = Mux(mei, Privileged.CAUSE_MACHINE_EXTERNAL_INTERRUPT,
Mux(mti, Privileged.CAUSE_MACHINE_TIMER_INTERRUPT, Privileged.CAUSE_MACHINE_SOFTWARE_INTERRUPT))
val supervisorCause = Mux(sei, Privileged.CAUSE_SUPERVISOR_EXTERNAL_INTERRUPT,
Mux(sti, Privileged.CAUSE_SUPERVISOR_TIMER_INTERRUPT, Privileged.CAUSE_SUPERVISOR_SOFTWARE_INTERRUPT))
val machinePending = mei || mti || msi
val supervisorPending = sei || sti || ssi
val takeSupervisor = io.currentPriv =/= Privileged.PRV_M && supervisorPending
io.interruptValid := machinePending || takeSupervisor
io.interruptCause := Mux(takeSupervisor, supervisorCause, machineCause)
io.targetPriv := Mux(takeSupervisor, Privileged.PRV_S, Privileged.PRV_M)
}
object InterruptController {
def highestMachineCauseLit(msip: Boolean, mtip: Boolean, meip: Boolean): BigInt =
if (meip) Privileged.CAUSE_MACHINE_EXTERNAL_INTERRUPT.litValue
else if (mtip) Privileged.CAUSE_MACHINE_TIMER_INTERRUPT.litValue
else if (msip) Privileged.CAUSE_MACHINE_SOFTWARE_INTERRUPT.litValue
else BigInt(0)
def delegatesToSupervisorLit(cause: BigInt, mideleg: BigInt): Boolean =
((mideleg >> cause.toInt) & 1) == 1
}

View File

@@ -0,0 +1,11 @@
import chisel3._
class Plic(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle {
val externalPending = Input(Bool())
val enable = Input(Bool())
val mipMEIP = Output(Bool())
})
io.mipMEIP := io.externalPending && io.enable
}

View File

@@ -1,4 +1,5 @@
import chisel3._ import chisel3._
import chisel3.util._
class IssueQueue(p: CoreParams = CoreParams()) extends Module { class IssueQueue(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
@@ -9,6 +10,8 @@ class IssueQueue(p: CoreParams = CoreParams()) extends Module {
val issueValid = Output(Vec(p.issueWidth, Bool())) val issueValid = Output(Vec(p.issueWidth, Bool()))
val issue = Output(Vec(p.issueWidth, new RenamePacket(p))) val issue = Output(Vec(p.issueWidth, new RenamePacket(p)))
val issueReady = Input(Vec(p.issueWidth, Bool())) val issueReady = Input(Vec(p.issueWidth, Bool()))
val robHeadValid = Input(Bool())
val robHeadIdx = Input(UInt(log2Ceil(p.robEntries).W))
val flush = Input(Bool()) val flush = Input(Bool())
}) })
@@ -17,6 +20,8 @@ class IssueQueue(p: CoreParams = CoreParams()) extends Module {
intRs.io.enq := io.enq intRs.io.enq := io.enq
intRs.io.wakeup := io.wakeup intRs.io.wakeup := io.wakeup
intRs.io.issueReady := io.issueReady intRs.io.issueReady := io.issueReady
intRs.io.robHeadValid := io.robHeadValid
intRs.io.robHeadIdx := io.robHeadIdx
intRs.io.flush := io.flush intRs.io.flush := io.flush
io.enqReady := intRs.io.enqReady io.enqReady := intRs.io.enqReady

View File

@@ -1,4 +1,5 @@
import chisel3._ import chisel3._
import chisel3.util._
class IssueStage(p: CoreParams = CoreParams()) extends Module { class IssueStage(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
@@ -9,6 +10,8 @@ class IssueStage(p: CoreParams = CoreParams()) extends Module {
val outValid = Output(Vec(p.issueWidth, Bool())) val outValid = Output(Vec(p.issueWidth, Bool()))
val out = Output(Vec(p.issueWidth, new RenamePacket(p))) val out = Output(Vec(p.issueWidth, new RenamePacket(p)))
val outReady = Input(Vec(p.issueWidth, Bool())) val outReady = Input(Vec(p.issueWidth, Bool()))
val robHeadValid = Input(Bool())
val robHeadIdx = Input(UInt(log2Ceil(p.robEntries).W))
val flush = Input(Bool()) val flush = Input(Bool())
}) })
@@ -17,6 +20,8 @@ class IssueStage(p: CoreParams = CoreParams()) extends Module {
queue.io.enq := io.in queue.io.enq := io.in
queue.io.wakeup := io.wakeup queue.io.wakeup := io.wakeup
queue.io.issueReady := io.outReady queue.io.issueReady := io.outReady
queue.io.robHeadValid := io.robHeadValid
queue.io.robHeadIdx := io.robHeadIdx
queue.io.flush := io.flush queue.io.flush := io.flush
io.inReady := queue.io.enqReady io.inReady := queue.io.enqReady

View File

@@ -10,6 +10,8 @@ class ReservationStation(p: CoreParams = CoreParams(), entries: Int = 16) extend
val issueValid = Output(Vec(p.issueWidth, Bool())) val issueValid = Output(Vec(p.issueWidth, Bool()))
val issue = Output(Vec(p.issueWidth, new RenamePacket(p))) val issue = Output(Vec(p.issueWidth, new RenamePacket(p)))
val issueReady = Input(Vec(p.issueWidth, Bool())) val issueReady = Input(Vec(p.issueWidth, Bool()))
val robHeadValid = Input(Bool())
val robHeadIdx = Input(UInt(log2Ceil(p.robEntries).W))
val flush = Input(Bool()) val flush = Input(Bool())
}) })
@@ -37,7 +39,10 @@ class ReservationStation(p: CoreParams = CoreParams(), entries: Int = 16) extend
valid(j) && slots(j).decoded.isStore && isOlder(slots(j).robIdx, slots(i).robIdx) valid(j) && slots(j).decoded.isStore && isOlder(slots(j).robIdx, slots(i).robIdx)
)).asUInt.orR )).asUInt.orR
val waitsForOlderStore = (slots(i).decoded.isLoad || slots(i).decoded.isAmo) && olderStorePending val waitsForOlderStore = (slots(i).decoded.isLoad || slots(i).decoded.isAmo) && olderStorePending
readyVec(i) := valid(i) && src1ReadyNow && src2ReadyNow && !waitsForOlderStore val serializing = slots(i).decoded.isSystem || slots(i).decoded.isFenceI ||
slots(i).decoded.isSfenceVma || slots(i).decoded.isWfi
val serializingAtHead = !serializing || (io.robHeadValid && slots(i).robIdx === io.robHeadIdx)
readyVec(i) := valid(i) && src1ReadyNow && src2ReadyNow && !waitsForOlderStore && serializingAtHead
} }
val issue0OH = PriorityEncoderOH(readyVec.asUInt) val issue0OH = PriorityEncoderOH(readyVec.asUInt)

View File

@@ -87,7 +87,7 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
val data = SyncReadMem(sets, Vec(p.dCacheWays, Vec(lineWords, UInt(p.xlen.W)))) val data = SyncReadMem(sets, Vec(p.dCacheWays, Vec(lineWords, UInt(p.xlen.W))))
val repl = RegInit(VecInit(Seq.fill(sets)(0.U(log2Ceil(p.dCacheWays).W)))) val repl = RegInit(VecInit(Seq.fill(sets)(0.U(log2Ceil(p.dCacheWays).W))))
val sIdle :: sLookup :: sMiss :: sAmoRead :: sAmoWrite :: sMisalignReadLo :: sMisalignReadHi :: sMisalignResp :: Nil = Enum(8) val sIdle :: sLookup :: sMiss :: sAmoRead :: sAmoWrite :: Nil = Enum(5)
val state = RegInit(sIdle) val state = RegInit(sIdle)
val reqReg = Reg(new MemRequest(p)) val reqReg = Reg(new MemRequest(p))
val reqSet = Reg(UInt(setBits.W)) val reqSet = Reg(UInt(setBits.W))
@@ -101,12 +101,13 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
val scStore = RegInit(false.B) val scStore = RegInit(false.B)
val reservationValid = RegInit(false.B) val reservationValid = RegInit(false.B)
val reservationAddr = Reg(UInt(p.xlen.W)) val reservationAddr = Reg(UInt(p.xlen.W))
val misalignLo = Reg(UInt(p.xlen.W))
val misalignHi = Reg(UInt(p.xlen.W))
def reservationGranule(addr: UInt): UInt = addr(p.xlen - 1, 2) def reservationGranule(addr: UInt): UInt = addr(p.xlen - 1, 2)
val set = setIndex(io.req.addr) val set = setIndex(io.req.addr)
val reqBytes = accessBytes(io.req.size)
val reqMisaligned = (io.req.addr(2, 0) & (reqBytes - 1.U)) =/= 0.U
assert(!(io.reqValid && reqMisaligned), "DCache received misaligned request; LSU must trap before DCache")
val storeEndSet = setIndex(io.req.addr + accessBytes(io.req.size) - 1.U) val storeEndSet = setIndex(io.req.addr + accessBytes(io.req.size) - 1.U)
val word = wordIndex(io.req.addr) val word = wordIndex(io.req.addr)
val readFire = state === sIdle && io.reqValid && !io.req.isStore && !io.req.isAmo val readFire = state === sIdle && io.reqValid && !io.req.isStore && !io.req.isAmo
@@ -130,24 +131,6 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
memReq.amoOp := reqReg.amoOp memReq.amoOp := reqReg.amoOp
memReq.size := 3.U memReq.size := 3.U
val misalignLoReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
misalignLoReq.addr := alignedWordAddr(reqReg.addr)
misalignLoReq.data := 0.U
misalignLoReq.isStore := false.B
misalignLoReq.isSigned := reqReg.isSigned
misalignLoReq.isAmo := false.B
misalignLoReq.amoOp := reqReg.amoOp
misalignLoReq.size := 3.U
val misalignHiReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
misalignHiReq.addr := alignedWordAddr(reqReg.addr) + 8.U
misalignHiReq.data := 0.U
misalignHiReq.isStore := false.B
misalignHiReq.isSigned := reqReg.isSigned
misalignHiReq.isAmo := false.B
misalignHiReq.amoOp := reqReg.amoOp
misalignHiReq.size := 3.U
val amoReadReq = WireDefault(0.U.asTypeOf(new MemRequest(p))) val amoReadReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
amoReadReq.addr := lineAddr(reqReg.addr) + (reqWord << byteBits) amoReadReq.addr := lineAddr(reqReg.addr) + (reqWord << byteBits)
amoReadReq.data := 0.U amoReadReq.data := 0.U
@@ -167,21 +150,16 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
amoWriteReq.size := reqReg.size amoWriteReq.size := reqReg.size
io.reqReady := state === sIdle io.reqReady := state === sIdle
io.memReqValid := state === sMiss || storeBypass || state === sMisalignReadLo || io.memReqValid := state === sMiss || storeBypass || state === sAmoRead ||
state === sMisalignReadHi || state === sAmoRead ||
state === sAmoWrite && scStore state === sAmoWrite && scStore
io.memReq := Mux(storeBypass, io.req, io.memReq := Mux(storeBypass, io.req,
Mux(state === sMisalignReadLo, misalignLoReq, Mux(state === sAmoRead, amoReadReq,
Mux(state === sMisalignReadHi, misalignHiReq, Mux(state === sAmoWrite, amoWriteReq, memReq)))
Mux(state === sAmoRead, amoReadReq,
Mux(state === sAmoWrite, amoWriteReq, memReq)))))
io.respValid := state === sLookup && hit && !reqReg.isStore || io.respValid := state === sLookup && hit && !reqReg.isStore ||
state === sMiss && io.memRespValid && !reqReg.isStore || state === sMiss && io.memRespValid && !reqReg.isStore ||
state === sAmoWrite || state === sMisalignResp state === sAmoWrite
val misalignMerged = (Cat(misalignHi, misalignLo) >> (reqReg.addr(byteBits - 1, 0) << 3))(p.xlen - 1, 0)
io.respData := Mux(state === sAmoWrite, amoOldData, io.respData := Mux(state === sAmoWrite, amoOldData,
Mux(state === sMisalignResp, loadSelect(misalignMerged, 0.U, reqReg.size, reqReg.isSigned), Mux(state === sMiss, loadSelect(io.memRespData, reqReg.addr, reqReg.size, reqReg.isSigned), hitResp))
Mux(state === sMiss, loadSelect(io.memRespData, reqReg.addr, reqReg.size, reqReg.isSigned), hitResp)))
io.miss := state === sLookup && !hit || state === sMiss io.miss := state === sLookup && !hit || state === sMiss
when(storeBypass) { when(storeBypass) {
@@ -211,11 +189,6 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
reqSet := set reqSet := set
reqWord := word reqWord := word
state := sAmoRead state := sAmoRead
}.elsewhen(io.reqValid && !io.req.isStore && crossesWord(io.req.addr, io.req.size)) {
reqReg := io.req
reqSet := set
reqWord := word
state := sMisalignReadLo
}.elsewhen(io.reqValid && !io.req.isStore) { }.elsewhen(io.reqValid && !io.req.isStore) {
reqReg := io.req reqReg := io.req
reqSet := set reqSet := set
@@ -272,17 +245,5 @@ class DCache(p: CoreParams = CoreParams()) extends Module {
}.elsewhen(state === sAmoWrite) { }.elsewhen(state === sAmoWrite) {
scStore := false.B scStore := false.B
state := sIdle state := sIdle
}.elsewhen(state === sMisalignReadLo) {
when(io.memRespValid) {
misalignLo := io.memRespData
state := sMisalignReadHi
}
}.elsewhen(state === sMisalignReadHi) {
when(io.memRespValid) {
misalignHi := io.memRespData
state := sMisalignResp
}
}.elsewhen(state === sMisalignResp) {
state := sIdle
} }
} }

View File

@@ -10,6 +10,7 @@ class DTLB(p: CoreParams = CoreParams()) extends Module {
val req = Input(new TlbReq(p)) val req = Input(new TlbReq(p))
val resp = Output(new TlbResp(p)) val resp = Output(new TlbResp(p))
val refill = Input(new TlbRefill(p)) val refill = Input(new TlbRefill(p))
val flush = Input(Bool())
val missVpn = Output(UInt(vpnBits.W)) val missVpn = Output(UInt(vpnBits.W))
}) })
@@ -22,21 +23,39 @@ class DTLB(p: CoreParams = CoreParams()) extends Module {
val reqVpn = io.req.vaddr(38, 12) val reqVpn = io.req.vaddr(38, 12)
val pageOff = io.req.vaddr(11, 0) val pageOff = io.req.vaddr(11, 0)
val hitVec = VecInit((0 until p.dtlbEntries).map(i => valid(i) && vpn(i) === reqVpn)) val hitVec = VecInit((0 until p.dtlbEntries).map { i =>
val samePage = Mux(level(i) === 2.U, vpn(i)(26, 18) === reqVpn(26, 18),
Mux(level(i) === 1.U, vpn(i)(26, 9) === reqVpn(26, 9), vpn(i) === reqVpn))
valid(i) && samePage
})
val hit = io.req.valid && hitVec.asUInt.orR val hit = io.req.valid && hitVec.asUInt.orR
val hitIdx = OHToUInt(hitVec) val hitIdx = OHToUInt(hitVec)
val hitLevel = level(hitIdx)
val paddrPpn0 = Mux(hitLevel === 0.U, ppn(hitIdx)(8, 0), reqVpn(8, 0))
val paddrPpn1 = Mux(hitLevel <= 1.U, ppn(hitIdx)(17, 9), reqVpn(17, 9))
val paddrPpn2 = ppn(hitIdx)(43, 18)
val r = flags(hitIdx)(1) val r = flags(hitIdx)(1)
val w = flags(hitIdx)(2) val w = flags(hitIdx)(2)
val pageFault = hit && Mux(io.req.isStore, !w, !r) val x = flags(hitIdx)(3)
val u = flags(hitIdx)(4)
val a = flags(hitIdx)(6)
val d = flags(hitIdx)(7)
val sModeToUserFault = io.req.priv === Privileged.PRV_S && u && !io.req.sum
val uModeToSupervisorFault = io.req.priv === Privileged.PRV_U && !u
val readAllowed = r || (io.req.mxr && x)
val accessAllowed = Mux(io.req.isStore, w && d, readAllowed)
val pageFault = hit && (sModeToUserFault || uModeToSupervisorFault || !accessAllowed || !a)
io.resp.hit := hit && !pageFault io.resp.hit := hit && !pageFault
io.resp.miss := io.req.valid && !hit io.resp.miss := io.req.valid && !hit
io.resp.paddr := Cat(ppn(hitIdx), pageOff) io.resp.paddr := Cat(paddrPpn2, paddrPpn1, paddrPpn0, pageOff)
io.resp.pageFault := pageFault io.resp.pageFault := pageFault
io.resp.accessFault := false.B io.resp.accessFault := false.B
io.missVpn := reqVpn io.missVpn := reqVpn
when(io.refill.valid) { when(io.flush) {
valid := VecInit(Seq.fill(p.dtlbEntries)(false.B))
}.elsewhen(io.refill.valid) {
valid(repl) := true.B valid(repl) := true.B
vpn(repl) := io.refill.vpn vpn(repl) := io.refill.vpn
ppn(repl) := io.refill.ppn ppn(repl) := io.refill.ppn

View File

@@ -5,6 +5,10 @@ class LSU(p: CoreParams = CoreParams()) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val reqValid = Input(Bool()) val reqValid = Input(Bool())
val req = Input(new MemRequest(p)) val req = Input(new MemRequest(p))
val checkOnly = Input(Bool())
val sfenceVma = Input(Bool())
val currentPriv = Input(UInt(2.W))
val mstatus = Input(UInt(p.xlen.W))
val reqReady = Output(Bool()) val reqReady = Output(Bool())
val satp = Input(UInt(p.xlen.W)) val satp = Input(UInt(p.xlen.W))
val dmemReqValid = Output(Bool()) val dmemReqValid = Output(Bool())
@@ -14,44 +18,114 @@ class LSU(p: CoreParams = CoreParams()) extends Module {
val respValid = Output(Bool()) val respValid = Output(Bool())
val respData = Output(UInt(p.xlen.W)) val respData = Output(UInt(p.xlen.W))
val pageFault = Output(Bool()) val pageFault = Output(Bool())
val accessFault = Output(Bool())
val misaligned = Output(Bool())
val faultCause = Output(UInt(p.xlen.W))
val faultAddr = Output(UInt(p.xlen.W))
}) })
val dtlb = Module(new DTLB(p)) val dtlb = Module(new DTLB(p))
val mmu = Module(new MMU(p)) val mmu = Module(new MMU(p))
val dcache = Module(new DCache(p)) val dcache = Module(new DCache(p))
val bare = io.satp(63, 60) === 0.U val mprv = io.mstatus(Privileged.MSTATUS_MPRV_BIT)
val mpp = io.mstatus(Privileged.MSTATUS_MPP_HI, Privileged.MSTATUS_MPP_LO)
val effectivePriv = Mux(io.currentPriv === Privileged.PRV_M && mprv, mpp, io.currentPriv)
val pendingValid = RegInit(false.B)
val pendingReq = Reg(new MemRequest(p))
val pendingCheckOnly = Reg(Bool())
val pendingPriv = Reg(UInt(2.W))
val pendingMstatus = Reg(UInt(p.xlen.W))
val pendingSatp = Reg(UInt(p.xlen.W))
dtlb.io.req.valid := io.reqValid && !bare io.reqReady := dcache.io.reqReady && !pendingValid
dtlb.io.req.vaddr := io.req.addr
dtlb.io.req.isStore := io.req.isStore val acceptCurrent = io.reqValid && io.reqReady
val activeValid = pendingValid || acceptCurrent
val activeReq = WireDefault(io.req)
val activeCheckOnly = WireDefault(io.checkOnly)
val activePriv = WireDefault(effectivePriv)
val activeMstatus = WireDefault(io.mstatus)
val activeSatp = WireDefault(io.satp)
when(pendingValid) {
activeReq := pendingReq
activeCheckOnly := pendingCheckOnly
activePriv := pendingPriv
activeMstatus := pendingMstatus
activeSatp := pendingSatp
}
val translate = activeSatp(63, 60) =/= 0.U && activePriv =/= Privileged.PRV_M
dtlb.io.req.valid := activeValid && translate
dtlb.io.req.vaddr := activeReq.addr
dtlb.io.req.isStore := activeReq.isStore
dtlb.io.req.isFetch := false.B dtlb.io.req.isFetch := false.B
dtlb.io.req.priv := activePriv
dtlb.io.req.sum := activeMstatus(Privileged.MSTATUS_SUM_BIT)
dtlb.io.req.mxr := activeMstatus(Privileged.MSTATUS_MXR_BIT)
dtlb.io.flush := io.sfenceVma
mmu.io.satp := io.satp mmu.io.satp := activeSatp
mmu.io.req.valid := io.reqValid && !bare && dtlb.io.resp.miss mmu.io.req.valid := activeValid && translate && dtlb.io.resp.miss
mmu.io.req.vaddr := io.req.addr mmu.io.req.vaddr := activeReq.addr
mmu.io.req.isStore := io.req.isStore mmu.io.req.isStore := activeReq.isStore
mmu.io.req.isFetch := false.B mmu.io.req.isFetch := false.B
mmu.io.req.priv := activePriv
mmu.io.req.sum := activeMstatus(Privileged.MSTATUS_SUM_BIT)
mmu.io.req.mxr := activeMstatus(Privileged.MSTATUS_MXR_BIT)
dtlb.io.refill := mmu.io.refill dtlb.io.refill := mmu.io.refill
val ptwOutstanding = RegInit(false.B) val ptwOutstanding = RegInit(false.B)
when(mmu.io.ptwMemReq.valid) { val ptwReqFire = mmu.io.ptwMemReq.valid && !ptwOutstanding
ptwOutstanding := true.B val ptwRespFire = io.dmemRespValid && (ptwOutstanding || ptwReqFire)
}.elsewhen(io.dmemRespValid && ptwOutstanding) { dontTouch(ptwReqFire)
when(ptwRespFire) {
ptwOutstanding := false.B ptwOutstanding := false.B
}.elsewhen(ptwReqFire) {
ptwOutstanding := true.B
} }
mmu.io.ptwMemResp.valid := io.dmemRespValid && ptwOutstanding mmu.io.ptwMemResp.valid := ptwRespFire
mmu.io.ptwMemResp.data := io.dmemRespData mmu.io.ptwMemResp.data := io.dmemRespData
val translatedAddr = Mux(bare, io.req.addr, dtlb.io.resp.paddr) val translatedAddr = Mux(translate, dtlb.io.resp.paddr, activeReq.addr)
val translationReady = bare || dtlb.io.resp.hit val translationReady = !translate || dtlb.io.resp.hit
val translationFault = dtlb.io.resp.pageFault || mmu.io.resp.pageFault val translationFault = dtlb.io.resp.pageFault || mmu.io.resp.pageFault
io.reqReady := dcache.io.reqReady && !ptwOutstanding val accessFault = dtlb.io.resp.accessFault || mmu.io.resp.accessFault
val accessBytes = MuxLookup(activeReq.size, 8.U(4.W))(Seq(
0.U -> 1.U(4.W),
1.U -> 2.U(4.W),
2.U -> 4.U(4.W),
3.U -> 8.U(4.W)
))
val misaligned = activeValid && (activeReq.addr(2, 0) & (accessBytes - 1.U)) =/= 0.U
val newFault = activeValid && (translationFault || accessFault || misaligned)
val computedFaultCause = Mux(misaligned,
Mux(activeReq.isStore, Privileged.CAUSE_STORE_ADDR_MISALIGNED, Privileged.CAUSE_LOAD_ADDR_MISALIGNED),
Mux(translationFault,
Mux(activeReq.isStore, Privileged.CAUSE_STORE_PAGE_FAULT, Privileged.CAUSE_LOAD_PAGE_FAULT),
Mux(activeReq.isStore, Privileged.CAUSE_STORE_ACCESS_FAULT, Privileged.CAUSE_LOAD_ACCESS_FAULT)))
val checkOnlyDispatch = activeValid && activeCheckOnly && translationReady && !translationFault && !accessFault && !misaligned
val dcacheDispatch = activeValid && !activeCheckOnly && translationReady && !translationFault && !accessFault && !misaligned && dcache.io.reqReady
val storeComplete = dcacheDispatch && activeReq.isStore || checkOnlyDispatch
dontTouch(storeComplete)
val latchPending = acceptCurrent && !dcacheDispatch && !newFault
val clearPending = pendingValid && (dcacheDispatch || checkOnlyDispatch || newFault)
dcache.io.reqValid := io.reqValid && translationReady && !translationFault when(clearPending) {
dcache.io.req := io.req pendingValid := false.B
}.elsewhen(latchPending) {
pendingValid := true.B
pendingReq := io.req
pendingCheckOnly := io.checkOnly
pendingPriv := effectivePriv
pendingMstatus := io.mstatus
pendingSatp := io.satp
}
dcache.io.reqValid := dcacheDispatch
dcache.io.req := activeReq
dcache.io.req.addr := translatedAddr dcache.io.req.addr := translatedAddr
dcache.io.memRespValid := io.dmemRespValid && !ptwOutstanding dcache.io.memRespValid := io.dmemRespValid && !ptwOutstanding && !ptwReqFire
dcache.io.memRespData := io.dmemRespData dcache.io.memRespData := io.dmemRespData
val ptwReqAsMem = WireDefault(0.U.asTypeOf(new MemRequest(p))) val ptwReqAsMem = WireDefault(0.U.asTypeOf(new MemRequest(p)))
@@ -63,9 +137,13 @@ class LSU(p: CoreParams = CoreParams()) extends Module {
ptwReqAsMem.amoOp := 0.U ptwReqAsMem.amoOp := 0.U
ptwReqAsMem.size := 3.U ptwReqAsMem.size := 3.U
io.dmemReqValid := mmu.io.ptwMemReq.valid || dcache.io.memReqValid io.dmemReqValid := ptwReqFire || dcache.io.memReqValid
io.dmemReq := Mux(mmu.io.ptwMemReq.valid, ptwReqAsMem, dcache.io.memReq) io.dmemReq := Mux(ptwReqFire, ptwReqAsMem, dcache.io.memReq)
io.respValid := dcache.io.respValid || translationFault io.respValid := dcache.io.respValid || newFault || storeComplete
io.respData := dcache.io.respData io.respData := dcache.io.respData
io.pageFault := translationFault io.pageFault := translationFault
io.accessFault := accessFault
io.misaligned := misaligned
io.faultCause := computedFaultCause
io.faultAddr := activeReq.addr
} }

View File

@@ -7,6 +7,9 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
val reqVpn = Input(UInt(27.W)) val reqVpn = Input(UInt(27.W))
val isStore = Input(Bool()) val isStore = Input(Bool())
val isFetch = Input(Bool()) val isFetch = Input(Bool())
val priv = Input(UInt(2.W))
val sum = Input(Bool())
val mxr = Input(Bool())
val satp = Input(UInt(p.xlen.W)) val satp = Input(UInt(p.xlen.W))
val memReq = Output(new PtwMemReq(p)) val memReq = Output(new PtwMemReq(p))
val memResp = Input(new PtwMemResp(p)) val memResp = Input(new PtwMemResp(p))
@@ -20,6 +23,9 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
val vpnReg = Reg(UInt(27.W)) val vpnReg = Reg(UInt(27.W))
val isStoreReg = Reg(Bool()) val isStoreReg = Reg(Bool())
val isFetchReg = Reg(Bool()) val isFetchReg = Reg(Bool())
val privReg = Reg(UInt(2.W))
val sumReg = Reg(Bool())
val mxrReg = Reg(Bool())
val rootPpn = io.satp(43, 0) val rootPpn = io.satp(43, 0)
val pte = io.memResp.data val pte = io.memResp.data
val pteV = pte(0) val pteV = pte(0)
@@ -32,17 +38,29 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
val pteD = pte(7) val pteD = pte(7)
val pteFlags = pte(7, 0) val pteFlags = pte(7, 0)
val ptePpn = pte(53, 10) val ptePpn = pte(53, 10)
val level = Wire(UInt(2.W))
level := Mux(state === sL2, 2.U, Mux(state === sL1, 1.U, 0.U))
val pteIsLeaf = pteR || pteX val pteIsLeaf = pteR || pteX
val invalidPte = !pteV || (!pteR && pteW) val invalidPte = !pteV || (!pteR && pteW)
val permFault = Mux(isFetchReg, !pteX, Mux(isStoreReg, !pteW || !pteD, !pteR)) || !pteA val userPage = pteU
val sModeToUserFault = privReg === Privileged.PRV_S && userPage && (isFetchReg || !sumReg)
val uModeToSupervisorFault = privReg === Privileged.PRV_U && !userPage
val privilegeFault = sModeToUserFault || uModeToSupervisorFault
val readAllowed = pteR || (mxrReg && pteX)
val accessAllowed = Mux(isFetchReg, pteX, Mux(isStoreReg, pteW && pteD, readAllowed))
val accessFault = !accessAllowed || !pteA
val superpageMisaligned =
(level === 2.U && ptePpn(17, 0) =/= 0.U) ||
(level === 1.U && ptePpn(8, 0) =/= 0.U)
val permFault = privilegeFault || accessFault || superpageMisaligned
val walkFault = RegInit(false.B) val walkFault = RegInit(false.B)
val nextPpn = Reg(UInt(44.W)) val nextPpn = Reg(UInt(44.W))
val leafFlagsReg = Reg(UInt(8.W))
val leafLevelReg = Reg(UInt(2.W))
def vpnPart(vpn: UInt, level: Int): UInt = def vpnPart(vpn: UInt, level: Int): UInt =
vpn(9 * level + 8, 9 * level) vpn(9 * level + 8, 9 * level)
val level = Wire(UInt(2.W))
level := Mux(state === sL2, 2.U, Mux(state === sL1, 1.U, 0.U))
val curPpn = Reg(UInt(44.W)) val curPpn = Reg(UInt(44.W))
val pteAddr = Cat(curPpn, vpnPart(vpnReg, 0), 0.U(3.W)) val pteAddr = Cat(curPpn, vpnPart(vpnReg, 0), 0.U(3.W))
val pteAddrL1 = Cat(curPpn, vpnPart(vpnReg, 1), 0.U(3.W)) val pteAddrL1 = Cat(curPpn, vpnPart(vpnReg, 1), 0.U(3.W))
@@ -54,8 +72,8 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
io.pageFault := walkFault io.pageFault := walkFault
io.refill.valid := state === sDone && !walkFault io.refill.valid := state === sDone && !walkFault
io.refill.vpn := vpnReg io.refill.vpn := vpnReg
io.refill.level := level io.refill.level := leafLevelReg
io.refill.flags := pteFlags io.refill.flags := leafFlagsReg
io.refill.ppn := nextPpn io.refill.ppn := nextPpn
when(state === sIdle) { when(state === sIdle) {
@@ -64,6 +82,9 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
vpnReg := io.reqVpn vpnReg := io.reqVpn
isStoreReg := io.isStore isStoreReg := io.isStore
isFetchReg := io.isFetch isFetchReg := io.isFetch
privReg := io.priv
sumReg := io.sum
mxrReg := io.mxr
state := sL2 state := sL2
} }
}.elsewhen((state === sL2 || state === sL1 || state === sL0) && io.memResp.valid) { }.elsewhen((state === sL2 || state === sL1 || state === sL0) && io.memResp.valid) {
@@ -78,6 +99,8 @@ class PageTableWalker(p: CoreParams = CoreParams()) extends Module {
val ppn1 = Mux(level <= 1.U, ptePpn(17, 9), vpnReg(17, 9)) val ppn1 = Mux(level <= 1.U, ptePpn(17, 9), vpnReg(17, 9))
val ppn2 = ptePpn(43, 18) val ppn2 = ptePpn(43, 18)
nextPpn := Cat(ppn2, ppn1, ppn0) nextPpn := Cat(ppn2, ppn1, ppn0)
leafFlagsReg := pteFlags
leafLevelReg := level
state := sDone state := sDone
}.otherwise { }.otherwise {
curPpn := ptePpn curPpn := ptePpn
@@ -111,6 +134,9 @@ class MMU(p: CoreParams = CoreParams()) extends Module {
walker.io.reqVpn := io.req.vaddr(38, 12) walker.io.reqVpn := io.req.vaddr(38, 12)
walker.io.isStore := io.req.isStore walker.io.isStore := io.req.isStore
walker.io.isFetch := io.req.isFetch walker.io.isFetch := io.req.isFetch
walker.io.priv := io.req.priv
walker.io.sum := io.req.sum
walker.io.mxr := io.req.mxr
walker.io.satp := io.satp walker.io.satp := io.satp
walker.io.memResp := io.ptwMemResp walker.io.memResp := io.ptwMemResp

View File

@@ -5,6 +5,8 @@ class MemStage(p: CoreParams = CoreParams()) extends Module {
val reqValid = Input(Bool()) val reqValid = Input(Bool())
val req = Input(new MemRequest(p)) val req = Input(new MemRequest(p))
val satp = Input(UInt(p.xlen.W)) val satp = Input(UInt(p.xlen.W))
val currentPriv = Input(UInt(2.W))
val mstatus = Input(UInt(p.xlen.W))
val dmemReqValid = Output(Bool()) val dmemReqValid = Output(Bool())
val dmemReq = Output(new MemRequest(p)) val dmemReq = Output(new MemRequest(p))
val dmemRespValid = Input(Bool()) val dmemRespValid = Input(Bool())
@@ -17,6 +19,10 @@ class MemStage(p: CoreParams = CoreParams()) extends Module {
val lsu = Module(new LSU(p)) val lsu = Module(new LSU(p))
lsu.io.reqValid := io.reqValid lsu.io.reqValid := io.reqValid
lsu.io.req := io.req lsu.io.req := io.req
lsu.io.checkOnly := false.B
lsu.io.sfenceVma := false.B
lsu.io.currentPriv := io.currentPriv
lsu.io.mstatus := io.mstatus
lsu.io.satp := io.satp lsu.io.satp := io.satp
lsu.io.dmemRespValid := io.dmemRespValid lsu.io.dmemRespValid := io.dmemRespValid
lsu.io.dmemRespData := io.dmemRespData lsu.io.dmemRespData := io.dmemRespData

View File

@@ -30,6 +30,7 @@ class StoreQueue(p: CoreParams = CoreParams()) extends Module {
val commitRobIdx = Input(UInt(robBits.W)) val commitRobIdx = Input(UInt(robBits.W))
val drainValid = Output(Bool()) val drainValid = Output(Bool())
val drain = Output(new MemRequest(p)) val drain = Output(new MemRequest(p))
val drainRobIdx = Output(UInt(robBits.W))
val drainReady = Input(Bool()) val drainReady = Input(Bool())
val flush = Input(Bool()) val flush = Input(Bool())
}) })
@@ -140,6 +141,7 @@ class StoreQueue(p: CoreParams = CoreParams()) extends Module {
io.drain.isAmo := false.B io.drain.isAmo := false.B
io.drain.amoOp := 0.U io.drain.amoOp := 0.U
io.drain.size := entries(drainIdx).size io.drain.size := entries(drainIdx).size
io.drainRobIdx := entries(drainIdx).robIdx
when(io.flush) { when(io.flush) {
entries.foreach(_ := 0.U.asTypeOf(new StoreQueueEntry(p))) entries.foreach(_ := 0.U.asTypeOf(new StoreQueueEntry(p)))

View File

@@ -22,6 +22,9 @@ class RobEntry(p: CoreParams = CoreParams()) extends Bundle {
val csrRs1 = UInt(p.xlen.W) val csrRs1 = UInt(p.xlen.W)
val csrZimm = UInt(5.W) val csrZimm = UInt(5.W)
val fenceI = Bool() val fenceI = Bool()
val sfenceVma = Bool()
val xret = Bool()
val xretIsMret = Bool()
} }
class ROB(p: CoreParams = CoreParams()) extends Module { class ROB(p: CoreParams = CoreParams()) extends Module {
@@ -43,6 +46,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W))) val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W)))
val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W))) val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W))) val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W)))
val completeFenceI = Input(Vec(p.issueWidth, Bool()))
val completeSfenceVma = Input(Vec(p.issueWidth, Bool()))
val completeXret = Input(Vec(p.issueWidth, Bool()))
val completeXretIsMret = Input(Vec(p.issueWidth, Bool()))
val commitValid = Output(Vec(p.issueWidth, Bool())) val commitValid = Output(Vec(p.issueWidth, Bool()))
val commit = Output(Vec(p.issueWidth, new RobEntry(p))) val commit = Output(Vec(p.issueWidth, new RobEntry(p)))
val commitReady = Input(Vec(p.issueWidth, Bool())) val commitReady = Input(Vec(p.issueWidth, Bool()))
@@ -63,6 +70,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
val csrCmd = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(3.W)))) val csrCmd = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(3.W))))
val csrRs1 = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W)))) val csrRs1 = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W))))
val csrZimm = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(5.W)))) val csrZimm = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(5.W))))
val fenceI = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
val sfenceVma = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
val xret = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
val xretIsMret = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
val head = RegInit(0.U(idxBits.W)) val head = RegInit(0.U(idxBits.W))
val tail = RegInit(0.U(idxBits.W)) val tail = RegInit(0.U(idxBits.W))
val count = RegInit(0.U(log2Ceil(p.robEntries + 1).W)) val count = RegInit(0.U(log2Ceil(p.robEntries + 1).W))
@@ -87,6 +98,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
headEntry0.csrCmd := csrCmd(head0) headEntry0.csrCmd := csrCmd(head0)
headEntry0.csrRs1 := csrRs1(head0) headEntry0.csrRs1 := csrRs1(head0)
headEntry0.csrZimm := csrZimm(head0) headEntry0.csrZimm := csrZimm(head0)
headEntry0.fenceI := fenceI(head0)
headEntry0.sfenceVma := sfenceVma(head0)
headEntry0.xret := xret(head0)
headEntry0.xretIsMret := xretIsMret(head0)
headEntry1 := entries(head1) headEntry1 := entries(head1)
headEntry1.valid := valid(head1) headEntry1.valid := valid(head1)
headEntry1.completed := completed(head1) headEntry1.completed := completed(head1)
@@ -100,6 +115,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
headEntry1.csrCmd := csrCmd(head1) headEntry1.csrCmd := csrCmd(head1)
headEntry1.csrRs1 := csrRs1(head1) headEntry1.csrRs1 := csrRs1(head1)
headEntry1.csrZimm := csrZimm(head1) headEntry1.csrZimm := csrZimm(head1)
headEntry1.fenceI := fenceI(head1)
headEntry1.sfenceVma := sfenceVma(head1)
headEntry1.xret := xret(head1)
headEntry1.xretIsMret := xretIsMret(head1)
io.empty := count === 0.U io.empty := count === 0.U
io.canAllocate := (p.robEntries.U - count) >= p.issueWidth.U io.canAllocate := (p.robEntries.U - count) >= p.issueWidth.U
@@ -117,6 +136,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
exception := VecInit(Seq.fill(p.robEntries)(false.B)) exception := VecInit(Seq.fill(p.robEntries)(false.B))
branchMispredict := VecInit(Seq.fill(p.robEntries)(false.B)) branchMispredict := VecInit(Seq.fill(p.robEntries)(false.B))
csrValid := VecInit(Seq.fill(p.robEntries)(false.B)) csrValid := VecInit(Seq.fill(p.robEntries)(false.B))
fenceI := VecInit(Seq.fill(p.robEntries)(false.B))
sfenceVma := VecInit(Seq.fill(p.robEntries)(false.B))
xret := VecInit(Seq.fill(p.robEntries)(false.B))
xretIsMret := VecInit(Seq.fill(p.robEntries)(false.B))
head := 0.U head := 0.U
tail := 0.U tail := 0.U
count := 0.U count := 0.U
@@ -136,6 +159,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
csrCmd(tail0) := 0.U csrCmd(tail0) := 0.U
csrRs1(tail0) := 0.U csrRs1(tail0) := 0.U
csrZimm(tail0) := 0.U csrZimm(tail0) := 0.U
fenceI(tail0) := io.allocateEntry(0).fenceI
sfenceVma(tail0) := io.allocateEntry(0).sfenceVma
xret(tail0) := io.allocateEntry(0).xret
xretIsMret(tail0) := io.allocateEntry(0).xretIsMret
} }
when(io.allocateValid(1) && io.canAllocate) { when(io.allocateValid(1) && io.canAllocate) {
entries(tail1) := io.allocateEntry(1) entries(tail1) := io.allocateEntry(1)
@@ -152,6 +179,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
csrCmd(tail1) := 0.U csrCmd(tail1) := 0.U
csrRs1(tail1) := 0.U csrRs1(tail1) := 0.U
csrZimm(tail1) := 0.U csrZimm(tail1) := 0.U
fenceI(tail1) := io.allocateEntry(1).fenceI
sfenceVma(tail1) := io.allocateEntry(1).sfenceVma
xret(tail1) := io.allocateEntry(1).xret
xretIsMret(tail1) := io.allocateEntry(1).xretIsMret
} }
for (i <- 0 until p.issueWidth) { for (i <- 0 until p.issueWidth) {
when(io.completeValid(i)) { when(io.completeValid(i)) {
@@ -166,6 +197,10 @@ class ROB(p: CoreParams = CoreParams()) extends Module {
csrCmd(io.completeIdx(i)) := io.completeCsrCmd(i) csrCmd(io.completeIdx(i)) := io.completeCsrCmd(i)
csrRs1(io.completeIdx(i)) := io.completeCsrRs1(i) csrRs1(io.completeIdx(i)) := io.completeCsrRs1(i)
csrZimm(io.completeIdx(i)) := io.completeCsrZimm(i) csrZimm(io.completeIdx(i)) := io.completeCsrZimm(i)
fenceI(io.completeIdx(i)) := io.completeFenceI(i)
sfenceVma(io.completeIdx(i)) := io.completeSfenceVma(i)
xret(io.completeIdx(i)) := io.completeXret(i)
xretIsMret(io.completeIdx(i)) := io.completeXretIsMret(i)
} }
} }
val commit0 = io.commitValid(0) && io.commitReady(0) val commit0 = io.commitValid(0) && io.commitReady(0)

View File

@@ -27,6 +27,10 @@ class RenameStage(p: CoreParams = CoreParams()) extends Module {
val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W))) val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W)))
val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W))) val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W))) val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W)))
val completeFenceI = Input(Vec(p.issueWidth, Bool()))
val completeSfenceVma = Input(Vec(p.issueWidth, Bool()))
val completeXret = Input(Vec(p.issueWidth, Bool()))
val completeXretIsMret = Input(Vec(p.issueWidth, Bool()))
val commitReady = Input(Vec(p.issueWidth, Bool())) val commitReady = Input(Vec(p.issueWidth, Bool()))
val commitValid = Output(Vec(p.issueWidth, Bool())) val commitValid = Output(Vec(p.issueWidth, Bool()))
@@ -96,6 +100,9 @@ class RenameStage(p: CoreParams = CoreParams()) extends Module {
e.dest := Mux(io.in(i).writesRd, freeList.io.allocPhys(i), table.io.oldPrd(i)) e.dest := Mux(io.in(i).writesRd, freeList.io.allocPhys(i), table.io.oldPrd(i))
e.oldDest := table.io.oldPrd(i) e.oldDest := table.io.oldPrd(i)
e.fenceI := io.in(i).isFenceI e.fenceI := io.in(i).isFenceI
e.sfenceVma := io.in(i).isSfenceVma
e.xret := io.in(i).isXret
e.xretIsMret := io.in(i).isMret
rob.io.allocateEntry(i) := e rob.io.allocateEntry(i) := e
} }
rob.io.completeValid := io.completeValid rob.io.completeValid := io.completeValid
@@ -110,6 +117,10 @@ class RenameStage(p: CoreParams = CoreParams()) extends Module {
rob.io.completeCsrCmd := io.completeCsrCmd rob.io.completeCsrCmd := io.completeCsrCmd
rob.io.completeCsrRs1 := io.completeCsrRs1 rob.io.completeCsrRs1 := io.completeCsrRs1
rob.io.completeCsrZimm := io.completeCsrZimm rob.io.completeCsrZimm := io.completeCsrZimm
rob.io.completeFenceI := io.completeFenceI
rob.io.completeSfenceVma := io.completeSfenceVma
rob.io.completeXret := io.completeXret
rob.io.completeXretIsMret := io.completeXretIsMret
rob.io.commitReady := io.commitReady rob.io.commitReady := io.commitReady
rob.io.flush := io.flush rob.io.flush := io.flush
io.commitValid := rob.io.commitValid io.commitValid := rob.io.commitValid

View File

@@ -0,0 +1,50 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class CommitPrivilegeSpec extends AnyFlatSpec with Matchers {
"Commit" should "emit redirect, trap, and xRET ports" in {
class Harness extends Module {
val io = IO(new Bundle {
val redirectPc = Output(UInt(64.W))
val xret = Output(Bool())
})
val dut = Module(new CommitStage())
dut.io.robValid := VecInit(Seq.fill(2)(false.B))
dut.io.robEntry := VecInit(Seq.fill(2)(0.U.asTypeOf(new RobEntry())))
io.redirectPc := dut.io.redirectPc
io.xret := dut.io.xret
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_redirectPc")
verilog should include("io_xret")
}
it should "not commit destination mappings for excepting instructions" in {
class Harness extends Module {
val io = IO(new Bundle {
val commitReady = Output(Bool())
val commitMapValid = Output(Bool())
})
val dut = Module(new CommitStage())
val entry = WireDefault(0.U.asTypeOf(new RobEntry()))
entry.valid := true.B
entry.completed := true.B
entry.exception := true.B
entry.writesDest := true.B
entry.archDest := 10.U
entry.dest := 33.U
dut.io.robValid := VecInit(Seq(true.B, false.B))
dut.io.robEntry := VecInit(Seq(entry, 0.U.asTypeOf(new RobEntry())))
io.commitReady := dut.io.commitReady(0)
io.commitMapValid := dut.io.commitMapValid(0)
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("assign io_commitReady = 1'h1;")
verilog should include("assign io_commitMapValid = 1'h0;")
}
}

View File

@@ -0,0 +1,24 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class RobCommitMetaSpec extends AnyFlatSpec with Matchers {
"ROB and CommitStage" should "emit privilege metadata IO" in {
class Harness extends Module {
val io = IO(new Bundle {
val flush = Output(Bool())
val sfence = Output(Bool())
})
val dut = Module(new CommitStage())
dut.io.robValid := VecInit(Seq.fill(2)(false.B))
dut.io.robEntry := VecInit(Seq.fill(2)(0.U.asTypeOf(new RobEntry())))
io.flush := dut.io.flush
io.sfence := dut.io.sfenceVma
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_flush")
verilog should include("io_sfence")
}
}

View File

@@ -0,0 +1,28 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class BundlesSpec extends AnyFlatSpec with Matchers {
"TrapInfo" should "emit the expected trap fields" in {
class Harness extends Module {
val io = IO(new Bundle {
val cause = Output(UInt(64.W))
val originPriv = Output(UInt(2.W))
})
val trap = Wire(new TrapInfo())
trap.valid := true.B
trap.isInterrupt := false.B
trap.cause := Privileged.CAUSE_ILLEGAL_INSTRUCTION
trap.tval := 0.U
trap.epc := 0.U
trap.originPriv := Privileged.PRV_M
io.cause := trap.cause
io.originPriv := trap.originPriv
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_cause")
verilog should include("io_originPriv")
}
}

View File

@@ -0,0 +1,27 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class PrivilegedSpec extends AnyFlatSpec with Matchers {
"privilege encodings" should "match RV64 spec" in {
Privileged.PRV_U.litValue should be(0)
Privileged.PRV_S.litValue should be(1)
Privileged.PRV_M.litValue should be(3)
}
"ecall causes" should "match U/S/M encodings" in {
Privileged.CAUSE_ECALL_FROM_U.litValue should be(8)
Privileged.CAUSE_ECALL_FROM_S.litValue should be(9)
Privileged.CAUSE_ECALL_FROM_M.litValue should be(11)
}
"misa" should "only advertise implemented base extensions" in {
val misa = Privileged.MISA_RV64_IMASU.litValue
val fBit = BigInt(1) << ('F' - 'A')
val dBit = BigInt(1) << ('D' - 'A')
val cBit = BigInt(1) << ('C' - 'A')
(misa & fBit) should be(0)
(misa & dBit) should be(0)
(misa & cBit) should be(0)
}
}

View File

@@ -0,0 +1,86 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class CSRFileSpec extends AnyFlatSpec with Matchers {
private def driveDefaults(dut: CSRFile): Unit = {
dut.io.cmd.valid := false.B
dut.io.cmd.addr := 0.U
dut.io.cmd.cmd := 0.U
dut.io.cmd.rs1 := 0.U
dut.io.cmd.zimm := 0.U
dut.io.currentPriv := Privileged.PRV_M
dut.io.trap := false.B
dut.io.trapPc := 0.U
dut.io.trapCause := 0.U
dut.io.trapTval := 0.U
dut.io.trapTargetPriv := Privileged.PRV_M
dut.io.trapIsInterrupt := false.B
dut.io.xret := false.B
dut.io.xretIsMret := true.B
}
"CSRFile" should "expose permission and trap-aware ports" in {
class Harness extends Module {
val io = IO(new Bundle {
val rdata = Output(UInt(64.W))
val illegal = Output(Bool())
})
val dut = Module(new CSRFile())
driveDefaults(dut)
dut.io.readAddr := Privileged.CSR_MSTATUS
dut.io.currentPriv := Privileged.PRV_U
io.rdata := dut.io.rdata
io.illegal := dut.io.illegal
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_rdata")
verilog should include("io_illegal")
}
it should "read RV64 xlen fields as SXL=2 and UXL=2" in {
class Harness extends Module {
val io = IO(new Bundle {
val rdata = Output(UInt(64.W))
})
val dut = Module(new CSRFile())
driveDefaults(dut)
dut.io.readAddr := Privileged.CSR_MSTATUS
io.rdata := dut.io.rdata
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("64'hA00000000")
}
it should "emit machine counter and ID CSR decode semantics" in {
class Harness extends Module {
val io = IO(new Bundle {
val readAddr = Input(UInt(12.W))
val writeAddr = Input(UInt(12.W))
val writeData = Input(UInt(64.W))
val rdata = Output(UInt(64.W))
})
val dut = Module(new CSRFile())
driveDefaults(dut)
dut.io.cmd.valid := true.B
dut.io.cmd.addr := io.writeAddr
dut.io.cmd.cmd := 1.U
dut.io.cmd.rs1 := io.writeData
dut.io.readAddr := io.readAddr
io.rdata := dut.io.rdata
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("mcountinhibit")
verilog should include("suppressInstretIncrement")
verilog should include("12'h320")
verilog should include("12'hB02")
verilog should include("12'hF11")
verilog should include("12'hF12")
verilog should include("12'hF13")
verilog should include("12'hF14")
}
}

View File

@@ -0,0 +1,71 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class CSRPermissionSpec extends AnyFlatSpec with Matchers {
"readAllowed" should "allow U-read of user counters and deny M-only CSRs" in {
CSRPermission.readAllowedLit(Privileged.CSR_CYCLE.litValue, Privileged.PRV_U.litValue) should be(true)
CSRPermission.readAllowedLit(Privileged.CSR_MSTATUS.litValue, Privileged.PRV_U.litValue) should be(false)
}
"writeAllowed" should "block read-only and privilege-incompatible CSRs" in {
CSRPermission.writeAllowedLit(Privileged.CSR_MTVEC.litValue, Privileged.PRV_S.litValue) should be(false)
CSRPermission.writeAllowedLit(Privileged.CSR_SATP.litValue, Privileged.PRV_U.litValue) should be(false)
CSRPermission.writeAllowedLit(Privileged.CSR_SATP.litValue, Privileged.PRV_S.litValue) should be(true)
}
it should "allow machine-mode WARL writes to misa" in {
CSRPermission.writeAllowedLit(Privileged.CSR_MISA.litValue, Privileged.PRV_M.litValue) should be(true)
}
"CSR permissions" should "reject writes to read-only counters" in {
CSRPermission.writeAllowedLit(Privileged.CSR_CYCLE.litValue, Privileged.PRV_M.litValue) should be(false)
CSRPermission.readAllowedLit(Privileged.CSR_CYCLE.litValue, Privileged.PRV_M.litValue) should be(true)
}
it should "reject machine CSRs below M mode" in {
CSRPermission.readAllowedLit(Privileged.CSR_MSTATUS.litValue, Privileged.PRV_S.litValue) should be(false)
CSRPermission.writeAllowedLit(Privileged.CSR_MSTATUS.litValue, Privileged.PRV_S.litValue) should be(false)
}
it should "allow machine-mode access to debug trigger and PMP CSRs used by privileged tests" in {
val machineWritable = Seq(
Privileged.CSR_TSELECT,
Privileged.CSR_TDATA1,
Privileged.CSR_TDATA2,
Privileged.CSR_TCONTROL,
Privileged.CSR_PMPADDR0,
Privileged.CSR_PMPCFG0,
Privileged.CSR_MNSTATUS)
machineWritable.foreach { csr =>
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_S.litValue) should be(false)
}
}
it should "allow machine-mode reads of machine ID CSRs only and reject writes" in {
val machineIds = Seq(
Privileged.CSR_MVENDORID,
Privileged.CSR_MARCHID,
Privileged.CSR_MIMPID,
Privileged.CSR_MHARTID)
machineIds.foreach { csr =>
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(false)
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_S.litValue) should be(false)
}
}
it should "allow machine-mode reads and writes to minstret and mcountinhibit" in {
val machineCounters = Seq(
Privileged.CSR_MINSTRET,
Privileged.CSR_MCOUNTINHIBIT)
machineCounters.foreach { csr =>
CSRPermission.readAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
CSRPermission.writeAllowedLit(csr.litValue, Privileged.PRV_M.litValue) should be(true)
}
}
}

View File

@@ -0,0 +1,19 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class PrivilegeControlSpec extends AnyFlatSpec with Matchers {
"PrivilegeControl" should "expose current privilege and set interface" in {
class Harness extends Module {
val io = IO(new Bundle { val priv = Output(UInt(2.W)) })
val dut = Module(new PrivilegeControl())
dut.io.nextPriv := Privileged.PRV_M
dut.io.setPriv := false.B
io.priv := dut.io.priv
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_priv")
}
}

View File

@@ -0,0 +1,46 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import _root_.circt.stage.ChiselStage
class PrivilegeTransitionSpec extends AnyFlatSpec with Matchers {
"trap target privilege" should "honor exception delegation only below M-mode" in {
val uEcallBit = BigInt(1) << Privileged.CAUSE_ECALL_FROM_U.litValue.toInt
PrivilegeTransitions.trapTargetPrivLit(
currentPriv = Privileged.PRV_U.litValue,
cause = Privileged.CAUSE_ECALL_FROM_U.litValue,
isInterrupt = false,
medeleg = uEcallBit,
mideleg = 0) should be(Privileged.PRV_S.litValue)
PrivilegeTransitions.trapTargetPrivLit(
currentPriv = Privileged.PRV_M.litValue,
cause = Privileged.CAUSE_ECALL_FROM_M.litValue,
isInterrupt = false,
medeleg = BigInt(1) << Privileged.CAUSE_ECALL_FROM_M.litValue.toInt,
mideleg = 0) should be(Privileged.PRV_M.litValue)
}
"xRET target privilege" should "recover MPP and SPP fields" in {
val mstatusMppS = BigInt(1) << 11
val sstatusSpp = BigInt(1) << 8
PrivilegeTransitions.mretNextPrivLit(mstatusMppS) should be(Privileged.PRV_S.litValue)
PrivilegeTransitions.sretNextPrivLit(sstatusSpp) should be(Privileged.PRV_S.litValue)
PrivilegeTransitions.sretNextPrivLit(0) should be(Privileged.PRV_U.litValue)
}
"xRET target pc selection" should "use mepc for mret and sepc for sret" in {
PrivilegeTransitions.xretTargetPcLit(isMret = true, mepc = 0x1000, sepc = 0x2000) should be(0x1000)
PrivilegeTransitions.xretTargetPcLit(isMret = false, mepc = 0x1000, sepc = 0x2000) should be(0x2000)
}
it should "select xRET redirect pc from commit-time CSR state" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("xretRedirectPc")
verilog should include("io_redirectPc")
}
it should "serialize CSR and privileged side-effect instructions at the ROB head" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("serializingReady0")
verilog should include("serializingReady1")
}
}

View File

@@ -0,0 +1,30 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class DecoderPrivFlagSpec extends AnyFlatSpec with Matchers {
"Decoder" should "emit privileged instruction flags" in {
class Harness extends Module {
val io = IO(new Bundle {
val ecall = Output(Bool())
val sfence = Output(Bool())
val fenceI = Output(Bool())
val wfi = Output(Bool())
})
val dut = Module(new Decoder())
dut.io.pc := 0.U
dut.io.inst := "h10500073".U
io.ecall := dut.io.out.isEcall
io.sfence := dut.io.out.isSfenceVma
io.fenceI := dut.io.out.isFenceI
io.wfi := dut.io.out.isWfi
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_ecall")
verilog should include("io_sfence")
verilog should include("io_fenceI")
verilog should include("io_wfi")
}
}

View File

@@ -0,0 +1,10 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class EcallCauseSpec extends AnyFlatSpec with Matchers {
"ECALL cause" should "depend on current privilege" in {
ExceptionSource.ecallCauseLit(Privileged.PRV_U.litValue) should be(Privileged.CAUSE_ECALL_FROM_U.litValue)
ExceptionSource.ecallCauseLit(Privileged.PRV_S.litValue) should be(Privileged.CAUSE_ECALL_FROM_S.litValue)
ExceptionSource.ecallCauseLit(Privileged.PRV_M.litValue) should be(Privileged.CAUSE_ECALL_FROM_M.litValue)
}
}

View File

@@ -0,0 +1,11 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class ExceptionPrioritySpec extends AnyFlatSpec with Matchers {
"priority ranking" should "prefer instruction faults before illegal and ecall" in {
ExceptionSource.priorityOf(Privileged.CAUSE_INSTR_PAGE_FAULT) should be(0)
ExceptionSource.priorityOf(Privileged.CAUSE_INSTR_ACCESS_FAULT) should be(1)
ExceptionSource.priorityOf(Privileged.CAUSE_ILLEGAL_INSTRUCTION) should be(2)
ExceptionSource.priorityOf(Privileged.CAUSE_ECALL_FROM_U) should be(5)
}
}

View File

@@ -0,0 +1,44 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class IllegalInstructionSpec extends AnyFlatSpec with Matchers {
"Decoder" should "emit illegal and privileged instruction fields" in {
class Harness extends Module {
val io = IO(new Bundle {
val illegal = Output(Bool())
val isMret = Output(Bool())
val isEcall = Output(Bool())
})
val dut = Module(new Decoder())
dut.io.pc := 0.U
dut.io.inst := "h30200073".U
io.illegal := dut.io.out.illegal
io.isMret := dut.io.out.isMret
io.isEcall := dut.io.out.isEcall
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_isMret")
verilog should include("io_isEcall")
}
"OoOBackend" should "gate writeback when an issued instruction raises an exception" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("issueRaisesException")
verilog should include("loadRespHasFault")
}
it should "report illegal instruction bits in trap tval instead of the pc" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("decoded_inst")
verilog should not include(": _issue_io_out_0_decoded_pc")
verilog should not include(": _issue_io_out_1_decoded_pc")
}
it should "raise instruction-address-misaligned on control-transfer targets" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("controlTargetMisaligned")
}
}

View File

@@ -0,0 +1,26 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class ClintSpec extends AnyFlatSpec with Matchers {
"Clint" should "emit timer and software interrupt outputs" in {
class Harness extends Module {
val io = IO(new Bundle {
val msip = Output(Bool())
val mtip = Output(Bool())
})
val dut = Module(new Clint())
dut.io.addr := 0.U
dut.io.wen := false.B
dut.io.wdata := 0.U
dut.io.ren := false.B
io.msip := dut.io.mipMSIP
io.mtip := dut.io.mipMTIP
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_msip")
verilog should include("io_mtip")
}
}

View File

@@ -0,0 +1,14 @@
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class InterruptControllerSpec extends AnyFlatSpec with Matchers {
"InterruptController" should "prefer MEI over MTI over MSI and honor delegation" in {
InterruptController.highestMachineCauseLit(msip = true, mtip = true, meip = true) should be(
Privileged.CAUSE_MACHINE_EXTERNAL_INTERRUPT.litValue)
InterruptController.highestMachineCauseLit(msip = true, mtip = true, meip = false) should be(
Privileged.CAUSE_MACHINE_TIMER_INTERRUPT.litValue)
InterruptController.delegatesToSupervisorLit(
cause = Privileged.CAUSE_SUPERVISOR_TIMER_INTERRUPT.litValue,
mideleg = BigInt(1) << Privileged.CAUSE_SUPERVISOR_TIMER_INTERRUPT.litValue.toInt) should be(true)
}
}

View File

@@ -0,0 +1,19 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class PlicSpec extends AnyFlatSpec with Matchers {
"Plic" should "emit external interrupt output" in {
class Harness extends Module {
val io = IO(new Bundle { val meip = Output(Bool()) })
val dut = Module(new Plic())
dut.io.externalPending := true.B
dut.io.enable := true.B
io.meip := dut.io.mipMEIP
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_meip")
}
}

View File

@@ -0,0 +1,94 @@
import chisel3._
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class Sv39Spec extends AnyFlatSpec with Matchers {
private def occurrences(haystack: String, needle: String): Int =
haystack.sliding(needle.length).count(_ == needle)
"MMU" should "emit Sv39 response and refill fields" in {
class Harness extends Module {
val io = IO(new Bundle {
val pageFault = Output(Bool())
val paddr = Output(UInt(64.W))
})
val dut = Module(new MMU())
dut.io.satp := 0.U
dut.io.req.valid := false.B
dut.io.req.vaddr := 0.U
dut.io.req.isStore := false.B
dut.io.req.isFetch := false.B
dut.io.req.priv := Privileged.PRV_M
dut.io.req.sum := false.B
dut.io.req.mxr := false.B
dut.io.ptwMemResp.valid := false.B
dut.io.ptwMemResp.data := 0.U
io.pageFault := dut.io.resp.pageFault
io.paddr := dut.io.resp.paddr
}
val verilog = ChiselStage.emitSystemVerilog(new Harness)
verilog should include("io_pageFault")
verilog should include("io_paddr")
}
it should "emit registered refill metadata" in {
val verilog = ChiselStage.emitSystemVerilog(new MMU())
verilog should include("leafFlagsReg")
verilog should include("leafLevelReg")
}
"DTLB" should "emit data permission controls for cached hits" in {
val verilog = ChiselStage.emitSystemVerilog(new DTLB())
occurrences(verilog, "io_req_priv") should be > 1
occurrences(verilog, "io_req_sum") should be > 1
occurrences(verilog, "io_req_mxr") should be > 1
}
"LSU" should "emit effective privilege controls for data translation" in {
val verilog = ChiselStage.emitSystemVerilog(new LSU())
verilog should include("io_currentPriv")
verilog should include("io_mstatus")
verilog should include("io_mstatus[17]")
}
"Frontend" should "emit instruction-side Sv39 translation controls" in {
val verilog = ChiselStage.emitSystemVerilog(new Frontend())
verilog should include("io_satp")
verilog should include("io_currentPriv")
verilog should include("io_ptwMemReqValid")
verilog should include("io_ptwMemReqAddr")
verilog should include("io_ptwMemRespValid")
verilog should include("io_ptwMemRespData")
verilog should include("fetchTranslate")
verilog should include("immu")
verilog should include("itlbMiss")
verilog should include("translationReady")
verilog should include("translatedFetchAddr")
}
it should "emit pending request replay state for DTLB misses" in {
val verilog = ChiselStage.emitSystemVerilog(new LSU())
verilog should include("pendingValid")
verilog should include("pendingReq_addr")
verilog should include("pendingPriv")
verilog should include("pendingMstatus")
verilog should include("ptwReqFire")
verilog should include("storeComplete")
verilog should not include("faultValid")
}
"OoOBackend" should "complete stores from LSU drain responses" in {
val verilog = ChiselStage.emitSystemVerilog(new OoOBackend())
verilog should include("storeCheckPending")
verilog should include("storeCheckPendingRob")
verilog should include("storeCheckResp")
}
"MemStage" should "expose LSU privilege controls" in {
val verilog = ChiselStage.emitSystemVerilog(new MemStage())
verilog should include("io_currentPriv")
verilog should include("io_mstatus")
}
}