factor out more global constants
This commit is contained in:
parent
ee081d1671
commit
c5b93798fb
@ -5,17 +5,13 @@ import Node._
|
||||
import Constants._
|
||||
import uncore._
|
||||
|
||||
class ioHellaCacheArbiter(n: Int) extends Bundle
|
||||
class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val requestor = Vec(n) { new ioHellaCache() }.flip
|
||||
val mem = new ioHellaCache
|
||||
val io = new Bundle {
|
||||
val requestor = Vec(n) { new ioHellaCache()(conf.dcache) }.flip
|
||||
val mem = new ioHellaCache()(conf.dcache)
|
||||
}
|
||||
|
||||
class rocketHellaCacheArbiter(n: Int) extends Component
|
||||
{
|
||||
val io = new ioHellaCacheArbiter(n)
|
||||
require(DCACHE_TAG_BITS >= log2Up(n) + CPU_TAG_BITS)
|
||||
|
||||
var req_val = Bool(false)
|
||||
var req_rdy = io.mem.req.ready
|
||||
for (i <- 0 until n)
|
||||
@ -78,7 +74,7 @@ class ioUncachedRequestor extends Bundle {
|
||||
val xact_finish = (new FIFOIO) { new TransactionFinish }
|
||||
}
|
||||
|
||||
class rocketMemArbiter(n: Int) extends Component {
|
||||
class MemArbiter(n: Int) extends Component {
|
||||
val io = new Bundle {
|
||||
val mem = new ioUncachedRequestor
|
||||
val requestor = Vec(n) { new ioUncachedRequestor }.flip
|
||||
|
@ -155,11 +155,6 @@ trait InterruptConstants {
|
||||
}
|
||||
|
||||
abstract trait RocketDcacheConstants extends ArbiterConstants with uncore.constants.AddressConstants {
|
||||
val INST_BITS = 32
|
||||
val CPU_DATA_BITS = 64;
|
||||
val CPU_TAG_BITS = 9;
|
||||
val DCACHE_TAG_BITS = log2Up(DCACHE_PORTS) + CPU_TAG_BITS
|
||||
val LG_REFILL_WIDTH = 4; // log2(cache bus width in bytes)
|
||||
val NMSHR = if (HAVE_VEC) 4 else 2 // number of primary misses
|
||||
require(log2Up(NMSHR)+3 <= uncore.Constants.TILE_XACT_ID_BITS)
|
||||
val NRPQ = 16; // number of secondary misses
|
||||
@ -168,10 +163,6 @@ abstract trait RocketDcacheConstants extends ArbiterConstants with uncore.consta
|
||||
require(OFFSET_BITS == log2Up(uncore.Constants.CACHE_DATA_SIZE_IN_BYTES))
|
||||
require(OFFSET_BITS <= uncore.Constants.X_INIT_WRITE_MASK_BITS)
|
||||
require(log2Up(OFFSET_BITS) <= uncore.Constants.X_INIT_SUBWORD_ADDR_BITS)
|
||||
val IDX_BITS = 7;
|
||||
val TAG_BITS = PADDR_BITS - OFFSET_BITS - IDX_BITS;
|
||||
val NWAYS = 4
|
||||
require(IDX_BITS+OFFSET_BITS <= PGIDX_BITS);
|
||||
}
|
||||
|
||||
trait TLBConstants {
|
||||
|
@ -8,21 +8,21 @@ import hwacha._
|
||||
class ioRocket(implicit conf: RocketConfiguration) extends Bundle
|
||||
{
|
||||
val host = new ioHTIF(conf.ntiles)
|
||||
val imem = new IOCPUFrontend
|
||||
val vimem = new IOCPUFrontend
|
||||
val dmem = new ioHellaCache
|
||||
val imem = new IOCPUFrontend()(conf.icache)
|
||||
val vimem = new IOCPUFrontend()(conf.icache)
|
||||
val dmem = new ioHellaCache()(conf.dcache)
|
||||
}
|
||||
|
||||
class rocketProc(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new ioRocket
|
||||
|
||||
val ctrl = new rocketCtrl
|
||||
val dpath = new rocketDpath
|
||||
val ctrl = new Control
|
||||
val dpath = new Datapath
|
||||
|
||||
val dtlb = new rocketTLB(DTLB_ENTRIES);
|
||||
val ptw = new rocketPTW(if (HAVE_VEC) 3 else 2)
|
||||
val arb = new rocketHellaCacheArbiter(DCACHE_PORTS)
|
||||
val arb = new HellaCacheArbiter(DCACHE_PORTS)
|
||||
|
||||
var vu: vu = null
|
||||
if (HAVE_VEC)
|
||||
@ -199,17 +199,13 @@ class rocketProc(implicit conf: RocketConfiguration) extends Component
|
||||
vu.io.xcpt.hold := ctrl.io.vec_iface.hold
|
||||
|
||||
// hooking up vector memory interface
|
||||
val storegen = new StoreDataGen
|
||||
storegen.io.typ := vu.io.dmem_req.bits.typ
|
||||
storegen.io.din := vu.io.dmem_req.bits.data
|
||||
|
||||
arb.io.requestor(DCACHE_VU).req.valid := vu.io.dmem_req.valid
|
||||
arb.io.requestor(DCACHE_VU).req.bits.kill := vu.io.dmem_req.bits.kill
|
||||
arb.io.requestor(DCACHE_VU).req.bits.cmd := vu.io.dmem_req.bits.cmd
|
||||
arb.io.requestor(DCACHE_VU).req.bits.typ := vu.io.dmem_req.bits.typ
|
||||
arb.io.requestor(DCACHE_VU).req.bits.idx := vu.io.dmem_req.bits.idx
|
||||
arb.io.requestor(DCACHE_VU).req.bits.ppn := Reg(vu.io.dmem_req.bits.ppn)
|
||||
arb.io.requestor(DCACHE_VU).req.bits.data := Reg(storegen.io.dout)
|
||||
arb.io.requestor(DCACHE_VU).req.bits.data := Reg(StoreGen(vu.io.dmem_req.bits.typ, Bits(0), vu.io.dmem_req.bits.data).data)
|
||||
arb.io.requestor(DCACHE_VU).req.bits.tag := vu.io.dmem_req.bits.tag
|
||||
|
||||
vu.io.dmem_req.ready := arb.io.requestor(DCACHE_VU).req.ready
|
||||
|
@ -67,23 +67,7 @@ class ioCtrlDpath extends Bundle()
|
||||
val pcr_replay = Bool(INPUT)
|
||||
}
|
||||
|
||||
class ioCtrlAll extends Bundle()
|
||||
{
|
||||
val dpath = new ioCtrlDpath();
|
||||
val imem = new IOCPUFrontend
|
||||
val dmem = new ioHellaCache
|
||||
val dtlb_val = Bool(OUTPUT);
|
||||
val dtlb_kill = Bool(OUTPUT);
|
||||
val dtlb_rdy = Bool(INPUT);
|
||||
val dtlb_miss = Bool(INPUT);
|
||||
val xcpt_dtlb_ld = Bool(INPUT);
|
||||
val xcpt_dtlb_st = Bool(INPUT);
|
||||
val fpu = new ioCtrlFPU();
|
||||
val vec_dpath = new ioCtrlDpathVec()
|
||||
val vec_iface = new ioCtrlVecInterface()
|
||||
}
|
||||
|
||||
abstract trait rocketCtrlDecodeConstants
|
||||
abstract trait DecodeConstants
|
||||
{
|
||||
val xpr64 = Y;
|
||||
|
||||
@ -98,7 +82,7 @@ abstract trait rocketCtrlDecodeConstants
|
||||
val table: Array[(Bits, List[Bits])]
|
||||
}
|
||||
|
||||
object rocketCtrlXDecode extends rocketCtrlDecodeConstants
|
||||
object XDecode extends DecodeConstants
|
||||
{
|
||||
val table = Array(
|
||||
// jalr eret
|
||||
@ -209,7 +193,7 @@ object rocketCtrlXDecode extends rocketCtrlDecodeConstants
|
||||
RDINSTRET-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,MUL_X, N,Y,WA_RD,WB_IRT,PCR_N,SYNC_N,N,N,N,N))
|
||||
}
|
||||
|
||||
object rocketCtrlFDecode extends rocketCtrlDecodeConstants
|
||||
object FDecode extends DecodeConstants
|
||||
{
|
||||
val table = Array(
|
||||
// jalr eret
|
||||
@ -277,7 +261,7 @@ object rocketCtrlFDecode extends rocketCtrlDecodeConstants
|
||||
FSD-> List(FPU_Y,Y,N,BR_N, N,N,Y,A2_BTYPE,DW_XPR,FN_ADD, Y,M_XWR, MT_D, N,MUL_X, N,N,WA_X, WB_ALU,PCR_N,SYNC_N,N,N,N,N))
|
||||
}
|
||||
|
||||
object rocketCtrlVDecode extends rocketCtrlDecodeConstants
|
||||
object VDecode extends DecodeConstants
|
||||
{
|
||||
val table = Array(
|
||||
// jalr eret
|
||||
@ -334,15 +318,28 @@ object rocketCtrlVDecode extends rocketCtrlDecodeConstants
|
||||
VXCPTHOLD-> List(VEC_Y,N,Y,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,MUL_X, N,N,WA_X, WB_X, PCR_N,SYNC_N,N,N,Y,N))
|
||||
}
|
||||
|
||||
class rocketCtrl extends Component
|
||||
class Control(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new ioCtrlAll();
|
||||
val io = new Bundle {
|
||||
val dpath = new ioCtrlDpath
|
||||
val imem = new IOCPUFrontend()(conf.icache)
|
||||
val dmem = new ioHellaCache()(conf.dcache)
|
||||
val dtlb_val = Bool(OUTPUT)
|
||||
val dtlb_kill = Bool(OUTPUT)
|
||||
val dtlb_rdy = Bool(INPUT)
|
||||
val dtlb_miss = Bool(INPUT)
|
||||
val xcpt_dtlb_ld = Bool(INPUT)
|
||||
val xcpt_dtlb_st = Bool(INPUT)
|
||||
val fpu = new ioCtrlFPU
|
||||
val vec_dpath = new ioCtrlDpathVec
|
||||
val vec_iface = new ioCtrlVecInterface
|
||||
}
|
||||
|
||||
var decode_table = rocketCtrlXDecode.table
|
||||
if (HAVE_FPU) decode_table ++= rocketCtrlFDecode.table
|
||||
if (HAVE_VEC) decode_table ++= rocketCtrlVDecode.table
|
||||
var decode_table = XDecode.table
|
||||
if (HAVE_FPU) decode_table ++= FDecode.table
|
||||
if (HAVE_VEC) decode_table ++= VDecode.table
|
||||
|
||||
val cs = DecodeLogic(io.dpath.inst, rocketCtrlXDecode.decode_default, decode_table)
|
||||
val cs = DecodeLogic(io.dpath.inst, XDecode.decode_default, decode_table)
|
||||
|
||||
val id_int_val :: id_fp_val :: id_vec_val :: id_br_type :: id_jalr :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_fn_dw :: id_fn_alu :: cs0 = cs
|
||||
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_wen :: id_sel_wa :: id_sel_wb :: cs1 = cs0
|
||||
|
@ -6,13 +6,14 @@ import Constants._
|
||||
import Instructions._
|
||||
import hwacha._
|
||||
|
||||
class ioDpathAll(implicit conf: RocketConfiguration) extends Bundle
|
||||
class Datapath(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new Bundle {
|
||||
val host = new ioHTIF(conf.ntiles)
|
||||
val ctrl = new ioCtrlDpath().flip
|
||||
val dmem = new ioHellaCache
|
||||
val dmem = new ioHellaCache()(conf.dcache)
|
||||
val dtlb = new ioDTLB_CPU_req_bundle().asOutput()
|
||||
val imem = new IOCPUFrontend
|
||||
val imem = new IOCPUFrontend()(conf.icache)
|
||||
val ptbr_wen = Bool(OUTPUT);
|
||||
val ptbr = UFix(OUTPUT, PADDR_BITS);
|
||||
val fpu = new ioDpathFPU();
|
||||
@ -22,10 +23,6 @@ class ioDpathAll(implicit conf: RocketConfiguration) extends Bundle
|
||||
val vec_imul_resp = Bits(INPUT, hwacha.Constants.SZ_XLEN)
|
||||
}
|
||||
|
||||
class rocketDpath(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new ioDpathAll();
|
||||
|
||||
val pcr = new rocketDpathPCR();
|
||||
val ex_pcr = pcr.io.r.data;
|
||||
|
||||
@ -215,6 +212,7 @@ class rocketDpath(implicit conf: RocketConfiguration) extends Component
|
||||
io.dmem.req.bits.idx := ex_effective_address
|
||||
io.dmem.req.bits.data := Mux(io.ctrl.mem_fp_val, io.fpu.store_data, mem_reg_rs2)
|
||||
io.dmem.req.bits.tag := Cat(ex_reg_waddr, io.ctrl.ex_fp_val)
|
||||
require(io.dmem.req.bits.tag.getWidth >= 6)
|
||||
io.dtlb.vpn := ex_effective_address >> UFix(PGIDX_BITS)
|
||||
|
||||
// processor control regfile read
|
||||
@ -252,17 +250,12 @@ class rocketDpath(implicit conf: RocketConfiguration) extends Component
|
||||
Mux(ex_reg_ctrl_sel_wb === WB_IRT, irt_reg,
|
||||
ex_alu_out))).toBits // WB_ALU
|
||||
|
||||
// subword store data generation
|
||||
val storegen = new StoreDataGen
|
||||
storegen.io.typ := io.ctrl.ex_mem_type
|
||||
storegen.io.din := ex_rs2
|
||||
|
||||
// memory stage
|
||||
mem_reg_kill := ex_reg_kill
|
||||
when (!ex_reg_kill) {
|
||||
mem_reg_pc := ex_reg_pc
|
||||
mem_reg_inst := ex_reg_inst
|
||||
mem_reg_rs2 := storegen.io.dout
|
||||
mem_reg_rs2 := StoreGen(io.ctrl.ex_mem_type, Bits(0), ex_rs2).data
|
||||
mem_reg_waddr := ex_reg_waddr
|
||||
mem_reg_wdata := ex_wdata
|
||||
mem_reg_raddr1 := ex_reg_raddr1
|
||||
|
@ -10,7 +10,7 @@ case class ICacheConfig(sets: Int, assoc: Int, co: CoherencePolicyWithUncached,
|
||||
parity: Boolean = false)
|
||||
{
|
||||
val w = 1
|
||||
val ibytes = INST_BITS/8
|
||||
val ibytes = 4
|
||||
|
||||
val dm = assoc == 1
|
||||
val lines = sets * assoc
|
||||
@ -37,29 +37,31 @@ class FrontendReq extends Bundle {
|
||||
val currentpc = UFix(width = VADDR_BITS+1)
|
||||
}
|
||||
|
||||
class FrontendResp extends Bundle {
|
||||
class FrontendResp(implicit conf: ICacheConfig) extends Bundle {
|
||||
val pc = UFix(width = VADDR_BITS+1) // ID stage PC
|
||||
val data = Bits(width = INST_BITS)
|
||||
val data = Bits(width = conf.ibytes*8)
|
||||
val taken = Bool()
|
||||
val xcpt_ma = Bool()
|
||||
val xcpt_if = Bool()
|
||||
|
||||
override def clone = new FrontendResp().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class IOCPUFrontend extends Bundle {
|
||||
class IOCPUFrontend(implicit conf: ICacheConfig) extends Bundle {
|
||||
val req = new PipeIO()(new FrontendReq)
|
||||
val resp = new FIFOIO()(new FrontendResp).flip
|
||||
val ptw = new IOTLBPTW().flip
|
||||
}
|
||||
|
||||
class Frontend(c: ICacheConfig) extends Component
|
||||
class Frontend(implicit c: ICacheConfig) extends Component
|
||||
{
|
||||
val io = new Bundle {
|
||||
val cpu = new IOCPUFrontend().flip
|
||||
val cpu = new IOCPUFrontend()(c).flip
|
||||
val mem = new ioUncachedRequestor
|
||||
}
|
||||
|
||||
val btb = new rocketDpathBTB(BTB_ENTRIES)
|
||||
val icache = new ICache(c)
|
||||
val icache = new ICache
|
||||
val tlb = new TLB(ITLB_ENTRIES)
|
||||
|
||||
val s1_pc = Reg() { UFix() }
|
||||
@ -123,7 +125,7 @@ class Frontend(c: ICacheConfig) extends Component
|
||||
io.cpu.resp.bits.xcpt_if := s2_xcpt_if
|
||||
}
|
||||
|
||||
class ICache(c: ICacheConfig) extends Component
|
||||
class ICache(implicit c: ICacheConfig) extends Component
|
||||
{
|
||||
val io = new Bundle {
|
||||
val req = new PipeIO()(new Bundle {
|
||||
@ -133,7 +135,7 @@ class ICache(c: ICacheConfig) extends Component
|
||||
val kill = Bool() // delayed one cycle
|
||||
}).flip
|
||||
val resp = new FIFOIO()(new Bundle {
|
||||
val data = Bits(width = INST_BITS)
|
||||
val data = Bits(width = c.ibytes*8)
|
||||
val datablock = Bits(width = c.databits)
|
||||
})
|
||||
val mem = new ioUncachedRequestor
|
||||
|
@ -4,162 +4,157 @@ import Chisel._
|
||||
import Constants._
|
||||
import uncore._
|
||||
|
||||
class ioReplacementWayGen extends Bundle {
|
||||
val pick_new_way = Bool(dir = INPUT)
|
||||
val way_en = Bits(width = NWAYS, dir = INPUT)
|
||||
val way_id = UFix(width = log2Up(NWAYS), dir = OUTPUT)
|
||||
}
|
||||
|
||||
class RandomReplacementWayGen extends Component {
|
||||
val io = new ioReplacementWayGen()
|
||||
//TODO: Actually limit selection based on which ways are allowed (io.ways_en)
|
||||
io.way_id := UFix(0)
|
||||
if(NWAYS > 1)
|
||||
case class DCacheConfig(sets: Int, ways: Int, co: CoherencePolicy,
|
||||
nmshr: Int, nsecondary: Int, nsdq: Int,
|
||||
reqtagbits: Int = -1)
|
||||
{
|
||||
val rand_way_id = LFSR16(io.pick_new_way)(log2Up(NWAYS)-1,0)
|
||||
when (rand_way_id < UFix(NWAYS)) { io.way_id := rand_way_id }
|
||||
}
|
||||
require(isPow2(sets))
|
||||
require(isPow2(ways)) // TODO: relax this
|
||||
def lines = sets*ways
|
||||
def dm = ways == 1
|
||||
def ppnbits = PPN_BITS
|
||||
def pgidxbits = PGIDX_BITS
|
||||
def offbits = OFFSET_BITS
|
||||
def paddrbits = ppnbits + pgidxbits
|
||||
def lineaddrbits = ppnbits - offbits
|
||||
def idxbits = log2Up(sets)
|
||||
def waybits = log2Up(ways)
|
||||
def tagbits = lineaddrbits - idxbits
|
||||
def databytes = 8 // assumed by StoreGen/LoadGen/AMOALU
|
||||
def databits = databytes*8
|
||||
}
|
||||
|
||||
class StoreMaskGen extends Component {
|
||||
val io = new Bundle {
|
||||
val typ = Bits(INPUT, 3)
|
||||
val addr = Bits(INPUT, 3)
|
||||
val wmask = Bits(OUTPUT, 8)
|
||||
abstract class ReplacementPolicy
|
||||
{
|
||||
def way: UFix
|
||||
def miss: Unit
|
||||
def hit: Unit
|
||||
}
|
||||
|
||||
val word = (io.typ === MT_W) || (io.typ === MT_WU)
|
||||
val half = (io.typ === MT_H) || (io.typ === MT_HU)
|
||||
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU)
|
||||
class RandomReplacement(implicit conf: DCacheConfig) extends ReplacementPolicy
|
||||
{
|
||||
private val replace = Bool()
|
||||
replace := Bool(false)
|
||||
val lfsr = LFSR16(replace)
|
||||
|
||||
io.wmask := Mux(byte_, Bits( 1,1) << io.addr(2,0).toUFix,
|
||||
Mux(half, Bits( 3,2) << Cat(io.addr(2,1), Bits(0,1)).toUFix,
|
||||
Mux(word, Bits( 15,4) << Cat(io.addr(2), Bits(0,2)).toUFix,
|
||||
Bits(255,8))));
|
||||
def way = if (conf.dm) UFix(0) else lfsr(conf.waybits-1,0)
|
||||
def miss = replace := Bool(true)
|
||||
def hit = {}
|
||||
}
|
||||
|
||||
class StoreDataGen extends Component {
|
||||
val io = new Bundle {
|
||||
val typ = Bits(INPUT, 3)
|
||||
val din = Bits(INPUT, 64)
|
||||
val dout = Bits(OUTPUT, 64)
|
||||
case class StoreGen(typ: Bits, addr: Bits, dat: Bits)
|
||||
{
|
||||
val byte = typ === MT_B || typ === MT_BU
|
||||
val half = typ === MT_H || typ === MT_HU
|
||||
val word = typ === MT_W || typ === MT_WU
|
||||
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)),
|
||||
Mux(word, Fill(2, dat(31,0)),
|
||||
dat)))
|
||||
}
|
||||
|
||||
val word = (io.typ === MT_W) || (io.typ === MT_WU)
|
||||
val half = (io.typ === MT_H) || (io.typ === MT_HU)
|
||||
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU)
|
||||
case class LoadGen(typ: Bits, addr: Bits, dat: Bits)
|
||||
{
|
||||
val t = StoreGen(typ, addr, dat)
|
||||
val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D
|
||||
|
||||
io.dout := Mux(byte_, Fill(8, io.din( 7,0)),
|
||||
Mux(half, Fill(4, io.din(15,0)),
|
||||
Mux(word, Fill(2, io.din(31,0)),
|
||||
io.din)))
|
||||
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(addr(0), half(15,8), half(7,0))
|
||||
val byte = Cat(Mux(t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift)
|
||||
}
|
||||
|
||||
// this currently requires that CPU_DATA_BITS == 64
|
||||
class LoadDataGen extends Component {
|
||||
val io = new Bundle {
|
||||
val typ = Bits(INPUT, 3)
|
||||
val addr = Bits(INPUT, log2Up(MEM_DATA_BITS/8))
|
||||
val din = Bits(INPUT, MEM_DATA_BITS)
|
||||
val dout = Bits(OUTPUT, 64)
|
||||
val r_dout = Bits(OUTPUT, 64)
|
||||
val r_dout_subword = Bits(OUTPUT, 64)
|
||||
}
|
||||
|
||||
val sext = (io.typ === MT_B) || (io.typ === MT_H) ||
|
||||
(io.typ === MT_W) || (io.typ === MT_D)
|
||||
val word = (io.typ === MT_W) || (io.typ === MT_WU)
|
||||
val half = (io.typ === MT_H) || (io.typ === MT_HU)
|
||||
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU)
|
||||
|
||||
val shifted = io.din >> Cat(io.addr(io.addr.width-1,2), Bits(0, 5)).toUFix
|
||||
val extended =
|
||||
Mux(word, Cat(Fill(32, sext & shifted(31)), shifted(31,0)), shifted)
|
||||
|
||||
val r_extended = Reg(extended)
|
||||
val r_sext = Reg(sext)
|
||||
val r_half = Reg(half)
|
||||
val r_byte = Reg(byte_)
|
||||
val r_addr = Reg(io.addr)
|
||||
|
||||
val shifted_subword = r_extended >> Cat(r_addr(1,0), Bits(0, 3)).toUFix
|
||||
val extended_subword =
|
||||
Mux(r_byte, Cat(Fill(56, r_sext & shifted_subword( 7)), shifted_subword( 7,0)),
|
||||
Mux(r_half, Cat(Fill(48, r_sext & shifted_subword(15)), shifted_subword(15,0)),
|
||||
shifted_subword))
|
||||
|
||||
io.dout := extended
|
||||
io.r_dout := r_extended
|
||||
io.r_dout_subword := extended_subword
|
||||
}
|
||||
|
||||
class MSHRReq extends Bundle {
|
||||
class MSHRReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val tag_miss = Bool()
|
||||
val old_dirty = Bool()
|
||||
val old_tag = Bits(width = TAG_BITS)
|
||||
val old_tag = Bits(width = conf.tagbits)
|
||||
|
||||
val tag = Bits(width = TAG_BITS)
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
val way_oh = Bits(width = NWAYS)
|
||||
val tag = Bits(width = conf.tagbits)
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val way_oh = Bits(width = conf.ways)
|
||||
|
||||
val offset = Bits(width = OFFSET_BITS)
|
||||
val offset = Bits(width = conf.offbits)
|
||||
val cmd = Bits(width = 4)
|
||||
val typ = Bits(width = 3)
|
||||
val cpu_tag = Bits(width = DCACHE_TAG_BITS)
|
||||
val data = Bits(width = CPU_DATA_BITS)
|
||||
val cpu_tag = Bits(width = conf.reqtagbits)
|
||||
val data = Bits(width = conf.databits)
|
||||
|
||||
override def clone = new MSHRReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class RPQEntry extends Bundle {
|
||||
val offset = Bits(width = OFFSET_BITS)
|
||||
class RPQEntry(implicit conf: DCacheConfig) extends Bundle {
|
||||
val offset = Bits(width = conf.offbits)
|
||||
val cmd = Bits(width = 4)
|
||||
val typ = Bits(width = 3)
|
||||
val sdq_id = UFix(width = log2Up(NSDQ))
|
||||
val cpu_tag = Bits(width = DCACHE_TAG_BITS)
|
||||
val sdq_id = UFix(width = log2Up(conf.nsdq))
|
||||
val cpu_tag = Bits(width = conf.reqtagbits)
|
||||
|
||||
override def clone = new RPQEntry().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class Replay extends RPQEntry {
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
val way_oh = Bits(width = NWAYS)
|
||||
class Replay(implicit conf: DCacheConfig) extends RPQEntry {
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val way_oh = Bits(width = conf.ways)
|
||||
|
||||
override def clone = new Replay().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class DataReq extends Bundle {
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
val offset = Bits(width = OFFSET_BITS)
|
||||
class DataReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val offset = Bits(width = conf.offbits)
|
||||
val cmd = Bits(width = 4)
|
||||
val typ = Bits(width = 3)
|
||||
val data = Bits(width = CPU_DATA_BITS)
|
||||
val way_oh = Bits(width = NWAYS)
|
||||
val data = Bits(width = conf.databits)
|
||||
val way_oh = Bits(width = conf.ways)
|
||||
|
||||
override def clone = new DataReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class DataArrayReq extends Bundle {
|
||||
val way_en = Bits(width = NWAYS)
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
class DataArrayReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val way_en = Bits(width = conf.ways)
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val offset = Bits(width = log2Up(REFILL_CYCLES))
|
||||
val rw = Bool()
|
||||
val wmask = Bits(width = MEM_DATA_BITS/8)
|
||||
val data = Bits(width = MEM_DATA_BITS)
|
||||
|
||||
override def clone = new DataArrayReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class WritebackReq extends Bundle {
|
||||
val tag = Bits(width = TAG_BITS)
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
val way_oh = Bits(width = NWAYS)
|
||||
class WritebackReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val tag = Bits(width = conf.tagbits)
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val way_oh = Bits(width = conf.ways)
|
||||
val tile_xact_id = Bits(width = TILE_XACT_ID_BITS)
|
||||
|
||||
override def clone = new WritebackReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class MetaData extends Bundle {
|
||||
class MetaData(implicit conf: DCacheConfig) extends Bundle {
|
||||
val state = UFix(width = 2)
|
||||
val tag = Bits(width = TAG_BITS)
|
||||
val tag = Bits(width = conf.tagbits)
|
||||
|
||||
override def clone = new MetaData().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class MetaArrayReq extends Bundle {
|
||||
val way_en = Bits(width = NWAYS)
|
||||
val idx = Bits(width = IDX_BITS)
|
||||
class MetaArrayReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val way_en = Bits(width = conf.ways)
|
||||
val idx = Bits(width = conf.idxbits)
|
||||
val rw = Bool()
|
||||
val data = new MetaData()
|
||||
|
||||
override def clone = new MetaArrayReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class MSHR(id: Int)(implicit conf: RocketConfiguration) extends Component {
|
||||
class MSHR(id: Int)(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req_pri_val = Bool(INPUT)
|
||||
val req_pri_rdy = Bool(OUTPUT)
|
||||
@ -169,10 +164,10 @@ class MSHR(id: Int)(implicit conf: RocketConfiguration) extends Component {
|
||||
val req_sdq_id = UFix(INPUT, log2Up(NSDQ))
|
||||
|
||||
val idx_match = Bool(OUTPUT)
|
||||
val idx = Bits(OUTPUT, IDX_BITS)
|
||||
val idx = Bits(OUTPUT, conf.idxbits)
|
||||
val refill_count = Bits(OUTPUT, log2Up(REFILL_CYCLES))
|
||||
val tag = Bits(OUTPUT, TAG_BITS)
|
||||
val way_oh = Bits(OUTPUT, NWAYS)
|
||||
val tag = Bits(OUTPUT, conf.tagbits)
|
||||
val way_oh = Bits(OUTPUT, conf.ways)
|
||||
|
||||
val mem_req = (new FIFOIO) { new TransactionInit }
|
||||
val meta_req = (new FIFOIO) { new MetaArrayReq() }
|
||||
@ -293,14 +288,14 @@ class MSHR(id: Int)(implicit conf: RocketConfiguration) extends Component {
|
||||
io.replay.bits.way_oh := req.way_oh
|
||||
}
|
||||
|
||||
class MSHRFile(implicit conf: RocketConfiguration) extends Component {
|
||||
class MSHRFile(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new MSHRReq }.flip
|
||||
val secondary_miss = Bool(OUTPUT)
|
||||
|
||||
val mem_resp_idx = Bits(OUTPUT, IDX_BITS)
|
||||
val mem_resp_idx = Bits(OUTPUT, conf.idxbits)
|
||||
val mem_resp_offset = Bits(OUTPUT, log2Up(REFILL_CYCLES))
|
||||
val mem_resp_way_oh = Bits(OUTPUT, NWAYS)
|
||||
val mem_resp_way_oh = Bits(OUTPUT, conf.ways)
|
||||
|
||||
val fence_rdy = Bool(OUTPUT)
|
||||
|
||||
@ -314,7 +309,7 @@ class MSHRFile(implicit conf: RocketConfiguration) extends Component {
|
||||
val probe = (new FIFOIO) { Bool() }.flip
|
||||
|
||||
val cpu_resp_val = Bool(OUTPUT)
|
||||
val cpu_resp_tag = Bits(OUTPUT, DCACHE_TAG_BITS)
|
||||
val cpu_resp_tag = Bits(OUTPUT, conf.reqtagbits)
|
||||
}
|
||||
|
||||
val sdq_val = Reg(resetVal = Bits(0, NSDQ))
|
||||
@ -416,7 +411,7 @@ class MSHRFile(implicit conf: RocketConfiguration) extends Component {
|
||||
}
|
||||
|
||||
|
||||
class WritebackUnit(implicit conf: RocketConfiguration) extends Component {
|
||||
class WritebackUnit(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new WritebackReq() }.flip
|
||||
val probe = (new FIFOIO) { new WritebackReq() }.flip
|
||||
@ -485,16 +480,16 @@ class WritebackUnit(implicit conf: RocketConfiguration) extends Component {
|
||||
io.probe_rep_data.bits.data := io.data_resp
|
||||
}
|
||||
|
||||
class ProbeUnit(implicit conf: RocketConfiguration) extends Component {
|
||||
class ProbeUnit(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new ProbeRequest }.flip
|
||||
val rep = (new FIFOIO) { new ProbeReply }
|
||||
val meta_req = (new FIFOIO) { new MetaArrayReq }
|
||||
val mshr_req = (new FIFOIO) { Bool() }
|
||||
val wb_req = (new FIFOIO) { new WritebackReq }
|
||||
val tag_match_way_oh = Bits(INPUT, NWAYS)
|
||||
val tag_match_way_oh = Bits(INPUT, conf.ways)
|
||||
val line_state = UFix(INPUT, 2)
|
||||
val addr = Bits(OUTPUT, PADDR_BITS-OFFSET_BITS)
|
||||
val addr = Bits(OUTPUT, conf.lineaddrbits)
|
||||
}
|
||||
|
||||
val s_reset :: s_invalid :: s_meta_req :: s_meta_resp :: s_mshr_req :: s_probe_rep :: s_writeback_req :: s_writeback_resp :: Nil = Enum(8) { UFix() }
|
||||
@ -535,21 +530,21 @@ class ProbeUnit(implicit conf: RocketConfiguration) extends Component {
|
||||
io.rep.bits := conf.co.newProbeReply(req, Mux(hit, line_state, conf.co.newStateOnFlush))
|
||||
|
||||
io.meta_req.valid := state === s_meta_req || state === s_meta_resp || state === s_mshr_req || state === s_probe_rep && hit
|
||||
io.meta_req.bits.way_en := Mux(state === s_probe_rep, way_oh, ~UFix(0, NWAYS))
|
||||
io.meta_req.bits.way_en := Mux(state === s_probe_rep, way_oh, Fix(-1))
|
||||
io.meta_req.bits.rw := state === s_probe_rep
|
||||
io.meta_req.bits.idx := req.addr
|
||||
io.meta_req.bits.data.state := conf.co.newStateOnProbeRequest(req, line_state)
|
||||
io.meta_req.bits.data.tag := req.addr >> UFix(IDX_BITS)
|
||||
io.meta_req.bits.data.tag := req.addr >> UFix(conf.idxbits)
|
||||
io.mshr_req.valid := state === s_meta_resp || state === s_mshr_req
|
||||
io.addr := req.addr
|
||||
|
||||
io.wb_req.valid := state === s_writeback_req
|
||||
io.wb_req.bits.way_oh := way_oh
|
||||
io.wb_req.bits.idx := req.addr
|
||||
io.wb_req.bits.tag := req.addr >> UFix(IDX_BITS)
|
||||
io.wb_req.bits.tag := req.addr >> UFix(conf.idxbits)
|
||||
}
|
||||
|
||||
class FlushUnit(lines: Int)(implicit conf: RocketConfiguration) extends Component {
|
||||
class FlushUnit(lines: Int)(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { Bool() }.flip
|
||||
val meta_req = (new FIFOIO) { new MetaArrayReq() }
|
||||
@ -560,15 +555,15 @@ class FlushUnit(lines: Int)(implicit conf: RocketConfiguration) extends Componen
|
||||
val state = Reg(resetVal = s_reset)
|
||||
val idx_cnt = Reg(resetVal = UFix(0, log2Up(lines)))
|
||||
val next_idx_cnt = idx_cnt + UFix(1)
|
||||
val way_cnt = if (NWAYS == 1) UFix(0) else Reg(resetVal = UFix(0, log2Up(NWAYS)))
|
||||
val way_cnt = if (conf.dm) UFix(0) else Reg(resetVal = UFix(0, conf.waybits))
|
||||
val next_way_cnt = way_cnt + UFix(1)
|
||||
|
||||
switch (state) {
|
||||
is(s_reset) {
|
||||
when (io.meta_req.ready) {
|
||||
state := Mux(way_cnt === UFix(NWAYS-1) && idx_cnt.andR, s_ready, s_reset);
|
||||
when (way_cnt === UFix(NWAYS-1)) { idx_cnt := next_idx_cnt };
|
||||
if (NWAYS > 1) way_cnt := next_way_cnt;
|
||||
state := Mux(way_cnt === UFix(conf.ways-1) && idx_cnt.andR, s_ready, s_reset);
|
||||
when (way_cnt === UFix(conf.ways-1)) { idx_cnt := next_idx_cnt };
|
||||
if (!conf.dm) way_cnt := next_way_cnt;
|
||||
}
|
||||
}
|
||||
is(s_ready) { when (io.req.valid) { state := s_meta_read } }
|
||||
@ -577,13 +572,13 @@ class FlushUnit(lines: Int)(implicit conf: RocketConfiguration) extends Componen
|
||||
state := s_meta_read
|
||||
when (io.mshr_req.ready) {
|
||||
state := s_meta_read
|
||||
when (way_cnt === UFix(NWAYS-1)) {
|
||||
when (way_cnt === UFix(conf.ways-1)) {
|
||||
when (idx_cnt.andR) {
|
||||
state := s_ready
|
||||
}
|
||||
idx_cnt := next_idx_cnt
|
||||
}
|
||||
if (NWAYS > 1) way_cnt := next_way_cnt;
|
||||
if (!conf.dm) way_cnt := next_way_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -591,35 +586,35 @@ class FlushUnit(lines: Int)(implicit conf: RocketConfiguration) extends Componen
|
||||
io.req.ready := state === s_ready
|
||||
io.mshr_req.valid := state === s_meta_wait
|
||||
io.meta_req.valid := (state === s_meta_read) || (state === s_reset)
|
||||
io.meta_req.bits.way_en := UFixToOH(way_cnt, NWAYS)
|
||||
io.meta_req.bits.way_en := UFixToOH(way_cnt)
|
||||
io.meta_req.bits.idx := idx_cnt
|
||||
io.meta_req.bits.rw := (state === s_reset)
|
||||
io.meta_req.bits.data.state := conf.co.newStateOnFlush()
|
||||
io.meta_req.bits.data.tag := UFix(0)
|
||||
}
|
||||
|
||||
class MetaDataArrayArray(lines: Int) extends Component {
|
||||
class MetaDataArrayArray(lines: Int)(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new MetaArrayReq() }.flip
|
||||
val resp = Vec(NWAYS){ (new MetaData).asOutput }
|
||||
val resp = Vec(conf.ways){ (new MetaData).asOutput }
|
||||
val state_req = (new FIFOIO) { new MetaArrayReq() }.flip
|
||||
val way_en = Bits(width = NWAYS, dir = OUTPUT)
|
||||
val way_en = Bits(OUTPUT, conf.ways)
|
||||
}
|
||||
|
||||
val permBits = io.req.bits.data.state.width
|
||||
val perms = Mem(lines) { UFix(width = permBits*NWAYS) }
|
||||
val tags = Mem(lines, seqRead = true) { Bits(width = TAG_BITS*NWAYS) }
|
||||
val perms = Mem(lines) { UFix(width = permBits*conf.ways) }
|
||||
val tags = Mem(lines, seqRead = true) { Bits(width = conf.tagbits*conf.ways) }
|
||||
val tag = Reg() { Bits() }
|
||||
val raddr = Reg() { Bits() }
|
||||
val way_en_ = Reg { Bits(width=NWAYS) }
|
||||
val way_en_ = Reg { Bits(width = conf.ways) }
|
||||
|
||||
when (io.state_req.valid && io.state_req.bits.rw) {
|
||||
perms.write(io.state_req.bits.idx, Fill(NWAYS, io.state_req.bits.data.state), FillInterleaved(permBits, io.state_req.bits.way_en))
|
||||
perms.write(io.state_req.bits.idx, Fill(conf.ways, io.state_req.bits.data.state), FillInterleaved(permBits, io.state_req.bits.way_en))
|
||||
}
|
||||
when (io.req.valid) {
|
||||
when (io.req.bits.rw) {
|
||||
perms.write(io.req.bits.idx, Fill(NWAYS, io.req.bits.data.state), FillInterleaved(permBits, io.req.bits.way_en))
|
||||
tags.write(io.req.bits.idx, Fill(NWAYS, io.req.bits.data.tag), FillInterleaved(TAG_BITS, io.req.bits.way_en))
|
||||
perms.write(io.req.bits.idx, Fill(conf.ways, io.req.bits.data.state), FillInterleaved(permBits, io.req.bits.way_en))
|
||||
tags.write(io.req.bits.idx, Fill(conf.ways, io.req.bits.data.tag), FillInterleaved(conf.tagbits, io.req.bits.way_en))
|
||||
}
|
||||
.otherwise {
|
||||
raddr := io.req.bits.idx
|
||||
@ -629,9 +624,9 @@ class MetaDataArrayArray(lines: Int) extends Component {
|
||||
}
|
||||
|
||||
val perm = perms(raddr)
|
||||
for(w <- 0 until NWAYS) {
|
||||
for (w <- 0 until conf.ways) {
|
||||
io.resp(w).state := perm(permBits*(w+1)-1, permBits*w)
|
||||
io.resp(w).tag := tag(TAG_BITS*(w+1)-1, TAG_BITS*w)
|
||||
io.resp(w).tag := tag(conf.tagbits*(w+1)-1, conf.tagbits*w)
|
||||
}
|
||||
|
||||
io.way_en := way_en_
|
||||
@ -639,7 +634,7 @@ class MetaDataArrayArray(lines: Int) extends Component {
|
||||
io.state_req.ready := Bool(true)
|
||||
}
|
||||
|
||||
class DataArray(lines: Int) extends Component {
|
||||
class DataArray(lines: Int)(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new DataArrayReq() }.flip
|
||||
val resp = Bits(width = MEM_DATA_BITS, dir = OUTPUT)
|
||||
@ -659,19 +654,19 @@ class DataArray(lines: Int) extends Component {
|
||||
io.req.ready := Bool(true)
|
||||
}
|
||||
|
||||
class DataArrayArray(lines: Int) extends Component {
|
||||
class DataArrayArray(lines: Int)(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val req = (new FIFOIO) { new DataArrayReq() }.flip
|
||||
val resp = Vec(NWAYS){ Bits(dir = OUTPUT, width = MEM_DATA_BITS) }
|
||||
val way_en = Bits(width = NWAYS, dir = OUTPUT)
|
||||
val resp = Vec(conf.ways){ Bits(OUTPUT, MEM_DATA_BITS) }
|
||||
val way_en = Bits(OUTPUT, conf.ways)
|
||||
}
|
||||
|
||||
val way_en_ = Reg { Bits(width=NWAYS) }
|
||||
val way_en_ = Reg { Bits(width = conf.ways) }
|
||||
when (io.req.valid && io.req.ready) {
|
||||
way_en_ := io.req.bits.way_en
|
||||
}
|
||||
|
||||
for(w <- 0 until NWAYS) {
|
||||
for (w <- 0 until conf.ways) {
|
||||
val way = new DataArray(lines)
|
||||
way.io.req.bits <> io.req.bits
|
||||
way.io.req.valid := io.req.valid && io.req.bits.way_en(w).toBool
|
||||
@ -713,24 +708,28 @@ class AMOALU extends Component {
|
||||
io.out := Mux(word, Cat(out(31,0), out(31,0)).toUFix, out)
|
||||
}
|
||||
|
||||
class HellaCacheReq extends Bundle {
|
||||
class HellaCacheReq(implicit conf: DCacheConfig) extends Bundle {
|
||||
val kill = Bool()
|
||||
val typ = Bits(width = 3)
|
||||
val idx = Bits(width = PGIDX_BITS)
|
||||
val ppn = Bits(width = PPN_BITS)
|
||||
val data = Bits(width = 64)
|
||||
val tag = Bits(width = DCACHE_TAG_BITS)
|
||||
val idx = Bits(width = conf.pgidxbits)
|
||||
val ppn = Bits(width = conf.ppnbits)
|
||||
val data = Bits(width = conf.databits)
|
||||
val tag = Bits(width = conf.reqtagbits)
|
||||
val cmd = Bits(width = 4)
|
||||
|
||||
override def clone = new HellaCacheReq().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class HellaCacheResp extends Bundle {
|
||||
class HellaCacheResp(implicit conf: DCacheConfig) extends Bundle {
|
||||
val miss = Bool()
|
||||
val nack = Bool()
|
||||
val replay = Bool()
|
||||
val typ = Bits(width = 3)
|
||||
val data = Bits(width = 64)
|
||||
val data_subword = Bits(width = 64)
|
||||
val tag = Bits(width = DCACHE_TAG_BITS)
|
||||
val data = Bits(width = conf.databits)
|
||||
val data_subword = Bits(width = conf.databits)
|
||||
val tag = Bits(width = conf.reqtagbits)
|
||||
|
||||
override def clone = new HellaCacheResp().asInstanceOf[this.type]
|
||||
}
|
||||
|
||||
class AlignmentExceptions extends Bundle {
|
||||
@ -743,29 +742,27 @@ class HellaCacheExceptions extends Bundle {
|
||||
}
|
||||
|
||||
// interface between D$ and processor/DTLB
|
||||
class ioHellaCache extends Bundle {
|
||||
class ioHellaCache(implicit conf: DCacheConfig) extends Bundle {
|
||||
val req = (new FIFOIO){ new HellaCacheReq }
|
||||
val resp = (new PipeIO){ new HellaCacheResp }.flip
|
||||
val xcpt = (new HellaCacheExceptions).asInput
|
||||
}
|
||||
|
||||
class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
class HellaCache(implicit conf: DCacheConfig) extends Component {
|
||||
val io = new Bundle {
|
||||
val cpu = (new ioHellaCache).flip
|
||||
val mem = new ioTileLink
|
||||
}
|
||||
|
||||
val lines = 1 << IDX_BITS
|
||||
val addrbits = PADDR_BITS
|
||||
val indexbits = IDX_BITS
|
||||
val offsetbits = OFFSET_BITS
|
||||
val tagmsb = PADDR_BITS-1
|
||||
val taglsb = indexbits+offsetbits
|
||||
val lines = 1 << conf.idxbits
|
||||
val indexbits = conf.idxbits
|
||||
val tagmsb = conf.paddrbits-1
|
||||
val taglsb = indexbits+conf.offbits
|
||||
val tagbits = tagmsb-taglsb+1
|
||||
val indexmsb = taglsb-1
|
||||
val indexlsb = offsetbits
|
||||
val indexlsb = conf.offbits
|
||||
val offsetmsb = indexlsb-1
|
||||
val offsetlsb = log2Up(CPU_DATA_BITS/8)
|
||||
val offsetlsb = log2Up(conf.databytes)
|
||||
val ramindexlsb = log2Up(MEM_DATA_BITS/8)
|
||||
|
||||
val early_nack = Reg { Bool() }
|
||||
@ -821,9 +818,9 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
r_cpu_req_tag := io.cpu.req.bits.tag
|
||||
}
|
||||
when (prober.io.meta_req.valid) {
|
||||
r_cpu_req_idx := Cat(prober.io.meta_req.bits.data.tag, prober.io.meta_req.bits.idx, mshr.io.data_req.bits.offset)(PGIDX_BITS-1,0)
|
||||
r_cpu_req_idx := Cat(prober.io.meta_req.bits.data.tag, prober.io.meta_req.bits.idx, mshr.io.data_req.bits.offset)(conf.pgidxbits-1,0)
|
||||
}
|
||||
when (replay_amo_val) {
|
||||
when (mshr.io.data_req.valid) {
|
||||
r_cpu_req_idx := Cat(mshr.io.data_req.bits.idx, mshr.io.data_req.bits.offset)
|
||||
r_cpu_req_cmd := mshr.io.data_req.bits.cmd
|
||||
r_cpu_req_type := mshr.io.data_req.bits.typ
|
||||
@ -860,17 +857,17 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
meta_arb.io.in(3).valid := io.cpu.req.valid
|
||||
meta_arb.io.in(3).bits.idx := io.cpu.req.bits.idx(indexmsb,indexlsb)
|
||||
meta_arb.io.in(3).bits.rw := Bool(false)
|
||||
meta_arb.io.in(3).bits.way_en := ~UFix(0, NWAYS)
|
||||
meta_arb.io.in(3).bits.way_en := Fix(-1)
|
||||
val early_tag_nack = !meta_arb.io.in(3).ready
|
||||
val cpu_req_ppn = Mux(prober.io.mshr_req.valid, prober.io.addr >> UFix(PGIDX_BITS-OFFSET_BITS), io.cpu.req.bits.ppn)
|
||||
val cpu_req_ppn = Mux(prober.io.mshr_req.valid, prober.io.addr >> UFix(conf.pgidxbits-conf.offbits), io.cpu.req.bits.ppn)
|
||||
val cpu_req_tag = Cat(cpu_req_ppn, r_cpu_req_idx)(tagmsb,taglsb)
|
||||
val tag_match_arr = (0 until NWAYS).map( w => conf.co.isValid(meta.io.resp(w).state) && (meta.io.resp(w).tag === cpu_req_tag))
|
||||
val tag_match_arr = (0 until conf.ways).map( w => conf.co.isValid(meta.io.resp(w).state) && (meta.io.resp(w).tag === cpu_req_tag))
|
||||
val tag_match = Cat(Bits(0),tag_match_arr:_*).orR
|
||||
val tag_match_way_oh = Cat(Bits(0),tag_match_arr.reverse:_*)(NWAYS-1, 0) //TODO: use Vec
|
||||
val tag_hit_arr = (0 until NWAYS).map( w => conf.co.isHit(r_cpu_req_cmd, meta.io.resp(w).state) && (meta.io.resp(w).tag === cpu_req_tag))
|
||||
val tag_match_way_oh = Cat(Bits(0),tag_match_arr.reverse:_*)(conf.ways-1, 0) //TODO: use Vec
|
||||
val tag_hit_arr = (0 until conf.ways).map( w => conf.co.isHit(r_cpu_req_cmd, meta.io.resp(w).state) && (meta.io.resp(w).tag === cpu_req_tag))
|
||||
val tag_hit = Cat(Bits(0),tag_hit_arr:_*).orR
|
||||
val meta_resp_way_oh = Mux(meta.io.way_en === ~UFix(0, NWAYS), tag_match_way_oh, meta.io.way_en)
|
||||
val data_resp_way_oh = Mux(data.io.way_en === ~UFix(0, NWAYS), tag_match_way_oh, data.io.way_en)
|
||||
val meta_resp_way_oh = Mux(meta.io.way_en.andR, tag_match_way_oh, meta.io.way_en)
|
||||
val data_resp_way_oh = Mux(data.io.way_en.andR, tag_match_way_oh, data.io.way_en)
|
||||
val meta_resp_mux = Mux1H(meta_resp_way_oh, meta.io.resp)
|
||||
val data_resp_mux = Mux1H(data_resp_way_oh, data.io.resp)
|
||||
|
||||
@ -881,9 +878,8 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
wb.io.probe_rep_data <> io.mem.probe_rep_data
|
||||
|
||||
// replacement policy
|
||||
val replacer = new RandomReplacementWayGen()
|
||||
replacer.io.way_en := ~UFix(0, NWAYS)
|
||||
val replaced_way_oh = Mux(flusher.io.mshr_req.valid, r_way_oh, UFixToOH(replacer.io.way_id, NWAYS))
|
||||
val replacer = new RandomReplacement
|
||||
val replaced_way_oh = Mux(flusher.io.mshr_req.valid, r_way_oh, UFixToOH(replacer.way))
|
||||
val meta_wb_mux = Mux1H(replaced_way_oh, meta.io.resp)
|
||||
|
||||
// refill response
|
||||
@ -900,8 +896,8 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
data_arb.io.in(4).bits.idx := io.cpu.req.bits.idx(indexmsb,indexlsb)
|
||||
data_arb.io.in(4).bits.rw := Bool(false)
|
||||
data_arb.io.in(4).valid := io.cpu.req.valid && req_read
|
||||
data_arb.io.in(4).bits.way_en := ~UFix(0, NWAYS) // intiate load on all ways, mux after tag check
|
||||
val early_load_nack = req_read && !data_arb.io.in(4).ready
|
||||
data_arb.io.in(4).bits.way_en := Fix(-1) // intiate load on all ways, mux after tag check
|
||||
val early_load_nack = !data_arb.io.in(4).ready
|
||||
|
||||
// store hits and AMO hits and misses use a pending store register.
|
||||
// we nack new stores if a pending store can't retire for some reason.
|
||||
@ -963,7 +959,7 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
mshr.io.mem_abort.bits := io.mem.xact_abort.bits
|
||||
io.mem.xact_abort.ready := Bool(true)
|
||||
mshr.io.meta_req <> meta_arb.io.in(1)
|
||||
replacer.io.pick_new_way := mshr.io.req.valid && mshr.io.req.ready
|
||||
when (mshr.io.req.fire()) { replacer.miss }
|
||||
|
||||
// replays
|
||||
val replay = mshr.io.data_req.bits
|
||||
@ -992,13 +988,11 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
|
||||
// store write mask generation.
|
||||
// assumes store replays are higher-priority than pending stores.
|
||||
val maskgen = new StoreMaskGen
|
||||
val store_offset = Mux(!replay_fire, p_store_idx(offsetmsb,0), replay.offset)
|
||||
maskgen.io.typ := Mux(!replay_fire, p_store_type, replay.typ)
|
||||
maskgen.io.addr := store_offset(offsetlsb-1,0)
|
||||
val store_wmask_wide = maskgen.io.wmask << Cat(store_offset(ramindexlsb-1,offsetlsb), Bits(0, log2Up(CPU_DATA_BITS/8))).toUFix
|
||||
val store_type = Mux(!replay_fire, p_store_type, replay.typ)
|
||||
val store_wmask_wide = StoreGen(store_type, store_offset, Bits(0)).mask << Cat(store_offset(ramindexlsb-1,offsetlsb), Bits(0, log2Up(conf.databytes))).toUFix
|
||||
val store_data = Mux(!replay_fire, p_store_data, replay.data)
|
||||
val store_data_wide = Fill(MEM_DATA_BITS/CPU_DATA_BITS, store_data)
|
||||
val store_data_wide = Fill(MEM_DATA_BITS/conf.databits, store_data)
|
||||
data_arb.io.in(1).bits.data := store_data_wide
|
||||
data_arb.io.in(1).bits.wmask := store_wmask_wide
|
||||
data_arb.io.in(2).bits.data := store_data_wide
|
||||
@ -1006,15 +1000,12 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
|
||||
// load data subword mux/sign extension.
|
||||
// subword loads are delayed by one cycle.
|
||||
val loadgen = new LoadDataGen
|
||||
val loadgen_use_replay = Reg(replay_fire)
|
||||
loadgen.io.typ := Mux(loadgen_use_replay, Reg(replay.typ), r_cpu_req_type)
|
||||
loadgen.io.addr := Mux(loadgen_use_replay, Reg(replay.offset), r_cpu_req_idx)(ramindexlsb-1,0)
|
||||
loadgen.io.din := data_resp_mux
|
||||
val loadgen_data = data_resp_mux >> Cat(r_cpu_req_idx(log2Up(MEM_DATA_BITS/8)-1,3), Bits(0,6))
|
||||
val loadgen = LoadGen(r_cpu_req_type, r_cpu_req_idx, loadgen_data)
|
||||
|
||||
amoalu.io.cmd := p_store_cmd
|
||||
amoalu.io.typ := p_store_type
|
||||
amoalu.io.lhs := loadgen.io.r_dout.toUFix
|
||||
amoalu.io.lhs := Reg(loadgen.word).toUFix
|
||||
amoalu.io.rhs := p_store_data.toUFix
|
||||
|
||||
early_nack := early_tag_nack || early_load_nack || r_cpu_req_val && r_req_amo || replay_amo_val || r_replay_amo
|
||||
@ -1036,9 +1027,9 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
|
||||
io.cpu.resp.bits.replay := mshr.io.cpu_resp_val
|
||||
io.cpu.resp.bits.miss := r_cpu_req_val_ && (!tag_hit || mshr.io.secondary_miss) && r_req_read
|
||||
io.cpu.resp.bits.tag := Mux(mshr.io.cpu_resp_val, mshr.io.cpu_resp_tag, r_cpu_req_tag)
|
||||
io.cpu.resp.bits.typ := loadgen.io.typ
|
||||
io.cpu.resp.bits.data := loadgen.io.dout
|
||||
io.cpu.resp.bits.data_subword := loadgen.io.r_dout_subword
|
||||
io.cpu.resp.bits.typ := r_cpu_req_type
|
||||
io.cpu.resp.bits.data := loadgen.word
|
||||
io.cpu.resp.bits.data_subword := Reg(loadgen.byte)
|
||||
|
||||
val xact_init_arb = (new Arbiter(2)) { new TransactionInit }
|
||||
xact_init_arb.io.in(0) <> wb.io.mem_req
|
||||
|
@ -5,14 +5,14 @@ import Node._
|
||||
import Constants._
|
||||
import scala.math._
|
||||
|
||||
class ioPTW(n: Int) extends Bundle
|
||||
class ioPTW(n: Int)(implicit conf: RocketConfiguration) extends Bundle
|
||||
{
|
||||
val requestor = Vec(n) { new IOTLBPTW }.flip
|
||||
val mem = new ioHellaCache
|
||||
val mem = new ioHellaCache()(conf.dcache)
|
||||
val ptbr = UFix(INPUT, PADDR_BITS)
|
||||
}
|
||||
|
||||
class rocketPTW(n: Int) extends Component
|
||||
class rocketPTW(n: Int)(implicit conf: RocketConfiguration) extends Component
|
||||
{
|
||||
val io = new ioPTW(n)
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
package rocket
|
||||
|
||||
import Chisel._
|
||||
import Node._
|
||||
import Constants._
|
||||
|
||||
class SkidBuffer[T <: Data](entries: Int, lateEnq: Boolean = false)(data: => T) extends Component
|
||||
{
|
||||
val io = new Bundle {
|
||||
val enq = new FIFOIO()(data).flip
|
||||
val deq = new FIFOIO()(data)
|
||||
}
|
||||
|
||||
require(entries >= 2)
|
||||
val fq = new Queue(1, flow = true)(data)
|
||||
val pq = new Queue(entries-1, pipe = true)(data)
|
||||
val (iq, oq) = if (lateEnq) (pq, fq) else (fq, pq)
|
||||
|
||||
iq.io.enq <> io.enq
|
||||
oq.io.enq <> iq.io.deq
|
||||
io.deq <> oq.io.deq
|
||||
}
|
||||
|
||||
object SkidBuffer
|
||||
{
|
||||
def apply[T <: Data](enq: FIFOIO[T], entries: Int = 2): FIFOIO[T] = {
|
||||
val s = new SkidBuffer(entries)(enq.bits.clone)
|
||||
s.io.enq <> enq
|
||||
s.io.deq
|
||||
}
|
||||
}
|
@ -6,20 +6,26 @@ import Constants._
|
||||
import uncore._
|
||||
|
||||
case class RocketConfiguration(ntiles: Int, co: CoherencePolicyWithUncached,
|
||||
icache: ICacheConfig)
|
||||
|
||||
class Tile(resetSignal: Bool = null)(implicit conf: RocketConfiguration) extends Component(resetSignal)
|
||||
icache: ICacheConfig, dcache: DCacheConfig)
|
||||
{
|
||||
val dcacheReqTagBits = 9 // enforce compliance with require()
|
||||
}
|
||||
|
||||
class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Component(resetSignal)
|
||||
{
|
||||
implicit val dcConf = confIn.dcache.copy(reqtagbits = confIn.dcacheReqTagBits + log2Up(DMEM_PORTS))
|
||||
implicit val conf = confIn.copy(dcache = dcConf)
|
||||
|
||||
val io = new Bundle {
|
||||
val tilelink = new ioTileLink
|
||||
val host = new ioHTIF(conf.ntiles)
|
||||
}
|
||||
|
||||
val cpu = new rocketProc
|
||||
val icache = new Frontend(conf.icache)
|
||||
val icache = new Frontend()(confIn.icache)
|
||||
val dcache = new HellaCache
|
||||
|
||||
val arbiter = new rocketMemArbiter(DMEM_PORTS)
|
||||
val arbiter = new MemArbiter(DMEM_PORTS)
|
||||
arbiter.io.requestor(DMEM_DCACHE) <> dcache.io.mem
|
||||
arbiter.io.requestor(DMEM_ICACHE) <> icache.io.mem
|
||||
|
||||
@ -34,7 +40,7 @@ class Tile(resetSignal: Bool = null)(implicit conf: RocketConfiguration) extends
|
||||
|
||||
if (HAVE_VEC)
|
||||
{
|
||||
val vicache = new Frontend(ICacheConfig(128, 1, conf.co)) // 128 sets x 1 ways (8KB)
|
||||
val vicache = new Frontend()(ICacheConfig(128, 1, conf.co)) // 128 sets x 1 ways (8KB)
|
||||
arbiter.io.requestor(DMEM_VICACHE) <> vicache.io.mem
|
||||
cpu.io.vimem <> vicache.io.cpu
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user