Removed all traces of params
This commit is contained in:
parent
69a4dd0a79
commit
84576650b5
@ -5,7 +5,7 @@ package rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import uncore._
|
import uncore._
|
||||||
|
|
||||||
class HellaCacheArbiter(n: Int) extends Module
|
class HellaCacheArbiter(n: Int)(implicit p: Parameters) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = Vec(new HellaCacheIO, n).flip
|
val requestor = Vec(new HellaCacheIO, n).flip
|
||||||
|
@ -6,18 +6,23 @@ import Chisel._
|
|||||||
import junctions._
|
import junctions._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
case object NBTBEntries extends Field[Int]
|
case object BtbKey extends Field[BtbParameters]
|
||||||
case object NRAS extends Field[Int]
|
case class BtbParameters(nEntries: Int = 62, nRAS: Int = 2, updatesOutOfOrder: Boolean = false)
|
||||||
|
|
||||||
abstract trait BTBParameters extends CoreParameters {
|
abstract trait HasBtbParameters extends HasCoreParameters {
|
||||||
val matchBits = params(PgIdxBits)
|
val matchBits = p(PgIdxBits)
|
||||||
val entries = params(NBTBEntries)
|
val entries = p(BtbKey).nEntries
|
||||||
val nRAS = params(NRAS)
|
val nRAS = p(BtbKey).nRAS
|
||||||
|
val updatesOutOfOrder = p(BtbKey).updatesOutOfOrder
|
||||||
val nPages = ((1 max(log2Up(entries)))+1)/2*2 // control logic assumes 2 divides pages
|
val nPages = ((1 max(log2Up(entries)))+1)/2*2 // control logic assumes 2 divides pages
|
||||||
val opaqueBits = log2Up(entries)
|
val opaqueBits = log2Up(entries)
|
||||||
val nBHT = 1 << log2Up(entries*2)
|
val nBHT = 1 << log2Up(entries*2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class BtbModule(implicit val p: Parameters) extends Module with HasBtbParameters
|
||||||
|
abstract class BtbBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||||
|
with HasBtbParameters
|
||||||
|
|
||||||
class RAS(nras: Int) {
|
class RAS(nras: Int) {
|
||||||
def push(addr: UInt): Unit = {
|
def push(addr: UInt): Unit = {
|
||||||
when (count < nras) { count := count + 1 }
|
when (count < nras) { count := count + 1 }
|
||||||
@ -38,7 +43,7 @@ class RAS(nras: Int) {
|
|||||||
private val stack = Reg(Vec(UInt(), nras))
|
private val stack = Reg(Vec(UInt(), nras))
|
||||||
}
|
}
|
||||||
|
|
||||||
class BHTResp extends Bundle with BTBParameters {
|
class BHTResp(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val history = UInt(width = log2Up(nBHT).max(1))
|
val history = UInt(width = log2Up(nBHT).max(1))
|
||||||
val value = UInt(width = 2)
|
val value = UInt(width = 2)
|
||||||
}
|
}
|
||||||
@ -52,7 +57,7 @@ class BHTResp extends Bundle with BTBParameters {
|
|||||||
// - each counter corresponds with the address of the fetch packet ("fetch pc").
|
// - each counter corresponds with the address of the fetch packet ("fetch pc").
|
||||||
// - updated when a branch resolves (and BTB was a hit for that branch).
|
// - updated when a branch resolves (and BTB was a hit for that branch).
|
||||||
// The updating branch must provide its "fetch pc".
|
// The updating branch must provide its "fetch pc".
|
||||||
class BHT(nbht: Int) {
|
class BHT(nbht: Int)(implicit p: Parameters) {
|
||||||
val nbhtbits = log2Up(nbht)
|
val nbhtbits = log2Up(nbht)
|
||||||
def get(addr: UInt, update: Bool): BHTResp = {
|
def get(addr: UInt, update: Bool): BHTResp = {
|
||||||
val res = Wire(new BHTResp)
|
val res = Wire(new BHTResp)
|
||||||
@ -76,7 +81,7 @@ class BHT(nbht: Int) {
|
|||||||
// BTB update occurs during branch resolution (and only on a mispredict).
|
// BTB update occurs during branch resolution (and only on a mispredict).
|
||||||
// - "pc" is what future fetch PCs will tag match against.
|
// - "pc" is what future fetch PCs will tag match against.
|
||||||
// - "br_pc" is the PC of the branch instruction.
|
// - "br_pc" is the PC of the branch instruction.
|
||||||
class BTBUpdate extends Bundle with BTBParameters {
|
class BTBUpdate(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val prediction = Valid(new BTBResp)
|
val prediction = Valid(new BTBResp)
|
||||||
val pc = UInt(width = vaddrBits)
|
val pc = UInt(width = vaddrBits)
|
||||||
val target = UInt(width = vaddrBits)
|
val target = UInt(width = vaddrBits)
|
||||||
@ -88,14 +93,14 @@ class BTBUpdate extends Bundle with BTBParameters {
|
|||||||
|
|
||||||
// BHT update occurs during branch resolution on all conditional branches.
|
// BHT update occurs during branch resolution on all conditional branches.
|
||||||
// - "pc" is what future fetch PCs will tag match against.
|
// - "pc" is what future fetch PCs will tag match against.
|
||||||
class BHTUpdate extends Bundle with BTBParameters {
|
class BHTUpdate(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val prediction = Valid(new BTBResp)
|
val prediction = Valid(new BTBResp)
|
||||||
val pc = UInt(width = vaddrBits)
|
val pc = UInt(width = vaddrBits)
|
||||||
val taken = Bool()
|
val taken = Bool()
|
||||||
val mispredict = Bool()
|
val mispredict = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class RASUpdate extends Bundle with BTBParameters {
|
class RASUpdate(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val isCall = Bool()
|
val isCall = Bool()
|
||||||
val isReturn = Bool()
|
val isReturn = Bool()
|
||||||
val returnAddr = UInt(width = vaddrBits)
|
val returnAddr = UInt(width = vaddrBits)
|
||||||
@ -106,16 +111,16 @@ class RASUpdate extends Bundle with BTBParameters {
|
|||||||
// shifting off the lowest log(inst_bytes) bits off).
|
// shifting off the lowest log(inst_bytes) bits off).
|
||||||
// - "resp.mask" provides a mask of valid instructions (instructions are
|
// - "resp.mask" provides a mask of valid instructions (instructions are
|
||||||
// masked off by the predicted taken branch).
|
// masked off by the predicted taken branch).
|
||||||
class BTBResp extends Bundle with BTBParameters {
|
class BTBResp(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val taken = Bool()
|
val taken = Bool()
|
||||||
val mask = Bits(width = params(FetchWidth))
|
val mask = Bits(width = fetchWidth)
|
||||||
val bridx = Bits(width = log2Up(params(FetchWidth)))
|
val bridx = Bits(width = log2Up(fetchWidth))
|
||||||
val target = UInt(width = vaddrBits)
|
val target = UInt(width = vaddrBits)
|
||||||
val entry = UInt(width = opaqueBits)
|
val entry = UInt(width = opaqueBits)
|
||||||
val bht = new BHTResp
|
val bht = new BHTResp
|
||||||
}
|
}
|
||||||
|
|
||||||
class BTBReq extends Bundle with BTBParameters {
|
class BTBReq(implicit p: Parameters) extends BtbBundle()(p) {
|
||||||
val addr = UInt(width = vaddrBits)
|
val addr = UInt(width = vaddrBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +128,7 @@ class BTBReq extends Bundle with BTBParameters {
|
|||||||
// Higher-performance processors may cause BTB updates to occur out-of-order,
|
// Higher-performance processors may cause BTB updates to occur out-of-order,
|
||||||
// which requires an extra CAM port for updates (to ensure no duplicates get
|
// which requires an extra CAM port for updates (to ensure no duplicates get
|
||||||
// placed in BTB).
|
// placed in BTB).
|
||||||
class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParameters {
|
class BTB(implicit p: Parameters) extends BtbModule {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Valid(new BTBReq).flip
|
val req = Valid(new BTBReq).flip
|
||||||
val resp = Valid(new BTBResp)
|
val resp = Valid(new BTBResp)
|
||||||
@ -145,7 +150,7 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete
|
|||||||
|
|
||||||
val useRAS = Reg(Vec(entries, Bool()))
|
val useRAS = Reg(Vec(entries, Bool()))
|
||||||
val isJump = Reg(Vec(entries, Bool()))
|
val isJump = Reg(Vec(entries, Bool()))
|
||||||
val brIdx = Mem(entries, UInt(width=log2Up(params(FetchWidth))))
|
val brIdx = Mem(entries, UInt(width=log2Up(fetchWidth)))
|
||||||
|
|
||||||
private def page(addr: UInt) = addr >> matchBits
|
private def page(addr: UInt) = addr >> matchBits
|
||||||
private def pageMatch(addr: UInt) = {
|
private def pageMatch(addr: UInt) = {
|
||||||
@ -198,7 +203,7 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete
|
|||||||
assert(io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
|
assert(io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
|
||||||
|
|
||||||
val waddr =
|
val waddr =
|
||||||
if (updates_out_of_order) Mux(updateHits.orR, OHToUInt(updateHits), nextRepl)
|
if (updatesOutOfOrder) Mux(updateHits.orR, OHToUInt(updateHits), nextRepl)
|
||||||
else Mux(updateHit, r_btb_update.bits.prediction.bits.entry, nextRepl)
|
else Mux(updateHit, r_btb_update.bits.prediction.bits.entry, nextRepl)
|
||||||
|
|
||||||
// invalidate entries if we stomp on pages they depend upon
|
// invalidate entries if we stomp on pages they depend upon
|
||||||
@ -212,10 +217,10 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete
|
|||||||
tgtPages(waddr) := tgtPageUpdate
|
tgtPages(waddr) := tgtPageUpdate
|
||||||
useRAS(waddr) := r_btb_update.bits.isReturn
|
useRAS(waddr) := r_btb_update.bits.isReturn
|
||||||
isJump(waddr) := r_btb_update.bits.isJump
|
isJump(waddr) := r_btb_update.bits.isJump
|
||||||
if (params(FetchWidth) == 1) {
|
if (fetchWidth == 1) {
|
||||||
brIdx(waddr) := UInt(0)
|
brIdx(waddr) := UInt(0)
|
||||||
} else {
|
} else {
|
||||||
brIdx(waddr) := r_btb_update.bits.br_pc >> log2Up(params(CoreInstBits)/8)
|
brIdx(waddr) := r_btb_update.bits.br_pc >> log2Up(coreInstBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
require(nPages % 2 == 0)
|
require(nPages % 2 == 0)
|
||||||
@ -243,7 +248,7 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete
|
|||||||
io.resp.bits.target := Cat(Mux1H(Mux1H(hits, tgtPagesOH), pages), Mux1H(hits, tgts))
|
io.resp.bits.target := Cat(Mux1H(Mux1H(hits, tgtPagesOH), pages), Mux1H(hits, tgts))
|
||||||
io.resp.bits.entry := OHToUInt(hits)
|
io.resp.bits.entry := OHToUInt(hits)
|
||||||
io.resp.bits.bridx := brIdx(io.resp.bits.entry)
|
io.resp.bits.bridx := brIdx(io.resp.bits.entry)
|
||||||
if (params(FetchWidth) == 1) {
|
if (fetchWidth == 1) {
|
||||||
io.resp.bits.mask := UInt(1)
|
io.resp.bits.mask := UInt(1)
|
||||||
} else {
|
} else {
|
||||||
// note: btb_resp is clock gated, so the mask is only relevant for the io.resp.valid case
|
// note: btb_resp is clock gated, so the mask is only relevant for the io.resp.valid case
|
||||||
|
@ -64,12 +64,14 @@ object CSR
|
|||||||
val C = UInt(3,SZ)
|
val C = UInt(3,SZ)
|
||||||
val I = UInt(4,SZ)
|
val I = UInt(4,SZ)
|
||||||
val R = UInt(5,SZ)
|
val R = UInt(5,SZ)
|
||||||
|
|
||||||
|
val ADDRSZ = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFileIO extends CoreBundle {
|
class CSRFileIO(implicit p: Parameters) extends CoreBundle {
|
||||||
val host = new HTIFIO
|
val host = new HtifIO
|
||||||
val rw = new Bundle {
|
val rw = new Bundle {
|
||||||
val addr = UInt(INPUT, 12)
|
val addr = UInt(INPUT, CSR.ADDRSZ)
|
||||||
val cmd = Bits(INPUT, CSR.SZ)
|
val cmd = Bits(INPUT, CSR.SZ)
|
||||||
val rdata = Bits(OUTPUT, xLen)
|
val rdata = Bits(OUTPUT, xLen)
|
||||||
val wdata = Bits(INPUT, xLen)
|
val wdata = Bits(INPUT, xLen)
|
||||||
@ -86,7 +88,7 @@ class CSRFileIO extends CoreBundle {
|
|||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
||||||
val uarch_counters = Vec(UInt(INPUT, log2Up(1+retireWidth)), 16)
|
val uarch_counters = Vec(UInt(INPUT, log2Up(1+retireWidth)), 16)
|
||||||
val custom_mrw_csrs = Vec(UInt(INPUT, xLen), params(NCustomMRWCSRs))
|
val custom_mrw_csrs = Vec(UInt(INPUT, xLen), nCustomMrwCsrs)
|
||||||
val cause = UInt(INPUT, xLen)
|
val cause = UInt(INPUT, xLen)
|
||||||
val pc = UInt(INPUT, vaddrBitsExtended)
|
val pc = UInt(INPUT, vaddrBitsExtended)
|
||||||
val fatc = Bool(OUTPUT)
|
val fatc = Bool(OUTPUT)
|
||||||
@ -98,7 +100,7 @@ class CSRFileIO extends CoreBundle {
|
|||||||
val interrupt_cause = UInt(OUTPUT, xLen)
|
val interrupt_cause = UInt(OUTPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile extends CoreModule
|
class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||||
{
|
{
|
||||||
val io = new CSRFileIO
|
val io = new CSRFileIO
|
||||||
|
|
||||||
@ -124,12 +126,12 @@ class CSRFile extends CoreModule
|
|||||||
val reg_stats = Reg(init=Bool(false))
|
val reg_stats = Reg(init=Bool(false))
|
||||||
val reg_time = Reg(UInt(width = xLen))
|
val reg_time = Reg(UInt(width = xLen))
|
||||||
val reg_instret = WideCounter(xLen, io.retire)
|
val reg_instret = WideCounter(xLen, io.retire)
|
||||||
val reg_cycle = if (EnableCommitLog) { reg_instret } else { WideCounter(xLen) }
|
val reg_cycle = if (enableCommitLog) { reg_instret } else { WideCounter(xLen) }
|
||||||
val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _))
|
val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _))
|
||||||
val reg_fflags = Reg(UInt(width = 5))
|
val reg_fflags = Reg(UInt(width = 5))
|
||||||
val reg_frm = Reg(UInt(width = 3))
|
val reg_frm = Reg(UInt(width = 3))
|
||||||
|
|
||||||
val irq_rocc = Bool(!params(BuildRoCC).isEmpty) && io.rocc.interrupt
|
val irq_rocc = Bool(!p(BuildRoCC).isEmpty) && io.rocc.interrupt
|
||||||
|
|
||||||
io.interrupt_cause := 0
|
io.interrupt_cause := 0
|
||||||
io.interrupt := io.interrupt_cause(xLen-1)
|
io.interrupt := io.interrupt_cause(xLen-1)
|
||||||
@ -153,40 +155,40 @@ class CSRFile extends CoreModule
|
|||||||
val system_insn = io.rw.cmd === CSR.I
|
val system_insn = io.rw.cmd === CSR.I
|
||||||
val cpu_ren = io.rw.cmd != CSR.N && !system_insn
|
val cpu_ren = io.rw.cmd != CSR.N && !system_insn
|
||||||
|
|
||||||
val host_pcr_req_valid = Reg(Bool()) // don't reset
|
val host_csr_req_valid = Reg(Bool()) // don't reset
|
||||||
val host_pcr_req_fire = host_pcr_req_valid && !cpu_ren
|
val host_csr_req_fire = host_csr_req_valid && !cpu_ren
|
||||||
val host_pcr_rep_valid = Reg(Bool()) // don't reset
|
val host_csr_rep_valid = Reg(Bool()) // don't reset
|
||||||
val host_pcr_bits = Reg(io.host.pcr.req.bits)
|
val host_csr_bits = Reg(io.host.csr.req.bits)
|
||||||
io.host.pcr.req.ready := !host_pcr_req_valid && !host_pcr_rep_valid
|
io.host.csr.req.ready := !host_csr_req_valid && !host_csr_rep_valid
|
||||||
io.host.pcr.resp.valid := host_pcr_rep_valid
|
io.host.csr.resp.valid := host_csr_rep_valid
|
||||||
io.host.pcr.resp.bits := host_pcr_bits.data
|
io.host.csr.resp.bits := host_csr_bits.data
|
||||||
when (io.host.pcr.req.fire()) {
|
when (io.host.csr.req.fire()) {
|
||||||
host_pcr_req_valid := true
|
host_csr_req_valid := true
|
||||||
host_pcr_bits := io.host.pcr.req.bits
|
host_csr_bits := io.host.csr.req.bits
|
||||||
}
|
}
|
||||||
when (host_pcr_req_fire) {
|
when (host_csr_req_fire) {
|
||||||
host_pcr_req_valid := false
|
host_csr_req_valid := false
|
||||||
host_pcr_rep_valid := true
|
host_csr_rep_valid := true
|
||||||
host_pcr_bits.data := io.rw.rdata
|
host_csr_bits.data := io.rw.rdata
|
||||||
}
|
}
|
||||||
when (io.host.pcr.resp.fire()) { host_pcr_rep_valid := false }
|
when (io.host.csr.resp.fire()) { host_csr_rep_valid := false }
|
||||||
|
|
||||||
io.host.debug_stats_pcr := reg_stats // direct export up the hierarchy
|
io.host.debug_stats_csr := reg_stats // direct export up the hierarchy
|
||||||
|
|
||||||
val read_time = if (params(UsePerfCounters)) reg_time else (reg_cycle: UInt)
|
val read_time = if (usingPerfCounters) reg_time else (reg_cycle: UInt)
|
||||||
val read_mstatus = io.status.toBits
|
val read_mstatus = io.status.toBits
|
||||||
val isa_string = "IMA" +
|
val isa_string = "IMA" +
|
||||||
(if (params(UseVM)) "S" else "") +
|
(if (usingVM) "S" else "") +
|
||||||
(if (!params(BuildFPU).isEmpty) "FD" else "") +
|
(if (usingFPU) "FD" else "") +
|
||||||
(if (!params(BuildRoCC).isEmpty) "X" else "")
|
(if (usingRoCC) "X" else "")
|
||||||
val cpuid = ((if (xLen == 32) BigInt(0) else BigInt(2)) << (xLen-2)) |
|
val cpuid = ((if (xLen == 32) BigInt(0) else BigInt(2)) << (xLen-2)) |
|
||||||
isa_string.map(x => 1 << (x - 'A')).reduce(_|_)
|
isa_string.map(x => 1 << (x - 'A')).reduce(_|_)
|
||||||
val impid = 1
|
val impid = 1
|
||||||
|
|
||||||
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
||||||
CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)),
|
CSRs.fflags -> (if (usingFPU) reg_fflags else UInt(0)),
|
||||||
CSRs.frm -> (if (!params(BuildFPU).isEmpty) reg_frm else UInt(0)),
|
CSRs.frm -> (if (usingFPU) reg_frm else UInt(0)),
|
||||||
CSRs.fcsr -> (if (!params(BuildFPU).isEmpty) Cat(reg_frm, reg_fflags) else UInt(0)),
|
CSRs.fcsr -> (if (usingFPU) Cat(reg_frm, reg_fflags) else UInt(0)),
|
||||||
CSRs.cycle -> reg_cycle,
|
CSRs.cycle -> reg_cycle,
|
||||||
CSRs.cyclew -> reg_cycle,
|
CSRs.cyclew -> reg_cycle,
|
||||||
CSRs.time -> read_time,
|
CSRs.time -> read_time,
|
||||||
@ -213,7 +215,7 @@ class CSRFile extends CoreModule
|
|||||||
CSRs.mtohost -> reg_tohost,
|
CSRs.mtohost -> reg_tohost,
|
||||||
CSRs.mfromhost -> reg_fromhost)
|
CSRs.mfromhost -> reg_fromhost)
|
||||||
|
|
||||||
if (params(UsePerfCounters)) {
|
if (usingPerfCounters) {
|
||||||
read_mapping += CSRs.instret -> reg_instret
|
read_mapping += CSRs.instret -> reg_instret
|
||||||
read_mapping += CSRs.instretw -> reg_instret
|
read_mapping += CSRs.instretw -> reg_instret
|
||||||
|
|
||||||
@ -221,7 +223,7 @@ class CSRFile extends CoreModule
|
|||||||
read_mapping += (CSRs.uarch0 + i) -> reg_uarch_counters(i)
|
read_mapping += (CSRs.uarch0 + i) -> reg_uarch_counters(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params(UseVM)) {
|
if (usingVM) {
|
||||||
val read_sstatus = Wire(init=new SStatus().fromBits(read_mstatus))
|
val read_sstatus = Wire(init=new SStatus().fromBits(read_mstatus))
|
||||||
read_sstatus.zero1 := 0
|
read_sstatus.zero1 := 0
|
||||||
read_sstatus.zero2 := 0
|
read_sstatus.zero2 := 0
|
||||||
@ -248,14 +250,14 @@ class CSRFile extends CoreModule
|
|||||||
read_mapping += CSRs.stvec -> reg_stvec.sextTo(xLen)
|
read_mapping += CSRs.stvec -> reg_stvec.sextTo(xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i <- 0 until params(NCustomMRWCSRs)) {
|
for (i <- 0 until nCustomMrwCsrs) {
|
||||||
val addr = 0x790 + i // turn 0x790 into parameter CustomMRWCSRBase?
|
val addr = 0x790 + i // turn 0x790 into parameter CustomMRWCSRBase?
|
||||||
require(addr >= 0x780 && addr <= 0x7ff, "custom MRW CSR address " + i + " is out of range")
|
require(addr >= 0x780 && addr <= 0x7ff, "custom MRW CSR address " + i + " is out of range")
|
||||||
require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use")
|
require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use")
|
||||||
read_mapping += addr -> io.custom_mrw_csrs(i)
|
read_mapping += addr -> io.custom_mrw_csrs(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
val addr = Mux(cpu_ren, io.rw.addr, host_pcr_bits.addr)
|
val addr = Mux(cpu_ren, io.rw.addr, host_csr_bits.addr)
|
||||||
val decoded_addr = read_mapping map { case (k, v) => k -> (addr === k) }
|
val decoded_addr = read_mapping map { case (k, v) => k -> (addr === k) }
|
||||||
|
|
||||||
val addr_valid = decoded_addr.values.reduce(_||_)
|
val addr_valid = decoded_addr.values.reduce(_||_)
|
||||||
@ -264,11 +266,11 @@ class CSRFile extends CoreModule
|
|||||||
val priv_sufficient = reg_mstatus.prv >= csr_addr_priv
|
val priv_sufficient = reg_mstatus.prv >= csr_addr_priv
|
||||||
val read_only = io.rw.addr(11,10).andR
|
val read_only = io.rw.addr(11,10).andR
|
||||||
val cpu_wen = cpu_ren && io.rw.cmd != CSR.R && priv_sufficient
|
val cpu_wen = cpu_ren && io.rw.cmd != CSR.R && priv_sufficient
|
||||||
val wen = cpu_wen && !read_only || host_pcr_req_fire && host_pcr_bits.rw
|
val wen = cpu_wen && !read_only || host_csr_req_fire && host_csr_bits.rw
|
||||||
val wdata = Mux(io.rw.cmd === CSR.W, io.rw.wdata,
|
val wdata = Mux(io.rw.cmd === CSR.W, io.rw.wdata,
|
||||||
Mux(io.rw.cmd === CSR.C, io.rw.rdata & ~io.rw.wdata,
|
Mux(io.rw.cmd === CSR.C, io.rw.rdata & ~io.rw.wdata,
|
||||||
Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata,
|
Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata,
|
||||||
host_pcr_bits.data)))
|
host_csr_bits.data)))
|
||||||
|
|
||||||
val opcode = io.rw.addr
|
val opcode = io.rw.addr
|
||||||
val insn_call = !opcode(8) && !opcode(0) && system_insn
|
val insn_call = !opcode(8) && !opcode(0) && system_insn
|
||||||
@ -355,7 +357,7 @@ class CSRFile extends CoreModule
|
|||||||
io.csr_replay := io.host.ipi_req.valid && !io.host.ipi_req.ready
|
io.csr_replay := io.host.ipi_req.valid && !io.host.ipi_req.ready
|
||||||
io.csr_stall := reg_wfi
|
io.csr_stall := reg_wfi
|
||||||
|
|
||||||
when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.mtohost)) { reg_tohost := UInt(0) }
|
when (host_csr_req_fire && !host_csr_bits.rw && decoded_addr(CSRs.mtohost)) { reg_tohost := UInt(0) }
|
||||||
|
|
||||||
io.rw.rdata := Mux1H(for ((k, v) <- read_mapping) yield decoded_addr(k) -> v)
|
io.rw.rdata := Mux1H(for ((k, v) <- read_mapping) yield decoded_addr(k) -> v)
|
||||||
|
|
||||||
@ -370,7 +372,7 @@ class CSRFile extends CoreModule
|
|||||||
reg_mstatus.ie := new_mstatus.ie
|
reg_mstatus.ie := new_mstatus.ie
|
||||||
reg_mstatus.ie1 := new_mstatus.ie1
|
reg_mstatus.ie1 := new_mstatus.ie1
|
||||||
|
|
||||||
val supportedModes = Vec((PRV_M :: PRV_U :: (if (params(UseVM)) List(PRV_S) else Nil)).map(UInt(_)))
|
val supportedModes = Vec((PRV_M :: PRV_U :: (if (usingVM) List(PRV_S) else Nil)).map(UInt(_)))
|
||||||
if (supportedModes.size > 1) {
|
if (supportedModes.size > 1) {
|
||||||
reg_mstatus.mprv := new_mstatus.mprv
|
reg_mstatus.mprv := new_mstatus.mprv
|
||||||
when (supportedModes contains new_mstatus.prv) { reg_mstatus.prv := new_mstatus.prv }
|
when (supportedModes contains new_mstatus.prv) { reg_mstatus.prv := new_mstatus.prv }
|
||||||
@ -381,17 +383,17 @@ class CSRFile extends CoreModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params(UseVM)) {
|
if (usingVM) {
|
||||||
val vm_on = if (xLen == 32) 8 else 9
|
val vm_on = if (xLen == 32) 8 else 9
|
||||||
when (new_mstatus.vm === 0) { reg_mstatus.vm := 0 }
|
when (new_mstatus.vm === 0) { reg_mstatus.vm := 0 }
|
||||||
when (new_mstatus.vm === vm_on) { reg_mstatus.vm := vm_on }
|
when (new_mstatus.vm === vm_on) { reg_mstatus.vm := vm_on }
|
||||||
}
|
}
|
||||||
if (params(UseVM) || !params(BuildFPU).isEmpty) reg_mstatus.fs := new_mstatus.fs
|
if (usingVM || usingFPU) reg_mstatus.fs := new_mstatus.fs
|
||||||
if (!params(BuildRoCC).isEmpty) reg_mstatus.xs := new_mstatus.xs
|
if (usingRoCC) reg_mstatus.xs := new_mstatus.xs
|
||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.mip)) {
|
when (decoded_addr(CSRs.mip)) {
|
||||||
val new_mip = new MIP().fromBits(wdata)
|
val new_mip = new MIP().fromBits(wdata)
|
||||||
if (params(UseVM)) {
|
if (usingVM) {
|
||||||
reg_mip.ssip := new_mip.ssip
|
reg_mip.ssip := new_mip.ssip
|
||||||
reg_mip.stip := new_mip.stip
|
reg_mip.stip := new_mip.stip
|
||||||
}
|
}
|
||||||
@ -399,7 +401,7 @@ class CSRFile extends CoreModule
|
|||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.mie)) {
|
when (decoded_addr(CSRs.mie)) {
|
||||||
val new_mie = new MIP().fromBits(wdata)
|
val new_mie = new MIP().fromBits(wdata)
|
||||||
if (params(UseVM)) {
|
if (usingVM) {
|
||||||
reg_mie.ssip := new_mie.ssip
|
reg_mie.ssip := new_mie.ssip
|
||||||
reg_mie.stip := new_mie.stip
|
reg_mie.stip := new_mie.stip
|
||||||
}
|
}
|
||||||
@ -413,14 +415,14 @@ class CSRFile extends CoreModule
|
|||||||
when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
|
when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
|
||||||
when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
|
when (decoded_addr(CSRs.mcause)) { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
|
||||||
when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) }
|
when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) }
|
||||||
if (params(UsePerfCounters))
|
if (usingPerfCounters)
|
||||||
when (decoded_addr(CSRs.instretw)) { reg_instret := wdata }
|
when (decoded_addr(CSRs.instretw)) { reg_instret := wdata }
|
||||||
when (decoded_addr(CSRs.mtimecmp)) { reg_mtimecmp := wdata; reg_mip.mtip := false }
|
when (decoded_addr(CSRs.mtimecmp)) { reg_mtimecmp := wdata; reg_mip.mtip := false }
|
||||||
when (decoded_addr(CSRs.mtime)) { reg_time := wdata }
|
when (decoded_addr(CSRs.mtime)) { reg_time := wdata }
|
||||||
when (decoded_addr(CSRs.mfromhost)){ when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } }
|
when (decoded_addr(CSRs.mfromhost)){ when (reg_fromhost === UInt(0) || !host_csr_req_fire) { reg_fromhost := wdata } }
|
||||||
when (decoded_addr(CSRs.mtohost)) { when (reg_tohost === UInt(0) || host_pcr_req_fire) { reg_tohost := wdata } }
|
when (decoded_addr(CSRs.mtohost)) { when (reg_tohost === UInt(0) || host_csr_req_fire) { reg_tohost := wdata } }
|
||||||
when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) }
|
when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) }
|
||||||
if (params(UseVM)) {
|
if (usingVM) {
|
||||||
when (decoded_addr(CSRs.sstatus)) {
|
when (decoded_addr(CSRs.sstatus)) {
|
||||||
val new_sstatus = new SStatus().fromBits(wdata)
|
val new_sstatus = new SStatus().fromBits(wdata)
|
||||||
reg_mstatus.ie := new_sstatus.ie
|
reg_mstatus.ie := new_sstatus.ie
|
||||||
@ -428,7 +430,7 @@ class CSRFile extends CoreModule
|
|||||||
reg_mstatus.prv1 := Mux[UInt](new_sstatus.ps, PRV_S, PRV_U)
|
reg_mstatus.prv1 := Mux[UInt](new_sstatus.ps, PRV_S, PRV_U)
|
||||||
reg_mstatus.mprv := new_sstatus.mprv
|
reg_mstatus.mprv := new_sstatus.mprv
|
||||||
reg_mstatus.fs := new_sstatus.fs // even without an FPU
|
reg_mstatus.fs := new_sstatus.fs // even without an FPU
|
||||||
if (!params(BuildRoCC).isEmpty) reg_mstatus.xs := new_sstatus.xs
|
if (usingRoCC) reg_mstatus.xs := new_sstatus.xs
|
||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.sip)) {
|
when (decoded_addr(CSRs.sip)) {
|
||||||
val new_sip = new MIP().fromBits(wdata)
|
val new_sip = new MIP().fromBits(wdata)
|
||||||
|
@ -42,7 +42,7 @@ object ALU
|
|||||||
}
|
}
|
||||||
import ALU._
|
import ALU._
|
||||||
|
|
||||||
class ALUIO extends CoreBundle {
|
class ALUIO(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val dw = Bits(INPUT, SZ_DW)
|
val dw = Bits(INPUT, SZ_DW)
|
||||||
val fn = Bits(INPUT, SZ_ALU_FN)
|
val fn = Bits(INPUT, SZ_ALU_FN)
|
||||||
val in2 = UInt(INPUT, xLen)
|
val in2 = UInt(INPUT, xLen)
|
||||||
@ -51,8 +51,7 @@ class ALUIO extends CoreBundle {
|
|||||||
val adder_out = UInt(OUTPUT, xLen)
|
val adder_out = UInt(OUTPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ALU extends Module
|
class ALU(implicit p: Parameters) extends Module {
|
||||||
{
|
|
||||||
val io = new ALUIO
|
val io = new ALUIO
|
||||||
|
|
||||||
// ADD, SUB
|
// ADD, SUB
|
||||||
|
@ -353,8 +353,7 @@ class FPUFMAPipe(val latency: Int, sigWidth: Int, expWidth: Int) extends Module
|
|||||||
io.out := Pipe(valid, res, latency-1)
|
io.out := Pipe(valid, res, latency-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPU extends CoreModule
|
class FPU(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
{
|
|
||||||
val io = new FPUIO
|
val io = new FPUIO
|
||||||
|
|
||||||
val ex_reg_valid = Reg(next=io.valid, init=Bool(false))
|
val ex_reg_valid = Reg(next=io.valid, init=Bool(false))
|
||||||
@ -385,7 +384,7 @@ class FPU extends CoreModule
|
|||||||
val regfile = Mem(32, Bits(width = 65))
|
val regfile = Mem(32, Bits(width = 65))
|
||||||
when (load_wb) {
|
when (load_wb) {
|
||||||
regfile(load_wb_tag) := load_wb_data_recoded
|
regfile(load_wb_tag) := load_wb_data_recoded
|
||||||
if (EnableCommitLog) {
|
if (enableCommitLog) {
|
||||||
printf ("f%d p%d 0x%x\n", load_wb_tag, load_wb_tag + UInt(32),
|
printf ("f%d p%d 0x%x\n", load_wb_tag, load_wb_tag + UInt(32),
|
||||||
Mux(load_wb_single, load_wb_data(31,0), load_wb_data))
|
Mux(load_wb_single, load_wb_data(31,0), load_wb_data))
|
||||||
}
|
}
|
||||||
@ -415,11 +414,11 @@ class FPU extends CoreModule
|
|||||||
req.in3 := ex_rs3
|
req.in3 := ex_rs3
|
||||||
req.typ := ex_reg_inst(21,20)
|
req.typ := ex_reg_inst(21,20)
|
||||||
|
|
||||||
val sfma = Module(new FPUFMAPipe(params(SFMALatency), 23, 9))
|
val sfma = Module(new FPUFMAPipe(p(SFMALatency), 23, 9))
|
||||||
sfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && ex_ctrl.single
|
sfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && ex_ctrl.single
|
||||||
sfma.io.in.bits := req
|
sfma.io.in.bits := req
|
||||||
|
|
||||||
val dfma = Module(new FPUFMAPipe(params(DFMALatency), 52, 12))
|
val dfma = Module(new FPUFMAPipe(p(DFMALatency), 52, 12))
|
||||||
dfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && !ex_ctrl.single
|
dfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && !ex_ctrl.single
|
||||||
dfma.io.in.bits := req
|
dfma.io.in.bits := req
|
||||||
|
|
||||||
@ -488,7 +487,7 @@ class FPU extends CoreModule
|
|||||||
val wexc = Vec(pipes.map(_.res.exc))(wsrc)
|
val wexc = Vec(pipes.map(_.res.exc))(wsrc)
|
||||||
when (wen(0) || divSqrt_wen) {
|
when (wen(0) || divSqrt_wen) {
|
||||||
regfile(waddr) := wdata
|
regfile(waddr) := wdata
|
||||||
if (EnableCommitLog) {
|
if (enableCommitLog) {
|
||||||
val wdata_unrec_s = hardfloat.recodedFloatNToFloatN(wdata(64,0), 23, 9)
|
val wdata_unrec_s = hardfloat.recodedFloatNToFloatN(wdata(64,0), 23, 9)
|
||||||
val wdata_unrec_d = hardfloat.recodedFloatNToFloatN(wdata(64,0), 52, 12)
|
val wdata_unrec_d = hardfloat.recodedFloatNToFloatN(wdata(64,0), 52, 12)
|
||||||
val wb_single = (winfo(0) >> 5)(0)
|
val wb_single = (winfo(0) >> 5)(0)
|
||||||
@ -518,7 +517,7 @@ class FPU extends CoreModule
|
|||||||
|
|
||||||
divSqrt_wdata := 0
|
divSqrt_wdata := 0
|
||||||
divSqrt_flags := 0
|
divSqrt_flags := 0
|
||||||
if (params(FDivSqrt)) {
|
if (p(FDivSqrt)) {
|
||||||
val divSqrt_single = Reg(Bool())
|
val divSqrt_single = Reg(Bool())
|
||||||
val divSqrt_rm = Reg(Bits())
|
val divSqrt_rm = Reg(Bits())
|
||||||
val divSqrt_flags_double = Reg(Bits())
|
val divSqrt_flags_double = Reg(Bits())
|
||||||
|
122
rocket/src/main/scala/frontend.scala
Normal file
122
rocket/src/main/scala/frontend.scala
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package rocket
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import uncore._
|
||||||
|
import Util._
|
||||||
|
|
||||||
|
class FrontendReq(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
|
val pc = UInt(width = vaddrBitsExtended)
|
||||||
|
}
|
||||||
|
|
||||||
|
class FrontendResp(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
|
val pc = UInt(width = vaddrBitsExtended) // ID stage PC
|
||||||
|
val data = Vec(Bits(width = coreInstBits), fetchWidth)
|
||||||
|
val mask = Bits(width = fetchWidth)
|
||||||
|
val xcpt_if = Bool()
|
||||||
|
}
|
||||||
|
|
||||||
|
class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
|
val req = Valid(new FrontendReq)
|
||||||
|
val resp = Decoupled(new FrontendResp).flip
|
||||||
|
val btb_resp = Valid(new BTBResp).flip
|
||||||
|
val btb_update = Valid(new BTBUpdate)
|
||||||
|
val bht_update = Valid(new BHTUpdate)
|
||||||
|
val ras_update = Valid(new RASUpdate)
|
||||||
|
val invalidate = Bool(OUTPUT)
|
||||||
|
val npc = UInt(INPUT, width = vaddrBitsExtended)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Frontend(implicit p: Parameters) extends CoreModule()(p) with HasL1CacheParameters {
|
||||||
|
val io = new Bundle {
|
||||||
|
val cpu = new FrontendIO().flip
|
||||||
|
val ptw = new TLBPTWIO()
|
||||||
|
val mem = new ClientUncachedTileLinkIO
|
||||||
|
}
|
||||||
|
|
||||||
|
val btb = Module(new BTB)
|
||||||
|
val icache = Module(new ICache)
|
||||||
|
val tlb = Module(new TLB)
|
||||||
|
|
||||||
|
val s1_pc_ = Reg(UInt())
|
||||||
|
val s1_pc = ~(~s1_pc_ | (coreInstBytes-1)) // discard PC LSBS (this propagates down the pipeline)
|
||||||
|
val s1_same_block = Reg(Bool())
|
||||||
|
val s2_valid = Reg(init=Bool(true))
|
||||||
|
val s2_pc = Reg(init=UInt(START_ADDR))
|
||||||
|
val s2_btb_resp_valid = Reg(init=Bool(false))
|
||||||
|
val s2_btb_resp_bits = Reg(btb.io.resp.bits)
|
||||||
|
val s2_xcpt_if = Reg(init=Bool(false))
|
||||||
|
|
||||||
|
val msb = vaddrBits-1
|
||||||
|
val lsb = log2Up(fetchWidth*coreInstBytes)
|
||||||
|
val btbTarget = Cat(btb.io.resp.bits.target(msb), btb.io.resp.bits.target)
|
||||||
|
val ntpc_0 = s1_pc + UInt(coreInstBytes*fetchWidth)
|
||||||
|
val ntpc = Cat(s1_pc(msb) & ntpc_0(msb), ntpc_0(msb,lsb), Bits(0,lsb)) // unsure
|
||||||
|
val icmiss = s2_valid && !icache.io.resp.valid
|
||||||
|
val predicted_npc = Mux(btb.io.resp.bits.taken, btbTarget, ntpc)
|
||||||
|
val npc = Mux(icmiss, s2_pc, predicted_npc).toUInt
|
||||||
|
val s0_same_block = !icmiss && !io.cpu.req.valid && !btb.io.resp.bits.taken && ((ntpc & rowBytes) === (s1_pc & rowBytes))
|
||||||
|
|
||||||
|
val stall = io.cpu.resp.valid && !io.cpu.resp.ready
|
||||||
|
when (!stall) {
|
||||||
|
s1_same_block := s0_same_block && !tlb.io.resp.miss
|
||||||
|
s1_pc_ := npc
|
||||||
|
s2_valid := !icmiss
|
||||||
|
when (!icmiss) {
|
||||||
|
s2_pc := s1_pc
|
||||||
|
s2_btb_resp_valid := btb.io.resp.valid
|
||||||
|
when (btb.io.resp.valid) { s2_btb_resp_bits := btb.io.resp.bits }
|
||||||
|
s2_xcpt_if := tlb.io.resp.xcpt_if
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when (io.cpu.req.valid) {
|
||||||
|
s1_same_block := Bool(false)
|
||||||
|
s1_pc_ := io.cpu.req.bits.pc
|
||||||
|
s2_valid := Bool(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
btb.io.req.valid := !stall && !icmiss
|
||||||
|
btb.io.req.bits.addr := s1_pc
|
||||||
|
btb.io.btb_update := io.cpu.btb_update
|
||||||
|
btb.io.bht_update := io.cpu.bht_update
|
||||||
|
btb.io.ras_update := io.cpu.ras_update
|
||||||
|
btb.io.invalidate := io.cpu.invalidate || io.ptw.invalidate
|
||||||
|
|
||||||
|
io.ptw <> tlb.io.ptw
|
||||||
|
tlb.io.req.valid := !stall && !icmiss
|
||||||
|
tlb.io.req.bits.vpn := s1_pc >> pgIdxBits
|
||||||
|
tlb.io.req.bits.asid := UInt(0)
|
||||||
|
tlb.io.req.bits.passthrough := Bool(false)
|
||||||
|
tlb.io.req.bits.instruction := Bool(true)
|
||||||
|
tlb.io.req.bits.store := Bool(false)
|
||||||
|
|
||||||
|
io.mem <> icache.io.mem
|
||||||
|
icache.io.req.valid := !stall && !s0_same_block
|
||||||
|
icache.io.req.bits.idx := io.cpu.npc
|
||||||
|
icache.io.invalidate := io.cpu.invalidate
|
||||||
|
icache.io.req.bits.ppn := tlb.io.resp.ppn
|
||||||
|
icache.io.req.bits.kill := io.cpu.req.valid ||
|
||||||
|
tlb.io.resp.miss || tlb.io.resp.xcpt_if ||
|
||||||
|
icmiss || io.ptw.invalidate
|
||||||
|
icache.io.resp.ready := !stall && !s1_same_block
|
||||||
|
|
||||||
|
io.cpu.resp.valid := s2_valid && (s2_xcpt_if || icache.io.resp.valid)
|
||||||
|
io.cpu.resp.bits.pc := s2_pc
|
||||||
|
io.cpu.npc := Mux(io.cpu.req.valid, io.cpu.req.bits.pc, npc)
|
||||||
|
|
||||||
|
require(fetchWidth * coreInstBytes <= rowBytes)
|
||||||
|
val fetch_data =
|
||||||
|
if (fetchWidth * coreInstBytes == rowBytes) icache.io.resp.bits.datablock
|
||||||
|
else icache.io.resp.bits.datablock >> (s2_pc(log2Up(rowBytes)-1,log2Up(fetchWidth*coreInstBytes)) << log2Up(fetchWidth*coreInstBits))
|
||||||
|
|
||||||
|
for (i <- 0 until fetchWidth) {
|
||||||
|
io.cpu.resp.bits.data(i) := fetch_data(i*coreInstBits+coreInstBits-1, i*coreInstBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
val all_ones = UInt((1 << (fetchWidth+1))-1)
|
||||||
|
val msk_pc = if (fetchWidth == 1) all_ones else all_ones << s2_pc(log2Up(fetchWidth) -1+2,2)
|
||||||
|
io.cpu.resp.bits.mask := Mux(s2_btb_resp_valid, msk_pc & s2_btb_resp_bits.mask, msk_pc)
|
||||||
|
io.cpu.resp.bits.xcpt_if := s2_xcpt_if
|
||||||
|
|
||||||
|
io.cpu.btb_resp.valid := s2_btb_resp_valid
|
||||||
|
io.cpu.btb_resp.bits := s2_btb_resp_bits
|
||||||
|
}
|
@ -4,148 +4,25 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
abstract trait L1CacheParameters extends CacheParameters with CoreParameters {
|
trait HasL1CacheParameters extends HasCacheParameters with HasCoreParameters {
|
||||||
val outerDataBeats = params(TLDataBeats)
|
val outerDataBeats = p(TLDataBeats)
|
||||||
val outerDataBits = params(TLDataBits)
|
val outerDataBits = p(TLDataBits)
|
||||||
val refillCyclesPerBeat = outerDataBits/rowBits
|
val refillCyclesPerBeat = outerDataBits/rowBits
|
||||||
val refillCycles = refillCyclesPerBeat*outerDataBeats
|
val refillCycles = refillCyclesPerBeat*outerDataBeats
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract trait FrontendParameters extends L1CacheParameters
|
class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
abstract class FrontendBundle extends Bundle with FrontendParameters
|
|
||||||
abstract class FrontendModule extends Module with FrontendParameters
|
|
||||||
|
|
||||||
class FrontendReq extends CoreBundle {
|
|
||||||
val pc = UInt(width = vaddrBitsExtended)
|
|
||||||
}
|
|
||||||
|
|
||||||
class FrontendResp extends CoreBundle {
|
|
||||||
val pc = UInt(width = vaddrBitsExtended) // ID stage PC
|
|
||||||
val data = Vec(Bits(width = coreInstBits), coreFetchWidth)
|
|
||||||
val mask = Bits(width = coreFetchWidth)
|
|
||||||
val xcpt_if = Bool()
|
|
||||||
}
|
|
||||||
|
|
||||||
class CPUFrontendIO extends CoreBundle {
|
|
||||||
val req = Valid(new FrontendReq)
|
|
||||||
val resp = Decoupled(new FrontendResp).flip
|
|
||||||
val btb_resp = Valid(new BTBResp).flip
|
|
||||||
val btb_update = Valid(new BTBUpdate)
|
|
||||||
val bht_update = Valid(new BHTUpdate)
|
|
||||||
val ras_update = Valid(new RASUpdate)
|
|
||||||
val invalidate = Bool(OUTPUT)
|
|
||||||
val npc = UInt(INPUT, width = vaddrBitsExtended)
|
|
||||||
}
|
|
||||||
|
|
||||||
class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule
|
|
||||||
{
|
|
||||||
val io = new Bundle {
|
|
||||||
val cpu = new CPUFrontendIO().flip
|
|
||||||
val ptw = new TLBPTWIO()
|
|
||||||
val mem = new ClientUncachedTileLinkIO
|
|
||||||
}
|
|
||||||
|
|
||||||
val btb = Module(new BTB(btb_updates_out_of_order))
|
|
||||||
val icache = Module(new ICache)
|
|
||||||
val tlb = Module(new TLB)
|
|
||||||
|
|
||||||
val s1_pc_ = Reg(UInt())
|
|
||||||
val s1_pc = ~(~s1_pc_ | (coreInstBytes-1)) // discard PC LSBS (this propagates down the pipeline)
|
|
||||||
val s1_same_block = Reg(Bool())
|
|
||||||
val s2_valid = Reg(init=Bool(true))
|
|
||||||
val s2_pc = Reg(init=UInt(START_ADDR))
|
|
||||||
val s2_btb_resp_valid = Reg(init=Bool(false))
|
|
||||||
val s2_btb_resp_bits = Reg(btb.io.resp.bits)
|
|
||||||
val s2_xcpt_if = Reg(init=Bool(false))
|
|
||||||
|
|
||||||
val msb = vaddrBits-1
|
|
||||||
val lsb = log2Up(coreFetchWidth*coreInstBytes)
|
|
||||||
val btbTarget = Cat(btb.io.resp.bits.target(msb), btb.io.resp.bits.target)
|
|
||||||
val ntpc_0 = s1_pc + UInt(coreInstBytes*coreFetchWidth)
|
|
||||||
val ntpc = Cat(s1_pc(msb) & ntpc_0(msb), ntpc_0(msb,lsb), Bits(0,lsb)) // unsure
|
|
||||||
val icmiss = s2_valid && !icache.io.resp.valid
|
|
||||||
val predicted_npc = Mux(btb.io.resp.bits.taken, btbTarget, ntpc)
|
|
||||||
val npc = Mux(icmiss, s2_pc, predicted_npc).toUInt
|
|
||||||
val s0_same_block = !icmiss && !io.cpu.req.valid && !btb.io.resp.bits.taken && ((ntpc & rowBytes) === (s1_pc & rowBytes))
|
|
||||||
|
|
||||||
val stall = io.cpu.resp.valid && !io.cpu.resp.ready
|
|
||||||
when (!stall) {
|
|
||||||
s1_same_block := s0_same_block && !tlb.io.resp.miss
|
|
||||||
s1_pc_ := npc
|
|
||||||
s2_valid := !icmiss
|
|
||||||
when (!icmiss) {
|
|
||||||
s2_pc := s1_pc
|
|
||||||
s2_btb_resp_valid := btb.io.resp.valid
|
|
||||||
when (btb.io.resp.valid) { s2_btb_resp_bits := btb.io.resp.bits }
|
|
||||||
s2_xcpt_if := tlb.io.resp.xcpt_if
|
|
||||||
}
|
|
||||||
}
|
|
||||||
when (io.cpu.req.valid) {
|
|
||||||
s1_same_block := Bool(false)
|
|
||||||
s1_pc_ := io.cpu.req.bits.pc
|
|
||||||
s2_valid := Bool(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
btb.io.req.valid := !stall && !icmiss
|
|
||||||
btb.io.req.bits.addr := s1_pc
|
|
||||||
btb.io.btb_update := io.cpu.btb_update
|
|
||||||
btb.io.bht_update := io.cpu.bht_update
|
|
||||||
btb.io.ras_update := io.cpu.ras_update
|
|
||||||
btb.io.invalidate := io.cpu.invalidate || io.ptw.invalidate
|
|
||||||
|
|
||||||
io.ptw <> tlb.io.ptw
|
|
||||||
tlb.io.req.valid := !stall && !icmiss
|
|
||||||
tlb.io.req.bits.vpn := s1_pc >> pgIdxBits
|
|
||||||
tlb.io.req.bits.asid := UInt(0)
|
|
||||||
tlb.io.req.bits.passthrough := Bool(false)
|
|
||||||
tlb.io.req.bits.instruction := Bool(true)
|
|
||||||
tlb.io.req.bits.store := Bool(false)
|
|
||||||
|
|
||||||
io.mem <> icache.io.mem
|
|
||||||
icache.io.req.valid := !stall && !s0_same_block
|
|
||||||
icache.io.req.bits.idx := io.cpu.npc
|
|
||||||
icache.io.invalidate := io.cpu.invalidate
|
|
||||||
icache.io.req.bits.ppn := tlb.io.resp.ppn
|
|
||||||
icache.io.req.bits.kill := io.cpu.req.valid ||
|
|
||||||
tlb.io.resp.miss || tlb.io.resp.xcpt_if ||
|
|
||||||
icmiss || io.ptw.invalidate
|
|
||||||
icache.io.resp.ready := !stall && !s1_same_block
|
|
||||||
|
|
||||||
io.cpu.resp.valid := s2_valid && (s2_xcpt_if || icache.io.resp.valid)
|
|
||||||
io.cpu.resp.bits.pc := s2_pc
|
|
||||||
io.cpu.npc := Mux(io.cpu.req.valid, io.cpu.req.bits.pc, npc)
|
|
||||||
|
|
||||||
require(coreFetchWidth * coreInstBytes <= rowBytes)
|
|
||||||
val fetch_data =
|
|
||||||
if (coreFetchWidth * coreInstBytes == rowBytes) icache.io.resp.bits.datablock
|
|
||||||
else icache.io.resp.bits.datablock >> (s2_pc(log2Up(rowBytes)-1,log2Up(coreFetchWidth*coreInstBytes)) << log2Up(coreFetchWidth*coreInstBits))
|
|
||||||
|
|
||||||
for (i <- 0 until coreFetchWidth) {
|
|
||||||
io.cpu.resp.bits.data(i) := fetch_data(i*coreInstBits+coreInstBits-1, i*coreInstBits)
|
|
||||||
}
|
|
||||||
|
|
||||||
val all_ones = UInt((1 << (coreFetchWidth+1))-1)
|
|
||||||
val msk_pc = if (coreFetchWidth == 1) all_ones else all_ones << s2_pc(log2Up(coreFetchWidth) -1+2,2)
|
|
||||||
io.cpu.resp.bits.mask := Mux(s2_btb_resp_valid, msk_pc & s2_btb_resp_bits.mask, msk_pc)
|
|
||||||
io.cpu.resp.bits.xcpt_if := s2_xcpt_if
|
|
||||||
|
|
||||||
io.cpu.btb_resp.valid := s2_btb_resp_valid
|
|
||||||
io.cpu.btb_resp.bits := s2_btb_resp_bits
|
|
||||||
}
|
|
||||||
|
|
||||||
class ICacheReq extends FrontendBundle {
|
|
||||||
val idx = UInt(width = pgIdxBits)
|
val idx = UInt(width = pgIdxBits)
|
||||||
val ppn = UInt(width = ppnBits) // delayed one cycle
|
val ppn = UInt(width = ppnBits) // delayed one cycle
|
||||||
val kill = Bool() // delayed one cycle
|
val kill = Bool() // delayed one cycle
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICacheResp extends FrontendBundle {
|
class ICacheResp(implicit p: Parameters) extends CoreBundle()(p) with HasL1CacheParameters {
|
||||||
val data = Bits(width = coreInstBits)
|
val data = Bits(width = coreInstBits)
|
||||||
val datablock = Bits(width = rowBits)
|
val datablock = Bits(width = rowBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICache extends FrontendModule
|
class ICache(implicit p: Parameters) extends CoreModule()(p) with HasL1CacheParameters {
|
||||||
{
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Valid(new ICacheReq).flip
|
val req = Valid(new ICacheReq).flip
|
||||||
val resp = Decoupled(new ICacheResp)
|
val resp = Decoupled(new ICacheResp)
|
||||||
|
@ -6,29 +6,35 @@ import Chisel._
|
|||||||
import ALU._
|
import ALU._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class MultiplierReq extends CoreBundle {
|
class MultiplierReq(dataBits: Int, tagBits: Int) extends Bundle {
|
||||||
val fn = Bits(width = SZ_ALU_FN)
|
val fn = Bits(width = SZ_ALU_FN)
|
||||||
val dw = Bits(width = SZ_DW)
|
val dw = Bits(width = SZ_DW)
|
||||||
val in1 = Bits(width = xLen)
|
val in1 = Bits(width = dataBits)
|
||||||
val in2 = Bits(width = xLen)
|
val in2 = Bits(width = dataBits)
|
||||||
val tag = UInt(width = log2Up(params(NMultXpr)))
|
val tag = UInt(width = tagBits)
|
||||||
|
override def cloneType = new MultiplierReq(dataBits, tagBits).asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplierResp extends CoreBundle {
|
class MultiplierResp(dataBits: Int, tagBits: Int) extends Bundle {
|
||||||
val data = Bits(width = xLen)
|
val data = Bits(width = dataBits)
|
||||||
val tag = UInt(width = log2Up(params(NMultXpr)))
|
val tag = UInt(width = tagBits)
|
||||||
|
override def cloneType = new MultiplierResp(dataBits, tagBits).asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplierIO extends Bundle {
|
class MultiplierIO(dataBits: Int, tagBits: Int) extends Bundle {
|
||||||
val req = Decoupled(new MultiplierReq).flip
|
val req = Decoupled(new MultiplierReq(dataBits, tagBits)).flip
|
||||||
val kill = Bool(INPUT)
|
val kill = Bool(INPUT)
|
||||||
val resp = Decoupled(new MultiplierResp)
|
val resp = Decoupled(new MultiplierResp(dataBits, tagBits))
|
||||||
}
|
}
|
||||||
|
|
||||||
class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false) extends Module {
|
class MulDiv(
|
||||||
val io = new MultiplierIO
|
width: Int,
|
||||||
|
nXpr: Int = 32,
|
||||||
|
unroll: Int = 1,
|
||||||
|
earlyOut: Boolean = false) extends Module {
|
||||||
|
val io = new MultiplierIO(width, log2Up(nXpr))
|
||||||
val w = io.req.bits.in1.getWidth
|
val w = io.req.bits.in1.getWidth
|
||||||
val mulw = (w+mulUnroll-1)/mulUnroll*mulUnroll
|
val mulw = (w+unroll-1)/unroll*unroll
|
||||||
|
|
||||||
val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(UInt(), 6)
|
val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(UInt(), 6)
|
||||||
val state = Reg(init=s_ready)
|
val state = Reg(init=s_ready)
|
||||||
@ -87,18 +93,18 @@ class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false) extends Module {
|
|||||||
val mplier = mulReg(mulw-1,0)
|
val mplier = mulReg(mulw-1,0)
|
||||||
val accum = mulReg(2*mulw,mulw).toSInt
|
val accum = mulReg(2*mulw,mulw).toSInt
|
||||||
val mpcand = divisor.toSInt
|
val mpcand = divisor.toSInt
|
||||||
val prod = mplier(mulUnroll-1,0) * mpcand + accum
|
val prod = mplier(unroll-1,0) * mpcand + accum
|
||||||
val nextMulReg = Cat(prod, mplier(mulw-1,mulUnroll)).toUInt
|
val nextMulReg = Cat(prod, mplier(mulw-1,unroll)).toUInt
|
||||||
|
|
||||||
val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * mulUnroll)(log2Up(mulw)-1,0))(mulw-1,0)
|
val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * unroll)(log2Up(mulw)-1,0))(mulw-1,0)
|
||||||
val eOut = Bool(earlyOut) && count != mulw/mulUnroll-1 && count != 0 &&
|
val eOut = Bool(earlyOut) && count != mulw/unroll-1 && count != 0 &&
|
||||||
!isHi && (mplier & ~eOutMask) === UInt(0)
|
!isHi && (mplier & ~eOutMask) === UInt(0)
|
||||||
val eOutRes = (mulReg >> (mulw - count * mulUnroll)(log2Up(mulw)-1,0))
|
val eOutRes = (mulReg >> (mulw - count * unroll)(log2Up(mulw)-1,0))
|
||||||
val nextMulReg1 = Cat(nextMulReg(2*mulw,mulw), Mux(eOut, eOutRes, nextMulReg)(mulw-1,0))
|
val nextMulReg1 = Cat(nextMulReg(2*mulw,mulw), Mux(eOut, eOutRes, nextMulReg)(mulw-1,0))
|
||||||
remainder := Cat(nextMulReg1 >> w, Bool(false), nextMulReg1(w-1,0))
|
remainder := Cat(nextMulReg1 >> w, Bool(false), nextMulReg1(w-1,0))
|
||||||
|
|
||||||
count := count + 1
|
count := count + 1
|
||||||
when (eOut || count === mulw/mulUnroll-1) {
|
when (eOut || count === mulw/unroll-1) {
|
||||||
state := Mux(isHi, s_move_rem, s_done)
|
state := Mux(isHi, s_move_rem, s_done)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,11 @@ case object NMSHRs extends Field[Int]
|
|||||||
case object NIOMSHRs extends Field[Int]
|
case object NIOMSHRs extends Field[Int]
|
||||||
case object LRSCCycles extends Field[Int]
|
case object LRSCCycles extends Field[Int]
|
||||||
|
|
||||||
abstract trait L1HellaCacheParameters extends L1CacheParameters {
|
trait HasL1HellaCacheParameters extends HasL1CacheParameters {
|
||||||
val wordBits = params(WordBits)
|
val wordBits = p(WordBits)
|
||||||
val wordBytes = wordBits/8
|
val wordBytes = wordBits/8
|
||||||
val wordOffBits = log2Up(wordBytes)
|
val wordOffBits = log2Up(wordBytes)
|
||||||
val beatBytes = params(CacheBlockBytes) / params(TLDataBeats)
|
val beatBytes = p(CacheBlockBytes) / p(TLDataBeats)
|
||||||
val beatWords = beatBytes / wordBytes
|
val beatWords = beatBytes / wordBytes
|
||||||
val beatOffBits = log2Up(beatBytes)
|
val beatOffBits = log2Up(beatBytes)
|
||||||
val idxMSB = untagBits-1
|
val idxMSB = untagBits-1
|
||||||
@ -29,43 +29,48 @@ abstract trait L1HellaCacheParameters extends L1CacheParameters {
|
|||||||
val doNarrowRead = coreDataBits * nWays % rowBits == 0
|
val doNarrowRead = coreDataBits * nWays % rowBits == 0
|
||||||
val encDataBits = code.width(coreDataBits)
|
val encDataBits = code.width(coreDataBits)
|
||||||
val encRowBits = encDataBits*rowWords
|
val encRowBits = encDataBits*rowWords
|
||||||
val sdqDepth = params(StoreDataQueueDepth)
|
val sdqDepth = p(StoreDataQueueDepth)
|
||||||
val nMSHRs = params(NMSHRs)
|
val nMSHRs = p(NMSHRs)
|
||||||
val nIOMSHRs = params(NIOMSHRs)
|
val nIOMSHRs = p(NIOMSHRs)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters
|
abstract class L1HellaCacheModule(implicit val p: Parameters) extends Module
|
||||||
abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters
|
with HasL1HellaCacheParameters
|
||||||
|
abstract class L1HellaCacheBundle(implicit val p: Parameters) extends junctions.ParameterizedBundle()(p)
|
||||||
|
with HasL1HellaCacheParameters
|
||||||
|
|
||||||
trait HasCoreMemOp extends CoreBundle {
|
trait HasCoreMemOp extends HasCoreParameters {
|
||||||
val addr = UInt(width = coreMaxAddrBits)
|
val addr = UInt(width = coreMaxAddrBits)
|
||||||
val tag = Bits(width = coreDCacheReqTagBits)
|
val tag = Bits(width = coreDCacheReqTagBits)
|
||||||
val cmd = Bits(width = M_SZ)
|
val cmd = Bits(width = M_SZ)
|
||||||
val typ = Bits(width = MT_SZ)
|
val typ = Bits(width = MT_SZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasCoreData extends CoreBundle {
|
trait HasCoreData extends HasCoreParameters {
|
||||||
val data = Bits(width = coreDataBits)
|
val data = Bits(width = coreDataBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasSDQId extends CoreBundle with L1HellaCacheParameters {
|
trait HasSDQId extends HasL1HellaCacheParameters {
|
||||||
val sdq_id = UInt(width = log2Up(sdqDepth))
|
val sdq_id = UInt(width = log2Up(sdqDepth))
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasMissInfo extends CoreBundle with L1HellaCacheParameters {
|
trait HasMissInfo extends HasL1HellaCacheParameters {
|
||||||
val tag_match = Bool()
|
val tag_match = Bool()
|
||||||
val old_meta = new L1Metadata
|
val old_meta = new L1Metadata
|
||||||
val way_en = Bits(width = nWays)
|
val way_en = Bits(width = nWays)
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheReqInternal extends HasCoreMemOp {
|
class HellaCacheReqInternal(implicit p: Parameters) extends L1HellaCacheBundle()(p)
|
||||||
|
with HasCoreMemOp {
|
||||||
val kill = Bool()
|
val kill = Bool()
|
||||||
val phys = Bool()
|
val phys = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheReq extends HellaCacheReqInternal with HasCoreData
|
class HellaCacheReq(implicit p: Parameters) extends HellaCacheReqInternal()(p) with HasCoreData
|
||||||
|
|
||||||
class HellaCacheResp extends HasCoreMemOp with HasCoreData {
|
class HellaCacheResp(implicit p: Parameters) extends L1HellaCacheBundle()(p)
|
||||||
|
with HasCoreMemOp
|
||||||
|
with HasCoreData {
|
||||||
val nack = Bool() // comes 2 cycles after req.fire
|
val nack = Bool() // comes 2 cycles after req.fire
|
||||||
val replay = Bool()
|
val replay = Bool()
|
||||||
val has_data = Bool()
|
val has_data = Bool()
|
||||||
@ -84,7 +89,7 @@ class HellaCacheExceptions extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// interface between D$ and processor/DTLB
|
// interface between D$ and processor/DTLB
|
||||||
class HellaCacheIO extends CoreBundle {
|
class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val req = Decoupled(new HellaCacheReq)
|
val req = Decoupled(new HellaCacheReq)
|
||||||
val resp = Valid(new HellaCacheResp).flip
|
val resp = Valid(new HellaCacheResp).flip
|
||||||
val replay_next = Valid(Bits(width = coreDCacheReqTagBits)).flip
|
val replay_next = Valid(Bits(width = coreDCacheReqTagBits)).flip
|
||||||
@ -93,50 +98,51 @@ class HellaCacheIO extends CoreBundle {
|
|||||||
val ordered = Bool(INPUT)
|
val ordered = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class L1DataReadReq extends L1HellaCacheBundle {
|
class L1DataReadReq(implicit p: Parameters) extends L1HellaCacheBundle()(p) {
|
||||||
val way_en = Bits(width = nWays)
|
val way_en = Bits(width = nWays)
|
||||||
val addr = Bits(width = untagBits)
|
val addr = Bits(width = untagBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class L1DataWriteReq extends L1DataReadReq {
|
class L1DataWriteReq(implicit p: Parameters) extends L1DataReadReq()(p) {
|
||||||
val wmask = Bits(width = rowWords)
|
val wmask = Bits(width = rowWords)
|
||||||
val data = Bits(width = encRowBits)
|
val data = Bits(width = encRowBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class L1RefillReq extends L1DataReadReq
|
class L1RefillReq(implicit p: Parameters) extends L1DataReadReq()(p)
|
||||||
|
|
||||||
class L1MetaReadReq extends MetaReadReq {
|
class L1MetaReadReq(implicit p: Parameters) extends MetaReadReq {
|
||||||
val tag = Bits(width = tagBits)
|
val tag = Bits(width = tagBits)
|
||||||
|
override def cloneType = new L1MetaReadReq()(p).asInstanceOf[this.type] //TODO remove
|
||||||
}
|
}
|
||||||
|
|
||||||
class L1MetaWriteReq extends
|
class L1MetaWriteReq(implicit p: Parameters) extends
|
||||||
MetaWriteReq[L1Metadata](new L1Metadata)
|
MetaWriteReq[L1Metadata](new L1Metadata)
|
||||||
|
|
||||||
object L1Metadata {
|
object L1Metadata {
|
||||||
def apply(tag: Bits, coh: ClientMetadata) = {
|
def apply(tag: Bits, coh: ClientMetadata)(implicit p: Parameters) = {
|
||||||
val meta = Wire(new L1Metadata)
|
val meta = Wire(new L1Metadata)
|
||||||
meta.tag := tag
|
meta.tag := tag
|
||||||
meta.coh := coh
|
meta.coh := coh
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class L1Metadata extends Metadata with L1HellaCacheParameters {
|
class L1Metadata(implicit p: Parameters) extends Metadata()(p) with HasL1HellaCacheParameters {
|
||||||
val coh = new ClientMetadata
|
val coh = new ClientMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
class Replay extends HellaCacheReqInternal with HasCoreData
|
class Replay(implicit p: Parameters) extends HellaCacheReqInternal()(p) with HasCoreData
|
||||||
class ReplayInternal extends HellaCacheReqInternal with HasSDQId
|
class ReplayInternal(implicit p: Parameters) extends HellaCacheReqInternal()(p) with HasSDQId
|
||||||
|
|
||||||
class MSHRReq extends Replay with HasMissInfo
|
class MSHRReq(implicit p: Parameters) extends Replay()(p) with HasMissInfo
|
||||||
class MSHRReqInternal extends ReplayInternal with HasMissInfo
|
class MSHRReqInternal(implicit p: Parameters) extends ReplayInternal()(p) with HasMissInfo
|
||||||
|
|
||||||
class ProbeInternal extends Probe with HasClientTransactionId
|
class ProbeInternal(implicit p: Parameters) extends Probe()(p) with HasClientTransactionId
|
||||||
|
|
||||||
class WritebackReq extends Release with CacheParameters {
|
class WritebackReq(implicit p: Parameters) extends Release()(p) with HasCacheParameters {
|
||||||
val way_en = Bits(width = nWays)
|
val way_en = Bits(width = nWays)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IOMSHR(id: Int) extends L1HellaCacheModule {
|
class IOMSHR(id: Int)(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new HellaCacheReq).flip
|
val req = Decoupled(new HellaCacheReq).flip
|
||||||
val acquire = Decoupled(new Acquire)
|
val acquire = Decoupled(new Acquire)
|
||||||
@ -213,7 +219,7 @@ class IOMSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHR(id: Int) extends L1HellaCacheModule {
|
class MSHR(id: Int)(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req_pri_val = Bool(INPUT)
|
val req_pri_val = Bool(INPUT)
|
||||||
val req_pri_rdy = Bool(OUTPUT)
|
val req_pri_rdy = Bool(OUTPUT)
|
||||||
@ -256,7 +262,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
val (refill_cnt, refill_count_done) = Counter(io.mem_grant.valid && gnt_multi_data, refillCycles) // TODO: Zero width?
|
val (refill_cnt, refill_count_done) = Counter(io.mem_grant.valid && gnt_multi_data, refillCycles) // TODO: Zero width?
|
||||||
val refill_done = io.mem_grant.valid && (!gnt_multi_data || refill_count_done)
|
val refill_done = io.mem_grant.valid && (!gnt_multi_data || refill_count_done)
|
||||||
|
|
||||||
val rpq = Module(new Queue(new ReplayInternal, params(ReplayQueueDepth)))
|
val rpq = Module(new Queue(new ReplayInternal, p(ReplayQueueDepth)))
|
||||||
rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(io.req_bits.cmd)
|
rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(io.req_bits.cmd)
|
||||||
rpq.io.enq.bits := io.req_bits
|
rpq.io.enq.bits := io.req_bits
|
||||||
rpq.io.deq.ready := io.replay.ready && state === s_drain_rpq || state === s_invalid
|
rpq.io.deq.ready := io.replay.ready && state === s_drain_rpq || state === s_invalid
|
||||||
@ -362,7 +368,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHRFile extends L1HellaCacheModule {
|
class MSHRFile(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new MSHRReq).flip
|
val req = Decoupled(new MSHRReq).flip
|
||||||
val resp = Decoupled(new HellaCacheResp)
|
val resp = Decoupled(new HellaCacheResp)
|
||||||
@ -498,7 +504,7 @@ class MSHRFile extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WritebackUnit extends L1HellaCacheModule {
|
class WritebackUnit(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new WritebackReq).flip
|
val req = Decoupled(new WritebackReq).flip
|
||||||
val meta_read = Decoupled(new L1MetaReadReq)
|
val meta_read = Decoupled(new L1MetaReadReq)
|
||||||
@ -578,7 +584,7 @@ class WritebackUnit extends L1HellaCacheModule {
|
|||||||
} else { io.data_resp })
|
} else { io.data_resp })
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProbeUnit extends L1HellaCacheModule {
|
class ProbeUnit(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new ProbeInternal).flip
|
val req = Decoupled(new ProbeInternal).flip
|
||||||
val rep = Decoupled(new Release)
|
val rep = Decoupled(new Release)
|
||||||
@ -653,7 +659,7 @@ class ProbeUnit extends L1HellaCacheModule {
|
|||||||
io.wb_req.bits.way_en := way_en
|
io.wb_req.bits.way_en := way_en
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataArray extends L1HellaCacheModule {
|
class DataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val read = Decoupled(new L1DataReadReq).flip
|
val read = Decoupled(new L1DataReadReq).flip
|
||||||
val write = Decoupled(new L1DataWriteReq).flip
|
val write = Decoupled(new L1DataWriteReq).flip
|
||||||
@ -700,18 +706,18 @@ class DataArray extends L1HellaCacheModule {
|
|||||||
io.write.ready := Bool(true)
|
io.write.ready := Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCache extends L1HellaCacheModule {
|
class HellaCache(implicit p: Parameters) extends L1HellaCacheModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
val mem = new ClientTileLinkIO
|
val mem = new ClientTileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
require(params(LRSCCycles) >= 32) // ISA requires 16-insn LRSC sequences to succeed
|
require(p(LRSCCycles) >= 32) // ISA requires 16-insn LRSC sequences to succeed
|
||||||
require(isPow2(nSets))
|
require(isPow2(nSets))
|
||||||
require(isPow2(nWays)) // TODO: relax this
|
require(isPow2(nWays)) // TODO: relax this
|
||||||
require(params(RowBits) <= params(TLDataBits))
|
require(p(RowBits) <= p(TLDataBits))
|
||||||
require(paddrBits-blockOffBits == params(TLBlockAddrBits) )
|
require(paddrBits-blockOffBits == p(TLBlockAddrBits) )
|
||||||
require(untagBits <= pgIdxBits)
|
require(untagBits <= pgIdxBits)
|
||||||
|
|
||||||
val wb = Module(new WritebackUnit)
|
val wb = Module(new WritebackUnit)
|
||||||
@ -855,7 +861,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
when (lrsc_valid) { lrsc_count := lrsc_count - 1 }
|
when (lrsc_valid) { lrsc_count := lrsc_count - 1 }
|
||||||
when (s2_valid_masked && s2_hit || s2_replay) {
|
when (s2_valid_masked && s2_hit || s2_replay) {
|
||||||
when (s2_lr) {
|
when (s2_lr) {
|
||||||
when (!lrsc_valid) { lrsc_count := params(LRSCCycles)-1 }
|
when (!lrsc_valid) { lrsc_count := p(LRSCCycles)-1 }
|
||||||
lrsc_addr := s2_req.addr >> blockOffBits
|
lrsc_addr := s2_req.addr >> blockOffBits
|
||||||
}
|
}
|
||||||
when (s2_sc) {
|
when (s2_sc) {
|
||||||
@ -899,7 +905,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
writeArb.io.in(0).bits.way_en := s3_way
|
writeArb.io.in(0).bits.way_en := s3_way
|
||||||
|
|
||||||
// replacement policy
|
// replacement policy
|
||||||
val replacer = params(Replacer)()
|
val replacer = p(Replacer)()
|
||||||
val s1_replaced_way_en = UIntToOH(replacer.way)
|
val s1_replaced_way_en = UIntToOH(replacer.way)
|
||||||
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
|
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
|
||||||
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)
|
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq)
|
||||||
@ -1039,7 +1045,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exposes a sane decoupled request interface
|
// exposes a sane decoupled request interface
|
||||||
class SimpleHellaCacheIF extends Module
|
class SimpleHellaCacheIF(implicit p: Parameters) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = new HellaCacheIO().flip
|
val requestor = new HellaCacheIO().flip
|
||||||
|
@ -6,32 +6,32 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class PTWReq extends CoreBundle {
|
class PTWReq(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val addr = UInt(width = vpnBits)
|
val addr = UInt(width = vpnBits)
|
||||||
val prv = Bits(width = 2)
|
val prv = Bits(width = 2)
|
||||||
val store = Bool()
|
val store = Bool()
|
||||||
val fetch = Bool()
|
val fetch = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTWResp extends CoreBundle {
|
class PTWResp(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val error = Bool()
|
val error = Bool()
|
||||||
val pte = new PTE
|
val pte = new PTE
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBPTWIO extends CoreBundle {
|
class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val req = Decoupled(new PTWReq)
|
val req = Decoupled(new PTWReq)
|
||||||
val resp = Valid(new PTWResp).flip
|
val resp = Valid(new PTWResp).flip
|
||||||
val status = new MStatus().asInput
|
val status = new MStatus().asInput
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DatapathPTWIO extends CoreBundle {
|
class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val ptbr = UInt(INPUT, paddrBits)
|
val ptbr = UInt(INPUT, paddrBits)
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val status = new MStatus().asInput
|
val status = new MStatus().asInput
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTE extends CoreBundle {
|
class PTE(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val ppn = Bits(width = ppnBits)
|
val ppn = Bits(width = ppnBits)
|
||||||
val reserved_for_software = Bits(width = 3)
|
val reserved_for_software = Bits(width = 3)
|
||||||
val d = Bool()
|
val d = Bool()
|
||||||
@ -51,8 +51,7 @@ class PTE extends CoreBundle {
|
|||||||
Mux(prv(0), Mux(fetch, sx(), Mux(store, sw(), sr())), Mux(fetch, ux(), Mux(store, uw(), ur())))
|
Mux(prv(0), Mux(fetch, sx(), Mux(store, sw(), sr())), Mux(fetch, ux(), Mux(store, uw(), ur())))
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTW(n: Int) extends CoreModule
|
class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
{
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = Vec(new TLBPTWIO, n).flip
|
val requestor = Vec(new TLBPTWIO, n).flip
|
||||||
val mem = new HellaCacheIO
|
val mem = new HellaCacheIO
|
||||||
|
@ -20,24 +20,21 @@ class RoCCInstruction extends Bundle
|
|||||||
val opcode = Bits(width = 7)
|
val opcode = Bits(width = 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCCommand extends CoreBundle
|
class RoCCCommand(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
{
|
|
||||||
val inst = new RoCCInstruction
|
val inst = new RoCCInstruction
|
||||||
val rs1 = Bits(width = xLen)
|
val rs1 = Bits(width = xLen)
|
||||||
val rs2 = Bits(width = xLen)
|
val rs2 = Bits(width = xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCResponse extends CoreBundle
|
class RoCCResponse(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
{
|
|
||||||
val rd = Bits(width = 5)
|
val rd = Bits(width = 5)
|
||||||
val data = Bits(width = xLen)
|
val data = Bits(width = xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCInterface extends Bundle
|
class RoCCInterface(implicit p: Parameters) extends Bundle {
|
||||||
{
|
|
||||||
val cmd = Decoupled(new RoCCCommand).flip
|
val cmd = Decoupled(new RoCCCommand).flip
|
||||||
val resp = Decoupled(new RoCCResponse)
|
val resp = Decoupled(new RoCCResponse)
|
||||||
val mem = new HellaCacheIO
|
val mem = new HellaCacheIO()(p.alterPartial({ case CacheName => "L1D" }))
|
||||||
val busy = Bool(OUTPUT)
|
val busy = Bool(OUTPUT)
|
||||||
val s = Bool(INPUT)
|
val s = Bool(INPUT)
|
||||||
val interrupt = Bool(OUTPUT)
|
val interrupt = Bool(OUTPUT)
|
||||||
@ -51,15 +48,12 @@ class RoCCInterface extends Bundle
|
|||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RoCC extends CoreModule
|
abstract class RoCC(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
{
|
|
||||||
val io = new RoCCInterface
|
val io = new RoCCInterface
|
||||||
io.mem.req.bits.phys := Bool(true) // don't perform address translation
|
io.mem.req.bits.phys := Bool(true) // don't perform address translation
|
||||||
}
|
}
|
||||||
|
|
||||||
class AccumulatorExample extends RoCC
|
class AccumulatorExample(n: Int = 4)(implicit p: Parameters) extends RoCC()(p) {
|
||||||
{
|
|
||||||
val n = 4
|
|
||||||
val regfile = Mem(UInt(width = xLen), n)
|
val regfile = Mem(UInt(width = xLen), n)
|
||||||
val busy = Reg(init=Vec(Bool(false), n))
|
val busy = Reg(init=Vec(Bool(false), n))
|
||||||
|
|
||||||
|
@ -7,10 +7,9 @@ import junctions._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
case object BuildFPU extends Field[Option[() => FPU]]
|
case object BuildFPU extends Field[Option[Parameters => FPU]]
|
||||||
case object FDivSqrt extends Field[Boolean]
|
case object FDivSqrt extends Field[Boolean]
|
||||||
case object XLen extends Field[Int]
|
case object XLen extends Field[Int]
|
||||||
case object NMultXpr extends Field[Int]
|
|
||||||
case object FetchWidth extends Field[Int]
|
case object FetchWidth extends Field[Int]
|
||||||
case object RetireWidth extends Field[Int]
|
case object RetireWidth extends Field[Int]
|
||||||
case object UseVM extends Field[Boolean]
|
case object UseVM extends Field[Boolean]
|
||||||
@ -23,59 +22,65 @@ case object CoreDataBits extends Field[Int]
|
|||||||
case object CoreDCacheReqTagBits extends Field[Int]
|
case object CoreDCacheReqTagBits extends Field[Int]
|
||||||
case object NCustomMRWCSRs extends Field[Int]
|
case object NCustomMRWCSRs extends Field[Int]
|
||||||
|
|
||||||
abstract trait CoreParameters extends UsesParameters {
|
trait HasCoreParameters {
|
||||||
val xLen = params(XLen)
|
implicit val p: Parameters
|
||||||
val paddrBits = params(PAddrBits)
|
val xLen = p(XLen)
|
||||||
val vaddrBits = params(VAddrBits)
|
val paddrBits = p(PAddrBits)
|
||||||
val pgIdxBits = params(PgIdxBits)
|
val vaddrBits = p(VAddrBits)
|
||||||
val ppnBits = params(PPNBits)
|
val pgIdxBits = p(PgIdxBits)
|
||||||
val vpnBits = params(VPNBits)
|
val ppnBits = p(PPNBits)
|
||||||
val pgLevels = params(PgLevels)
|
val vpnBits = p(VPNBits)
|
||||||
val pgLevelBits = params(PgLevelBits)
|
val pgLevels = p(PgLevels)
|
||||||
val asIdBits = params(ASIdBits)
|
val pgLevelBits = p(PgLevelBits)
|
||||||
|
val asIdBits = p(ASIdBits)
|
||||||
|
|
||||||
val retireWidth = params(RetireWidth)
|
val retireWidth = p(RetireWidth)
|
||||||
val coreFetchWidth = params(FetchWidth)
|
val fetchWidth = p(FetchWidth)
|
||||||
val coreInstBits = params(CoreInstBits)
|
val coreInstBits = p(CoreInstBits)
|
||||||
val coreInstBytes = coreInstBits/8
|
val coreInstBytes = coreInstBits/8
|
||||||
val coreDataBits = xLen
|
val coreDataBits = xLen
|
||||||
val coreDataBytes = coreDataBits/8
|
val coreDataBytes = coreDataBits/8
|
||||||
val coreDCacheReqTagBits = params(CoreDCacheReqTagBits)
|
val coreDCacheReqTagBits = p(CoreDCacheReqTagBits)
|
||||||
val coreMaxAddrBits = math.max(ppnBits,vpnBits+1) + pgIdxBits
|
val coreMaxAddrBits = math.max(ppnBits,vpnBits+1) + pgIdxBits
|
||||||
val vaddrBitsExtended = vaddrBits + (vaddrBits < xLen).toInt
|
val vaddrBitsExtended = vaddrBits + (vaddrBits < xLen).toInt
|
||||||
val mmioBase = params(MMIOBase)
|
val mmioBase = p(MMIOBase)
|
||||||
|
val nCustomMrwCsrs = p(NCustomMRWCSRs)
|
||||||
|
|
||||||
|
val usingVM = p(UseVM)
|
||||||
|
val usingFPU = !p(BuildFPU).isEmpty
|
||||||
|
val usingFDivSqrt = p(FDivSqrt)
|
||||||
|
val usingRoCC = !p(BuildRoCC).isEmpty
|
||||||
|
val usingFastMulDiv = p(FastMulDiv)
|
||||||
|
val fastLoadWord = p(FastLoadWord)
|
||||||
|
val fastLoadByte = p(FastLoadByte)
|
||||||
|
|
||||||
// Print out log of committed instructions and their writeback values.
|
// Print out log of committed instructions and their writeback values.
|
||||||
// Requires post-processing due to out-of-order writebacks.
|
// Requires post-processing due to out-of-order writebacks.
|
||||||
val EnableCommitLog = false
|
val enableCommitLog = false
|
||||||
|
val usingPerfCounters = p(UsePerfCounters)
|
||||||
|
|
||||||
if(params(FastLoadByte)) require(params(FastLoadWord))
|
if (fastLoadByte) require(fastLoadWord)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract trait RocketCoreParameters extends CoreParameters
|
abstract class CoreModule(implicit val p: Parameters) extends Module
|
||||||
{
|
with HasCoreParameters
|
||||||
require(params(FetchWidth) == 1) // for now...
|
abstract class CoreBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||||
require(params(RetireWidth) == 1) // for now...
|
with HasCoreParameters
|
||||||
}
|
|
||||||
|
|
||||||
abstract class CoreBundle extends Bundle with CoreParameters
|
class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
abstract class CoreModule extends Module with CoreParameters
|
|
||||||
|
|
||||||
class Rocket extends CoreModule
|
|
||||||
{
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HTIFIO
|
val host = new HtifIO
|
||||||
val imem = new CPUFrontendIO
|
val imem = new FrontendIO()(p.alterPartial({case CacheName => "L1I" }))
|
||||||
val dmem = new HellaCacheIO
|
val dmem = new HellaCacheIO()(p.alterPartial({ case CacheName => "L1D" }))
|
||||||
val ptw = new DatapathPTWIO().flip
|
val ptw = new DatapathPTWIO().flip
|
||||||
val fpu = new FPUIO().flip
|
val fpu = new FPUIO().flip
|
||||||
val rocc = new RoCCInterface().flip
|
val rocc = new RoCCInterface().flip
|
||||||
}
|
}
|
||||||
|
|
||||||
var decode_table = XDecode.table
|
var decode_table = XDecode.table
|
||||||
if (!params(BuildFPU).isEmpty) decode_table ++= FDecode.table
|
if (usingFPU) decode_table ++= FDecode.table
|
||||||
if (!params(BuildFPU).isEmpty && params(FDivSqrt)) decode_table ++= FDivSqrtDecode.table
|
if (usingFPU && usingFDivSqrt) decode_table ++= FDivSqrtDecode.table
|
||||||
if (!params(BuildRoCC).isEmpty) decode_table ++= RoCCDecode.table
|
if (usingRoCC) decode_table ++= RoCCDecode.table
|
||||||
|
|
||||||
val ex_ctrl = Reg(new IntCtrlSigs)
|
val ex_ctrl = Reg(new IntCtrlSigs)
|
||||||
val mem_ctrl = Reg(new IntCtrlSigs)
|
val mem_ctrl = Reg(new IntCtrlSigs)
|
||||||
@ -123,7 +128,7 @@ class Rocket extends CoreModule
|
|||||||
|
|
||||||
// decode stage
|
// decode stage
|
||||||
val id_pc = io.imem.resp.bits.pc
|
val id_pc = io.imem.resp.bits.pc
|
||||||
val id_inst = io.imem.resp.bits.data(0).toBits; require(params(FetchWidth) == 1)
|
val id_inst = io.imem.resp.bits.data(0).toBits; require(fetchWidth == 1)
|
||||||
val id_ctrl = Wire(new IntCtrlSigs()).decode(id_inst, decode_table)
|
val id_ctrl = Wire(new IntCtrlSigs()).decode(id_inst, decode_table)
|
||||||
val id_raddr3 = id_inst(31,27)
|
val id_raddr3 = id_inst(31,27)
|
||||||
val id_raddr2 = id_inst(24,20)
|
val id_raddr2 = id_inst(24,20)
|
||||||
@ -156,7 +161,7 @@ class Rocket extends CoreModule
|
|||||||
val id_amo_rl = id_inst(25)
|
val id_amo_rl = id_inst(25)
|
||||||
val id_fence_next = id_ctrl.fence || id_ctrl.amo && id_amo_rl
|
val id_fence_next = id_ctrl.fence || id_ctrl.amo && id_amo_rl
|
||||||
val id_mem_busy = !io.dmem.ordered || io.dmem.req.valid
|
val id_mem_busy = !io.dmem.ordered || io.dmem.req.valid
|
||||||
val id_rocc_busy = Bool(!params(BuildRoCC).isEmpty) &&
|
val id_rocc_busy = Bool(usingRoCC) &&
|
||||||
(io.rocc.busy || ex_reg_valid && ex_ctrl.rocc ||
|
(io.rocc.busy || ex_reg_valid && ex_ctrl.rocc ||
|
||||||
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
|
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
|
||||||
id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy
|
id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy
|
||||||
@ -169,8 +174,8 @@ class Rocket extends CoreModule
|
|||||||
(id_illegal_insn, UInt(Causes.illegal_instruction))))
|
(id_illegal_insn, UInt(Causes.illegal_instruction))))
|
||||||
|
|
||||||
val dcache_bypass_data =
|
val dcache_bypass_data =
|
||||||
if(params(FastLoadByte)) io.dmem.resp.bits.data
|
if (fastLoadByte) io.dmem.resp.bits.data
|
||||||
else if(params(FastLoadWord)) io.dmem.resp.bits.data_word_bypass
|
else if (fastLoadWord) io.dmem.resp.bits.data_word_bypass
|
||||||
else wb_reg_wdata
|
else wb_reg_wdata
|
||||||
|
|
||||||
// detect bypass opportunities
|
// detect bypass opportunities
|
||||||
@ -207,8 +212,9 @@ class Rocket extends CoreModule
|
|||||||
alu.io.in1 := ex_op1.toUInt
|
alu.io.in1 := ex_op1.toUInt
|
||||||
|
|
||||||
// multiplier and divider
|
// multiplier and divider
|
||||||
val div = Module(new MulDiv(mulUnroll = if(params(FastMulDiv)) 8 else 1,
|
val div = Module(new MulDiv(width = xLen,
|
||||||
earlyOut = params(FastMulDiv)))
|
unroll = if(usingFastMulDiv) 8 else 1,
|
||||||
|
earlyOut = usingFastMulDiv))
|
||||||
div.io.req.valid := ex_reg_valid && ex_ctrl.div
|
div.io.req.valid := ex_reg_valid && ex_ctrl.div
|
||||||
div.io.req.bits.dw := ex_ctrl.alu_dw
|
div.io.req.bits.dw := ex_ctrl.alu_dw
|
||||||
div.io.req.bits.fn := ex_ctrl.alu_fn
|
div.io.req.bits.fn := ex_ctrl.alu_fn
|
||||||
@ -345,7 +351,7 @@ class Rocket extends CoreModule
|
|||||||
val ll_wdata = Wire(init = div.io.resp.bits.data)
|
val ll_wdata = Wire(init = div.io.resp.bits.data)
|
||||||
val ll_waddr = Wire(init = div.io.resp.bits.tag)
|
val ll_waddr = Wire(init = div.io.resp.bits.tag)
|
||||||
val ll_wen = Wire(init = div.io.resp.fire())
|
val ll_wen = Wire(init = div.io.resp.fire())
|
||||||
if (!params(BuildRoCC).isEmpty) {
|
if (usingRoCC) {
|
||||||
io.rocc.resp.ready := !(wb_reg_valid && wb_ctrl.wxd)
|
io.rocc.resp.ready := !(wb_reg_valid && wb_ctrl.wxd)
|
||||||
when (io.rocc.resp.fire()) {
|
when (io.rocc.resp.fire()) {
|
||||||
div.io.resp.ready := Bool(false)
|
div.io.resp.ready := Bool(false)
|
||||||
@ -356,7 +362,7 @@ class Rocket extends CoreModule
|
|||||||
}
|
}
|
||||||
when (dmem_resp_replay && dmem_resp_xpu) {
|
when (dmem_resp_replay && dmem_resp_xpu) {
|
||||||
div.io.resp.ready := Bool(false)
|
div.io.resp.ready := Bool(false)
|
||||||
if (!params(BuildRoCC).isEmpty)
|
if (usingRoCC)
|
||||||
io.rocc.resp.ready := Bool(false)
|
io.rocc.resp.ready := Bool(false)
|
||||||
ll_waddr := dmem_resp_waddr
|
ll_waddr := dmem_resp_waddr
|
||||||
ll_wen := Bool(true)
|
ll_wen := Bool(true)
|
||||||
@ -410,7 +416,7 @@ class Rocket extends CoreModule
|
|||||||
|
|
||||||
// stall for RAW/WAW hazards on CSRs, LB/LH, and mul/div in memory stage.
|
// stall for RAW/WAW hazards on CSRs, LB/LH, and mul/div in memory stage.
|
||||||
val mem_mem_cmd_bh =
|
val mem_mem_cmd_bh =
|
||||||
if (params(FastLoadWord)) Bool(!params(FastLoadByte)) && mem_reg_slow_bypass
|
if (fastLoadWord) Bool(!fastLoadByte) && mem_reg_slow_bypass
|
||||||
else Bool(true)
|
else Bool(true)
|
||||||
val mem_cannot_bypass = mem_ctrl.csr != CSR.N || mem_ctrl.mem && mem_mem_cmd_bh || mem_ctrl.div || mem_ctrl.fp || mem_ctrl.rocc
|
val mem_cannot_bypass = mem_ctrl.csr != CSR.N || mem_ctrl.mem && mem_mem_cmd_bh || mem_ctrl.div || mem_ctrl.fp || mem_ctrl.rocc
|
||||||
val data_hazard_mem = mem_ctrl.wxd && checkHazards(hazard_targets, _ === mem_waddr)
|
val data_hazard_mem = mem_ctrl.wxd && checkHazards(hazard_targets, _ === mem_waddr)
|
||||||
@ -423,7 +429,7 @@ class Rocket extends CoreModule
|
|||||||
val fp_data_hazard_wb = wb_ctrl.wfd && checkHazards(fp_hazard_targets, _ === wb_waddr)
|
val fp_data_hazard_wb = wb_ctrl.wfd && checkHazards(fp_hazard_targets, _ === wb_waddr)
|
||||||
val id_wb_hazard = wb_reg_valid && (data_hazard_wb && wb_set_sboard || fp_data_hazard_wb)
|
val id_wb_hazard = wb_reg_valid && (data_hazard_wb && wb_set_sboard || fp_data_hazard_wb)
|
||||||
|
|
||||||
val id_stall_fpu = if (!params(BuildFPU).isEmpty) {
|
val id_stall_fpu = if (usingFPU) {
|
||||||
val fp_sboard = new Scoreboard(32)
|
val fp_sboard = new Scoreboard(32)
|
||||||
fp_sboard.set((wb_dcache_miss && wb_ctrl.wfd || io.fpu.sboard_set) && wb_valid, wb_waddr)
|
fp_sboard.set((wb_dcache_miss && wb_ctrl.wfd || io.fpu.sboard_set) && wb_valid, wb_waddr)
|
||||||
fp_sboard.clear(dmem_resp_replay && dmem_resp_fpu, dmem_resp_waddr)
|
fp_sboard.clear(dmem_resp_replay && dmem_resp_fpu, dmem_resp_waddr)
|
||||||
@ -436,7 +442,7 @@ class Rocket extends CoreModule
|
|||||||
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
||||||
id_ctrl.fp && id_stall_fpu ||
|
id_ctrl.fp && id_stall_fpu ||
|
||||||
id_ctrl.mem && !io.dmem.req.ready ||
|
id_ctrl.mem && !io.dmem.req.ready ||
|
||||||
Bool(!params(BuildRoCC).isEmpty) && wb_reg_rocc_pending && id_ctrl.rocc && !io.rocc.cmd.ready ||
|
Bool(usingRoCC) && wb_reg_rocc_pending && id_ctrl.rocc && !io.rocc.cmd.ready ||
|
||||||
id_do_fence ||
|
id_do_fence ||
|
||||||
csr.io.csr_stall
|
csr.io.csr_stall
|
||||||
ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || csr.io.interrupt
|
ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || csr.io.interrupt
|
||||||
@ -488,7 +494,7 @@ class Rocket extends CoreModule
|
|||||||
io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(vaddrBits-1,0)).toUInt
|
io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(vaddrBits-1,0)).toUInt
|
||||||
io.dmem.req.bits.tag := Cat(ex_waddr, ex_ctrl.fp)
|
io.dmem.req.bits.tag := Cat(ex_waddr, ex_ctrl.fp)
|
||||||
io.dmem.req.bits.data := Mux(mem_ctrl.fp, io.fpu.store_data, mem_reg_rs2)
|
io.dmem.req.bits.data := Mux(mem_ctrl.fp, io.fpu.store_data, mem_reg_rs2)
|
||||||
require(params(CoreDCacheReqTagBits) >= 6)
|
require(p(CoreDCacheReqTagBits) >= 6)
|
||||||
io.dmem.invalidate_lr := wb_xcpt
|
io.dmem.invalidate_lr := wb_xcpt
|
||||||
|
|
||||||
io.rocc.cmd.valid := wb_rocc_val
|
io.rocc.cmd.valid := wb_rocc_val
|
||||||
@ -498,7 +504,7 @@ class Rocket extends CoreModule
|
|||||||
io.rocc.cmd.bits.rs1 := wb_reg_wdata
|
io.rocc.cmd.bits.rs1 := wb_reg_wdata
|
||||||
io.rocc.cmd.bits.rs2 := wb_reg_rs2
|
io.rocc.cmd.bits.rs2 := wb_reg_rs2
|
||||||
|
|
||||||
if (EnableCommitLog) {
|
if (enableCommitLog) {
|
||||||
val pc = Wire(SInt(width=64))
|
val pc = Wire(SInt(width=64))
|
||||||
pc := wb_reg_pc
|
pc := wb_reg_pc
|
||||||
val inst = wb_reg_inst
|
val inst = wb_reg_inst
|
||||||
|
@ -11,22 +11,27 @@ case object NDCachePorts extends Field[Int]
|
|||||||
case object NPTWPorts extends Field[Int]
|
case object NPTWPorts extends Field[Int]
|
||||||
case object BuildRoCC extends Field[Option[() => RoCC]]
|
case object BuildRoCC extends Field[Option[() => RoCC]]
|
||||||
|
|
||||||
abstract class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) {
|
abstract class Tile(resetSignal: Bool = null)
|
||||||
|
(implicit p: Parameters) extends Module(_reset = resetSignal) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cached = new ClientTileLinkIO
|
val cached = new ClientTileLinkIO
|
||||||
val uncached = new ClientUncachedTileLinkIO
|
val uncached = new ClientUncachedTileLinkIO
|
||||||
val host = new HTIFIO
|
val host = new HtifIO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketTile(resetSignal: Bool = null) extends Tile(resetSignal) {
|
class RocketTile(resetSignal: Bool = null)(implicit p: Parameters) extends Tile(resetSignal)(p) {
|
||||||
val icache = Module(new Frontend, { case CacheName => "L1I"; case CoreName => "Rocket" })
|
//TODO
|
||||||
val dcache = Module(new HellaCache, { case CacheName => "L1D" })
|
val dcacheParams = p.alterPartial({ case CacheName => "L1D" })
|
||||||
val ptw = Module(new PTW(params(NPTWPorts)))
|
val icache = Module(new Frontend()(p.alterPartial({
|
||||||
val core = Module(new Rocket, { case CoreName => "Rocket" })
|
case CacheName => "L1I"
|
||||||
|
case CoreName => "Rocket" })))
|
||||||
|
val dcache = Module(new HellaCache()(dcacheParams))
|
||||||
|
val ptw = Module(new PTW(p(NPTWPorts))(dcacheParams))
|
||||||
|
val core = Module(new Rocket()(p.alterPartial({ case CoreName => "Rocket" })))
|
||||||
|
|
||||||
dcache.io.cpu.invalidate_lr := core.io.dmem.invalidate_lr // Bypass signal to dcache
|
dcache.io.cpu.invalidate_lr := core.io.dmem.invalidate_lr // Bypass signal to dcache
|
||||||
val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts)))
|
val dcArb = Module(new HellaCacheArbiter(p(NDCachePorts))(dcacheParams))
|
||||||
dcArb.io.requestor(0) <> ptw.io.mem
|
dcArb.io.requestor(0) <> ptw.io.mem
|
||||||
dcArb.io.requestor(1) <> core.io.dmem
|
dcArb.io.requestor(1) <> core.io.dmem
|
||||||
dcache.io.cpu <> dcArb.io.mem
|
dcache.io.cpu <> dcArb.io.mem
|
||||||
@ -39,20 +44,16 @@ class RocketTile(resetSignal: Bool = null) extends Tile(resetSignal) {
|
|||||||
core.io.ptw <> ptw.io.dpath
|
core.io.ptw <> ptw.io.dpath
|
||||||
|
|
||||||
//If so specified, build an FPU module and wire it in
|
//If so specified, build an FPU module and wire it in
|
||||||
params(BuildFPU)
|
p(BuildFPU) foreach { fpu => core.io.fpu <> fpu(p).io }
|
||||||
.map { bf => bf() }
|
|
||||||
.foreach { fpu =>
|
|
||||||
core.io.fpu <> fpu.io
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect the caches and ROCC to the outer memory system
|
// Connect the caches and ROCC to the outer memory system
|
||||||
io.cached <> dcache.io.mem
|
io.cached <> dcache.io.mem
|
||||||
// If so specified, build an RoCC module and wire it in
|
// If so specified, build an RoCC module and wire it in
|
||||||
// otherwise, just hookup the icache
|
// otherwise, just hookup the icache
|
||||||
io.uncached <> params(BuildRoCC).map { buildItHere =>
|
io.uncached <> p(BuildRoCC).map { buildItHere =>
|
||||||
val rocc = buildItHere()
|
val rocc = buildItHere()
|
||||||
val memArb = Module(new ClientTileLinkIOArbiter(3))
|
val memArb = Module(new ClientTileLinkIOArbiter(3))
|
||||||
val dcIF = Module(new SimpleHellaCacheIF)
|
val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams))
|
||||||
core.io.rocc <> rocc.io
|
core.io.rocc <> rocc.io
|
||||||
dcIF.io.requestor <> rocc.io.mem
|
dcIF.io.requestor <> rocc.io.mem
|
||||||
dcArb.io.requestor(2) <> dcIF.io.cache
|
dcArb.io.requestor(2) <> dcIF.io.cache
|
||||||
|
@ -9,17 +9,19 @@ import scala.math._
|
|||||||
|
|
||||||
case object NTLBEntries extends Field[Int]
|
case object NTLBEntries extends Field[Int]
|
||||||
|
|
||||||
abstract trait TLBParameters extends CoreParameters {
|
trait HasTLBParameters extends HasCoreParameters {
|
||||||
val addrMap = new AddrHashMap(params(NastiAddrMap))
|
val addrMap = new AddrHashMap(p(NastiAddrMap))
|
||||||
val entries = params(NTLBEntries)
|
val entries = p(NTLBEntries)
|
||||||
val camAddrBits = ceil(log(entries)/log(2)).toInt
|
val camAddrBits = ceil(log(entries)/log(2)).toInt
|
||||||
val camTagBits = asIdBits + vpnBits
|
val camTagBits = asIdBits + vpnBits
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TLBBundle extends Bundle with TLBParameters
|
abstract class TLBModule(implicit val p: Parameters) extends Module
|
||||||
abstract class TLBModule extends Module with TLBParameters
|
with HasTLBParameters
|
||||||
|
abstract class TLBBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||||
|
with HasTLBParameters
|
||||||
|
|
||||||
class CAMIO extends TLBBundle {
|
class CAMIO(implicit p: Parameters) extends TLBBundle()(p) {
|
||||||
val clear = Bool(INPUT)
|
val clear = Bool(INPUT)
|
||||||
val clear_mask = Bits(INPUT, entries)
|
val clear_mask = Bits(INPUT, entries)
|
||||||
val tag = Bits(INPUT, camTagBits)
|
val tag = Bits(INPUT, camTagBits)
|
||||||
@ -32,7 +34,7 @@ class CAMIO extends TLBBundle {
|
|||||||
val write_addr = UInt(INPUT, camAddrBits)
|
val write_addr = UInt(INPUT, camAddrBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCAM extends TLBModule {
|
class RocketCAM(implicit p: Parameters) extends TLBModule()(p) {
|
||||||
val io = new CAMIO
|
val io = new CAMIO
|
||||||
val cam_tags = Mem(entries, Bits(width = camTagBits))
|
val cam_tags = Mem(entries, Bits(width = camTagBits))
|
||||||
|
|
||||||
@ -75,7 +77,7 @@ class PseudoLRU(n: Int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBReq extends CoreBundle {
|
class TLBReq(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val asid = UInt(width = asIdBits)
|
val asid = UInt(width = asIdBits)
|
||||||
val vpn = UInt(width = vpnBits+1)
|
val vpn = UInt(width = vpnBits+1)
|
||||||
val passthrough = Bool()
|
val passthrough = Bool()
|
||||||
@ -83,7 +85,7 @@ class TLBReq extends CoreBundle {
|
|||||||
val store = Bool()
|
val store = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBRespNoHitIndex extends CoreBundle {
|
class TLBRespNoHitIndex(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
// lookup responses
|
// lookup responses
|
||||||
val miss = Bool(OUTPUT)
|
val miss = Bool(OUTPUT)
|
||||||
val ppn = UInt(OUTPUT, ppnBits)
|
val ppn = UInt(OUTPUT, ppnBits)
|
||||||
@ -92,11 +94,11 @@ class TLBRespNoHitIndex extends CoreBundle {
|
|||||||
val xcpt_if = Bool(OUTPUT)
|
val xcpt_if = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBResp extends TLBRespNoHitIndex with TLBParameters {
|
class TLBResp(implicit p: Parameters) extends TLBRespNoHitIndex()(p) with HasTLBParameters {
|
||||||
val hit_idx = UInt(OUTPUT, entries)
|
val hit_idx = UInt(OUTPUT, entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLB extends TLBModule {
|
class TLB(implicit p: Parameters) extends TLBModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new TLBReq).flip
|
val req = Decoupled(new TLBReq).flip
|
||||||
val resp = new TLBResp
|
val resp = new TLBResp
|
||||||
@ -177,7 +179,7 @@ class TLB extends TLBModule {
|
|||||||
io.resp.xcpt_st := !addr_ok || !addr_prot.w || bad_va || tlb_hit && !(w_array & tag_cam.io.hits).orR
|
io.resp.xcpt_st := !addr_ok || !addr_prot.w || bad_va || tlb_hit && !(w_array & tag_cam.io.hits).orR
|
||||||
io.resp.xcpt_if := !addr_ok || !addr_prot.x || bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR
|
io.resp.xcpt_if := !addr_ok || !addr_prot.x || bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR
|
||||||
io.resp.miss := tlb_miss
|
io.resp.miss := tlb_miss
|
||||||
io.resp.ppn := Mux(vm_enabled, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(params(PPNBits)-1,0))
|
io.resp.ppn := Mux(vm_enabled, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(ppnBits-1,0))
|
||||||
io.resp.hit_idx := tag_cam.io.hits
|
io.resp.hit_idx := tag_cam.io.hits
|
||||||
|
|
||||||
// clear invalid entries on access, or all entries on a TLB flush
|
// clear invalid entries on access, or all entries on a TLB flush
|
||||||
|
Loading…
Reference in New Issue
Block a user