diff --git a/src/main/scala/rvspeccore/core/RiscvCore.scala b/src/main/scala/rvspeccore/core/RiscvCore.scala index bdb0c2a..4179e17 100644 --- a/src/main/scala/rvspeccore/core/RiscvCore.scala +++ b/src/main/scala/rvspeccore/core/RiscvCore.scala @@ -9,29 +9,19 @@ import spec.instset.csr.EventSig import spec.instset.csr.SatpStruct abstract class BaseCore()(implicit config: RVConfig) extends Module { - // Define Basic parts implicit val XLEN: Int = config.XLEN - val io = IO(new Bundle { - // Processor IO - val inst = Input(UInt(32.W)) - val valid = Input(Bool()) - val mem = new MemIO - val tlb = new TLBIO - // Exposed processor status - val now = Output(State()) - val next = Output(State()) - val event = Output(new EventSig) - val iFetchpc = Output(UInt(XLEN.W)) - }) - // Initial State - val now = RegInit(State.wireInit()) + + // State + val now = Wire(State()) val next = Wire(State()) - val mem = Wire(new MemIO) - val tlb = Wire(new TLBIO) - // Global Data + // IO ports + val iFetchpc = Wire(UInt(XLEN.W)) + val mem = Wire(new MemIO) + val tlb = Wire(new TLBIO) + // Global signals + val inst = Wire(UInt(32.W)) val global_data = Wire(new GlobalData) // TODO: GlobalData only has setpc? event, iFetchpc? val event = Wire(new EventSig) - val iFetchpc = Wire(UInt(XLEN.W)) } class GlobalData extends Bundle { val setpc = Bool() @@ -95,13 +85,30 @@ object State { } } -class RiscvCore()(implicit config: RVConfig) extends BaseCore with RVInstSet { +class RiscvTrans()(implicit config: RVConfig) extends BaseCore with RVInstSet { + val io = IO(new Bundle { + // Processor IO + val inst = Input(UInt(32.W)) + val valid = Input(Bool()) + val iFetchpc = Output(UInt(XLEN.W)) + val mem = new MemIO + val tlb = new TLBIO + // Processor status + val now = Input(State()) + val next = Output(State()) + // Exposed signals + val event = Output(new EventSig) + }) + // Initial the value + now := io.now // these signals should keep the value in the next clock if there no changes below next := now + inst := 0.U global_data.setpc := false.B event := 0.U.asTypeOf(new EventSig) iFetchpc := now.pc + // dont read or write mem // if there no LOAD/STORE below mem := 0.U.asTypeOf(new MemIO) @@ -159,12 +166,41 @@ class RiscvCore()(implicit config: RVConfig) extends BaseCore with RVInstSet { io.mem <> mem io.tlb <> tlb - // update - now := next - - // output - io.now := now io.next := next io.event := event io.iFetchpc := iFetchpc } + +class RiscvCore()(implicit config: RVConfig) extends Module { + implicit val XLEN: Int = config.XLEN + + val io = IO(new Bundle { + // Processor IO + val inst = Input(UInt(32.W)) + val valid = Input(Bool()) + val iFetchpc = Output(UInt(XLEN.W)) + val mem = new MemIO + val tlb = new TLBIO + // Processor status + val now = Output(State()) + val next = Output(State()) + // Exposed signals + val event = Output(new EventSig) + }) + + val state = RegInit(State.wireInit()) + val trans = Module(new RiscvTrans()) + + trans.io.inst := io.inst + trans.io.valid := io.valid + trans.io.mem <> io.mem + trans.io.tlb <> io.tlb + + trans.io.now := state + state := trans.io.next + + io.now := state + io.next := trans.io.next + io.event := trans.io.event + io.iFetchpc := trans.io.iFetchpc +} diff --git a/src/main/scala/rvspeccore/core/spec/instset/CommonDecode.scala b/src/main/scala/rvspeccore/core/spec/instset/CommonDecode.scala index 264ce08..0a4de94 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/CommonDecode.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/CommonDecode.scala @@ -13,8 +13,6 @@ import rvspeccore.core.tool.BitTool._ * - 2.3 Immediate Encoding Variants */ trait CommonDecode extends BaseCore with csr.ExceptionSupport { - val inst = WireInit(0.U(32.W)) - val opcode = WireInit(0.U(7.W)) val rd = WireInit(0.U(5.W)) val funct3 = WireInit(0.U(3.W)) diff --git a/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala b/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala index d2bd64b..bd8affd 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/csr/CSRSupport.scala @@ -13,7 +13,6 @@ trait CSRSupport extends BaseCore with ExceptionSupport { // def ModeS = 0x1.U // 01 Supervisor // def ModeR = 0x2.U // 10 Reserved // def ModeM = 0x3.U // 11 Machine - val lr = RegInit(Bool(), false.B) val VAddrBits = if (XLEN == 32) 32 else 39 val retTarget = Wire(UInt(VAddrBits.W)) retTarget := DontCare @@ -102,7 +101,6 @@ trait CSRSupport extends BaseCore with ExceptionSupport { mstatusNew.mpp := ModeM } next.csr.mstatus := mstatusNew.asUInt - lr := false.B retTarget := next.csr.mepc(VAddrBits - 1, 0) // printf("nextpc1:%x\n",now.csr.mepc) global_data.setpc := true.B @@ -132,7 +130,6 @@ trait CSRSupport extends BaseCore with ExceptionSupport { mstatusNew.spp := ModeU mstatusNew.mprv := 0x0.U // Volume II P21 " If xPP != M, xRET also sets MPRV = 0 " next.csr.mstatus := mstatusNew.asUInt - lr := false.B retTarget := next.csr.sepc(VAddrBits - 1, 0) // printf("nextpc1:%x\n",now.csr.sepc) global_data.setpc := true.B diff --git a/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala b/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala index 3bc6c01..e2e7295 100644 --- a/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala +++ b/src/main/scala/rvspeccore/core/spec/instset/csr/ExceptionSupport.scala @@ -149,7 +149,7 @@ trait ExceptionSupport extends BaseCore { // event.intrNO := exceptionNO event.cause := exceptionNO event.exceptionPC := now.pc - event.exceptionInst := io.inst(31, 0) + event.exceptionInst := inst(31, 0) // FIXME: 目前仅仅考虑了异常 val deleg = now.csr.medeleg val delegS = (deleg(exceptionNO)) && (now.internal.privilegeMode < ModeM) @@ -201,18 +201,18 @@ trait ExceptionSupport extends BaseCore { // .otherwise { next.csr.mtval := io.inst(31, 0) } } is(MExceptionCode.instructionAccessFault.U) { - when(io.inst(1, 0) =/= "b11".U(2.W)) { next.csr.mtval := io.inst(15, 0) } - .otherwise { next.csr.mtval := io.inst(31, 0) } + when(inst(1, 0) =/= "b11".U(2.W)) { next.csr.mtval := inst(15, 0) } + .otherwise { next.csr.mtval := inst(31, 0) } } is(MExceptionCode.environmentCallFromMmode.U) { next.csr.mtval := 0.U } is(MExceptionCode.storeOrAMOAddressMisaligned.U) { - next.csr.mtval := io.mem.write.addr + next.csr.mtval := mem.write.addr // printf("[Debug]:storeOrAMOAddressMisaligned %x %x\n",io.mem.write.addr,next.csr.mtval) } is(MExceptionCode.loadAddressMisaligned.U) { - next.csr.mtval := io.mem.read.addr + next.csr.mtval := mem.read.addr // printf("[Debug]:loadAddressMisaligned %x %x\n",io.mem.read.addr,next.csr.mtval) } is(MExceptionCode.instructionAddressMisaligned.U) { @@ -268,17 +268,17 @@ trait ExceptionSupport extends BaseCore { // : * the first MXLEN bits of the faulting instruction // simply implement it for now // FIXME: 实际上 非法指令存的是指令本身 其他的错误并非存储指令到mtval中 其他的也需要改 - when(io.inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := io.inst(15, 0) } - .otherwise { next.csr.stval := io.inst(31, 0) } + when(inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := inst(15, 0) } + .otherwise { next.csr.stval := inst(31, 0) } } is(MExceptionCode.instructionAccessFault.U) { - when(io.inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := io.inst(15, 0) } - .otherwise { next.csr.stval := io.inst(31, 0) } + when(inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := inst(15, 0) } + .otherwise { next.csr.stval := inst(31, 0) } } // 实际上是S Mode is(MExceptionCode.breakpoint.U) { - when(io.inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := io.inst(15, 0) } - .otherwise { next.csr.stval := io.inst(31, 0) } + when(inst(1, 0) =/= "b11".U(2.W)) { next.csr.stval := inst(15, 0) } + .otherwise { next.csr.stval := inst(31, 0) } } is(MExceptionCode.environmentCallFromMmode.U) { // FIXME: 很奇怪 把这个删了代码就不能跑了 无法理解 @@ -289,11 +289,11 @@ trait ExceptionSupport extends BaseCore { } // FIXME:三种非对齐访存 把非必要的Case进行合并 is(MExceptionCode.storeOrAMOAddressMisaligned.U) { - next.csr.stval := io.mem.write.addr + next.csr.stval := mem.write.addr // printf("[Debug]:storeOrAMOAddressMisaligned %x %x\n",io.mem.write.addr,next.csr.stval) } is(MExceptionCode.loadAddressMisaligned.U) { - next.csr.stval := io.mem.read.addr + next.csr.stval := mem.read.addr // printf("[Debug]:loadAddressMisaligned %x %x\n",io.mem.read.addr,next.csr.stval) } diff --git a/src/test/scala/rvspeccore/checker/CheckerSpec.scala b/src/test/scala/rvspeccore/checker/CheckerSpec.scala index de547ad..07acafc 100644 --- a/src/test/scala/rvspeccore/checker/CheckerSpec.scala +++ b/src/test/scala/rvspeccore/checker/CheckerSpec.scala @@ -16,14 +16,14 @@ class CheckerWithResultSpec extends AnyFlatSpec with ChiselScalatestTester { val checker = Module(new CheckerWithResult(checkMem)) checker.io.instCommit.valid := RegNext(io.valid, false.B) checker.io.instCommit.inst := RegNext(io.inst) - checker.io.instCommit.pc := RegNext(now.pc) + checker.io.instCommit.pc := RegNext(state.pc) checker.io.event.valid := RegNext(io.event.valid, false.B) checker.io.event.intrNO := RegNext(io.event.intrNO) checker.io.event.cause := RegNext(io.event.cause) checker.io.event.exceptionPC := RegNext(io.event.exceptionPC) checker.io.event.exceptionInst := RegNext(io.event.exceptionInst) // printf("[ DUT ] Valid:%x PC: %x Inst: %x\n", checker.io.instCommit.valid, checker.io.instCommit.pc, checker.io.instCommit.inst) - checker.io.result := now + checker.io.result := state checker.io.itlbmem.map(cm => { cm := DontCare @@ -34,15 +34,15 @@ class CheckerWithResultSpec extends AnyFlatSpec with ChiselScalatestTester { }) // checker.io.tlb.get.Anotherwrite := DontCare checker.io.mem.map(cm => { - cm.read.addr := mem.read.addr - cm.read.data := mem.read.data - cm.read.memWidth := mem.read.memWidth - cm.read.valid := mem.read.valid - - cm.write.addr := mem.write.addr - cm.write.data := mem.write.data - cm.write.memWidth := mem.write.memWidth - cm.write.valid := mem.write.valid + cm.read.valid := trans.io.mem.read.valid + cm.read.addr := trans.io.mem.read.addr + cm.read.memWidth := trans.io.mem.read.memWidth + cm.read.data := trans.io.mem.read.data + + cm.write.valid := trans.io.mem.write.valid + cm.write.addr := trans.io.mem.write.addr + cm.write.memWidth := trans.io.mem.write.memWidth + cm.write.data := trans.io.mem.write.data }) } @@ -80,21 +80,21 @@ class CheckerWithWBSpec extends AnyFlatSpec with ChiselScalatestTester { wb.data := 0.U for (i <- 0 until 32) { - when(now.reg(i.U) =/= next.reg(i.U)) { + when(state.reg(i.U) =/= trans.io.next.reg(i.U)) { wb.valid := true.B wb.dest := i.U - wb.data := next.reg(i.U) + wb.data := trans.io.next.reg(i.U) } } val checker = Module(new CheckerWithWB(checkMem)) checker.io.instCommit.valid := io.valid checker.io.instCommit.inst := io.inst - checker.io.instCommit.pc := now.pc + checker.io.instCommit.pc := state.pc checker.io.wb := wb - checker.io.mem.map(_ := mem) + checker.io.mem.map(_ := trans.io.mem) } it should "pass RiscvTests" in { diff --git a/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala b/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala index eb0521c..d070482 100644 --- a/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala +++ b/src/test/scala/rvspeccore/checker/ConnectHelperSpec.scala @@ -16,11 +16,11 @@ class ConnectHelperSpec extends AnyFlatSpec with ChiselScalatestTester { val checker = Module(new CheckerWithResult(false)) checker.io.instCommit.valid := RegNext(io.valid, false.B) checker.io.instCommit.inst := RegNext(io.inst) - checker.io.instCommit.pc := RegNext(now.pc) + checker.io.instCommit.pc := RegNext(state.pc) - ConnectCheckerResult.setRegSource(now.reg) + ConnectCheckerResult.setRegSource(state.reg) val csr = ConnectCheckerResult.makeCSRSource() - csr := now.csr + csr := state.csr ConnectCheckerResult.setChecker(checker) }