Skip to content

Commit

Permalink
Add supprot for Zba, Zbb and Zbc (#28)
Browse files Browse the repository at this point in the history
* test: add test cases for zba zbb zbc.

* feat: add support for Zba, Zbb and Zbc.

* fix: remove redundant comments.
  • Loading branch information
SeddonShen authored Nov 4, 2024
1 parent d826f38 commit 12b8663
Show file tree
Hide file tree
Showing 126 changed files with 92,510 additions and 78 deletions.
75 changes: 29 additions & 46 deletions src/main/scala/rvspeccore/checker/Checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,20 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false

if (checkMem) {
if (!config.functions.tlb) {
assert(io.mem.get.read.valid === specCore.io.mem.read.valid)
when(io.mem.get.read.valid || specCore.io.mem.read.valid) {
assert(io.mem.get.read.addr === specCore.io.mem.read.addr)
assert(io.mem.get.read.memWidth === specCore.io.mem.read.memWidth)
assert(regDelay(io.mem.get.read.valid) === regDelay(specCore.io.mem.read.valid))
when(regDelay(io.mem.get.read.valid || specCore.io.mem.read.valid)) {
assert(regDelay(io.mem.get.read.addr) === regDelay(specCore.io.mem.read.addr))
assert(regDelay(io.mem.get.read.memWidth) === regDelay(specCore.io.mem.read.memWidth))
}
assert(io.mem.get.write.valid === specCore.io.mem.write.valid)
when(io.mem.get.write.valid || specCore.io.mem.write.valid) {
assert(io.mem.get.write.addr === specCore.io.mem.write.addr)
assert(io.mem.get.write.data === specCore.io.mem.write.data)
assert(io.mem.get.write.memWidth === specCore.io.mem.write.memWidth)
assert(regDelay(io.mem.get.write.valid) === regDelay(specCore.io.mem.write.valid))
when(regDelay(io.mem.get.write.valid || specCore.io.mem.write.valid)) {
assert(regDelay(io.mem.get.write.addr) === regDelay(specCore.io.mem.write.addr))
assert(regDelay(io.mem.get.write.data) === regDelay(specCore.io.mem.write.data))
assert(regDelay(io.mem.get.write.memWidth) === regDelay(specCore.io.mem.write.memWidth))
}
specCore.io.mem.read.data := io.mem.get.read.data
} else {
// printf("[specCore] Valid:%x PC: %x Inst: %x\n", specCore.io.valid, specCore.io.now.pc, specCore.io.inst)
// printf("[SpecCore] Valid:%x PC: %x Inst: %x\n", specCore.io.valid, specCore.io.now.pc, specCore.io.inst)
// specCore.io.mem.read.data := { if (checkMem) io.mem.get.read.data else DontCare }
val TLBLoadQueue = Seq.fill(3)(Module(new QueueModuleTLB()))
// initial the queue
Expand All @@ -114,18 +114,6 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false
TLBLoadQueue(i).io.in.bits := 0.U.asTypeOf(new StoreOrLoadInfoTLB)
}
when(io.dtlbmem.get.read.valid) {
assert(RegNext(TLBLoadQueue(0).io.in.valid, false.B) === false.B)
assert(RegNext(TLBLoadQueue(0).io.in.bits.addr, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(0).io.in.bits.data, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(0).io.in.bits.level, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(1).io.in.valid, false.B) === false.B)
assert(RegNext(TLBLoadQueue(1).io.in.bits.addr, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(1).io.in.bits.data, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(1).io.in.bits.level, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(2).io.in.valid, false.B) === false.B)
assert(RegNext(TLBLoadQueue(2).io.in.bits.addr, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(2).io.in.bits.data, 0.U) === 0.U)
assert(RegNext(TLBLoadQueue(2).io.in.bits.level, 0.U) === 0.U)

for (i <- 0 until 3) {
when(io.dtlbmem.get.read.level === i.U) {
Expand All @@ -139,12 +127,10 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false
for (i <- 0 until 3) {
when(specCore.io.tlb.get.Anotherread(i).valid) {
TLBLoadQueue(2 - i).io.out.ready := true.B
// printf("Load out Queue.... valid: %x %x %x %x\n", LoadQueue.io.out.valid, LoadQueue.io.out.bits.addr, LoadQueue.io.out.bits.data, LoadQueue.io.out.bits.memWidth)
// printf("[SpecCore] Load out Queue Valid: %x %x %x %x\n", LoadQueue.io.out.valid, LoadQueue.io.out.bits.addr, LoadQueue.io.out.bits.data, LoadQueue.io.out.bits.memWidth)
specCore.io.tlb.get.Anotherread(i).data := {
if (checkMem) TLBLoadQueue(2 - i).io.out.bits.data else DontCare
}
// TODO: 第Level 1 assert is inconsistent nutshell and the condition need to modify.
// assert(TLBLoadQueue(i).io.out.bits.addr === specCore.io.mem.read.addr)
}
when(regDelay(specCore.io.tlb.get.Anotherread(i).valid)) {
assert(regDelay(TLBLoadQueue(2 - i).io.out.bits.addr) === regDelay(specCore.io.tlb.get.Anotherread(i).addr))
Expand All @@ -158,17 +144,17 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false
LoadQueue.io.in.bits.addr := io.mem.get.read.addr
LoadQueue.io.in.bits.data := io.mem.get.read.data
LoadQueue.io.in.bits.memWidth := io.mem.get.read.memWidth
// printf("Load into Queue.... valid: %x %x %x %x\n", LoadQueue.io.in.valid, load_push.addr, load_push.data, load_push.memWidth)
// printf("[SpecCore] Load into Queue Valid: %x %x %x %x\n", LoadQueue.io.in.valid, load_push.addr, load_push.data, load_push.memWidth)
}.otherwise {
LoadQueue.io.in.valid := false.B
LoadQueue.io.in.bits := 0.U.asTypeOf(new StoreOrLoadInfo)
}
when(specCore.io.mem.read.valid) {
when(regDelay(specCore.io.mem.read.valid)) {
LoadQueue.io.out.ready := true.B
// printf("Load out Queue.... valid: %x %x %x %x\n", LoadQueue.io.out.valid, LoadQueue.io.out.bits.addr, LoadQueue.io.out.bits.data, LoadQueue.io.out.bits.memWidth)
// printf("[SpecCore] Load out Queue Valid: %x %x %x %x\n", LoadQueue.io.out.valid, LoadQueue.io.out.bits.addr, LoadQueue.io.out.bits.data, LoadQueue.io.out.bits.memWidth)
specCore.io.mem.read.data := LoadQueue.io.out.bits.data
assert(LoadQueue.io.out.bits.addr === specCore.io.mem.read.addr)
assert(LoadQueue.io.out.bits.memWidth === specCore.io.mem.read.memWidth)
assert(regDelay(LoadQueue.io.out.bits.addr) === regDelay(specCore.io.mem.read.addr))
assert(regDelay(LoadQueue.io.out.bits.memWidth) === regDelay(specCore.io.mem.read.memWidth))
}.otherwise {
LoadQueue.io.out.ready := false.B
specCore.io.mem.read.data := 0.U
Expand All @@ -180,17 +166,17 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false
StoreQueue.io.in.bits.addr := io.mem.get.write.addr
StoreQueue.io.in.bits.data := io.mem.get.write.data
StoreQueue.io.in.bits.memWidth := io.mem.get.write.memWidth
// printf("Store into Queue.... valid: %x %x %x %x\n", StoreQueue.io.in.valid, store_push.addr, store_push.data, store_push.memWidth)
// printf("[SpecCore] Store into Queue Valid: %x %x %x %x\n", StoreQueue.io.in.valid, store_push.addr, store_push.data, store_push.memWidth)
}.otherwise {
StoreQueue.io.in.valid := false.B
StoreQueue.io.in.bits := 0.U.asTypeOf(new StoreOrLoadInfo)
}
when(specCore.io.mem.write.valid) {
when(regDelay(specCore.io.mem.write.valid)) {
StoreQueue.io.out.ready := true.B
// printf("Store out Queue.... valid: %x %x %x %x\n", StoreQueue.io.out.valid, StoreQueue.io.out.bits.addr, StoreQueue.io.out.bits.data, StoreQueue.io.out.bits.memWidth)
assert(StoreQueue.io.out.bits.addr === specCore.io.mem.write.addr)
assert(StoreQueue.io.out.bits.data === specCore.io.mem.write.data)
assert(StoreQueue.io.out.bits.memWidth === specCore.io.mem.write.memWidth)
// printf("[SpecCore] Store out Queue Valid: %x %x %x %x\n", StoreQueue.io.out.valid, StoreQueue.io.out.bits.addr, StoreQueue.io.out.bits.data, StoreQueue.io.out.bits.memWidth)
assert(regDelay(StoreQueue.io.out.bits.addr) === regDelay(specCore.io.mem.write.addr))
assert(regDelay(StoreQueue.io.out.bits.data) === regDelay(specCore.io.mem.write.data))
assert(regDelay(StoreQueue.io.out.bits.memWidth) === regDelay(specCore.io.mem.write.memWidth))
}.otherwise {
StoreQueue.io.out.ready := false.B
}
Expand All @@ -200,25 +186,22 @@ class CheckerWithResult(val checkMem: Boolean = true, enableReg: Boolean = false
}

when(regDelay(io.instCommit.valid)) {
// next reg
for (i <- 0 until 32) {
assert(regDelay(io.result.reg(i.U)) === regDelay(specCore.io.next.reg(i.U)))
}
}
// printf("[SSD] io.instCommit.valid %x io.event.valid %x speccore.io.event.valid %x\n", io.instCommit.valid, io.event.valid, specCore.io.event.valid)
when(io.instCommit.valid) {
// now pc:
assert(io.instCommit.pc === specCore.io.now.pc)
assert(regDelay(io.instCommit.pc) === regDelay(specCore.io.now.pc))
// next pc: hard to get next pc in a pipeline, check it at next instruction

// next csr:
io.result.csr.table.zip(specCore.io.next.csr.table).map {
case (result, next) => {
assert(result.signal === next.signal)
assert(regDelay(result.signal) === regDelay(next.signal))
}
}
// next reg
for (i <- 0 until 32) {
assert(regDelay(io.result.reg(i.U)) === regDelay(specCore.io.next.reg(i.U)))
}
}


when(regDelay(io.event.valid) || regDelay(specCore.io.event.valid)) {
assert(
regDelay(io.event.valid) === regDelay(specCore.io.event.valid)
Expand Down
7 changes: 6 additions & 1 deletion src/main/scala/rvspeccore/core/RVConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chisel3.util._
case class RVConfig(configs: (String, Any)*) {
private val acceptKeys = Map(
"XLEN" -> Set("32", "64"),
"extensions" -> Set("I", "M", "C", "Zifencei", "Zicsr", "U", "S"),
"extensions" -> Set("I", "M", "C", "Zifencei", "Zicsr", "Zba", "Zbb", "Zbc", "U", "S"),
"fakeExtensions" -> "ABCDEFGHIJKLMNOPQRSTUVWXYZ".map(_.toString).toSet,
"initValue" -> Set("pc", "mstatus", "mtvec"),
"functions" -> Set("Privileged", "TLB"),
Expand Down Expand Up @@ -40,6 +40,11 @@ case class RVConfig(configs: (String, Any)*) {
val C = raw.contains("C")
val Zifencei = raw.contains("Zifencei")
val Zicsr = raw.contains("Zicsr")
val Zba = raw.contains("Zba")
val Zbb = raw.contains("Zbb")
val Zbc = raw.contains("Zbc")
val Zbs = raw.contains("Zbs")
val B = Zba || Zbb || Zbc || Zbs

// - RSIC-V ISA, Privileged, 20240411
// - 1. Introduction
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/rvspeccore/core/RiscvCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class RiscvTrans()(implicit config: RVConfig) extends BaseCore with RVInstSet {
if (config.functions.privileged) doRVPrivileged
if (config.extensions.Zicsr) doRVZicsr
if (config.extensions.Zifencei) doRVZifencei
if (config.extensions.B) doRVB

// End excute
next.reg(0) := 0.U
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/rvspeccore/core/spec/RVInstSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ trait RVInstSet
with csr.CSRSupport
with csr.ExceptionSupport
with PrivilegedExtension
with BExtension
Loading

0 comments on commit 12b8663

Please sign in to comment.