提交 d602f6fa 编写于 作者: Z Zihao Yu

Merge branch 'rv64im' into 'master'

Rv64im

See merge request projectn/noop!9
......@@ -43,6 +43,7 @@ VERILATOR_FLAGS = --top-module $(SIM_TOP) \
+define+PRINTF_COND=1 \
+define+RANDOMIZE_REG_INIT \
--assert --output-split 20000 \
--trace \
--x-assign unique -O3 -CFLAGS "$(EMU_CXXFLAGS)" \
-LDFLAGS "$(EMU_LDFLAGS)"
......@@ -56,9 +57,9 @@ $(EMU_MK): $(SIM_TOP_V) | $(EMU_DEPS)
verilator --cc --exe $(VERILATOR_FLAGS) \
-o $(abspath $(EMU)) -Mdir $(@D) $^ $(EMU_DEPS)
REF_SO := $(NEMU_HOME)/build/riscv32-nemu-so
REF_SO := $(NEMU_HOME)/build/riscv64-nemu-so
$(REF_SO):
$(MAKE) -C $(NEMU_HOME) ISA=riscv32 SHARE=1
$(MAKE) -C $(NEMU_HOME) ISA=riscv64 SHARE=1
$(EMU): $(EMU_MK) $(EMU_DEPS) $(EMU_HEADERS) $(REF_SO)
CPPFLAGS=-DREF_SO=\\\"$(REF_SO)\\\" $(MAKE) -C $(dir $(EMU_MK)) -f $(abspath $(EMU_MK))
......
microbench:
make -C /home/aw/projectn/nexus-am/apps/microbench ARCH=riscv64-noop run 2>&1 | tee > /home/aw/riscv-projecti/noop/debug/microbench.log
\ No newline at end of file
开发日志
=================
[TOC]
# CPU调整到riscv64指令集 2019.9.3-
- 调整数据通路宽度到64
- 调整DCache读写宽度
- 调整外围内存, 总线配置
- 引入新指令
## 模块改动说明
### Cache
* Cache64: 64位数据缓存, 使用64位地址
* 目前所有的Cache对外数据宽度均为64
RV64指令集中, 地址非对齐的访存结果是实现相关的, 为了简化设计, 这里对非对齐的访存不做特殊处理
TODO: IMM变化 1
TODO: 32位乘法器/除法器 1
TODO: RESET VECTOR
TODO: 64 bit AddressSpace 分配
TODO: cache直接使用参数改成64位的效果尚未测试
TODO: 特权寄存器变更
TODO: simple bus 调整和 AXI4 调整 1
## 新指令列表
```
指令|模式|当前进度
--- |BitPat("b1098765_43210_98765_432_10987_6543210")|-
LWU |BitPat("b???????_?????_?????_110_?????_0000011")|1
LD |BitPat("b???????_?????_?????_011_?????_0000011")|1
SD |BitPat("b???????_?????_?????_011_?????_0100011")|1
SLLI |BitPat("b0000000_?????_?????_001_?????_0010011")|1
SRLI |BitPat("b0000000_?????_?????_101_?????_0010011")|1
SRAI |BitPat("b0100000_?????_?????_101_?????_0010011")|1
ADDIW |BitPat("b???????_?????_?????_000_?????_0011011")|1
SLLIW |BitPat("b0000000_?????_?????_001_?????_0011011")|1
SRLIW |BitPat("b0000000_?????_?????_101_?????_0011011")|1
SRAIW |BitPat("b0100000_?????_?????_101_?????_0011011")|1
ADDW |BitPat("b0000000_?????_?????_000_?????_0111011")|1
SUBW |BitPat("b0100000_?????_?????_000_?????_0111011")|1
SLLW |BitPat("b0000000_?????_?????_001_?????_0111011")|1
SRLW |BitPat("b0000000_?????_?????_101_?????_0111011")|1
SRAW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
MULW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
DIVW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
DIVUW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
REMW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
REMUW |BitPat("b0100000_?????_?????_101_?????_0111011")|1
```
其他要调整的指令
* LX/SX
* ALUI
\ No newline at end of file
......@@ -17,8 +17,8 @@ object AXI4Parameters {
// These are not fixed:
val idBits = 1
val addrBits = 32
val dataBits = 32
val addrBits = 64
val dataBits = 64
val userBits = 1
def CACHE_RALLOCATE = 8.U(cacheBits.W)
......
......@@ -12,35 +12,35 @@ class DistributedMem(memByte: Int, dualPort: Boolean, delayCycles: Int = 0, data
val useTreadle = false
val wordNum = memByte / 4
val wordNum = memByte / 8
val memAddrBits = log2Up(wordNum)
def Index(addr: UInt): UInt = addr(memAddrBits + 2 - 1, 2)
val rwIdx = Index(io.rw.req.bits.addr)
val roIdx = Index(io.ro.req.bits.addr)
val wen = io.rw.isWrite()
val wdataVec = VecInit.tabulate(4) { i => io.rw.req.bits.wdata(8 * (i + 1) - 1, 8 * i) }
val wmask = VecInit.tabulate(4) { i => io.rw.req.bits.wmask(i).toBool }
val wdataVec = VecInit.tabulate(8) { i => io.rw.req.bits.wdata(8 * (i + 1) - 1, 8 * i) }
val wmask = VecInit.tabulate(8) { i => io.rw.req.bits.wmask(i).toBool }
val rwData = Wire(UInt(32.W))
val roData = Wire(UInt(32.W))
val rwData = Wire(UInt(64.W))
val roData = Wire(UInt(64.W))
if (useTreadle) {
val mem = Mem(memByte, UInt(8.W))
if (dataFile != "")
loadMemoryFromFile(mem, dataFile)
def read(idx: UInt) = Cat(mem(idx + 3.U), mem(idx + 2.U), mem(idx + 1.U), mem(idx + 0.U))
def read(idx: UInt) = Cat(mem(idx + 7.U), mem(idx + 6.U), mem(idx + 5.U), mem(idx + 4.U), mem(idx + 3.U), mem(idx + 2.U), mem(idx + 1.U), mem(idx + 0.U))
rwData := read(rwIdx << 2)
roData := read(roIdx << 2)
rwData := read(rwIdx << 3)
roData := read(roIdx << 3)
wmask.zipWithIndex.map { case(m, i) => {
when (m && wen) {
mem((rwIdx << 2) + i.U) := wdataVec(i)
mem((rwIdx << 3) + i.U) := wdataVec(i)
}
}}
}
else {
val mem = Mem(wordNum, Vec(4, UInt(8.W)))
val mem = Mem(wordNum, Vec(8, UInt(8.W)))
if (dataFile != "")
loadMemoryFromFile(mem, dataFile)
......
......@@ -25,7 +25,7 @@ object SimpleBusCmd {
}
class SimpleBusReqBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
val addr = Output(UInt(32.W))
val addr = Output(UInt(64.W))
val size = Output(UInt(3.W))
val cmd = Output(SimpleBusCmd())
val wmask = Output(UInt((dataBits / 8).W))
......@@ -59,7 +59,7 @@ class SimpleBusRespBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
}
// Uncache
class SimpleBusUC(dataBits: Int = 32, userBits: Int = 0) extends Bundle {
class SimpleBusUC(dataBits: Int = 64, userBits: Int = 0) extends Bundle {
val req = Decoupled(new SimpleBusReqBundle(dataBits, userBits))
val resp = Flipped(Decoupled(new SimpleBusRespBundle(dataBits, userBits)))
......@@ -76,7 +76,7 @@ class SimpleBusUC(dataBits: Int = 32, userBits: Int = 0) extends Bundle {
}
// Cache
class SimpleBusC(dataBits: Int = 32, userBits: Int = 0) extends Bundle {
class SimpleBusC(dataBits: Int = 64, userBits: Int = 0) extends Bundle {
val mem = new SimpleBusUC(dataBits, userBits)
val coh = Flipped(new SimpleBusUC(dataBits, userBits))
......
......@@ -24,7 +24,7 @@ class SimpleBus2AXI4Converter[OT <: AXI4Lite](outType: OT) extends Module {
w.data := mem.req.bits.wdata
w.strb := mem.req.bits.wmask
def LineBeats = 8
def LineBeats = 4 //Note: LineBeats = 8 while using rv32 inst set
val wlast = WireInit(true.B)
val rlast = WireInit(true.B)
if (outType.getClass == classOf[AXI4]) {
......@@ -58,6 +58,25 @@ class SimpleBus2AXI4Converter[OT <: AXI4Lite](outType: OT) extends Module {
axi.w .valid := mem.isWrite() && !wAck
mem.req.ready := Mux(mem.req.bits.isWrite(), !wAck && axi.w.ready, axi.ar.ready)
Debug(false){
printf("[CVT] isWrite %x wAck %x wr %x arr %x addr %x\n", mem.req.bits.isWrite(), wAck, axi.w.ready, axi.ar.ready, mem.req.bits.addr)
}
Debug(false){
when((ar.addr(31,4) === "h8010f00".U)&&(axi.ar.valid || axi.aw.valid)){
printf("[AXI] TIME %d addr: %x arv %x awv %x\n", GTimer(), ar.addr, axi.ar.valid, axi.aw.valid)
}
}
Debug(false){
when((w.data(31,0) === "h18be6784".U)&& axi.w.valid){
printf("[AXI] TIME %d wdata: %x wr: %x\n", GTimer(), w.data, axi.w.ready)
}
when((w.data(63,32) === "h18be6784".U)&& axi.w.valid){
printf("[AXI] TIME %d wdata: %x wr: %x\n", GTimer(), w.data, axi.w.ready)
}
}
axi.r.ready := mem.resp.ready
axi.b.ready := mem.resp.ready
mem.resp.valid := Mux(wen, axi.b.valid, axi.r.valid)
......
......@@ -10,22 +10,22 @@ import utils._
class RAMHelper(memByte: Int) extends BlackBox {
val io = IO(new Bundle {
val clk = Input(Clock())
val rIdx = Input(UInt(32.W))
val rdata = Output(UInt(32.W))
val wIdx = Input(UInt(32.W))
val wdata = Input(UInt(32.W))
val wmask = Input(UInt(32.W))
val rIdx = Input(UInt(64.W))
val rdata = Output(UInt(64.W))
val wIdx = Input(UInt(64.W))
val wdata = Input(UInt(64.W))
val wmask = Input(UInt(64.W))
val wen = Input(Bool())
})
}
class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, beatBytes: Int = 4,
class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, beatBytes: Int = 8,
useBlackBox: Boolean = false) extends AXI4SlaveModule(_type) {
val offsetBits = log2Up(memByte)
val offsetMask = (1 << offsetBits) - 1
def index(addr: UInt) = (addr & offsetMask.U) >> log2Ceil(beatBytes)
def inRange(idx: UInt) = idx < (memByte / 4).U
def inRange(idx: UInt) = idx < (memByte / 8).U
val wIdx = index(waddr) + writeBeatCnt
val rIdx = index(raddr) + readBeatCnt
......
......@@ -25,7 +25,7 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e
val beatCnt = Counter(256)
val len = HoldUnless(axi4.ar.bits.len, axi4.ar.fire())
val burst = HoldUnless(axi4.ar.bits.burst, axi4.ar.fire())
val wrapAddr = axi4.ar.bits.addr & ~(axi4.ar.bits.len.asTypeOf(UInt(32.W)) << axi4.ar.bits.size)
val wrapAddr = axi4.ar.bits.addr & ~(axi4.ar.bits.len.asTypeOf(UInt(64.W)) << axi4.ar.bits.size)
raddr := HoldUnless(wrapAddr, axi4.ar.fire())
axi4.r.bits.last := (c.value === len)
when (ren) {
......@@ -38,7 +38,7 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e
}
when (axi4.ar.fire()) {
beatCnt.value := (axi4.ar.bits.addr >> axi4.ar.bits.size) & axi4.ar.bits.len
assert(axi4.ar.bits.size === "b10".U)
assert(axi4.ar.bits.size === "b11".U)
when (axi4.ar.bits.burst === AXI4Parameters.BURST_WRAP) {
assert(axi4.ar.bits.len === 1.U || axi4.ar.bits.len === 3.U ||
axi4.ar.bits.len === 7.U || axi4.ar.bits.len === 15.U)
......
......@@ -7,13 +7,13 @@ import chisel3.util.experimental.BoringUtils
import utils._
class TableAddr(idxBits: Int) extends Bundle {
def tagBits = 32 - 2 - idxBits
def tagBits = 64 - 2 - idxBits
val tag = UInt(tagBits.W)
val idx = UInt(idxBits.W)
val pad = UInt(2.W)
def fromUInt(x: UInt) = x.asTypeOf(UInt(32.W)).asTypeOf(this)
def fromUInt(x: UInt) = x.asTypeOf(UInt(64.W)).asTypeOf(this)
def getTag(x: UInt) = fromUInt(x).tag
def getIdx(x: UInt) = fromUInt(x).idx
......@@ -31,9 +31,9 @@ object BTBtype {
class BPUUpdateReq extends Bundle {
val valid = Output(Bool())
val pc = Output(UInt(32.W))
val pc = Output(UInt(64.W))
val isMissPredict = Output(Bool())
val actualTarget = Output(UInt(32.W))
val actualTarget = Output(UInt(64.W))
val actualTaken = Output(Bool()) // for branch
val fuOpType = Output(FuOpType())
val btbType = Output(BTBtype())
......@@ -41,7 +41,7 @@ class BPUUpdateReq extends Bundle {
class BPU1 extends Module {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(32.W)))) }
val in = new Bundle { val pc = Flipped(Valid((UInt(64.W)))) }
val out = new RedirectIO
val flush = Input(Bool())
})
......@@ -54,7 +54,7 @@ class BPU1 extends Module {
def btbEntry() = new Bundle {
val tag = UInt(btbAddr.tagBits.W)
val _type = UInt(2.W)
val target = UInt(32.W)
val target = UInt(64.W)
}
val btb = Module(new SRAMTemplate(btbEntry(), set = NRbtb, shouldReset = true, holdRead = true, singlePort = true))
......@@ -75,7 +75,7 @@ class BPU1 extends Module {
// RAS
val NRras = 16
val ras = Mem(NRras, UInt(32.W))
val ras = Mem(NRras, UInt(64.W))//???
val sp = Counter(NRras)
val rasTarget = RegEnable(ras.read(sp.value), io.in.pc.valid)
......
......@@ -19,20 +19,20 @@ class CtrlSignalIO extends Bundle {
}
class DataSrcIO extends Bundle {
val src1 = Output(UInt(32.W))
val src2 = Output(UInt(32.W))
val imm = Output(UInt(32.W))
val src1 = Output(UInt(64.W))
val src2 = Output(UInt(64.W))
val imm = Output(UInt(64.W))
}
class RedirectIO extends Bundle {
val target = Output(UInt(32.W))
val target = Output(UInt(64.W))
val valid = Output(Bool())
}
class CtrlFlowIO extends Bundle {
val instr = Output(UInt(32.W))
val pc = Output(UInt(32.W))
val pnpc = Output(UInt(32.W))
val pc = Output(UInt(64.W))
val pnpc = Output(UInt(64.W))
val redirect = new RedirectIO
}
......@@ -45,22 +45,22 @@ class DecodeIO extends Bundle {
class WriteBackIO extends Bundle {
val rfWen = Output(Bool())
val rfDest = Output(UInt(5.W))
val rfData = Output(UInt(32.W))
val rfData = Output(UInt(64.W))
}
class CommitIO extends Bundle {
val decode = new DecodeIO
val isMMIO = Output(Bool())
val commits = Output(Vec(FuType.num, UInt(32.W)))
val commits = Output(Vec(FuType.num, UInt(64.W)))
}
class FunctionUnitIO extends Bundle {
val in = Flipped(Decoupled(new Bundle {
val src1 = Output(UInt(32.W))
val src2 = Output(UInt(32.W))
val src1 = Output(UInt(64.W))
val src2 = Output(UInt(64.W))
val func = Output(FuOpType())
}))
val out = Decoupled(Output(UInt(32.W)))
val out = Decoupled(Output(UInt(64.W)))
}
class ForwardIO extends Bundle {
......
......@@ -30,14 +30,13 @@ object CSRInstr extends HasInstrType {
}
trait HasCSRConst {
// these are actually S-mode CSRs to match riscv32-nemu
val Mstatus = 0x100
val Mtvec = 0x105
val Mepc = 0x141
val Mcause = 0x142
val Mstatus = 0x300
val Mtvec = 0x305
val Mepc = 0x341
val Mcause = 0x342
def privEcall = 0x000.U
def privMret = 0x102.U
def privMret = 0x302.U
}
class CSRIO extends FunctionUnitIO {
......@@ -58,7 +57,7 @@ class CSR(implicit val p: NOOPConfig) extends Module with HasCSRConst {
this.func := func
io.out.bits
}
val mtvec = Reg(UInt(32.W))
val mcause = Reg(UInt(32.W))
val mstatus = RegInit("h000c0100".U)
......@@ -90,12 +89,19 @@ class CSR(implicit val p: NOOPConfig) extends Module with HasCSRConst {
))
when (valid && func =/= CSROpType.jmp) {
when (addr === Mtvec.U) { mtvec := wdata }
when (addr === Mstatus.U) { mstatus := wdata }
when (addr === Mepc.U) { mepc := wdata }
when (addr === Mcause.U) { mcause := wdata }
when (addr === Mtvec.U) { mtvec := wdata(31, 0) }
when (addr === Mstatus.U) { mstatus := wdata(31, 0) }
when (addr === Mepc.U) { mepc := wdata(31, 0) }
when (addr === Mcause.U) { mcause := wdata(31, 0) }
}
// when (valid && func =/= CSROpType.jmp){
// when (addr === Mtvec.U) {printf("[CSR] %x pc: %x inst: %x\n", GTimer(), io.cfIn.pc, io.cfIn.instr)}
// }
// when (valid && func =/= CSROpType.jmp){
// when (addr === Mcause.U) {printf("[CSR] %x pc: %x inst: %x mcause: r %x w %x\n", GTimer(), io.cfIn.pc, io.cfIn.instr, rdata, wdata)}
// }
io.out.bits := rdata
val isMret = addr === privMret
......@@ -103,9 +109,15 @@ class CSR(implicit val p: NOOPConfig) extends Module with HasCSRConst {
val isEcall = (addr === privEcall) && !isException
val exceptionNO = Mux1H(List(
io.isInvOpcode -> 2.U,
isEcall -> 9.U //11.U
isEcall -> 11.U
))
Debug(){
when(io.isInvOpcode && valid){
printf("[CSR] Invalid Op at %x\n", io.cfIn.pc)
}
}
io.redirect.valid := (valid && func === CSROpType.jmp) || isException
io.redirect.target := Mux(isMret, mepc, mtvec)
......
......@@ -11,14 +11,14 @@ import utils._
sealed trait HasCacheConst {
val TotalSize = 32 // Kbytes
val LineSize = 32 // byte
val LineBeats = LineSize / 4
val LineBeats = LineSize / 8 //DATA WIDTH 64
val Ways = 1
val Sets = TotalSize * 1024 / LineSize / Ways
val OffsetBits = log2Up(LineSize)
val IndexBits = log2Up(Sets)
val WordIndexBits = log2Up(LineBeats)
val TagBits = 32 - OffsetBits - IndexBits
val dataBits = 32
val TagBits = 64 - OffsetBits - IndexBits
val dataBits = 64
val debug = false
......@@ -26,7 +26,7 @@ sealed trait HasCacheConst {
val tag = UInt(TagBits.W)
val index = UInt(IndexBits.W)
val wordIndex = UInt(WordIndexBits.W)
val byteOffset = UInt(2.W)
val byteOffset = UInt(3.W)//rv32: byteOffset = UInt(2.W)
}
def CacheMetaArrayReadBus() = new SRAMReadBus(new MetaBundle, set = Sets, way = Ways)
......@@ -34,7 +34,7 @@ sealed trait HasCacheConst {
def CacheMetaArrayWriteBus() = new SRAMWriteBus(new MetaBundle, set = Sets, way = Ways)
def CacheDataArrayWriteBus() = new SRAMWriteBus(new DataBundle, set = Sets, way = Ways * LineBeats)
def maskExpand(m: UInt): UInt = Cat(m.toBools.map(Fill(8, _)).reverse)
def maskExpand(m: UInt): UInt = Cat(m.asBools.map(Fill(8, _)).reverse)
def isSameWord(a1: UInt, a2: UInt) = ((a1 >> 2) === (a2 >> 2))
def isSetConflict(a1: UInt, a2: UInt) = (a1.asTypeOf(addrBundle).index === a2.asTypeOf(addrBundle).index)
}
......@@ -52,7 +52,7 @@ sealed class MetaPipelineBundle extends Bundle with HasCacheConst {
}
sealed class DataBundle extends Bundle {
val data = Output(UInt(32.W))
val data = Output(UInt(64.W))
}
sealed class Stage1IO(userBits: Int = 0) extends Bundle with HasCacheConst {
......@@ -75,6 +75,11 @@ sealed class CacheStage1(ro: Boolean, name: String, userBits: Int = 0) extends M
})
if (ro) when (io.in.fire()) { assert(!io.in.bits.isWrite()) }
Debug(false){
when(io.in.fire()){
printf("[L1$] cache stage1, addr in: %x\n", io.in.bits.addr)
}
}
// read meta array and data array
List(io.metaReadBus, io.dataReadBus).map { case x => {
......@@ -118,7 +123,9 @@ sealed class CacheStage2(ro: Boolean, name: String, userBits: Int = 0) extends M
io.out.bits.meta.tag := meta.tag
io.out.bits.meta.dirty := dirty && io.in.valid
io.out.bits.req <> io.in.bits.req
Debug(){
printf("[L1$] stage 2: addr %x, io.in.valid: %x, io.in.ready: %x, io.out.valid: %x, io.out.ready: %x\n", req.addr, io.in.valid, io.in.ready, io.out.valid, io.out.ready)
}
io.out.valid := io.in.valid
io.in.ready := !io.in.valid || io.out.fire()
}
......@@ -129,7 +136,7 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
val in = Flipped(Decoupled(new Stage2IO(userBits)))
val out = Decoupled(new SimpleBusRespBundle(dataBits = dataBits, userBits = userBits))
val isFinish = Output(Bool())
val addr = Output(UInt(32.W))
val addr = Output(UInt(64.W))
val flush = Input(Bool())
val dataBlock = Flipped(Vec(Ways * LineBeats, new DataBundle))
val dataWriteBus = CacheDataArrayWriteBus()
......@@ -145,7 +152,7 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
val dataBlockIdx = Wire(UInt(WordIndexBits.W))
val dataRead = io.dataBlock(dataBlockIdx).data
val wordMask = Mux(req.isWrite(), maskExpand(req.wmask), 0.U(32.W))
val wordMask = Mux(req.isWrite(), maskExpand(req.wmask), 0.U(64.W))
val dataHitWriteBus = WireInit(0.U.asTypeOf(CacheDataArrayWriteBus()))
val metaHitWriteBus = WireInit(0.U.asTypeOf(CacheMetaArrayWriteBus()))
......@@ -165,7 +172,7 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
// if miss, access memory
io.mem := DontCare
List(io.mem.req.bits).map { a =>
a.size := "b10".U
a.size := "b11".U //"b10" with rv32
a.user := 0.U
}
......@@ -180,12 +187,12 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
dataBlockIdx := Mux(state === s_memWriteReq, writeBeatCnt.value, addr.wordIndex)
io.mem.req.bits.wdata := dataRead
io.mem.req.bits.wmask := 0xf.U
io.mem.req.bits.wmask := 0xff.U
io.mem.req.bits.cmd := Mux(state === s_memReadReq, SimpleBusCmd.readBurst,
Mux((writeBeatCnt.value === (LineBeats - 1).U), SimpleBusCmd.writeLast, SimpleBusCmd.writeBurst))
// critical word first
val raddr = Cat(req.addr(31, 2), 0.U(2.W))
val raddr = Cat(req.addr(63, 3), 0.U(3.W))
// dirty block addr
val waddr = Cat(meta.tag, addr.index, 0.U(OffsetBits.W))
io.mem.req.bits.addr := Mux(state === s_memReadReq, raddr, waddr)
......@@ -200,6 +207,11 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
val readingFirst = !afterFirstRead && io.mem.resp.fire() && (state === s_memReadResp)
val inRdataRegDemand = RegEnable(io.mem.resp.bits.rdata, readingFirst)
Debug(){
when(io.mem.req.valid && io.mem.req.ready){
printf("[L1$] mem access addr: %x\n", io.mem.req.bits.addr)
}
}
switch (state) {
is (s_idle) {
......@@ -207,7 +219,9 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
alreadyOutFire := false.B
// actually this can use s2 to test
when (miss && !io.flush) { state := Mux(if (ro) false.B else meta.dirty, s_memWriteReq, s_memReadReq) }
when (miss && !io.flush) {
state := Mux(if (ro) false.B else meta.dirty, s_memWriteReq, s_memReadReq)
}
}
is (s_memReadReq) { when (io.mem.req.fire()) {
state := s_memReadResp
......@@ -226,6 +240,9 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
dataRefillWriteBus.req.bits.data.data := inRdata
dataRefillWriteBus.req.bits.wordIndex := readBeatCnt.value
Debug(){
printf("[L1$] mem access data : %x index: %x\n", dataRefillWriteBus.req.bits.data.data, dataRefillWriteBus.req.bits.wordIndex)
}
readBeatCnt.inc()
when (io.mem.resp.bits.isReadLast()) { state := s_wait_resp }
......@@ -350,10 +367,10 @@ sealed class CacheProbeStage(ro: Boolean, name: String) extends Module with HasC
// FIXME: should invalidate the meta array
}
class Cache(ro: Boolean, name: String, dataBits: Int = 32, userBits: Int = 0) extends Module with HasCacheConst {
class Cache(ro: Boolean, name: String, dataBits: Int = 64, userBits: Int = 0) extends Module with HasCacheConst {
val io = IO(new Bundle {
val in = Flipped(new SimpleBusUC(dataBits, userBits))
val addr = Output(UInt(32.W))
val addr = Output(UInt(64.W))
val flush = Input(UInt(2.W))
val out = new SimpleBusC(dataBits)
})
......@@ -369,7 +386,7 @@ class Cache(ro: Boolean, name: String, dataBits: Int = 32, userBits: Int = 0) ex
PipelineConnect(s1.io.out, s2.io.in, s2.io.out.fire(), io.flush(0))
PipelineConnect(s2.io.out, s3.io.in, s3.io.isFinish, io.flush(1))
io.in.resp <> s3.io.out
// printf("io.flush(0): %x io.flush(1): %x\n", io.flush(0), io.flush(1))
s3.io.flush := io.flush(1)
io.addr := s3.io.addr
io.out.mem <> s3.io.mem
......
......@@ -4,14 +4,16 @@ import chisel3._
import chisel3.util._
trait HasInstrType {
private val InstrTypeNum = 7
def InstrN = "b000".U
def InstrI = "b100".U
def InstrR = "b101".U
def InstrS = "b010".U
def InstrB = "b001".U
def InstrU = "b110".U
def InstrJ = "b111".U
private val InstrTypeNum = 9
def InstrN = "b0000".U
def InstrI = "b0100".U
def InstrR = "b0101".U
def InstrS = "b0010".U
def InstrB = "b0001".U
def InstrU = "b0110".U
def InstrJ = "b0111".U
def InstrIW = "b1100".U
def isrfWen(instrType : UInt): Bool = instrType(2)
}
......@@ -33,7 +35,7 @@ object FuType {
}
object FuOpType {
def apply() = UInt(5.W)
def apply() = UInt(6.W)
}
object Instructions extends HasInstrType {
......
......@@ -26,6 +26,10 @@ class EXU(implicit val p: NOOPConfig) extends Module {
val fuValids = Wire(Vec(FuType.num, Bool()))
(0 until FuType.num).map (i => fuValids(i) := (fuType === i.U) && io.in.valid && !io.flush)
// when(io.in.valid){
// printf("EXv %b %b %b %b %x %x\n", fuValids(0), fuValids(1), fuValids(2), fuValids(3), fuType, io.flush)
// }
val alu = Module(new ALU)
val aluOut = alu.access(valid = fuValids(FuType.alu), src1 = src1, src2 = src2, func = fuOpType)
alu.io.cfIn := io.in.bits.cf
......
......@@ -15,6 +15,12 @@ class IDU(implicit val p: NOOPConfig) extends Module with HasInstrType {
val instrType :: fuType :: fuOpType :: Nil =
ListLookup(instr, Instructions.DecodeDefault, Instructions.DecodeTable)
Debug(){
when(io.out.valid){
printf("[IDU] pc: %x instrType: %x fuType: %x fuOpType: %x\n", io.in.bits.pc, instrType, fuType, fuOpType)
}
}
io.out.bits := DontCare
io.out.bits.ctrl.fuType := fuType
......@@ -41,11 +47,12 @@ class IDU(implicit val p: NOOPConfig) extends Module with HasInstrType {
io.out.bits.data := DontCare
io.out.bits.data.imm := LookupTree(instrType, List(
InstrI -> Cat(Fill(20, instr(31)), instr(31, 20)),
InstrS -> Cat(Fill(20, instr(31)), instr(31, 25), instr(11, 7)),
InstrB -> Cat(Fill(20, instr(31)), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)),
InstrU -> Cat(instr(31, 12), 0.U(12.W)),
InstrJ -> Cat(Fill(12, instr(31)), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W))
InstrIW -> Cat(Fill(20+32, instr(31)), instr(31, 20)),//fixed
InstrI -> Cat(Fill(20+32, instr(31)), instr(31, 20)),
InstrS -> Cat(Fill(20+32, instr(31)), instr(31, 25), instr(11, 7)),
InstrB -> Cat(Fill(20+32, instr(31)), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)),
InstrU -> Cat(Fill(32, instr(31)), instr(31, 12), 0.U(12.W)),//fixed
InstrJ -> Cat(Fill(12+32, instr(31)), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W))
))
when (fuType === FuType.alu) {
......
......@@ -8,13 +8,13 @@ import utils._
import bus.simplebus._
trait HasResetVector {
val resetVector = 0x80100000L
val resetVector = 0x80100000L//TODO: set reset vec
}
class IFU extends Module with HasResetVector {
class IFU(implicit val p: NOOPConfig) extends Module with HasResetVector {
val io = IO(new Bundle {
val imem = new SimpleBusUC(userBits = 32)
val pc = Input(UInt(32.W))
val pc = Input(UInt(64.W))
val out = Decoupled(new CtrlFlowIO)
val redirect = Flipped(new RedirectIO)
val flushVec = Output(UInt(4.W))
......@@ -22,7 +22,7 @@ class IFU extends Module with HasResetVector {
})
// pc
val pc = RegInit(resetVector.U(32.W))
val pc = RegInit(resetVector.U(64.W))
val pcUpdate = io.redirect.valid || io.imem.req.fire()
val snpc = pc + 4.U // sequential next pc
......@@ -39,25 +39,38 @@ class IFU extends Module with HasResetVector {
//bp2.io.in.bits := io.out.bits
//bp2.io.in.valid := io.imem.resp.fire()
when (pcUpdate) { pc := npc }
when (pcUpdate) {
pc := npc
// printf("[IF1] pc=%x\n", pc)
}
io.flushVec := Mux(io.redirect.valid, "b1111".U, 0.U)
io.bpFlush := false.B
io.imem := DontCare
io.imem.req.valid := io.out.ready
io.imem.req.bits.addr := pc
io.imem.req.bits.size := "b10".U
io.imem.req.bits.addr := Cat(pc(63,2),0.U(2.W))//cache will treat it as Cat(pc(63,3),0.U(3.W))
io.imem.req.bits.size := "b11".U
io.imem.req.bits.cmd := SimpleBusCmd.read
io.imem.req.bits.user := npc
io.imem.resp.ready := io.out.ready || io.flushVec(0)
io.out.bits := DontCare
io.out.bits.pc := io.pc
io.out.bits.instr := io.imem.resp.bits.rdata
if (p.HasIcache) {
io.out.bits.instr := Mux(io.pc(2), io.imem.resp.bits.rdata(63,32), io.imem.resp.bits.rdata(31,0))//inst path only uses 32bit inst, get the right inst according to pc(2)
}else{
io.out.bits.instr := io.imem.resp.bits.rdata(31,0)
}
io.out.bits.pnpc := io.imem.resp.bits.user
io.out.valid := io.imem.resp.valid && !io.flushVec(0)
Debug(){
when (io.out.fire()) {
printf("[IF1] pc=%x inst=%x\n", io.out.bits.pc, io.out.bits.instr)
}
}
BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire()), "perfCntCondMimemStall")
BoringUtils.addSource(io.flushVec.orR, "perfCntCondMifuFlush")
}
......@@ -7,10 +7,10 @@ import chisel3.util.experimental.BoringUtils
import utils._
class RegFile {
val rf = Mem(32, UInt(32.W))
val rf = Mem(32, UInt(64.W))
def read(addr: UInt) : UInt = Mux(addr === 0.U, 0.U, rf(addr))
def write(addr: UInt, data: UInt) = { rf(addr) := data }
}
}
class ScoreBoard {
val busy = RegInit(0.U(32.W))
......@@ -79,7 +79,7 @@ class ISU(implicit val p: NOOPConfig) extends Module {
when (io.wb.rfWen) { rf.write(io.wb.rfDest, io.wb.rfData) }
val wbClearMask = Mux(io.wb.rfWen && !isDepend(io.wb.rfDest, io.forward.wb.rfDest, forwardRfWen), sb.mask(io.wb.rfDest), 0.U(32.W))
val wbClearMask = Mux(io.wb.rfWen && !isDepend(io.wb.rfDest, io.forward.wb.rfDest, forwardRfWen), sb.mask(io.wb.rfDest), 0.U(64.W))
val isuFireSetMask = Mux(io.out.fire(), sb.mask(rfDest), 0.U)
when (io.flush) { sb.update(0.U, "hffffffff".U) }
.otherwise { sb.update(isuFireSetMask, wbClearMask) }
......@@ -92,5 +92,11 @@ class ISU(implicit val p: NOOPConfig) extends Module {
if (!p.FPGAPlatform) {
BoringUtils.addSource(VecInit((0 to 31).map(i => rf.read(i.U))), "difftestRegs")
Debug(){
when(io.out.fire()){
printf("[ISU] pc=%x, inst=%x rfwen=%b\n", io.out.bits.cf.pc, io.out.bits.cf.instr, io.out.bits.ctrl.rfWen)
}
}
}
}
......@@ -13,14 +13,14 @@ case class NOOPConfig (
HasIcache: Boolean = true,
HasDcache: Boolean = true,
HasMExtension: Boolean = true,
HasDiv: Boolean = true,
HasDiv: Boolean = true,
EnableDebug: Boolean = false
)
object AddressSpace {
// (start, size)
def mmio = List((0x40000000L, 0x10000000L))
def dram = (0x80000000L, 0x10000000L)
def mmio = List((0x0000000040000000L, 0x0000000010000000L))
def dram = (0x0000000080000000L, 0x0000000010000000L)
//def isMMIO(addr: UInt) = mmio.map(range => ((addr & ~((range._2 - 1).U(32.W))) === range._1.U)).reduce(_ || _)
def isMMIO(addr: UInt) = addr(31,28) === "h4".U
......@@ -40,7 +40,7 @@ class NOOP(implicit val p: NOOPConfig) extends Module {
val wbu = Module(new WBU)
def pipelineConnect2[T <: Data](left: DecoupledIO[T], right: DecoupledIO[T],
isFlush: Bool, entries: Int = 2, pipe: Boolean = false) = {
isFlush: Bool, entries: Int = 4, pipe: Boolean = false) = {
right <> FlushableQueue(left, isFlush, entries = entries, pipe = pipe)
}
......@@ -52,8 +52,9 @@ class NOOP(implicit val p: NOOPConfig) extends Module {
exu.io.flush := ifu.io.flushVec(3)
Debug() {
printf("%d: flush = %b, ifu:(%d,%d), idu:(%d,%d), isu:(%d,%d), exu:(%d,%d), wbu: (%d,%d)\n",
GTimer(), ifu.io.flushVec.asUInt, ifu.io.out.valid, ifu.io.out.ready,
printf("------------------------ TIMER: %d ------------------------\n", GTimer())
printf("flush = %b, ifu:(%d,%d), idu:(%d,%d), isu:(%d,%d), exu:(%d,%d), wbu: (%d,%d)\n",
ifu.io.flushVec.asUInt, ifu.io.out.valid, ifu.io.out.ready,
idu.io.in.valid, idu.io.in.ready, isu.io.in.valid, isu.io.in.ready,
exu.io.in.valid, exu.io.in.ready, wbu.io.in.valid, wbu.io.in.ready)
when (ifu.io.out.valid) { printf("IFU: pc = 0x%x, instr = 0x%x, pnpc = 0x%x\n", ifu.io.out.bits.pc, ifu.io.out.bits.instr, ifu.io.out.bits.pnpc) }
......@@ -69,7 +70,7 @@ class NOOP(implicit val p: NOOPConfig) extends Module {
isu.io.forward <> exu.io.forward
io.imem <> (if (p.HasIcache) {
val icache = Module(new Cache(ro = true, name = "icache", userBits = 32))
val icache = Module(new Cache(ro = true, name = "icache", userBits = 64))
icache.io.in <> ifu.io.imem
icache.io.flush := Fill(2, ifu.io.flushVec(0) | ifu.io.bpFlush)
ifu.io.pc := icache.io.addr
......@@ -77,7 +78,7 @@ class NOOP(implicit val p: NOOPConfig) extends Module {
} else { ifu.io.imem })
io.dmem <> (if (p.HasDcache) {
val dcache = Module(new Cache(ro = false, name = "dcache"))
val dcache = Module(new Cache(ro = false, name = "dcache", userBits = 64))
dcache.io.in <> exu.io.dmem
dcache.io.flush := Fill(2, false.B)
dcache.io.out
......
......@@ -19,7 +19,7 @@ class Monitor extends BlackBox {
val reset = Input(Bool())
val isNoopTrap = Input(Bool())
val trapCode = Input(UInt(32.W))
val trapPC = Input(UInt(32.W))
val trapPC = Input(UInt(64.W))
val cycleCnt = Input(UInt(32.W))
val instrCnt = Input(UInt(32.W))
})
......
......@@ -3,6 +3,7 @@ package noop
import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils
import utils._
class WBU(implicit val p: NOOPConfig) extends Module {
val io = IO(new Bundle {
......@@ -18,7 +19,16 @@ class WBU(implicit val p: NOOPConfig) extends Module {
io.redirect := io.in.bits.decode.cf.redirect
io.redirect.valid := io.in.bits.decode.cf.redirect.valid && io.in.valid
Debug(){
when(io.wb.rfWen){
printf("[WBU] pc:%x reg: %d, data: %x commit type: %x uncache: %x\n", io.in.bits.decode.cf.pc, io.wb.rfDest, io.wb.rfData, io.in.bits.decode.ctrl.fuType, io.in.bits.isMMIO)
}
}
// when(io.in.valid){
// printf("[WBU] pc:%x reg: %d, data: %x commit type: %x %x\n", io.in.bits.decode.cf.pc, io.wb.rfDest, io.wb.rfData, io.in.bits.decode.ctrl.fuType, io.wb.rfWen)
// }
BoringUtils.addSource(io.in.valid, "perfCntCondMinstret")
if (!p.FPGAPlatform) {
BoringUtils.addSource(RegNext(io.in.valid), "difftestCommit")
......
......@@ -7,28 +7,35 @@ import chisel3.util.experimental.BoringUtils
import utils._
object ALUOpType {
def add = "b00000".U
def sll = "b00001".U
def slt = "b00010".U
def sltu = "b00011".U
def xor = "b00100".U
def srl = "b00101".U
def or = "b00110".U
def and = "b00111".U
def sub = "b01000".U
def sra = "b01101".U
def add = "b000000".U
def sll = "b000001".U
def slt = "b000010".U
def sltu = "b000011".U
def xor = "b000100".U
def srl = "b000101".U
def or = "b000110".U
def and = "b000111".U
def sub = "b001000".U
def sra = "b001101".U
def sllw = "b100000".U
def srlw = "b100001".U
def sraw = "b100010".U
def addw = "b100011".U
def subw = "b100100".U
}
object ALUInstr extends HasInstrType {
//RV32I
def ADDI = BitPat("b????????????_?????_000_?????_0010011")
def SLLI = BitPat("b0000000?????_?????_001_?????_0010011")
// def SLLI = BitPat("b0000000?????_?????_001_?????_0010011")
def SLTI = BitPat("b????????????_?????_010_?????_0010011")
def SLTIU = BitPat("b????????????_?????_011_?????_0010011")
def XORI = BitPat("b????????????_?????_100_?????_0010011")
def SRLI = BitPat("b0000000?????_?????_101_?????_0010011")
// def SRLI = BitPat("b0000000?????_?????_101_?????_0010011")
def ORI = BitPat("b????????????_?????_110_?????_0010011")
def ANDI = BitPat("b????????????_?????_111_?????_0010011")
def SRAI = BitPat("b0100000?????_?????_101_?????_0010011")
// def SRAI = BitPat("b0100000?????_?????_101_?????_0010011")
def ADD = BitPat("b0000000_?????_?????_000_?????_0110011")
def SLL = BitPat("b0000000_?????_?????_001_?????_0110011")
......@@ -44,16 +51,30 @@ object ALUInstr extends HasInstrType {
def AUIPC = BitPat("b????????????????????_?????_0010111")
def LUI = BitPat("b????????????????????_?????_0110111")
//RV64I
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
def SLLI = BitPat("b000000?_?????_?????_001_?????_0010011")
def SRLI = BitPat("b000000?_?????_?????_101_?????_0010011")
def SRAI = BitPat("b010000?_?????_?????_101_?????_0010011")
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
def SRLIW = BitPat("b0000000_?????_?????_101_?????_0011011")
def SRAIW = BitPat("b0100000_?????_?????_101_?????_0011011")
def SLLW = BitPat("b0000000_?????_?????_001_?????_0111011")
def SRLW = BitPat("b0000000_?????_?????_101_?????_0111011")
def SRAW = BitPat("b0100000_?????_?????_101_?????_0111011")
def ADDW = BitPat("b0000000_?????_?????_000_?????_0111011")
def SUBW = BitPat("b0100000_?????_?????_000_?????_0111011")
val table = Array(
ADDI -> List(InstrI, FuType.alu, ALUOpType.add),
SLLI -> List(InstrI, FuType.alu, ALUOpType.sll),
// SLLI -> List(InstrI, FuType.alu, ALUOpType.sll),
SLTI -> List(InstrI, FuType.alu, ALUOpType.slt),
SLTIU -> List(InstrI, FuType.alu, ALUOpType.sltu),
XORI -> List(InstrI, FuType.alu, ALUOpType.xor),
SRLI -> List(InstrI, FuType.alu, ALUOpType.srl),
// SRLI -> List(InstrI, FuType.alu, ALUOpType.srl),
ORI -> List(InstrI, FuType.alu, ALUOpType.or ),
ANDI -> List(InstrI, FuType.alu, ALUOpType.and),
SRAI -> List(InstrI, FuType.alu, ALUOpType.sra),
// SRAI -> List(InstrI, FuType.alu, ALUOpType.sra),
ADD -> List(InstrR, FuType.alu, ALUOpType.add),
SLL -> List(InstrR, FuType.alu, ALUOpType.sll),
......@@ -67,14 +88,28 @@ object ALUInstr extends HasInstrType {
SRA -> List(InstrR, FuType.alu, ALUOpType.sra),
AUIPC -> List(InstrU, FuType.alu, ALUOpType.add),
LUI -> List(InstrU, FuType.alu, ALUOpType.add)
LUI -> List(InstrU, FuType.alu, ALUOpType.add),
ADDIW -> List(InstrI, FuType.alu, ALUOpType.addw),
SLLI -> List(InstrI, FuType.alu, ALUOpType.sll),
SRLI -> List(InstrI, FuType.alu, ALUOpType.srl),
SRAI -> List(InstrI, FuType.alu, ALUOpType.sra),
SLLIW -> List(InstrI, FuType.alu, ALUOpType.sllw),
SRLIW -> List(InstrI, FuType.alu, ALUOpType.srlw),
SRAIW -> List(InstrI, FuType.alu, ALUOpType.sraw),
SLLW -> List(InstrR, FuType.alu, ALUOpType.sllw),
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw)
)
}
class ALUIO extends FunctionUnitIO {
val cfIn = Flipped(new CtrlFlowIO)
val redirect = new RedirectIO
val offset = Input(UInt(32.W))
val offset = Input(UInt(64.W))
}
class ALU extends Module {
......@@ -89,22 +124,32 @@ class ALU extends Module {
io.out.bits
}
val isAdderSub = (func =/= ALUOpType.add) && !BRUOpType.isJump(func)
val adderRes = (src1 +& (src2 ^ Fill(32, isAdderSub))) + isAdderSub
val src132 = src1(31,0)
val src232 = src2(31,0)
val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) && !BRUOpType.isJump(func)
val adderRes = (src1 +& (src2 ^ Fill(64, isAdderSub))) + isAdderSub
val adderWRes = (src132 +& (src232 ^ Fill(32, isAdderSub))) + isAdderSub
val xorRes = src1 ^ src2
val sltu = !adderRes(32)
val slt = xorRes(31) ^ sltu
val sltu = !adderRes(64)
val slt = xorRes(63) ^ sltu
val shamt = src2(4, 0)
val shamt64 = src2(5, 0)//TODO
val aluRes = LookupTreeDefault(func, adderRes, List(
ALUOpType.sll -> ((src1 << shamt)(31, 0)),
ALUOpType.slt -> Cat(0.U(31.W), slt),
ALUOpType.sltu -> Cat(0.U(31.W), sltu),
ALUOpType.sll -> ((src1 << shamt64)(63, 0)),
ALUOpType.slt -> Cat(0.U(63.W), slt),
ALUOpType.sltu -> Cat(0.U(63.W), sltu),
ALUOpType.sllw -> Cat(Fill(32, (src132 << shamt)(31)), (src132 << shamt)(31, 0)),
ALUOpType.xor -> xorRes,
ALUOpType.srl -> (src1 >> shamt),
ALUOpType.srl -> (src1 >> shamt64),
ALUOpType.srlw -> Cat(Fill(32, (src132 >> shamt)(31)), (src132 >> shamt)(31,0)),
ALUOpType.or -> (src1 | src2),
ALUOpType.and -> (src1 & src2),
ALUOpType.sra -> ((src1.asSInt >> shamt).asUInt)
ALUOpType.sra -> ((src1.asSInt >> shamt64).asUInt),
ALUOpType.sraw -> Cat(Fill(32, (src132.asSInt >> shamt)(31)), ((src132.asSInt >> shamt).asUInt)),
ALUOpType.addw -> Cat(Fill(32, adderWRes(31)), adderWRes(31,0)),
ALUOpType.subw -> Cat(Fill(32, adderWRes(31)), adderWRes(31,0))
))
val branchOpTable = List(
......@@ -128,6 +173,12 @@ class ALU extends Module {
io.in.ready := true.B
io.out.valid := valid
Debug(){
when(io.out.valid){
printf("[ALU] func: %b 1: %x, 2: %x, out: %x\n", func, src1, src2, io.out.bits)
}
}
val bpuUpdateReq = WireInit(0.U.asTypeOf(new BPUUpdateReq))
bpuUpdateReq.valid := valid && isBru
bpuUpdateReq.pc := io.cfIn.pc
......
......@@ -7,20 +7,20 @@ import chisel3.util.experimental.BoringUtils
import utils._
object BRUOpType {
def jal = "b11000".U
def jalr = "b11010".U
def beq = "b10000".U
def bne = "b10001".U
def blt = "b10100".U
def bge = "b10101".U
def bltu = "b10110".U
def bgeu = "b10111".U
def jal = "b011000".U
def jalr = "b011010".U
def beq = "b010000".U
def bne = "b010001".U
def blt = "b010100".U
def bge = "b010101".U
def bltu = "b010110".U
def bgeu = "b010111".U
// for RAS
def call = "b11100".U
def ret = "b11110".U
def call = "b011100".U
def ret = "b011110".U
def isBru(func: UInt) = func(4)
def isBru(func: UInt) = func(4)//[important]
def isBranch(func: UInt) = !func(3)
def isJump(func: UInt) = isBru(func) && !isBranch(func)
def getBranchType(func: UInt) = func(2, 1)
......
package noop
//TODO(rv64)
import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils
......@@ -10,12 +10,15 @@ import bus.simplebus._
object LSUOpType {
def lb = "b0000".U
def lh = "b0001".U
def lw = "b0010".U
def lw = "b0111".U
def ld = "b0010".U
def lbu = "b0100".U
def lhu = "b0101".U
def lwu = "b0110".U
def sb = "b1000".U
def sh = "b1001".U
def sw = "b1010".U
def sd = "b1011".U
def isStore(func: UInt): Bool = func(3)
}
......@@ -29,21 +32,27 @@ object LSUInstr extends HasInstrType {
def SB = BitPat("b???????_?????_?????_000_?????_0100011")
def SH = BitPat("b???????_?????_?????_001_?????_0100011")
def SW = BitPat("b???????_?????_?????_010_?????_0100011")
def LWU = BitPat("b???????_?????_?????_110_?????_0000011")
def LD = BitPat("b???????_?????_?????_011_?????_0000011")
def SD = BitPat("b???????_?????_?????_011_?????_0100011")
val table = Array(
LB -> List(InstrI, FuType.lsu, LSUOpType.lb ),
LH -> List(InstrI, FuType.lsu, LSUOpType.lh ),
LW -> List(InstrI, FuType.lsu, LSUOpType.lw ),
LD -> List(InstrI, FuType.lsu, LSUOpType.ld ),
LBU -> List(InstrI, FuType.lsu, LSUOpType.lbu),
LHU -> List(InstrI, FuType.lsu, LSUOpType.lhu),
LWU -> List(InstrI, FuType.lsu, LSUOpType.lwu),
SB -> List(InstrS, FuType.lsu, LSUOpType.sb ),
SH -> List(InstrS, FuType.lsu, LSUOpType.sh ),
SW -> List(InstrS, FuType.lsu, LSUOpType.sw)
SW -> List(InstrS, FuType.lsu, LSUOpType.sw),
SD -> List(InstrS, FuType.lsu, LSUOpType.sd)
)
}
class LSUIO extends FunctionUnitIO {
val wdata = Input(UInt(32.W))
val wdata = Input(UInt(64.W))
val dmem = new SimpleBusUC
val mmio = new SimpleBusUC
val isMMIO = Output(Bool())
......@@ -63,16 +72,18 @@ class LSU extends Module {
def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
LookupTree(sizeEncode, List(
"b00".U -> 0x1.U,
"b01".U -> 0x3.U,
"b10".U -> 0xf.U
)) << addr(1, 0)
"b00".U -> 0x1.U, //0001 << addr(2:0)
"b01".U -> 0x3.U, //0011
"b10".U -> 0xf.U, //1111
"b11".U -> 0xff.U //11111111
)) << addr(2, 0)
}
def genWdata(data: UInt, sizeEncode: UInt): UInt = {
LookupTree(sizeEncode, List(
"b00".U -> Fill(4, data(7, 0)),
"b01".U -> Fill(2, data(15, 0)),
"b10".U -> data
"b00".U -> Fill(8, data(7, 0)),
"b01".U -> Fill(4, data(15, 0)),
"b10".U -> Fill(2, data(31, 0)),
"b11".U -> data
))
}
......@@ -85,7 +96,7 @@ class LSU extends Module {
val state = RegInit(s_idle)
val mmio = AddressSpace.isMMIO(addr)
val partialLoad = !isStore && (func =/= LSUOpType.lw)
val partialLoad = !isStore && (func =/= LSUOpType.ld)
switch (state) {
is (s_idle) { when (valid) {
......@@ -98,11 +109,11 @@ class LSU extends Module {
}
dmem.req.bits.addr := addr
dmem.req.bits.size := func(1, 0)
dmem.req.bits.size := func(2, 0)
dmem.req.valid := valid && (state === s_idle) && !mmio
dmem.req.bits.cmd := Mux(isStore, SimpleBusCmd.write, SimpleBusCmd.read)
dmem.req.bits.wdata := genWdata(io.wdata, func(1, 0))
dmem.req.bits.wmask := genWmask(addr, func(1, 0))
dmem.req.bits.wdata := genWdata(io.wdata, func(2, 0))
dmem.req.bits.wmask := genWmask(addr, func(2, 0))
dmem.req.bits.user := 0.U
dmem.resp.ready := true.B
......@@ -110,6 +121,46 @@ class LSU extends Module {
io.mmio.req.valid := valid && (state === s_idle) && mmio
io.mmio.resp.ready := true.B
Debug(true){
// when(isStore && (dmem.req.bits.wdata(31,0) === "h00003f00".U)){
// printf("TIME %d addr: %x dmem.req.bits.wdata %x, dmem.req.bits.wmask %x\n", GTimer(), addr, dmem.req.bits.wdata, dmem.req.bits.wmask)
// }
// when(isStore && (dmem.req.bits.wdata(31,0) === "h8018b120".U)){
// printf("TIME %d addr: %x dmem.req.bits.wdata %x, dmem.req.bits.wmask %x\n", GTimer(), addr, dmem.req.bits.wdata, dmem.req.bits.wmask)
// }
// when(isStore && (addr(31,0) === "h40600000".U)){
// printf("TIME %d addr: %x dmem.req.bits.wdata %x, dmem.req.bits.wmask %x im %x\n", GTimer(), addr, dmem.req.bits.wdata, dmem.req.bits.wmask, mmio)
// }
}
Debug(){
when(dmem.req.fire()){
printf("[LSU] (req) addr:%x data:%x wen:%b\n",addr, dmem.req.bits.wdata, isStore)
}
when(dmem.resp.fire()){
printf("[LSU] (resp) addr:%x data:%x wen:%b\n",addr, io.out.bits, isStore)
// printf("%x\n", rdata)
}
when(io.mmio.req.fire()){
printf("[LSU] (mmio req) addr:%x data:%x wen:%b\n",addr, dmem.req.bits.wdata, isStore)
}
when(io.mmio.resp.fire()){
printf("[LSU] (mmio resp) addr:%x data:%x wen:%b\n",addr, io.out.bits, isStore)
// printf("%x\n", rdata)
}
when(state===s_partialLoad){
printf("[LSU] (partialLoad) addr:%x data:%x wen:%b\n",addr, io.out.bits, isStore)
}
}
io.out.valid := Mux(isStore && !mmio, state === s_partialLoad, Mux(partialLoad, state === s_partialLoad,
Mux(mmio, io.mmio.resp.fire(), dmem.resp.fire() && (state === s_wait_resp))))
io.in.ready := (state === s_idle)
......@@ -117,17 +168,23 @@ class LSU extends Module {
val mmioLatch = RegNext(mmio)
val rdata = Mux(mmioLatch, io.mmio.resp.bits.rdata, dmem.resp.bits.rdata)
val rdataLatch = RegNext(rdata)
val rdataSel = LookupTree(addrLatch(1, 0), List(
"b00".U -> rdataLatch,
"b01".U -> rdataLatch(15, 8),
"b10".U -> rdataLatch(31, 16),
"b11".U -> rdataLatch(31, 24)
val rdataSel = LookupTree(addrLatch(2, 0), List(
"b000".U -> rdataLatch(63, 0),
"b001".U -> rdataLatch(63, 8),
"b010".U -> rdataLatch(63, 16),
"b011".U -> rdataLatch(63, 24),
"b100".U -> rdataLatch(63, 32),
"b101".U -> rdataLatch(63, 40),
"b110".U -> rdataLatch(63, 48),
"b111".U -> rdataLatch(63, 56)
))
val rdataPartialLoad = LookupTree(func, List(
LSUOpType.lb -> Cat(Fill(24, rdataSel(7)), rdataSel(7, 0)),
LSUOpType.lh -> Cat(Fill(16, rdataSel(15)), rdataSel(15, 0)),
LSUOpType.lbu -> Cat(0.U(24.W), rdataSel(7, 0)),
LSUOpType.lhu -> Cat(0.U(16.W), rdataSel(15, 0))
LSUOpType.lb -> Cat(Fill(24+32, rdataSel(7)), rdataSel(7, 0)),
LSUOpType.lh -> Cat(Fill(16+32, rdataSel(15)), rdataSel(15, 0)),
LSUOpType.lw -> Cat(Fill(32, rdataSel(31)), rdataSel(31, 0)),
LSUOpType.lbu -> Cat(0.U((24+32).W), rdataSel(7, 0)),
LSUOpType.lhu -> Cat(0.U((16+32).W), rdataSel(15, 0)),
LSUOpType.lwu -> Cat(0.U((32).W), rdataSel(31, 0))
))
io.out.bits := Mux(partialLoad, rdataPartialLoad, rdata)
......
......@@ -7,15 +7,22 @@ import chisel3.util.experimental.BoringUtils
import utils._
object MDUOpType {
def mul = "b000".U
def mulh = "b001".U
def div = "b100".U
def divu = "b101".U
def rem = "b110".U
def remu = "b111".U
def mul = "b0000".U
def mulh = "b0001".U
def div = "b0100".U
def divu = "b0101".U
def rem = "b0110".U
def remu = "b0111".U
def mulw = "b1000".U
def divw = "b1100".U
def divuw = "b1101".U
def remw = "b1110".U
def remuw = "b1111".U
def isDiv(op: UInt) = op(2)
def isSign(op: UInt) = isDiv(op) && !op(0)
def isW(op: UInt) = op(3)
}
object MDUInstr extends HasInstrType {
......@@ -25,16 +32,26 @@ object MDUInstr extends HasInstrType {
def DIVU = BitPat("b0000001_?????_?????_101_?????_0110011")
def REM = BitPat("b0000001_?????_?????_110_?????_0110011")
def REMU = BitPat("b0000001_?????_?????_111_?????_0110011")
def MULW = BitPat("b0000001_?????_?????_000_?????_0111011")
def DIVW = BitPat("b0000001_?????_?????_100_?????_0111011")
def DIVUW = BitPat("b0000001_?????_?????_101_?????_0111011")
def REMW = BitPat("b0000001_?????_?????_110_?????_0111011")
def REMUW = BitPat("b0000001_?????_?????_111_?????_0111011")
val mulTable = Array(
MUL -> List(InstrR, FuType.mdu, MDUOpType.mul),
MULH -> List(InstrR, FuType.mdu, MDUOpType.mulh)
MULH -> List(InstrR, FuType.mdu, MDUOpType.mulh),
MULW -> List(InstrR, FuType.mdu, MDUOpType.mulw)
)
val divTable = Array(
DIV -> List(InstrR, FuType.mdu, MDUOpType.div),
DIVU -> List(InstrR, FuType.mdu, MDUOpType.divu),
REM -> List(InstrR, FuType.mdu, MDUOpType.rem),
REMU -> List(InstrR, FuType.mdu, MDUOpType.remu)
REMU -> List(InstrR, FuType.mdu, MDUOpType.remu),
DIVW -> List(InstrR, FuType.mdu, MDUOpType.divw),
DIVUW -> List(InstrR, FuType.mdu, MDUOpType.divuw),
REMW -> List(InstrR, FuType.mdu, MDUOpType.remw),
REMUW -> List(InstrR, FuType.mdu, MDUOpType.remuw)
)
def table(implicit p: NOOPConfig) = mulTable ++ (if (p.HasDiv) divTable else Nil)
}
......@@ -64,7 +81,7 @@ class Multiplier(len: Int)(implicit val p: NOOPConfig) extends Module {
io.out.valid := mulPipeOut.valid
}
class Divider(len: Int = 32)(implicit val p: NOOPConfig) extends Module {
class Divider(len: Int = 64)(implicit val p: NOOPConfig) extends Module {
val io = IO(new MulDivIO(len))
val shiftReg = Reg(UInt((1 + len * 2).W))
......@@ -121,17 +138,28 @@ class MDU(implicit val p: NOOPConfig) extends Module {
io.out.bits
}
val mul = Module(new Multiplier(32))
val div = Module(new Divider(32))
val mul = Module(new Multiplier(64))
val div = Module(new Divider(64))
val mul32 = Module(new Multiplier(32))
val div32 = Module(new Divider(32))
List(mul.io, div.io).map { case x =>
x.in.bits(0) := src1
x.in.bits(1) := src2
x.sign := MDUOpType.isSign(func)
x.out.ready := io.out.ready
}
List(mul32.io, div32.io).map { case x =>
x.in.bits(0) := src1(31,0)
x.in.bits(1) := src2(31,0)
x.sign := MDUOpType.isSign(func)
x.out.ready := io.out.ready
}
val isDiv = MDUOpType.isDiv(func)
mul.io.in.valid := io.in.valid && !isDiv
div.io.in.valid := io.in.valid && isDiv
val isW = MDUOpType.isW(func)
mul.io.in.valid := io.in.valid && !isDiv && !isW
div.io.in.valid := io.in.valid && isDiv && !isW
mul32.io.in.valid := io.in.valid && !isDiv && isW
div32.io.in.valid := io.in.valid && isDiv && isW
io.out.bits := LookupTree(func, List(
MDUOpType.mul -> mul.io.out.bits(0),
......@@ -139,12 +167,18 @@ class MDU(implicit val p: NOOPConfig) extends Module {
MDUOpType.div -> div.io.out.bits(0),
MDUOpType.divu -> div.io.out.bits(0),
MDUOpType.rem -> div.io.out.bits(1),
MDUOpType.remu -> div.io.out.bits(1)
MDUOpType.remu -> div.io.out.bits(1),
MDUOpType.mulw -> Cat(Fill(32, mul32.io.out.bits(0)(31)), mul32.io.out.bits(0)),
MDUOpType.divw -> Cat(Fill(32, div32.io.out.bits(0)(31)), div32.io.out.bits(0)),
MDUOpType.divuw-> Cat(Fill(32, div32.io.out.bits(0)(31)), div32.io.out.bits(0)),//not sure: spec used "signed ext to describe this inst"
MDUOpType.remw -> Cat(Fill(32, div32.io.out.bits(1)(31)), div32.io.out.bits(1)),
MDUOpType.remuw-> Cat(Fill(32, div32.io.out.bits(1)(31)), div32.io.out.bits(1))
))
val isDivReg = Mux(io.in.fire(), isDiv, RegNext(isDiv))
io.in.ready := Mux(isDiv, div.io.in.ready, mul.io.in.ready)
io.out.valid := Mux(isDivReg, div.io.out.valid, mul.io.out.valid)
io.out.valid := Mux(isDivReg, div.io.out.valid || div32.io.out.valid, mul.io.out.valid || mul32.io.out.valid)
BoringUtils.addSource(mul.io.out.fire(), "perfCntCondMmulInstr")
}
......@@ -7,7 +7,7 @@ import utils._
import bus.simplebus._
trait HasCoherenceConst {
val supportCoh = true
val supportCoh = false
}
class CoherenceInterconnect extends Module with HasCoherenceConst {
......@@ -32,7 +32,7 @@ class CoherenceInterconnect extends Module with HasCoherenceConst {
val inflightSrc = Reg(UInt(1.W)) // 0 - icache, 1 - dcache
val lockWriteFun = ((x: SimpleBusReqBundle) => x.isWrite())
val inputArb = Module(new LockingArbiter(chiselTypeOf(io.in(0).mem.req.bits), 2, 8, Some(lockWriteFun)))
val inputArb = Module(new LockingArbiter(chiselTypeOf(io.in(0).mem.req.bits), 2, 4, Some(lockWriteFun)))
(inputArb.io.in zip io.in.map(_.mem.req)).map{ case (arb, in) => arb <> in }
val thisReq = inputArb.io.out
......
......@@ -7,7 +7,7 @@ import noop.NOOPConfig
object Debug {
def apply(flag: Boolean = NOOPConfig().EnableDebug, cond: Bool = true.B)(body: => Unit): Any =
if (flag) { when (cond && GTimer() > 1020.U) { body } }
if (flag) { when (cond && GTimer() > 0.U && GTimer() < 1200.U) { body } }
}
object ShowType {
......
......@@ -4,8 +4,8 @@ import chisel3._
import chisel3.util._
class DiffTestIO extends Bundle {
val r = Output(Vec(32, UInt(32.W)))
val r = Output(Vec(32, UInt(64.W)))
val commit = Output(Bool())
val thisPC = Output(UInt(32.W))
val thisPC = Output(UInt(64.W))
val isMMIO = Output(Bool())
}
......@@ -10,7 +10,7 @@ uint32_t screen_size(void);
void set_abort(void);
static struct timeval boot = {};
static uint32_t vmem[0x400000 / sizeof(uint32_t)];
static uint64_t vmem[0x400000 / sizeof(uint64_t)];
void init_device(void) {
init_sdl();
......@@ -51,7 +51,7 @@ uint32_t uptime(void) {
}
extern "C" void device_helper(
uint8_t req_wen, uint32_t req_addr, uint32_t req_wdata, uint8_t req_wmask, uint32_t *resp_rdata) {
uint8_t req_wen, uint64_t req_addr, uint64_t req_wdata, uint8_t req_wmask, uint64_t *resp_rdata) {
switch (req_addr) {
// read uartlite stat register
case 0x40600008:
......@@ -70,10 +70,10 @@ extern "C" void device_helper(
default:
if (req_addr >= 0x40000000 && req_addr < 0x40400000 && req_wen) {
// write to vmem
vmem[(req_addr - 0x40000000) / sizeof(uint32_t)] = req_wdata;
vmem[(req_addr - 0x40000000) / sizeof(uint64_t)] = req_wdata;
}
else {
eprintf("bad address = 0x%08x, wen = %d\n", req_addr, req_wen);
eprintf("bad address = 0x%08x, wen = %d\n", (uint32_t)req_addr, req_wen);
assert(0);
}
}
......
......@@ -33,7 +33,7 @@ void difftest_skip_dut() {
is_skip_dut = true;
}
void init_difftest(uint32_t *reg, const char *mainargs) {
void init_difftest(uint64_t *reg, const char *mainargs) {
void *handle;
handle = dlopen(REF_SO, RTLD_LAZY | RTLD_DEEPBIND);
assert(handle);
......@@ -64,11 +64,11 @@ void init_difftest(uint32_t *reg, const char *mainargs) {
ref_difftest_setregs(reg);
}
int difftest_step(uint32_t *reg_scala, uint32_t this_pc, int isMMIO) {
uint32_t ref_r[33];
static uint32_t nemu_pc = 0x80100000;
int difftest_step(uint64_t *reg_scala, uint64_t this_pc, int isMMIO) {
uint64_t ref_r[33];
static uint64_t nemu_pc = 0x80100000;
if (isMMIO) {
// printf("diff pc: %x\n", this_pc);
// MMIO accessing should not be a branch or jump, just +4 to get the next pc
reg_scala[32] += 4;
nemu_pc += 4;
......@@ -80,7 +80,7 @@ int difftest_step(uint32_t *reg_scala, uint32_t this_pc, int isMMIO) {
ref_difftest_exec(1);
ref_difftest_getregs(&ref_r);
uint32_t temp = ref_r[32];
uint64_t temp = ref_r[32];
ref_r[32] = nemu_pc;
nemu_pc = temp;
......@@ -89,7 +89,7 @@ int difftest_step(uint32_t *reg_scala, uint32_t this_pc, int isMMIO) {
int i;
for (i = 0; i < 33; i ++) {
if (reg_scala[i] != ref_r[i]) {
printf("x%2d different at pc = 0x%08x, right= 0x%08x, wrong = 0x%08x\n",
printf("x%2d different at pc = 0x%08lx, right= 0x%016lx, wrong = 0x%016lx\n",
i, this_pc, ref_r[i], reg_scala[i]);
}
}
......
......@@ -5,10 +5,10 @@
#include <assert.h>
#include <string.h>
typedef uint32_t rtlreg_t;
typedef uint64_t rtlreg_t;
typedef uint32_t paddr_t;
typedef uint32_t vaddr_t;
typedef uint64_t paddr_t;
typedef uint64_t vaddr_t;
typedef uint16_t ioaddr_t;
......
......@@ -24,7 +24,7 @@ class Emulator {
static const struct option long_options[];
static void print_help(const char *file);
void read_emu_regs(uint32_t *r) {
void read_emu_regs(uint64_t *r) {
#define macro(x) r[x] = dut_ptr->io_difftest_r_##x
macro(0); macro(1); macro(2); macro(3); macro(4); macro(5); macro(6); macro(7);
macro(8); macro(9); macro(10); macro(11); macro(12); macro(13); macro(14); macro(15);
......@@ -60,8 +60,8 @@ class Emulator {
// init core
reset_ncycles(10);
extern void init_difftest(uint32_t *reg, const char *mainargs);
uint32_t reg[33];
extern void init_difftest(uint64_t *reg, const char *mainargs);
uint64_t reg[33];
read_emu_regs(reg);
reg[32] = 0x80100000;
init_difftest(reg, mainargs);
......@@ -108,10 +108,10 @@ class Emulator {
// difftest
if (dut_ptr->io_difftest_commit) {
uint32_t reg[33];
uint64_t reg[33];
read_emu_regs(reg);
extern int difftest_step(uint32_t *reg_scala, uint32_t this_pc, int isMMIO);
extern int difftest_step(uint64_t *reg_scala, uint64_t this_pc, int isMMIO);
if (difftest_step(reg, dut_ptr->io_difftest_thisPC, dut_ptr->io_difftest_isMMIO)) {
set_abort();
}
......
......@@ -8,12 +8,12 @@ enum {
};
static int g_trapCode = STATE_RUNNING;
static int g_trapPC = 0;
static uint64_t g_trapPC = 0;
static int g_cycleCnt = 0, g_instrCnt = 0;
bool is_finish() { return g_trapCode != STATE_RUNNING; }
extern "C" void monitor(int trapCode, int trapPC, int cycleCnt, int instrCnt) {
extern "C" void monitor(int trapCode, uint64_t trapPC, int cycleCnt, int instrCnt) {
g_trapCode = trapCode;
g_trapPC = trapPC;
g_cycleCnt = cycleCnt;
......@@ -41,6 +41,7 @@ int display_trapinfo(long long max_cycles) {
}
double ipc = (double)g_instrCnt / g_cycleCnt;
eprintf(ANSI_COLOR_MAGENTA "total guest instructions = %d\n" ANSI_COLOR_RESET, g_instrCnt);
eprintf(ANSI_COLOR_MAGENTA "instrCnt = %d, cycleCnt = %d, IPC = %lf\n" ANSI_COLOR_RESET,
g_instrCnt, g_cycleCnt, ipc);
return g_trapCode != STATE_GOODTRAP;
......
......@@ -2,9 +2,9 @@
#define RAMSIZE (128 * 1024 * 1024)
static uint32_t ram[RAMSIZE / sizeof(uint32_t)];
static uint64_t ram[RAMSIZE / sizeof(uint64_t)];
static long img_size = 0;
void* get_img_start() { return &ram[0x100000 / sizeof(uint32_t)]; }
void* get_img_start() { return &ram[0x100000 / sizeof(uint64_t)]; }
long get_img_size() { return img_size; }
void init_ram(const char *img, const char *mainargs) {
......@@ -29,7 +29,7 @@ void init_ram(const char *img, const char *mainargs) {
}
extern "C" void ram_helper(
uint32_t rIdx, uint32_t *rdata, uint32_t wIdx, uint32_t wdata, uint32_t wmask, uint8_t wen) {
uint64_t rIdx, uint64_t *rdata, uint64_t wIdx, uint64_t wdata, uint64_t wmask, uint8_t wen) {
*rdata = ram[rIdx];
if (wen) { ram[wIdx] = (ram[wIdx] & ~wmask) | (wdata & wmask); }
}
......@@ -11,10 +11,10 @@ class DeviceHelper extends BlackBox {
val reset = Input(Bool())
val reqValid = Input(Bool())
val reqWen = Input(Bool())
val reqAddr = Input(UInt(32.W))
val reqWdata = Input(UInt(32.W))
val reqWmask = Input(UInt(4.W))
val respRdata = Output(UInt(32.W))
val reqAddr = Input(UInt(64.W))
val reqWdata = Input(UInt(64.W))
val reqWmask = Input(UInt(8.W))
val respRdata = Output(UInt(64.W))
})
}
......
import "DPI-C" function void device_helper
(
input bit req_wen,
input int req_addr,
input int req_wdata,
input longint req_addr,
input longint req_wdata,
input byte req_wmask,
output int resp_rdata
output longint resp_rdata
);
module DeviceHelper(
......@@ -12,14 +12,14 @@ module DeviceHelper(
input reset,
input reqValid,
input reqWen,
input [31:0] reqAddr,
input [31:0] reqWdata,
input [3:0] reqWmask,
output [31:0] respRdata
input [63:0] reqAddr,
input [63:0] reqWdata,
input [7:0] reqWmask,
output [63:0] respRdata
);
always @(posedge clk) begin
if (reqValid && !reset) device_helper(reqWen, reqAddr, reqWdata, {4'b0, reqWmask}, respRdata);
if (reqValid && !reset) device_helper(reqWen, reqAddr, reqWdata, reqWmask, respRdata);
end
endmodule
......@@ -2,7 +2,7 @@
import "DPI-C" function void monitor
(
input int trapCode,
input int trapPC,
input longint trapPC,
input int cycleCnt,
input int instrCnt
);
......@@ -13,7 +13,7 @@ module Monitor(
input reset,
input isNoopTrap,
input [31:0] trapCode,
input [31:0] trapPC,
input [63:0] trapPC,
input [31:0] cycleCnt,
input [31:0] instrCnt
);
......
import "DPI-C" function void ram_helper
(
input int rIdx,
output int rdata,
input int wIdx,
input int wdata,
input int wmask,
input longint rIdx,
output longint rdata,
input longint wIdx,
input longint wdata,
input longint wmask,
input bit wen
);
module RAMHelper(
input clk,
input [31:0] rIdx,
output [31:0] rdata,
input [31:0] wIdx,
input [31:0] wdata,
input [31:0] wmask,
input [63:0] rIdx,
output [63:0] rdata,
input [63:0] wIdx,
input [63:0] wdata,
input [63:0] wmask,
input wen
);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册