Rename some params, use refactored TileLink
This commit is contained in:
parent
00e074cdd9
commit
741e6b77ad
@ -10,8 +10,7 @@ import uncore._
|
|||||||
case object NBTBEntries extends Field[Int]
|
case object NBTBEntries extends Field[Int]
|
||||||
case object NRAS extends Field[Int]
|
case object NRAS extends Field[Int]
|
||||||
|
|
||||||
abstract trait BTBParameters extends UsesParameters {
|
abstract trait BTBParameters extends CoreParameters {
|
||||||
val vaddrBits = params(VAddrBits)
|
|
||||||
val matchBits = params(PgIdxBits)
|
val matchBits = params(PgIdxBits)
|
||||||
val entries = params(NBTBEntries)
|
val entries = params(NBTBEntries)
|
||||||
val nRAS = params(NRAS)
|
val nRAS = params(NRAS)
|
||||||
|
@ -7,7 +7,7 @@ import Util._
|
|||||||
import uncore._
|
import uncore._
|
||||||
|
|
||||||
case object BuildFPU extends Field[Option[() => FPU]]
|
case object BuildFPU extends Field[Option[() => FPU]]
|
||||||
case object XprLen extends Field[Int]
|
case object XLen extends Field[Int]
|
||||||
case object NMultXpr 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]
|
||||||
@ -20,14 +20,23 @@ case object CoreDataBits extends Field[Int]
|
|||||||
case object CoreDCacheReqTagBits extends Field[Int]
|
case object CoreDCacheReqTagBits extends Field[Int]
|
||||||
|
|
||||||
abstract trait CoreParameters extends UsesParameters {
|
abstract trait CoreParameters extends UsesParameters {
|
||||||
val xprLen = params(XprLen)
|
val xLen = params(XLen)
|
||||||
|
val paddrBits = params(PAddrBits)
|
||||||
|
val vaddrBits = params(VAddrBits)
|
||||||
|
val pgIdxBits = params(PgIdxBits)
|
||||||
|
val ppnBits = params(PPNBits)
|
||||||
|
val vpnBits = params(VPNBits)
|
||||||
|
val permBits = params(PermBits)
|
||||||
|
val asIdBits = params(ASIdBits)
|
||||||
|
|
||||||
|
val retireWidth = params(RetireWidth)
|
||||||
val coreFetchWidth = params(FetchWidth)
|
val coreFetchWidth = params(FetchWidth)
|
||||||
val coreInstBits = params(CoreInstBits)
|
val coreInstBits = params(CoreInstBits)
|
||||||
val coreInstBytes = coreInstBits/8
|
val coreInstBytes = coreInstBits/8
|
||||||
val coreDataBits = xprLen
|
val coreDataBits = xLen
|
||||||
val coreDataBytes = coreDataBits/8
|
val coreDataBytes = coreDataBits/8
|
||||||
val coreDCacheReqTagBits = params(CoreDCacheReqTagBits)
|
val coreDCacheReqTagBits = params(CoreDCacheReqTagBits)
|
||||||
val coreMaxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits)
|
val coreMaxAddrBits = math.max(ppnBits,vpnBits+1) + pgIdxBits
|
||||||
|
|
||||||
if(params(FastLoadByte)) require(params(FastLoadWord))
|
if(params(FastLoadByte)) require(params(FastLoadWord))
|
||||||
}
|
}
|
||||||
|
@ -34,52 +34,52 @@ object CSR
|
|||||||
val C = Bits(3,2)
|
val C = Bits(3,2)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFileIO extends Bundle {
|
class CSRFileIO 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, 12)
|
||||||
val cmd = Bits(INPUT, CSR.SZ)
|
val cmd = Bits(INPUT, CSR.SZ)
|
||||||
val rdata = Bits(OUTPUT, params(XprLen))
|
val rdata = Bits(OUTPUT, xLen)
|
||||||
val wdata = Bits(INPUT, params(XprLen))
|
val wdata = Bits(INPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
val status = new Status().asOutput
|
val status = new Status().asOutput
|
||||||
val ptbr = UInt(OUTPUT, params(PAddrBits))
|
val ptbr = UInt(OUTPUT, paddrBits)
|
||||||
val evec = UInt(OUTPUT, params(VAddrBits)+1)
|
val evec = UInt(OUTPUT, vaddrBits+1)
|
||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
val retire = UInt(INPUT, log2Up(1+params(RetireWidth)))
|
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
||||||
val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+params(RetireWidth))))
|
val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+retireWidth)))
|
||||||
val cause = UInt(INPUT, params(XprLen))
|
val cause = UInt(INPUT, xLen)
|
||||||
val badvaddr_wen = Bool(INPUT)
|
val badvaddr_wen = Bool(INPUT)
|
||||||
val pc = UInt(INPUT, params(VAddrBits)+1)
|
val pc = UInt(INPUT, vaddrBits+1)
|
||||||
val sret = Bool(INPUT)
|
val sret = Bool(INPUT)
|
||||||
val fatc = Bool(OUTPUT)
|
val fatc = Bool(OUTPUT)
|
||||||
val replay = Bool(OUTPUT)
|
val replay = Bool(OUTPUT)
|
||||||
val time = UInt(OUTPUT, params(XprLen))
|
val time = UInt(OUTPUT, xLen)
|
||||||
val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ)
|
val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ)
|
||||||
val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip
|
val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip
|
||||||
val rocc = new RoCCInterface().flip
|
val rocc = new RoCCInterface().flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile extends Module
|
class CSRFile extends CoreModule
|
||||||
{
|
{
|
||||||
val io = new CSRFileIO
|
val io = new CSRFileIO
|
||||||
|
|
||||||
val reg_epc = Reg(Bits(width = params(VAddrBits)+1))
|
val reg_epc = Reg(Bits(width = vaddrBits+1))
|
||||||
val reg_badvaddr = Reg(Bits(width = params(VAddrBits)))
|
val reg_badvaddr = Reg(Bits(width = vaddrBits))
|
||||||
val reg_evec = Reg(Bits(width = params(VAddrBits)))
|
val reg_evec = Reg(Bits(width = vaddrBits))
|
||||||
val reg_compare = Reg(Bits(width = 32))
|
val reg_compare = Reg(Bits(width = 32))
|
||||||
val reg_cause = Reg(Bits(width = params(XprLen)))
|
val reg_cause = Reg(Bits(width = xLen))
|
||||||
val reg_tohost = Reg(init=Bits(0, params(XprLen)))
|
val reg_tohost = Reg(init=Bits(0, xLen))
|
||||||
val reg_fromhost = Reg(init=Bits(0, params(XprLen)))
|
val reg_fromhost = Reg(init=Bits(0, xLen))
|
||||||
val reg_sup0 = Reg(Bits(width = params(XprLen)))
|
val reg_sup0 = Reg(Bits(width = xLen))
|
||||||
val reg_sup1 = Reg(Bits(width = params(XprLen)))
|
val reg_sup1 = Reg(Bits(width = xLen))
|
||||||
val reg_ptbr = Reg(UInt(width = params(PAddrBits)))
|
val reg_ptbr = Reg(UInt(width = paddrBits))
|
||||||
val reg_stats = Reg(init=Bool(false))
|
val reg_stats = Reg(init=Bool(false))
|
||||||
val reg_status = Reg(new Status) // reset down below
|
val reg_status = Reg(new Status) // reset down below
|
||||||
val reg_time = WideCounter(params(XprLen))
|
val reg_time = WideCounter(xLen)
|
||||||
val reg_instret = WideCounter(params(XprLen), io.retire)
|
val reg_instret = WideCounter(xLen, io.retire)
|
||||||
val reg_uarch_counters = io.uarch_counters.map(WideCounter(params(XprLen), _))
|
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))
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ class CSRFile extends Module
|
|||||||
|
|
||||||
when (io.badvaddr_wen) {
|
when (io.badvaddr_wen) {
|
||||||
val wdata = io.rw.wdata
|
val wdata = io.rw.wdata
|
||||||
val (upper, lower) = Split(wdata, params(VAddrBits))
|
val (upper, lower) = Split(wdata, vaddrBits)
|
||||||
val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR)
|
val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR)
|
||||||
reg_badvaddr := Cat(sign, lower).toSInt
|
reg_badvaddr := Cat(sign, lower).toSInt
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ class CSRFile extends Module
|
|||||||
when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) }
|
when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) }
|
||||||
|
|
||||||
val read_impl = Bits(2)
|
val read_impl = Bits(2)
|
||||||
val read_ptbr = reg_ptbr(params(PAddrBits)-1, params(PgIdxBits)) << UInt(params(PgIdxBits))
|
val read_ptbr = reg_ptbr(paddrBits-1, pgIdxBits) << UInt(pgIdxBits)
|
||||||
|
|
||||||
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 (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)),
|
||||||
@ -211,8 +211,8 @@ class CSRFile extends Module
|
|||||||
when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata }
|
when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata }
|
||||||
when (decoded_addr(CSRs.frm)) { reg_frm := wdata }
|
when (decoded_addr(CSRs.frm)) { reg_frm := wdata }
|
||||||
when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth }
|
when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth }
|
||||||
when (decoded_addr(CSRs.epc)) { reg_epc := wdata(params(VAddrBits),0).toSInt }
|
when (decoded_addr(CSRs.epc)) { reg_epc := wdata(vaddrBits,0).toSInt }
|
||||||
when (decoded_addr(CSRs.evec)) { reg_evec := wdata(params(VAddrBits)-1,0).toSInt }
|
when (decoded_addr(CSRs.evec)) { reg_evec := wdata(vaddrBits-1,0).toSInt }
|
||||||
when (decoded_addr(CSRs.count)) { reg_time := wdata.toUInt }
|
when (decoded_addr(CSRs.count)) { reg_time := wdata.toUInt }
|
||||||
when (decoded_addr(CSRs.compare)) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) }
|
when (decoded_addr(CSRs.compare)) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) }
|
||||||
when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } }
|
when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } }
|
||||||
@ -220,7 +220,7 @@ class CSRFile extends Module
|
|||||||
when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) }
|
when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) }
|
||||||
when (decoded_addr(CSRs.sup0)) { reg_sup0 := wdata }
|
when (decoded_addr(CSRs.sup0)) { reg_sup0 := wdata }
|
||||||
when (decoded_addr(CSRs.sup1)) { reg_sup1 := wdata }
|
when (decoded_addr(CSRs.sup1)) { reg_sup1 := wdata }
|
||||||
when (decoded_addr(CSRs.ptbr)) { reg_ptbr := Cat(wdata(params(PAddrBits)-1, params(PgIdxBits)), Bits(0, params(PgIdxBits))).toUInt }
|
when (decoded_addr(CSRs.ptbr)) { reg_ptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)).toUInt }
|
||||||
when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) }
|
when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import uncore.constants.MemoryOpConstants._
|
|||||||
import ALU._
|
import ALU._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class CtrlDpathIO extends Bundle
|
class CtrlDpathIO extends CoreBundle
|
||||||
{
|
{
|
||||||
// outputs to datapath
|
// outputs to datapath
|
||||||
val sel_pc = UInt(OUTPUT, 3)
|
val sel_pc = UInt(OUTPUT, 3)
|
||||||
@ -27,7 +27,7 @@ class CtrlDpathIO extends Bundle
|
|||||||
// exception handling
|
// exception handling
|
||||||
val retire = Bool(OUTPUT)
|
val retire = Bool(OUTPUT)
|
||||||
val exception = Bool(OUTPUT)
|
val exception = Bool(OUTPUT)
|
||||||
val cause = UInt(OUTPUT, params(XprLen))
|
val cause = UInt(OUTPUT, xLen)
|
||||||
val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault
|
val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault
|
||||||
// inputs from datapath
|
// inputs from datapath
|
||||||
val inst = Bits(INPUT, 32)
|
val inst = Bits(INPUT, 32)
|
||||||
@ -328,7 +328,7 @@ object RoCCDecode extends DecodeConstants
|
|||||||
CUSTOM3_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N))
|
CUSTOM3_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N,N))
|
||||||
}
|
}
|
||||||
|
|
||||||
class Control extends Module
|
class Control extends CoreModule
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val dpath = new CtrlDpathIO
|
val dpath = new CtrlDpathIO
|
||||||
@ -388,7 +388,7 @@ class Control extends Module
|
|||||||
val id_reg_fence = Reg(init=Bool(false))
|
val id_reg_fence = Reg(init=Bool(false))
|
||||||
|
|
||||||
val sr = io.dpath.status
|
val sr = io.dpath.status
|
||||||
var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (params(XprLen)-1) | i)))
|
var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (xLen-1) | i)))
|
||||||
|
|
||||||
val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts)
|
val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts)
|
||||||
val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked
|
val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked
|
||||||
|
@ -7,7 +7,7 @@ import Instructions._
|
|||||||
import Util._
|
import Util._
|
||||||
import uncore._
|
import uncore._
|
||||||
|
|
||||||
class Datapath extends Module
|
class Datapath extends CoreModule
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val host = new HTIFIO
|
val host = new HTIFIO
|
||||||
@ -149,10 +149,10 @@ class Datapath extends Module
|
|||||||
io.fpu.fromint_data := ex_rs(0)
|
io.fpu.fromint_data := ex_rs(0)
|
||||||
|
|
||||||
def vaSign(a0: UInt, ea: Bits) = {
|
def vaSign(a0: UInt, ea: Bits) = {
|
||||||
// efficient means to compress 64-bit VA into params(VAddrBits)+1 bits
|
// efficient means to compress 64-bit VA into vaddrBits+1 bits
|
||||||
// (VA is bad if VA(params(VAddrBits)) != VA(params(VAddrBits)-1))
|
// (VA is bad if VA(vaddrBits) != VA(vaddrBits-1))
|
||||||
val a = a0 >> params(VAddrBits)-1
|
val a = a0 >> vaddrBits-1
|
||||||
val e = ea(params(VAddrBits),params(VAddrBits)-1)
|
val e = ea(vaddrBits,vaddrBits-1)
|
||||||
Mux(a === UInt(0) || a === UInt(1), e != UInt(0),
|
Mux(a === UInt(0) || a === UInt(1), e != UInt(0),
|
||||||
Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1),
|
Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1),
|
||||||
e(0)))
|
e(0)))
|
||||||
@ -160,7 +160,7 @@ class Datapath extends Module
|
|||||||
|
|
||||||
// D$ request interface (registered inside D$ module)
|
// D$ request interface (registered inside D$ module)
|
||||||
// other signals (req_val, req_rdy) connect to control module
|
// other signals (req_val, req_rdy) connect to control module
|
||||||
io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(params(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(io.ctrl.ex_waddr, io.ctrl.ex_ctrl.fp)
|
io.dmem.req.bits.tag := Cat(io.ctrl.ex_waddr, io.ctrl.ex_ctrl.fp)
|
||||||
require(io.dmem.req.bits.tag.getWidth >= 6)
|
require(io.dmem.req.bits.tag.getWidth >= 6)
|
||||||
require(params(CoreDCacheReqTagBits) >= 6)
|
require(params(CoreDCacheReqTagBits) >= 6)
|
||||||
@ -231,7 +231,7 @@ class Datapath extends Module
|
|||||||
val mem_br_target = mem_reg_pc +
|
val mem_br_target = mem_reg_pc +
|
||||||
Mux(io.ctrl.mem_ctrl.branch && io.ctrl.mem_br_taken, imm(IMM_SB, mem_reg_inst),
|
Mux(io.ctrl.mem_ctrl.branch && io.ctrl.mem_br_taken, imm(IMM_SB, mem_reg_inst),
|
||||||
Mux(io.ctrl.mem_ctrl.jal, imm(IMM_UJ, mem_reg_inst), SInt(4)))
|
Mux(io.ctrl.mem_ctrl.jal, imm(IMM_UJ, mem_reg_inst), SInt(4)))
|
||||||
val mem_npc = Mux(io.ctrl.mem_ctrl.jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(params(VAddrBits)-1,0)), mem_br_target)
|
val mem_npc = Mux(io.ctrl.mem_ctrl.jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(vaddrBits-1,0)), mem_br_target)
|
||||||
io.ctrl.mem_misprediction := mem_npc != ex_reg_pc || !io.ctrl.ex_valid
|
io.ctrl.mem_misprediction := mem_npc != ex_reg_pc || !io.ctrl.ex_valid
|
||||||
io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1
|
io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1
|
||||||
val mem_int_wdata = Mux(io.ctrl.mem_ctrl.jalr, mem_br_target, mem_reg_wdata)
|
val mem_int_wdata = Mux(io.ctrl.mem_ctrl.jalr, mem_br_target, mem_reg_wdata)
|
||||||
|
@ -43,13 +43,13 @@ object ALU
|
|||||||
}
|
}
|
||||||
import ALU._
|
import ALU._
|
||||||
|
|
||||||
class ALUIO extends Bundle {
|
class ALUIO extends CoreBundle {
|
||||||
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, params(XprLen))
|
val in2 = UInt(INPUT, xLen)
|
||||||
val in1 = UInt(INPUT, params(XprLen))
|
val in1 = UInt(INPUT, xLen)
|
||||||
val out = UInt(OUTPUT, params(XprLen))
|
val out = UInt(OUTPUT, xLen)
|
||||||
val adder_out = UInt(OUTPUT, params(XprLen))
|
val adder_out = UInt(OUTPUT, xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ALU extends Module
|
class ALU extends Module
|
||||||
|
@ -4,7 +4,6 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
case object NITLBEntries extends Field[Int]
|
|
||||||
case object ECCCode extends Field[Option[Code]]
|
case object ECCCode extends Field[Option[Code]]
|
||||||
|
|
||||||
abstract trait L1CacheParameters extends CacheParameters with CoreParameters {
|
abstract trait L1CacheParameters extends CacheParameters with CoreParameters {
|
||||||
@ -20,18 +19,18 @@ abstract class FrontendBundle extends Bundle with FrontendParameters
|
|||||||
abstract class FrontendModule extends Module with FrontendParameters
|
abstract class FrontendModule extends Module with FrontendParameters
|
||||||
|
|
||||||
class FrontendReq extends CoreBundle {
|
class FrontendReq extends CoreBundle {
|
||||||
val pc = UInt(width = params(VAddrBits)+1)
|
val pc = UInt(width = vaddrBits+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrontendResp extends CoreBundle {
|
class FrontendResp extends CoreBundle {
|
||||||
val pc = UInt(width = params(VAddrBits)+1) // ID stage PC
|
val pc = UInt(width = vaddrBits+1) // ID stage PC
|
||||||
val data = Vec.fill(coreFetchWidth) (Bits(width = coreInstBits))
|
val data = Vec.fill(coreFetchWidth) (Bits(width = coreInstBits))
|
||||||
val mask = Bits(width = coreFetchWidth)
|
val mask = Bits(width = coreFetchWidth)
|
||||||
val xcpt_ma = Bool()
|
val xcpt_ma = Bool()
|
||||||
val xcpt_if = Bool()
|
val xcpt_if = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class CPUFrontendIO extends CoreBundle {
|
class CPUFrontendIO extends Bundle {
|
||||||
val req = Valid(new FrontendReq)
|
val req = Valid(new FrontendReq)
|
||||||
val resp = Decoupled(new FrontendResp).flip
|
val resp = Decoupled(new FrontendResp).flip
|
||||||
val btb_resp = Valid(new BTBResp).flip
|
val btb_resp = Valid(new BTBResp).flip
|
||||||
@ -51,7 +50,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule
|
|||||||
|
|
||||||
val btb = Module(new BTB(btb_updates_out_of_order))
|
val btb = Module(new BTB(btb_updates_out_of_order))
|
||||||
val icache = Module(new ICache)
|
val icache = Module(new ICache)
|
||||||
val tlb = Module(new TLB(params(NITLBEntries)))
|
val tlb = Module(new TLB)
|
||||||
|
|
||||||
val s1_pc_ = Reg(UInt())
|
val s1_pc_ = Reg(UInt())
|
||||||
val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline)
|
val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline)
|
||||||
@ -134,7 +133,7 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule
|
|||||||
|
|
||||||
class ICacheReq extends FrontendBundle {
|
class ICacheReq extends FrontendBundle {
|
||||||
val idx = UInt(width = pgIdxBits)
|
val idx = UInt(width = pgIdxBits)
|
||||||
val ppn = UInt(width = params(PPNBits)) // delayed one cycle
|
val ppn = UInt(width = ppnBits) // delayed one cycle
|
||||||
val kill = Bool() // delayed one cycle
|
val kill = Bool() // delayed one cycle
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,14 +189,15 @@ class ICache extends FrontendModule
|
|||||||
val s2_miss = s2_valid && !s2_any_tag_hit
|
val s2_miss = s2_valid && !s2_any_tag_hit
|
||||||
rdy := state === s_ready && !s2_miss
|
rdy := state === s_ready && !s2_miss
|
||||||
|
|
||||||
val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCyclesPerBeat, (g: Grant) => co.messageUpdatesDataArray(g)))
|
val ser = Module(new FlowThroughSerializer(
|
||||||
|
io.mem.grant.bits,
|
||||||
|
refillCyclesPerBeat))
|
||||||
ser.io.in <> io.mem.grant
|
ser.io.in <> io.mem.grant
|
||||||
val (refill_cnt, refill_wrap) = Counter(ser.io.out.fire(), refillCycles) //TODO Zero width wire
|
val (refill_cnt, refill_wrap) = Counter(ser.io.out.fire(), refillCycles) //TODO Zero width wire
|
||||||
val refill_done = state === s_refill && refill_wrap
|
val refill_done = state === s_refill && refill_wrap
|
||||||
val refill_valid = ser.io.out.valid
|
val refill_valid = ser.io.out.valid
|
||||||
val refill_bits = ser.io.out.bits
|
val refill_bits = ser.io.out.bits
|
||||||
ser.io.out.ready := Bool(true)
|
ser.io.out.ready := Bool(true)
|
||||||
//assert(!c.tlco.isVoluntary(refill_bits.payload) || !refill_valid, "UncachedRequestors shouldn't get voluntary grants.")
|
|
||||||
|
|
||||||
val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0)
|
val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0)
|
||||||
val entagbits = code.width(tagBits)
|
val entagbits = code.width(tagBits)
|
||||||
@ -251,7 +251,7 @@ class ICache extends FrontendModule
|
|||||||
val s1_raddr = Reg(UInt())
|
val s1_raddr = Reg(UInt())
|
||||||
when (refill_valid && repl_way === UInt(i)) {
|
when (refill_valid && repl_way === UInt(i)) {
|
||||||
val e_d = code.encode(refill_bits.payload.data)
|
val e_d = code.encode(refill_bits.payload.data)
|
||||||
if(refillCycles > 1) data_array(Cat(s2_idx, refill_cnt)) := e_d
|
if(refillCycles > 1) data_array(Cat(s2_idx, refill_bits.payload.addr_beat)) := e_d
|
||||||
else data_array(s2_idx) := e_d
|
else data_array(s2_idx) := e_d
|
||||||
}
|
}
|
||||||
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
||||||
@ -266,14 +266,14 @@ class ICache extends FrontendModule
|
|||||||
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
||||||
|
|
||||||
val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
|
val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
|
||||||
ack_q.io.enq.valid := refill_done && co.requiresAckForGrant(refill_bits.payload)
|
ack_q.io.enq.valid := refill_done && refill_bits.payload.requiresAck()
|
||||||
ack_q.io.enq.bits.payload.manager_xact_id := refill_bits.payload.manager_xact_id
|
ack_q.io.enq.bits.payload := refill_bits.payload.makeFinish()
|
||||||
ack_q.io.enq.bits.header.dst := refill_bits.header.src
|
ack_q.io.enq.bits.header.dst := refill_bits.header.src
|
||||||
|
|
||||||
// output signals
|
// output signals
|
||||||
io.resp.valid := s2_hit
|
io.resp.valid := s2_hit
|
||||||
io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready
|
io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready
|
||||||
io.mem.acquire.bits.payload := UncachedRead(s2_addr >> UInt(blockOffBits))
|
io.mem.acquire.bits.payload := UncachedReadBlock(addr_block = s2_addr >> UInt(blockOffBits))
|
||||||
io.mem.finish <> ack_q.io.deq
|
io.mem.finish <> ack_q.io.deq
|
||||||
|
|
||||||
// control state machine
|
// control state machine
|
||||||
|
@ -6,16 +6,16 @@ import Chisel._
|
|||||||
import ALU._
|
import ALU._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class MultiplierReq extends Bundle {
|
class MultiplierReq extends CoreBundle {
|
||||||
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 = params(XprLen))
|
val in1 = Bits(width = xLen)
|
||||||
val in2 = Bits(width = params(XprLen))
|
val in2 = Bits(width = xLen)
|
||||||
val tag = UInt(width = log2Up(params(NMultXpr)))
|
val tag = UInt(width = log2Up(params(NMultXpr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplierResp extends Bundle {
|
class MultiplierResp extends CoreBundle {
|
||||||
val data = Bits(width = params(XprLen))
|
val data = Bits(width = xLen)
|
||||||
val tag = UInt(width = log2Up(params(NMultXpr)))
|
val tag = UInt(width = log2Up(params(NMultXpr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,17 +6,21 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
|
case object WordBits extends Field[Int]
|
||||||
case object StoreDataQueueDepth extends Field[Int]
|
case object StoreDataQueueDepth extends Field[Int]
|
||||||
case object ReplayQueueDepth extends Field[Int]
|
case object ReplayQueueDepth extends Field[Int]
|
||||||
case object NMSHRs extends Field[Int]
|
case object NMSHRs extends Field[Int]
|
||||||
case object LRSCCycles extends Field[Int]
|
case object LRSCCycles extends Field[Int]
|
||||||
case object NDTLBEntries extends Field[Int]
|
|
||||||
|
|
||||||
abstract trait L1HellaCacheParameters extends L1CacheParameters {
|
abstract trait L1HellaCacheParameters extends L1CacheParameters {
|
||||||
|
val wordBits = params(WordBits)
|
||||||
|
val wordBytes = wordBits/8
|
||||||
|
val wordOffBits = log2Up(wordBytes)
|
||||||
val idxMSB = untagBits-1
|
val idxMSB = untagBits-1
|
||||||
val idxLSB = blockOffBits
|
val idxLSB = blockOffBits
|
||||||
val offsetmsb = idxLSB-1
|
val offsetmsb = idxLSB-1
|
||||||
val offsetlsb = wordOffBits
|
val offsetlsb = wordOffBits
|
||||||
|
val rowWords = rowBits/wordBits
|
||||||
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
|
||||||
@ -27,64 +31,39 @@ abstract trait L1HellaCacheParameters extends L1CacheParameters {
|
|||||||
abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters
|
abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters
|
||||||
abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters
|
abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters
|
||||||
|
|
||||||
class StoreGen(typ: Bits, addr: Bits, dat: Bits)
|
trait HasCoreMemOp extends CoreBundle {
|
||||||
{
|
val addr = UInt(width = coreMaxAddrBits)
|
||||||
val byte = typ === MT_B || typ === MT_BU
|
val tag = Bits(width = coreDCacheReqTagBits)
|
||||||
val half = typ === MT_H || typ === MT_HU
|
val cmd = Bits(width = M_SZ)
|
||||||
val word = typ === MT_W || typ === MT_WU
|
val typ = Bits(width = MT_SZ)
|
||||||
def mask =
|
|
||||||
Mux(byte, Bits( 1) << addr(2,0),
|
|
||||||
Mux(half, Bits( 3) << Cat(addr(2,1), Bits(0,1)),
|
|
||||||
Mux(word, Bits( 15) << Cat(addr(2), Bits(0,2)),
|
|
||||||
Bits(255))))
|
|
||||||
def data =
|
|
||||||
Mux(byte, Fill(8, dat( 7,0)),
|
|
||||||
Mux(half, Fill(4, dat(15,0)),
|
|
||||||
wordData))
|
|
||||||
lazy val wordData =
|
|
||||||
Mux(word, Fill(2, dat(31,0)),
|
|
||||||
dat)
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadGen(typ: Bits, addr: Bits, dat: Bits, zero: Bool)
|
|
||||||
{
|
|
||||||
val t = new StoreGen(typ, addr, dat)
|
|
||||||
val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D
|
|
||||||
|
|
||||||
val wordShift = Mux(addr(2), dat(63,32), dat(31,0))
|
|
||||||
val word = Cat(Mux(t.word, Fill(32, sign && wordShift(31)), dat(63,32)), wordShift)
|
|
||||||
val halfShift = Mux(addr(1), word(31,16), word(15,0))
|
|
||||||
val half = Cat(Mux(t.half, Fill(48, sign && halfShift(15)), word(63,16)), halfShift)
|
|
||||||
val byteShift = Mux(zero, UInt(0), Mux(addr(0), half(15,8), half(7,0)))
|
|
||||||
val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasCoreData extends CoreBundle {
|
trait HasCoreData extends CoreBundle {
|
||||||
val data = Bits(width = coreDataBits)
|
val data = Bits(width = coreDataBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheReqInternal extends CoreBundle {
|
trait HasSDQId extends CoreBundle with L1HellaCacheParameters {
|
||||||
val kill = Bool()
|
val sdq_id = UInt(width = log2Up(sdqDepth))
|
||||||
val typ = Bits(width = MT_SZ)
|
|
||||||
val phys = Bool()
|
|
||||||
val addr = UInt(width = coreMaxAddrBits)
|
|
||||||
val tag = Bits(width = coreDCacheReqTagBits)
|
|
||||||
val cmd = Bits(width = M_SZ)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheReq extends HellaCacheReqInternal
|
trait HasMissInfo extends CoreBundle with L1HellaCacheParameters {
|
||||||
with HasCoreData
|
val tag_match = Bool()
|
||||||
|
val old_meta = new L1Metadata
|
||||||
|
val way_en = Bits(width = nWays)
|
||||||
|
}
|
||||||
|
|
||||||
class HellaCacheResp extends CoreBundle
|
class HellaCacheReqInternal extends HasCoreMemOp {
|
||||||
with HasCoreData {
|
val kill = Bool()
|
||||||
|
val phys = Bool()
|
||||||
|
}
|
||||||
|
|
||||||
|
class HellaCacheReq extends HellaCacheReqInternal with HasCoreData
|
||||||
|
|
||||||
|
class HellaCacheResp extends 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 typ = Bits(width = 3)
|
|
||||||
val has_data = Bool()
|
val has_data = Bool()
|
||||||
val data_subword = Bits(width = coreDataBits)
|
val data_subword = Bits(width = coreDataBits)
|
||||||
val tag = Bits(width = coreDCacheReqTagBits)
|
|
||||||
val cmd = Bits(width = 4)
|
|
||||||
val addr = UInt(width = coreMaxAddrBits)
|
|
||||||
val store_data = Bits(width = coreDataBits)
|
val store_data = Bits(width = coreDataBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,27 +87,12 @@ class HellaCacheIO extends CoreBundle {
|
|||||||
val ordered = Bool(INPUT)
|
val ordered = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasSDQId extends CoreBundle with L1HellaCacheParameters {
|
class L1DataReadReq extends L1HellaCacheBundle {
|
||||||
val sdq_id = UInt(width = log2Up(sdqDepth))
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasMissInfo extends CoreBundle with L1HellaCacheParameters {
|
|
||||||
val tag_match = Bool()
|
|
||||||
val old_meta = new L1Metadata
|
|
||||||
val way_en = Bits(width = nWays)
|
|
||||||
}
|
|
||||||
|
|
||||||
class Replay extends HellaCacheReqInternal with HasCoreData
|
|
||||||
class ReplayInternal extends HellaCacheReqInternal with HasSDQId
|
|
||||||
class MSHRReq extends Replay with HasMissInfo
|
|
||||||
class MSHRReqInternal extends ReplayInternal with HasMissInfo
|
|
||||||
|
|
||||||
class DataReadReq extends L1HellaCacheBundle {
|
|
||||||
val way_en = Bits(width = nWays)
|
val way_en = Bits(width = nWays)
|
||||||
val addr = Bits(width = untagBits)
|
val addr = Bits(width = untagBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataWriteReq extends DataReadReq {
|
class L1DataWriteReq extends L1DataReadReq {
|
||||||
val wmask = Bits(width = rowWords)
|
val wmask = Bits(width = rowWords)
|
||||||
val data = Bits(width = encRowBits)
|
val data = Bits(width = encRowBits)
|
||||||
}
|
}
|
||||||
@ -152,14 +116,16 @@ class L1Metadata extends Metadata with L1HellaCacheParameters {
|
|||||||
val coh = co.clientMetadataOnFlush.clone
|
val coh = co.clientMetadataOnFlush.clone
|
||||||
}
|
}
|
||||||
|
|
||||||
class InternalProbe extends Probe with HasClientTransactionId
|
class Replay extends HellaCacheReqInternal with HasCoreData
|
||||||
|
class ReplayInternal extends HellaCacheReqInternal with HasSDQId
|
||||||
|
|
||||||
class WritebackReq extends L1HellaCacheBundle {
|
class MSHRReq extends Replay with HasMissInfo
|
||||||
val tag = Bits(width = tagBits)
|
class MSHRReqInternal extends ReplayInternal with HasMissInfo
|
||||||
val idx = Bits(width = idxBits)
|
|
||||||
|
class ProbeInternal extends Probe with HasClientTransactionId
|
||||||
|
|
||||||
|
class WritebackReq extends Release with CacheParameters {
|
||||||
val way_en = Bits(width = nWays)
|
val way_en = Bits(width = nWays)
|
||||||
val client_xact_id = Bits(width = params(TLClientXactIdBits))
|
|
||||||
val r_type = UInt(width = co.releaseTypeWidth)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHR(id: Int) extends L1HellaCacheModule {
|
class MSHR(id: Int) extends L1HellaCacheModule {
|
||||||
@ -174,7 +140,7 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
val tag = Bits(OUTPUT, tagBits)
|
val tag = Bits(OUTPUT, tagBits)
|
||||||
|
|
||||||
val mem_req = Decoupled(new Acquire)
|
val mem_req = Decoupled(new Acquire)
|
||||||
val mem_resp = new DataWriteReq().asOutput
|
val mem_resp = new L1DataWriteReq().asOutput
|
||||||
val meta_read = Decoupled(new L1MetaReadReq)
|
val meta_read = Decoupled(new L1MetaReadReq)
|
||||||
val meta_write = Decoupled(new L1MetaWriteReq)
|
val meta_write = Decoupled(new L1MetaWriteReq)
|
||||||
val replay = Decoupled(new ReplayInternal)
|
val replay = Decoupled(new ReplayInternal)
|
||||||
@ -188,17 +154,19 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
val state = Reg(init=s_invalid)
|
val state = Reg(init=s_invalid)
|
||||||
|
|
||||||
val acquire_type = Reg(UInt())
|
val acquire_type = Reg(UInt())
|
||||||
val release_type = Reg(UInt())
|
|
||||||
val line_state = Reg(new ClientMetadata)
|
val line_state = Reg(new ClientMetadata)
|
||||||
val req = Reg(new MSHRReqInternal())
|
val req = Reg(new MSHRReqInternal())
|
||||||
|
|
||||||
val req_cmd = io.req_bits.cmd
|
val req_cmd = io.req_bits.cmd
|
||||||
val req_idx = req.addr(untagBits-1,blockOffBits)
|
val req_idx = req.addr(untagBits-1,blockOffBits)
|
||||||
val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits)
|
val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits)
|
||||||
val sec_rdy = idx_match && (state === s_wb_req || state === s_wb_resp || state === s_meta_clear || (state === s_refill_req || state === s_refill_resp) && !co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits))
|
val sec_rdy = idx_match && !co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits) &&
|
||||||
|
Vec(s_wb_req, s_wb_resp, s_meta_clear, s_refill_req, s_refill_resp).contains(state)
|
||||||
|
|
||||||
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
|
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
|
||||||
val (refill_cnt, refill_done) = Counter(reply && co.messageUpdatesDataArray(io.mem_grant.bits.payload), refillCycles) // TODO: Zero width?
|
val gnt_multi_data = io.mem_grant.bits.payload.hasMultibeatData()
|
||||||
|
val (refill_cnt, refill_count_done) = Counter(reply && gnt_multi_data, refillCycles) // TODO: Zero width?
|
||||||
|
val refill_done = reply && (!gnt_multi_data || refill_count_done)
|
||||||
val wb_done = reply && (state === s_wb_resp)
|
val wb_done = reply && (state === s_wb_resp)
|
||||||
|
|
||||||
val meta_on_flush = co.clientMetadataOnFlush
|
val meta_on_flush = co.clientMetadataOnFlush
|
||||||
@ -234,16 +202,14 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
state := s_meta_clear
|
state := s_meta_clear
|
||||||
}
|
}
|
||||||
when (io.wb_req.fire()) { // s_wb_req
|
when (io.wb_req.fire()) { // s_wb_req
|
||||||
state := s_wb_resp
|
state := Mux(io.wb_req.bits.requiresAck(), s_wb_resp, s_meta_clear)
|
||||||
}
|
}
|
||||||
when (io.req_sec_val && io.req_sec_rdy) { // s_wb_req, s_wb_resp, s_refill_req
|
when (io.req_sec_val && io.req_sec_rdy) { // s_wb_req, s_wb_resp, s_refill_req
|
||||||
acquire_type := co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits)
|
acquire_type := co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits)
|
||||||
}
|
}
|
||||||
when (io.req_pri_val && io.req_pri_rdy) {
|
when (io.req_pri_val && io.req_pri_rdy) {
|
||||||
line_state := meta_on_flush
|
line_state := meta_on_flush
|
||||||
refill_cnt := UInt(0)
|
|
||||||
acquire_type := co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush)
|
acquire_type := co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush)
|
||||||
release_type := co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc
|
|
||||||
req := io.req_bits
|
req := io.req_bits
|
||||||
|
|
||||||
when (io.req_bits.tag_match) {
|
when (io.req_bits.tag_match) {
|
||||||
@ -259,8 +225,8 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
|
val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1))
|
||||||
ackq.io.enq.valid := (wb_done || refill_done) && co.requiresAckForGrant(io.mem_grant.bits.payload)
|
ackq.io.enq.valid := (wb_done || refill_done) && io.mem_grant.bits.payload.requiresAck()
|
||||||
ackq.io.enq.bits.payload.manager_xact_id := io.mem_grant.bits.payload.manager_xact_id
|
ackq.io.enq.bits.payload := io.mem_grant.bits.payload.makeFinish()
|
||||||
ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src
|
ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src
|
||||||
val can_finish = state === s_invalid || state === s_refill_req || state === s_refill_resp
|
val can_finish = state === s_invalid || state === s_refill_req || state === s_refill_resp
|
||||||
io.mem_finish.valid := ackq.io.deq.valid && can_finish
|
io.mem_finish.valid := ackq.io.deq.valid && can_finish
|
||||||
@ -286,14 +252,17 @@ class MSHR(id: Int) extends L1HellaCacheModule {
|
|||||||
io.meta_write.bits.way_en := req.way_en
|
io.meta_write.bits.way_en := req.way_en
|
||||||
|
|
||||||
io.wb_req.valid := state === s_wb_req && ackq.io.enq.ready
|
io.wb_req.valid := state === s_wb_req && ackq.io.enq.ready
|
||||||
io.wb_req.bits.tag := req.old_meta.tag
|
io.wb_req.bits := Release.makeVoluntaryWriteback(
|
||||||
io.wb_req.bits.idx := req_idx
|
meta = req.old_meta.coh,
|
||||||
|
client_xact_id = UInt(id),
|
||||||
|
addr_block = Cat(req.old_meta.tag, req_idx))
|
||||||
io.wb_req.bits.way_en := req.way_en
|
io.wb_req.bits.way_en := req.way_en
|
||||||
io.wb_req.bits.client_xact_id := Bits(id)
|
|
||||||
io.wb_req.bits.r_type := co.getReleaseTypeOnVoluntaryWriteback()
|
|
||||||
|
|
||||||
io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready
|
io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready
|
||||||
io.mem_req.bits := Acquire(acquire_type, Cat(io.tag, req_idx).toUInt, Bits(id))
|
io.mem_req.bits := Acquire(
|
||||||
|
a_type = acquire_type,
|
||||||
|
addr_block = Cat(io.tag, req_idx).toUInt,
|
||||||
|
client_xact_id = Bits(id))
|
||||||
io.mem_finish <> ackq.io.deq
|
io.mem_finish <> ackq.io.deq
|
||||||
|
|
||||||
io.meta_read.valid := state === s_drain_rpq
|
io.meta_read.valid := state === s_drain_rpq
|
||||||
@ -317,7 +286,7 @@ class MSHRFile extends L1HellaCacheModule {
|
|||||||
val secondary_miss = Bool(OUTPUT)
|
val secondary_miss = Bool(OUTPUT)
|
||||||
|
|
||||||
val mem_req = Decoupled(new Acquire)
|
val mem_req = Decoupled(new Acquire)
|
||||||
val mem_resp = new DataWriteReq().asOutput
|
val mem_resp = new L1DataWriteReq().asOutput
|
||||||
val meta_read = Decoupled(new L1MetaReadReq)
|
val meta_read = Decoupled(new L1MetaReadReq)
|
||||||
val meta_write = Decoupled(new L1MetaWriteReq)
|
val meta_write = Decoupled(new L1MetaWriteReq)
|
||||||
val replay = Decoupled(new Replay)
|
val replay = Decoupled(new Replay)
|
||||||
@ -341,10 +310,14 @@ class MSHRFile extends L1HellaCacheModule {
|
|||||||
val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits
|
val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits
|
||||||
|
|
||||||
val wbTagList = Vec.fill(nMSHRs){Bits()}
|
val wbTagList = Vec.fill(nMSHRs){Bits()}
|
||||||
val memRespMux = Vec.fill(nMSHRs){new DataWriteReq}
|
val memRespMux = Vec.fill(nMSHRs){new L1DataWriteReq}
|
||||||
val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, nMSHRs))
|
val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, nMSHRs))
|
||||||
val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, nMSHRs))
|
val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, nMSHRs))
|
||||||
val mem_req_arb = Module(new LockingArbiter(new Acquire, nMSHRs, outerDataBeats, co.messageHasData _))
|
val mem_req_arb = Module(new LockingArbiter(
|
||||||
|
new Acquire,
|
||||||
|
nMSHRs,
|
||||||
|
outerDataBeats,
|
||||||
|
(a: Acquire) => a.hasMultibeatData()))
|
||||||
val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), nMSHRs))
|
val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), nMSHRs))
|
||||||
val wb_req_arb = Module(new Arbiter(new WritebackReq, nMSHRs))
|
val wb_req_arb = Module(new Arbiter(new WritebackReq, nMSHRs))
|
||||||
val replay_arb = Module(new Arbiter(new ReplayInternal, nMSHRs))
|
val replay_arb = Module(new Arbiter(new ReplayInternal, nMSHRs))
|
||||||
@ -362,7 +335,7 @@ class MSHRFile extends L1HellaCacheModule {
|
|||||||
|
|
||||||
idxMatch(i) := mshr.io.idx_match
|
idxMatch(i) := mshr.io.idx_match
|
||||||
tagList(i) := mshr.io.tag
|
tagList(i) := mshr.io.tag
|
||||||
wbTagList(i) := mshr.io.wb_req.bits.tag
|
wbTagList(i) := mshr.io.wb_req.bits.addr_block >> UInt(idxBits)
|
||||||
|
|
||||||
alloc_arb.io.in(i).valid := mshr.io.req_pri_rdy
|
alloc_arb.io.in(i).valid := mshr.io.req_pri_rdy
|
||||||
mshr.io.req_pri_val := alloc_arb.io.in(i).ready
|
mshr.io.req_pri_val := alloc_arb.io.in(i).ready
|
||||||
@ -413,9 +386,9 @@ class MSHRFile extends L1HellaCacheModule {
|
|||||||
|
|
||||||
class WritebackUnit extends L1HellaCacheModule {
|
class WritebackUnit extends L1HellaCacheModule {
|
||||||
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)
|
||||||
val data_req = Decoupled(new DataReadReq())
|
val data_req = Decoupled(new L1DataReadReq)
|
||||||
val data_resp = Bits(INPUT, encRowBits)
|
val data_resp = Bits(INPUT, encRowBits)
|
||||||
val release = Decoupled(new Release)
|
val release = Decoupled(new Release)
|
||||||
}
|
}
|
||||||
@ -423,9 +396,10 @@ class WritebackUnit extends L1HellaCacheModule {
|
|||||||
val active = Reg(init=Bool(false))
|
val active = Reg(init=Bool(false))
|
||||||
val r1_data_req_fired = Reg(init=Bool(false))
|
val r1_data_req_fired = Reg(init=Bool(false))
|
||||||
val r2_data_req_fired = Reg(init=Bool(false))
|
val r2_data_req_fired = Reg(init=Bool(false))
|
||||||
val cnt = Reg(init = UInt(0, width = log2Up(refillCycles+1))) //TODO Zero width
|
val data_req_cnt = Reg(init = UInt(0, width = log2Up(refillCycles+1))) //TODO Zero width
|
||||||
val buf_v = (if(refillCyclesPerBeat > 1) Reg(init=Bits(0, width = refillCyclesPerBeat-1)) else Bits(1))
|
val buf_v = (if(refillCyclesPerBeat > 1) Reg(init=Bits(0, width = refillCyclesPerBeat-1)) else Bits(1))
|
||||||
val beat_done = buf_v.andR
|
val beat_done = buf_v.andR
|
||||||
|
val (beat_cnt, all_beats_done) = Counter(io.release.fire(), outerDataBeats)
|
||||||
val req = Reg(new WritebackReq)
|
val req = Reg(new WritebackReq)
|
||||||
|
|
||||||
io.release.valid := false
|
io.release.valid := false
|
||||||
@ -434,59 +408,62 @@ class WritebackUnit extends L1HellaCacheModule {
|
|||||||
r2_data_req_fired := r1_data_req_fired
|
r2_data_req_fired := r1_data_req_fired
|
||||||
when (io.data_req.fire() && io.meta_read.fire()) {
|
when (io.data_req.fire() && io.meta_read.fire()) {
|
||||||
r1_data_req_fired := true
|
r1_data_req_fired := true
|
||||||
cnt := cnt + 1
|
data_req_cnt := data_req_cnt + 1
|
||||||
}
|
}
|
||||||
when (r2_data_req_fired) {
|
when (r2_data_req_fired) {
|
||||||
io.release.valid := beat_done
|
io.release.valid := beat_done
|
||||||
when(!io.release.ready) {
|
when(!io.release.ready) {
|
||||||
r1_data_req_fired := false
|
r1_data_req_fired := false
|
||||||
r2_data_req_fired := false
|
r2_data_req_fired := false
|
||||||
cnt := cnt - Mux[UInt](Bool(refillCycles > 1) && r1_data_req_fired, 2, 1)
|
data_req_cnt := data_req_cnt - Mux[UInt](Bool(refillCycles > 1) && r1_data_req_fired, 2, 1)
|
||||||
} .elsewhen(beat_done) { if(refillCyclesPerBeat > 1) buf_v := 0 }
|
} .elsewhen(beat_done) { if(refillCyclesPerBeat > 1) buf_v := 0 }
|
||||||
when(!r1_data_req_fired) {
|
when(!r1_data_req_fired) {
|
||||||
active := cnt < UInt(refillCycles)
|
active := data_req_cnt < UInt(refillCycles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (io.req.fire()) {
|
when (io.req.fire()) {
|
||||||
active := true
|
active := true
|
||||||
cnt := 0
|
data_req_cnt := 0
|
||||||
if(refillCyclesPerBeat > 1) buf_v := 0
|
if(refillCyclesPerBeat > 1) buf_v := 0
|
||||||
req := io.req.bits
|
req := io.req.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
val fire = active && cnt < UInt(refillCycles)
|
|
||||||
io.req.ready := !active
|
io.req.ready := !active
|
||||||
|
|
||||||
// We reissue the meta read as it sets up the muxing for s2_data_muxed
|
val req_idx = req.addr_block(idxBits-1, 0)
|
||||||
|
val fire = active && data_req_cnt < UInt(refillCycles)
|
||||||
|
|
||||||
|
// We reissue the meta read as it sets up the mux ctrl for s2_data_muxed
|
||||||
io.meta_read.valid := fire
|
io.meta_read.valid := fire
|
||||||
io.meta_read.bits.idx := req.idx
|
io.meta_read.bits.idx := req_idx
|
||||||
io.meta_read.bits.tag := req.tag
|
io.meta_read.bits.tag := req.addr_block >> UInt(idxBits)
|
||||||
|
|
||||||
io.data_req.valid := fire
|
io.data_req.valid := fire
|
||||||
io.data_req.bits.way_en := req.way_en
|
io.data_req.bits.way_en := req.way_en
|
||||||
io.data_req.bits.addr := (if(refillCycles > 1) Cat(req.idx, cnt(log2Up(refillCycles)-1,0))
|
io.data_req.bits.addr := (if(refillCycles > 1)
|
||||||
else req.idx) << rowOffBits
|
Cat(req_idx, data_req_cnt(log2Up(refillCycles)-1,0))
|
||||||
|
else req_idx) << rowOffBits
|
||||||
|
|
||||||
io.release.bits.r_type := req.r_type
|
io.release.bits := req
|
||||||
io.release.bits.addr := Cat(req.tag, req.idx).toUInt
|
io.release.bits.addr_beat := beat_cnt
|
||||||
io.release.bits.client_xact_id := req.client_xact_id
|
io.release.bits.data := (if(refillCyclesPerBeat > 1) {
|
||||||
io.release.bits.data :=
|
// If the cache rows are narrower than a TLDataBeat,
|
||||||
(if(refillCyclesPerBeat > 1) {
|
// then buffer enough data_resps to make a whole beat
|
||||||
val data_buf = Reg(Bits())
|
val data_buf = Reg(Bits())
|
||||||
when(active && r2_data_req_fired && !beat_done) {
|
when(active && r2_data_req_fired && !beat_done) {
|
||||||
data_buf := Cat(io.data_resp, data_buf((refillCyclesPerBeat-1)*encRowBits-1, encRowBits))
|
data_buf := Cat(io.data_resp, data_buf((refillCyclesPerBeat-1)*encRowBits-1, encRowBits))
|
||||||
buf_v := (if(refillCyclesPerBeat > 2)
|
buf_v := (if(refillCyclesPerBeat > 2)
|
||||||
Cat(UInt(1), buf_v(refillCyclesPerBeat-2,1))
|
Cat(UInt(1), buf_v(refillCyclesPerBeat-2,1))
|
||||||
else UInt(1))
|
else UInt(1))
|
||||||
}
|
}
|
||||||
Cat(io.data_resp, data_buf)
|
Cat(io.data_resp, data_buf)
|
||||||
} else { io.data_resp })
|
} else { io.data_resp })
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProbeUnit extends L1HellaCacheModule {
|
class ProbeUnit extends L1HellaCacheModule {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new InternalProbe).flip
|
val req = Decoupled(new ProbeInternal).flip
|
||||||
val rep = Decoupled(new Release)
|
val rep = Decoupled(new Release)
|
||||||
val meta_read = Decoupled(new L1MetaReadReq)
|
val meta_read = Decoupled(new L1MetaReadReq)
|
||||||
val meta_write = Decoupled(new L1MetaWriteReq)
|
val meta_write = Decoupled(new L1MetaWriteReq)
|
||||||
@ -500,7 +477,7 @@ class ProbeUnit extends L1HellaCacheModule {
|
|||||||
val state = Reg(init=s_invalid)
|
val state = Reg(init=s_invalid)
|
||||||
val line_state = Reg(co.clientMetadataOnFlush.clone)
|
val line_state = Reg(co.clientMetadataOnFlush.clone)
|
||||||
val way_en = Reg(Bits())
|
val way_en = Reg(Bits())
|
||||||
val req = Reg(new InternalProbe)
|
val req = Reg(new ProbeInternal)
|
||||||
val hit = way_en.orR
|
val hit = way_en.orR
|
||||||
|
|
||||||
when (state === s_meta_write && io.meta_write.ready) {
|
when (state === s_meta_write && io.meta_write.ready) {
|
||||||
@ -538,36 +515,32 @@ class ProbeUnit extends L1HellaCacheModule {
|
|||||||
state := s_invalid
|
state := s_invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val reply = Mux(hit, req.makeRelease(req.client_xact_id, line_state),
|
||||||
|
req.makeRelease(req.client_xact_id))
|
||||||
io.req.ready := state === s_invalid
|
io.req.ready := state === s_invalid
|
||||||
io.rep.valid := state === s_release &&
|
io.rep.valid := state === s_release &&
|
||||||
!(hit && co.needsWriteback(line_state)) // Otherwise WBU will issue release
|
!(hit && co.needsWriteback(line_state)) // Otherwise WBU will issue release
|
||||||
io.rep.bits := Release(co.getReleaseTypeOnProbe(req,
|
io.rep.bits := reply
|
||||||
Mux(hit, line_state, co.clientMetadataOnFlush)),
|
|
||||||
req.addr,
|
|
||||||
req.client_xact_id)
|
|
||||||
|
|
||||||
io.meta_read.valid := state === s_meta_read
|
io.meta_read.valid := state === s_meta_read
|
||||||
io.meta_read.bits.idx := req.addr
|
io.meta_read.bits.idx := req.addr_block
|
||||||
io.meta_read.bits.tag := req.addr >> idxBits
|
io.meta_read.bits.tag := req.addr_block >> idxBits
|
||||||
|
|
||||||
io.meta_write.valid := state === s_meta_write
|
io.meta_write.valid := state === s_meta_write
|
||||||
io.meta_write.bits.way_en := way_en
|
io.meta_write.bits.way_en := way_en
|
||||||
io.meta_write.bits.idx := req.addr
|
io.meta_write.bits.idx := req.addr_block
|
||||||
|
io.meta_write.bits.data.tag := req.addr_block >> idxBits
|
||||||
io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state)
|
io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state)
|
||||||
io.meta_write.bits.data.tag := req.addr >> UInt(idxBits)
|
|
||||||
|
|
||||||
io.wb_req.valid := state === s_writeback_req
|
io.wb_req.valid := state === s_writeback_req
|
||||||
|
io.wb_req.bits := reply
|
||||||
io.wb_req.bits.way_en := way_en
|
io.wb_req.bits.way_en := way_en
|
||||||
io.wb_req.bits.idx := req.addr
|
|
||||||
io.wb_req.bits.tag := req.addr >> UInt(idxBits)
|
|
||||||
io.wb_req.bits.r_type := co.getReleaseTypeOnProbe(req, Mux(hit, line_state, co.clientMetadataOnFlush))
|
|
||||||
io.wb_req.bits.client_xact_id := req.client_xact_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataArray extends L1HellaCacheModule {
|
class DataArray extends L1HellaCacheModule {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val read = Decoupled(new DataReadReq).flip
|
val read = Decoupled(new L1DataReadReq).flip
|
||||||
val write = Decoupled(new DataWriteReq).flip
|
val write = Decoupled(new L1DataWriteReq).flip
|
||||||
val resp = Vec.fill(nWays){Bits(OUTPUT, encRowBits)}
|
val resp = Vec.fill(nWays){Bits(OUTPUT, encRowBits)}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,47 +585,6 @@ class DataArray extends L1HellaCacheModule {
|
|||||||
io.write.ready := Bool(true)
|
io.write.ready := Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AMOALU extends L1HellaCacheModule {
|
|
||||||
val io = new Bundle {
|
|
||||||
val addr = Bits(INPUT, blockOffBits)
|
|
||||||
val cmd = Bits(INPUT, 4)
|
|
||||||
val typ = Bits(INPUT, 3)
|
|
||||||
val lhs = Bits(INPUT, coreDataBits)
|
|
||||||
val rhs = Bits(INPUT, coreDataBits)
|
|
||||||
val out = Bits(OUTPUT, coreDataBits)
|
|
||||||
}
|
|
||||||
|
|
||||||
require(coreDataBits == 64)
|
|
||||||
val storegen = new StoreGen(io.typ, io.addr, io.rhs)
|
|
||||||
val rhs = storegen.wordData
|
|
||||||
|
|
||||||
val sgned = io.cmd === M_XA_MIN || io.cmd === M_XA_MAX
|
|
||||||
val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU
|
|
||||||
val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU
|
|
||||||
val word = io.typ === MT_W || io.typ === MT_WU || io.typ === MT_B || io.typ === MT_BU
|
|
||||||
|
|
||||||
val mask = SInt(-1,64) ^ (io.addr(2) << 31)
|
|
||||||
val adder_out = (io.lhs & mask).toUInt + (rhs & mask)
|
|
||||||
|
|
||||||
val cmp_lhs = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63))
|
|
||||||
val cmp_rhs = Mux(word && !io.addr(2), rhs(31), rhs(63))
|
|
||||||
val lt_lo = io.lhs(31,0) < rhs(31,0)
|
|
||||||
val lt_hi = io.lhs(63,32) < rhs(63,32)
|
|
||||||
val eq_hi = io.lhs(63,32) === rhs(63,32)
|
|
||||||
val lt = Mux(word, Mux(io.addr(2), lt_hi, lt_lo), lt_hi || eq_hi && lt_lo)
|
|
||||||
val less = Mux(cmp_lhs === cmp_rhs, lt, Mux(sgned, cmp_lhs, cmp_rhs))
|
|
||||||
|
|
||||||
val out = Mux(io.cmd === M_XA_ADD, adder_out,
|
|
||||||
Mux(io.cmd === M_XA_AND, io.lhs & rhs,
|
|
||||||
Mux(io.cmd === M_XA_OR, io.lhs | rhs,
|
|
||||||
Mux(io.cmd === M_XA_XOR, io.lhs ^ rhs,
|
|
||||||
Mux(Mux(less, min, max), io.lhs,
|
|
||||||
storegen.data)))))
|
|
||||||
|
|
||||||
val wmask = FillInterleaved(8, storegen.mask)
|
|
||||||
io.out := wmask & out | ~wmask & io.lhs
|
|
||||||
}
|
|
||||||
|
|
||||||
class HellaCache extends L1HellaCacheModule {
|
class HellaCache extends L1HellaCacheModule {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
@ -693,7 +625,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
val s1_sc = s1_req.cmd === M_XSC
|
val s1_sc = s1_req.cmd === M_XSC
|
||||||
val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd)
|
val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd)
|
||||||
|
|
||||||
val dtlb = Module(new TLB(params(NDTLBEntries)))
|
val dtlb = Module(new TLB)
|
||||||
dtlb.io.ptw <> io.cpu.ptw
|
dtlb.io.ptw <> io.cpu.ptw
|
||||||
dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys
|
dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys
|
||||||
dtlb.io.req.bits.passthrough := s1_req.phys
|
dtlb.io.req.bits.passthrough := s1_req.phys
|
||||||
@ -754,8 +686,8 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
|
|
||||||
// data
|
// data
|
||||||
val data = Module(new DataArray)
|
val data = Module(new DataArray)
|
||||||
val readArb = Module(new Arbiter(new DataReadReq, 4))
|
val readArb = Module(new Arbiter(new L1DataReadReq, 4))
|
||||||
val writeArb = Module(new Arbiter(new DataWriteReq, 2))
|
val writeArb = Module(new Arbiter(new L1DataWriteReq, 2))
|
||||||
data.io.write.valid := writeArb.io.out.valid
|
data.io.write.valid := writeArb.io.out.valid
|
||||||
writeArb.io.out.ready := data.io.write.ready
|
writeArb.io.out.ready := data.io.write.ready
|
||||||
data.io.write.bits := writeArb.io.out.bits
|
data.io.write.bits := writeArb.io.out.bits
|
||||||
@ -837,9 +769,9 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeArb.io.in(0).bits.addr := s3_req.addr
|
writeArb.io.in(0).bits.addr := s3_req.addr
|
||||||
writeArb.io.in(0).bits.wmask := UInt(1) << (if(rowOffBits > offsetlsb)
|
val rowIdx = s3_req.addr(rowOffBits-1,offsetlsb).toUInt
|
||||||
s3_req.addr(rowOffBits-1,offsetlsb).toUInt
|
val rowWMask = UInt(1) << (if(rowOffBits > offsetlsb) rowIdx else UInt(0))
|
||||||
else UInt(0))
|
writeArb.io.in(0).bits.wmask := rowWMask
|
||||||
writeArb.io.in(0).bits.data := Fill(rowWords, s3_req.data)
|
writeArb.io.in(0).bits.data := Fill(rowWords, s3_req.data)
|
||||||
writeArb.io.in(0).valid := s3_valid
|
writeArb.io.in(0).valid := s3_valid
|
||||||
writeArb.io.in(0).bits.way_en := s3_way
|
writeArb.io.in(0).bits.way_en := s3_way
|
||||||
@ -871,7 +803,7 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
||||||
|
|
||||||
// probes and releases
|
// probes and releases
|
||||||
val releaseArb = Module(new LockingArbiter(new Release, 2, outerDataBeats, co.messageHasData _))
|
val releaseArb = Module(new LockingArbiter(new Release, 2, outerDataBeats, (r: Release) => r.hasMultibeatData()))
|
||||||
DecoupledLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release
|
DecoupledLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release
|
||||||
|
|
||||||
val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe)
|
val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe)
|
||||||
@ -886,14 +818,15 @@ class HellaCache extends L1HellaCacheModule {
|
|||||||
prober.io.mshr_rdy := mshrs.io.probe_rdy
|
prober.io.mshr_rdy := mshrs.io.probe_rdy
|
||||||
|
|
||||||
// refills
|
// refills
|
||||||
def doRefill(g: Grant): Bool = co.messageUpdatesDataArray(g)
|
val ser = Module(new FlowThroughSerializer(
|
||||||
val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCyclesPerBeat, doRefill))
|
io.mem.grant.bits,
|
||||||
|
refillCyclesPerBeat))
|
||||||
ser.io.in <> io.mem.grant
|
ser.io.in <> io.mem.grant
|
||||||
val refill = ser.io.out
|
val refill = ser.io.out
|
||||||
mshrs.io.mem_grant.valid := refill.fire()
|
mshrs.io.mem_grant.valid := refill.fire()
|
||||||
mshrs.io.mem_grant.bits := refill.bits
|
mshrs.io.mem_grant.bits := refill.bits
|
||||||
refill.ready := writeArb.io.in(1).ready || !doRefill(refill.bits.payload)
|
refill.ready := writeArb.io.in(1).ready || !refill.bits.payload.hasData()
|
||||||
writeArb.io.in(1).valid := refill.valid && doRefill(refill.bits.payload)
|
writeArb.io.in(1).valid := refill.valid && refill.bits.payload.hasData()
|
||||||
writeArb.io.in(1).bits := mshrs.io.mem_resp
|
writeArb.io.in(1).bits := mshrs.io.mem_resp
|
||||||
writeArb.io.in(1).bits.wmask := SInt(-1)
|
writeArb.io.in(1).bits.wmask := SInt(-1)
|
||||||
writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0)
|
writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0)
|
||||||
@ -1008,15 +941,15 @@ class SimpleHellaCacheIF extends Module
|
|||||||
io.cache.req.bits.data := RegEnable(req_arb.io.out.bits.data, s0_req_fire)
|
io.cache.req.bits.data := RegEnable(req_arb.io.out.bits.data, s0_req_fire)
|
||||||
io.cache.req <> req_arb.io.out
|
io.cache.req <> req_arb.io.out
|
||||||
|
|
||||||
// replay queues
|
/* replay queues:
|
||||||
// replayq1 holds the older request
|
replayq1 holds the older request.
|
||||||
// replayq2 holds the newer request (for the first nack)
|
replayq2 holds the newer request (for the first nack).
|
||||||
// we need to split the queues like this for the case where the older request
|
We need to split the queues like this for the case where the older request
|
||||||
// goes through but gets nacked, while the newer request stalls
|
goes through but gets nacked, while the newer request stalls.
|
||||||
// if this happens, the newer request will go through before the older
|
If this happens, the newer request will go through before the older one.
|
||||||
// request
|
We don't need to check replayq1.io.enq.ready and replayq2.io.enq.ready as
|
||||||
// we don't need to check replayq1.io.enq.ready and replayq2.io.enq.ready as
|
there will only be two requests going through at most.
|
||||||
// there will only be two requests going through at most
|
*/
|
||||||
|
|
||||||
// stash d$ request in stage 2 if nacked (older request)
|
// stash d$ request in stage 2 if nacked (older request)
|
||||||
replayq1.io.enq.valid := Bool(false)
|
replayq1.io.enq.valid := Bool(false)
|
||||||
|
@ -6,28 +6,28 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import Util._
|
import Util._
|
||||||
|
|
||||||
class PTWResp extends Bundle {
|
class PTWResp extends CoreBundle {
|
||||||
val error = Bool()
|
val error = Bool()
|
||||||
val ppn = UInt(width = params(PPNBits))
|
val ppn = UInt(width = ppnBits)
|
||||||
val perm = Bits(width = params(PermBits))
|
val perm = Bits(width = permBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBPTWIO extends Bundle {
|
class TLBPTWIO extends CoreBundle {
|
||||||
val req = Decoupled(UInt(width = params(VPNBits)))
|
val req = Decoupled(UInt(width = vpnBits))
|
||||||
val resp = Valid(new PTWResp).flip
|
val resp = Valid(new PTWResp).flip
|
||||||
val status = new Status().asInput
|
val status = new Status().asInput
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val sret = Bool(INPUT)
|
val sret = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DatapathPTWIO extends Bundle {
|
class DatapathPTWIO extends CoreBundle {
|
||||||
val ptbr = UInt(INPUT, params(PAddrBits))
|
val ptbr = UInt(INPUT, paddrBits)
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val sret = Bool(INPUT)
|
val sret = Bool(INPUT)
|
||||||
val status = new Status().asInput
|
val status = new Status().asInput
|
||||||
}
|
}
|
||||||
|
|
||||||
class PTW(n: Int) extends Module
|
class PTW(n: Int) extends CoreModule
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val requestor = Vec.fill(n){new TLBPTWIO}.flip
|
val requestor = Vec.fill(n){new TLBPTWIO}.flip
|
||||||
@ -36,8 +36,8 @@ class PTW(n: Int) extends Module
|
|||||||
}
|
}
|
||||||
|
|
||||||
val levels = 3
|
val levels = 3
|
||||||
val bitsPerLevel = params(VPNBits)/levels
|
val bitsPerLevel = vpnBits/levels
|
||||||
require(params(VPNBits) == levels * bitsPerLevel)
|
require(vpnBits == levels * bitsPerLevel)
|
||||||
|
|
||||||
val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5)
|
val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5)
|
||||||
val state = Reg(init=s_ready)
|
val state = Reg(init=s_ready)
|
||||||
@ -49,14 +49,14 @@ class PTW(n: Int) extends Module
|
|||||||
|
|
||||||
val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count)
|
val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count)
|
||||||
|
|
||||||
val arb = Module(new RRArbiter(UInt(width = params(VPNBits)), n))
|
val arb = Module(new RRArbiter(UInt(width = vpnBits), n))
|
||||||
arb.io.in <> io.requestor.map(_.req)
|
arb.io.in <> io.requestor.map(_.req)
|
||||||
arb.io.out.ready := state === s_ready
|
arb.io.out.ready := state === s_ready
|
||||||
|
|
||||||
when (arb.io.out.fire()) {
|
when (arb.io.out.fire()) {
|
||||||
r_req_vpn := arb.io.out.bits
|
r_req_vpn := arb.io.out.bits
|
||||||
r_req_dest := arb.io.chosen
|
r_req_dest := arb.io.chosen
|
||||||
r_pte := Cat(io.dpath.ptbr(params(PAddrBits)-1,params(PgIdxBits)), io.mem.resp.bits.data(params(PgIdxBits)-1,0))
|
r_pte := Cat(io.dpath.ptbr(paddrBits-1,pgIdxBits), io.mem.resp.bits.data(pgIdxBits-1,0))
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.mem.resp.valid) {
|
when (io.mem.resp.valid) {
|
||||||
@ -67,13 +67,13 @@ class PTW(n: Int) extends Module
|
|||||||
io.mem.req.bits.phys := Bool(true)
|
io.mem.req.bits.phys := Bool(true)
|
||||||
io.mem.req.bits.cmd := M_XRD
|
io.mem.req.bits.cmd := M_XRD
|
||||||
io.mem.req.bits.typ := MT_D
|
io.mem.req.bits.typ := MT_D
|
||||||
io.mem.req.bits.addr := Cat(r_pte(params(PAddrBits)-1,params(PgIdxBits)), vpn_idx).toUInt << log2Up(params(XprLen)/8)
|
io.mem.req.bits.addr := Cat(r_pte(paddrBits-1,pgIdxBits), vpn_idx).toUInt << log2Up(xLen/8)
|
||||||
io.mem.req.bits.kill := Bool(false)
|
io.mem.req.bits.kill := Bool(false)
|
||||||
|
|
||||||
val resp_val = state === s_done || state === s_error
|
val resp_val = state === s_done || state === s_error
|
||||||
val resp_err = state === s_error || state === s_wait
|
val resp_err = state === s_error || state === s_wait
|
||||||
|
|
||||||
val r_resp_ppn = io.mem.req.bits.addr >> UInt(params(PgIdxBits))
|
val r_resp_ppn = io.mem.req.bits.addr >> UInt(pgIdxBits)
|
||||||
val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count)
|
val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count)
|
||||||
|
|
||||||
for (i <- 0 until io.requestor.size) {
|
for (i <- 0 until io.requestor.size) {
|
||||||
|
@ -19,17 +19,17 @@ class RoCCInstruction extends Bundle
|
|||||||
val opcode = Bits(width = 7)
|
val opcode = Bits(width = 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCCommand extends Bundle
|
class RoCCCommand extends CoreBundle
|
||||||
{
|
{
|
||||||
val inst = new RoCCInstruction
|
val inst = new RoCCInstruction
|
||||||
val rs1 = Bits(width = params(XprLen))
|
val rs1 = Bits(width = xLen)
|
||||||
val rs2 = Bits(width = params(XprLen))
|
val rs2 = Bits(width = xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCResponse extends Bundle
|
class RoCCResponse extends CoreBundle
|
||||||
{
|
{
|
||||||
val rd = Bits(width = 5)
|
val rd = Bits(width = 5)
|
||||||
val data = Bits(width = params(XprLen))
|
val data = Bits(width = xLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCInterface extends Bundle
|
class RoCCInterface extends Bundle
|
||||||
@ -50,7 +50,7 @@ class RoCCInterface extends Bundle
|
|||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RoCC extends Module
|
abstract class RoCC extends CoreModule
|
||||||
{
|
{
|
||||||
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
|
||||||
@ -59,7 +59,7 @@ abstract class RoCC extends Module
|
|||||||
class AccumulatorExample extends RoCC
|
class AccumulatorExample extends RoCC
|
||||||
{
|
{
|
||||||
val n = 4
|
val n = 4
|
||||||
val regfile = Mem(UInt(width = params(XprLen)), n)
|
val regfile = Mem(UInt(width = xLen), n)
|
||||||
val busy = Vec.fill(n){Reg(init=Bool(false))}
|
val busy = Vec.fill(n){Reg(init=Bool(false))}
|
||||||
|
|
||||||
val cmd = Queue(io.cmd)
|
val cmd = Queue(io.cmd)
|
||||||
|
@ -6,23 +6,33 @@ import Chisel._
|
|||||||
import uncore._
|
import uncore._
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
class CAMIO(entries: Int, addr_bits: Int, tag_bits: Int) extends Bundle {
|
case object NTLBEntries extends Field[Int]
|
||||||
|
|
||||||
|
abstract trait TLBParameters extends CoreParameters {
|
||||||
|
val entries = params(NTLBEntries)
|
||||||
|
val camAddrBits = ceil(log(entries)/log(2)).toInt
|
||||||
|
val camTagBits = asIdBits + vpnBits
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TLBBundle extends Bundle with TLBParameters
|
||||||
|
abstract class TLBModule extends Module with TLBParameters
|
||||||
|
|
||||||
|
class CAMIO extends TLBBundle {
|
||||||
val clear = Bool(INPUT)
|
val clear = Bool(INPUT)
|
||||||
val clear_hit = Bool(INPUT)
|
val clear_hit = Bool(INPUT)
|
||||||
val tag = Bits(INPUT, tag_bits)
|
val tag = Bits(INPUT, camTagBits)
|
||||||
val hit = Bool(OUTPUT)
|
val hit = Bool(OUTPUT)
|
||||||
val hits = UInt(OUTPUT, entries)
|
val hits = UInt(OUTPUT, entries)
|
||||||
val valid_bits = Bits(OUTPUT, entries)
|
val valid_bits = Bits(OUTPUT, entries)
|
||||||
|
|
||||||
val write = Bool(INPUT)
|
val write = Bool(INPUT)
|
||||||
val write_tag = Bits(INPUT, tag_bits)
|
val write_tag = Bits(INPUT, camTagBits)
|
||||||
val write_addr = UInt(INPUT, addr_bits)
|
val write_addr = UInt(INPUT, camAddrBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCAM(entries: Int, tag_bits: Int) extends Module {
|
class RocketCAM extends TLBModule {
|
||||||
val addr_bits = ceil(log(entries)/log(2)).toInt
|
val io = new CAMIO
|
||||||
val io = new CAMIO(entries, addr_bits, tag_bits)
|
val cam_tags = Mem(Bits(width = camTagBits), entries)
|
||||||
val cam_tags = Mem(Bits(width = tag_bits), entries)
|
|
||||||
|
|
||||||
val vb_array = Reg(init=Bits(0, entries))
|
val vb_array = Reg(init=Bits(0, entries))
|
||||||
when (io.write) {
|
when (io.write) {
|
||||||
@ -66,30 +76,27 @@ class PseudoLRU(n: Int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBReq extends Bundle
|
class TLBReq extends TLBBundle {
|
||||||
{
|
val asid = UInt(width = asIdBits)
|
||||||
val asid = UInt(width = params(ASIdBits))
|
val vpn = UInt(width = vpnBits+1)
|
||||||
val vpn = UInt(width = params(VPNBits)+1)
|
|
||||||
val passthrough = Bool()
|
val passthrough = Bool()
|
||||||
val instruction = Bool()
|
val instruction = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBResp(entries: Int) extends Bundle
|
class TLBResp(cnt: Option[Int] = None) extends TLBBundle {
|
||||||
{
|
|
||||||
// lookup responses
|
// lookup responses
|
||||||
val miss = Bool(OUTPUT)
|
val miss = Bool(OUTPUT)
|
||||||
val hit_idx = UInt(OUTPUT, entries)
|
val hit_idx = UInt(OUTPUT, cnt.getOrElse(entries))
|
||||||
val ppn = UInt(OUTPUT, params(PPNBits))
|
val ppn = UInt(OUTPUT, ppnBits)
|
||||||
val xcpt_ld = Bool(OUTPUT)
|
val xcpt_ld = Bool(OUTPUT)
|
||||||
val xcpt_st = Bool(OUTPUT)
|
val xcpt_st = Bool(OUTPUT)
|
||||||
val xcpt_if = Bool(OUTPUT)
|
val xcpt_if = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLB(entries: Int) extends Module
|
class TLB extends TLBModule {
|
||||||
{
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new TLBReq).flip
|
val req = Decoupled(new TLBReq).flip
|
||||||
val resp = new TLBResp(entries)
|
val resp = new TLBResp
|
||||||
val ptw = new TLBPTWIO
|
val ptw = new TLBPTWIO
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +105,7 @@ class TLB(entries: Int) extends Module
|
|||||||
val r_refill_tag = Reg(UInt())
|
val r_refill_tag = Reg(UInt())
|
||||||
val r_refill_waddr = Reg(UInt())
|
val r_refill_waddr = Reg(UInt())
|
||||||
|
|
||||||
val tag_cam = Module(new RocketCAM(entries, params(ASIdBits)+params(VPNBits)))
|
val tag_cam = Module(new RocketCAM)
|
||||||
val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries)
|
val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries)
|
||||||
|
|
||||||
val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt
|
val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt
|
||||||
@ -135,7 +142,7 @@ class TLB(entries: Int) extends Module
|
|||||||
val plru = new PseudoLRU(entries)
|
val plru = new PseudoLRU(entries)
|
||||||
val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace)
|
val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace)
|
||||||
|
|
||||||
val bad_va = io.req.bits.vpn(params(VPNBits)) != io.req.bits.vpn(params(VPNBits)-1)
|
val bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1)
|
||||||
val tlb_hit = io.ptw.status.vm && tag_hit
|
val tlb_hit = io.ptw.status.vm && tag_hit
|
||||||
val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va
|
val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user