1
0

Removed all traces of params

This commit is contained in:
Henry Cook 2015-10-05 21:48:05 -07:00
parent 69a4dd0a79
commit 84576650b5
14 changed files with 383 additions and 365 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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())

View 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
}

View File

@ -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)

View File

@ -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)
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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