diff --git a/build.sc b/build.sc index 86b3d745c..112ae9209 100644 --- a/build.sc +++ b/build.sc @@ -10,7 +10,8 @@ object ivys { trait CommonModule extends ScalaModule { override def scalaVersion = ivys.scala - override def scalacOptions = Seq("-Ymacro-annotations") + override def scalacOptions = Seq("-Ymacro-annotations") ++ + Seq("-Xfatal-warnings", "-feature", "-deprecation", "-language:reflectiveCalls") } trait HasChisel3 extends ScalaModule { diff --git a/difftest b/difftest index b0bb8d51a..360927487 160000 --- a/difftest +++ b/difftest @@ -1 +1 @@ -Subproject commit b0bb8d51a4bd3d41fce295ed38e40f4798ce5583 +Subproject commit 360927487041c9a200991da09d398614eb376167 diff --git a/src/main/scala/bus/axi4/AXI4.scala b/src/main/scala/bus/axi4/AXI4.scala index 3e6e663b1..683ce6c0e 100644 --- a/src/main/scala/bus/axi4/AXI4.scala +++ b/src/main/scala/bus/axi4/AXI4.scala @@ -122,10 +122,10 @@ class AXI4(val dataBits: Int = AXI4Parameters.dataBits, val idBits: Int = AXI4Pa override val r = Flipped(Decoupled(new AXI4BundleR(dataBits, idBits))) def dump(name: String) = { - when (aw.fire()) { printf(p"${GTimer()},[${name}.aw] ${aw.bits}\n") } - when (w.fire()) { printf(p"${GTimer()},[${name}.w] ${w.bits}\n") } - when (b.fire()) { printf(p"${GTimer()},[${name}.b] ${b.bits}\n") } - when (ar.fire()) { printf(p"${GTimer()},[${name}.ar] ${ar.bits}\n") } - when (r.fire()) { printf(p"${GTimer()},[${name}.r] ${r.bits}\n") } + when (aw.fire) { printf(p"${GTimer()},[${name}.aw] ${aw.bits}\n") } + when (w.fire) { printf(p"${GTimer()},[${name}.w] ${w.bits}\n") } + when (b.fire) { printf(p"${GTimer()},[${name}.b] ${b.bits}\n") } + when (ar.fire) { printf(p"${GTimer()},[${name}.ar] ${ar.bits}\n") } + when (r.fire) { printf(p"${GTimer()},[${name}.r] ${r.bits}\n") } } } diff --git a/src/main/scala/bus/simplebus/Crossbar.scala b/src/main/scala/bus/simplebus/Crossbar.scala index e2b2d535b..815d88855 100644 --- a/src/main/scala/bus/simplebus/Crossbar.scala +++ b/src/main/scala/bus/simplebus/Crossbar.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package bus.simplebus @@ -36,9 +36,9 @@ class SimpleBusCrossbar1toN(addressSpace: List[(Long, Long)]) extends Module { val outMatchVec = VecInit(addressSpace.map( range => (addr >= range._1.U && addr < (range._1 + range._2).U))) val outSelVec = VecInit(PriorityEncoderOH(outMatchVec)) - val outSelRespVec = RegEnable(next=outSelVec, - init=VecInit(Seq.fill(outSelVec.length)(false.B)), - enable=io.in.req.fire() && state === s_idle) + val outSelRespVec = RegEnable(outSelVec, + VecInit(Seq.fill(outSelVec.length)(false.B)), + io.in.req.fire && state === s_idle) val reqInvalidAddr = io.in.req.valid && !outSelVec.asUInt.orR when (reqInvalidAddr) { @@ -50,11 +50,11 @@ class SimpleBusCrossbar1toN(addressSpace: List[(Long, Long)]) extends Module { switch (state) { is (s_idle) { - when (io.in.req.fire()) { state := s_resp } + when (io.in.req.fire) { state := s_resp } when (reqInvalidAddr) { state := s_error } } - is (s_resp) { when (io.in.resp.fire()) { state := s_idle } } - is (s_error) { when (io.in.resp.fire()) { state := s_idle } } + is (s_resp) { when (io.in.resp.fire) { state := s_idle } } + is (s_error) { when (io.in.resp.fire) { state := s_idle } } } // bind out.req channel @@ -73,10 +73,10 @@ class SimpleBusCrossbar1toN(addressSpace: List[(Long, Long)]) extends Module { // io.in.resp.bits.exc.get := state === s_error Debug() { - when (io.in.req.fire()) { + when (io.in.req.fire) { printf(p"${GTimer()}: xbar: outSelVec = ${outSelVec}, outSel.req: ${io.in.req.bits}\n") } - when (io.in.resp.fire()) { + when (io.in.resp.fire) { printf(p"${GTimer()}: xbar: outSelVec = ${outSelVec}, outSel.resp: ${io.in.resp.bits}\n") } } @@ -112,14 +112,14 @@ class SimpleBusCrossbarNto1(n: Int, userBits:Int = 0) extends Module { switch (state) { is (s_idle) { - when (thisReq.fire()) { + when (thisReq.fire) { inflightSrc := inputArb.io.chosen when (thisReq.bits.isRead()) { state := s_readResp } .elsewhen (thisReq.bits.isWriteLast() || thisReq.bits.isWriteSingle()) { state := s_writeResp } } } - is (s_readResp) { when (io.out.resp.fire() && io.out.resp.bits.isReadLast()) { state := s_idle } } - is (s_writeResp) { when (io.out.resp.fire()) { state := s_idle } } + is (s_readResp) { when (io.out.resp.fire && io.out.resp.bits.isReadLast) { state := s_idle } } + is (s_writeResp) { when (io.out.resp.fire) { state := s_idle } } } } @@ -142,7 +142,7 @@ class SimpleBusAutoIDCrossbarNto1(n: Int, userBits: Int = 0) extends Module { val out = new SimpleBusUC(userBits, idBits = n) }) - // Note: to use SimpleBusAutoIDCrossbarNto1, every master device must ensure resp.ready is always true + // Note: to use SimpleBusAutoIDCrossbarNto1, every master device must ensure resp.ready is always true val reqValid = WireInit(VecInit(List.tabulate(n)(i => io.in(i).req.valid))) val reqSelect = PriorityEncoder(reqValid.asUInt) @@ -160,7 +160,7 @@ class SimpleBusAutoIDCrossbarNto1(n: Int, userBits: Int = 0) extends Module { } io.out.req.valid := reqValid.asUInt.orR - io.out.req.bits.id.get := reqSelectVec.asUInt // Simple bus ID is OH + io.out.req.bits.id.get := reqSelectVec.asUInt // Simple bus ID is OH io.out.resp.ready := true.B // io.in(reqSelect).resp.ready // assert(io.out.resp.ready) @@ -175,10 +175,10 @@ class SimpleBusAutoIDCrossbarNto1(n: Int, userBits: Int = 0) extends Module { } Debug(){ - when(io.out.req.fire()){ + when(io.out.req.fire){ printf("[Crossbar REQ] addr %x cmd %x select %b\n", io.out.req.bits.addr, io.out.req.bits.cmd, reqSelectVec) } - when(io.out.resp.fire()){ + when(io.out.resp.fire){ printf("[Crossbar RESP] data %x select %b\n", io.out.resp.bits.rdata, io.out.resp.bits.id.get) } } diff --git a/src/main/scala/bus/simplebus/DistributedMem.scala b/src/main/scala/bus/simplebus/DistributedMem.scala index 99931b7bc..ba12e24e4 100644 --- a/src/main/scala/bus/simplebus/DistributedMem.scala +++ b/src/main/scala/bus/simplebus/DistributedMem.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package bus.simplebus @@ -29,14 +29,14 @@ class DistributedMem(memByte: Int, dualPort: Boolean, delayCycles: Int = 0, data val ro = Flipped(new SimpleBusUC) }) - val wordNum = memByte / 8 + val wordNum = memByte / 8 val nBank = XLEN / 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 wen = io.rw.isWrite val wdataVec = VecInit.tabulate(nBank) { i => io.rw.req.bits.wdata(8 * (i + 1) - 1, 8 * i) } val wmask = VecInit.tabulate(nBank) { i => io.rw.req.bits.wmask(i).asBool } @@ -56,16 +56,16 @@ class DistributedMem(memByte: Int, dualPort: Boolean, delayCycles: Int = 0, data val state = RegInit(s_idle) switch (state) { is (s_idle) { - when (p.req.fire()) { state := Mux(p.resp.fire(), s_idle, s_reading) } + when (p.req.fire) { state := Mux(p.resp.fire, s_idle, s_reading) } } is (s_reading) { - when (p.resp.fire()) { state := s_idle } + when (p.resp.fire) { state := s_idle } } } p.req.ready := state === s_idle p.resp.bits.rdata := rdata - p.resp.valid := (if (delayCycles == 0) p.req.fire() else Counter(state === s_reading, delayCycles)._2) + p.resp.valid := (if (delayCycles == 0) p.req.fire else Counter(state === s_reading, delayCycles)._2) } readPort(io.rw, rwData) diff --git a/src/main/scala/bus/simplebus/SimpleBus.scala b/src/main/scala/bus/simplebus/SimpleBus.scala index 320072e78..757411ccc 100644 --- a/src/main/scala/bus/simplebus/SimpleBus.scala +++ b/src/main/scala/bus/simplebus/SimpleBus.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package bus.simplebus @@ -60,7 +60,7 @@ class SimpleBusReqBundle(val userBits: Int = 0, val addrBits: Int = 32, val idBi p"wmask = 0x${Hexadecimal(wmask)}, wdata = 0x${Hexadecimal(wdata)}" } - def apply(addr: UInt, cmd: UInt, size: UInt, wdata: UInt, wmask: UInt, user: UInt = 0.U, id: UInt = 0.U) { + def apply(addr: UInt, cmd: UInt, size: UInt, wdata: UInt, wmask: UInt, user: UInt = 0.U, id: UInt = 0.U) = { this.addr := addr this.cmd := cmd this.size := size @@ -88,11 +88,11 @@ class SimpleBusRespBundle(val userBits: Int = 0, val idBits: Int = 0) extends Si override def toPrintable: Printable = p"rdata = ${Hexadecimal(rdata)}, cmd = ${cmd}" - def isReadLast() = cmd === SimpleBusCmd.readLast - def isProbeHit() = cmd === SimpleBusCmd.probeHit - def isProbeMiss() = cmd === SimpleBusCmd.probeMiss - def isWriteResp() = cmd === SimpleBusCmd.writeResp - def isPrefetch() = cmd === SimpleBusCmd.prefetch + def isReadLast = cmd === SimpleBusCmd.readLast + def isProbeHit = cmd === SimpleBusCmd.probeHit + def isProbeMiss = cmd === SimpleBusCmd.probeMiss + def isWriteResp = cmd === SimpleBusCmd.writeResp + def isPrefetch = cmd === SimpleBusCmd.prefetch } // Uncache @@ -100,15 +100,15 @@ class SimpleBusUC(val userBits: Int = 0, val addrBits: Int = 32, val idBits: Int val req = Decoupled(new SimpleBusReqBundle(userBits, addrBits, idBits)) val resp = Flipped(Decoupled(new SimpleBusRespBundle(userBits, idBits))) - def isWrite() = req.valid && req.bits.isWrite() - def isRead() = req.valid && req.bits.isRead() - def toAXI4Lite() = SimpleBus2AXI4Converter(this, new AXI4Lite, false) + def isWrite = req.valid && req.bits.isWrite() + def isRead = req.valid && req.bits.isRead() + def toAXI4Lite = SimpleBus2AXI4Converter(this, new AXI4Lite, false) def toAXI4(isFromCache: Boolean = false) = SimpleBus2AXI4Converter(this, new AXI4, isFromCache) - def toMemPort() = SimpleBus2MemPortConverter(this, new MemPortIo(32)) + def toMemPort = SimpleBus2MemPortConverter(this, new MemPortIo(32)) def dump(name: String) = { - when (req.fire()) { printf(p"${GTimer()},[${name}] ${req.bits}\n") } - when (resp.fire()) { printf(p"${GTimer()},[${name}] ${resp.bits}\n") } + when (req.fire) { printf(p"${GTimer()},[${name}] ${req.bits}\n") } + when (resp.fire) { printf(p"${GTimer()},[${name}] ${resp.bits}\n") } } } @@ -121,10 +121,10 @@ class SimpleBusUCExpender(val userBits: Int, val userVal: UInt, val addrBits: In io.out.req.valid := io.in.req.valid io.in.req.ready := io.out.req.ready io.out.req.bits.addr := io.in.req.bits.addr - io.out.req.bits.size := io.in.req.bits.size - io.out.req.bits.cmd := io.in.req.bits.cmd - io.out.req.bits.wmask := io.in.req.bits.wmask - io.out.req.bits.wdata := io.in.req.bits.wdata + io.out.req.bits.size := io.in.req.bits.size + io.out.req.bits.cmd := io.in.req.bits.cmd + io.out.req.bits.wmask := io.in.req.bits.wmask + io.out.req.bits.wdata := io.in.req.bits.wdata io.out.req.bits.user.get := userVal io.in.resp.valid := io.out.resp.valid io.out.resp.ready := io.in.resp.ready diff --git a/src/main/scala/bus/simplebus/ToAXI4.scala b/src/main/scala/bus/simplebus/ToAXI4.scala index f4364c1ae..b88b9b7e5 100644 --- a/src/main/scala/bus/simplebus/ToAXI4.scala +++ b/src/main/scala/bus/simplebus/ToAXI4.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package bus.simplebus @@ -102,7 +102,7 @@ class AXI42SimpleBusConverter() extends Module { } } - when (isState(axi_write) && axi.w.fire()) { + when (isState(axi_write) && axi.w.fire) { mem.req.valid := true.B req.cmd := Mux(aw_reg.len === 0.U, SimpleBusCmd.write, Mux(w.last, SimpleBusCmd.writeLast, SimpleBusCmd.writeBurst)) @@ -134,11 +134,11 @@ class AXI42SimpleBusConverter() extends Module { axi.b.valid := bresp_en && mem.resp.valid axi.b.bits.resp := AXI4Parameters.RESP_OKAY - when (axi.ar.fire()) { assert(mem.req.fire() && !isInflight()); } - when (axi.aw.fire()) { assert(!isInflight()); } - when (axi.w.fire()) { assert(mem.req .fire() && isState(axi_write)); } - when (axi.b.fire()) { assert(mem.resp.fire() && isState(axi_write)); } - when (axi.r.fire()) { assert(mem.resp.fire() && isState(axi_read)); } + when (axi.ar.fire) { assert(mem.req.fire && !isInflight()); } + when (axi.aw.fire) { assert(!isInflight()); } + when (axi.w.fire) { assert(mem.req .fire && isState(axi_write)); } + when (axi.b.fire) { assert(mem.resp.fire && isState(axi_write)); } + when (axi.r.fire) { assert(mem.resp.fire && isState(axi_read)); } } @@ -184,14 +184,14 @@ class SimpleBus2AXI4Converter[OT <: AXI4Lite](outType: OT, isFromCache: Boolean) mem.resp.bits.cmd := Mux(rlast, SimpleBusCmd.readLast, 0.U) val wSend = Wire(Bool()) - val awAck = BoolStopWatch(axi.aw.fire(), wSend) - val wAck = BoolStopWatch(axi.w.fire() && wlast, wSend) - wSend := (axi.aw.fire() && axi.w.fire() && wlast) || (awAck && wAck) - val wen = RegEnable(mem.req.bits.isWrite(), mem.req.fire()) - - axi.ar.valid := mem.isRead() - axi.aw.valid := mem.isWrite() && !awAck - axi.w .valid := mem.isWrite() && !wAck + val awAck = BoolStopWatch(axi.aw.fire, wSend) + val wAck = BoolStopWatch(axi.w.fire && wlast, wSend) + wSend := (axi.aw.fire && axi.w.fire && wlast) || (awAck && wAck) + val wen = RegEnable(mem.req.bits.isWrite(), mem.req.fire) + + axi.ar.valid := mem.isRead + axi.aw.valid := mem.isWrite && !awAck + axi.w .valid := mem.isWrite && !wAck mem.req.ready := Mux(mem.req.bits.isWrite(), !wAck && axi.w.ready, axi.ar.ready) axi.r.ready := mem.resp.ready diff --git a/src/main/scala/device/AXI4CLINT.scala b/src/main/scala/device/AXI4CLINT.scala index 776203141..00de7af70 100644 --- a/src/main/scala/device/AXI4CLINT.scala +++ b/src/main/scala/device/AXI4CLINT.scala @@ -61,7 +61,7 @@ class AXI4CLINT(sim: Boolean = false) extends AXI4SlaveModule(new AXI4Lite, new def getOffset(addr: UInt) = addr(15,0) RegMap.generate(mapping, getOffset(raddr), in.r.bits.data, - getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb)) + getOffset(waddr), in.w.fire, in.w.bits.data, MaskExpand(in.w.bits.strb)) io.extra.get.mtip := RegNext(mtime >= mtimecmp) io.extra.get.msip := RegNext(msip =/= 0.U) diff --git a/src/main/scala/device/AXI4DMA.scala b/src/main/scala/device/AXI4DMA.scala index 8f6d7bd66..c1b463132 100644 --- a/src/main/scala/device/AXI4DMA.scala +++ b/src/main/scala/device/AXI4DMA.scala @@ -50,20 +50,20 @@ class AXI4DMA extends AXI4SlaveModule(new AXI4Lite, new DMABundle) { } } when (state === s_idle && len =/= 0.U) { state := s_read_req } - when (state === s_read_req && dma.ar.fire()) { state := s_read_wait_resp } - when (state === s_read_wait_resp && dma.r.fire()) { + when (state === s_read_req && dma.ar.fire) { state := s_read_wait_resp } + when (state === s_read_wait_resp && dma.r.fire) { data := dma.r.bits.data.asTypeOf(Vec(8 / step, UInt(stepBits.W)))(src(2, log2Ceil(step))) state := s_write_req } val wSend = Wire(Bool()) val wlast = dma.w.bits.last - val awAck = BoolStopWatch(dma.aw.fire(), wSend) - val wAck = BoolStopWatch(dma.w.fire() && wlast, wSend) - wSend := (dma.aw.fire() && dma.w.fire() && wlast) || (awAck && wAck) + val awAck = BoolStopWatch(dma.aw.fire, wSend) + val wAck = BoolStopWatch(dma.w.fire && wlast, wSend) + wSend := (dma.aw.fire && dma.w.fire && wlast) || (awAck && wAck) when (state === s_write_req && wSend) { state := s_write_wait_resp } - when (state === s_write_wait_resp && dma.b.fire()) { + when (state === s_write_wait_resp && dma.b.fire) { len := len - step.U dest := dest + step.U src := src + step.U @@ -99,6 +99,6 @@ class AXI4DMA extends AXI4SlaveModule(new AXI4Lite, new DMABundle) { ) RegMap.generate(mapping, raddr(3,0), in.r.bits.data, - waddr(3,0), in.w.fire(), in.w.bits.data(31, 0), MaskExpand(in.w.bits.strb >> waddr(2, 0))(31, 0) + waddr(3,0), in.w.fire, in.w.bits.data(31, 0), MaskExpand(in.w.bits.strb >> waddr(2, 0))(31, 0) ) } diff --git a/src/main/scala/device/AXI4DummySD.scala b/src/main/scala/device/AXI4DummySD.scala index 62ed150bb..f2664931c 100644 --- a/src/main/scala/device/AXI4DummySD.scala +++ b/src/main/scala/device/AXI4DummySD.scala @@ -113,7 +113,7 @@ class AXI4DummySD extends AXI4SlaveModule(new AXI4Lite) with HasSDConst { val sdHelper = Module(new SDHelper) sdHelper.io.clk := clock - sdHelper.io.ren := (getOffset(raddr) === 0x40.U && io.in.ar.fire()) + sdHelper.io.ren := (getOffset(raddr) === 0x40.U && io.in.ar.fire) sdHelper.io.setAddr := setAddr sdHelper.io.addr := regs(sdarg) def sdRead = sdHelper.io.data @@ -138,7 +138,7 @@ class AXI4DummySD extends AXI4SlaveModule(new AXI4Lite) with HasSDConst { else Mux(waddr(2), in.w.bits.strb(7,4), in.w.bits.strb(3,0)) val rdata = Wire(UInt(DataBits.W)) RegMap.generate(mapping, getOffset(raddr), rdata, - getOffset(waddr), in.w.fire(), in.w.bits.data(31, 0), MaskExpand(strb)) + getOffset(waddr), in.w.fire, in.w.bits.data(31, 0), MaskExpand(strb)) in.r.bits.data := (if (DataBits == 32) RegEnable(RegNext(rdata(31,0)), ren) else RegEnable(RegNext(Fill(2, rdata(31,0))), ren)) diff --git a/src/main/scala/device/AXI4Flash.scala b/src/main/scala/device/AXI4Flash.scala index b79bf5b5d..6ca9c2b72 100644 --- a/src/main/scala/device/AXI4Flash.scala +++ b/src/main/scala/device/AXI4Flash.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package device @@ -36,7 +36,7 @@ class AXI4Flash extends AXI4SlaveModule(new AXI4Lite) { val rdata = Wire(UInt(64.W)) RegMap.generate(mapping, getOffset(raddr), rdata, - getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb)) + getOffset(waddr), in.w.fire, in.w.bits.data, MaskExpand(in.w.bits.strb)) in.r.bits.data := RegEnable(RegNext(Fill(2, rdata(31,0))), ren) } diff --git a/src/main/scala/device/AXI4PLIC.scala b/src/main/scala/device/AXI4PLIC.scala index f334b8440..5213bc240 100644 --- a/src/main/scala/device/AXI4PLIC.scala +++ b/src/main/scala/device/AXI4PLIC.scala @@ -65,7 +65,7 @@ class AXI4PLIC(nrIntr: Int, nrHart: Int) extends AXI4SlaveModule(new AXI4Lite, n val claimCompletionMap = claimCompletion.zipWithIndex.map { case (r, hart) => { val addr = 0x200004 + hart * 0x1000 - when (in.r.fire() && (getOffset(raddr) === addr.U)) { inHandle(r) := true.B } + when (in.r.fire && (getOffset(raddr) === addr.U)) { inHandle(r) := true.B } RegMap(addr, r, completionFn) } }.toMap @@ -86,7 +86,7 @@ class AXI4PLIC(nrIntr: Int, nrHart: Int) extends AXI4SlaveModule(new AXI4Lite, n val rdata = Wire(UInt(32.W)) RegMap.generate(mapping, getOffset(raddr), rdata, - getOffset(waddr), in.w.fire(), in.w.bits.data(31, 0), + getOffset(waddr), in.w.fire, in.w.bits.data(31, 0), MaskExpand(in.w.bits.strb >> waddr(2,0))(31, 0) ) // narrow read diff --git a/src/main/scala/device/AXI4RAM.scala b/src/main/scala/device/AXI4RAM.scala index ff6b4e59b..c43e1e226 100644 --- a/src/main/scala/device/AXI4RAM.scala +++ b/src/main/scala/device/AXI4RAM.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package device @@ -35,7 +35,7 @@ class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, val wIdx = index(waddr) + writeBeatCnt val rIdx = index(raddr) + readBeatCnt - val wen = in.w.fire() && inRange(wIdx) + val wen = in.w.fire && inRange(wIdx) val rdata = if (useBlackBox) { val mem = DifftestMem(memByte, 8) @@ -58,4 +58,3 @@ class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, in.r.bits.data := rdata } - diff --git a/src/main/scala/device/AXI4Slave.scala b/src/main/scala/device/AXI4Slave.scala index 9031f73ca..4b35d17a0 100644 --- a/src/main/scala/device/AXI4Slave.scala +++ b/src/main/scala/device/AXI4Slave.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package device @@ -40,20 +40,20 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e case axi4: AXI4 => val c = Counter(256) 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 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(PAddrBits.W)) << axi4.ar.bits.size) - raddr := HoldUnless(wrapAddr, axi4.ar.fire()) + raddr := HoldUnless(wrapAddr, axi4.ar.fire) axi4.r.bits.last := (c.value === len) when (ren) { beatCnt.inc() when (burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) { beatCnt.value := 0.U } } - when (axi4.r.fire()) { + when (axi4.r.fire) { c.inc() when (axi4.r.bits.last) { c.value := 0.U } } - when (axi4.ar.fire()) { + when (axi4.ar.fire) { beatCnt.value := (axi4.ar.bits.addr >> axi4.ar.bits.size) & axi4.ar.bits.len when (axi4.ar.bits.len =/= 0.U && axi4.ar.bits.burst === AXI4Parameters.BURST_WRAP) { assert(axi4.ar.bits.len === 1.U || axi4.ar.bits.len === 3.U || @@ -67,19 +67,19 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e (0.U, true.B) } - val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true) + val r_busy = BoolStopWatch(in.ar.fire, in.r.fire && rLast, startHighPriority = true) in.ar.ready := in.r.ready || !r_busy in.r.bits.resp := AXI4Parameters.RESP_OKAY - ren := RegNext(in.ar.fire(), init=false.B) || (in.r.fire() && !rLast) - in.r.valid := BoolStopWatch(ren && (in.ar.fire() || r_busy), in.r.fire(), startHighPriority = true) + ren := RegNext(in.ar.fire, init=false.B) || (in.r.fire && !rLast) + in.r.valid := BoolStopWatch(ren && (in.ar.fire || r_busy), in.r.fire, startHighPriority = true) val waddr = Wire(UInt()) val (writeBeatCnt, wLast) = in match { case axi4: AXI4 => val c = Counter(256) - waddr := HoldUnless(axi4.aw.bits.addr, axi4.aw.fire()) - when (axi4.w.fire()) { + waddr := HoldUnless(axi4.aw.bits.addr, axi4.aw.fire) + when (axi4.w.fire) { c.inc() when (axi4.w.bits.last) { c.value := 0.U } } @@ -90,18 +90,18 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e (0.U, true.B) } - val w_busy = BoolStopWatch(in.aw.fire(), in.b.fire(), startHighPriority = true) + val w_busy = BoolStopWatch(in.aw.fire, in.b.fire, startHighPriority = true) in.aw.ready := !w_busy in. w.ready := in.aw.valid || (w_busy) in.b.bits.resp := AXI4Parameters.RESP_OKAY - in.b.valid := BoolStopWatch(in.w.fire() && wLast, in.b.fire(), startHighPriority = true) + in.b.valid := BoolStopWatch(in.w.fire && wLast, in.b.fire, startHighPriority = true) in match { case axi4: AXI4 => - axi4.b.bits.id := RegEnable(axi4.aw.bits.id, axi4.aw.fire()) - axi4.b.bits.user := RegEnable(axi4.aw.bits.user, axi4.aw.fire()) - axi4.r.bits.id := RegEnable(axi4.ar.bits.id, axi4.ar.fire()) - axi4.r.bits.user := RegEnable(axi4.ar.bits.user, axi4.ar.fire()) + axi4.b.bits.id := RegEnable(axi4.aw.bits.id, axi4.aw.fire) + axi4.b.bits.user := RegEnable(axi4.aw.bits.user, axi4.aw.fire) + axi4.r.bits.id := RegEnable(axi4.ar.bits.id, axi4.ar.fire) + axi4.r.bits.user := RegEnable(axi4.ar.bits.user, axi4.ar.fire) case axi4lite: AXI4Lite => } } diff --git a/src/main/scala/device/AXI4UART.scala b/src/main/scala/device/AXI4UART.scala index c191c4d8b..2e2129c90 100644 --- a/src/main/scala/device/AXI4UART.scala +++ b/src/main/scala/device/AXI4UART.scala @@ -30,9 +30,9 @@ class AXI4UART extends AXI4SlaveModule(new AXI4Lite, _extra = new UARTIO) val stat = RegInit(1.U(32.W)) val ctrl = RegInit(0.U(32.W)) - io.extra.get.out.valid := (waddr(3,0) === 4.U && in.w.fire()) + io.extra.get.out.valid := (waddr(3,0) === 4.U && in.w.fire) io.extra.get.out.ch := in.w.bits.data(7,0) - io.extra.get.in.valid := (raddr(3,0) === 0.U && in.r.fire()) + io.extra.get.in.valid := (raddr(3,0) === 0.U && in.r.fire) val mapping = Map( RegMap(0x0, io.extra.get.in.ch, RegMap.Unwritable), @@ -42,6 +42,6 @@ class AXI4UART extends AXI4SlaveModule(new AXI4Lite, _extra = new UARTIO) ) RegMap.generate(mapping, raddr(3,0), in.r.bits.data, - waddr(3,0), in.w.fire(), in.w.bits.data(31, 0), MaskExpand(in.w.bits.strb >> waddr(2, 0))(31, 0) + waddr(3,0), in.w.fire, in.w.bits.data(31, 0), MaskExpand(in.w.bits.strb >> waddr(2, 0))(31, 0) ) } diff --git a/src/main/scala/device/AXI4VGA.scala b/src/main/scala/device/AXI4VGA.scala index e58ceda75..fa11f6398 100644 --- a/src/main/scala/device/AXI4VGA.scala +++ b/src/main/scala/device/AXI4VGA.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package device @@ -70,7 +70,7 @@ class VGACtrlBundle extends Bundle { class VGACtrl extends AXI4SlaveModule(new AXI4Lite, new VGACtrlBundle) with HasVGAParameter { val fbSizeReg = Cat(FBWidth.U(16.W), FBHeight.U(16.W)) - val sync = in.aw.fire() + val sync = in.aw.fire val mapping = Map( RegMap(0x0, fbSizeReg, RegMap.Unwritable), @@ -78,7 +78,7 @@ class VGACtrl extends AXI4SlaveModule(new AXI4Lite, new VGACtrlBundle) with HasV ) RegMap.generate(mapping, raddr(3,0), in.r.bits.data, - waddr(3,0), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb)) + waddr(3,0), in.w.fire, in.w.bits.data, MaskExpand(in.w.bits.strb)) io.extra.get.sync := sync } @@ -133,7 +133,7 @@ class AXI4VGA(sim: Boolean = false) extends Module with HasVGAParameter { io.in.fb.ar.ready := true.B io.in.fb.r.bits.data := 0.U io.in.fb.r.bits.resp := AXI4Parameters.RESP_OKAY - io.in.fb.r.valid := BoolStopWatch(io.in.fb.ar.fire(), io.in.fb.r.fire(), startHighPriority = true) + io.in.fb.r.valid := BoolStopWatch(io.in.fb.ar.fire, io.in.fb.r.fire, startHighPriority = true) def inRange(x: UInt, start: Int, end: Int) = (x >= start.U) && (x < end.U) @@ -162,7 +162,7 @@ class AXI4VGA(sim: Boolean = false) extends Module with HasVGAParameter { fb.io.in.ar.valid := RegNext(nextPixel) && hCounterIs2 fb.io.in.r.ready := true.B - val data = HoldUnless(fb.io.in.r.bits.data, fb.io.in.r.fire()) + val data = HoldUnless(fb.io.in.r.bits.data, fb.io.in.r.fire) val color = if (Settings.get("IsRV32")) data(31, 0) else Mux(hCounter(1), data(63, 32), data(31, 0)) io.vga.rgb := Mux(io.vga.valid, color(23, 0), 0.U) diff --git a/src/main/scala/nutcore/backend/fu/CSR.scala b/src/main/scala/nutcore/backend/fu/CSR.scala index cf89979c3..27671bb48 100644 --- a/src/main/scala/nutcore/backend/fu/CSR.scala +++ b/src/main/scala/nutcore/backend/fu/CSR.scala @@ -624,7 +624,7 @@ class CSR(implicit val p: NutCoreConfig) extends NutCoreModule with HasCSRConst{ csrExceptionVec(loadPageFault) := hasLoadPageFault csrExceptionVec(storePageFault) := hasStorePageFault val iduExceptionVec = io.cfIn.exceptionVec - val raiseExceptionVec = csrExceptionVec.asUInt() | iduExceptionVec.asUInt() + val raiseExceptionVec = csrExceptionVec.asUInt | iduExceptionVec.asUInt val raiseException = raiseExceptionVec.orR val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) io.wenFix := raiseException @@ -639,7 +639,7 @@ class CSR(implicit val p: NutCoreConfig) extends NutCoreModule with HasCSRConst{ io.redirect.rtype := 0.U io.redirect.target := Mux(resetSatp, io.cfIn.pc + 4.U, Mux(raiseExceptionIntr, trapTarget, retTarget)) - Debug(raiseExceptionIntr, "excin %b excgen %b", csrExceptionVec.asUInt(), iduExceptionVec.asUInt()) + Debug(raiseExceptionIntr, "excin %b excgen %b", csrExceptionVec.asUInt, iduExceptionVec.asUInt) Debug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",io.cfIn.pc, intrNO, io.cfIn.intrVec.asUInt, exceptionNO, raiseExceptionVec.asUInt) Debug(raiseExceptionIntr, "[MST] time %d pc %x mstatus %x mideleg %x medeleg %x mode %x\n", GTimer(), io.cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) Debug(io.redirect.valid, "redirect to %x\n", io.redirect.target) diff --git a/src/main/scala/nutcore/backend/fu/LSU.scala b/src/main/scala/nutcore/backend/fu/LSU.scala index 7d03ed8c0..10857fc8f 100644 --- a/src/main/scala/nutcore/backend/fu/LSU.scala +++ b/src/main/scala/nutcore/backend/fu/LSU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -49,7 +49,7 @@ object LSUOpType { //TODO: refactor LSU fuop def amomax = "b0110000".U def amominu = "b0110001".U def amomaxu = "b0110010".U - + def isAdd(func: UInt) = func(6) def isAtom(func: UInt): Bool = func(5) def isStore(func: UInt): Bool = func(3) @@ -181,7 +181,7 @@ class AtomALU extends NutCoreModule { val src1 = io.src1 val src2 = io.src2 val func = io.func - val isAdderSub = !LSUOpType.isAdd(func) + val isAdderSub = !LSUOpType.isAdd(func) val adderRes = (src1 +& (src2 ^ Fill(XLEN, isAdderSub))) + isAdderSub val xorRes = src1 ^ src2 val sltu = !adderRes(XLEN) @@ -258,7 +258,7 @@ class LSU extends NutCoreModule with HasLSUConst { BoringUtils.addSink(lr, "lr") BoringUtils.addSink(lrAddr, "lr_addr") val scInvalid = !(src1 === lrAddr) && scReq - setLr := (lrReq || scReq) && io.in.fire() + setLr := (lrReq || scReq) && io.in.fire setLrVal := lrReq setLrAddr := src1 @@ -284,7 +284,7 @@ class LSU extends NutCoreModule with HasLSUConst { (storeReq || amoReq || scReq && !scInvalid), // needStore (loadReq || amoReq || lrReq) // needLoad ) - // If a LSU inst triggers an exception, it has no difference compared with other normal insts + // If a LSU inst triggers an exception, it has no difference compared with other normal insts // except it will be canceled by redirect bit // L/S Queue @@ -314,7 +314,7 @@ class LSU extends NutCoreModule with HasLSUConst { val havePendingAMOStoreEnq = MEMOpID.needAlu(moq(moqDmemPtr).op) && moq(moqDmemPtr).valid && moq(moqDmemPtr).tlbfin val dmemReqFrommoq = havePendingDmemReq || havePendingStoreEnq || havePendingAMOStoreEnq val skipAInst = !moq(moqDmemPtr).valid && moqDmemPtr =/= moqDtlbPtr || moq(moqDmemPtr).valid && moq(moqDmemPtr).tlbfin && (moq(moqDmemPtr).loadPageFault || moq(moqDmemPtr).storePageFault || moq(moqDmemPtr).loadAddrMisaligned || moq(moqDmemPtr).storeAddrMisaligned || !moq(moqDmemPtr).op(2,0).orR) - val haveLoadResp = io.dmem.resp.fire() && MEMOpID.commitToCDB(opResp) && moq(moqidxResp).valid //FIXIT: to use non blocking dcache, set it to false + val haveLoadResp = io.dmem.resp.fire && MEMOpID.commitToCDB(opResp) && moq(moqidxResp).valid //FIXIT: to use non blocking dcache, set it to false val havePendingCDBCmt = (0 until moqSize).map(i => moq(i).finished && moq(i).valid).reduce(_ | _) val pendingCDBCmtSelect = PriorityEncoder(VecInit((0 until moqSize).map(i => moq(i).finished && moq(i).valid))) val writebackSelect = Wire(UInt(log2Up(moqSize).W)) @@ -322,13 +322,13 @@ class LSU extends NutCoreModule with HasLSUConst { // assert(!(moq(pendingCDBCmtSelect).valid && !MEMOpID.needStore(moq(pendingCDBCmtSelect).op) && MEMOpID.needLoad(moq(pendingCDBCmtSelect).op))) // load queue enqueue - val moqEnqueue = io.in.fire() + val moqEnqueue = io.in.fire when(moqEnqueue){ moqHeadPtr := moqHeadPtr + 1.U } // move moqDtlbPtr - val dtlbReqsend = io.dtlb.req.fire() || !dtlbEnable && moqEnqueue + val dtlbReqsend = io.dtlb.req.fire || !dtlbEnable && moqEnqueue when(dtlbReqsend){ moqDtlbPtr := moqDtlbPtr + 1.U } // move moqDmemPtr - val moqReqsend = dmem.req.fire() && MEMOpID.commitToCDB(opReq) + val moqReqsend = dmem.req.fire && MEMOpID.commitToCDB(opReq) val nextmoqDmemPtr = WireInit(moqDmemPtr) when(moqReqsend || storeQueueEnqueue || skipAInst){ nextmoqDmemPtr := moqDmemPtr + 1.U @@ -336,7 +336,7 @@ class LSU extends NutCoreModule with HasLSUConst { moqDmemPtr := nextmoqDmemPtr // load queue dequeue - when(io.out.fire()){ + when(io.out.fire){ moq(writebackSelect).valid := false.B moq(writebackSelect).finished := true.B } @@ -354,7 +354,7 @@ class LSU extends NutCoreModule with HasLSUConst { } moq(i).brMask := updateBrMask(moq(i).brMask) // fixit, AS WELL AS STORE BRMASK !!!!! }) - + // write data to moq val vaddrIsMMIO = AddressSpace.isMMIO(addr) val paddrIsMMIO = AddressSpace.isMMIO(io.dtlb.resp.bits.rdata) @@ -390,11 +390,11 @@ class LSU extends NutCoreModule with HasLSUConst { moq(moqDmemPtr).finished := true.B // store inst does not need to access mem until it is commited } - + Debug("[LSU MOQ] pc id vaddr paddr func op data mmio valid finished exc mask\n") for(i <- 0 until moqSize){ Debug( - "[LSU MOQ] 0x%x %x 0x%x 0x%x %b %b %x mmio:%b valid:%b finished:%b%b exc:%b%b%b%b %x %d", + "[LSU MOQ] 0x%x %x 0x%x 0x%x %b %b %x mmio:%b valid:%b finished:%b%b exc:%b%b%b%b %x %d", moq(i).pc, moq(i).prfidx, moq(i).vaddr, moq(i).paddr, moq(i).func, moq(i).op, moq(i).data, moq(i).isMMIO, moq(i).valid, moq(i).tlbfin, moq(i).finished, moq(i).loadPageFault, moq(i).storePageFault, moq(i).loadAddrMisaligned, moq(i).storeAddrMisaligned, moq(i).brMask, i.U ) Debug(false, moq(i).valid, " valid") @@ -416,7 +416,7 @@ class LSU extends NutCoreModule with HasLSUConst { val storeQueue = Reg(Vec(storeQueueSize, new StoreQueueEntry)) // Store Queue contains store insts that have finished TLB lookup stage // There are 2 types of store insts in this queue: ROB-commited (retired) / CDB-commited (commited) - // CDB-commited insts have already gotten their paddr from TLB, + // CDB-commited insts have already gotten their paddr from TLB, // but whether these insts will be canceled is still pending for judgement. // ROB-commited insts are those insts already retired from ROB // val storeAlloc = RegInit(0.U((log2Up(storeQueueSize)+1).W)) @@ -426,30 +426,30 @@ class LSU extends NutCoreModule with HasLSUConst { val haveUnconfirmedStore = storeHeadPtr =/= storeCmtPtr val haveUnrequiredStore = storeCmtPtr =/= 0.U && storeQueue(0).valid val haveUnfinishedStore = 0.U =/= storeHeadPtr - val storeQueueFull = storeHeadPtr === storeQueueSize.U + val storeQueueFull = storeHeadPtr === storeQueueSize.U io.haveUnfinishedStore := haveUnfinishedStore Debug(storeCmtPtr > storeHeadPtr, "retired store should be less than valid store\n") - + // assert(storeCmtPtr <= storeHeadPtr, "retired store should be less than valid store") // alloc a slot when a store tlb request is sent - // val storeQueueAlloc = dmem.req.fire() && MEMOpID.commitToCDB(opReq) && MEMOpID.needStore(opReq) + // val storeQueueAlloc = dmem.req.fire && MEMOpID.commitToCDB(opReq) && MEMOpID.needStore(opReq) // after a store inst get its paddr from TLB, add it to store queue val dtlbRespUser = io.dtlb.resp.bits.user.get.asTypeOf(new DCacheUserBundle) - val tlbRespStoreEnq = false.B //io.dtlb.resp.fire() && MEMOpID.needStore(dtlbRespUser.op) && !MEMOpID.needAlu(dtlbRespUser.op) && !bruFlush && moq(dtlbRespUser.moqidx).valid && tlbRespmoqidx === moqDmemPtr + val tlbRespStoreEnq = false.B //io.dtlb.resp.fire && MEMOpID.needStore(dtlbRespUser.op) && !MEMOpID.needAlu(dtlbRespUser.op) && !bruFlush && moq(dtlbRespUser.moqidx).valid && tlbRespmoqidx === moqDmemPtr storeQueueEnqueue := havePendingStoreEnq && !storeQueueFull || !havePendingDmemReq && tlbRespStoreEnq && !storeQueueFull - val tlbRespAMOStoreEnq = false.B //io.dtlb.resp.fire() && MEMOpID.needAlu(dtlbRespUser.op) && !bruFlush && moq(dtlbRespUser.moqidx).valid && tlbRespmoqidx === moqDmemPtr + val tlbRespAMOStoreEnq = false.B //io.dtlb.resp.fire && MEMOpID.needAlu(dtlbRespUser.op) && !bruFlush && moq(dtlbRespUser.moqidx).valid && tlbRespmoqidx === moqDmemPtr val storeQueueAMOEnqueue = havePendingAMOStoreEnq && moqReqsend || tlbRespAMOStoreEnq && moqReqsend assert(!(storeQueueAMOEnqueue && storeQueueFull)) // when a store inst is retired, commit 1 term in Store Queue val storeQueueConfirm = io.scommit // TODO: Argo only support 1 scommit / cycle // when a store inst actually writes data to dmem, mark it as `waiting for dmem resp` - val storeQueueReqsend = dmem.req.fire() && MEMOpID.commitToSTQ(opReq) + val storeQueueReqsend = dmem.req.fire && MEMOpID.commitToSTQ(opReq) val storeQueueSkipInst = !storeQueue(0).valid && storeHeadPtr =/= 0.U // when dmem try to commit to store queue, i.e. dmem report a write op is finished, dequeue - // FIXIT: in current case, we can always assume a store is succeed after req.fire() - // therefore storeQueueDequeue is not necessary - val storeQueueDequeue = storeQueueReqsend || storeQueueSkipInst // dmem.resp.fire() && MEMOpID.commitToSTQ(opResp) && !MEMOpID.needLoad(opResp) //&& MEMOpID.needStore(opResp) + // FIXIT: in current case, we can always assume a store is succeed after req.fire + // therefore storeQueueDequeue is not necessary + val storeQueueDequeue = storeQueueReqsend || storeQueueSkipInst // dmem.resp.fire && MEMOpID.commitToSTQ(opResp) && !MEMOpID.needLoad(opResp) //&& MEMOpID.needStore(opResp) when(storeQueueDequeue){ // storeQueue := Cat(storeQueue(0), storeQueue(storeQueueSize-1, 1)) List.tabulate(storeQueueSize - 1)(i => { @@ -463,7 +463,7 @@ class LSU extends NutCoreModule with HasLSUConst { when((storeQueueDequeue && !storeQueueSkipInst) && !storeQueueConfirm){nextStoreCmtPtr := storeCmtPtr - 1.U} when(!(storeQueueDequeue && !storeQueueSkipInst) && storeQueueConfirm){nextStoreCmtPtr := storeCmtPtr + 1.U} storeCmtPtr := nextStoreCmtPtr - + // move storeHeadPtr ptr when(storeQueueDequeue && !(storeQueueEnqueue || storeQueueAMOEnqueue)){storeHeadPtr := storeHeadPtr - 1.U} when(!storeQueueDequeue && (storeQueueEnqueue || storeQueueAMOEnqueue)){storeHeadPtr := storeHeadPtr + 1.U} @@ -517,7 +517,7 @@ class LSU extends NutCoreModule with HasLSUConst { val haveUnfinishedUCStore = if(EnableOutOfOrderMemAccess){ false.B } else { VecInit(storeQueue.map(i => i.isMMIO && i.valid)).asUInt.orR } // For debug - val storeTBCV = io.dmem.req.fire() && io.dmem.req.bits.cmd === SimpleBusCmd.write + val storeTBCV = io.dmem.req.fire && io.dmem.req.bits.cmd === SimpleBusCmd.write val storeTBC = WireInit(storeQueue(0.U).pc) BoringUtils.addSource(storeTBCV, "GSPCV") BoringUtils.addSource(storeTBC, "GSPC") @@ -529,7 +529,7 @@ class LSU extends NutCoreModule with HasLSUConst { Debug("[LSU STQ] pc id vaddr paddr func op data mmio v mask \n") for(i <- 0 to (storeQueueSize - 1)){ Debug( - "[LSU STQ] 0x%x %x 0x%x 0x%x %b %b %x mmio:%b %b %x %d", + "[LSU STQ] 0x%x %x 0x%x 0x%x %b %b %x mmio:%b %b %x %d", storeQueue(i).pc, storeQueue(i).prfidx, storeQueue(i).vaddr, storeQueue(i).paddr, storeQueue(i).func, storeQueue(i).op, storeQueue(i).data, storeQueue(i).isMMIO, storeQueue(i).valid, storeQueue(i).brMask, i.U ) // Debug(storeAlloc === i.U, " alloc") @@ -549,7 +549,7 @@ class LSU extends NutCoreModule with HasLSUConst { //------------------------------------------------------- // Exception check, fix mop - // Misalign exception generation + // Misalign exception generation val addrAligned = LookupTree(size, List( "b00".U -> true.B, //b "b01".U -> (addr(0) === 0.U), //h @@ -576,12 +576,12 @@ class LSU extends NutCoreModule with HasLSUConst { val pfType = Mux(havePendingDtlbReq, LSUOpType.needMemWrite(moq(moqDtlbPtr).func), LSUOpType.needMemWrite(func)) // 0: load pf 1: store pf io.dtlb.req.bits.apply( - addr = Mux(havePendingDtlbReq, moq(moqDtlbPtr).vaddr(VAddrBits-1, 0), addr(VAddrBits-1, 0)), - size = 0.U, wdata = 0.U, wmask = 0.U, - cmd = pfType, + addr = Mux(havePendingDtlbReq, moq(moqDtlbPtr).vaddr(VAddrBits-1, 0), addr(VAddrBits-1, 0)), + size = 0.U, wdata = 0.U, wmask = 0.U, + cmd = pfType, user = dtlbUserBundle.asUInt ) - io.dtlb.req.valid := havePendingDtlbReq || io.in.fire() && dtlbEnable + io.dtlb.req.valid := havePendingDtlbReq || io.in.fire && dtlbEnable io.dtlb.resp.ready := true.B val loadPF = WireInit(false.B) @@ -590,17 +590,17 @@ class LSU extends NutCoreModule with HasLSUConst { BoringUtils.addSink(storePF, "storePF") // FIXIT: this is nasty // val dtlbPF = loadPF || storePF Debug(io.flush, "[DTLB FLUSH]\n") - Debug(io.dtlb.req.fire(), "[DTLB REQ] %d: req paddr for %x MOQid %x\n", GTimer(), io.dtlb.req.bits.addr, moqDtlbPtr) - Debug(io.dtlb.resp.fire(), "[DTLB RESP] %d: get paddr: %x for %x MOQid %x exc l %b s %b\n", GTimer(), io.dtlb.resp.bits.rdata, moq(tlbRespmoqidx).vaddr, tlbRespmoqidx, loadPF, storePF) - when(io.dtlb.resp.fire()){ + Debug(io.dtlb.req.fire, "[DTLB REQ] %d: req paddr for %x MOQid %x\n", GTimer(), io.dtlb.req.bits.addr, moqDtlbPtr) + Debug(io.dtlb.resp.fire, "[DTLB RESP] %d: get paddr: %x for %x MOQid %x exc l %b s %b\n", GTimer(), io.dtlb.resp.bits.rdata, moq(tlbRespmoqidx).vaddr, tlbRespmoqidx, loadPF, storePF) + when(io.dtlb.resp.fire){ moq(tlbRespmoqidx).paddr := io.dtlb.resp.bits.rdata // FIXIT moq(tlbRespmoqidx).tlbfin := true.B moq(tlbRespmoqidx).isMMIO := paddrIsMMIO moq(tlbRespmoqidx).loadPageFault := loadPF moq(tlbRespmoqidx).storePageFault := storePF } - // assert(moq(tlbRespmoqidx).valid && !moq(tlbRespmoqidx).tlbfin || !io.dtlb.resp.fire()) - // assert(!(!dtlbEnable && io.dtlb.resp.fire())) + // assert(moq(tlbRespmoqidx).valid && !moq(tlbRespmoqidx).tlbfin || !io.dtlb.resp.fire) + // assert(!(!dtlbEnable && io.dtlb.resp.fire)) //------------------------------------------------------- // Mem Req @@ -613,7 +613,7 @@ class LSU extends NutCoreModule with HasLSUConst { // * commitToVPU // * reqLOAD // * reqSTORE - // * reqAtomALU + // * reqAtomALU // Mem req srcs are distingushed by attribute: // doNothing 0000: bubble: just go throught the pipeline and do nothing @@ -649,13 +649,13 @@ class LSU extends NutCoreModule with HasLSUConst { // loadDMemReq val loadDMemReqSrcPick = Mux(havePendingDmemReq, moqDmemPtr, io.dtlb.resp.bits.user.get.asTypeOf(new DCacheUserBundle).moqidx) - val loadDTlbRespReqValid = false.B //dtlbEnable && io.dtlb.resp.fire() && MEMOpID.needLoad(dtlbRespUser.op) && !dmemReqFrommoq && + val loadDTlbRespReqValid = false.B //dtlbEnable && io.dtlb.resp.fire && MEMOpID.needLoad(dtlbRespUser.op) && !dmemReqFrommoq && //!loadPF && !storePF && !moq(tlbRespmoqidx).loadAddrMisaligned && !moq(tlbRespmoqidx).storeAddrMisaligned && //!bruFlush && moq(tlbRespmoqidx).valid && tlbRespmoqidx === moqDmemPtr val loadSideUserBundle = Wire(new DCacheUserBundle) val atomData = Wire(UInt(XLEN.W)) - + loadSideUserBundle.moqidx := loadDMemReqSrcPick loadSideUserBundle.op := moq(loadDMemReqSrcPick).op @@ -694,7 +694,7 @@ class LSU extends NutCoreModule with HasLSUConst { // } // Send request to dmem - + def genWmask(addr: UInt, sizeEncode: UInt): UInt = { LookupTree(sizeEncode, List( "b00".U -> 0x1.U, //0001 << addr(2:0) @@ -703,7 +703,7 @@ class LSU extends NutCoreModule with HasLSUConst { "b11".U -> 0xff.U //11111111 )) << addr(2, 0) } - + def genWdata(data: UInt, sizeEncode: UInt): UInt = { LookupTree(sizeEncode, List( "b00".U -> Fill(8, data(7, 0)), @@ -713,7 +713,7 @@ class LSU extends NutCoreModule with HasLSUConst { )) } - // when(mem.fire() && !pageTableWalkerWorking) push forward LQ/SQ pointer + // when(mem.fire && !pageTableWalkerWorking) push forward LQ/SQ pointer // TODO: apply user dmem.req.bits.apply(addr = memReq.addr(VAddrBits-1, 0), size = memReq.size, wdata = memReq.wdata, wmask = genWmask(memReq.addr, memReq.size), cmd = memReq.cmd, user = memReq.user.asUInt) @@ -745,8 +745,8 @@ class LSU extends NutCoreModule with HasLSUConst { })) val forwardWmask = List.tabulate(storeQueueSize)(i => storeQueue(i).wmask & Fill(XLEN/8, forwardVec(i))).foldRight(0.U)((sum, i) => sum | i) for(j <- (0 to (XLEN/8 - 1))){ - dataBackVec(j) := MuxCase( - // default = dmem.resp.bits.rdata(8*(j+1)-1, 8*j), + dataBackVec(j) := MuxCase( + // default = dmem.resp.bits.rdata(8*(j+1)-1, 8*j), default = 0.U, mapping = List.tabulate(storeQueueSize)(i => { (forwardVec(i) && storeQueue(i).wmask(j), storeQueue(i).data(8*(j+1)-1, 8*j)) @@ -756,7 +756,7 @@ class LSU extends NutCoreModule with HasLSUConst { // Load Address Lookup Table // "Load Address Queue" - // + // // Store addr backward match // TODO: opt timing val robLoadInstVec = WireInit(0.U(robSize.W)) @@ -769,13 +769,13 @@ class LSU extends NutCoreModule with HasLSUConst { when(io.robAllocate.valid){ ldStmask(io.robAllocate.bits) := 0.U } - when(io.dmem.req.fire() && MEMOpID.needLoad(opReq)){ + when(io.dmem.req.fire && MEMOpID.needLoad(opReq)){ ldAddr(reqRobidx) := io.dmem.req.bits.addr(PAddrBits-1, 3) ldStmask(reqRobidx) := moq(loadDMemReqSrcPick).stMask ldDataMask(reqRobidx) := genWmask(io.dmem.req.bits.addr, moq(loadDMemReqSrcPick).size) } - Debug(io.dmem.req.fire() && MEMOpID.needLoad(opReq), "[LSU] add load to MOQ pc:%x stmask:%x\n",io.dmem.req.bits.addr(PAddrBits-1, 3), moq(reqRobidx).stMask) - + Debug(io.dmem.req.fire && MEMOpID.needLoad(opReq), "[LSU] add load to MOQ pc:%x stmask:%x\n",io.dmem.req.bits.addr(PAddrBits-1, 3), moq(reqRobidx).stMask) + val storeNeedRollback = (0 until robSize).map(i =>{ ldAddr(i) === Mux(havePendingStqEnq, moq(moqDmemPtr).paddr(PAddrBits-1, 3), io.dtlb.resp.bits.rdata(PAddrBits-1, 3)) && (ldDataMask(i) & genWmask(moq(storeQueueEnqSrcPick).vaddr, moq(moqDmemPtr).size)).orR && @@ -786,12 +786,12 @@ class LSU extends NutCoreModule with HasLSUConst { moq(storeQueueEnqSrcPick).rollback := true.B // printf("%d: Rollback detected at pc %x vaddr %x\n", GTimer(), moq(storeQueueEnqSrcPick).pc, moq(storeQueueEnqSrcPick).vaddr) } - + // Debug(storeQueueEnqueue, "store backward pc %x lvec %b rob %x addrtag %x\n",moq(storeQueueEnqSrcPick).pc, robLoadInstVec, moq(storeQueueEnqSrcPick).prfidx(prfAddrWidth-1,1), Mux(havePendingStqEnq, moq(moqDmemPtr).paddr(PAddrBits-1, 3), io.dtlb.resp.bits.rdata(PAddrBits-1, 3))) // (0 until robSize).map(i =>Debug(storeQueueEnqueue, "%x %x %x "+i+"\n",ldAddr(i),ldStmask(i),robLoadInstVec(i))) - + // write back to load queue - when(dmem.req.fire() && MEMOpID.needLoad(opReq)){ + when(dmem.req.fire && MEMOpID.needLoad(opReq)){ moq(moqDmemPtr).fdata := dataBack moq(moqDmemPtr).fmask := forwardWmask } @@ -802,7 +802,7 @@ class LSU extends NutCoreModule with HasLSUConst { rdataFwdSelVec(j) := Mux(moq(moqidxResp).fmask(j), moq(moqidxResp).fdata(8*(j+1)-1, 8*j), dmem.resp.bits.rdata(8*(j+1)-1, 8*j)) } - when(dmem.resp.fire()){ + when(dmem.resp.fire){ when(MEMOpID.commitToCDB(opResp) || MEMOpID.commitToVPU(opResp)){ when(MEMOpID.needLoad(opResp)){moq(moqidxResp).data := rdataFwdSel} moq(moqidxResp).finished := true.B @@ -845,7 +845,7 @@ class LSU extends NutCoreModule with HasLSUConst { atomALU.io.isWordOp := !moq(moqidxResp).size(0) //recover atomWidthW from size // When an atom inst reaches here, store its result to store buffer, // then commit it to CDB, set atom-on-the-fly to false - val atomDataReg = RegEnable(genWdata(atomALU.io.result, moq(moqidxResp).size), io.out.fire() && LSUOpType.isAMO(moq(moqidxResp).func)) + val atomDataReg = RegEnable(genWdata(atomALU.io.result, moq(moqidxResp).size), io.out.fire && LSUOpType.isAMO(moq(moqidxResp).func)) atomData := atomDataReg // Commit to CDB @@ -858,7 +858,7 @@ class LSU extends NutCoreModule with HasLSUConst { ) ) - // Debug(LSUOpType.isAMO(moq(moqTailPtr).func) && io.out.fire(), "[AMO] %d: pc %x %x %x func %b word %b op %b res %x addr %x:%x\n", GTimer(), moq(moqTailPtr).pc, atomALU.io.src1, atomALU.io.src2, moq(moqTailPtr).func, atomALU.io.isWordOp, moq(moqTailPtr).op, atomALU.io.result, moq(moqTailPtr).vaddr, moq(moqTailPtr).paddr) + // Debug(LSUOpType.isAMO(moq(moqTailPtr).func) && io.out.fire, "[AMO] %d: pc %x %x %x func %b word %b op %b res %x addr %x:%x\n", GTimer(), moq(moqTailPtr).pc, atomALU.io.src1, atomALU.io.src2, moq(moqTailPtr).func, atomALU.io.isWordOp, moq(moqTailPtr).op, atomALU.io.result, moq(moqTailPtr).vaddr, moq(moqTailPtr).paddr) io.uopOut := DontCare io.isMMIO := moq(writebackSelect).isMMIO @@ -888,14 +888,14 @@ class LSU extends NutCoreModule with HasLSUConst { } } - Debug(io.out.fire() && io.uopOut.decode.cf.redirect.valid, "rollback at pc %x\n", moq(writebackSelect).pc) + Debug(io.out.fire && io.uopOut.decode.cf.redirect.valid, "rollback at pc %x\n", moq(writebackSelect).pc) - BoringUtils.addSource(io.out.fire() && io.isMMIO, "perfCntCondMmmioInstr") + BoringUtils.addSource(io.out.fire && io.isMMIO, "perfCntCondMmmioInstr") BoringUtils.addSource(moqFull, "perfCntCondMmemqFull") BoringUtils.addSource(storeQueueFull, "perfCntCondMstqFull") - BoringUtils.addSource(io.in.fire() && MEMOpID.needLoad(memop), "perfCntCondMloadCnt") - BoringUtils.addSource(io.in.fire() && MEMOpID.needStore(memop), "perfCntCondMstoreCnt") - BoringUtils.addSource(dmem.req.fire() && MEMOpID.needLoad(opReq) && forwardWmask.orR, "perfCntCondMmemSBL") + BoringUtils.addSource(io.in.fire && MEMOpID.needLoad(memop), "perfCntCondMloadCnt") + BoringUtils.addSource(io.in.fire && MEMOpID.needStore(memop), "perfCntCondMstoreCnt") + BoringUtils.addSource(dmem.req.fire && MEMOpID.needLoad(opReq) && forwardWmask.orR, "perfCntCondMmemSBL") BoringUtils.addSource(storeQueueFull, "perfCntCondMpendingLS") BoringUtils.addSource(storeQueueFull, "perfCntCondMpendingSCmt") BoringUtils.addSource(storeQueueFull, "perfCntCondMpendingSReq") @@ -909,15 +909,15 @@ class LSU extends NutCoreModule with HasLSUConst { dmem.req.valid, dmem.req.ready, dmem.req.bits.addr, dmem.req.bits.wdata, dmem.req.bits.user.get.asTypeOf(new DCacheUserBundle).op, dmem.req.bits.user.get.asTypeOf(new DCacheUserBundle).moqidx, dmem.resp.valid, dmem.resp.ready, dmem.resp.bits.rdata, dmem.resp.bits.user.get.asTypeOf(new DCacheUserBundle).op, dmem.resp.bits.user.get.asTypeOf(new DCacheUserBundle).moqidx ) - when(dmem.req.fire()){ + when(dmem.req.fire){ Debug("[DREQ] ") Debug(false, loadReadygo, "loadDMemReq") Debug(false, storeReadygo, "storeDMemReq") Debug(false, !loadReadygo && !storeReadygo, "noDMemReq") Debug(false, " pc %x addr 0x%x size %x wdata %x cmd %x moqidx %x memop %b spending %x lpending %x time %d\n", reqpc, dmem.req.bits.addr, dmem.req.bits.size, dmem.req.bits.wdata, dmem.req.bits.cmd, memReq.user.moqidx, memReq.user.op, storeCmtPtr - 0.U, moqHeadPtr - moqDmemPtr, GTimer()) } - Debug(dmem.resp.fire(), "[DRESP] memdata %x fwddata %x:%b data %x moqidx %x memop %b isMMIO %x time %d\n", dmem.resp.bits.rdata, moq(dmemUserOut.moqidx).fdata, moq(dmemUserOut.moqidx).fmask, rdataFwdSel, dmemUserOut.moqidx, dmemUserOut.op, lsuMMIO, GTimer()) - Debug(dmem.req.fire() && !MEMOpID.needStore(opReq) && forwardWmask.orR, "[FWD] dataBack %x forwardWmask %b\n", dataBack, forwardWmask) + Debug(dmem.resp.fire, "[DRESP] memdata %x fwddata %x:%b data %x moqidx %x memop %b isMMIO %x time %d\n", dmem.resp.bits.rdata, moq(dmemUserOut.moqidx).fdata, moq(dmemUserOut.moqidx).fmask, rdataFwdSel, dmemUserOut.moqidx, dmemUserOut.op, lsuMMIO, GTimer()) + Debug(dmem.req.fire && !MEMOpID.needStore(opReq) && forwardWmask.orR, "[FWD] dataBack %x forwardWmask %b\n", dataBack, forwardWmask) val printMemTrace = false val addrTrack = List( @@ -925,13 +925,13 @@ class LSU extends NutCoreModule with HasLSUConst { ) when(printMemTrace.B || addrTrack.map(i => dmem.req.bits.addr === i).foldRight(false.B)((sum, i) => sum | i)){ - when(dmem.req.fire()){ + when(dmem.req.fire){ Debug("DREQ TRACE] ") Debug(false, loadReadygo, "loadDMemReq") Debug(false, storeReadygo, "storeDMemReq") Debug(false, (!loadReadygo && !storeReadygo), "noDMemReq") Debug(" pc %x addr 0x%x size %x wdata %x cmd %x moqidx %x memop %b spending %x lpending %x\n", reqpc, dmem.req.bits.addr, dmem.req.bits.size, dmem.req.bits.wdata, dmem.req.bits.cmd, memReq.user.moqidx, memReq.user.op, storeCmtPtr - 0.U, moqHeadPtr - moqDmemPtr) }} - Debug(dmem.resp.fire(), "[LSU DRESP TRACE] memdata %x fwddata %x:%b data %x moqidx %x memop %b isMMIO %x\n", dmem.resp.bits.rdata, moq(dmemUserOut.moqidx).fdata, moq(dmemUserOut.moqidx).fmask, rdataFwdSel, dmemUserOut.moqidx, dmemUserOut.op, lsuMMIO) - Debug(dmem.req.fire() && !MEMOpID.needStore(opReq) && forwardWmask.orR, "[LSU FWD TRACE] dataBack %x forwardWmask %b\n", dataBack, forwardWmask) + Debug(dmem.resp.fire, "[LSU DRESP TRACE] memdata %x fwddata %x:%b data %x moqidx %x memop %b isMMIO %x\n", dmem.resp.bits.rdata, moq(dmemUserOut.moqidx).fdata, moq(dmemUserOut.moqidx).fmask, rdataFwdSel, dmemUserOut.moqidx, dmemUserOut.op, lsuMMIO) + Debug(dmem.req.fire && !MEMOpID.needStore(opReq) && forwardWmask.orR, "[LSU FWD TRACE] dataBack %x forwardWmask %b\n", dataBack, forwardWmask) } diff --git a/src/main/scala/nutcore/backend/fu/MDU.scala b/src/main/scala/nutcore/backend/fu/MDU.scala index b3e3243df..c94dc217a 100644 --- a/src/main/scala/nutcore/backend/fu/MDU.scala +++ b/src/main/scala/nutcore/backend/fu/MDU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -57,7 +57,7 @@ class Multiplier(len: Int) extends NutCoreModule { def DSPOutPipe[T <: Data](a: T) = RegNext(RegNext(RegNext(a))) val mulRes = (DSPInPipe(io.in.bits(0)).asSInt * DSPInPipe(io.in.bits(1)).asSInt) io.out.bits := DSPOutPipe(mulRes).asUInt - io.out.valid := DSPOutPipe(DSPInPipe(io.in.fire())) + io.out.valid := DSPOutPipe(DSPInPipe(io.in.fire)) val busy = RegInit(false.B) when (io.in.valid && !busy) { busy := true.B } @@ -75,7 +75,7 @@ class Divider(len: Int = 64) extends NutCoreModule { val s_idle :: s_log2 :: s_shift :: s_compute :: s_finish :: Nil = Enum(5) val state = RegInit(s_idle) - val newReq = (state === s_idle) && io.in.fire() + val newReq = (state === s_idle) && io.in.fire val (a, b) = (io.in.bits(0), io.in.bits(1)) val divBy0 = b === 0.U(len.W) @@ -178,11 +178,11 @@ class MDU extends NutCoreModule { val res = Mux(isDiv, divRes, mulRes) io.out.bits := Mux(isW, SignExt(res(31,0),XLEN), res) - val isDivReg = Mux(io.in.fire(), isDiv, RegNext(isDiv)) + 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) Debug("[FU-MDU] irv-orv %d %d - %d %d\n", io.in.ready, io.in.valid, io.out.ready, io.out.valid) - BoringUtils.addSource(mul.io.out.fire(), "perfCntCondMmulInstr") + BoringUtils.addSource(mul.io.out.fire, "perfCntCondMmulInstr") } diff --git a/src/main/scala/nutcore/backend/fu/UnpipelinedLSU.scala b/src/main/scala/nutcore/backend/fu/UnpipelinedLSU.scala index 21a06ce2a..c9be3e102 100644 --- a/src/main/scala/nutcore/backend/fu/UnpipelinedLSU.scala +++ b/src/main/scala/nutcore/backend/fu/UnpipelinedLSU.scala @@ -113,7 +113,7 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { // storeQueue.io.enq.bits.src2 := src2 // storeQueue.io.enq.bits.wdata := io.wdata // storeQueue.io.enq.bits.func := func - // storeQueue.io.deq.ready := lsExecUnit.io.out.fire() + // storeQueue.io.deq.ready := lsExecUnit.io.out.fire // } lsExecUnit.io.in.valid := false.B @@ -144,7 +144,7 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.in.bits.src2 := DontCare lsExecUnit.io.in.bits.func := func lsExecUnit.io.wdata := io.wdata - io.in.ready := lsExecUnit.io.out.fire() || scInvalid + io.in.ready := lsExecUnit.io.out.fire || scInvalid io.out.valid := lsExecUnit.io.out.valid || scInvalid state := s_idle } @@ -162,10 +162,10 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.in.bits.src2 := DontCare lsExecUnit.io.in.bits.func := func lsExecUnit.io.wdata := io.wdata - io.in.ready := lsExecUnit.io.out.fire() + io.in.ready := lsExecUnit.io.out.fire io.out.valid := lsExecUnit.io.out.valid assert(!atomReq || !amoReq || !lrReq || !scReq) - when(io.out.fire()){state := s_idle} + when(io.out.fire){state := s_idle} } // is(s_load){ @@ -175,9 +175,9 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { // lsExecUnit.io.in.bits.src2 := src2 // lsExecUnit.io.in.bits.func := func // lsExecUnit.io.wdata := DontCare - // io.in.ready := lsExecUnit.io.out.fire() + // io.in.ready := lsExecUnit.io.out.fire // io.out.valid := lsExecUnit.io.out.valid - // when(lsExecUnit.io.out.fire()){state := s_idle}//load finished + // when(lsExecUnit.io.out.fire){state := s_idle}//load finished // } is(s_amo_l){ @@ -189,7 +189,7 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.wdata := DontCare io.in.ready := false.B io.out.valid := false.B - when(lsExecUnit.io.out.fire()){ + when(lsExecUnit.io.out.fire){ state := s_amo_a; Debug("[AMO-L] lsExecUnit.io.out.bits %x addr %x src2 %x\n", lsExecUnit.io.out.bits, lsExecUnit.io.in.bits.src1, io.wdata) } @@ -218,9 +218,9 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.in.bits.src2 := DontCare lsExecUnit.io.in.bits.func := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) lsExecUnit.io.wdata := atomMemReg - io.in.ready := lsExecUnit.io.out.fire() - io.out.valid := lsExecUnit.io.out.fire() - when(lsExecUnit.io.out.fire()){ + io.in.ready := lsExecUnit.io.out.fire + io.out.valid := lsExecUnit.io.out.fire + when(lsExecUnit.io.out.fire){ state := s_idle; Debug("[AMO-S] atomRegReg %x addr %x\n", atomRegReg, lsExecUnit.io.in.bits.src1) } @@ -232,9 +232,9 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.in.bits.src2 := DontCare lsExecUnit.io.in.bits.func := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw) lsExecUnit.io.wdata := DontCare - io.in.ready := lsExecUnit.io.out.fire() - io.out.valid := lsExecUnit.io.out.fire() - when(lsExecUnit.io.out.fire()){ + io.in.ready := lsExecUnit.io.out.fire + io.out.valid := lsExecUnit.io.out.fire + when(lsExecUnit.io.out.fire){ state := s_idle; Debug("[LR]\n") } @@ -246,9 +246,9 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { lsExecUnit.io.in.bits.src2 := DontCare lsExecUnit.io.in.bits.func := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) lsExecUnit.io.wdata := io.wdata - io.in.ready := lsExecUnit.io.out.fire() - io.out.valid := lsExecUnit.io.out.fire() - when(lsExecUnit.io.out.fire()){ + io.in.ready := lsExecUnit.io.out.fire + io.out.valid := lsExecUnit.io.out.fire + when(lsExecUnit.io.out.fire){ state := s_idle; Debug("[SC] \n") } @@ -260,14 +260,14 @@ class UnpipelinedLSU extends NutCoreModule with HasLSUConst { io.in.ready := true.B } - Debug(io.out.fire(), "[LSU-AGU] state %x inv %x inr %x\n", state, io.in.valid, io.in.ready) + Debug(io.out.fire, "[LSU-AGU] state %x inv %x inr %x\n", state, io.in.valid, io.in.ready) // controled by FSM // io.in.ready := lsExecUnit.io.in.ready // lsExecUnit.io.wdata := io.wdata // io.out.valid := lsExecUnit.io.out.valid //Set LR/SC bits - setLr := io.out.fire() && (lrReq || scReq) + setLr := io.out.fire && (lrReq || scReq) setLrVal := lrReq setLrAddr := src1 @@ -350,21 +350,21 @@ class LSExecUnit extends NutCoreModule { switch (state) { is (s_idle) { - when (dmem.req.fire() && dtlbEnable) { state := s_wait_tlb } - when (dmem.req.fire() && !dtlbEnable) { state := s_wait_resp } - //when (dmem.req.fire()) { state := Mux(isStore, s_partialLoad, s_wait_resp) } + when (dmem.req.fire && dtlbEnable) { state := s_wait_tlb } + when (dmem.req.fire && !dtlbEnable) { state := s_wait_resp } + //when (dmem.req.fire) { state := Mux(isStore, s_partialLoad, s_wait_resp) } } is (s_wait_tlb) { when (dtlbFinish && dtlbPF ) { state := s_idle } when (dtlbFinish && !dtlbPF) { state := s_wait_resp/*Mux(isStore, s_partialLoad, s_wait_resp) */} } - is (s_wait_resp) { when (dmem.resp.fire()) { state := Mux(partialLoad, s_partialLoad, s_idle) } } + is (s_wait_resp) { when (dmem.resp.fire) { state := Mux(partialLoad, s_partialLoad, s_idle) } } is (s_partialLoad) { state := s_idle } } - Debug(dmem.req.fire(), "[LSU] %x, size %x, wdata_raw %x, isStore %x\n", addr, func(1,0), io.wdata, isStore) - Debug(dmem.req.fire(), "[LSU] dtlbFinish:%d dtlbEnable:%d dtlbPF:%d state:%d addr:%x dmemReqFire:%d dmemRespFire:%d dmemRdata:%x\n",dtlbFinish, dtlbEnable, dtlbPF, state, dmem.req.bits.addr, dmem.req.fire(), dmem.resp.fire(), dmem.resp.bits.rdata) - Debug(dtlbFinish && dtlbEnable, "[LSU] dtlbFinish:%d dtlbEnable:%d dtlbPF:%d state:%d addr:%x dmemReqFire:%d dmemRespFire:%d dmemRdata:%x\n",dtlbFinish, dtlbEnable, dtlbPF, state, dmem.req.bits.addr, dmem.req.fire(), dmem.resp.fire(), dmem.resp.bits.rdata) + Debug(dmem.req.fire, "[LSU] %x, size %x, wdata_raw %x, isStore %x\n", addr, func(1,0), io.wdata, isStore) + Debug(dmem.req.fire, "[LSU] dtlbFinish:%d dtlbEnable:%d dtlbPF:%d state:%d addr:%x dmemReqFire:%d dmemRespFire:%d dmemRdata:%x\n",dtlbFinish, dtlbEnable, dtlbPF, state, dmem.req.bits.addr, dmem.req.fire, dmem.resp.fire, dmem.resp.bits.rdata) + Debug(dtlbFinish && dtlbEnable, "[LSU] dtlbFinish:%d dtlbEnable:%d dtlbPF:%d state:%d addr:%x dmemReqFire:%d dmemRespFire:%d dmemRdata:%x\n",dtlbFinish, dtlbEnable, dtlbPF, state, dmem.req.bits.addr, dmem.req.fire, dmem.resp.fire, dmem.resp.bits.rdata) val size = func(1,0) val reqAddr = if (XLEN == 32) SignExt(addr, VAddrBits) else addr(VAddrBits-1,0) @@ -379,10 +379,10 @@ class LSExecUnit extends NutCoreModule { dmem.req.valid := valid && (state === s_idle) && !io.loadAddrMisaligned && !io.storeAddrMisaligned dmem.resp.ready := true.B - io.out.valid := Mux( dtlbPF && state =/= s_idle || io.loadAddrMisaligned || io.storeAddrMisaligned, true.B, Mux(partialLoad, state === s_partialLoad, dmem.resp.fire() && (state === s_wait_resp))) + io.out.valid := Mux( dtlbPF && state =/= s_idle || io.loadAddrMisaligned || io.storeAddrMisaligned, true.B, Mux(partialLoad, state === s_partialLoad, dmem.resp.fire && (state === s_wait_resp))) io.in.ready := (state === s_idle) || dtlbPF - Debug(io.out.fire(), "[LSU-EXECUNIT] state %x dresp %x dpf %x lm %x sm %x\n", state, dmem.resp.fire(), dtlbPF, io.loadAddrMisaligned, io.storeAddrMisaligned) + Debug(io.out.fire, "[LSU-EXECUNIT] state %x dresp %x dpf %x lm %x sm %x\n", state, dmem.resp.fire, dtlbPF, io.loadAddrMisaligned, io.storeAddrMisaligned) val rdata = dmem.resp.bits.rdata val rdataLatch = RegNext(rdata) @@ -431,8 +431,8 @@ class LSExecUnit extends NutCoreModule { Debug(io.loadAddrMisaligned || io.storeAddrMisaligned, "misaligned addr detected\n") - BoringUtils.addSource(dmem.isRead() && dmem.req.fire(), "perfCntCondMloadInstr") - BoringUtils.addSource(BoolStopWatch(dmem.isRead(), dmem.resp.fire()), "perfCntCondMloadStall") - BoringUtils.addSource(BoolStopWatch(dmem.isWrite(), dmem.resp.fire()), "perfCntCondMstoreStall") + BoringUtils.addSource(dmem.isRead && dmem.req.fire, "perfCntCondMloadInstr") + BoringUtils.addSource(BoolStopWatch(dmem.isRead, dmem.resp.fire), "perfCntCondMloadStall") + BoringUtils.addSource(BoolStopWatch(dmem.isWrite, dmem.resp.fire), "perfCntCondMstoreStall") BoringUtils.addSource(io.isMMIO, "perfCntCondMmmioInstr") } diff --git a/src/main/scala/nutcore/backend/ooo/Backend.scala b/src/main/scala/nutcore/backend/ooo/Backend.scala index fa4846790..0c9d29866 100644 --- a/src/main/scala/nutcore/backend/ooo/Backend.scala +++ b/src/main/scala/nutcore/backend/ooo/Backend.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -78,7 +78,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val bruRedirect = Wire(new RedirectIO) val mispredictRec = Wire(new MisPredictionRecIO) val flushBackend = if(enableCheckpoint){ - io.flush + io.flush } else { io.flush || rob.io.redirect.valid && rob.io.redirect.rtype === 1.U } @@ -114,13 +114,13 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR // Choose inst to be dispatched // Check structural hazard //TODO: Use bit instead of counter - val mduCnt = Wire(UInt(2.W)) + val mduCnt = Wire(UInt(2.W)) mduCnt := List.tabulate(robWidth)(i => (io.in(i).valid && io.in(i).bits.ctrl.fuType === FuType.mdu)).foldRight(0.U)((sum, i) => sum +& i) - val lsuCnt = Wire(UInt(2.W)) + val lsuCnt = Wire(UInt(2.W)) lsuCnt := List.tabulate(robWidth)(i => (io.in(i).valid && io.in(i).bits.ctrl.fuType === FuType.lsu)).foldRight(0.U)((sum, i) => sum +& i) - val bruCnt = Wire(UInt(2.W)) + val bruCnt = Wire(UInt(2.W)) bruCnt := List.tabulate(robWidth)(i => (io.in(i).valid && io.in(i).bits.ctrl.fuType === FuType.bru && ALUOpType.isBru(io.in(i).bits.ctrl.fuOpType))).foldRight(0.U)((sum, i) => sum +& i) - val csrCnt = Wire(UInt(2.W)) + val csrCnt = Wire(UInt(2.W)) csrCnt := List.tabulate(robWidth)(i => (io.in(i).valid && (io.in(i).bits.ctrl.fuType === FuType.csr || io.in(i).bits.ctrl.fuType === FuType.mou))).foldRight(0.U)((sum, i) => sum +& i) val rfSrc = List( @@ -135,7 +135,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR ) val inst = Wire(Vec(DispatchWidth + 1, new RenamedDecodeIO)) - + List.tabulate(DispatchWidth)(i => { inst(i).decode := io.in(i).bits inst(i).prfDest := Cat(rob.io.index, i.U(1.W)) @@ -145,9 +145,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR inst(i).src2Rdy := !rob.io.rvalid(2*i+1) || rob.io.rcommited(2*i+1) inst(i).brMask := DontCare // read rf, update src - inst(i).decode.data.src1 := rf.read(rfSrc(2*i)) + inst(i).decode.data.src1 := rf.read(rfSrc(2*i)) when(rob.io.rvalid(2*i) && rob.io.rcommited(2*i)){inst(i).decode.data.src1 := rob.io.rprf(2*i)} - inst(i).decode.data.src2 := rf.read(rfSrc(2*i + 1)) + inst(i).decode.data.src2 := rf.read(rfSrc(2*i + 1)) when(rob.io.rvalid(2*i+1) && rob.io.rcommited(2*i+1)){inst(i).decode.data.src2 := rob.io.rprf(2*i+1)} }) inst(DispatchWidth) := DontCare @@ -188,7 +188,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR when(io.in(i).bits.ctrl.src2Type =/= SrcType.reg){ inst(i).src2Rdy := true.B inst(i).decode.data.src2 := io.in(i).bits.data.imm - } + } }) //TODO: refactor src gen with Mux1H @@ -207,7 +207,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val blockReg = RegInit(false.B) val haveUnfinishedStore = Wire(Bool()) when((rob.io.empty || flushBackend) && !haveUnfinishedStore){ blockReg := false.B } - when(io.in(0).bits.ctrl.isBlocked && io.in(0).fire()){ blockReg := true.B } + when(io.in(0).bits.ctrl.isBlocked && io.in(0).fire){ blockReg := true.B } val mispredictionRecoveryReg = RegInit(false.B) when(io.redirect.valid && io.redirect.rtype === 1.U){ mispredictionRecoveryReg := true.B } when(rob.io.empty || flushBackend){ mispredictionRecoveryReg := false.B } @@ -221,7 +221,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR Debug(io.redirect.valid && io.redirect.rtype === 1.U, "[REDIRECT] bpr start, redirect to %x\n", io.redirect.target) Debug(io.redirect.valid && io.redirect.rtype === 0.U, "[REDIRECT]special redirect to %x\n", io.redirect.target) - instCango(0) := + instCango(0) := io.in(0).valid && rob.io.in(0).ready && // rob has empty slot !(hasBlockInst(0) && !pipeLineEmpty) && @@ -235,7 +235,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR FuType.csr -> csrrs.io.in.ready, FuType.mou -> csrrs.io.in.ready )) - instCango(1) := + instCango(1) := instCango(0) && io.in(1).valid && rob.io.in(1).ready && // rob has empty slot @@ -271,9 +271,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val brMask = Wire(Vec(robWidth+2, UInt(checkpointSize.W))) val isBranch = List.tabulate(robWidth)(i => io.in(i).valid && io.in(i).bits.ctrl.fuType === FuType.bru) brMask(0) := brMaskGen - brMask(1) := brMaskGen | (UIntToOH(brurs.io.updateCheckpoint.get.bits) & Fill(checkpointSize, io.in(0).fire() && isBranch(0))) + brMask(1) := brMaskGen | (UIntToOH(brurs.io.updateCheckpoint.get.bits) & Fill(checkpointSize, io.in(0).fire && isBranch(0))) brMask(2) := DontCare - brMask(3) := brMask(1) | (UIntToOH(brurs.io.updateCheckpoint.get.bits) & Fill(checkpointSize, io.in(1).fire() && isBranch(1))) + brMask(3) := brMask(1) | (UIntToOH(brurs.io.updateCheckpoint.get.bits) & Fill(checkpointSize, io.in(1).fire && isBranch(1))) brMaskReg := Mux(flushBackend, 0.U, Mux(io.redirect.valid && io.redirect.rtype === 1.U, updateBrMask(bruDelayer.io.out.bits.brMask), brMask(3))) Debug("[brMask] %d: old %x -> new %x\n", GTimer(), brMaskReg, Mux(flushBackend, 0.U, brMask(2))) @@ -282,7 +282,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val rsInstSel = List(bruInst, alu1Inst, alu2Inst, csrInst, lsuInst, mduInst) List.tabulate(rs.length)(i => { rs(i).io.in.valid := instCango(rsInstSel(i)) - rs(i).io.in.bits := inst(rsInstSel(i)) + rs(i).io.in.bits := inst(rsInstSel(i)) rs(i).io.in.bits.brMask := brMask(rsInstSel(i)) rs(i).io.cdb <> cdb rs(i).io.flush := flushBackend @@ -313,9 +313,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val brucommit = Wire(new OOCommitIO) val brucommitdelayed = Wire(new OOCommitIO) val bruOut = bru.access( - valid = brurs.io.out.valid, - src1 = brurs.io.out.bits.decode.data.src1, - src2 = brurs.io.out.bits.decode.data.src2, + valid = brurs.io.out.valid, + src1 = brurs.io.out.bits.decode.data.src1, + src2 = brurs.io.out.bits.decode.data.src2, func = brurs.io.out.bits.decode.ctrl.fuOpType ) val bruWritebackReady = Wire(Bool()) @@ -342,8 +342,8 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR // commit redirect bruRedirect := bruDelayer.io.out.bits.decode.cf.redirect - bruRedirect.valid := bruDelayer.io.out.bits.decode.cf.redirect.valid && bruDelayer.io.out.fire() - mispredictRec.valid := bruDelayer.io.out.fire() + bruRedirect.valid := bruDelayer.io.out.bits.decode.cf.redirect.valid && bruDelayer.io.out.fire + mispredictRec.valid := bruDelayer.io.out.fire mispredictRec.checkpoint := bruDelayer.io.freeCheckpoint.get.bits mispredictRec.prfidx := bruDelayer.io.out.bits.prfidx mispredictRec.redirect := bruRedirect @@ -361,19 +361,19 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val lsu = Module(new LSU) val lsucommit = Wire(new OOCommitIO) val lsuTlbPF = WireInit(false.B) - + val lsuUop = lsurs.io.out.bits val lsuOut = lsu.access( valid = lsurs.io.out.valid, - src1 = lsuUop.decode.data.src1, - src2 = lsuUop.decode.data.imm, - func = lsuUop.decode.ctrl.fuOpType, + src1 = lsuUop.decode.data.src1, + src2 = lsuUop.decode.data.imm, + func = lsuUop.decode.ctrl.fuOpType, dtlbPF = lsuTlbPF ) lsu.io.uopIn := lsuUop lsu.io.stMaskIn := lsurs.io.stMaskOut.get - lsu.io.robAllocate.valid := io.in(0).fire() + lsu.io.robAllocate.valid := io.in(0).fire lsu.io.robAllocate.bits := rob.io.index lsu.io.mispredictRec := mispredictRec lsu.io.scommit := rob.io.scommit @@ -397,7 +397,7 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR lsucommit.decode.cf.exceptionVec := lsu.io.exceptionVec // backend exceptions only come from LSU - raiseBackendException := lsucommit.exception && lsu.io.out.fire() + raiseBackendException := lsucommit.exception && lsu.io.out.fire // for backend exceptions, we reuse 'intrNO' field in ROB // when ROB.exception(x) === 1, intrNO(x) represents backend exception vec for this inst lsucommit.intrNO := lsucommit.decode.cf.exceptionVec.asUInt @@ -408,9 +408,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val mducommit = Wire(new OOCommitIO) val mducommitdelayed = Wire(new OOCommitIO) val mduOut = mdu.access( - valid = mdurs.io.out.valid, - src1 = mdurs.io.out.bits.decode.data.src1, - src2 = mdurs.io.out.bits.decode.data.src2, + valid = mdurs.io.out.valid, + src1 = mdurs.io.out.bits.decode.data.src1, + src2 = mdurs.io.out.bits.decode.data.src2, func = mdurs.io.out.bits.decode.ctrl.fuOpType ) val mduWritebackReady = Wire(Bool()) @@ -444,9 +444,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR } val csrcommit = Wire(new OOCommitIO) val csrOut = csr.access( - valid = csrVaild, - src1 = csrUop.decode.data.src1, - src2 = csrUop.decode.data.src2, + valid = csrVaild, + src1 = csrUop.decode.data.src1, + src2 = csrUop.decode.data.src2, func = csrUop.decode.ctrl.fuOpType ) csr.io.cfIn := csrUop.decode.cf @@ -474,9 +474,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR val moucommit = Wire(new OOCommitIO) // mou does not write register mou.access( - valid = csrrs.io.out.valid && csrrs.io.out.bits.decode.ctrl.fuType === FuType.mou, - src1 = csrrs.io.out.bits.decode.data.src1, - src2 = csrrs.io.out.bits.decode.data.src2, + valid = csrrs.io.out.valid && csrrs.io.out.bits.decode.ctrl.fuType === FuType.mou, + src1 = csrrs.io.out.bits.decode.data.src1, + src2 = csrrs.io.out.bits.decode.data.src2, func = csrrs.io.out.bits.decode.ctrl.fuOpType ) mou.io.cfIn := csrrs.io.out.bits.decode.cf @@ -502,9 +502,9 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR // ------------------------------------------------ // Common Data Bus - // + // // Currently, FUs can commit to any CDB socket. - // + // // Alternatively, FUs can be divided into different groups. // For each group, only one inst can be commited to ROB in a single cycle. @@ -585,28 +585,28 @@ class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasR // Performance Counter - BoringUtils.addSource(alu1.io.out.fire(), "perfCntCondMaluInstr") - BoringUtils.addSource(bru.io.out.fire(), "perfCntCondMbruInstr") - BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr") - BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr") + BoringUtils.addSource(alu1.io.out.fire, "perfCntCondMaluInstr") + BoringUtils.addSource(bru.io.out.fire, "perfCntCondMbruInstr") + BoringUtils.addSource(lsu.io.out.fire, "perfCntCondMlsuInstr") + BoringUtils.addSource(mdu.io.out.fire, "perfCntCondMmduInstr") BoringUtils.addSource(!rob.io.in(0).ready, "perfCntCondMrobFull") BoringUtils.addSource(!alu1rs.io.in.ready, "perfCntCondMalu1rsFull") BoringUtils.addSource(!alu2rs.io.in.ready, "perfCntCondMalu2rsFull") BoringUtils.addSource(!brurs.io.in.ready, "perfCntCondMbrursFull") BoringUtils.addSource(!lsurs.io.in.ready, "perfCntCondMlsursFull") BoringUtils.addSource(!mdurs.io.in.ready, "perfCntCondMmdursFull") - BoringUtils.addSource(lsurs.io.out.fire(), "perfCntCondMlsuIssue") - BoringUtils.addSource(mdurs.io.out.fire(), "perfCntCondMmduIssue") + BoringUtils.addSource(lsurs.io.out.fire, "perfCntCondMlsuIssue") + BoringUtils.addSource(mdurs.io.out.fire, "perfCntCondMmduIssue") BoringUtils.addSource(rob.io.empty, "perfCntCondMrobEmpty") BoringUtils.addSource(cmtStrHaz(0), "perfCntCondMcmtCnt0") BoringUtils.addSource(cmtStrHaz(1), "perfCntCondMcmtCnt1") BoringUtils.addSource(cmtStrHaz(2), "perfCntCondMcmtCnt2") BoringUtils.addSource(cmtStrHaz(3), "perfCntCondMcmtStrHaz1") BoringUtils.addSource(cmtStrHaz(4), "perfCntCondMcmtStrHaz2") - BoringUtils.addSource(alu2.io.out.fire(), "perfCntCondMaluInstr2") - BoringUtils.addSource(!(rob.io.in(0).fire() | rob.io.in(1).fire()), "perfCntCondMdispatch0") - BoringUtils.addSource(rob.io.in(0).fire() ^ rob.io.in(1).fire(), "perfCntCondMdispatch1") - BoringUtils.addSource(rob.io.in(0).fire() & rob.io.in(1).fire(), "perfCntCondMdispatch2") + BoringUtils.addSource(alu2.io.out.fire, "perfCntCondMaluInstr2") + BoringUtils.addSource(!(rob.io.in(0).fire | rob.io.in(1).fire), "perfCntCondMdispatch0") + BoringUtils.addSource(rob.io.in(0).fire ^ rob.io.in(1).fire, "perfCntCondMdispatch1") + BoringUtils.addSource(rob.io.in(0).fire & rob.io.in(1).fire, "perfCntCondMdispatch2") val inst1RSfull = !LookupTree(io.in(0).bits.ctrl.fuType, List( FuType.bru -> brurs.io.in.ready, @@ -681,18 +681,18 @@ class Backend_inorder(implicit val p: NutCoreConfig) extends NutCoreModule { val exu = Module(new EXU) val wbu = Module(new WBU) - PipelineConnect(isu.io.out, exu.io.in, exu.io.out.fire(), io.flush(0)) + PipelineConnect(isu.io.out, exu.io.in, exu.io.out.fire, io.flush(0)) PipelineConnect(exu.io.out, wbu.io.in, true.B, io.flush(1)) isu.io.in <> io.in - + isu.io.flush := io.flush(0) exu.io.flush := io.flush(1) isu.io.wb <> wbu.io.wb io.redirect <> wbu.io.redirect // forward - isu.io.forward <> exu.io.forward + isu.io.forward <> exu.io.forward io.memMMU.imem <> exu.io.memMMU.imem io.memMMU.dmem <> exu.io.memMMU.dmem diff --git a/src/main/scala/nutcore/backend/ooo/ROB.scala b/src/main/scala/nutcore/backend/ooo/ROB.scala index 0a7de4a02..aa37b9ad2 100644 --- a/src/main/scala/nutcore/backend/ooo/ROB.scala +++ b/src/main/scala/nutcore/backend/ooo/ROB.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -86,7 +86,7 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType val intrNO = Reg(Vec(robSize, Vec(robWidth, UInt(XLEN.W)))) val prf = Mem(robSize * robWidth, UInt(XLEN.W)) - // lsroq + // lsroq // Currently, ROB is also used as lsroq when out of order store is enabled val load = RegInit(VecInit(List.fill(robSize)(VecInit(List.fill(robWidth)(false.B))))) val store = RegInit(VecInit(List.fill(robSize)(VecInit(List.fill(robWidth)(false.B))))) @@ -100,13 +100,13 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType val ringBufferTail = RegInit(0.U(log2Up(robSize).W)) val ringBufferEmpty = ringBufferHead === ringBufferTail && !valid(ringBufferHead)(0) && !valid(ringBufferHead)(1) val ringBufferFull = ringBufferTail === ringBufferHead && (valid(ringBufferHead)(0) || valid(ringBufferHead)(1)) - val ringBufferAllowin = !ringBufferFull + val ringBufferAllowin = !ringBufferFull io.index := ringBufferHead io.empty := ringBufferEmpty - // Register Map + // Register Map val rmtMap = Reg(Vec(NRReg, UInt(prfAddrWidth.W))) val rmtValid = RegInit(VecInit(Seq.fill(NRReg)(false.B))) @@ -212,15 +212,15 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType valid(ringBufferTail)(i) := false.B // free prf (update RMT) when( - decode(ringBufferTail)(i).ctrl.rfWen && - rmtMap(decode(ringBufferTail)(i).ctrl.rfDest) === Cat(ringBufferTail, i.U(1.W)) && // no other in flight inst will write this reg + decode(ringBufferTail)(i).ctrl.rfWen && + rmtMap(decode(ringBufferTail)(i).ctrl.rfDest) === Cat(ringBufferTail, i.U(1.W)) && // no other in flight inst will write this reg valid(ringBufferTail)(i) ){ rmtValid(decode(ringBufferTail)(i).ctrl.rfDest) := false.B } // update checkpoint when( - decode(ringBufferTail)(i).ctrl.rfWen && + decode(ringBufferTail)(i).ctrl.rfWen && valid(ringBufferTail)(i) ){ (0 until checkpointSize).map(k => { @@ -258,7 +258,7 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType (0 until RetireWidth).map(_.U) ) io.redirect := redirect(ringBufferTail)(redirectBank) - io.redirect.valid := retireATerm && List.tabulate(robWidth)(i => + io.redirect.valid := retireATerm && List.tabulate(robWidth)(i => redirect(ringBufferTail)(i).valid && valid(ringBufferTail)(i) ).reduce(_ || _) // io.redirect.rtype := 0.U @@ -276,7 +276,7 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType // By doing this, we can treat CSR module as a single cycle FU. // TODO: delay 1 cycle for better timing performance - io.exception := + io.exception := valid(ringBufferTail)(0) && exception(ringBufferTail)(0) || valid(ringBufferTail)(1) && exception(ringBufferTail)(1) && (!valid(ringBufferTail)(0) || commited(ringBufferTail)(0) && !redirect(ringBufferTail)(0).valid) @@ -311,17 +311,17 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType when(io.exception){ cancelScommit := true.B } when(io.flush){ cancelScommit := false.B } - io.scommit := List.tabulate(robWidth)(i => - valid(ringBufferTail)(i) && - store(ringBufferTail)(i) && - List.tabulate(i)(j => (!redirect(ringBufferTail)(j).valid)).foldRight(true.B)((sum, k) => sum && k) && + io.scommit := List.tabulate(robWidth)(i => + valid(ringBufferTail)(i) && + store(ringBufferTail)(i) && + List.tabulate(i)(j => (!redirect(ringBufferTail)(j).valid)).foldRight(true.B)((sum, k) => sum && k) && List.tabulate(i+1)(j => (!exception(ringBufferTail)(j))).foldRight(true.B)((sum, k) => sum && k) && !cancelScommit ).reduce(_ || _) && retireATerm // In current version, only one l/s inst can be sent to agu in a cycle // therefore, in all banks, there is no more than 1 store insts - Debug(io.scommit, "[SCommit] %x %x %x %x\n", + Debug(io.scommit, "[SCommit] %x %x %x %x\n", redirect(ringBufferTail)(0).valid, redirect(ringBufferTail)(1).valid, exception(ringBufferTail)(0), @@ -350,9 +350,9 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType Q1.io.deq.bits =/= lsupc && Q2.io.deq.bits =/= lsupc || !Q1.io.deq.valid - ) + ) ){ - Debug("[ERROR] robpc1 %x robpc2 %x v %x lsupc %x\n", + Debug("[ERROR] robpc1 %x robpc2 %x v %x lsupc %x\n", Q1.io.deq.bits, Q2.io.deq.bits, Q1.io.deq.valid, @@ -415,10 +415,10 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType // Send robInstValid signal to LSU for "backward" val robLoadInstVec = WireInit(VecInit((0 until robSize).map(i => { (0 until robWidth).map(j => valid(i)(j) && load(i)(j)).reduce(_ || _) - })).asUInt) + })).asUInt) val robStoreInstVec = WireInit(VecInit((0 until robSize).map(i => { (0 until robWidth).map(j => valid(i)(j) && store(i)(j)).reduce(_ || _) - })).asUInt) + })).asUInt) // TODO: use a single bit in rob misc field to save "isload" BoringUtils.addSource(robLoadInstVec, "ROBLoadInstVec") BoringUtils.addSource(robStoreInstVec, "ROBStoreInstVec") @@ -438,8 +438,8 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType } // Generate Debug Info - Debug(io.in(0).fire(), "[DISPATCH1] pc = 0x%x inst %x wen %x wdst %x\n", io.in(0).bits.cf.pc, io.in(0).bits.cf.instr, io.in(0).bits.ctrl.rfWen, io.in(0).bits.ctrl.rfDest) - Debug(io.in(1).fire(), "[DISPATCH2] pc = 0x%x inst %x wen %x wdst %x\n", io.in(1).bits.cf.pc, io.in(1).bits.cf.instr, io.in(1).bits.ctrl.rfWen, io.in(1).bits.ctrl.rfDest) + Debug(io.in(0).fire, "[DISPATCH1] pc = 0x%x inst %x wen %x wdst %x\n", io.in(0).bits.cf.pc, io.in(0).bits.cf.instr, io.in(0).bits.ctrl.rfWen, io.in(0).bits.ctrl.rfDest) + Debug(io.in(1).fire, "[DISPATCH2] pc = 0x%x inst %x wen %x wdst %x\n", io.in(1).bits.cf.pc, io.in(1).bits.cf.instr, io.in(1).bits.ctrl.rfWen, io.in(1).bits.ctrl.rfDest) Debug(io.cdb(0).valid, "[COMMIT1] pc = 0x%x inst %x wen %x wdst %x wdata = 0x%x\n", io.cdb(0).bits.decode.cf.pc, io.cdb(0).bits.decode.cf.instr, io.cdb(0).bits.decode.ctrl.rfWen, io.cdb(0).bits.decode.ctrl.rfDest, io.cdb(0).bits.commits) Debug(io.cdb(1).valid, "[COMMIT2] pc = 0x%x inst %x wen %x wdst %x wdata = 0x%x\n", io.cdb(1).bits.decode.cf.pc, io.cdb(1).bits.decode.cf.instr, io.cdb(1).bits.decode.ctrl.rfWen, io.cdb(1).bits.decode.ctrl.rfDest, io.cdb(1).bits.commits) Debug(retireATerm && valid(ringBufferTail)(0), "[RETIRE1] pc = 0x%x inst %x wen %x wdst %x wdata %x mmio %x intrNO %x\n", decode(ringBufferTail)(0).cf.pc, decode(ringBufferTail)(0).cf.instr, io.wb(0).rfWen, io.wb(0).rfDest, io.wb(0).rfData, isMMIO(ringBufferTail)(0), intrNO(ringBufferTail)(0)) @@ -463,7 +463,7 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType Debug("\n") Debug("[ROB] pc v w c r e pc v w c r e\n") for(i <- 0 to (robSize - 1)){ - Debug("[ROB] 0x%x %d %d %d %d %d 0x%x %d %d %d %d %d " + i, + Debug("[ROB] 0x%x %d %d %d %d %d 0x%x %d %d %d %d %d " + i, decode(i)(0).cf.pc, valid(i)(0), commited(i)(0), canceled(i)(0), redirect(i)(0).valid && valid(i)(0), exception(i)(0), decode(i)(1).cf.pc, valid(i)(1), commited(i)(1), canceled(i)(1), redirect(i)(1).valid && valid(i)(1), exception(i)(1) ) @@ -472,7 +472,7 @@ class ROB(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstrType when(ringBufferTail === i.U){Debug(" tail")} Debug("\n") } - + // for(i <- 0 to (robSize - 1)){ // Debug("[ROB] %b %b " + i + "\n", brMask(i)(0), brMask(i)(1)) // } diff --git a/src/main/scala/nutcore/backend/ooo/RS.scala b/src/main/scala/nutcore/backend/ooo/RS.scala index 54ad1298f..28e120b2c 100644 --- a/src/main/scala/nutcore/backend/ooo/RS.scala +++ b/src/main/scala/nutcore/backend/ooo/RS.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -78,7 +78,7 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori // Here we listen to commit signal chosen by ROB? // If prf === src, mark it as `ready` - List.tabulate(rsSize)(i => + List.tabulate(rsSize)(i => when(valid(i)){ List.tabulate(rsCommitWidth)(j => when(!src1Rdy(i) && prfSrc1(i) === io.cdb(j).bits.prfidx && io.cdb(j).valid){ @@ -105,7 +105,7 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori val emptySlot = ~valid.asUInt val enqueueSelect = PriorityEncoder(emptySlot) // TODO: replace PriorityEncoder with other logic - when(io.in.fire()){ + when(io.in.fire){ decode(enqueueSelect) := io.in.bits valid(enqueueSelect) := true.B prfSrc1(enqueueSelect) := io.in.bits.prfSrc1 @@ -120,7 +120,7 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori // RS dequeue val dequeueSelect = Wire(UInt(log2Up(size).W)) dequeueSelect := PriorityEncoder(instRdy) - when(io.out.fire() || forceDequeue){ + when(io.out.fire || forceDequeue){ if(!checkpoint){ valid(dequeueSelect) := false.B } @@ -133,12 +133,12 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori io.out.bits.decode.data.src2 := src2(dequeueSelect) when(io.flush){ - List.tabulate(rsSize)(i => + List.tabulate(rsSize)(i => valid(i) := false.B ) } - Debug(io.out.fire(), "[ISSUE-"+ name + "] " + "TIMER: %d pc = 0x%x inst %x wen %x id %d\n", GTimer(), io.out.bits.decode.cf.pc, io.out.bits.decode.cf.instr, io.out.bits.decode.ctrl.rfWen, io.out.bits.prfDest) + Debug(io.out.fire, "[ISSUE-"+ name + "] " + "TIMER: %d pc = 0x%x inst %x wen %x id %d\n", GTimer(), io.out.bits.decode.cf.pc, io.out.bits.decode.cf.instr, io.out.bits.decode.ctrl.rfWen, io.out.bits.prfDest) Debug("[RS " + name + "] pc v src1 src2\n") for(i <- 0 to (size -1)){ @@ -148,26 +148,26 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori // Debug("\n") } - // fix unpipelined + // fix unpipelined // when `pipelined` === false, RS helps unpipelined FU to store its uop for commit // if an unpipelined fu can store uop itself, set `pipelined` to true (it behaves just like a pipelined FU) if(!pipelined){ val fuValidReg = RegInit(false.B) val brMaskPReg = RegInit(0.U(checkpointSize.W)) val fuFlushReg = RegInit(false.B) - val fuDecodeReg = RegEnable(io.out.bits, io.out.fire()) + val fuDecodeReg = RegEnable(io.out.bits, io.out.fire) brMaskPReg := updateBrMask(brMaskPReg) - when(io.out.fire()){ - fuValidReg := true.B + when(io.out.fire){ + fuValidReg := true.B brMaskPReg := updateBrMask(brMask(dequeueSelect)) } when(io.commit.get){ fuValidReg := false.B } - when((io.flush || needMispredictionRecovery(brMaskPReg)) && fuValidReg || (io.flush || needMispredictionRecovery(brMask(dequeueSelect))) && io.out.fire()){ fuFlushReg := true.B } + when((io.flush || needMispredictionRecovery(brMaskPReg)) && fuValidReg || (io.flush || needMispredictionRecovery(brMask(dequeueSelect))) && io.out.fire){ fuFlushReg := true.B } when(io.commit.get){ fuFlushReg := false.B } when(fuValidReg){ io.out.bits := fuDecodeReg } when(fuValidReg){ io.out.valid := true.B && !fuFlushReg} io.out.bits.brMask := brMaskPReg - Debug("[RS " + name + "] pc 0x%x valid %x flush %x brMaskPReg %x prfidx %d in %x\n", fuDecodeReg.decode.cf.pc, fuValidReg, fuFlushReg, brMaskPReg, fuDecodeReg.prfDest, io.out.fire()) + Debug("[RS " + name + "] pc 0x%x valid %x flush %x brMaskPReg %x prfidx %d in %x\n", fuDecodeReg.decode.cf.pc, fuValidReg, fuFlushReg, brMaskPReg, fuDecodeReg.prfDest, io.out.fire) } if(fifo){ @@ -178,15 +178,15 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori })) // update priorityMask io.out.valid := instRdy(dequeueSelect) - List.tabulate(rsSize)(i => - when(needMispredictionRecovery(brMask(i))){ - List.tabulate(rsSize)(j => - priorityMask(j)(i):= false.B + List.tabulate(rsSize)(i => + when(needMispredictionRecovery(brMask(i))){ + List.tabulate(rsSize)(j => + priorityMask(j)(i):= false.B ) } ) - when(io.in.fire()){priorityMask(enqueueSelect) := valid} - when(io.out.fire()){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} + when(io.in.fire){priorityMask(enqueueSelect) := valid} + when(io.out.fire){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} when(io.flush){(0 until rsSize).map(i => priorityMask(i) := VecInit(Seq.fill(rsSize)(false.B)))} } @@ -197,15 +197,15 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori !(priorityMask(i).asUInt & instRdy.asUInt).orR & instRdy(i) })) // update priorityMask - List.tabulate(rsSize)(i => - when(needMispredictionRecovery(brMask(i))){ - List.tabulate(rsSize)(j => - priorityMask(j)(i):= false.B + List.tabulate(rsSize)(i => + when(needMispredictionRecovery(brMask(i))){ + List.tabulate(rsSize)(j => + priorityMask(j)(i):= false.B ) } ) - when(io.in.fire()){ priorityMask(enqueueSelect) := valid} - when(io.out.fire()){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} + when(io.in.fire){ priorityMask(enqueueSelect) := valid} + when(io.out.fire){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} when(io.flush){(0 until rsSize).map(i => priorityMask(i) := VecInit(Seq.fill(rsSize)(false.B)))} } @@ -216,7 +216,7 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori val dequeueSelectVec = VecInit(List.tabulate(rsSize)(i => { valid(i) && Mux( - needStore(i), + needStore(i), !(priorityMask(i).asUInt.orR), // there is no other inst ahead !((priorityMask(i).asUInt & needStore.asUInt).orR) // there is no store (with no valid addr) ahead ) && @@ -225,18 +225,18 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori dequeueSelect := OHToUInt(dequeueSelectVec) io.out.valid := instRdy(dequeueSelect) && dequeueSelectVec(dequeueSelect) // update priorityMask - List.tabulate(rsSize)(i => - when(needMispredictionRecovery(brMask(i))){ - List.tabulate(rsSize)(j => - priorityMask(j)(i):= false.B + List.tabulate(rsSize)(i => + when(needMispredictionRecovery(brMask(i))){ + List.tabulate(rsSize)(j => + priorityMask(j)(i):= false.B ) } ) - when(io.in.fire()){ + when(io.in.fire){ priorityMask(enqueueSelect) := valid needStore(enqueueSelect) := LSUOpType.needMemWrite(io.in.bits.decode.ctrl.fuOpType) } - when(io.out.fire()){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} + when(io.out.fire){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} when(io.flush){(0 until rsSize).map(i => priorityMask(i) := VecInit(Seq.fill(rsSize)(false.B)))} } @@ -250,7 +250,7 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori val dequeueSelectVec = VecInit(List.tabulate(rsSize)(i => { valid(i) && Mux( - needStore(i), + needStore(i), !(priorityMask(i).asUInt.orR), // there is no other inst ahead true.B ) && @@ -265,18 +265,18 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori io.out.valid := instRdy(dequeueSelect) && !priorityMask(dequeueSelect).asUInt.orR && valid(dequeueSelect) } // update priorityMask - List.tabulate(rsSize)(i => - when(needMispredictionRecovery(brMask(i))){ - List.tabulate(rsSize)(j => - priorityMask(j)(i):= false.B + List.tabulate(rsSize)(i => + when(needMispredictionRecovery(brMask(i))){ + List.tabulate(rsSize)(j => + priorityMask(j)(i):= false.B ) } ) - when(io.in.fire()){ + when(io.in.fire){ priorityMask(enqueueSelect) := valid needStore(enqueueSelect) := LSUOpType.needMemWrite(io.in.bits.decode.ctrl.fuOpType) } - when(io.out.fire()){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} + when(io.out.fire){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} when(io.flush){(0 until rsSize).map(i => priorityMask(i) := VecInit(Seq.fill(rsSize)(false.B)))} //update stMask @@ -285,13 +285,13 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori (0 until robSize).map(i => { when(!robStoreInstVec(i)){stMaskReg(i) := false.B} }) - when(io.in.fire() && LSUOpType.needMemWrite(io.in.bits.decode.ctrl.fuOpType)){ + when(io.in.fire && LSUOpType.needMemWrite(io.in.bits.decode.ctrl.fuOpType)){ stMaskReg(io.in.bits.prfDest(prfAddrWidth-1,1)) := true.B } - when(io.in.fire()){ + when(io.in.fire){ stMask(enqueueSelect) := stMaskReg } - when(io.out.fire()){ + when(io.out.fire){ stMaskReg(io.out.bits.prfDest(prfAddrWidth-1,1)) := false.B (0 until rsSize).map(i => { stMask(i)(io.out.bits.prfDest(prfAddrWidth-1,1)) := false.B @@ -306,27 +306,27 @@ class RS(size: Int = 2, pipelined: Boolean = true, fifo: Boolean = false, priori if(checkpoint){ require(priority) - io.updateCheckpoint.get.valid := io.in.fire() + io.updateCheckpoint.get.valid := io.in.fire io.updateCheckpoint.get.bits := enqueueSelect io.recoverCheckpoint.get.valid := DontCare io.recoverCheckpoint.get.bits := dequeueSelect val pending = RegInit(VecInit(Seq.fill(rsSize)(false.B))) - when(io.in.fire()){pending(enqueueSelect) := true.B} - when(io.out.fire()){pending(dequeueSelect) := false.B} + when(io.in.fire){pending(enqueueSelect) := true.B} + when(io.out.fire){pending(dequeueSelect) := false.B} when(io.flush){List.tabulate(rsSize)(i => pending(i) := false.B)} instRdy := VecInit(List.tabulate(rsSize)(i => src1Rdy(i) && src2Rdy(i) && valid(i) && pending(i))) when(io.freeCheckpoint.get.valid){valid(io.freeCheckpoint.get.bits) := false.B} - List.tabulate(rsSize)(i => - when(needMispredictionRecovery(brMask(i))){ - List.tabulate(rsSize)(j => - priorityMask(j)(i):= false.B + List.tabulate(rsSize)(i => + when(needMispredictionRecovery(brMask(i))){ + List.tabulate(rsSize)(j => + priorityMask(j)(i):= false.B ) } ) - when(io.in.fire()){priorityMask(enqueueSelect) := (valid.asUInt & pending.asUInt).asBools} - when(io.out.fire()){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} + when(io.in.fire){priorityMask(enqueueSelect) := (valid.asUInt & pending.asUInt).asBools} + when(io.out.fire){(0 until rsSize).map(i => priorityMask(i)(dequeueSelect) := false.B)} when(io.flush){(0 until rsSize).map(i => priorityMask(i) := VecInit(Seq.fill(rsSize)(false.B)))} BoringUtils.addSource(PopCount(valid) === 0.U, "perfCntCondMbrInROB_0") diff --git a/src/main/scala/nutcore/backend/seq/EXU.scala b/src/main/scala/nutcore/backend/seq/EXU.scala index d25272785..e82189fb1 100644 --- a/src/main/scala/nutcore/backend/seq/EXU.scala +++ b/src/main/scala/nutcore/backend/seq/EXU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -84,7 +84,7 @@ class EXU(implicit val p: NutCoreConfig) extends NutCoreModule { mou.access(valid = fuValids(FuType.mou), src1 = src1, src2 = src2, func = fuOpType) mou.io.cfIn := io.in.bits.cf mou.io.out.ready := true.B - + io.out.bits.decode := DontCare (io.out.bits.decode.ctrl, io.in.bits.ctrl) match { case (o, i) => o.rfWen := i.rfWen && (!lsuTlbPF && !lsu.io.loadAddrMisaligned && !lsu.io.storeAddrMisaligned || !fuValids(FuType.lsu)) && !(csr.io.wenFix && fuValids(FuType.csr)) @@ -98,7 +98,7 @@ class EXU(implicit val p: NutCoreConfig) extends NutCoreModule { io.out.bits.decode.cf.redirect := Mux(mou.io.redirect.valid, mou.io.redirect, Mux(csr.io.redirect.valid, csr.io.redirect, alu.io.redirect)) - + Debug(mou.io.redirect.valid || csr.io.redirect.valid || alu.io.redirect.valid, "[REDIRECT] mou %x csr %x alu %x \n", mou.io.redirect.valid, csr.io.redirect.valid, alu.io.redirect.valid) Debug(mou.io.redirect.valid || csr.io.redirect.valid || alu.io.redirect.valid, "[REDIRECT] flush: %d mou %x csr %x alu %x\n", io.flush, mou.io.redirect.target, csr.io.redirect.target, alu.io.redirect.target) @@ -114,20 +114,20 @@ class EXU(implicit val p: NutCoreConfig) extends NutCoreModule { io.out.bits.commits(FuType.mdu) := mduOut io.out.bits.commits(FuType.mou) := 0.U - io.in.ready := !io.in.valid || io.out.fire() + io.in.ready := !io.in.valid || io.out.fire io.forward.valid := io.in.valid io.forward.wb.rfWen := io.in.bits.ctrl.rfWen io.forward.wb.rfDest := io.in.bits.ctrl.rfDest - io.forward.wb.rfData := Mux(alu.io.out.fire(), aluOut, lsuOut) + io.forward.wb.rfData := Mux(alu.io.out.fire, aluOut, lsuOut) io.forward.fuType := io.in.bits.ctrl.fuType val isBru = ALUOpType.isBru(fuOpType) - BoringUtils.addSource(alu.io.out.fire() && !isBru, "perfCntCondMaluInstr") - BoringUtils.addSource(alu.io.out.fire() && isBru, "perfCntCondMbruInstr") - BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr") - BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr") - BoringUtils.addSource(csr.io.out.fire(), "perfCntCondMcsrInstr") + BoringUtils.addSource(alu.io.out.fire && !isBru, "perfCntCondMaluInstr") + BoringUtils.addSource(alu.io.out.fire && isBru, "perfCntCondMbruInstr") + BoringUtils.addSource(lsu.io.out.fire, "perfCntCondMlsuInstr") + BoringUtils.addSource(mdu.io.out.fire, "perfCntCondMmduInstr") + BoringUtils.addSource(csr.io.out.fire, "perfCntCondMcsrInstr") if (!p.FPGAPlatform) { val cycleCnt = WireInit(0.U(64.W)) diff --git a/src/main/scala/nutcore/backend/seq/ISU.scala b/src/main/scala/nutcore/backend/seq/ISU.scala index cdb2b59ac..c80214f21 100644 --- a/src/main/scala/nutcore/backend/seq/ISU.scala +++ b/src/main/scala/nutcore/backend/seq/ISU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -23,10 +23,10 @@ import chisel3.util.experimental.BoringUtils import utils._ import difftest._ -// Sequential Inst Issue Unit +// Sequential Inst Issue Unit class ISU(implicit val p: NutCoreConfig) extends NutCoreModule with HasRegFileParameter { val io = IO(new Bundle { - val in = Vec(2, Flipped(Decoupled(new DecodeIO))) // make in-order backend compatible with high performance frontend + val in = Vec(2, Flipped(Decoupled(new DecodeIO))) // make in-order backend compatible with high performance frontend val out = Decoupled(new DecodeIO) val wb = Flipped(new WriteBackIO) val forward = Flipped(new ForwardIO) @@ -83,20 +83,20 @@ class ISU(implicit val p: NutCoreConfig) extends NutCoreModule with HasRegFilePa 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(NRReg.W)) - // val isuFireSetMask = Mux(io.out.fire(), sb.mask(rfDest), 0.U) - val isuFireSetMask = Mux(io.out.fire(), sb.mask(rfDest1), 0.U) + // val isuFireSetMask = Mux(io.out.fire, sb.mask(rfDest), 0.U) + val isuFireSetMask = Mux(io.out.fire, sb.mask(rfDest1), 0.U) when (io.flush) { sb.update(0.U, Fill(NRReg, 1.U(1.W))) } .otherwise { sb.update(isuFireSetMask, wbClearMask) } - io.in(0).ready := !io.in(0).valid || io.out.fire() + io.in(0).ready := !io.in(0).valid || io.out.fire io.in(1).ready := false.B - Debug(io.out.fire(), "issue: pc %x npc %x instr %x src1 %x src2 %x imm %x\n", io.out.bits.cf.pc, io.out.bits.cf.pnpc, io.out.bits.cf.instr, io.out.bits.data.src1, io.out.bits.data.src2, io.out.bits.data.imm) + Debug(io.out.fire, "issue: pc %x npc %x instr %x src1 %x src2 %x imm %x\n", io.out.bits.cf.pc, io.out.bits.cf.pnpc, io.out.bits.cf.instr, io.out.bits.data.src1, io.out.bits.data.src2, io.out.bits.data.imm) // read after write BoringUtils.addSource(io.in(0).valid && !io.out.valid, "perfCntCondMrawStall") - BoringUtils.addSource(io.out.valid && !io.out.fire(), "perfCntCondMexuBusy") - BoringUtils.addSource(io.out.fire(), "perfCntCondISUIssue") + BoringUtils.addSource(io.out.valid && !io.out.fire, "perfCntCondMexuBusy") + BoringUtils.addSource(io.out.fire, "perfCntCondISUIssue") if (!p.FPGAPlatform) { val difftest = DifftestModule(new DiffArchIntRegState) diff --git a/src/main/scala/nutcore/frontend/BPU.scala b/src/main/scala/nutcore/frontend/BPU.scala index 470fe9ab1..73db38266 100644 --- a/src/main/scala/nutcore/frontend/BPU.scala +++ b/src/main/scala/nutcore/frontend/BPU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -61,7 +61,7 @@ class BPUUpdateReq extends NutCoreBundle { class BPU_ooo extends NutCoreModule { val io = IO(new Bundle { val in = new Bundle { val pc = Flipped(Valid((UInt(VAddrBits.W)))) } - val out = new RedirectIO + val out = new RedirectIO val flush = Input(Bool()) val brIdx = Output(Vec(4, Bool())) // val target = Output(Vec(4, UInt(VAddrBits.W))) @@ -102,13 +102,13 @@ class BPU_ooo extends NutCoreModule { // we should latch the input pc for one cycle val pcLatch = RegEnable(io.in.pc.bits, io.in.pc.valid) val btbHit = Wire(Vec(4, Bool())) - (0 to 3).map(i => btbHit(i) := btbRead(i).valid && btbRead(i).tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb(i).io.r.req.fire(), init = false.B)) + (0 to 3).map(i => btbHit(i) := btbRead(i).valid && btbRead(i).tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb(i).io.r.req.fire, init = false.B)) // btbHit will ignore pc(2,0). pc(2,0) is used to build brIdx val crosslineJump = btbRead(3).crosslineJump && btbHit(3) && !io.brIdx(0) && !io.brIdx(1) && !io.brIdx(2) io.crosslineJump := crosslineJump // val crosslineJumpLatch = RegNext(crosslineJump) // val crosslineJumpTarget = RegEnable(btbRead.target, crosslineJump) - + // PHT val pht = List.fill(4)(Mem(NRbtb >> 2, UInt(2.W))) val phtTaken = Wire(Vec(4, Bool())) @@ -129,7 +129,7 @@ class BPU_ooo extends NutCoreModule { btbWrite.target := req.actualTarget btbWrite._type := req.btbType btbWrite.crosslineJump := req.pc(2,1)==="h3".U && !req.isRVC // ((pc_offset % 8) == 6) && inst is 32bit in length - btbWrite.valid := true.B + btbWrite.valid := true.B // NOTE: We only update BTB at a miss prediction. // If a miss prediction is found, the pipeline will be flushed // in the next cycle. Therefore it is safe to use single-port @@ -182,7 +182,7 @@ class BPU_ooo extends NutCoreModule { Debug(io.out.valid, "[BPU] pc %x io.brIdx.asUInt %b phtTaken %x %x %x %x valid %x %x %x %x\n", pcLatch, io.brIdx.asUInt, phtTaken(0), phtTaken(1), phtTaken(2), phtTaken(3), btbRead(0).valid, btbRead(1).valid, btbRead(2).valid, btbRead(3).valid) // io.out.valid := btbHit && Mux(btbRead._type === BTBtype.B, phtTaken, true.B) && !crosslineJump || crosslineJumpLatch && !flush && !crosslineJump - // Note: + // Note: // btbHit && Mux(btbRead._type === BTBtype.B, phtTaken, true.B) && !crosslineJump : normal branch predict // crosslineJumpLatch && !flush && !crosslineJump : cross line branch predict, bpu will require imem to fetch the next 16bit of current inst in next instline // `&& !crosslineJump` is used to make sure this logic will run correctly when imem stalls (pcUpdate === false) @@ -317,7 +317,7 @@ class BPU_inorder extends NutCoreModule { // since there is one cycle latency to read SyncReadMem, // we should latch the input pc for one cycle val pcLatch = RegEnable(io.in.pc.bits, io.in.pc.valid) - val btbHit = btbRead.valid && btbRead.tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb.io.r.req.fire(), init = false.B) && !(pcLatch(1) && btbRead.brIdx(0)) + val btbHit = btbRead.valid && btbRead.tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb.io.r.req.fire, init = false.B) && !(pcLatch(1) && btbRead.brIdx(0)) // btbHit will ignore pc(1,0). pc(1,0) is used to build brIdx // !(pcLatch(1) && btbRead.brIdx(0)) is used to deal with the following case: // ------------------------------------------------- @@ -331,7 +331,7 @@ class BPU_inorder extends NutCoreModule { Debug(btbHit, "[BTBHT1] %d pc=%x tag=%x,%x index=%x bridx=%x tgt=%x,%x flush %x type:%x\n", GTimer(), pcLatch, btbRead.tag, btbAddr.getTag(pcLatch), btbAddr.getIdx(pcLatch), btbRead.brIdx, btbRead.target, io.out.target, flush,btbRead._type) Debug(btbHit, "[BTBHT2] btbRead.brIdx %x mask %x\n", btbRead.brIdx, Cat(crosslineJump, Fill(2, io.out.valid))) // Debug(btbHit, "[BTBHT5] btbReqValid:%d btbReqSetIdx:%x\n",btb.io.r.req.valid, btb.io.r.req.bits.setId) - + // PHT val pht = Mem(NRbtb, UInt(2.W)) val phtTaken = RegEnable(pht.read(btbAddr.getIdx(io.in.pc.bits))(1), io.in.pc.valid) @@ -358,14 +358,14 @@ class BPU_inorder extends NutCoreModule { // Debug("[BTBHT6] btbWrite.type is BTBtype.R/RET!!! Inpc:%x btbWrite.brIdx:%x setIdx:%x\n", io.in.pc.bits, btbWrite.brIdx, btb.io.w.req.bits.setIdx) // Debug("[BTBHT6] tag:%x target:%x _type:%x bridx:%x\n", btbWrite.tag,btbWrite.target,btbWrite._type,btbWrite.brIdx) // Debug(p"[BTBHT6] req:${req} \n") - //} + //} //Debug("[BTBHT5] tag: target:%x type:%d brIdx:%d\n", req.actualTarget, req.btbType, Cat(req.pc(2,0)==="h6".U && !req.isRVC, req.pc(1), ~req.pc(1))) btbWrite.tag := btbAddr.getTag(req.pc) btbWrite.target := req.actualTarget btbWrite._type := req.btbType btbWrite.brIdx := Cat(req.pc(2,0)==="h6".U && !req.isRVC, req.pc(1), ~req.pc(1)) - btbWrite.valid := true.B + btbWrite.valid := true.B // NOTE: We only update BTB at a miss prediction. // If a miss prediction is found, the pipeline will be flushed // in the next cycle. Therefore it is safe to use single-port @@ -420,7 +420,7 @@ class BPU_inorder extends NutCoreModule { io.out.valid := btbHit && Mux(btbRead._type === BTBtype.B, phtTaken, true.B && rasTarget=/=0.U) //TODO: add rasTarget=/=0.U, need fix io.out.rtype := 0.U // io.out.valid := btbHit && Mux(btbRead._type === BTBtype.B, phtTaken, true.B) && !crosslineJump || crosslineJumpLatch && !flush && !crosslineJump - // Note: + // Note: // btbHit && Mux(btbRead._type === BTBtype.B, phtTaken, true.B) && !crosslineJump : normal branch predict // crosslineJumpLatch && !flush && !crosslineJump : cross line branch predict, bpu will require imem to fetch the next 16bit of current inst in next instline // `&& !crosslineJump` is used to make sure this logic will run correctly when imem stalls (pcUpdate === false) @@ -442,7 +442,7 @@ class DummyPredicter extends NutCoreModule { io.valid := io.in.pc.valid // Predicter is returning a result io.out.valid := false.B // Need redirect io.out.target := DontCare // Redirect target - io.out.rtype := DontCare // Predicter does not need to care about it + io.out.rtype := DontCare // Predicter does not need to care about it io.brIdx := VecInit(Seq.fill(4)(false.B)) // Which inst triggers jump } diff --git a/src/main/scala/nutcore/frontend/Frontend.scala b/src/main/scala/nutcore/frontend/Frontend.scala index f34f160d0..0f2b1b434 100644 --- a/src/main/scala/nutcore/frontend/Frontend.scala +++ b/src/main/scala/nutcore/frontend/Frontend.scala @@ -1,27 +1,25 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore import chisel3._ import chisel3.util._ -import chisel3.util.experimental.BoringUtils import utils._ import bus.simplebus._ -import chisel3.experimental.IO class FrontendIO(implicit val p: NutCoreConfig) extends Bundle with HasNutCoreConst { val imem = new SimpleBusUC(userBits = ICacheUserBundleWidth, addrBits = VAddrBits) @@ -75,7 +73,7 @@ class Frontend_embedded(implicit val p: NutCoreConfig) extends NutCoreModule wit val ifu = Module(new IFU_embedded) val idu = Module(new IDU) - PipelineConnect(ifu.io.out, idu.io.in(0), idu.io.out(0).fire(), ifu.io.flushVec(0)) + PipelineConnect(ifu.io.out, idu.io.in(0), idu.io.out(0).fire, ifu.io.flushVec(0)) idu.io.in(1) := DontCare io.out <> idu.io.out @@ -105,7 +103,7 @@ class Frontend_inorder(implicit val p: NutCoreConfig) extends NutCoreModule with } PipelineConnect2(ifu.io.out, ibf.io.in, ifu.io.flushVec(0)) - PipelineConnect(ibf.io.out, idu.io.in(0), idu.io.out(0).fire(), ifu.io.flushVec(1)) + PipelineConnect(ibf.io.out, idu.io.in(0), idu.io.out(0).fire, ifu.io.flushVec(1)) idu.io.in(1) := DontCare ibf.io.flush := ifu.io.flushVec(1) diff --git a/src/main/scala/nutcore/frontend/IBF.scala b/src/main/scala/nutcore/frontend/IBF.scala index 15d08ef87..bcc8a54f8 100644 --- a/src/main/scala/nutcore/frontend/IBF.scala +++ b/src/main/scala/nutcore/frontend/IBF.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -59,7 +59,7 @@ class IBF extends NutCoreModule with HasInstrType with HasIBUFConst{ val icachePF = io.in.bits.icachePF instrVec := instr.asTypeOf(Vec(4, UInt(16.W))) (0 to 3).map(i => isRVC(i.U) := instrVec(i.U)(1,0) =/= "b11".U) - + //ibuf enqueue //if valid & ringBufferAllowin, enqueue val needEnqueue = Wire(Vec(4, Bool())) @@ -71,12 +71,12 @@ class IBF extends NutCoreModule with HasInstrType with HasIBUFConst{ // NOTE: needEnqueue is always of fmt "0?1?0?" // therefore we first shift input data, then enqueue // val enqueueSize = List.tabulate(4)(i => needEnqueue(i).asUInt).foldRight(0.U)((sum, i)=>sum+&i) // count(true) in needEnqueue - val enqueueSize = needEnqueue(0).asUInt()+&needEnqueue(1).asUInt()+&needEnqueue(2).asUInt()+&needEnqueue(3).asUInt() // count(true) in needEnqueue + val enqueueSize = needEnqueue(0).asUInt+&needEnqueue(1).asUInt+&needEnqueue(2).asUInt+&needEnqueue(3).asUInt // count(true) in needEnqueue val shiftSize = Mux(needEnqueue(0), 0.U, Mux(needEnqueue(1), 1.U, Mux(needEnqueue(2), 2.U, 3.U))) // count 0 in low addr in needEnqueue val enqueueFire = (0 to 3).map(i => enqueueSize >= (i+1).U) - val ibufWen = io.in.fire() // i.e. ringBufferAllowin && io.in.valid - def ibufWrite(targetSlot: Int, shiftSize: UInt){ + val ibufWen = io.in.fire // i.e. ringBufferAllowin && io.in.valid + def ibufWrite(targetSlot: Int, shiftSize: UInt) = { ringInstBuffer(targetSlot.U + ringBufferHead) := instrVec(shiftSize + targetSlot.U) pcRingMeta(targetSlot.U + ringBufferHead) := Cat(io.in.bits.pc(VAddrBits-1, 3), shiftSize + targetSlot.U, 0.U(1.W)) npcRingMeta(targetSlot.U + ringBufferHead) := io.in.bits.pnpc @@ -124,9 +124,9 @@ class IBF extends NutCoreModule with HasInstrType with HasIBUFConst{ io.out(0).valid := dequeueIsValid(0) && (dequeueIsRVC(0) || dequeueIsValid(1)) && !io.flush io.out(0).bits.exceptionVec.map(_ => false.B) io.out(0).bits.exceptionVec(instrPageFault) := ipfRingMeta(ringBufferTail) || !dequeueIsRVC(0) && ipfRingMeta(ringBufferTail + 1.U) - val dequeueSize1 = Mux(io.out(0).fire(), Mux(dequeueIsRVC(0), 1.U, 2.U), 0.U) // socket 2 will use dequeueSize1 to get its inst - Debug(io.out(0).fire(), "dequeue: bufferhead %x buffertail %x\n", ringBufferHead, ringBufferTail) - Debug(io.out(0).fire(), "dequeue1: inst %x pc %x npc %x br %x ipf %x(%x)\n", io.out(0).bits.instr, io.out(0).bits.pc, io.out(0).bits.pnpc, io.out(0).bits.brIdx, io.out(0).bits.exceptionVec(instrPageFault), io.out(0).bits.crossPageIPFFix) + val dequeueSize1 = Mux(io.out(0).fire, Mux(dequeueIsRVC(0), 1.U, 2.U), 0.U) // socket 2 will use dequeueSize1 to get its inst + Debug(io.out(0).fire, "dequeue: bufferhead %x buffertail %x\n", ringBufferHead, ringBufferTail) + Debug(io.out(0).fire, "dequeue1: inst %x pc %x npc %x br %x ipf %x(%x)\n", io.out(0).bits.instr, io.out(0).bits.pc, io.out(0).bits.pnpc, io.out(0).bits.brIdx, io.out(0).bits.exceptionVec(instrPageFault), io.out(0).bits.crossPageIPFFix) //dequeue socket 2 val inst2_StartIndex = ringBufferTail + dequeueSize1 @@ -147,8 +147,8 @@ class IBF extends NutCoreModule with HasInstrType with HasIBUFConst{ } io.out(1).bits.exceptionVec.map(_ => false.B) io.out(1).bits.exceptionVec(instrPageFault) := ipfRingMeta(inst2_StartIndex) || !dequeueIsRVC(dequeueSize1) && ipfRingMeta(inst2_StartIndex + 1.U) - val dequeueSize2 = Mux(io.out(1).fire(), Mux(dequeueIsRVC(dequeueSize1), 1.U, 2.U), 0.U) // socket 2 will use dequeueSize1 to get its inst - Debug(io.out(1).fire(), "dequeue2: inst %x pc %x npc %x br %x ipf %x(%x)\n", io.out(1).bits.instr, io.out(1).bits.pc, io.out(1).bits.pnpc, io.out(1).bits.brIdx, io.out(1).bits.exceptionVec(instrPageFault), io.out(1).bits.crossPageIPFFix) + val dequeueSize2 = Mux(io.out(1).fire, Mux(dequeueIsRVC(dequeueSize1), 1.U, 2.U), 0.U) // socket 2 will use dequeueSize1 to get its inst + Debug(io.out(1).fire, "dequeue2: inst %x pc %x npc %x br %x ipf %x(%x)\n", io.out(1).bits.instr, io.out(1).bits.pc, io.out(1).bits.pnpc, io.out(1).bits.brIdx, io.out(1).bits.exceptionVec(instrPageFault), io.out(1).bits.crossPageIPFFix) val dequeueSize = dequeueSize1 +& dequeueSize2 diff --git a/src/main/scala/nutcore/frontend/IDU.scala b/src/main/scala/nutcore/frontend/IDU.scala index 28f53f7ba..847bb8456 100644 --- a/src/main/scala/nutcore/frontend/IDU.scala +++ b/src/main/scala/nutcore/frontend/IDU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -39,7 +39,7 @@ class Decoder(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstr // val instrType :: fuType :: fuOpType :: Nil = ListLookup(instr, Instructions.DecodeDefault, Instructions.DecodeTable) val isRVC = if (HasCExtension) instr(1,0) =/= "b11".U else false.B val rvcImmType :: rvcSrc1Type :: rvcSrc2Type :: rvcDestType :: Nil = - ListLookup(instr, CInstructions.DecodeDefault, CInstructions.CExtraDecodeTable) + ListLookup(instr, CInstructions.DecodeDefault, CInstructions.CExtraDecodeTable) io.out.bits := DontCare @@ -65,7 +65,7 @@ class Decoder(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstr val rs2 = instr(6,2) val rs1p = LookupTree(instr(9,7), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2))) val rs2p = LookupTree(instr(4,2), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2))) - val rvc_shamt = Cat(instr(12),instr(6,2)) + val rvc_shamt = Cat(instr(12),instr(6,2)) // val rdp_rs1p = LookupTree(instr(9,7), RVCRegNumTable) // val rdp = LookupTree(instr(4,2), RVCRegNumTable) @@ -124,8 +124,8 @@ class Decoder(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstr RVCInstr.ImmADDI16SP-> SignExt(Cat(instr(12), instr(4,3), instr(5), instr(2), instr(6), 0.U(4.W)), XLEN), RVCInstr.ImmADD4SPN-> ZeroExt(Cat(instr(10,7), instr(12,11), instr(5), instr(6), 0.U(2.W)), XLEN), RVCInstr.ImmCBREAK -> 1.U(XLEN.W) - // ImmFLWSP -> - // ImmFLDSP -> + // ImmFLWSP -> + // ImmFLDSP -> )) io.out.bits.data.imm := Mux(isRVC, immrvc, imm) @@ -159,12 +159,12 @@ class Decoder(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstr //output signals io.out.valid := io.in.valid - io.in.ready := !io.in.valid || io.out.fire() && !hasIntr + io.in.ready := !io.in.valid || io.out.fire && !hasIntr io.out.bits.cf <> io.in.bits // fix c_break - Debug(io.out.fire(), "issue: pc %x npc %x instr %x\n", io.out.bits.cf.pc, io.out.bits.cf.pnpc, io.out.bits.cf.instr) + Debug(io.out.fire, "issue: pc %x npc %x instr %x\n", io.out.bits.cf.pc, io.out.bits.cf.pnpc, io.out.bits.cf.instr) val intrVec = WireInit(0.U(12.W)) BoringUtils.addSink(intrVec, "intrVecIDU") @@ -185,7 +185,8 @@ class Decoder(implicit val p: NutCoreConfig) extends NutCoreModule with HasInstr io.out.bits.ctrl.isNutCoreTrap := (instr === NutCoreTrap.TRAP) && io.in.valid io.isWFI := (instr === Priviledged.WFI) && io.in.valid - io.isBranch := VecInit(RV32I_BRUInstr.table.map(i => i._2.tail(1) === fuOpType)).asUInt.orR && fuType === FuType.bru + io.isBranch := VecInit(RV32I_BRUInstr.table.map(i => i._2.tail(1) === fuOpType).toIndexedSeq).asUInt.orR && + fuType === FuType.bru } diff --git a/src/main/scala/nutcore/frontend/IFU.scala b/src/main/scala/nutcore/frontend/IFU.scala index c585db2eb..b001c0f03 100644 --- a/src/main/scala/nutcore/frontend/IFU.scala +++ b/src/main/scala/nutcore/frontend/IFU.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -55,9 +55,9 @@ class IFU_ooo extends NutCoreModule with HasResetVector { // val pcBrIdx = RegInit(0.U(4.W)) val pcInstValid = RegInit("b1111".U) val pcUpdate = Wire(Bool()) - pcUpdate := io.redirect.valid || io.imem.req.fire() - val snpc = Cat(pc(VAddrBits-1, 3), 0.U(3.W)) + CacheReadWidth.U // IFU will always ask icache to fetch next instline - // Note: we define instline as 8 Byte aligned data from icache + pcUpdate := io.redirect.valid || io.imem.req.fire + val snpc = Cat(pc(VAddrBits-1, 3), 0.U(3.W)) + CacheReadWidth.U // IFU will always ask icache to fetch next instline + // Note: we define instline as 8 Byte aligned data from icache // Next-line branch predictor val nlp = Module(new BPU_ooo) @@ -74,7 +74,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { nlptarget_latch := nlp.io.out.target } - when (io.imem.req.fire() || io.redirect.valid) { + when (io.imem.req.fire || io.redirect.valid) { nlpvalidreg := false.B nlpbridx_latch := 0.U nlptarget_latch := 0.U @@ -85,13 +85,13 @@ class IFU_ooo extends NutCoreModule with HasResetVector { val bpuBrIdx = if (Settings.get("HasIcache")) nlp.io.brIdx.asUInt else nlpbridx_latch // cross instline inst branch predict logic "crosslineJump" - // + // // if "crosslineJump", icache will need to fetch next instline, then fetch redirect addr // "crosslineJump" mechanism is used to speed up such code: // ``` // 000c BranchCondition (32 bit inst) // ``` - // in this case, full inst is needed by BRU to get the right branch result, + // in this case, full inst is needed by BRU to get the right branch result, // so we need to fetch the next inst line to get the higher bits of a 32bit branch inst // but in order to use BP result to avoid pipeline flush, // the next inst provided by icache should be predicted npc, instead of sequential npc @@ -100,7 +100,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { val crosslineJump = nlp.io.crosslineJump val s_idle :: s_crosslineJump :: Nil = Enum(2) - val state = RegInit(s_idle) + val state = RegInit(s_idle) switch(state){ is(s_idle){ when(pcUpdate && crosslineJump && !io.redirect.valid){ state := s_crosslineJump } @@ -114,7 +114,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { // predicted next pc val pnpc = Mux(crosslineJump, snpc, bpuTarget) - + // next pc val npc = Wire(UInt(VAddrBits.W)) npc := Mux(io.redirect.valid, io.redirect.target, Mux(state === s_crosslineJump, crosslineJumpTarget, Mux(bpuValid, pnpc, snpc))) @@ -137,16 +137,16 @@ class IFU_ooo extends NutCoreModule with HasResetVector { // predicted branch position index, 4 bit vector val pbrIdx = bpuBrIdx | (crosslineJump << 3) brIdx := Mux(io.redirect.valid, 0.U, Mux(state === s_crosslineJump, 0.U, pbrIdx)) - + // BP will be disabled shortly after a redirect request - nlp.io.in.pc.valid := io.imem.req.fire() // only predict when Icache accepts a request + nlp.io.in.pc.valid := io.imem.req.fire // only predict when Icache accepts a request nlp.io.in.pc.bits := npc // predict one cycle early nlp.io.flush := io.redirect.valid // redirect means BPU may need to be updated // Multi-cycle branch predictor // Multi-cycle branch predictor will not be synthesized if EnableMultiCyclePredictor is set to false val mcp = Module(new DummyPredicter) - mcp.io.in.pc.valid := io.imem.req.fire() + mcp.io.in.pc.valid := io.imem.req.fire mcp.io.in.pc.bits := pc mcp.io.flush := io.redirect.valid mcp.io.ignore := state === s_crosslineJump @@ -160,9 +160,9 @@ class IFU_ooo extends NutCoreModule with HasResetVector { mcpResultQueue.io.enq.valid := mcp.io.valid mcpResultQueue.io.enq.bits.redirect := mcp.io.out mcpResultQueue.io.enq.bits.brIdx := mcp.io.brIdx - mcpResultQueue.io.deq.ready := io.imem.resp.fire() + mcpResultQueue.io.deq.ready := io.imem.resp.fire - val validMCPRedirect = + val validMCPRedirect = mcpResultQueue.io.deq.bits.redirect.valid && //mcp predicts branch mcpResultQueue.io.deq.bits.brIdx.asUInt =/= io.imem.resp.bits.user.get(VAddrBits*2 + 3, VAddrBits*2) //brIdx is different (mcpResultQueue.io.deq.bits.brIdx.asUInt & io.imem.resp.bits.user.get(VAddrBits*2 + 7, VAddrBits*2 + 4)).orR //mcp reports a valid branch @@ -170,9 +170,9 @@ class IFU_ooo extends NutCoreModule with HasResetVector { //val bp2 = Module(new BPU_nodelay) //bp2.io.in.bits := io.out.bits - //bp2.io.in.valid := io.imem.resp.fire() + //bp2.io.in.valid := io.imem.resp.fire - when (pcUpdate) { + when (pcUpdate) { pc := npc pcInstValid := npcInstValid // pcBrIdx := brIdx // just for debug @@ -180,7 +180,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { } Debug(pcUpdate, "[IFUIN] pc:%x pcUpdate:%d npc:%x RedValid:%d RedTarget:%x LJL:%d LJTarget:%x LJ:%d snpc:%x bpValid:%d pnpc:%x \n", - pc, pcUpdate, npc, io.redirect.valid, io.redirect.target,state === s_crosslineJump, crosslineJumpTarget, + pc, pcUpdate, npc, io.redirect.valid, io.redirect.target,state === s_crosslineJump, crosslineJumpTarget, crosslineJump,snpc,nlp.io.out.valid,nlp.io.out.target) io.flushVec := Mux(io.redirect.valid, Mux(io.redirect.rtype === 0.U, "b1111".U, "b0011".U), 0.U) @@ -201,8 +201,8 @@ class IFU_ooo extends NutCoreModule with HasResetVector { io.out.bits := DontCare //inst path only uses 32bit inst, get the right inst according to pc(2) - Debug(io.imem.req.fire(), "[IFI] pc=%x user=%x redirect %x pcInstValid %b brIdx %b npc %x pc %x pnpc %x\n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, pcInstValid.asUInt, (pcInstValid & brIdx).asUInt, npc, pc, nlp.io.out.target) - Debug(io.out.fire(), "[IFO] pc=%x user=%x inst=%x npc=%x bridx %b valid %b ipf %x\n", io.out.bits.pc, io.imem.resp.bits.user.get, io.out.bits.instr, io.out.bits.pnpc, io.out.bits.brIdx.asUInt, io.out.bits.instValid.asUInt, io.ipf) + Debug(io.imem.req.fire, "[IFI] pc=%x user=%x redirect %x pcInstValid %b brIdx %b npc %x pc %x pnpc %x\n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, pcInstValid.asUInt, (pcInstValid & brIdx).asUInt, npc, pc, nlp.io.out.target) + Debug(io.out.fire, "[IFO] pc=%x user=%x inst=%x npc=%x bridx %b valid %b ipf %x\n", io.out.bits.pc, io.imem.resp.bits.user.get, io.out.bits.instr, io.out.bits.pnpc, io.out.bits.brIdx.asUInt, io.out.bits.instValid.asUInt, io.ipf) // io.out.bits.instr := (if (XLEN == 64) io.imem.resp.bits.rdata.asTypeOf(Vec(2, UInt(32.W)))(io.out.bits.pc(2)) // else io.imem.resp.bits.rdata) @@ -242,7 +242,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { (0 until 4).map(i => maybeBranch(i) := preDecodeIsBranch(io.out.bits.instr(16*(i+1)-1, 16*i))) //TODO: use icache pre-decode result // When branch predicter set non-sequential npc for a non-branch inst, // flush IFU, fetch sequential inst instead. - when((brIdxByPredictor & ~maybeBranch.asUInt).orR && io.out.fire()){ + when((brIdxByPredictor & ~maybeBranch.asUInt).orR && io.out.fire){ Debug("[ERROR] FixInvalidBranchPredict\n") io.bpFlush := true.B io.out.bits.brIdx := 0.U @@ -252,7 +252,7 @@ class IFU_ooo extends NutCoreModule with HasResetVector { // TODO: update BPU } - BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire()), "perfCntCondMimemStall") + BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire), "perfCntCondMimemStall") BoringUtils.addSource(io.flushVec.orR, "perfCntCondMifuFlush") } @@ -268,7 +268,7 @@ class IFU_embedded extends NutCoreModule with HasResetVector { // pc val pc = RegInit(resetVector.U(32.W)) - val pcUpdate = io.redirect.valid || io.imem.req.fire() + val pcUpdate = io.redirect.valid || io.imem.req.fire val snpc = pc + 4.U // sequential next pc val bpu = Module(new BPU_embedded) @@ -276,8 +276,8 @@ class IFU_embedded extends NutCoreModule with HasResetVector { // predicted next pc val pnpc = bpu.io.out.target val npc = Mux(io.redirect.valid, io.redirect.target, Mux(bpu.io.out.valid, pnpc, snpc)) - - bpu.io.in.pc.valid := io.imem.req.fire() // only predict when Icache accepts a request + + bpu.io.in.pc.valid := io.imem.req.fire // only predict when Icache accepts a request bpu.io.in.pc.bits := npc // predict one cycle early bpu.io.flush := io.redirect.valid @@ -299,10 +299,10 @@ class IFU_embedded extends NutCoreModule with HasResetVector { } io.out.valid := io.imem.resp.valid && !io.flushVec(0) - Debug(io.imem.req.fire(), "[IFI] pc=%x user=%x redirect %x npc %x pc %x pnpc %x\n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, npc, pc, bpu.io.out.target) - Debug(io.out.fire(), "[IFO] pc=%x user=%x inst=%x npc=%x ipf %x\n", io.out.bits.pc, io.imem.resp.bits.user.get, io.out.bits.instr, io.out.bits.pnpc, io.ipf) + Debug(io.imem.req.fire, "[IFI] pc=%x user=%x redirect %x npc %x pc %x pnpc %x\n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, npc, pc, bpu.io.out.target) + Debug(io.out.fire, "[IFO] pc=%x user=%x inst=%x npc=%x ipf %x\n", io.out.bits.pc, io.imem.resp.bits.user.get, io.out.bits.instr, io.out.bits.pnpc, io.ipf) - BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire()), "perfCntCondMimemStall") + BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire), "perfCntCondMimemStall") BoringUtils.addSource(io.flushVec.orR, "perfCntCondMifuFlush") } @@ -320,13 +320,13 @@ class IFU_inorder extends NutCoreModule with HasResetVector { // pc val pc = RegInit(resetVector.U(VAddrBits.W)) - val pcUpdate = io.redirect.valid || io.imem.req.fire() + val pcUpdate = io.redirect.valid || io.imem.req.fire val snpc = Mux(pc(1), pc + 2.U, pc + 4.U) // sequential next pc val bp1 = Module(new BPU_inorder) val crosslineJump = bp1.io.crosslineJump - val crosslineJumpLatch = RegInit(false.B) + val crosslineJumpLatch = RegInit(false.B) when(pcUpdate || bp1.io.flush) { crosslineJumpLatch := Mux(bp1.io.flush, false.B, crosslineJump && !crosslineJumpLatch) } @@ -342,14 +342,14 @@ class IFU_inorder extends NutCoreModule with HasResetVector { // Debug("[NPC] %x %x %x %x %x %x\n",crosslineJumpLatch, crosslineJumpTarget, crosslineJump, bp1.io.out.valid, pnpc, snpc) // val npc = Mux(io.redirect.valid, io.redirect.target, Mux(io.redirectRVC.valid, io.redirectRVC.target, snpc)) - val brIdx = Wire(UInt(4.W)) + val brIdx = Wire(UInt(4.W)) // brIdx(0) -> branch at pc offset 0 (mod 4) // brIdx(1) -> branch at pc offset 2 (mod 4) // brIdx(2) -> branch at pc offset 6 (mod 8), and this inst is not rvc inst brIdx := Cat(npcIsSeq, Mux(io.redirect.valid, 0.U, pbrIdx)) //TODO: BP will be disabled shortly after a redirect request - bp1.io.in.pc.valid := io.imem.req.fire() // only predict when Icache accepts a request + bp1.io.in.pc.valid := io.imem.req.fire // only predict when Icache accepts a request bp1.io.in.pc.bits := npc // predict one cycle early // Debug(bp1.io.in.pc.valid, p"pc: ${Hexadecimal(pc)} npc: ${Hexadecimal(npc)}\n") @@ -357,8 +357,8 @@ class IFU_inorder extends NutCoreModule with HasResetVector { bp1.io.flush := io.redirect.valid - when (pcUpdate) { - pc := npc + when (pcUpdate) { + pc := npc // printf("[IF1] pc=%x\n", pc) } @@ -376,8 +376,8 @@ class IFU_inorder extends NutCoreModule with HasResetVector { io.out.bits := DontCare //inst path only uses 32bit inst, get the right inst according to pc(2) - Debug(io.imem.req.fire(), "[IFI] pc=%x user=%x %x %x %x \n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, pbrIdx, brIdx) - Debug(io.out.fire(), "[IFO] pc=%x inst=%x\n", io.out.bits.pc, io.out.bits.instr) + Debug(io.imem.req.fire, "[IFI] pc=%x user=%x %x %x %x \n", io.imem.req.bits.addr, io.imem.req.bits.user.getOrElse(0.U), io.redirect.valid, pbrIdx, brIdx) + Debug(io.out.fire, "[IFO] pc=%x inst=%x\n", io.out.bits.pc, io.out.bits.instr) // io.out.bits.instr := (if (XLEN == 64) io.imem.resp.bits.rdata.asTypeOf(Vec(2, UInt(32.W)))(io.out.bits.pc(2)) // else io.imem.resp.bits.rdata) @@ -390,6 +390,6 @@ class IFU_inorder extends NutCoreModule with HasResetVector { io.out.bits.exceptionVec(instrPageFault) := io.ipf io.out.valid := io.imem.resp.valid && !io.flushVec(0) - BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire()), "perfCntCondMimemStall") + BoringUtils.addSource(BoolStopWatch(io.imem.req.valid, io.imem.resp.fire), "perfCntCondMimemStall") BoringUtils.addSource(io.flushVec.orR, "perfCntCondMifuFlush") } \ No newline at end of file diff --git a/src/main/scala/nutcore/frontend/NaiveIBF.scala b/src/main/scala/nutcore/frontend/NaiveIBF.scala index 771170d13..c793ade11 100644 --- a/src/main/scala/nutcore/frontend/NaiveIBF.scala +++ b/src/main/scala/nutcore/frontend/NaiveIBF.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -35,7 +35,7 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept //RVC support FSM //only ensure pnpc given by this FSM is right. May need flush after 6 offset 32 bit inst - val s_idle :: s_extra :: s_waitnext :: s_waitnext_thenj :: Nil = Enum(4) + val s_idle :: s_extra :: s_waitnext :: s_waitnext_thenj :: Nil = Enum(4) val state = RegInit(UInt(2.W), s_idle) val pcOffsetR = RegInit(UInt(3.W), 0.U) val pcOffset = Mux(state === s_idle, io.in.bits.pc(2,0), pcOffsetR) @@ -45,14 +45,14 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept val canIn = WireInit(false.B) val brIdx = io.in.bits.brIdx // val brIdx = 0.U - val rvcFinish = pcOffset === 0.U && (!isRVC || brIdx(0)) || pcOffset === 4.U && (!isRVC || brIdx(0)) || pcOffset === 2.U && (isRVC || brIdx(1)) || pcOffset === 6.U && isRVC + val rvcFinish = pcOffset === 0.U && (!isRVC || brIdx(0)) || pcOffset === 4.U && (!isRVC || brIdx(0)) || pcOffset === 2.U && (isRVC || brIdx(1)) || pcOffset === 6.U && isRVC // if brIdx(0) (branch taken at inst with offest 0), ignore the rest part of this instline // just get next pc and instline from IFU val rvcNext = pcOffset === 0.U && (isRVC && !brIdx(0)) || pcOffset === 4.U && (isRVC && !brIdx(0)) || pcOffset === 2.U && !isRVC && !brIdx(1) val rvcSpecial = pcOffset === 6.U && !isRVC && !brIdx(2) val rvcSpecialJump = pcOffset === 6.U && !isRVC && brIdx(2) val pnpcIsSeq = brIdx(3) - // val pnpcIsSeqRight = io.in.bits.pnpc === (Cat(io.in.bits.pc(VAddrBits-1,2), 0.U(2.W)) + 4.U) // TODO: add a new user bit bpRight to do this + // val pnpcIsSeqRight = io.in.bits.pnpc === (Cat(io.in.bits.pc(VAddrBits-1,2), 0.U(2.W)) + 4.U) // TODO: add a new user bit bpRight to do this // assert(pnpcIsSeq === pnpcIsSeqRight) val flushIFU = (state === s_idle || state === s_extra) && rvcSpecial && io.in.valid && !pnpcIsSeq Debug(flushIFU, "flushIFU at pc %x offset %x\n", io.in.bits.pc, pcOffset) @@ -65,15 +65,15 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept val specialNPCR = Reg(UInt(VAddrBits.W)) // reg for pnc for full inst jump that cross 2 inst line val specialInstR = Reg(UInt(16.W)) val specialIPFR = RegInit(Bool(), false.B) - val redirectPC = Cat(io.in.bits.pc(VAddrBits-1,3), 0.U(3.W))+"b1010".U // IDU can got get full inst from a single inst line + val redirectPC = Cat(io.in.bits.pc(VAddrBits-1,3), 0.U(3.W))+"b1010".U // IDU can got get full inst from a single inst line val rvcForceLoadNext = (pcOffset === 2.U && !isRVC && io.in.bits.pnpc(2,0) === 4.U && !brIdx(1)) //------------------------------------------------------ - // rvcForceLoadNext is used to deal with: + // rvcForceLoadNext is used to deal with: // case 1: // 8010004a: 406007b7 lui a5,0x40600 // 8010004e: 470d li a4,3 // 80100050: 00e78623 sb a4,12(a5) # 4060000c <_start-0x3faffff4> - // For icache req inst in seq, if there is no rvcForceLoadNext, + // For icache req inst in seq, if there is no rvcForceLoadNext, // after 8010004e there will be 8010004c instead of 80100050 //------------------------------------------------------ // case 2: @@ -82,7 +82,7 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept // force load next instline into ID stage, if bp wrong, it will be flushed by flushIFU //------------------------------------------------------ // if there is a j inst in current inst line, a redirect req will be sent by ALU before invalid inst exception being committed - // when brIdx(1), next instline will just be branch target, eatline is no longer needed + // when brIdx(1), next instline will just be branch target, eatline is no longer needed // only for test, add this to pipeline when do real implementation // val predictBranch = io.in.valid && Mux(io.in.bits.pc(1), io.in.bits.pc + 2.U === io.in.bits.pnpc, io.in.bits.pc + 4.U === io.in.bits.pnpc) @@ -101,46 +101,46 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept canIn := rvcFinish || rvcForceLoadNext pcOut := io.in.bits.pc pnpcOut := Mux(rvcFinish, io.in.bits.pnpc, Mux(isRVC, io.in.bits.pc+2.U, io.in.bits.pc+4.U)) - when(io.out.fire() && rvcFinish){state := s_idle} - when(io.out.fire() && rvcNext){ + when(io.out.fire && rvcFinish){state := s_idle} + when(io.out.fire && rvcNext){ state := s_extra pcOffsetR := pcOffset + Mux(isRVC, 2.U, 4.U) } when(rvcSpecial && io.in.valid){ state := s_waitnext specialPCR := pcOut - specialInstR := io.in.bits.instr(63,63-16+1) + specialInstR := io.in.bits.instr(63,63-16+1) specialIPFR := io.in.bits.exceptionVec(instrPageFault) } when(rvcSpecialJump && io.in.valid){ state := s_waitnext_thenj specialPCR := pcOut specialNPCR := io.in.bits.pnpc - specialInstR := io.in.bits.instr(63,63-16+1) + specialInstR := io.in.bits.instr(63,63-16+1) specialIPFR := io.in.bits.exceptionVec(instrPageFault) } } is(s_extra){//get 16 aligned inst, pc controled by this FSM canGo := rvcFinish || rvcNext canIn := rvcFinish || rvcForceLoadNext - pcOut := Cat(io.in.bits.pc(VAddrBits-1,3), pcOffsetR(2,0)) + pcOut := Cat(io.in.bits.pc(VAddrBits-1,3), pcOffsetR(2,0)) pnpcOut := Mux(rvcFinish, io.in.bits.pnpc, Mux(isRVC, pcOut+2.U, pcOut+4.U)) - when(io.out.fire() && rvcFinish){state := s_idle} - when(io.out.fire() && rvcNext){ + when(io.out.fire && rvcFinish){state := s_idle} + when(io.out.fire && rvcNext){ state := s_extra pcOffsetR := pcOffset + Mux(isRVC, 2.U, 4.U) } when(rvcSpecial && io.in.valid){ state := s_waitnext specialPCR := pcOut - specialInstR := io.in.bits.instr(63,63-16+1) + specialInstR := io.in.bits.instr(63,63-16+1) specialIPFR := io.in.bits.exceptionVec(instrPageFault) } when(rvcSpecialJump && io.in.valid){ state := s_waitnext_thenj specialPCR := pcOut specialNPCR := io.in.bits.pnpc - specialInstR := io.in.bits.instr(63,63-16+1) + specialInstR := io.in.bits.instr(63,63-16+1) specialIPFR := io.in.bits.exceptionVec(instrPageFault) } } @@ -151,7 +151,7 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept // pnpcOut := Mux(rvcFinish, io.in.bits.pnpc, Mux(isRVC, pcOut+2.U, pcOut+4.U)) canGo := io.in.valid canIn := false.B - when(io.out.fire()){ + when(io.out.fire){ state := s_extra pcOffsetR := "b010".U } @@ -163,7 +163,7 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept // pnpcOut := Mux(rvcFinish, io.in.bits.pnpc, Mux(isRVC, pcOut+2.U, pcOut+4.U)) canGo := io.in.valid canIn := true.B - when(io.out.fire()){ + when(io.out.fire){ state := s_idle } } @@ -185,7 +185,7 @@ class NaiveRVCAlignBuffer extends NutCoreModule with HasInstrType with HasExcept io.out.bits.brIdx := Mux((pnpcOut === pcOut+4.U && !isRVC) || (pnpcOut === pcOut+2.U && isRVC), false.B, true.B) io.out.valid := io.in.valid && canGo - io.in.ready := (!io.in.valid || (io.out.fire() && canIn) || loadNextInstline) + io.in.ready := (!io.in.valid || (io.out.fire && canIn) || loadNextInstline) io.out.bits.exceptionVec := io.in.bits.exceptionVec io.out.bits.exceptionVec(instrPageFault) := io.in.bits.exceptionVec(instrPageFault) || specialIPFR && (state === s_waitnext_thenj || state === s_waitnext) diff --git a/src/main/scala/nutcore/mem/Cache.scala b/src/main/scala/nutcore/mem/Cache.scala index cc02a3635..3220c2d18 100644 --- a/src/main/scala/nutcore/mem/Cache.scala +++ b/src/main/scala/nutcore/mem/Cache.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -20,8 +20,6 @@ import chisel3._ import chisel3.util._ import chisel3.util.experimental.BoringUtils import bus.simplebus._ -import bus.axi4._ -import chisel3.experimental.IO import utils._ import top.Settings @@ -50,7 +48,7 @@ sealed trait HasCacheConst { val hasCoh = !ro val hasCohInt = (if (hasCoh) 1 else 0) val hasPrefetch = cacheName == "l2cache" - + val cacheLevel = cacheConfig.cacheLevel val TotalSize = cacheConfig.totalSize val Ways = cacheConfig.ways @@ -134,8 +132,8 @@ sealed class CacheStage1(implicit val cacheConfig: CacheConfig) extends CacheMod } val io = IO(new CacheStage1IO) - if (ro) when (io.in.fire()) { assert(!io.in.bits.isWrite()) } - Debug(io.in.fire(), "[L1$] cache stage1, addr in: %x, user: %x id: %x\n", io.in.bits.addr, io.in.bits.user.getOrElse(0.U), io.in.bits.id.getOrElse(0.U)) + if (ro) when (io.in.fire) { assert(!io.in.bits.isWrite()) } + Debug(io.in.fire, "[L1$] cache stage1, addr in: %x, user: %x id: %x\n", io.in.bits.addr, io.in.bits.user.getOrElse(0.U), io.in.bits.id.getOrElse(0.U)) // read meta array and data array val readBusValid = io.in.valid && io.out.ready @@ -144,7 +142,7 @@ sealed class CacheStage1(implicit val cacheConfig: CacheConfig) extends CacheMod io.out.bits.req := io.in.bits io.out.valid := io.in.valid && io.metaReadBus.req.ready && io.dataReadBus.req.ready - io.in.ready := (!io.in.valid || io.out.fire()) && io.metaReadBus.req.ready && io.dataReadBus.req.ready + io.in.ready := (!io.in.valid || io.out.fire) && io.metaReadBus.req.ready && io.dataReadBus.req.ready Debug("in.ready = %d, in.valid = %d, out.valid = %d, out.ready = %d, addr = %x, cmd = %x, dataReadBus.req.valid = %d\n", io.in.ready, io.in.valid, io.out.valid, io.out.ready, io.in.bits.addr, io.in.bits.cmd, io.dataReadBus.req.valid) } @@ -178,7 +176,7 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod val isForwardMeta = io.in.valid && io.metaWriteBus.req.valid && io.metaWriteBus.req.bits.setIdx === getMetaIdx(req.addr) val isForwardMetaReg = RegInit(false.B) when (isForwardMeta) { isForwardMetaReg := true.B } - when (io.in.fire() || !io.in.valid) { isForwardMetaReg := false.B } + when (io.in.fire || !io.in.valid) { isForwardMetaReg := false.B } val forwardMetaReg = RegEnable(io.metaWriteBus.req.bits, isForwardMeta) val metaWay = Wire(Vec(Ways, chiselTypeOf(forwardMetaReg.data))) @@ -191,13 +189,13 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod val hitVec = VecInit(metaWay.map(m => m.valid && (m.tag === addr.tag) && io.in.valid)).asUInt val victimWaymask = if (Ways > 1) (1.U << LFSR64()(log2Up(Ways)-1,0)) else "b1".U - + val invalidVec = VecInit(metaWay.map(m => !m.valid)).asUInt val hasInvalidWay = invalidVec.orR val refillInvalidWaymask = Mux(invalidVec >= 8.U, "b1000".U, Mux(invalidVec >= 4.U, "b0100".U, Mux(invalidVec >= 2.U, "b0010".U, "b0001".U))) - + // val waymask = Mux(io.out.bits.hit, hitVec, victimWaymask) val waymask = Mux(io.out.bits.hit, hitVec, Mux(hasInvalidWay, refillInvalidWaymask, victimWaymask)) when(PopCount(waymask) > 1.U){ @@ -220,16 +218,16 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod }) val isForwardDataReg = RegInit(false.B) when (isForwardData) { isForwardDataReg := true.B } - when (io.in.fire() || !io.in.valid) { isForwardDataReg := false.B } + when (io.in.fire || !io.in.valid) { isForwardDataReg := false.B } val forwardDataReg = RegEnable(io.dataWriteBus.req.bits, isForwardData) io.out.bits.isForwardData := isForwardDataReg || isForwardData io.out.bits.forwardData := Mux(isForwardData, io.dataWriteBus.req.bits, forwardDataReg) io.out.bits.req <> req io.out.valid := io.in.valid - io.in.ready := !io.in.valid || io.out.fire() + io.in.ready := !io.in.valid || io.out.fire - Debug("[isFD:%d isFDreg:%d inFire:%d invalid:%d \n", isForwardData, isForwardDataReg, io.in.fire(), io.in.valid) + Debug("[isFD:%d isFDreg:%d inFire:%d invalid:%d \n", isForwardData, isForwardDataReg, io.in.fire, io.in.valid) Debug("[isFM:%d isFMreg:%d metawreq:%x widx:%x ridx:%x \n", isForwardMeta, isForwardMetaReg, io.metaWriteBus.req.valid, io.metaWriteBus.req.bits.setIdx, getMetaIdx(req.addr)) } @@ -278,7 +276,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod val wordMask = Mux(!ro.B && req.isWrite(), MaskExpand(req.wmask), 0.U(DataBits.W)) val writeL2BeatCnt = Counter(LineBeats) - when(io.out.fire() && (req.cmd === SimpleBusCmd.writeBurst || req.isWriteLast())) { + when(io.out.fire && (req.cmd === SimpleBusCmd.writeBurst || req.isWriteLast())) { writeL2BeatCnt.inc() } @@ -297,7 +295,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod val needFlush = RegInit(false.B) when (io.flush && (state =/= s_idle)) { needFlush := true.B } - when (io.out.fire() && needFlush) { needFlush := false.B } + when (io.out.fire && needFlush) { needFlush := false.B } val readBeatCnt = Counter(LineBeats) val writeBeatCnt = Counter(LineBeats) @@ -311,9 +309,9 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod val dataHitWay = Mux1H(io.in.bits.waymask, dataWay).data switch (state2) { - is (s2_idle) { when (io.dataReadBus.req.fire()) { state2 := s2_dataReadWait } } + is (s2_idle) { when (io.dataReadBus.req.fire) { state2 := s2_dataReadWait } } is (s2_dataReadWait) { state2 := s2_dataOK } - is (s2_dataOK) { when (io.mem.req.fire() || io.cohResp.fire() || hitReadBurst && io.out.ready) { state2 := s2_idle } } + is (s2_dataOK) { when (io.mem.req.fire || io.cohResp.fire || hitReadBurst && io.out.ready) { state2 := s2_idle } } } // critical word first read @@ -336,8 +334,8 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod io.mmio.req.valid := (state === s_mmioReq) val afterFirstRead = RegInit(false.B) - val alreadyOutFire = RegEnable(true.B, init = false.B, io.out.fire()) - val readingFirst = !afterFirstRead && io.mem.resp.fire() && (state === s_memReadResp) + val alreadyOutFire = RegEnable(true.B, false.B, io.out.fire) + val readingFirst = !afterFirstRead && io.mem.resp.fire && (state === s_memReadResp) val inRdataRegDemand = RegEnable(Mux(mmio, io.mmio.resp.bits.rdata, io.mem.resp.bits.rdata), Mux(mmio, state === s_mmioResp, readingFirst)) @@ -345,7 +343,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod io.cohResp.valid := ((state === s_idle) && probe) || ((state === s_release) && (state2 === s2_dataOK)) io.cohResp.bits.rdata := dataHitWay - val releaseLast = Counter(state === s_release && io.cohResp.fire(), LineBeats)._2 + val releaseLast = Counter(state === s_release && io.cohResp.fire, LineBeats)._2 io.cohResp.bits.cmd := Mux(state === s_release, Mux(releaseLast, SimpleBusCmd.readLast, 0.U), Mux(hit, SimpleBusCmd.probeHit, SimpleBusCmd.probeMiss)) @@ -358,7 +356,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod alreadyOutFire := false.B when (probe) { - when (io.cohResp.fire()) { + when (io.cohResp.fire) { state := Mux(hit, s_release, s_idle) readBeatCnt.value := addr.wordIndex } @@ -370,40 +368,40 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod } } - is (s_mmioReq) { when (io.mmio.req.fire()) { state := s_mmioResp } } - is (s_mmioResp) { when (io.mmio.resp.fire()) { state := s_wait_resp } } + is (s_mmioReq) { when (io.mmio.req.fire) { state := s_mmioResp } } + is (s_mmioResp) { when (io.mmio.resp.fire) { state := s_wait_resp } } is (s_release) { - when (io.cohResp.fire() || respToL1Fire) { readBeatCnt.inc() } - when (probe && io.cohResp.fire() && releaseLast || respToL1Fire && respToL1Last) { state := s_idle } + when (io.cohResp.fire || respToL1Fire) { readBeatCnt.inc() } + when (probe && io.cohResp.fire && releaseLast || respToL1Fire && respToL1Last) { state := s_idle } } - is (s_memReadReq) { when (io.mem.req.fire()) { + is (s_memReadReq) { when (io.mem.req.fire) { state := s_memReadResp readBeatCnt.value := addr.wordIndex }} is (s_memReadResp) { - when (io.mem.resp.fire()) { + when (io.mem.resp.fire) { afterFirstRead := true.B readBeatCnt.inc() when (req.cmd === SimpleBusCmd.writeBurst) { writeL2BeatCnt.value := 0.U } - when (io.mem.resp.bits.isReadLast()) { state := s_wait_resp } + when (io.mem.resp.bits.isReadLast) { state := s_wait_resp } } } is (s_memWriteReq) { - when (io.mem.req.fire()) { writeBeatCnt.inc() } - when (io.mem.req.bits.isWriteLast() && io.mem.req.fire()) { state := s_memWriteResp } + when (io.mem.req.fire) { writeBeatCnt.inc() } + when (io.mem.req.bits.isWriteLast() && io.mem.req.fire) { state := s_memWriteResp } } - is (s_memWriteResp) { when (io.mem.resp.fire()) { state := s_memReadReq } } - is (s_wait_resp) { when (io.out.fire() || needFlush || alreadyOutFire) { state := s_idle } } + is (s_memWriteResp) { when (io.mem.resp.fire) { state := s_memReadReq } } + is (s_wait_resp) { when (io.out.fire || needFlush || alreadyOutFire) { state := s_idle } } } val dataRefill = MaskData(io.mem.resp.bits.rdata, req.wdata, Mux(readingFirst, wordMask, 0.U(DataBits.W))) - val dataRefillWriteBus = Wire(CacheDataArrayWriteBus).apply( - valid = (state === s_memReadResp) && io.mem.resp.fire(), setIdx = Cat(addr.index, readBeatCnt.value), + val dataRefillWriteBus = Wire(CacheDataArrayWriteBus()).apply( + valid = (state === s_memReadResp) && io.mem.resp.fire, setIdx = Cat(addr.index, readBeatCnt.value), data = Wire(new DataBundle).apply(dataRefill), waymask = io.in.bits.waymask) dataWriteArb.io.in(0) <> dataHitWriteBus.req @@ -411,7 +409,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod io.dataWriteBus.req <> dataWriteArb.io.out val metaRefillWriteBus = Wire(CacheMetaArrayWriteBus()).apply( - valid = (state === s_memReadResp) && io.mem.resp.fire() && io.mem.resp.bits.isReadLast(), + valid = (state === s_memReadResp) && io.mem.resp.fire && io.mem.resp.bits.isReadLast, data = Wire(new MetaBundle).apply(valid = true.B, tag = addr.tag, dirty = !ro.B && req.isWrite()), setIdx = getMetaIdx(req.addr), waymask = io.in.bits.waymask ) @@ -421,10 +419,10 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod io.metaWriteBus.req <> metaWriteArb.io.out if (cacheLevel == 2) { - when ((state === s_memReadResp) && io.mem.resp.fire() && req.isReadBurst()) { + when ((state === s_memReadResp) && io.mem.resp.fire && req.isReadBurst()) { // readBurst request miss io.out.bits.rdata := dataRefill - io.out.bits.cmd := Mux(io.mem.resp.bits.isReadLast(), SimpleBusCmd.readLast, SimpleBusCmd.readBurst) + io.out.bits.cmd := Mux(io.mem.resp.bits.isReadLast, SimpleBusCmd.readLast, SimpleBusCmd.readBurst) }.elsewhen (req.isWriteLast() || req.cmd === SimpleBusCmd.writeBurst) { // writeBurst/writeLast request, no matter hit or miss io.out.bits.rdata := Mux(hit, dataRead, inRdataRegDemand) @@ -445,7 +443,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod io.out.bits.id.zip(req.id).map { case (o,i) => o := i } io.out.valid := io.in.valid && Mux(req.isBurst() && (cacheLevel == 2).B, - Mux(req.isWrite() && (hit || !hit && state === s_wait_resp), true.B, (state === s_memReadResp && io.mem.resp.fire() && req.cmd === SimpleBusCmd.readBurst)) || (respToL1Fire && respToL1Last && state === s_release), + Mux(req.isWrite() && (hit || !hit && state === s_wait_resp), true.B, (state === s_memReadResp && io.mem.resp.fire && req.cmd === SimpleBusCmd.readBurst)) || (respToL1Fire && respToL1Last && state === s_release), Mux(probe, false.B, Mux(hit, true.B, Mux(req.isWrite() || mmio, state === s_wait_resp, afterFirstRead && !alreadyOutFire))) ) @@ -453,8 +451,8 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod // s2 and s3 can not be overwritten before a missing request // is totally handled. We use io.isFinish to indicate when the // request really ends. - io.isFinish := Mux(probe, io.cohResp.fire() && Mux(miss, state === s_idle, (state === s_release) && releaseLast), - Mux(hit || req.isWrite(), io.out.fire(), (state === s_wait_resp) && (io.out.fire() || alreadyOutFire)) + io.isFinish := Mux(probe, io.cohResp.fire && Mux(miss, state === s_idle, (state === s_release) && releaseLast), + Mux(hit || req.isWrite(), io.out.fire, (state === s_wait_resp) && (io.out.fire || alreadyOutFire)) ) io.in.ready := io.out.ready && (state === s_idle && !hitReadBurst) && !miss && !probe @@ -464,17 +462,17 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod assert(!(dataHitWriteBus.req.valid && dataRefillWriteBus.req.valid)) assert(!(!ro.B && io.flush), "only allow to flush icache") Debug(" metaread idx %x waymask %b metas %x%x:%x %x%x:%x %x%x:%x %x%x:%x %x\n", getMetaIdx(req.addr), io.in.bits.waymask.asUInt, io.in.bits.metas(0).valid, io.in.bits.metas(0).dirty, io.in.bits.metas(0).tag, io.in.bits.metas(1).valid, io.in.bits.metas(1).dirty, io.in.bits.metas(1).tag, io.in.bits.metas(2).valid, io.in.bits.metas(2).dirty, io.in.bits.metas(2).tag, io.in.bits.metas(3).valid, io.in.bits.metas(3).dirty, io.in.bits.metas(3).tag, io.in.bits.datas.asUInt) - Debug(io.metaWriteBus.req.fire(), "%d: [" + cacheName + " S3]: metawrite idx %x wmask %b meta %x%x:%x\n", GTimer(), io.metaWriteBus.req.bits.setIdx, io.metaWriteBus.req.bits.waymask.get, io.metaWriteBus.req.bits.data.valid, io.metaWriteBus.req.bits.data.dirty, io.metaWriteBus.req.bits.data.tag) + Debug(io.metaWriteBus.req.fire, "%d: [" + cacheName + " S3]: metawrite idx %x wmask %b meta %x%x:%x\n", GTimer(), io.metaWriteBus.req.bits.setIdx, io.metaWriteBus.req.bits.waymask.get, io.metaWriteBus.req.bits.data.valid, io.metaWriteBus.req.bits.data.dirty, io.metaWriteBus.req.bits.data.tag) Debug(" in.ready = %d, in.valid = %d, hit = %x, state = %d, addr = %x cmd:%d probe:%d isFinish:%d\n", io.in.ready, io.in.valid, hit, state, req.addr, req.cmd, probe, io.isFinish) Debug(" out.valid:%d rdata:%x cmd:%d user:%x id:%x \n", io.out.valid, io.out.bits.rdata, io.out.bits.cmd, io.out.bits.user.getOrElse(0.U), io.out.bits.id.getOrElse(0.U)) Debug(" DHW: (%d, %d), data:%x setIdx:%x MHW:(%d, %d)\n", dataHitWriteBus.req.valid, dataHitWriteBus.req.ready, dataHitWriteBus.req.bits.data.asUInt, dataHitWriteBus.req.bits.setIdx, metaHitWriteBus.req.valid, metaHitWriteBus.req.ready) Debug(" DreadCache: %x \n", io.in.bits.datas.asUInt) Debug(" useFD:%d isFD:%d FD:%x DreadArray:%x dataRead:%x inwaymask:%x FDwaymask:%x \n", useForwardData, io.in.bits.isForwardData, io.in.bits.forwardData.data.data, dataReadArray, dataRead, io.in.bits.waymask, io.in.bits.forwardData.waymask.getOrElse("b1".U)) - Debug(io.dataWriteBus.req.fire(), "[WB] waymask: %b data:%x setIdx:%x\n", + Debug(io.dataWriteBus.req.fire, "[WB] waymask: %b data:%x setIdx:%x\n", io.dataWriteBus.req.bits.waymask.get.asUInt, io.dataWriteBus.req.bits.data.asUInt, io.dataWriteBus.req.bits.setIdx) - Debug((state === s_memWriteReq) && io.mem.req.fire(), "[COUTW] cnt %x addr %x data %x cmd %x size %x wmask %x tag %x idx %x waymask %b \n", writeBeatCnt.value, io.mem.req.bits.addr, io.mem.req.bits.wdata, io.mem.req.bits.cmd, io.mem.req.bits.size, io.mem.req.bits.wmask, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) - Debug((state === s_memReadReq) && io.mem.req.fire(), "[COUTR] addr %x tag %x idx %x waymask %b \n", io.mem.req.bits.addr, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) - Debug((state === s_memReadResp) && io.mem.resp.fire(), "[COUTR] cnt %x data %x tag %x idx %x waymask %b \n", readBeatCnt.value, io.mem.resp.bits.rdata, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) + Debug((state === s_memWriteReq) && io.mem.req.fire, "[COUTW] cnt %x addr %x data %x cmd %x size %x wmask %x tag %x idx %x waymask %b \n", writeBeatCnt.value, io.mem.req.bits.addr, io.mem.req.bits.wdata, io.mem.req.bits.cmd, io.mem.req.bits.size, io.mem.req.bits.wmask, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) + Debug((state === s_memReadReq) && io.mem.req.fire, "[COUTR] addr %x tag %x idx %x waymask %b \n", io.mem.req.bits.addr, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) + Debug((state === s_memReadResp) && io.mem.resp.fire, "[COUTR] cnt %x data %x tag %x idx %x waymask %b \n", readBeatCnt.value, io.mem.resp.bits.rdata, addr.tag, getMetaIdx(req.addr), io.in.bits.waymask) } class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule with HasCacheIO { @@ -501,7 +499,7 @@ class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule with HasC s2.io.out.valid && s3.io.in.valid && s3.io.in.bits.req.isPrefetch() && !s3.io.in.ready } else { false.B } */ - PipelineConnect(s1.io.out, s2.io.in, s2.io.out.fire(), io.flush(0)) + 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 s3.io.flush := io.flush(1) @@ -509,7 +507,7 @@ class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule with HasC io.mmio <> s3.io.mmio io.empty := !s2.io.in.valid && !s3.io.in.valid - io.in.resp.valid := Mux(s3.io.out.valid && s3.io.out.bits.isPrefetch(), false.B, s3.io.out.valid || s3.io.dataReadRespToL1) + io.in.resp.valid := Mux(s3.io.out.valid && s3.io.out.bits.isPrefetch, false.B, s3.io.out.valid || s3.io.dataReadRespToL1) if (hasCoh) { val cohReq = io.out.coh.req.bits @@ -540,9 +538,9 @@ class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule with HasC s2.io.metaWriteBus := s3.io.metaWriteBus if (EnableOutOfOrderExec) { - BoringUtils.addSource(s3.io.out.fire() && s3.io.in.bits.hit, "perfCntCondM" + cacheName + "Hit") + BoringUtils.addSource(s3.io.out.fire && s3.io.in.bits.hit, "perfCntCondM" + cacheName + "Hit") BoringUtils.addSource(s3.io.in.valid && !s3.io.in.bits.hit, "perfCntCondM" + cacheName + "Loss") - BoringUtils.addSource(s1.io.in.fire(), "perfCntCondM" + cacheName + "Req") + BoringUtils.addSource(s1.io.in.fire, "perfCntCondM" + cacheName + "Req") } // io.in.dump(cacheName + ".in") Debug("InReq(%d, %d) InResp(%d, %d) \n", io.in.req.valid, io.in.req.ready, io.in.resp.valid, io.in.resp.ready) @@ -558,7 +556,7 @@ class Cache_fake(implicit val cacheConfig: CacheConfig) extends CacheModule with val state = RegInit(s_idle) val ismmio = AddressSpace.isMMIO(io.in.req.bits.addr) - val ismmioRec = RegEnable(ismmio, io.in.req.fire()) + val ismmioRec = RegEnable(ismmio, io.in.req.fire) if (cacheConfig.name == "dcache") { BoringUtils.addSource(ismmio, "lsuMMIO") } @@ -567,48 +565,48 @@ class Cache_fake(implicit val cacheConfig: CacheConfig) extends CacheModule with when (io.flush(0) && (state =/= s_idle)) { needFlush := true.B } when (state === s_idle && needFlush) { needFlush := false.B } - val alreadyOutFire = RegEnable(true.B, init = false.B, io.in.resp.fire()) + val alreadyOutFire = RegEnable(true.B, false.B, io.in.resp.fire) switch (state) { is (s_idle) { alreadyOutFire := false.B - when (io.in.req.fire() && !io.flush(0)) { state := Mux(ismmio, s_mmioReq, s_memReq) } + when (io.in.req.fire && !io.flush(0)) { state := Mux(ismmio, s_mmioReq, s_memReq) } } is (s_memReq) { - when (io.out.mem.req.fire()) { state := s_memResp } + when (io.out.mem.req.fire) { state := s_memResp } } is (s_memResp) { - when (io.out.mem.resp.fire()) { state := s_wait_resp } + when (io.out.mem.resp.fire) { state := s_wait_resp } } is (s_mmioReq) { - when (io.mmio.req.fire()) { state := s_mmioResp } + when (io.mmio.req.fire) { state := s_mmioResp } } is (s_mmioResp) { - when (io.mmio.resp.fire() || alreadyOutFire) { state := s_wait_resp } + when (io.mmio.resp.fire || alreadyOutFire) { state := s_wait_resp } } is (s_wait_resp) { - when (io.in.resp.fire() || needFlush || alreadyOutFire) { state := s_idle } + when (io.in.resp.fire || needFlush || alreadyOutFire) { state := s_idle } } } - val reqaddr = RegEnable(io.in.req.bits.addr, io.in.req.fire()) - val cmd = RegEnable(io.in.req.bits.cmd, io.in.req.fire()) - val size = RegEnable(io.in.req.bits.size, io.in.req.fire()) - val wdata = RegEnable(io.in.req.bits.wdata, io.in.req.fire()) - val wmask = RegEnable(io.in.req.bits.wmask, io.in.req.fire()) + val reqaddr = RegEnable(io.in.req.bits.addr, io.in.req.fire) + val cmd = RegEnable(io.in.req.bits.cmd, io.in.req.fire) + val size = RegEnable(io.in.req.bits.size, io.in.req.fire) + val wdata = RegEnable(io.in.req.bits.wdata, io.in.req.fire) + val wmask = RegEnable(io.in.req.bits.wmask, io.in.req.fire) io.in.req.ready := (state === s_idle) io.in.resp.valid := (state === s_wait_resp) && (!needFlush) - val mmiordata = RegEnable(io.mmio.resp.bits.rdata, io.mmio.resp.fire()) - val mmiocmd = RegEnable(io.mmio.resp.bits.cmd, io.mmio.resp.fire()) - val memrdata = RegEnable(io.out.mem.resp.bits.rdata, io.out.mem.resp.fire()) - val memcmd = RegEnable(io.out.mem.resp.bits.cmd, io.out.mem.resp.fire()) + val mmiordata = RegEnable(io.mmio.resp.bits.rdata, io.mmio.resp.fire) + val mmiocmd = RegEnable(io.mmio.resp.bits.cmd, io.mmio.resp.fire) + val memrdata = RegEnable(io.out.mem.resp.bits.rdata, io.out.mem.resp.fire) + val memcmd = RegEnable(io.out.mem.resp.bits.cmd, io.out.mem.resp.fire) io.in.resp.bits.rdata := Mux(ismmioRec, mmiordata, memrdata) io.in.resp.bits.cmd := Mux(ismmioRec, mmiocmd, memcmd) - val memuser = RegEnable(io.in.req.bits.user.getOrElse(0.U), io.in.req.fire()) + val memuser = RegEnable(io.in.req.bits.user.getOrElse(0.U), io.in.req.fire) io.in.resp.bits.user.zip(if (userBits > 0) Some(memuser) else None).map { case (o,i) => o := i } io.out.mem.req.bits.apply(addr = reqaddr, @@ -616,7 +614,7 @@ class Cache_fake(implicit val cacheConfig: CacheConfig) extends CacheModule with wdata = wdata, wmask = wmask) io.out.mem.req.valid := (state === s_memReq) io.out.mem.resp.ready := true.B - + io.mmio.req.bits.apply(addr = reqaddr, cmd = cmd, size = size, wdata = wdata, wmask = wmask) @@ -626,10 +624,10 @@ class Cache_fake(implicit val cacheConfig: CacheConfig) extends CacheModule with io.empty := false.B io.out.coh := DontCare - Debug(io.in.req.fire(), p"in.req: ${io.in.req.bits}\n") - Debug(io.out.mem.req.fire(), p"out.mem.req: ${io.out.mem.req.bits}\n") - Debug(io.out.mem.resp.fire(), p"out.mem.resp: ${io.out.mem.resp.bits}\n") - Debug(io.in.resp.fire(), p"in.resp: ${io.in.resp.bits}\n") + Debug(io.in.req.fire, p"in.req: ${io.in.req.bits}\n") + Debug(io.out.mem.req.fire, p"out.mem.req: ${io.out.mem.req.bits}\n") + Debug(io.out.mem.resp.fire, p"out.mem.resp: ${io.out.mem.resp.bits}\n") + Debug(io.in.resp.fire, p"in.resp: ${io.in.resp.bits}\n") } class Cache_dummy(implicit val cacheConfig: CacheConfig) extends CacheModule with HasCacheIO { @@ -638,7 +636,7 @@ class Cache_dummy(implicit val cacheConfig: CacheConfig) extends CacheModule wit when (io.flush(0)) { needFlush := true.B } - when (io.in.req.fire() && !io.flush(0)) { + when (io.in.req.fire && !io.flush(0)) { needFlush := false.B } @@ -647,10 +645,10 @@ class Cache_dummy(implicit val cacheConfig: CacheConfig) extends CacheModule wit io.in.resp.bits.rdata := io.out.mem.resp.bits.rdata io.in.resp.bits.cmd := io.out.mem.resp.bits.cmd - val memuser = RegEnable(io.in.req.bits.user.getOrElse(0.U), io.in.req.fire()) + val memuser = RegEnable(io.in.req.bits.user.getOrElse(0.U), io.in.req.fire) io.in.resp.bits.user.zip(if (userBits > 0) Some(memuser) else None).map { case (o,i) => o := i } - io.out.mem.req.bits.apply( + io.out.mem.req.bits.apply( addr = io.in.req.bits.addr, cmd = io.in.req.bits.cmd, size = io.in.req.bits.size, @@ -667,10 +665,10 @@ class Cache_dummy(implicit val cacheConfig: CacheConfig) extends CacheModule wit object Cache { def apply(in: SimpleBusUC, mmio: Seq[SimpleBusUC], flush: UInt, empty: Bool, enable: Boolean = true)(implicit cacheConfig: CacheConfig) = { - val cache = if (enable) Module(new Cache) - else (if (Settings.get("IsRV32")) - (if (cacheConfig.name == "dcache") Module(new Cache_fake) else Module(new Cache_dummy)) - else + val cache = if (enable) Module(new Cache) + else (if (Settings.get("IsRV32")) + (if (cacheConfig.name == "dcache") Module(new Cache_fake) else Module(new Cache_dummy)) + else (Module(new Cache_fake))) cache.io.flush := flush cache.io.in <> in diff --git a/src/main/scala/nutcore/mem/EmbeddedTLB.scala b/src/main/scala/nutcore/mem/EmbeddedTLB.scala index f15d08f5b..668cf7859 100644 --- a/src/main/scala/nutcore/mem/EmbeddedTLB.scala +++ b/src/main/scala/nutcore/mem/EmbeddedTLB.scala @@ -20,8 +20,6 @@ import chisel3._ import chisel3.util._ import chisel3.util.experimental.BoringUtils import bus.simplebus._ -import bus.axi4._ -import chisel3.experimental.IO import utils._ import top.Settings @@ -121,7 +119,7 @@ class EmbeddedTLB(implicit val tlbConfig: TLBConfig) extends TlbModule with HasT tlbEmpty.io.out.ready := DontCare PipelineConnectTLB(io.in.req, tlbExec.io.in, mdUpdate, tlbExec.io.isFinish, io.flush, vmEnable) if(tlbname == "dtlb") { - PipelineConnect(tlbExec.io.out, tlbEmpty.io.in, tlbEmpty.io.out.fire(), io.flush) + PipelineConnect(tlbExec.io.out, tlbEmpty.io.in, tlbEmpty.io.out.fire, io.flush) } when(!vmEnable) { tlbExec.io.out.ready := true.B // let existed request go out @@ -142,8 +140,8 @@ class EmbeddedTLB(implicit val tlbConfig: TLBConfig) extends TlbModule with HasT // lsu need dtlb signals if(tlbname == "dtlb") { - val alreadyOutFinish = RegEnable(true.B, init=false.B, tlbExec.io.out.valid && !tlbExec.io.out.ready) - when(alreadyOutFinish && tlbExec.io.out.fire()) { alreadyOutFinish := false.B} + val alreadyOutFinish = RegEnable(true.B, false.B, tlbExec.io.out.valid && !tlbExec.io.out.ready) + when(alreadyOutFinish && tlbExec.io.out.fire) { alreadyOutFinish := false.B} val tlbFinish = (tlbExec.io.out.valid && !alreadyOutFinish) || tlbExec.io.pf.isPF() BoringUtils.addSource(tlbFinish, "DTLBFINISH") BoringUtils.addSource(io.csrMMU.isPF(), "DTLBPF") @@ -258,14 +256,14 @@ class EmbeddedTLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val missRefillFlag = WireInit(0.U(8.W)) val memRdata = io.mem.resp.bits.rdata.asTypeOf(pteBundle) val raddr = Reg(UInt(PAddrBits.W)) - val alreadyOutFire = RegEnable(true.B, init = false.B, io.out.fire) + val alreadyOutFire = RegEnable(true.B, false.B, io.out.fire) //handle flush val needFlush = RegInit(false.B) val ioFlush = io.flush val isFlush = needFlush || ioFlush when (ioFlush && (state =/= s_idle)) { needFlush := true.B} - when (io.out.fire() && needFlush) { needFlush := false.B} + when (io.out.fire && needFlush) { needFlush := false.B} val missIPF = RegInit(false.B) @@ -289,12 +287,12 @@ class EmbeddedTLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ when (isFlush) { state := s_idle needFlush := false.B - }.elsewhen (io.mem.req.fire()) { state := s_memReadResp} + }.elsewhen (io.mem.req.fire) { state := s_memReadResp} } is (s_memReadResp) { val missflag = memRdata.flag.asTypeOf(flagBundle) - when (io.mem.resp.fire()) { + when (io.mem.resp.fire) { when (isFlush) { state := s_idle needFlush := false.B @@ -352,10 +350,10 @@ class EmbeddedTLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ when (isFlush) { state := s_idle needFlush := false.B - }.elsewhen (io.mem.req.fire()) { state := s_wait_resp } + }.elsewhen (io.mem.req.fire) { state := s_wait_resp } } - is (s_wait_resp) { when (io.out.fire() || ioFlush || alreadyOutFire){ + is (s_wait_resp) { when (io.out.fire || ioFlush || alreadyOutFire){ state := s_idle missIPF := false.B alreadyOutFire := false.B @@ -387,7 +385,7 @@ class EmbeddedTLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ io.in.ready := io.out.ready && (state === s_idle) && !miss && !hitWB && io.mdReady && (!io.pf.isPF() && !loadPF && !storePF)//maybe be optimized io.ipf := Mux(hit, hitinstrPF, missIPF) - io.isFinish := io.out.fire() || io.pf.isPF() + io.isFinish := io.out.fire || io.pf.isPF() Debug("In(%d, %d) Out(%d, %d) InAddr:%x OutAddr:%x cmd:%d \n", io.in.valid, io.in.ready, io.out.valid, io.out.ready, req.addr, io.out.bits.addr, req.cmd) Debug("isAMO:%d io.Flush:%d needFlush:%d alreadyOutFire:%d isFinish:%d\n",isAMO, io.flush, needFlush, alreadyOutFire, io.isFinish) diff --git a/src/main/scala/nutcore/mem/TLB.scala b/src/main/scala/nutcore/mem/TLB.scala index bcd452174..ed0ae0016 100644 --- a/src/main/scala/nutcore/mem/TLB.scala +++ b/src/main/scala/nutcore/mem/TLB.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -36,7 +36,7 @@ sealed trait Sv39Const extends HasNutCoreParameter{ val vpn1Len = 9 val vpn0Len = 9 val vpnLen = vpn2Len + vpn1Len + vpn0Len - + //val paddrLen = PAddrBits //val vaddrLen = VAddrBits val satpLen = XLEN @@ -47,7 +47,7 @@ sealed trait Sv39Const extends HasNutCoreParameter{ val ptEntryLen = XLEN val satpResLen = XLEN - ppnLen - satpModeLen - asidLen //val vaResLen = 25 // unused - //val paResLen = 25 // unused + //val paResLen = 25 // unused val pteResLen = XLEN - ppnLen - 2 - flagLen def vaBundle = new Bundle { @@ -88,7 +88,7 @@ sealed trait Sv39Const extends HasNutCoreParameter{ def paddrApply(ppn: UInt, vpnn: UInt):UInt = { Cat(Cat(ppn, vpnn), 0.U(3.W)) } - + def pteBundle = new Bundle { val reserved = UInt(pteResLen.W) val ppn = UInt(ppnLen.W) @@ -153,8 +153,8 @@ trait HasTlbConst extends Sv39Const{ val userBits = tlbConfig.userBits val maskLen = vpn0Len + vpn1Len // 18 - val metaLen = vpnLen + asidLen + maskLen + flagLen // 27 + 16 + 18 + 8 = 69, is asid necessary - val dataLen = ppnLen + PAddrBits // + val metaLen = vpnLen + asidLen + maskLen + flagLen // 27 + 16 + 18 + 8 = 69, is asid necessary + val dataLen = ppnLen + PAddrBits // val tlbLen = metaLen + dataLen val Ways = tlbConfig.ways val TotalEntry = tlbConfig.totalEntry @@ -209,8 +209,8 @@ sealed class TLBMDWriteBundle (val IndexBits: Int, val Ways: Int, val tlbLen: In val windex = Output(UInt(IndexBits.W)) val waymask = Output(UInt(Ways.W)) val wdata = Output(UInt(tlbLen.W)) - - def apply(wen: UInt, windex: UInt, waymask: UInt, vpn: UInt, asid: UInt, mask: UInt, flag: UInt, ppn: UInt, pteaddr: UInt) { + + def apply(wen: UInt, windex: UInt, waymask: UInt, vpn: UInt, asid: UInt, mask: UInt, flag: UInt, ppn: UInt, pteaddr: UInt) = { this.wen := wen this.windex := windex this.waymask := waymask @@ -274,7 +274,7 @@ class TLB(implicit val tlbConfig: TLBConfig) extends TlbModule{ val tlbExec = Module(new TLBExec) val mdTLB = Module(new TLBMD) val mdUpdate = Wire(Bool()) - + tlbExec.io.flush := io.flush tlbExec.io.satp := satp tlbExec.io.mem <> io.mem @@ -283,9 +283,9 @@ class TLB(implicit val tlbConfig: TLBConfig) extends TlbModule{ tlbExec.io.mdReady := mdTLB.io.ready mdTLB.io.rindex := getIndex(io.in.req.bits.addr) mdTLB.io.write <> tlbExec.io.mdWrite - + io.ipf := false.B - + // meta reset val flushTLB = WireInit(false.B) BoringUtils.addSink(flushTLB, "MOUFlushTLB") @@ -330,8 +330,8 @@ class TLB(implicit val tlbConfig: TLBConfig) extends TlbModule{ io.in.resp.bits.rdata := tlbExec.io.out.bits.addr io.in.resp.bits.cmd := DontCare io.in.resp.bits.user.map(_ := tlbExec.io.out.bits.user.getOrElse(0.U)) - val alreadyOutFinish = RegEnable(true.B, init=false.B, tlbExec.io.out.valid && !tlbExec.io.out.ready) - // when(alreadyOutFinish && tlbExec.io.out.fire()) { alreadyOutFinish := false.B} + val alreadyOutFinish = RegEnable(true.B, false.B, tlbExec.io.out.valid && !tlbExec.io.out.ready) + // when(alreadyOutFinish && tlbExec.io.out.fire) { alreadyOutFinish := false.B} when(alreadyOutFinish && tlbExec.io.out.valid) { alreadyOutFinish := false.B}//??? val tlbFinish = (tlbExec.io.out.valid && !alreadyOutFinish) || tlbExec.io.pf.isPF() BoringUtils.addSource(tlbFinish, "DTLBFINISH") @@ -380,7 +380,7 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val io = IO(new TLBExecIO) val md = io.md//RegEnable(mdTLB.io.tlbmd, io.in.ready) - + // lazy renaming val req = io.in.bits val vpn = req.addr.asTypeOf(vaBundle2).vpn.asTypeOf(vpnBundle) @@ -425,7 +425,7 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ io.pf.storePF := storePF //RegNext(storePF, init = false.B) if (tlbname == "itlb") { hitinstrPF := !hitExec && hit} - if (tlbname == "dtlb") { + if (tlbname == "dtlb") { loadPF := !hitLoad && req.isRead() && hit storePF := (!hitStore && req.isWrite() && hit) // AMO pagefault type will be fixed in LSU @@ -435,7 +435,7 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val s_idle :: s_memReadReq :: s_memReadResp :: s_write_pte :: s_wait_resp :: s_miss_slpf :: Nil = Enum(6) val state = RegInit(s_idle) val level = RegInit(Level.U(log2Up(Level).W)) - + val memRespStore = Reg(UInt(XLEN.W)) val missMask = WireInit("h3ffff".U(maskLen.W)) val missMaskStore = Reg(UInt(maskLen.W)) @@ -443,7 +443,7 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val missRefillFlag = WireInit(0.U(8.W)) val memRdata = io.mem.resp.bits.rdata.asTypeOf(pteBundle) val raddr = Reg(UInt(PAddrBits.W)) - val alreadyOutFire = RegEnable(true.B, init = false.B, if(tlbname == "itlb") io.out.fire else io.out.valid) + val alreadyOutFire = RegEnable(true.B, false.B, if(tlbname == "itlb") io.out.fire else io.out.valid) //handle flush val needFlush = RegInit(false.B) @@ -451,7 +451,7 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val isFlush = needFlush || ioFlush when (ioFlush && (state =/= s_idle)) { needFlush := true.B} if(tlbname == "itlb"){ - when (io.out.fire() && needFlush) { needFlush := false.B} + when (io.out.fire && needFlush) { needFlush := false.B} } if(tlbname == "dtlb"){ when (io.out.valid && needFlush) { needFlush := false.B} @@ -475,16 +475,16 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ } } - is (s_memReadReq) { + is (s_memReadReq) { when (isFlush) { state := s_idle needFlush := false.B - }.elsewhen (io.mem.req.fire()) { state := s_memReadResp} + }.elsewhen (io.mem.req.fire) { state := s_memReadResp} } - is (s_memReadResp) { + is (s_memReadResp) { val missflag = memRdata.flag.asTypeOf(flagBundle) - when (io.mem.resp.fire()) { + when (io.mem.resp.fire) { when (isFlush) { state := s_idle needFlush := false.B @@ -492,10 +492,10 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ when(!missflag.v || (!missflag.r && missflag.w)) { //TODO: fix needflush if(tlbname == "itlb") { state := s_wait_resp } else { state := s_miss_slpf } if(tlbname == "itlb") { missIPF := true.B } - if(tlbname == "dtlb") { + if(tlbname == "dtlb") { loadPF := req.isRead() - storePF := req.isWrite() - } + storePF := req.isWrite() + } Debug("tlbException!!! ") Debug(false, p" req:${req} Memreq:${io.mem.req} MemResp:${io.mem.resp}") Debug(false, " level:%d",level) @@ -512,16 +512,16 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ val updateAD = if (Settings.get("FPGAPlatform")) !missflag.a || (!missflag.d && req.isWrite()) else false.B val updateData = Cat( 0.U(56.W), req.isWrite(), 1.U(1.W), 0.U(6.W) ) missRefillFlag := Cat(req.isWrite(), 1.U(1.W), 0.U(6.W)) | missflag.asUInt - memRespStore := io.mem.resp.bits.rdata | updateData + memRespStore := io.mem.resp.bits.rdata | updateData if(tlbname == "itlb") { when (!permExec) { missIPF := true.B ; state := s_wait_resp} - .otherwise { + .otherwise { state := Mux(updateAD, s_write_pte, s_wait_resp) missMetaRefill := true.B } } if(tlbname == "dtlb") { - when((!permLoad && req.isRead()) || (!permStore && req.isWrite())) { + when((!permLoad && req.isRead()) || (!permStore && req.isWrite())) { state := s_miss_slpf loadPF := req.isRead() storePF := req.isWrite() @@ -541,12 +541,12 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ when (isFlush) { state := s_idle needFlush := false.B - }.elsewhen (io.mem.req.fire()) { state := s_wait_resp } + }.elsewhen (io.mem.req.fire) { state := s_wait_resp } } - is (s_wait_resp) { + is (s_wait_resp) { if(tlbname == "itlb"){ - when (io.out.fire() || ioFlush || alreadyOutFire){ + when (io.out.fire || ioFlush || alreadyOutFire){ state := s_idle missIPF := false.B alreadyOutFire := false.B @@ -571,21 +571,21 @@ sealed class TLBExec(implicit val tlbConfig: TLBConfig) extends TlbModule{ io.mem.resp.ready := true.B // tlb refill - io.mdWrite.apply(wen = RegNext((missMetaRefill && !isFlush) || (hitWB && state === s_idle && !isFlush), init = false.B), - windex = RegNext(getIndex(req.addr)), waymask = RegNext(waymask), vpn = RegNext(vpn.asUInt), - asid = RegNext(Mux(hitWB, hitMeta.asid, satp.asid)), mask = RegNext(Mux(hitWB, hitMask, missMask)), - flag = RegNext(Mux(hitWB, hitRefillFlag, missRefillFlag)), ppn = RegNext(Mux(hitWB, hitData.ppn, memRdata.ppn)), + io.mdWrite.apply(wen = RegNext((missMetaRefill && !isFlush) || (hitWB && state === s_idle && !isFlush), init = false.B), + windex = RegNext(getIndex(req.addr)), waymask = RegNext(waymask), vpn = RegNext(vpn.asUInt), + asid = RegNext(Mux(hitWB, hitMeta.asid, satp.asid)), mask = RegNext(Mux(hitWB, hitMask, missMask)), + flag = RegNext(Mux(hitWB, hitRefillFlag, missRefillFlag)), ppn = RegNext(Mux(hitWB, hitData.ppn, memRdata.ppn)), pteaddr = RegNext((Mux(hitWB, hitData.pteaddr, raddr)))) // io io.out.bits := req io.out.bits.addr := Mux(hit, maskPaddr(hitData.ppn, req.addr(PAddrBits-1, 0), hitMask), maskPaddr(memRespStore.asTypeOf(pteBundle).ppn, req.addr(PAddrBits-1, 0), missMaskStore)) io.out.valid := io.in.valid && Mux(hit && !hitWB, !(io.pf.isPF() || loadPF || storePF), state === s_wait_resp)// && !alreadyOutFire - + io.in.ready := io.out.ready && (state === s_idle) && !miss && !hitWB && io.mdReady && (!io.pf.isPF() && !loadPF && !storePF)//maybe be optimized io.ipf := Mux(hit, hitinstrPF, missIPF) - io.isFinish := io.out.fire() || io.pf.isPF() + io.isFinish := io.out.fire || io.pf.isPF() if(tlbname == "dtlb") { io.isFinish := io.out.valid || io.pf.isPF() diff --git a/src/main/scala/nutcore/utils/WritebackDelayer.scala b/src/main/scala/nutcore/utils/WritebackDelayer.scala index 1d1c3f3a3..153f02704 100644 --- a/src/main/scala/nutcore/utils/WritebackDelayer.scala +++ b/src/main/scala/nutcore/utils/WritebackDelayer.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -33,7 +33,7 @@ class WritebackDelayer(bru: Boolean = false, name: String = "unnamedDelayer") ex val valid = RegInit(false.B) val brMask = Reg(UInt(checkpointSize.W)) - + def needMispredictionRecovery(brMask: UInt) = { io.mispredictRec.valid && io.mispredictRec.redirect.valid && brMask(io.mispredictRec.checkpoint) } @@ -43,19 +43,19 @@ class WritebackDelayer(bru: Boolean = false, name: String = "unnamedDelayer") ex } brMask := updateBrMask(brMask) - when(io.in.fire()){brMask := updateBrMask(io.in.bits.brMask)} - when(needMispredictionRecovery(brMask) || io.out.fire()){valid := false.B} - when(io.in.fire()){valid := true.B} + when(io.in.fire){brMask := updateBrMask(io.in.bits.brMask)} + when(needMispredictionRecovery(brMask) || io.out.fire){valid := false.B} + when(io.in.fire){valid := true.B} when(io.flush) {valid := false.B} - io.in.ready := (!valid || io.out.fire()) && !needMispredictionRecovery(io.in.bits.brMask) - io.out.bits <> RegEnable(io.in.bits, io.in.fire()) + io.in.ready := (!valid || io.out.fire) && !needMispredictionRecovery(io.in.bits.brMask) + io.out.bits <> RegEnable(io.in.bits, io.in.fire) io.out.bits.brMask := brMask io.out.valid := valid if(bru){ - io.freeCheckpoint.get.bits <> RegEnable(io.checkpointIn.get, io.in.fire()) - io.freeCheckpoint.get.valid := io.out.fire() + io.freeCheckpoint.get.bits <> RegEnable(io.checkpointIn.get, io.in.fire) + io.freeCheckpoint.get.valid := io.out.fire } Debug(valid, "[WBDelay-"+name+"] delayer valid: pc %x brMask %x\n", io.out.bits.decode.cf.pc, brMask) diff --git a/src/main/scala/sim/MeipGen.scala b/src/main/scala/sim/MeipGen.scala index aa11d7cb4..0f723e48b 100644 --- a/src/main/scala/sim/MeipGen.scala +++ b/src/main/scala/sim/MeipGen.scala @@ -36,7 +36,7 @@ class AXI4MeipGen extends AXI4SlaveModule(new AXI4Lite, new MeipGenIO) { def getOffset(addr: UInt) = addr(3, 0) RegMap.generate(mapping, getOffset(raddr), in.r.bits.data, - getOffset(waddr), in.w.fire(), in.w.bits.data(0), MaskExpand(in.w.bits.strb)(0)) + getOffset(waddr), in.w.fire, in.w.bits.data(0), MaskExpand(in.w.bits.strb)(0)) io.extra.get.meip := meip } diff --git a/src/main/scala/sim/SimMMIO.scala b/src/main/scala/sim/SimMMIO.scala index 925fa6f0c..463495418 100644 --- a/src/main/scala/sim/SimMMIO.scala +++ b/src/main/scala/sim/SimMMIO.scala @@ -51,13 +51,13 @@ class SimMMIO extends Module { val sd = Module(new AXI4DummySD) val meipGen = Module(new AXI4MeipGen) val dma = Module(new AXI4DMA) - uart.io.in <> xbar.io.out(0).toAXI4Lite() - vga.io.in.fb <> xbar.io.out(1).toAXI4Lite() - vga.io.in.ctrl <> xbar.io.out(2).toAXI4Lite() - flash.io.in <> xbar.io.out(3).toAXI4Lite() - sd.io.in <> xbar.io.out(4).toAXI4Lite() - meipGen.io.in <> xbar.io.out(5).toAXI4Lite() - dma.io.in <> xbar.io.out(6).toAXI4Lite() + uart.io.in <> xbar.io.out(0).toAXI4Lite + vga.io.in.fb <> xbar.io.out(1).toAXI4Lite + vga.io.in.ctrl <> xbar.io.out(2).toAXI4Lite + flash.io.in <> xbar.io.out(3).toAXI4Lite + sd.io.in <> xbar.io.out(4).toAXI4Lite + meipGen.io.in <> xbar.io.out(5).toAXI4Lite + dma.io.in <> xbar.io.out(6).toAXI4Lite io.dma <> dma.io.extra.get.dma io.meip := meipGen.io.extra.get.meip uart.io.extra.get <> io.uart diff --git a/src/main/scala/system/Coherence.scala b/src/main/scala/system/Coherence.scala index 2199d8a31..d1279c01c 100644 --- a/src/main/scala/system/Coherence.scala +++ b/src/main/scala/system/Coherence.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package system @@ -73,27 +73,27 @@ class CoherenceManager extends Module with HasCoherenceParameter { switch (state) { is (s_idle) { - when (thisReq.fire()) { + when (thisReq.fire) { when (thisReq.bits.isRead()) { state := Mux(supportCoh.B, s_probeResp, s_memReadResp) } .elsewhen (thisReq.bits.isWriteLast()) { state := s_memWriteResp } } } is (s_probeResp) { - when (io.out.coh.resp.fire()) { - state := Mux(io.out.coh.resp.bits.isProbeHit(), s_probeForward, s_memReadReq) + when (io.out.coh.resp.fire) { + state := Mux(io.out.coh.resp.bits.isProbeHit, s_probeForward, s_memReadReq) } } is (s_probeForward) { val thisResp = io.in.resp thisResp <> io.out.coh.resp - when (thisResp.fire() && thisResp.bits.isReadLast()) { state := s_idle } + when (thisResp.fire && thisResp.bits.isReadLast) { state := s_idle } } is (s_memReadReq) { io.out.mem.req.bits := reqLatch io.out.mem.req.valid := true.B - when (io.out.mem.req.fire()) { state := s_memReadResp } + when (io.out.mem.req.fire) { state := s_memReadResp } } - is (s_memReadResp) { when (io.out.mem.resp.fire() && io.out.mem.resp.bits.isReadLast()) { state := s_idle } } - is (s_memWriteResp) { when (io.out.mem.resp.fire()) { state := s_idle } } + is (s_memReadResp) { when (io.out.mem.resp.fire && io.out.mem.resp.bits.isReadLast) { state := s_idle } } + is (s_memWriteResp) { when (io.out.mem.resp.fire) { state := s_idle } } } } diff --git a/src/main/scala/system/NutShell.scala b/src/main/scala/system/NutShell.scala index 4afa16e32..eb49ea5a3 100644 --- a/src/main/scala/system/NutShell.scala +++ b/src/main/scala/system/NutShell.scala @@ -62,7 +62,7 @@ class NutShell(implicit val p: NutCoreConfig) extends Module with HasSoCParamete axi2sb.io.in <> io.frontend nutcore.io.frontend <> axi2sb.io.out - val memport = xbar.io.out.toMemPort() + val memport = xbar.io.out.toMemPort memport.resp.bits.data := DontCare memport.resp.valid := DontCare memport.req.ready := DontCare @@ -111,14 +111,14 @@ class NutShell(implicit val p: NutCoreConfig) extends Module with HasSoCParamete else { io.mmio <> extDev } val clint = Module(new AXI4CLINT(sim = !p.FPGAPlatform)) - clint.io.in <> mmioXbar.io.out(0).toAXI4Lite() + clint.io.in <> mmioXbar.io.out(0).toAXI4Lite val mtipSync = clint.io.extra.get.mtip val msipSync = clint.io.extra.get.msip BoringUtils.addSource(mtipSync, "mtip") BoringUtils.addSource(msipSync, "msip") val plic = Module(new AXI4PLIC(nrIntr = Settings.getInt("NrExtIntr"), nrHart = 1)) - plic.io.in <> mmioXbar.io.out(1).toAXI4Lite() + plic.io.in <> mmioXbar.io.out(1).toAXI4Lite plic.io.extra.get.intrVec := RegNext(RegNext(io.meip)) val meipSync = plic.io.extra.get.meip(0) BoringUtils.addSource(meipSync, "meip") @@ -126,7 +126,7 @@ class NutShell(implicit val p: NutCoreConfig) extends Module with HasSoCParamete // ILA if (p.FPGAPlatform) { - def BoringUtilsConnect(sink: UInt, id: String) { + def BoringUtilsConnect(sink: UInt, id: String) = { val temp = WireInit(0.U(64.W)) BoringUtils.addSink(temp, id) sink := temp diff --git a/src/main/scala/system/Prefetcher.scala b/src/main/scala/system/Prefetcher.scala index a66b1f6a0..03a0e4d16 100644 --- a/src/main/scala/system/Prefetcher.scala +++ b/src/main/scala/system/Prefetcher.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package system @@ -40,9 +40,9 @@ class Prefetcher extends Module with HasPrefetcherParameter { prefetchReq.addr := io.in.bits.addr + XLEN.U //lastReqAddr not be initted, in vivado simulation maybe fail - //val lastReqAddr = (RegEnable(io.in.bits.addr, io.in.fire())) + //val lastReqAddr = (RegEnable(io.in.bits.addr, io.in.fire)) val lastReqAddr = RegInit(0.U(AddrBits.W)) - when (io.in.fire()) { + when (io.in.fire) { lastReqAddr := io.in.bits.addr } val thisReqAddr = io.in.bits.addr @@ -52,15 +52,15 @@ class Prefetcher extends Module with HasPrefetcherParameter { when (!getNewReq) { io.out.bits <> io.in.bits io.out.valid := io.in.valid - io.in.ready := !io.in.valid || io.out.fire() - getNewReq := io.in.fire() && io.in.bits.isBurst() && neqAddr + io.in.ready := !io.in.valid || io.out.fire + getNewReq := io.in.fire && io.in.bits.isBurst() && neqAddr }.otherwise { io.out.bits <> prefetchReq io.out.valid := !AddressSpace.isMMIO(prefetchReq.addr) io.in.ready := false.B - getNewReq := !(io.out.fire() || AddressSpace.isMMIO(prefetchReq.addr)) + getNewReq := !(io.out.fire || AddressSpace.isMMIO(prefetchReq.addr)) } - + Debug() { printf("%d: [Prefetcher]: in(%d,%d), out(%d,%d), in.bits.addr = %x\n", GTimer(), io.in.valid, io.in.ready, io.out.valid, io.out.ready, io.in.bits.addr) diff --git a/src/main/scala/utils/FlushableQueue.scala b/src/main/scala/utils/FlushableQueue.scala index b36e0f2db..1e1380fe1 100644 --- a/src/main/scala/utils/FlushableQueue.scala +++ b/src/main/scala/utils/FlushableQueue.scala @@ -28,8 +28,8 @@ class FlushableQueue[T <: Data](gen: T, val entries: Int, private val ptr_match = enq_ptr.value === deq_ptr.value private val empty = ptr_match && !maybe_full private val full = ptr_match && maybe_full - private val do_enq = WireInit(io.enq.fire()) - private val do_deq = WireInit(io.deq.fire()) + private val do_enq = WireInit(io.enq.fire) + private val do_deq = WireInit(io.deq.fire) when (do_enq) { ram(enq_ptr.value) := io.enq.bits @@ -96,7 +96,7 @@ object FlushableQueue { q.io.enq.bits := enq.bits q.io.flush := flush enq.ready := q.io.enq.ready - TransitName(q.io.deq, q) + q.io.deq } } } diff --git a/src/main/scala/utils/PipelineVector.scala b/src/main/scala/utils/PipelineVector.scala index 5cf791c72..044f0a2b8 100644 --- a/src/main/scala/utils/PipelineVector.scala +++ b/src/main/scala/utils/PipelineVector.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package nutcore @@ -31,16 +31,16 @@ object PipelineVector2Connect { val ringBufferTail = RegInit(0.U(log2Up(bufferSize).W)) val ringBufferEmpty = ringBufferHead === ringBufferTail val ringBufferAllowin = (0 to 1).map(i => (ringBufferHead + (i+1).U) =/= ringBufferTail).foldRight(true.B)((sum,i)=>sum&i) - + //enqueue val needEnqueue = Wire(Vec(2, Bool())) needEnqueue(0) := in1.valid needEnqueue(1) := in2.valid - val enqueueSize = needEnqueue(0).asUInt()+&needEnqueue(1).asUInt() // count(true) in needEnqueue + val enqueueSize = needEnqueue(0).asUInt+&needEnqueue(1).asUInt // count(true) in needEnqueue val enqueueFire = (0 to 1).map(i => enqueueSize >= (i+1).U) - val wen = in1.fire() || in2.fire() // i.e. ringBufferAllowin && in.valid + val wen = in1.fire || in2.fire // i.e. ringBufferAllowin && in.valid when(wen){ when(enqueueFire(0)){dataBuffer(0.U + ringBufferHead) := Mux(needEnqueue(0), in1.bits, in2.bits)} when(enqueueFire(1)){dataBuffer(1.U + ringBufferHead) := in2.bits} @@ -61,7 +61,7 @@ object PipelineVector2Connect { out2.valid := ringBufferHead =/= deq2_StartIndex && out1.valid //dequeue control - val dequeueSize = out1.fire().asUInt() +& out2.fire().asUInt + val dequeueSize = out1.fire.asUInt +& out2.fire.asUInt val dequeueFire = dequeueSize > 0.U when(dequeueFire){ ringBufferTail := ringBufferTail + dequeueSize; @@ -74,7 +74,7 @@ object PipelineVector2Connect { } Debug(){ - printf("[DPQ] size %x head %x tail %x enq %x deq %x\n", (bufferSize.asUInt() +& ringBufferHead.asUInt() - ringBufferTail.asUInt()) % bufferSize.asUInt(), ringBufferHead, ringBufferTail ,enqueueSize, dequeueSize) + printf("[DPQ] size %x head %x tail %x enq %x deq %x\n", (bufferSize.asUInt +& ringBufferHead.asUInt - ringBufferTail.asUInt) % bufferSize.asUInt, ringBufferHead, ringBufferTail ,enqueueSize, dequeueSize) } } diff --git a/src/main/scala/utils/SRAMTemplate.scala b/src/main/scala/utils/SRAMTemplate.scala index bcd91a75f..a2a2b899d 100644 --- a/src/main/scala/utils/SRAMTemplate.scala +++ b/src/main/scala/utils/SRAMTemplate.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package utils @@ -127,6 +127,6 @@ class SRAMTemplateWithArbiter[T <: Data](nRead: Int, gen: T, set: Int, way: Int // latch read results io.r.map{ case r => { - r.resp.data := HoldUnless(ram.io.r.resp.data, RegNext(r.req.fire())) + r.resp.data := HoldUnless(ram.io.r.resp.data, RegNext(r.req.fire)) }} } diff --git a/src/test/scala/cache/CacheTest.scala b/src/test/scala/cache/CacheTest.scala index 3c7213c85..ec1ca8b4d 100644 --- a/src/test/scala/cache/CacheTest.scala +++ b/src/test/scala/cache/CacheTest.scala @@ -1,17 +1,17 @@ /************************************************************************************** * Copyright (c) 2020 Institute of Computing Technology, CAS * Copyright (c) 2020 University of Chinese Academy of Sciences -* +* * NutShell is licensed under Mulan PSL v2. -* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: -* http://license.coscl.org.cn/MulanPSL2 -* -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -* FIT FOR A PARTICULAR PURPOSE. +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR +* FIT FOR A PARTICULAR PURPOSE. * -* See the Mulan PSL v2 for more details. +* See the Mulan PSL v2 for more details. ***************************************************************************************/ package top @@ -64,10 +64,10 @@ class NutCoreSimTop extends Module { val initCnt = Counter(NRmemBlock) switch (state) { is (s_init_req) { - when (in.req.fire()) { state := s_init_resp } + when (in.req.fire) { state := s_init_resp } } is (s_init_resp) { - when (in.resp.fire()) { + when (in.resp.fire) { val wrap = initCnt.inc() state := Mux(wrap, s_test, s_init_req) when (wrap) { @@ -107,23 +107,23 @@ class NutCoreSimTop extends Module { in.resp.ready := rand.readyChoose =/= 0.U val cohInflight = RegInit(false.B) - when (cohIn.resp.fire()) { + when (cohIn.resp.fire) { val resp = cohIn.resp.bits val isProbeEnd = resp.isProbeMiss() || (resp.cmd === SimpleBusCmd.readLast) when (isProbeEnd) { cohInflight := false.B } } - when (cohIn.req.fire()) { cohInflight := true.B } + when (cohIn.req.fire) { cohInflight := true.B } cohIn.req.bits.apply(addr = rand.cohAddr * 8.U + memBase.U, size = "b11".U, wdata = 0.U, wmask = 0.U, cmd = SimpleBusCmd.probe) cohIn.req.valid := (state === s_test) && rand.cohChoose === 0.U && !cohInflight cohIn.resp.ready := rand.cohReadyChoose =/= 0.U - when (Counter((state === s_test) && in.resp.fire(), printCnt)._2) { printf(".") } - when (Counter((state === s_test) && cohIn.req.fire(), printCnt)._2) { printf("@") } + when (Counter((state === s_test) && in.resp.fire, printCnt)._2) { printf(".") } + when (Counter((state === s_test) && cohIn.req.fire, printCnt)._2) { printf("@") } Debug(false) { - when (in.req.fire()) { printf(p"${GTimer()},[in.req] ${in.req.bits}\n") } + when (in.req.fire) { printf(p"${GTimer()},[in.req] ${in.req.bits}\n") } } def checkData(addr: UInt, data: UInt): Bool = data === Fill(2, addr) @@ -150,7 +150,7 @@ class NutCoreSimTop extends Module { } // check rdata from cohIn - val cohAddr = RegEnable(cohIn.req.bits.addr(31,0), cohIn.req.fire()) + val cohAddr = RegEnable(cohIn.req.bits.addr(31,0), cohIn.req.fire) when (cohIn.resp.valid) { val resp = cohIn.resp.bits val isRead = resp.cmd === SimpleBusCmd.readLast || resp.cmd === SimpleBusCmd.read