未验证 提交 1c0c19cd 编写于 作者: L ljw 提交者: GitHub

Merge branch 'master' into hardfloat

......@@ -17,14 +17,14 @@ import xiangshan.mem.LsqEnqIO
class CtrlToIntBlockIO extends XSBundle {
val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
val enqIqData = Vec(exuParameters.IntExuCnt, Output(new ExuInput))
val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort))
val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN)))
val redirect = ValidIO(new Redirect)
}
class CtrlToFpBlockIO extends XSBundle {
val enqIqCtrl = Vec(exuParameters.FpExuCnt, DecoupledIO(new MicroOp))
val enqIqData = Vec(exuParameters.FpExuCnt, Output(new ExuInput))
val readRf = Vec(NRFpReadPorts, Flipped(new RfReadPort))
val readRf = Vec(NRFpReadPorts, Flipped(new RfReadPort(XLEN + 1)))
val redirect = ValidIO(new Redirect)
}
......@@ -80,13 +80,11 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
io.frontend.cfiUpdateInfo <> brq.io.cfiInfo
decode.io.in <> io.frontend.cfVec
decode.io.toBrq <> brq.io.enqReqs
decode.io.brTags <> brq.io.brTags
decode.io.enqBrq <> brq.io.enq
brq.io.redirect.valid <> redirectValid
brq.io.redirect.bits <> redirect
brq.io.bcommit <> roq.io.bcommit
brq.io.enqReqs <> decode.io.toBrq
brq.io.exuRedirectWb <> io.fromIntBlock.exuRedirect
// pipeline between decode and dispatch
......
......@@ -38,14 +38,18 @@ object BrqPtr extends HasXSParameter {
}
}
class BrqEnqIO extends XSBundle {
val needAlloc = Vec(RenameWidth, Input(Bool()))
val req = Vec(RenameWidth, Flipped(DecoupledIO(new CtrlFlow)))
val resp = Vec(RenameWidth, Output(new BrqPtr))
}
class BrqIO extends XSBundle{
val redirect = Input(ValidIO(new Redirect))
// receive branch/jump calculated target
val exuRedirectWb = Vec(exuParameters.AluCnt + exuParameters.JmpCnt, Flipped(ValidIO(new ExuOutput)))
// from decode, branch insts enq
val enqReqs = Vec(DecodeWidth, Flipped(DecoupledIO(new CfCtrl)))
// to decode
val brTags = Output(Vec(DecodeWidth, new BrqPtr))
val enq = new BrqEnqIO
// to roq
val out = ValidIO(new ExuOutput)
// misprediction, flush pipeline
......@@ -118,22 +122,22 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val lastCycleRedirect = RegNext(io.redirect.valid)
val validEntries = distanceBetween(tailPtr, headPtr)
for(i <- 0 until DecodeWidth){
val offset = if(i == 0) 0.U else PopCount(io.enqReqs.take(i).map(_.valid))
val offset = if (i == 0) 0.U else PopCount(io.enq.needAlloc.take(i))
val brTag = tailPtr + offset
val idx = brTag.value
io.enqReqs(i).ready := validEntries <= (BrqSize - (i + 1)).U && !lastCycleRedirect
io.brTags(i) := brTag
when (io.enqReqs(i).fire()) {
io.enq.req(i).ready := validEntries <= (BrqSize - (i + 1)).U && !lastCycleRedirect
io.enq.resp(i) := brTag
when (io.enq.req(i).fire()) {
brQueue(idx).ptrFlag := brTag.flag
brQueue(idx).exuOut.brUpdate.pc := io.enqReqs(i).bits.cf.pc
brQueue(idx).exuOut.brUpdate.pnpc := io.enqReqs(i).bits.cf.brUpdate.pnpc
brQueue(idx).exuOut.brUpdate.fetchIdx := io.enqReqs(i).bits.cf.brUpdate.fetchIdx
brQueue(idx).exuOut.brUpdate.pd := io.enqReqs(i).bits.cf.brUpdate.pd
brQueue(idx).exuOut.brUpdate.bpuMeta := io.enqReqs(i).bits.cf.brUpdate.bpuMeta
brQueue(idx).exuOut.brUpdate.pc := io.enq.req(i).bits.pc
brQueue(idx).exuOut.brUpdate.pnpc := io.enq.req(i).bits.brUpdate.pnpc
brQueue(idx).exuOut.brUpdate.fetchIdx := io.enq.req(i).bits.brUpdate.fetchIdx
brQueue(idx).exuOut.brUpdate.pd := io.enq.req(i).bits.brUpdate.pd
brQueue(idx).exuOut.brUpdate.bpuMeta := io.enq.req(i).bits.brUpdate.bpuMeta
stateQueue(idx) := s_idle
}
}
val enqCnt = PopCount(io.enqReqs.map(_.fire()))
val enqCnt = PopCount(io.enq.req.map(_.fire()))
tailPtr := tailPtr + enqCnt
/**
......@@ -194,8 +198,8 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
for(i <- 0 until DecodeWidth){
XSDebug(
debug_normal_mode,
p"enq v:${io.enqReqs(i).valid} rdy:${io.enqReqs(i).ready} pc:${Hexadecimal(io.enqReqs(i).bits.cf.pc)}" +
p" brTag:${io.brTags(i)}\n"
p"enq v:${io.enq.req(i).valid} rdy:${io.enq.req(i).ready} pc:${Hexadecimal(io.enq.req(i).bits.pc)}" +
p" brTag:${io.enq.resp(i)}\n"
)
}
......
......@@ -3,15 +3,13 @@ package xiangshan.backend.decode
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.backend.brq.BrqPtr
import xiangshan.backend.brq.BrqEnqIO
import utils._
class DecodeStage extends XSModule {
val io = IO(new Bundle() {
// enq Brq
val toBrq = Vec(DecodeWidth, DecoupledIO(new CfCtrl))
// get brMask/brTag
val brTags = Input(Vec(DecodeWidth, new BrqPtr))
val enqBrq = Flipped(new BrqEnqIO)
// from Ibuffer
val in = Vec(DecodeWidth, Flipped(DecoupledIO(new CtrlFlow)))
......@@ -19,9 +17,8 @@ class DecodeStage extends XSModule {
// to DecBuffer
val out = Vec(DecodeWidth, DecoupledIO(new CfCtrl))
})
val decoders = Seq.fill(DecodeWidth)(Module(new DecodeUnit))
val decoderToBrq = Wire(Vec(DecodeWidth, new CfCtrl)) // without brTag and brMask
val decoderToDecBuffer = Wire(Vec(DecodeWidth, new CfCtrl)) // with brTag and brMask
// Handshake ---------------------
// 1. if current instruction is valid, then:
......@@ -33,21 +30,23 @@ class DecodeStage extends XSModule {
for (i <- 0 until DecodeWidth) {
decoders(i).io.enq.ctrl_flow <> io.in(i).bits
decoderToBrq(i) := decoders(i).io.deq.cf_ctrl // CfCtrl without bfTag and brMask
decoderToBrq(i).brTag := DontCare
io.toBrq(i).bits := decoderToBrq(i)
decoderToDecBuffer(i) := decoders(i).io.deq.cf_ctrl
decoderToDecBuffer(i).brTag := io.brTags(i)
io.out(i).bits := decoderToDecBuffer(i)
val isMret = decoders(i).io.deq.cf_ctrl.cf.instr === BitPat("b001100000010_00000_000_00000_1110011")
val isSret = decoders(i).io.deq.cf_ctrl.cf.instr === BitPat("b000100000010_00000_000_00000_1110011")
val thisBrqValid = !decoders(i).io.deq.cf_ctrl.cf.brUpdate.pd.notCFI || isMret || isSret
io.in(i).ready := io.out(i).ready && io.toBrq(i).ready
io.out(i).valid := io.in(i).valid && io.toBrq(i).ready
io.toBrq(i).valid := io.in(i).valid && thisBrqValid && io.out(i).ready
XSDebug(io.in(i).valid || io.out(i).valid || io.toBrq(i).valid, "i:%d In(%d %d) Out(%d %d) ToBrq(%d %d) pc:%x instr:%x\n", i.U, io.in(i).valid, io.in(i).ready, io.out(i).valid, io.out(i).ready, io.toBrq(i).valid, io.toBrq(i).ready, io.in(i).bits.pc, io.in(i).bits.instr)
val isMret = io.in(i).bits.instr === BitPat("b001100000010_00000_000_00000_1110011")
val isSret = io.in(i).bits.instr === BitPat("b000100000010_00000_000_00000_1110011")
val thisBrqValid = !io.in(i).bits.brUpdate.pd.notCFI || isMret || isSret
io.enqBrq.needAlloc(i) := thisBrqValid
io.enqBrq.req(i).valid := io.in(i).valid && thisBrqValid && io.out(i).ready
io.enqBrq.req(i).bits := io.in(i).bits
io.out(i).valid := io.in(i).valid && io.enqBrq.req(i).ready
io.out(i).bits := decoders(i).io.deq.cf_ctrl
io.out(i).bits.brTag := io.enqBrq.resp(i)
io.in(i).ready := io.out(i).ready && io.enqBrq.req(i).ready
XSDebug(io.in(i).valid || io.out(i).valid || io.enqBrq.req(i).valid,
"i:%d In(%d %d) Out(%d %d) ToBrq(%d %d) pc:%x instr:%x\n",
i.U, io.in(i).valid, io.in(i).ready, io.out(i).valid, io.out(i).ready,
io.enqBrq.req(i).valid, io.enqBrq.req(i).ready, io.in(i).bits.pc, io.in(i).bits.instr)
}
}
......@@ -34,8 +34,8 @@ class Dispatch extends XSModule {
// enq Lsq
val enqLsq = Flipped(new LsqEnqIO)
// read regfile
val readIntRf = Vec(NRIntReadPorts, Flipped(new RfReadPort))
val readFpRf = Vec(NRFpReadPorts, Flipped(new RfReadPort))
val readIntRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN)))
val readFpRf = Vec(NRFpReadPorts, Flipped(new RfReadPort(XLEN + 1)))
// read reg status (busy/ready)
val intPregRdy = Vec(NRIntReadPorts, Input(Bool()))
val fpPregRdy = Vec(NRFpReadPorts, Input(Bool()))
......
......@@ -10,7 +10,7 @@ import xiangshan.backend.exu.Exu._
class Dispatch2Fp extends XSModule {
val io = IO(new Bundle() {
val fromDq = Flipped(Vec(dpParams.FpDqDeqWidth, DecoupledIO(new MicroOp)))
val readRf = Vec(NRFpReadPorts - exuParameters.StuCnt, Flipped(new RfReadPort))
val readRf = Vec(NRFpReadPorts - exuParameters.StuCnt, Flipped(new RfReadPort(XLEN + 1)))
val regRdy = Vec(NRFpReadPorts - exuParameters.StuCnt, Input(Bool()))
val numExist = Input(Vec(exuParameters.FpExuCnt, UInt(log2Ceil(IssQueSize).W)))
val enqIQCtrl = Vec(exuParameters.FpExuCnt, DecoupledIO(new MicroOp))
......
......@@ -11,7 +11,7 @@ import xiangshan.backend.exu._
class Dispatch2Int extends XSModule {
val io = IO(new Bundle() {
val fromDq = Flipped(Vec(dpParams.IntDqDeqWidth, DecoupledIO(new MicroOp)))
val readRf = Vec(NRIntReadPorts - NRMemReadPorts, Flipped(new RfReadPort))
val readRf = Vec(NRIntReadPorts - NRMemReadPorts, Flipped(new RfReadPort(XLEN)))
val regRdy = Vec(NRIntReadPorts - NRMemReadPorts, Input(Bool()))
val numExist = Input(Vec(exuParameters.IntExuCnt, UInt(log2Ceil(IssQueSize).W)))
val enqIQCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
......
......@@ -10,8 +10,8 @@ import xiangshan.backend.exu.Exu._
class Dispatch2Ls extends XSModule {
val io = IO(new Bundle() {
val fromDq = Flipped(Vec(dpParams.LsDqDeqWidth, DecoupledIO(new MicroOp)))
val readIntRf = Vec(NRMemReadPorts, Flipped(new RfReadPort))
val readFpRf = Vec(exuParameters.StuCnt, Flipped(new RfReadPort))
val readIntRf = Vec(NRMemReadPorts, Flipped(new RfReadPort(XLEN)))
val readFpRf = Vec(exuParameters.StuCnt, Flipped(new RfReadPort(XLEN + 1)))
// val intRegAddr = Vec(NRMemReadPorts, Output(UInt(PhyRegIdxWidth.W)))
// val fpRegAddr = Vec(exuParameters.StuCnt, Output(UInt(PhyRegIdxWidth.W)))
val intRegRdy = Vec(NRMemReadPorts, Input(Bool()))
......
......@@ -4,15 +4,19 @@ import chisel3._
import chisel3.util._
import xiangshan._
class RfReadPort extends XSBundle {
class RfReadPort(len: Int) extends XSBundle {
val addr = Input(UInt(PhyRegIdxWidth.W))
val data = Output(UInt((XLEN + 1).W))
val data = Output(UInt(len.W))
override def cloneType: RfReadPort.this.type =
new RfReadPort(len).asInstanceOf[this.type]
}
class RfWritePort extends XSBundle {
class RfWritePort(len: Int) extends XSBundle {
val wen = Input(Bool())
val addr = Input(UInt(PhyRegIdxWidth.W))
val data = Input(UInt((XLEN + 1).W))
val data = Input(UInt(len.W))
override def cloneType: RfWritePort.this.type =
new RfWritePort(len).asInstanceOf[this.type]
}
class Regfile
......@@ -23,28 +27,25 @@ class Regfile
len: Int
) extends XSModule {
val io = IO(new Bundle() {
val readPorts = Vec(numReadPorts, new RfReadPort)
val writePorts = Vec(numWirtePorts, new RfWritePort)
val readPorts = Vec(numReadPorts, new RfReadPort(len))
val writePorts = Vec(numWirtePorts, new RfWritePort(len))
})
if (!env.FPGAPlatform) {
val useBlackBox = false
if (!useBlackBox) {
val mem = Mem(NRPhyRegs, UInt(len.W))
for(r <- io.readPorts){
val addr_reg = RegNext(r.addr)
r.data := {if(hasZero) Mux(addr_reg===0.U, 0.U, mem(addr_reg)) else mem(addr_reg)}
for (r <- io.readPorts) {
val raddr_reg = RegNext(r.addr)
val rdata = if (hasZero) Mux(raddr_reg === 0.U, 0.U, mem(raddr_reg)) else mem(raddr_reg)
r.data := rdata
}
for(w <- io.writePorts){
when(w.wen){
for (w <- io.writePorts) {
when(w.wen) {
mem(w.addr) := w.data
}
}
if (!env.FPGAPlatform) {
val debugArchRat = WireInit(VecInit(Seq.fill(32)(0.U(PhyRegIdxWidth.W))))
ExcitingUtils.addSink(
debugArchRat,
......@@ -53,15 +54,14 @@ class Regfile
)
val debugArchReg = WireInit(VecInit(debugArchRat.zipWithIndex.map(
x => if(hasZero){
if(x._2 == 0) 0.U else mem(x._1)
} else ieee(mem(x._1))
x => if(hasZero && x._2==0) 0.U else mem(x._1)
)))
ExcitingUtils.addSource(
debugArchReg,
if(hasZero) "DEBUG_INT_ARCH_REG" else "DEBUG_FP_ARCH_REG",
ExcitingUtils.Debug
)
}
} else {
val regfile = Module(new regfile_160x64_10w16r_sim)
......
......@@ -56,18 +56,23 @@ class SbufferLine extends SbufferBundle {
class ChooseReplace(nWay: Int) extends XSModule {
val io = IO(new Bundle{
// val in = Vec(StorePipelineWidth, Input(UInt(nWay.W)))
val mask = Vec(StoreBufferSize, Input(Bool()))
val mask = Vec(nWay, Input(Bool()))
val fire = Input(Bool())
val way = Output(UInt(nWay.W))
val flush = Input(Bool())
})
val wayReg = RegInit(0.U(log2Up(nWay).W))
val nextWay = (wayReg + 1.U)(log2Up(nWay)-1, 0)
val wayMask = ~((UIntToOH(wayReg)<<1.U)(nWay-1,0) - 1.U)
val stateMask = Cat(io.mask.reverse)
val loMask = (wayMask & stateMask)(nWay-1,0)
val nextWay = PriorityEncoder(Cat(stateMask, loMask))(log2Up(nWay)-1, 0)
XSDebug(p"ss[${Binary(Cat(stateMask, loMask))}] , nextWay[${nextWay}] \n")
io.way := wayReg
when(io.fire){
wayReg := Mux(io.mask(nextWay), nextWay, 0.U)
wayReg := nextWay
}
when(io.flush){
......@@ -373,10 +378,12 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val tagConflict = tagRead(evictionIdx) === tags(0) || tagRead(evictionIdx) === tags(1)
io.dcache.req.valid :=
((do_eviction && sbuffer_state === x_replace) || (sbuffer_state === x_drain_sbuffer)) &&
((do_eviction && sbuffer_state === x_replace) && !tagConflict || (sbuffer_state === x_drain_sbuffer)) &&
stateVec(evictionIdx)===s_valid &&
noSameBlockInflight(evictionIdx) &&
!tagConflict
noSameBlockInflight(evictionIdx)
XSDebug(p"1[${((do_eviction && sbuffer_state === x_replace) || (sbuffer_state === x_drain_sbuffer))}] 2[${stateVec(evictionIdx)===s_valid}] 3[${noSameBlockInflight(evictionIdx)}] 4[${!tagConflict}]\n")
io.dcache.req.bits.addr := getAddr(tagRead(evictionIdx))
io.dcache.req.bits.data := bufferRead(evictionIdx).data
......@@ -397,7 +404,6 @@ class NewSbuffer extends XSModule with HasSbufferCst {
io.dcache.resp.ready := true.B // sbuffer always ready to recv dcache resp
val respId = io.dcache.resp.bits.meta.id
when(io.dcache.resp.fire()){
XSDebug("")
stateVec(respId) := s_invalid
assert(stateVec(respId) === s_inflight)
XSDebug(p"recv cache resp: id=[$respId]\n")
......
package xiangshan.backend.brq
import org.scalatest._
import chiseltest._
import chisel3._
import chisel3.experimental.BundleLiterals._
import chisel3.util._
import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.VerilatorBackendAnnotation
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.must.Matchers
import top.Parameters
import utils.XSLog
import xiangshan._
import xiangshan.testutils._
import xiangshan.testutils.TestCaseGenerator._
import scala.util.Random
class BrqTest extends AnyFlatSpec
with ChiselScalatestTester
with Matchers
with ParallelTestExecution
with HasPartialDecoupledDriver {
it should "redirect out-of-order, dequeue in-order" in {
Parameters.set(Parameters.debugParameters)
test(new Brq {
AddSinks()
}).withAnnotations(Seq()) { c =>
def genEnqReq(x: => DecoupledIO[CfCtrl], pc: Long) = {
chiselTypeOf(x.bits).Lit(
_.cf.pc -> pc.U,
_.cf.brUpdate.pnpc -> (pc+4).U
)
}
def genExuWb(exuRedirect: => Valid[ExuOutput], tagIdx: Int, tagFlag: Boolean, target: Long) = {
chiselTypeOf(exuRedirect.bits).Lit(
_.redirect.brTag.value -> tagIdx.U,
_.redirect.brTag.flag -> tagFlag.B,
_.redirect.target -> target.U
)
}
c.io.enqReqs.head.initSource().setSourceClock(c.clock)
var brqPtrSeq = Seq[(BigInt, Boolean)]()
for (i <- 0 until 10) {
val enqPort = c.io.enqReqs.head
enqPort.enqueuePartial(genEnqReq(enqPort, i * 0x1000))
}
var enqTags = List.tabulate(10)(i => i)
val misPred = 6
println(s"enqTags:$enqTags misPredTag:$misPred")
enqTags = enqTags.take(misPred + 1)
var commitTags, deqTags = List[Int]()
def checkCommit = {
if (c.io.out.valid.peek().litToBoolean) {
commitTags = commitTags :+ c.io.redirect.bits.brTag.value.peek().litValue().toInt
println(s"====commited tags:$commitTags====")
}
}
def checkDeq = {
if(c.io.out.valid.peek().litToBoolean){
deqTags = deqTags :+ c.io.out.bits.uop.brTag.value.peek().litValue().toInt
println(s"====deq tags:$deqTags====")
}
}
println("====Start random write back====")
val wbPort = c.io.exuRedirectWb.head
//-----------------write back-----------------//
while (enqTags.nonEmpty) {
val idx = Random.nextInt(enqTags.size)
val tag = enqTags(idx)
println(s"====write tag:$tag back to Brq====")
enqTags = enqTags.filter(x => x != tag)
wbPort.valid.poke(true.B)
wbPort.bits.pokePartial(
genExuWb(wbPort, tag, tagFlag = false, if (tag == misPred) 0xffff else tag * 0x1000 + 4)
)
checkCommit
c.clock.step(1)
wbPort.valid.poke(false.B)
for (i <- 0 until Random.nextInt(3)) {
checkCommit
c.clock.step(1)
}
}
c.io.bcommit.poke((misPred+1).U)
c.clock.step(1)
c.io.bcommit.poke(0.U)
while (deqTags.size != misPred+1) {
checkCommit
checkDeq
c.clock.step(1)
}
c.clock.step(10)
val left = commitTags.takeWhile(x => x!=misPred)
val right = commitTags.dropWhile(x => x!=misPred).drop(1)
println(s"commited before mispred: $left")
println(s"commited after mispred: $right")
def isValidCommitSeq(in: Seq[Int]): Boolean = {
for(i <- 1 until in.size){
if(in(i) == in(i-1)) return false
}
true
}
assert(isValidCommitSeq(left) && isValidCommitSeq(right))
println(s"deq tags: $deqTags")
def isValidDeqSeq(in: Seq[Int]): Boolean = {
in.zipWithIndex.map(x => x._1==x._2).reduce(_&&_)
}
assert(isValidDeqSeq(deqTags))
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册