提交 4d5b6064 编写于 作者: Fa_wang's avatar Fa_wang

Merge remote-tracking branch 'origin/master' into trace-debug

...@@ -3,20 +3,34 @@ name: EMU Test ...@@ -3,20 +3,34 @@ name: EMU Test
on: on:
push: push:
branches: [ master, update-ci] branches: [ master ]
pull_request: pull_request:
branches: [ master ] branches: [ master ]
jobs: jobs:
build-emu: generate-verilog:
runs-on: self-hosted runs-on: self-hosted
name: Make EMU name: Generate Verilog
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
submodules: 'recursive' submodules: 'recursive'
- name: Check Wiring - name: Check Wiring
run: bash .github/workflows/check-usage.sh "BoringUtils" $GITHUB_WORKSPACE run: bash .github/workflows/check-usage.sh "BoringUtils" $GITHUB_WORKSPACE
- name: set env
run: |
echo "NEMU_HOME=/home/ci-runner/xsenv/NEMU" >> $GITHUB_ENV
echo "NOOP_HOME=$GITHUB_WORKSPACE" >> $GITHUB_ENV
- name: generate verilog file
run:
make verilog SIM_ARGS=--dual-core
build-emu:
runs-on: self-hosted
name: Make EMU
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Set env - name: Set env
run: | run: |
echo "NEMU_HOME=/home/ci-runner/xsenv/NEMU" >> $GITHUB_ENV echo "NEMU_HOME=/home/ci-runner/xsenv/NEMU" >> $GITHUB_ENV
...@@ -25,7 +39,7 @@ jobs: ...@@ -25,7 +39,7 @@ jobs:
echo "AM_HOME=/home/ci-runner/xsenv/nexus-am" >> $GITHUB_ENV echo "AM_HOME=/home/ci-runner/xsenv/nexus-am" >> $GITHUB_ENV
- name: Build EMU - name: Build EMU
run: run:
make ./build/emu SIM_ARGS=--disable-all NEMU_HOME=$NEMU_HOME NOOP_HOME=$NOOP_HOME -j60 make ./build/emu SIM_ARGS=--disable-all NEMU_HOME=$NEMU_HOME NOOP_HOME=$NOOP_HOME -j220
- name: Run cputest - name: Run cputest
run: | run: |
CPU_TEST_DIR=$AM_HOME/tests/cputest CPU_TEST_DIR=$AM_HOME/tests/cputest
......
Subproject commit 0315ccf27963d7fe4b5e850c709fb66298f8390c Subproject commit ab2a8e8afd162b601d9f749e6e6af452cccc03a7
...@@ -29,7 +29,7 @@ trait CommonModule extends ScalaModule { ...@@ -29,7 +29,7 @@ trait CommonModule extends ScalaModule {
} }
val chisel = Agg( val chisel = Agg(
ivy"edu.berkeley.cs::chisel3:3.4.0" ivy"edu.berkeley.cs::chisel3:3.4.1"
) )
object `api-config-chipsalliance` extends CommonModule { object `api-config-chipsalliance` extends CommonModule {
......
...@@ -5,15 +5,14 @@ import device.{AXI4Timer, TLTimer, AXI4Plic} ...@@ -5,15 +5,14 @@ import device.{AXI4Timer, TLTimer, AXI4Plic}
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp} import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
import freechips.rocketchip.tilelink.{TLBuffer, TLFuzzer, TLIdentityNode, TLXbar} import freechips.rocketchip.tilelink.{BankBinder, TLBuffer, TLBundleParameters, TLCacheCork, TLClientNode, TLFilter, TLFuzzer, TLIdentityNode, TLToAXI4, TLWidthWidget, TLXbar}
import utils.DebugIdentityNode import utils.DebugIdentityNode
import utils.XSInfo import utils.XSInfo
import xiangshan.{HasXSParameter, XSCore, HasXSLog} import xiangshan.{HasXSParameter, XSCore, HasXSLog}
import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressSet} import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
import freechips.rocketchip.tilelink.{TLBundleParameters, TLCacheCork, TLBuffer, TLClientNode, TLIdentityNode, TLXbar, TLWidthWidget, TLFilter, TLToAXI4} import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
import freechips.rocketchip.devices.tilelink.{TLError, DevNullParams} import freechips.rocketchip.amba.axi4.{AXI4Deinterleaver, AXI4Fragmenter, AXI4IdIndexer, AXI4IdentityNode, AXI4ToTL, AXI4UserYanker}
import freechips.rocketchip.amba.axi4.{AXI4ToTL, AXI4IdentityNode, AXI4UserYanker, AXI4Fragmenter, AXI4IdIndexer, AXI4Deinterleaver}
case class SoCParameters case class SoCParameters
( (
...@@ -44,51 +43,6 @@ class DummyCore()(implicit p: Parameters) extends LazyModule { ...@@ -44,51 +43,6 @@ class DummyCore()(implicit p: Parameters) extends LazyModule {
} }
class BankAddressConvertor(index: Int, bankBits: Int, blockBits: Int, recover: Boolean = false)(implicit p: Parameters) extends LazyModule {
val node = TLIdentityNode()
def shrink(addr: UInt): UInt = {
val msb = addr.getWidth - 1
Cat(0.U(bankBits.W), addr(msb, bankBits + blockBits), addr(blockBits - 1, 0))
}
def extend(addr: UInt): UInt = {
val msb = addr.getWidth - 1
Cat(addr(msb - bankBits, blockBits), index.U(bankBits.W), addr(blockBits - 1, 0))
}
lazy val module = new LazyModuleImp(this) with HasXSLog {
(node.in zip node.out) foreach { case ((in, _), (out, _)) =>
out <> in
if (!recover) {
out.a.bits.address := shrink(in.a.bits.address)
out.c.bits.address := shrink(in.c.bits.address)
in.b.bits.address := shrink(out.b.bits.address)
XSInfo(out.a.fire(), s"before bank $index A in addr %x -> out addr %x\n", in.a.bits.address, out.a.bits.address)
XSInfo(out.b.fire(), s"before bank $index B out addr %x -> in addr %x\n", out.b.bits.address, in.b.bits.address)
XSInfo(out.c.fire(), s"before bank $index C in addr %x -> out addr %x\n", in.c.bits.address, out.c.bits.address)
}
else {
out.a.bits.address := extend(in.a.bits.address)
out.c.bits.address := extend(in.c.bits.address)
in.b.bits.address := extend(out.b.bits.address)
XSInfo(out.a.fire(), s"after bank $index A in addr %x -> out addr %x\n", in.a.bits.address, out.a.bits.address)
XSInfo(out.b.fire(), s"after bank $index B out addr %x -> out addr %x\n", out.b.bits.address, in.b.bits.address)
XSInfo(out.c.fire(), s"after bank $index C in addr %x -> out addr %x\n", in.c.bits.address, out.c.bits.address)
}
}
}
}
object BankAddressConvertor {
def apply(index: Int, bankBits: Int, blockBits: Int, recover: Boolean)(implicit p: Parameters) = {
val bankAddressConvertor = LazyModule(new BankAddressConvertor(index, bankBits, blockBits, recover))
bankAddressConvertor.node
}
}
class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
// CPU Cores // CPU Cores
private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore())) private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore()))
...@@ -115,20 +69,19 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { ...@@ -115,20 +69,19 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
// ------------------------------------------------- // -------------------------------------------------
private val l3_xbar = TLXbar() private val l3_xbar = TLXbar()
private val l3_banks = (0 until L3NBanks) map (i => private val l3_node = LazyModule(new InclusiveCache(
LazyModule(new InclusiveCache(
CacheParameters( CacheParameters(
level = 3, level = 3,
ways = L3NWays, ways = L3NWays,
sets = L3NSets, sets = L3NSets,
blockBytes = L3BlockSize, blockBytes = L3BlockSize,
beatBytes = L2BusWidth / 8, beatBytes = L2BusWidth / 8,
cacheName = s"L3_$i" cacheName = "L3"
), ),
InclusiveCacheMicroParameters( InclusiveCacheMicroParameters(
writeBytes = 8 writeBytes = 8
) )
))) )).node
// L3 to memory network // L3 to memory network
// ------------------------------------------------- // -------------------------------------------------
...@@ -175,14 +128,8 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { ...@@ -175,14 +128,8 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
DebugIdentityNode() := DebugIdentityNode() :=
tlError_xbar tlError_xbar
def bankFilter(bank: Int) = AddressSet( val bankedNode =
base = bank * L3BlockSize, BankBinder(L3NBanks, L3BlockSize) :*= l3_node :*= TLBuffer() :*= DebugIdentityNode() :*= l3_xbar
mask = ~BigInt((L3NBanks - 1) * L3BlockSize))
for(i <- 0 until L3NBanks) {
val filter = TLFilter(TLFilter.mSelectIntersect(bankFilter(i)))
l3_banks(i).node := BankAddressConvertor(i, log2Ceil(L3NBanks), log2Ceil(L3BlockSize), recover = false) := TLBuffer() := DebugIdentityNode() := filter := l3_xbar
}
for(i <- 0 until L3NBanks) { for(i <- 0 until L3NBanks) {
mem(i) := mem(i) :=
...@@ -190,8 +137,7 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { ...@@ -190,8 +137,7 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
TLToAXI4() := TLToAXI4() :=
TLWidthWidget(L3BusWidth / 8) := TLWidthWidget(L3BusWidth / 8) :=
TLCacheCork() := TLCacheCork() :=
BankAddressConvertor(i, log2Ceil(L3NBanks), log2Ceil(L3BlockSize), recover = true) := bankedNode
l3_banks(i).node
} }
private val clint = LazyModule(new TLTimer( private val clint = LazyModule(new TLTimer(
......
...@@ -3,7 +3,7 @@ package utils ...@@ -3,7 +3,7 @@ package utils
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends Module { class DataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int, isSync: Boolean) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W))) val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(gen)) val rdata = Vec(numRead, Output(gen))
...@@ -15,8 +15,9 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, ...@@ -15,8 +15,9 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int,
val data = Mem(numEntries, gen) val data = Mem(numEntries, gen)
// read ports // read ports
val raddr = if (isSync) (RegNext(io.raddr)) else io.raddr
for (i <- 0 until numRead) { for (i <- 0 until numRead) {
io.rdata(i) := data(io.raddr(i)) io.rdata(i) := data(raddr(i))
} }
// below is the write ports (with priorities) // below is the write ports (with priorities)
...@@ -34,34 +35,5 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, ...@@ -34,34 +35,5 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int,
} }
} }
class SyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends Module { class SyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends DataModuleTemplate(gen, numEntries, numRead, numWrite, true)
val io = IO(new Bundle { class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends DataModuleTemplate(gen, numEntries, numRead, numWrite, false)
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(gen))
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(UInt(log2Up(numEntries).W)))
val wdata = Vec(numWrite, Input(gen))
})
val data = Mem(numEntries, gen)
// read ports
val raddr_reg = RegNext(io.raddr)
for (i <- 0 until numRead) {
io.rdata(i) := data(raddr_reg(i))
}
// below is the write ports (with priorities)
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for (i <- 0 until numWrite) {
for (j <- i+1 until numWrite) {
assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
}
}
}
...@@ -6,7 +6,7 @@ import xiangshan.backend.SelImm ...@@ -6,7 +6,7 @@ import xiangshan.backend.SelImm
import xiangshan.backend.brq.BrqPtr import xiangshan.backend.brq.BrqPtr
import xiangshan.backend.rename.FreeListPtr import xiangshan.backend.rename.FreeListPtr
import xiangshan.backend.roq.RoqPtr import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.decode.XDecode import xiangshan.backend.decode.{ImmUnion, XDecode}
import xiangshan.mem.{LqPtr, SqPtr} import xiangshan.mem.{LqPtr, SqPtr}
import xiangshan.frontend.PreDecodeInfo import xiangshan.frontend.PreDecodeInfo
import xiangshan.frontend.HasBPUParameter import xiangshan.frontend.HasBPUParameter
...@@ -14,6 +14,7 @@ import xiangshan.frontend.HasTageParameter ...@@ -14,6 +14,7 @@ import xiangshan.frontend.HasTageParameter
import xiangshan.frontend.HasIFUConst import xiangshan.frontend.HasIFUConst
import xiangshan.frontend.GlobalHistory import xiangshan.frontend.GlobalHistory
import utils._ import utils._
import scala.math.max import scala.math.max
import Chisel.experimental.chiselName import Chisel.experimental.chiselName
...@@ -219,7 +220,7 @@ class CtrlSignals extends XSBundle { ...@@ -219,7 +220,7 @@ class CtrlSignals extends XSBundle {
val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit
val isRVF = Bool() val isRVF = Bool()
val selImm = SelImm() val selImm = SelImm()
val imm = UInt(XLEN.W) val imm = UInt(ImmUnion.maxLen.W)
val commitType = CommitType() val commitType = CommitType()
val fpu = new FPUCtrlSignals val fpu = new FPUCtrlSignals
......
...@@ -5,18 +5,19 @@ import chisel3.util._ ...@@ -5,18 +5,19 @@ import chisel3.util._
import utils._ import utils._
import xiangshan._ import xiangshan._
import xiangshan.backend.decode.DecodeStage import xiangshan.backend.decode.DecodeStage
import xiangshan.backend.rename.{Rename, BusyTable} import xiangshan.backend.rename.{BusyTable, Rename}
import xiangshan.backend.brq.Brq import xiangshan.backend.brq.{Brq, BrqPcRead}
import xiangshan.backend.dispatch.Dispatch import xiangshan.backend.dispatch.Dispatch
import xiangshan.backend.exu._ import xiangshan.backend.exu._
import xiangshan.backend.exu.Exu.exuConfigs import xiangshan.backend.exu.Exu.exuConfigs
import xiangshan.backend.regfile.RfReadPort import xiangshan.backend.regfile.RfReadPort
import xiangshan.backend.roq.{Roq, RoqPtr, RoqCSRIO} import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqPtr}
import xiangshan.mem.LsqEnqIO import xiangshan.mem.LsqEnqIO
class CtrlToIntBlockIO extends XSBundle { class CtrlToIntBlockIO extends XSBundle {
val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp)) val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN))) val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN)))
val jumpPc = Output(UInt(VAddrBits.W))
// int block only uses port 0~7 // int block only uses port 0~7
val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) // TODO parameterize 8 here val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) // TODO parameterize 8 here
val redirect = ValidIO(new Redirect) val redirect = ValidIO(new Redirect)
...@@ -87,6 +88,8 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper { ...@@ -87,6 +88,8 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq.io.redirect.bits <> redirect brq.io.redirect.bits <> redirect
brq.io.bcommit <> roq.io.bcommit brq.io.bcommit <> roq.io.bcommit
brq.io.exuRedirectWb <> io.fromIntBlock.exuRedirect brq.io.exuRedirectWb <> io.fromIntBlock.exuRedirect
brq.io.pcReadReq.brqIdx := dispatch.io.enqIQCtrl(0).bits.brTag // jump
io.toIntBlock.jumpPc := brq.io.pcReadReq.pc
// pipeline between decode and dispatch // pipeline between decode and dispatch
val lastCycleRedirect = RegNext(redirectValid) val lastCycleRedirect = RegNext(redirectValid)
......
...@@ -156,8 +156,9 @@ class FloatBlock ...@@ -156,8 +156,9 @@ class FloatBlock
(0 until exuParameters.StuCnt).foreach(i => io.toMemBlock.readFpRf(i).data := fpRf.io.readPorts(i + 12).data) (0 until exuParameters.StuCnt).foreach(i => io.toMemBlock.readFpRf(i).data := fpRf.io.readPorts(i + 12).data)
// write fp rf arbiter // write fp rf arbiter
val fpWbArbiter = Module(new Wb( val fpWbArbiter = Module(new Wb(
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn).map(_.wbFpPriority), (exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn),
NRFpWritePorts NRFpWritePorts,
isFp = true
)) ))
fpWbArbiter.io.in <> exeUnits.map(_.io.toFp) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow fpWbArbiter.io.in <> exeUnits.map(_.io.toFp) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow
......
...@@ -102,11 +102,11 @@ class IntegerBlock ...@@ -102,11 +102,11 @@ class IntegerBlock
len = XLEN len = XLEN
)) ))
val aluExeUnits = Array.tabulate(exuParameters.AluCnt)(_ => Module(new AluExeUnit))
val jmpExeUnit = Module(new JumpExeUnit) val jmpExeUnit = Module(new JumpExeUnit)
val mduExeUnits = Array.tabulate(exuParameters.MduCnt)(_ => Module(new MulDivExeUnit)) val mduExeUnits = Array.tabulate(exuParameters.MduCnt)(_ => Module(new MulDivExeUnit))
val aluExeUnits = Array.tabulate(exuParameters.AluCnt)(_ => Module(new AluExeUnit))
val exeUnits = jmpExeUnit +: (aluExeUnits ++ mduExeUnits) val exeUnits = jmpExeUnit +: (mduExeUnits ++ aluExeUnits)
def needWakeup(cfg: ExuConfig): Boolean = def needWakeup(cfg: ExuConfig): Boolean =
(cfg.readIntRf && cfg.writeIntRf) || (cfg.readFpRf && cfg.writeFpRf) (cfg.readIntRf && cfg.writeIntRf) || (cfg.readFpRf && cfg.writeFpRf)
...@@ -151,6 +151,7 @@ class IntegerBlock ...@@ -151,6 +151,7 @@ class IntegerBlock
val src2Value = VecInit((0 until 4).map(i => intRf.io.readPorts(i * 2 + 1).data)) val src2Value = VecInit((0 until 4).map(i => intRf.io.readPorts(i * 2 + 1).data))
rsData.io.srcRegValue(0) := src1Value(readPortIndex(i)) rsData.io.srcRegValue(0) := src1Value(readPortIndex(i))
if (cfg.intSrcCnt > 1) rsData.io.srcRegValue(1) := src2Value(readPortIndex(i)) if (cfg.intSrcCnt > 1) rsData.io.srcRegValue(1) := src2Value(readPortIndex(i))
if (cfg == Exu.jumpExeUnitCfg) rsData.io.jumpPc := io.fromCtrlBlock.jumpPc
rsData.io.redirect <> redirect rsData.io.redirect <> redirect
rsData.io.writeBackedData <> writeBackData rsData.io.writeBackedData <> writeBackData
...@@ -221,8 +222,9 @@ class IntegerBlock ...@@ -221,8 +222,9 @@ class IntegerBlock
(0 until NRMemReadPorts).foreach(i => io.toMemBlock.readIntRf(i).data := intRf.io.readPorts(i + 8).data) (0 until NRMemReadPorts).foreach(i => io.toMemBlock.readIntRf(i).data := intRf.io.readPorts(i + 8).data)
// write int rf arbiter // write int rf arbiter
val intWbArbiter = Module(new Wb( val intWbArbiter = Module(new Wb(
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn).map(_.wbIntPriority), (exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn),
NRIntWritePorts NRIntWritePorts,
isFp = false
)) ))
intWbArbiter.io.in <> exeUnits.map(_.io.toInt) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow intWbArbiter.io.in <> exeUnits.map(_.io.toInt) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow
......
...@@ -5,6 +5,7 @@ import chisel3.util._ ...@@ -5,6 +5,7 @@ import chisel3.util._
import xiangshan._ import xiangshan._
import utils._ import utils._
import chisel3.ExcitingUtils._ import chisel3.ExcitingUtils._
import xiangshan.backend.decode.ImmUnion
class BrqPtr extends CircularQueuePtr(BrqPtr.BrqSize) with HasCircularQueuePtrHelper { class BrqPtr extends CircularQueuePtr(BrqPtr.BrqSize) with HasCircularQueuePtrHelper {
...@@ -44,6 +45,11 @@ class BrqEnqIO extends XSBundle { ...@@ -44,6 +45,11 @@ class BrqEnqIO extends XSBundle {
val resp = Vec(RenameWidth, Output(new BrqPtr)) val resp = Vec(RenameWidth, Output(new BrqPtr))
} }
class BrqPcRead extends XSBundle {
val brqIdx = Input(new BrqPtr)
val pc = Output(UInt(VAddrBits.W))
}
class BrqIO extends XSBundle{ class BrqIO extends XSBundle{
val redirect = Input(ValidIO(new Redirect)) val redirect = Input(ValidIO(new Redirect))
// receive branch/jump calculated target // receive branch/jump calculated target
...@@ -57,6 +63,8 @@ class BrqIO extends XSBundle{ ...@@ -57,6 +63,8 @@ class BrqIO extends XSBundle{
val cfiInfo = ValidIO(new CfiUpdateInfo) val cfiInfo = ValidIO(new CfiUpdateInfo)
// commit cnt of branch instr // commit cnt of branch instr
val bcommit = Input(UInt(BrTagWidth.W)) val bcommit = Input(UInt(BrTagWidth.W))
// read pc for jump unit
val pcReadReq = new BrqPcRead
} }
class Brq extends XSModule with HasCircularQueuePtrHelper { class Brq extends XSModule with HasCircularQueuePtrHelper {
...@@ -69,8 +77,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -69,8 +77,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val s_idle :: s_wb :: Nil = Enum(2) val s_idle :: s_wb :: Nil = Enum(2)
class DecodeEnqBrqData extends Bundle {
val cfiUpdateInfo = new CfiUpdateInfo
// we use this to calculate branch target
val imm12 = UInt(12.W)
}
// data and state // data and state
val decodeData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, DecodeWidth)) val decodeData = Module(new SyncDataModuleTemplate(new DecodeEnqBrqData, BrqSize, 3, DecodeWidth))
val writebackData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, exuParameters.AluCnt + exuParameters.JmpCnt)) val writebackData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, exuParameters.AluCnt + exuParameters.JmpCnt))
val ptrFlagVec = Reg(Vec(BrqSize, Bool())) val ptrFlagVec = Reg(Vec(BrqSize, Bool()))
val stateQueue = RegInit(VecInit(Seq.fill(BrqSize)(s_idle))) val stateQueue = RegInit(VecInit(Seq.fill(BrqSize)(s_idle)))
...@@ -109,9 +123,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -109,9 +123,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
} }
val brUpdateReadIdx = Mux(io.redirect.bits.flushItself(), io.redirect.bits.brTag - 1.U, io.redirect.bits.brTag) val brUpdateReadIdx = Mux(io.redirect.bits.flushItself(), io.redirect.bits.brTag - 1.U, io.redirect.bits.brTag)
val brUpdateReadEntry = Wire(new ExuOutput) val brUpdateReadEntry = Wire(new CfiUpdateInfo)
io.cfiInfo.valid := RegNext(io.redirect.valid || wbValid) io.cfiInfo.valid := RegNext(io.redirect.valid || wbValid)
io.cfiInfo.bits := brUpdateReadEntry.brUpdate io.cfiInfo.bits := brUpdateReadEntry
io.cfiInfo.bits.target := RegNext(Mux(io.redirect.bits.flushItself(),
io.redirect.bits.target,
wbEntry.brUpdate.target
))
io.cfiInfo.bits.brTarget := io.cfiInfo.bits.target
io.cfiInfo.bits.brTag := RegNext(brUpdateReadIdx) io.cfiInfo.bits.brTag := RegNext(brUpdateReadIdx)
io.cfiInfo.bits.isReplay := RegNext(io.redirect.bits.flushItself()) io.cfiInfo.bits.isReplay := RegNext(io.redirect.bits.flushItself())
io.cfiInfo.bits.isMisPred := RegNext(wbIsMisPred) io.cfiInfo.bits.isMisPred := RegNext(wbIsMisPred)
...@@ -183,31 +202,48 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -183,31 +202,48 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
} }
} }
def mergeDecodeWbData(dec: ExuOutput, wb: ExuOutput) : ExuOutput = { def mergeWbEntry(dec: DecodeEnqBrqData, wb: ExuOutput) : ExuOutput = {
val mergeData = Wire(new ExuOutput) val mergeData = Wire(new ExuOutput)
mergeData := dec
// only writeback necessary information // only writeback necessary information
mergeData.uop := wb.uop mergeData.uop := wb.uop
mergeData.data := wb.data mergeData.data := wb.data
mergeData.fflags := wb.fflags mergeData.fflags := wb.fflags
mergeData.redirectValid := wb.redirectValid mergeData.redirectValid := wb.redirectValid
// calculate target pc
val pc = dec.cfiUpdateInfo.pc
val offset = SignExt(ImmUnion.B.toImm32(dec.imm12), VAddrBits)
val snpc = pc + Mux(dec.cfiUpdateInfo.pd.isRVC, 2.U, 4.U)
val bnpc = pc + offset
val branch_pc = Mux(wb.brUpdate.taken, bnpc, snpc)
val redirectTarget = Mux(dec.cfiUpdateInfo.pd.isBr, branch_pc, wb.redirect.target)
mergeData.redirect := wb.redirect mergeData.redirect := wb.redirect
mergeData.redirect.target := redirectTarget
mergeData.debug := wb.debug mergeData.debug := wb.debug
mergeData.brUpdate.target := wb.brUpdate.target mergeData.brUpdate := dec.cfiUpdateInfo
mergeData.brUpdate.brTarget := wb.brUpdate.brTarget mergeData.brUpdate.target := redirectTarget
mergeData.brUpdate.brTarget := redirectTarget
mergeData.brUpdate.taken := wb.brUpdate.taken mergeData.brUpdate.taken := wb.brUpdate.taken
mergeData mergeData
} }
def mergeBrUpdateEntry(dec: DecodeEnqBrqData, wb: ExuOutput): CfiUpdateInfo = {
val mergeData = WireInit(dec.cfiUpdateInfo)
mergeData.taken := wb.brUpdate.taken
mergeData
}
decodeData.io.raddr(0) := writebackPtr_next.value decodeData.io.raddr(0) := writebackPtr_next.value
decodeData.io.raddr(1) := brUpdateReadIdx.value decodeData.io.raddr(1) := brUpdateReadIdx.value
decodeData.io.raddr(2) := io.pcReadReq.brqIdx.value
decodeData.io.wen := VecInit(io.enq.req.map(_.fire())) decodeData.io.wen := VecInit(io.enq.req.map(_.fire()))
decodeData.io.waddr := VecInit(enqBrTag.map(_.value)) decodeData.io.waddr := VecInit(enqBrTag.map(_.value))
decodeData.io.wdata.zip(io.enq.req).map{ case (wdata, req) => { decodeData.io.wdata.zip(io.enq.req).foreach{ case (wdata, req) =>
wdata := DontCare wdata.cfiUpdateInfo := req.bits.brUpdate
wdata.brUpdate := req.bits.brUpdate wdata.cfiUpdateInfo.pc := req.bits.pc
wdata.brUpdate.pc := req.bits.pc wdata.imm12 := ImmUnion.B.minBitsFromInstr(req.bits.instr)
}} }
writebackData.io.raddr(0) := writebackPtr_next.value writebackData.io.raddr(0) := writebackPtr_next.value
writebackData.io.raddr(1) := brUpdateReadIdx.value writebackData.io.raddr(1) := brUpdateReadIdx.value
...@@ -215,9 +251,10 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -215,9 +251,10 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
writebackData.io.waddr := VecInit(io.exuRedirectWb.map(_.bits.redirect.brTag.value)) writebackData.io.waddr := VecInit(io.exuRedirectWb.map(_.bits.redirect.brTag.value))
writebackData.io.wdata := VecInit(io.exuRedirectWb.map(_.bits)) writebackData.io.wdata := VecInit(io.exuRedirectWb.map(_.bits))
wbEntry := mergeDecodeWbData(decodeData.io.rdata(0), writebackData.io.rdata(0)) wbEntry := mergeWbEntry(decodeData.io.rdata(0), writebackData.io.rdata(0))
brUpdateReadEntry := mergeDecodeWbData(decodeData.io.rdata(1), writebackData.io.rdata(1)) brUpdateReadEntry := mergeBrUpdateEntry(decodeData.io.rdata(1), writebackData.io.rdata(1))
io.pcReadReq.pc := decodeData.io.rdata(2).cfiUpdateInfo.pc
// Debug info // Debug info
val debug_roq_redirect = io.redirect.valid && io.redirect.bits.isUnconditional() val debug_roq_redirect = io.redirect.valid && io.redirect.bits.isUnconditional()
......
...@@ -36,7 +36,7 @@ class DecodeStage extends XSModule { ...@@ -36,7 +36,7 @@ class DecodeStage extends XSModule {
val thisBrqValid = !io.in(i).bits.brUpdate.pd.notCFI || isMret || isSret val thisBrqValid = !io.in(i).bits.brUpdate.pd.notCFI || isMret || isSret
io.enqBrq.needAlloc(i) := thisBrqValid io.enqBrq.needAlloc(i) := thisBrqValid
io.enqBrq.req(i).valid := io.in(i).valid && thisBrqValid && io.out(i).ready io.enqBrq.req(i).valid := io.in(i).valid && thisBrqValid && io.out(i).ready
io.enqBrq.req(i).bits := io.in(i).bits io.enqBrq.req(i).bits := decoders(i).io.deq.cf_ctrl.cf
io.out(i).valid := io.in(i).valid && io.enqBrq.req(i).ready 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 := decoders(i).io.deq.cf_ctrl
......
...@@ -150,9 +150,9 @@ object XDecode extends DecodeConstants { ...@@ -150,9 +150,9 @@ object XDecode extends DecodeConstants {
CSRRS -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.set, Y, N, N, Y, Y, N, N, SelImm.IMM_I), CSRRS -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.set, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRC -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clr, Y, N, N, Y, Y, N, N, SelImm.IMM_I), CSRRC -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clr, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRWI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrti, Y, N, N, Y, Y, N, N, SelImm.IMM_I), CSRRWI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrti, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
CSRRSI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, Y, N, N, Y, Y, N, N, SelImm.IMM_I), CSRRSI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
CSRRCI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, Y, N, N, Y, Y, N, N, SelImm.IMM_I), CSRRCI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
SFENCE_VMA->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, Y, Y, Y, N, SelImm.IMM_X), SFENCE_VMA->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, Y, Y, Y, N, SelImm.IMM_X),
ECALL -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_X), ECALL -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_X),
...@@ -316,26 +316,98 @@ class RVCExpander extends XSModule { ...@@ -316,26 +316,98 @@ class RVCExpander extends XSModule {
} }
} }
object Imm32Gen { //object Imm32Gen {
def apply(sel: UInt, inst: UInt) = { // def apply(sel: UInt, inst: UInt) = {
val sign = Mux(sel === SelImm.IMM_Z, 0.S, inst(31).asSInt) // val sign = Mux(sel === SelImm.IMM_Z, 0.S, inst(31).asSInt)
val b30_20 = Mux(sel === SelImm.IMM_U, inst(30,20).asSInt, sign) // val b30_20 = Mux(sel === SelImm.IMM_U, inst(30,20).asSInt, sign)
val b19_12 = Mux(sel =/= SelImm.IMM_U && sel =/= SelImm.IMM_UJ, sign, inst(19,12).asSInt) // val b19_12 = Mux(sel =/= SelImm.IMM_U && sel =/= SelImm.IMM_UJ, sign, inst(19,12).asSInt)
val b11 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.S, // val b11 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.S,
Mux(sel === SelImm.IMM_UJ, inst(20).asSInt, // Mux(sel === SelImm.IMM_UJ, inst(20).asSInt,
Mux(sel === SelImm.IMM_SB, inst(7).asSInt, sign))) // Mux(sel === SelImm.IMM_SB, inst(7).asSInt, sign)))
val b10_5 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.U(1.W), inst(30,25)) // val b10_5 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.U(1.W), inst(30,25))
val b4_1 = Mux(sel === SelImm.IMM_U, 0.U(1.W), // val b4_1 = Mux(sel === SelImm.IMM_U, 0.U(1.W),
Mux(sel === SelImm.IMM_S || sel === SelImm.IMM_SB, inst(11,8), // Mux(sel === SelImm.IMM_S || sel === SelImm.IMM_SB, inst(11,8),
Mux(sel === SelImm.IMM_Z, inst(19,16), inst(24,21)))) // Mux(sel === SelImm.IMM_Z, inst(19,16), inst(24,21))))
val b0 = Mux(sel === SelImm.IMM_S, inst(7), // val b0 = Mux(sel === SelImm.IMM_S, inst(7),
Mux(sel === SelImm.IMM_I, inst(20), // Mux(sel === SelImm.IMM_I, inst(20),
Mux(sel === SelImm.IMM_Z, inst(15), 0.U(1.W)))) // Mux(sel === SelImm.IMM_Z, inst(15), 0.U(1.W))))
//
Cat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0) // Cat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0)
// }
//}
abstract class Imm(val len: Int) extends Bundle {
def toImm32(minBits: UInt): UInt = do_toImm32(minBits(len - 1, 0))
def do_toImm32(minBits: UInt): UInt
def minBitsFromInstr(instr: UInt): UInt
}
case class Imm_I() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31, 20))
}
case class Imm_S() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31, 25), instr(11, 7))
}
case class Imm_B() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31), instr(7), instr(30, 25), instr(11, 8))
}
case class Imm_U() extends Imm(20){
override def do_toImm32(minBits: UInt): UInt = Cat(minBits, 0.U(12.W))
override def minBitsFromInstr(instr: UInt): UInt = {
instr(31, 12)
}
}
case class Imm_J() extends Imm(20){
override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
override def minBitsFromInstr(instr: UInt): UInt = {
Cat(instr(31), instr(19, 12), instr(20), instr(30, 25), instr(24, 21))
}
}
case class Imm_Z() extends Imm(12 + 5){
override def do_toImm32(minBits: UInt): UInt = minBits
override def minBitsFromInstr(instr: UInt): UInt = {
Cat(instr(19, 15), instr(31, 20))
} }
} }
object ImmUnion {
val I = Imm_I()
val S = Imm_S()
val B = Imm_B()
val U = Imm_U()
val J = Imm_J()
val Z = Imm_Z()
val imms = Seq(I, S, B, U, J, Z)
val maxLen = imms.maxBy(_.len).len
val immSelMap = Seq(
SelImm.IMM_I,
SelImm.IMM_S,
SelImm.IMM_SB,
SelImm.IMM_U,
SelImm.IMM_UJ,
SelImm.IMM_Z
).zip(imms)
println(s"ImmUnion max len: $maxLen")
}
/** /**
* IO bundle for the Decode unit * IO bundle for the Decode unit
*/ */
...@@ -375,7 +447,7 @@ class DecodeUnit extends XSModule with DecodeUnitConstants { ...@@ -375,7 +447,7 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
val cs = Wire(new CtrlSignals()).decode(ctrl_flow.instr, decode_table) val cs = Wire(new CtrlSignals()).decode(ctrl_flow.instr, decode_table)
val fpDecoder = Module(new FPDecoder) val fpDecoder = Module(new FPDecoder)
fpDecoder.io.instr := io.enq.ctrl_flow.instr fpDecoder.io.instr := ctrl_flow.instr
cs.fpu := fpDecoder.io.fpCtrl cs.fpu := fpDecoder.io.fpCtrl
// read src1~3 location // read src1~3 location
...@@ -403,19 +475,26 @@ class DecodeUnit extends XSModule with DecodeUnitConstants { ...@@ -403,19 +475,26 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs.lsrc1 := XSTrapDecode.lsrc1 cs.lsrc1 := XSTrapDecode.lsrc1
} }
cs.imm := SignExt(Imm32Gen(cs.selImm, ctrl_flow.instr), XLEN) cs.imm := LookupTree(cs.selImm, ImmUnion.immSelMap.map(
x => {
val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
require(minBits.getWidth == x._2.len)
x._1 -> minBits
}
))
cf_ctrl.ctrl := cs cf_ctrl.ctrl := cs
// TODO: do we still need this?
// fix ret and call // fix ret and call
when (cs.fuType === FuType.jmp) { // when (cs.fuType === FuType.jmp) {
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U) // def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
when (isLink(cs.ldest) && cs.fuOpType === JumpOpType.jal) { cf_ctrl.ctrl.fuOpType := JumpOpType.call } // when (isLink(cs.ldest) && cs.fuOpType === JumpOpType.jal) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
when (cs.fuOpType === JumpOpType.jalr) { // when (cs.fuOpType === JumpOpType.jalr) {
when (isLink(cs.lsrc1)) { cf_ctrl.ctrl.fuOpType := JumpOpType.ret } // when (isLink(cs.lsrc1)) { cf_ctrl.ctrl.fuOpType := JumpOpType.ret }
when (isLink(cs.ldest)) { cf_ctrl.ctrl.fuOpType := JumpOpType.call } // when (isLink(cs.ldest)) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
} // }
} // }
io.deq.cf_ctrl := cf_ctrl io.deq.cf_ctrl := cf_ctrl
......
...@@ -17,37 +17,40 @@ class Dispatch2Int extends XSModule { ...@@ -17,37 +17,40 @@ class Dispatch2Int extends XSModule {
val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W)))
}) })
val jmpCnt = exuParameters.JmpCnt
val mduCnt = exuParameters.MduCnt
val aluCnt = exuParameters.AluCnt
/** /**
* Part 1: generate indexes for reservation stations * Part 1: generate indexes for reservation stations
*/ */
assert(jmpCnt == 1)
val jmpCanAccept = VecInit(io.fromDq.map(deq => deq.valid && jumpExeUnitCfg.canAccept(deq.bits.ctrl.fuType))) val jmpCanAccept = VecInit(io.fromDq.map(deq => deq.valid && jumpExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val aluCanAccept = VecInit(io.fromDq.map(deq => deq.valid && aluExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val mduCanAccept = VecInit(io.fromDq.map(deq => deq.valid && mulDivExeUnitCfg.canAccept(deq.bits.ctrl.fuType))) val mduCanAccept = VecInit(io.fromDq.map(deq => deq.valid && mulDivExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
assert(exuParameters.JmpCnt == 1) val aluCanAccept = VecInit(io.fromDq.map(deq => deq.valid && aluExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val jmpIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, exuParameters.JmpCnt, false))
val aluIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, exuParameters.AluCnt, true)) val jmpIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, jmpCnt, false))
val mduIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, exuParameters.MduCnt, true)) val mduIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, mduCnt, true))
val aluPriority = PriorityGen((0 until exuParameters.AluCnt).map(i => io.numExist(i+exuParameters.JmpCnt))) val aluIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, aluCnt, true))
val mduPriority = PriorityGen((0 until exuParameters.MduCnt).map(i => io.numExist(i+exuParameters.JmpCnt+exuParameters.AluCnt)))
val mduPriority = PriorityGen(io.numExist.slice(jmpCnt, jmpCnt + mduCnt))
val aluPriority = PriorityGen(io.numExist.drop(jmpCnt + mduCnt))
jmpIndexGen.io.validBits := jmpCanAccept jmpIndexGen.io.validBits := jmpCanAccept
aluIndexGen.io.validBits := aluCanAccept
mduIndexGen.io.validBits := mduCanAccept mduIndexGen.io.validBits := mduCanAccept
aluIndexGen.io.validBits := aluCanAccept
jmpIndexGen.io.priority := DontCare jmpIndexGen.io.priority := DontCare
aluIndexGen.io.priority := aluPriority
mduIndexGen.io.priority := mduPriority mduIndexGen.io.priority := mduPriority
aluIndexGen.io.priority := aluPriority
val allIndexGen = Seq(jmpIndexGen, aluIndexGen, mduIndexGen) val allIndexGen = Seq(jmpIndexGen, mduIndexGen, aluIndexGen)
val validVec = allIndexGen.map(_.io.mapping.map(_.valid)).reduceLeft(_ ++ _) val validVec = allIndexGen.flatMap(_.io.mapping.map(_.valid))
val indexVec = allIndexGen.map(_.io.mapping.map(_.bits)).reduceLeft(_ ++ _) val indexVec = allIndexGen.flatMap(_.io.mapping.map(_.bits))
for (i <- validVec.indices) {
// XSDebug(p"mapping $i: valid ${validVec(i)} index ${indexVec(i)}\n")
}
/** /**
* Part 2: assign regfile read ports * Part 2: assign regfile read ports
*/ */
val intStaticIndex = Seq(1, 2, 3, 4) val intStaticIndex = Seq(3, 4, 5, 6)
val intDynamicIndex = Seq(0, 5, 6) val intDynamicIndex = Seq(0, 1, 2)
val intStaticMappedValid = intStaticIndex.map(i => validVec(i)) val intStaticMappedValid = intStaticIndex.map(i => validVec(i))
val intDynamicMappedValid = intDynamicIndex.map(i => validVec(i)) val intDynamicMappedValid = intDynamicIndex.map(i => validVec(i))
val (intReadPortSrc, intDynamicExuSrc) = RegfileReadPortGen(intStaticMappedValid, intDynamicMappedValid) val (intReadPortSrc, intDynamicExuSrc) = RegfileReadPortGen(intStaticMappedValid, intDynamicMappedValid)
...@@ -66,18 +69,18 @@ class Dispatch2Int extends XSModule { ...@@ -66,18 +69,18 @@ class Dispatch2Int extends XSModule {
* Part 3: dispatch to reservation stations * Part 3: dispatch to reservation stations
*/ */
val jmpReady = io.enqIQCtrl(0).ready val jmpReady = io.enqIQCtrl(0).ready
val aluReady = Cat(io.enqIQCtrl.take(exuParameters.JmpCnt + exuParameters.AluCnt).drop(exuParameters.JmpCnt).map(_.ready)).andR val mduReady = Cat(io.enqIQCtrl.slice(jmpCnt, jmpCnt + mduCnt).map(_.ready)).andR
val mduReady = Cat(io.enqIQCtrl.drop(exuParameters.JmpCnt + exuParameters.AluCnt).map(_.ready)).andR val aluReady = Cat(io.enqIQCtrl.drop(jmpCnt + mduCnt).map(_.ready)).andR
for (i <- 0 until exuParameters.IntExuCnt) { for (i <- 0 until exuParameters.IntExuCnt) {
val enq = io.enqIQCtrl(i) val enq = io.enqIQCtrl(i)
if (i < exuParameters.JmpCnt) { if (i < jmpCnt) {
enq.valid := jmpIndexGen.io.mapping(i).valid// && jmpReady enq.valid := jmpIndexGen.io.mapping(i).valid// && jmpReady
} }
else if (i < exuParameters.JmpCnt + exuParameters.AluCnt) { else if (i < jmpCnt + mduCnt) {
enq.valid := aluIndexGen.io.mapping(i - exuParameters.JmpCnt).valid && aluReady enq.valid := mduIndexGen.io.mapping(i - jmpCnt).valid && mduReady
} }
else { else { // alu
enq.valid := mduIndexGen.io.mapping(i - (exuParameters.JmpCnt + exuParameters.AluCnt)).valid && mduReady enq.valid := aluIndexGen.io.mapping(i - (jmpCnt + mduCnt)).valid && aluReady
} }
enq.bits := io.fromDq(indexVec(i)).bits enq.bits := io.fromDq(indexVec(i)).bits
......
...@@ -85,7 +85,7 @@ object RegfileReadPortGen { ...@@ -85,7 +85,7 @@ object RegfileReadPortGen {
val choiceCount = dynamicMappedValid.length + 1 val choiceCount = dynamicMappedValid.length + 1
val readPortSrc = Wire(Vec(staticMappedValid.length, UInt(log2Ceil(choiceCount).W))) val readPortSrc = Wire(Vec(staticMappedValid.length, UInt(log2Ceil(choiceCount).W)))
var hasAssigned = (0 until choiceCount).map(_ => false.B) var hasAssigned = (0 until choiceCount).map(_ => false.B)
for (i <- 0 until staticMappedValid.length) { for (i <- staticMappedValid.indices) {
val valid = staticMappedValid(i) +: dynamicMappedValid val valid = staticMappedValid(i) +: dynamicMappedValid
val wantReadPort = (0 until choiceCount).map(j => valid(j) && ((j == 0).asBool() || !hasAssigned(j))) val wantReadPort = (0 until choiceCount).map(j => valid(j) && ((j == 0).asBool() || !hasAssigned(j)))
readPortSrc(i) := PriorityEncoder(wantReadPort) readPortSrc(i) := PriorityEncoder(wantReadPort)
...@@ -93,8 +93,8 @@ object RegfileReadPortGen { ...@@ -93,8 +93,8 @@ object RegfileReadPortGen {
hasAssigned = (0 until choiceCount).map(i => hasAssigned(i) || onehot(i)) hasAssigned = (0 until choiceCount).map(i => hasAssigned(i) || onehot(i))
} }
val dynamicExuSrc = Wire(Vec(dynamicMappedValid.length, UInt(log2Ceil(staticMappedValid.length).W))) val dynamicExuSrc = Wire(Vec(dynamicMappedValid.length, UInt(log2Ceil(staticMappedValid.length).W)))
for (i <- 0 until dynamicMappedValid.length) { for (i <- dynamicMappedValid.indices) {
val targetMatch = (0 until staticMappedValid.length).map(j => readPortSrc(j) === (i + 1).U) val targetMatch = staticMappedValid.indices.map(j => readPortSrc(j) === (i + 1).U)
dynamicExuSrc(i) := PriorityEncoder(targetMatch) dynamicExuSrc(i) := PriorityEncoder(targetMatch)
} }
(readPortSrc, dynamicExuSrc) (readPortSrc, dynamicExuSrc)
......
...@@ -6,9 +6,12 @@ import xiangshan._ ...@@ -6,9 +6,12 @@ import xiangshan._
import utils._ import utils._
class Wb(priorities: Seq[Int], numOut: Int) extends XSModule { class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule {
val priorities = cfgs.map(c => if(isFp) c.wbFpPriority else c.wbIntPriority)
val io = IO(new Bundle() { val io = IO(new Bundle() {
val in = Vec(priorities.size, Flipped(DecoupledIO(new ExuOutput))) val in = Vec(cfgs.size, Flipped(DecoupledIO(new ExuOutput)))
val out = Vec(numOut, ValidIO(new ExuOutput)) val out = Vec(numOut, ValidIO(new ExuOutput))
}) })
...@@ -35,7 +38,7 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule { ...@@ -35,7 +38,7 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
} }
def splitN[T](in: Seq[T], n: Int): Seq[Option[Seq[T]]] = { def splitN[T](in: Seq[T], n: Int): Seq[Option[Seq[T]]] = {
require(n > 0) if(n == 0) return Seq()
if(n == 1){ if(n == 1){
Seq(Some(in)) Seq(Some(in))
} else { } else {
...@@ -48,12 +51,12 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule { ...@@ -48,12 +51,12 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
} }
} }
if(mulReq.nonEmpty){
val arbReq = splitN( val arbReq = splitN(
otherReq, otherReq,
mulReq.size mulReq.size
) )
for(i <- mulReq.indices){
val arbiters = for(i <- mulReq.indices) yield {
val other = arbReq(i).getOrElse(Seq()) val other = arbReq(i).getOrElse(Seq())
val arb = Module(new Arbiter(new ExuOutput, 1+other.size)) val arb = Module(new Arbiter(new ExuOutput, 1+other.size))
arb.io.in <> mulReq(i) +: other arb.io.in <> mulReq(i) +: other
...@@ -61,11 +64,25 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule { ...@@ -61,11 +64,25 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
out.valid := arb.io.out.valid out.valid := arb.io.out.valid
out.bits := arb.io.out.bits out.bits := arb.io.out.bits
arb.io.out.ready := true.B arb.io.out.ready := true.B
} arb
} }
if(portUsed < numOut){ if(portUsed < numOut){
println(s"Warning: ${numOut - portUsed} ports are not used!") println(s"Warning: ${numOut - portUsed} ports are not used!")
io.out.drop(portUsed).foreach(_ <> DontCare) io.out.drop(portUsed).foreach(_ <> DontCare)
} }
val sb = new StringBuffer(s"\n${if(isFp) "fp" else "int"} wb arbiter:\n")
for((conn, i) <- directConnect.zipWithIndex){
sb.append(s"[ ${cfgs(io.in.indexOf(conn)).name} ] -> out #$i\n")
}
for(i <- mulReq.indices){
sb.append(s"[ ${cfgs(io.in.indexOf(mulReq(i))).name} ")
for(req <- arbReq(i).getOrElse(Nil)){
sb.append(s"${cfgs(io.in.indexOf(req)).name} ")
}
sb.append(s"] -> arb -> out #${directConnect.size + i}\n")
}
println(sb)
} }
\ No newline at end of file
...@@ -8,15 +8,16 @@ import xiangshan.backend.ALUOpType ...@@ -8,15 +8,16 @@ import xiangshan.backend.ALUOpType
class Alu extends FunctionUnit with HasRedirectOut { class Alu extends FunctionUnit with HasRedirectOut {
val (src1, src2, offset, func, pc, uop) = ( val (src1, src2, func, pc, uop) = (
io.in.bits.src(0), io.in.bits.src(0),
io.in.bits.src(1), io.in.bits.src(1),
io.in.bits.uop.ctrl.imm,
io.in.bits.uop.ctrl.fuOpType, io.in.bits.uop.ctrl.fuOpType,
SignExt(io.in.bits.uop.cf.pc, AddrBits), SignExt(io.in.bits.uop.cf.pc, AddrBits),
io.in.bits.uop io.in.bits.uop
) )
val offset = src2
val valid = io.in.valid val valid = io.in.valid
val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
...@@ -63,21 +64,30 @@ class Alu extends FunctionUnit with HasRedirectOut { ...@@ -63,21 +64,30 @@ class Alu extends FunctionUnit with HasRedirectOut {
val snpc = Mux(isRVC, pc + 2.U, pc + 4.U) val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
redirectOutValid := io.out.valid && isBranch redirectOutValid := io.out.valid && isBranch
redirectOut.pc := uop.cf.pc // Only brTag, level, roqIdx are needed
redirectOut.target := Mux(!taken && isBranch, snpc, target) // other infos are stored in brq
redirectOut := DontCare
redirectOut.brTag := uop.brTag redirectOut.brTag := uop.brTag
redirectOut.level := RedirectLevel.flushAfter redirectOut.level := RedirectLevel.flushAfter
redirectOut.interrupt := DontCare
redirectOut.roqIdx := uop.roqIdx redirectOut.roqIdx := uop.roqIdx
brUpdate := uop.cf.brUpdate // redirectOut.pc := DontCare//uop.cf.pc
// override brUpdate // redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target)
brUpdate.pc := uop.cf.pc // redirectOut.interrupt := DontCare//DontCare
brUpdate.target := Mux(!taken && isBranch, snpc, target)
brUpdate.brTarget := target // Only taken really needed, do we need brTag ?
brUpdate := DontCare
brUpdate.taken := isBranch && taken brUpdate.taken := isBranch && taken
brUpdate.brTag := uop.brTag brUpdate.brTag := uop.brTag
// brUpdate := uop.cf.brUpdate
// // override brUpdate
// brUpdate.pc := uop.cf.pc
// brUpdate.target := Mux(!taken && isBranch, snpc, target)
// brUpdate.brTarget := target
// brUpdate.taken := isBranch && taken
// brUpdate.brTag := uop.brTag
io.in.ready := io.out.ready io.in.ready := io.out.ready
io.out.valid := valid io.out.valid := valid
io.out.bits.uop <> io.in.bits.uop io.out.bits.uop <> io.in.bits.uop
......
...@@ -430,13 +430,13 @@ class CSR extends FunctionUnit with HasCSRConst ...@@ -430,13 +430,13 @@ class CSR extends FunctionUnit with HasCSRConst
(if (HasFPU) fcsrMapping else Nil) (if (HasFPU) fcsrMapping else Nil)
val addr = src2(11, 0) val addr = src2(11, 0)
val csri = src2(16, 12)
val rdata = Wire(UInt(XLEN.W)) val rdata = Wire(UInt(XLEN.W))
val csri = ZeroExt(cfIn.instr(19,15), XLEN) //unsigned imm for csri. [TODO]
val wdata = LookupTree(func, List( val wdata = LookupTree(func, List(
CSROpType.wrt -> src1, CSROpType.wrt -> src1,
CSROpType.set -> (rdata | src1), CSROpType.set -> (rdata | src1),
CSROpType.clr -> (rdata & (~src1).asUInt()), CSROpType.clr -> (rdata & (~src1).asUInt()),
CSROpType.wrti -> csri, //TODO: csri --> src2 CSROpType.wrti -> csri,
CSROpType.seti -> (rdata | csri), CSROpType.seti -> (rdata | csri),
CSROpType.clri -> (rdata & (~csri).asUInt()) CSROpType.clri -> (rdata & (~csri).asUInt())
)) ))
...@@ -629,12 +629,6 @@ class CSR extends FunctionUnit with HasCSRConst ...@@ -629,12 +629,6 @@ class CSR extends FunctionUnit with HasCSRConst
val raiseExceptionVec = csrio.exception.bits.cf.exceptionVec.asUInt() val raiseExceptionVec = csrio.exception.bits.cf.exceptionVec.asUInt()
val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
// if (!env.FPGAPlatform) {
val id = hartId()
val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
ExcitingUtils.addSource(difftestIntrNO, s"difftestIntrNOfromCSR$id")
ExcitingUtils.addSource(causeNO, s"difftestCausefromCSR$id")
// }
val raiseExceptionIntr = csrio.exception.valid val raiseExceptionIntr = csrio.exception.valid
XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
...@@ -797,6 +791,9 @@ class CSR extends FunctionUnit with HasCSRConst ...@@ -797,6 +791,9 @@ class CSR extends FunctionUnit with HasCSRConst
} }
} }
val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
ExcitingUtils.addSource(difftestIntrNO, "difftestIntrNOfromCSR")
ExcitingUtils.addSource(causeNO, "difftestCausefromCSR")
ExcitingUtils.addSource(priviledgeMode, "difftestMode", Debug) ExcitingUtils.addSource(priviledgeMode, "difftestMode", Debug)
ExcitingUtils.addSource(mstatus, "difftestMstatus", Debug) ExcitingUtils.addSource(mstatus, "difftestMstatus", Debug)
ExcitingUtils.addSource(mstatus & sstatusRmask, "difftestSstatus", Debug) ExcitingUtils.addSource(mstatus & sstatusRmask, "difftestSstatus", Debug)
......
...@@ -29,7 +29,7 @@ case class FuConfig ...@@ -29,7 +29,7 @@ case class FuConfig
writeIntRf: Boolean, writeIntRf: Boolean,
writeFpRf: Boolean, writeFpRf: Boolean,
hasRedirect: Boolean, hasRedirect: Boolean,
latency: HasFuLatency = CertainLatency(0) latency: HasFuLatency = CertainLatency(0),
) { ) {
def srcCnt: Int = math.max(numIntSrc, numFpSrc) def srcCnt: Int = math.max(numIntSrc, numFpSrc)
} }
...@@ -159,7 +159,7 @@ object FunctionUnit extends HasXSParameter { ...@@ -159,7 +159,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc = 0, numFpSrc = 0,
writeIntRf = true, writeIntRf = true,
writeFpRf = false, writeFpRf = false,
hasRedirect = true hasRedirect = true,
) )
val jmpCfg = FuConfig( val jmpCfg = FuConfig(
...@@ -170,7 +170,7 @@ object FunctionUnit extends HasXSParameter { ...@@ -170,7 +170,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc = 0, numFpSrc = 0,
writeIntRf = true, writeIntRf = true,
writeFpRf = false, writeFpRf = false,
hasRedirect = true hasRedirect = true,
) )
val fenceCfg = FuConfig( val fenceCfg = FuConfig(
......
...@@ -5,6 +5,7 @@ import chisel3.util._ ...@@ -5,6 +5,7 @@ import chisel3.util._
import xiangshan._ import xiangshan._
import utils._ import utils._
import xiangshan.backend._ import xiangshan.backend._
import xiangshan.backend.decode.ImmUnion
import xiangshan.backend.fu.FunctionUnit._ import xiangshan.backend.fu.FunctionUnit._
import xiangshan.backend.decode.isa._ import xiangshan.backend.decode.isa._
...@@ -16,7 +17,7 @@ trait HasRedirectOut { this: RawModule => ...@@ -16,7 +17,7 @@ trait HasRedirectOut { this: RawModule =>
class Jump extends FunctionUnit with HasRedirectOut { class Jump extends FunctionUnit with HasRedirectOut {
val (src1, offset, func, pc, uop) = ( val (src1, immMin, func, pc, uop) = (
io.in.bits.src(0), io.in.bits.src(0),
io.in.bits.uop.ctrl.imm, io.in.bits.uop.ctrl.imm,
io.in.bits.uop.ctrl.fuOpType, io.in.bits.uop.ctrl.fuOpType,
...@@ -24,6 +25,11 @@ class Jump extends FunctionUnit with HasRedirectOut { ...@@ -24,6 +25,11 @@ class Jump extends FunctionUnit with HasRedirectOut {
io.in.bits.uop io.in.bits.uop
) )
val offset = SignExt(Mux(JumpOpType.jumpOpIsJal(func),
ImmUnion.J.toImm32(immMin),
ImmUnion.I.toImm32(immMin)
), XLEN)
val redirectHit = uop.roqIdx.needFlush(io.redirectIn) val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
val valid = io.in.valid val valid = io.in.valid
...@@ -32,15 +38,16 @@ class Jump extends FunctionUnit with HasRedirectOut { ...@@ -32,15 +38,16 @@ class Jump extends FunctionUnit with HasRedirectOut {
val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset) val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
redirectOutValid := valid redirectOutValid := valid
redirectOut.pc := uop.cf.pc redirectOut := DontCare
// redirectOut.pc := uop.cf.pc
redirectOut.target := target redirectOut.target := target
redirectOut.brTag := uop.brTag redirectOut.brTag := uop.brTag
redirectOut.level := RedirectLevel.flushAfter redirectOut.level := RedirectLevel.flushAfter
redirectOut.interrupt := DontCare // redirectOut.interrupt := DontCare
redirectOut.roqIdx := uop.roqIdx redirectOut.roqIdx := uop.roqIdx
brUpdate := uop.cf.brUpdate brUpdate := DontCare //uop.cf.brUpdate
brUpdate.pc := uop.cf.pc // brUpdate.pc := uop.cf.pc
brUpdate.target := target brUpdate.target := target
brUpdate.brTarget := target brUpdate.brTarget := target
brUpdate.taken := true.B brUpdate.taken := true.B
......
...@@ -4,8 +4,10 @@ import chisel3._ ...@@ -4,8 +4,10 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import xiangshan._ import xiangshan._
import utils._ import utils._
import xiangshan.backend.decode.ImmUnion
import xiangshan.backend.exu.{Exu, ExuConfig} import xiangshan.backend.exu.{Exu, ExuConfig}
import xiangshan.backend.regfile.RfReadPort import xiangshan.backend.regfile.RfReadPort
import scala.math.max import scala.math.max
class BypassQueue(number: Int) extends XSModule { class BypassQueue(number: Int) extends XSModule {
...@@ -336,6 +338,7 @@ class ReservationStationData ...@@ -336,6 +338,7 @@ class ReservationStationData
// read src op value // read src op value
val srcRegValue = Vec(srcNum, Input(UInt((XLEN + 1).W))) val srcRegValue = Vec(srcNum, Input(UInt((XLEN + 1).W)))
val jumpPc = if(exuCfg == Exu.jumpExeUnitCfg) Input(UInt(VAddrBits.W)) else null
// broadcast selected uop to other issue queues // broadcast selected uop to other issue queues
val selectedUop = ValidIO(new MicroOp) val selectedUop = ValidIO(new MicroOp)
...@@ -404,6 +407,7 @@ class ReservationStationData ...@@ -404,6 +407,7 @@ class ReservationStationData
val deq = RegEnable(sel.bits, sel.valid) val deq = RegEnable(sel.bits, sel.valid)
val enqCtrl = io.ctrl.enqCtrl val enqCtrl = io.ctrl.enqCtrl
val enqUop = enqCtrl.bits val enqUop = enqCtrl.bits
val enqUopReg = RegEnable(enqUop, enqCtrl.fire())
// enq // enq
val enqPtr = enq(log2Up(IssQueSize)-1,0) val enqPtr = enq(log2Up(IssQueSize)-1,0)
...@@ -418,7 +422,33 @@ class ReservationStationData ...@@ -418,7 +422,33 @@ class ReservationStationData
} }
when (enqEnReg) { when (enqEnReg) {
exuCfg match {
case Exu.jumpExeUnitCfg =>
val src1Mux = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(io.jumpPc, XLEN),
io.srcRegValue(0)
)
dataWrite(enqPtrReg, 0, src1Mux)
case Exu.aluExeUnitCfg =>
val src1Mux = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(enqUopReg.cf.pc, XLEN),
io.srcRegValue(0)
)
dataWrite(enqPtrReg, 0, src1Mux)
// TODO: opt this, a full map is not necesscary here
val imm32 = LookupTree(
enqUopReg.ctrl.selImm,
ImmUnion.immSelMap.map(x => x._1 -> x._2.toImm32(enqUopReg.ctrl.imm))
)
val imm64 = SignExt(imm32, XLEN)
val src2Mux = Mux(enqUopReg.ctrl.src2Type === SrcType.imm,
imm64, io.srcRegValue(1)
)
dataWrite(enqPtrReg, 1, src2Mux)
case _ =>
(0 until srcNum).foreach(i => dataWrite(enqPtrReg, i, io.srcRegValue(i))) (0 until srcNum).foreach(i => dataWrite(enqPtrReg, i, io.srcRegValue(i)))
}
XSDebug(p"${exuCfg.name}: enqPtrReg:${enqPtrReg} pc: ${Hexadecimal(uop(enqPtrReg).cf.pc)}\n") XSDebug(p"${exuCfg.name}: enqPtrReg:${enqPtrReg} pc: ${Hexadecimal(uop(enqPtrReg).cf.pc)}\n")
XSDebug(p"[srcRegValue] " + List.tabulate(srcNum)(idx => p"src$idx: ${Hexadecimal(io.srcRegValue(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n") XSDebug(p"[srcRegValue] " + List.tabulate(srcNum)(idx => p"src$idx: ${Hexadecimal(io.srcRegValue(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n")
} }
...@@ -472,8 +502,8 @@ class ReservationStationData ...@@ -472,8 +502,8 @@ class ReservationStationData
exuInput.uop := uop(deq) exuInput.uop := uop(deq)
val regValues = List.tabulate(srcNum)(i => dataRead(Mux(sel.valid, sel.bits, deq), i)) val regValues = List.tabulate(srcNum)(i => dataRead(Mux(sel.valid, sel.bits, deq), i))
XSDebug(io.deq.fire(), p"[regValues] " + List.tabulate(srcNum)(idx => p"reg$idx: ${Hexadecimal(regValues(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n") XSDebug(io.deq.fire(), p"[regValues] " + List.tabulate(srcNum)(idx => p"reg$idx: ${Hexadecimal(regValues(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n")
exuInput.src1 := Mux(uop(deq).ctrl.src1Type === SrcType.pc, SignExt(uop(deq).cf.pc, XLEN + 1), regValues(0)) exuInput.src1 := regValues(0)
if (srcNum > 1) exuInput.src2 := Mux(uop(deq).ctrl.src2Type === SrcType.imm, uop(deq).ctrl.imm, regValues(1)) if (srcNum > 1) exuInput.src2 := regValues(1)
if (srcNum > 2) exuInput.src3 := regValues(2) if (srcNum > 2) exuInput.src3 := regValues(2)
io.deq.valid := RegNext(sel.valid) io.deq.valid := RegNext(sel.valid)
...@@ -496,7 +526,7 @@ class ReservationStationData ...@@ -496,7 +526,7 @@ class ReservationStationData
io.ctrl.feedback := DontCare io.ctrl.feedback := DontCare
if (feedback) { if (feedback) {
(0 until IssQueSize).map(i => (0 until IssQueSize).foreach(i =>
io.ctrl.feedback(i) := uop(i).roqIdx.asUInt === io.feedback.bits.roqIdx.asUInt && io.feedback.valid) io.ctrl.feedback(i) := uop(i).roqIdx.asUInt === io.feedback.bits.roqIdx.asUInt && io.feedback.valid)
io.ctrl.feedback(IssQueSize) := io.feedback.bits.hit io.ctrl.feedback(IssQueSize) := io.feedback.bits.hit
} }
......
...@@ -19,8 +19,10 @@ package object backend { ...@@ -19,8 +19,10 @@ package object backend {
object JumpOpType { object JumpOpType {
def jal = "b11_000".U def jal = "b11_000".U
def jalr = "b11_010".U def jalr = "b11_010".U
def call = "b11_011".U // def call = "b11_011".U
def ret = "b11_100".U // def ret = "b11_100".U
def jumpOpIsJal(op: UInt) = !op(1)
def jumpOpisJalr(op: UInt) = op(1)
} }
object FenceOpType { object FenceOpType {
......
...@@ -674,11 +674,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -674,11 +674,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
if(i % 4 == 3) XSDebug(false, true.B, "\n") if(i % 4 == 3) XSDebug(false, true.B, "\n")
} }
val id = roqDebugId() val instrCnt = RegInit(0.U(64.W))
val difftestIntrNO = WireInit(0.U(XLEN.W)) val retireCounter = Mux(state === s_idle, commitCnt, 0.U)
val difftestCause = WireInit(0.U(XLEN.W)) instrCnt := instrCnt + retireCounter
ExcitingUtils.addSink(difftestIntrNO, s"difftestIntrNOfromCSR$id") io.csr.perfinfo.retiredInstr := RegNext(retireCounter)
ExcitingUtils.addSink(difftestCause, s"difftestCausefromCSR$id")
if(!env.FPGAPlatform) { if(!env.FPGAPlatform) {
...@@ -721,11 +720,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -721,11 +720,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
debug_deqUop.ctrl.fuType === FuType.mou && debug_deqUop.ctrl.fuType === FuType.mou &&
(debug_deqUop.ctrl.fuOpType === LSUOpType.sc_d || debug_deqUop.ctrl.fuOpType === LSUOpType.sc_w) (debug_deqUop.ctrl.fuOpType === LSUOpType.sc_d || debug_deqUop.ctrl.fuOpType === LSUOpType.sc_w)
val instrCnt = RegInit(0.U(64.W)) val difftestIntrNO = WireInit(0.U(XLEN.W))
val retireCounter = Mux(state === s_idle, commitCnt, 0.U) val difftestCause = WireInit(0.U(XLEN.W))
instrCnt := instrCnt + retireCounter ExcitingUtils.addSink(difftestIntrNO, "difftestIntrNOfromCSR")
io.csr.perfinfo.retiredInstr := RegNext(retireCounter); ExcitingUtils.addSink(difftestCause, "difftestCausefromCSR")
XSDebug(difftestIntrNO =/= 0.U, "difftest intrNO set %x\n", difftestIntrNO) XSDebug(difftestIntrNO =/= 0.U, "difftest intrNO set %x\n", difftestIntrNO)
val retireCounterFix = Mux(io.redirectOut.valid, 1.U, retireCounter) val retireCounterFix = Mux(io.redirectOut.valid, 1.U, retireCounter)
val retirePCFix = SignExt(Mux(io.redirectOut.valid, debug_deqUop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN) val retirePCFix = SignExt(Mux(io.redirectOut.valid, debug_deqUop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN)
......
...@@ -398,7 +398,7 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame ...@@ -398,7 +398,7 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
// sync with prober // sync with prober
missQueue.io.probe_wb_req.valid := prober.io.wb_req.fire() missQueue.io.probe_wb_req.valid := prober.io.wb_req.fire()
missQueue.io.probe_wb_req.bits := prober.io.wb_req.bits missQueue.io.probe_wb_req.bits := prober.io.wb_req.bits
missQueue.io.probe_active := prober.io.inflight_req_block_addr missQueue.io.probe_active := prober.io.inflight_req_idx
//---------------------------------------- //----------------------------------------
// prober // prober
......
...@@ -306,7 +306,7 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule ...@@ -306,7 +306,7 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// if it releases the block we are trying to acquire, we don't care, since we will get it back eventually // if it releases the block we are trying to acquire, we don't care, since we will get it back eventually
// but we need to know whether it releases the block we are trying to evict // but we need to know whether it releases the block we are trying to evict
val prober_writeback_our_block = (state === s_refill_req || state === s_refill_resp || val prober_writeback_our_block = (state === s_refill_req || state === s_refill_resp ||
state === s_mem_finish || state === s_wait_probe_exit || state === s_send_resp || state === s_wb_req) && state === s_mem_finish || state === s_wait_probe_exit) &&
io.probe_wb_req.valid && !io.probe_wb_req.bits.voluntary && io.probe_wb_req.valid && !io.probe_wb_req.bits.voluntary &&
io.probe_wb_req.bits.tag === req_old_meta.tag && io.probe_wb_req.bits.tag === req_old_meta.tag &&
io.probe_wb_req.bits.idx === req_idx && io.probe_wb_req.bits.idx === req_idx &&
......
...@@ -126,14 +126,14 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule { ...@@ -126,14 +126,14 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
val id = cfg.nMissEntries val id = cfg.nMissEntries
val probeResponse = edge.ProbeAck( val probeResponse = edge.ProbeAck(
fromSource = id.U, fromSource = req.source,
toAddress = r_address, toAddress = r_address,
lgSize = log2Ceil(cfg.blockBytes).U, lgSize = log2Ceil(cfg.blockBytes).U,
reportPermissions = req.param reportPermissions = req.param
) )
val probeResponseData = edge.ProbeAck( val probeResponseData = edge.ProbeAck(
fromSource = id.U, fromSource = req.source,
toAddress = r_address, toAddress = r_address,
lgSize = log2Ceil(cfg.blockBytes).U, lgSize = log2Ceil(cfg.blockBytes).U,
reportPermissions = req.param, reportPermissions = req.param,
......
...@@ -403,7 +403,9 @@ class LoopPredictor extends BasePredictor with LTBParams { ...@@ -403,7 +403,9 @@ class LoopPredictor extends BasePredictor with LTBParams {
io.meta.specCnts(i) := ltbResps(i).meta io.meta.specCnts(i) := ltbResps(i).meta
} }
if (!env.FPGAPlatform) {
ExcitingUtils.addSource(io.resp.exit.reduce(_||_), "perfCntLoopExit", Perf) ExcitingUtils.addSource(io.resp.exit.reduce(_||_), "perfCntLoopExit", Perf)
}
if (BPUDebug && debug) { if (BPUDebug && debug) {
// debug info // debug info
......
...@@ -4,6 +4,7 @@ import chisel3._ ...@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import utils._ import utils._
import xiangshan._ import xiangshan._
import xiangshan.backend.decode.ImmUnion
import xiangshan.cache._ import xiangshan.cache._
// import xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants, TlbReq, DCacheLoadReq, DCacheWordResp} // import xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants, TlbReq, DCacheLoadReq, DCacheWordResp}
import xiangshan.backend.LSUOpType import xiangshan.backend.LSUOpType
...@@ -25,7 +26,7 @@ class LoadUnit_S0 extends XSModule { ...@@ -25,7 +26,7 @@ class LoadUnit_S0 extends XSModule {
}) })
val s0_uop = io.in.bits.uop val s0_uop = io.in.bits.uop
val s0_vaddr = io.in.bits.src1 + s0_uop.ctrl.imm val s0_vaddr = io.in.bits.src1 + SignExt(ImmUnion.I.toImm32(s0_uop.ctrl.imm), XLEN)
val s0_mask = genWmask(s0_vaddr, s0_uop.ctrl.fuOpType(1,0)) val s0_mask = genWmask(s0_vaddr, s0_uop.ctrl.fuOpType(1,0))
// query DTLB // query DTLB
......
...@@ -4,6 +4,7 @@ import chisel3._ ...@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import utils._ import utils._
import xiangshan._ import xiangshan._
import xiangshan.backend.decode.ImmUnion
import xiangshan.cache._ import xiangshan.cache._
// Store Pipeline Stage 0 // Store Pipeline Stage 0
...@@ -16,7 +17,7 @@ class StoreUnit_S0 extends XSModule { ...@@ -16,7 +17,7 @@ class StoreUnit_S0 extends XSModule {
}) })
// send req to dtlb // send req to dtlb
val saddr = io.in.bits.src1 + io.in.bits.uop.ctrl.imm val saddr = io.in.bits.src1 + SignExt(ImmUnion.S.toImm32(io.in.bits.uop.ctrl.imm), XLEN)
io.dtlbReq.bits.vaddr := saddr io.dtlbReq.bits.vaddr := saddr
io.dtlbReq.valid := io.in.valid io.dtlbReq.valid := io.in.valid
......
...@@ -9,13 +9,13 @@ import freechips.rocketchip.tilelink.{TLErrorEvaluator, TLMasterParameters, TLXb ...@@ -9,13 +9,13 @@ import freechips.rocketchip.tilelink.{TLErrorEvaluator, TLMasterParameters, TLXb
class SimMMIO()(implicit p: config.Parameters) extends LazyModule { class SimMMIO()(implicit p: config.Parameters) extends LazyModule {
val flash = LazyModule(new AXI4Flash(Seq(AddressSet(0x10000000L, 0xfffffff))))
val uart = LazyModule(new AXI4UART(Seq(AddressSet(0x40600000L, 0xf)))) val uart = LazyModule(new AXI4UART(Seq(AddressSet(0x40600000L, 0xf))))
val vga = LazyModule(new AXI4VGA( val vga = LazyModule(new AXI4VGA(
sim = false, sim = false,
fbAddress = Seq(AddressSet(0x50000000L, 0x3fffffL)), fbAddress = Seq(AddressSet(0x50000000L, 0x3fffffL)),
ctrlAddress = Seq(AddressSet(0x40001000L, 0x7L)) ctrlAddress = Seq(AddressSet(0x40001000L, 0x7L))
)) ))
val flash = LazyModule(new AXI4Flash(Seq(AddressSet(0x40000000L, 0xfff))))
val sd = LazyModule(new AXI4DummySD(Seq(AddressSet(0x40002000L, 0xfff)))) val sd = LazyModule(new AXI4DummySD(Seq(AddressSet(0x40002000L, 0xfff))))
val axiBus = AXI4Xbar() val axiBus = AXI4Xbar()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册