1
0

factor out more global constants

This commit is contained in:
Andrew Waterman 2012-11-05 23:52:32 -08:00
parent ee081d1671
commit c5b93798fb
10 changed files with 268 additions and 327 deletions

View File

@ -5,16 +5,12 @@ import Node._
import Constants._ import Constants._
import uncore._ 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 io = new Bundle {
val mem = new ioHellaCache 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_val = Bool(false)
var req_rdy = io.mem.req.ready var req_rdy = io.mem.req.ready
@ -78,7 +74,7 @@ class ioUncachedRequestor extends Bundle {
val xact_finish = (new FIFOIO) { new TransactionFinish } val xact_finish = (new FIFOIO) { new TransactionFinish }
} }
class rocketMemArbiter(n: Int) extends Component { class MemArbiter(n: Int) extends Component {
val io = new Bundle { val io = new Bundle {
val mem = new ioUncachedRequestor val mem = new ioUncachedRequestor
val requestor = Vec(n) { new ioUncachedRequestor }.flip val requestor = Vec(n) { new ioUncachedRequestor }.flip

View File

@ -155,11 +155,6 @@ trait InterruptConstants {
} }
abstract trait RocketDcacheConstants extends ArbiterConstants with uncore.constants.AddressConstants { 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 val NMSHR = if (HAVE_VEC) 4 else 2 // number of primary misses
require(log2Up(NMSHR)+3 <= uncore.Constants.TILE_XACT_ID_BITS) require(log2Up(NMSHR)+3 <= uncore.Constants.TILE_XACT_ID_BITS)
val NRPQ = 16; // number of secondary misses 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 == log2Up(uncore.Constants.CACHE_DATA_SIZE_IN_BYTES))
require(OFFSET_BITS <= uncore.Constants.X_INIT_WRITE_MASK_BITS) require(OFFSET_BITS <= uncore.Constants.X_INIT_WRITE_MASK_BITS)
require(log2Up(OFFSET_BITS) <= uncore.Constants.X_INIT_SUBWORD_ADDR_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 { trait TLBConstants {

View File

@ -8,21 +8,21 @@ import hwacha._
class ioRocket(implicit conf: RocketConfiguration) extends Bundle class ioRocket(implicit conf: RocketConfiguration) extends Bundle
{ {
val host = new ioHTIF(conf.ntiles) val host = new ioHTIF(conf.ntiles)
val imem = new IOCPUFrontend val imem = new IOCPUFrontend()(conf.icache)
val vimem = new IOCPUFrontend val vimem = new IOCPUFrontend()(conf.icache)
val dmem = new ioHellaCache val dmem = new ioHellaCache()(conf.dcache)
} }
class rocketProc(implicit conf: RocketConfiguration) extends Component class rocketProc(implicit conf: RocketConfiguration) extends Component
{ {
val io = new ioRocket val io = new ioRocket
val ctrl = new rocketCtrl val ctrl = new Control
val dpath = new rocketDpath val dpath = new Datapath
val dtlb = new rocketTLB(DTLB_ENTRIES); val dtlb = new rocketTLB(DTLB_ENTRIES);
val ptw = new rocketPTW(if (HAVE_VEC) 3 else 2) 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 var vu: vu = null
if (HAVE_VEC) if (HAVE_VEC)
@ -199,17 +199,13 @@ class rocketProc(implicit conf: RocketConfiguration) extends Component
vu.io.xcpt.hold := ctrl.io.vec_iface.hold vu.io.xcpt.hold := ctrl.io.vec_iface.hold
// hooking up vector memory interface // 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.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.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.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.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.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.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 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 vu.io.dmem_req.ready := arb.io.requestor(DCACHE_VU).req.ready

View File

@ -67,23 +67,7 @@ class ioCtrlDpath extends Bundle()
val pcr_replay = Bool(INPUT) val pcr_replay = Bool(INPUT)
} }
class ioCtrlAll extends Bundle() abstract trait DecodeConstants
{
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
{ {
val xpr64 = Y; val xpr64 = Y;
@ -98,7 +82,7 @@ abstract trait rocketCtrlDecodeConstants
val table: Array[(Bits, List[Bits])] val table: Array[(Bits, List[Bits])]
} }
object rocketCtrlXDecode extends rocketCtrlDecodeConstants object XDecode extends DecodeConstants
{ {
val table = Array( val table = Array(
// jalr eret // 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)) 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( val table = Array(
// jalr eret // 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)) 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( val table = Array(
// jalr eret // 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)) 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 var decode_table = XDecode.table
if (HAVE_FPU) decode_table ++= rocketCtrlFDecode.table if (HAVE_FPU) decode_table ++= FDecode.table
if (HAVE_VEC) decode_table ++= rocketCtrlVDecode.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_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 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

View File

@ -6,25 +6,22 @@ import Constants._
import Instructions._ import Instructions._
import hwacha._ import hwacha._
class ioDpathAll(implicit conf: RocketConfiguration) extends Bundle class Datapath(implicit conf: RocketConfiguration) extends Component
{ {
val host = new ioHTIF(conf.ntiles) val io = new Bundle {
val ctrl = new ioCtrlDpath().flip val host = new ioHTIF(conf.ntiles)
val dmem = new ioHellaCache val ctrl = new ioCtrlDpath().flip
val dtlb = new ioDTLB_CPU_req_bundle().asOutput() val dmem = new ioHellaCache()(conf.dcache)
val imem = new IOCPUFrontend val dtlb = new ioDTLB_CPU_req_bundle().asOutput()
val ptbr_wen = Bool(OUTPUT); val imem = new IOCPUFrontend()(conf.icache)
val ptbr = UFix(OUTPUT, PADDR_BITS); val ptbr_wen = Bool(OUTPUT);
val fpu = new ioDpathFPU(); val ptbr = UFix(OUTPUT, PADDR_BITS);
val vec_ctrl = new ioCtrlDpathVec().flip val fpu = new ioDpathFPU();
val vec_iface = new ioDpathVecInterface() val vec_ctrl = new ioCtrlDpathVec().flip
val vec_imul_req = new io_imul_req val vec_iface = new ioDpathVecInterface()
val vec_imul_resp = Bits(INPUT, hwacha.Constants.SZ_XLEN) val vec_imul_req = new io_imul_req
} 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 pcr = new rocketDpathPCR();
val ex_pcr = pcr.io.r.data; 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.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.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) 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) io.dtlb.vpn := ex_effective_address >> UFix(PGIDX_BITS)
// processor control regfile read // 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, Mux(ex_reg_ctrl_sel_wb === WB_IRT, irt_reg,
ex_alu_out))).toBits // WB_ALU 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 // memory stage
mem_reg_kill := ex_reg_kill mem_reg_kill := ex_reg_kill
when (!ex_reg_kill) { when (!ex_reg_kill) {
mem_reg_pc := ex_reg_pc mem_reg_pc := ex_reg_pc
mem_reg_inst := ex_reg_inst 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_waddr := ex_reg_waddr
mem_reg_wdata := ex_wdata mem_reg_wdata := ex_wdata
mem_reg_raddr1 := ex_reg_raddr1 mem_reg_raddr1 := ex_reg_raddr1

View File

@ -10,7 +10,7 @@ case class ICacheConfig(sets: Int, assoc: Int, co: CoherencePolicyWithUncached,
parity: Boolean = false) parity: Boolean = false)
{ {
val w = 1 val w = 1
val ibytes = INST_BITS/8 val ibytes = 4
val dm = assoc == 1 val dm = assoc == 1
val lines = sets * assoc val lines = sets * assoc
@ -37,29 +37,31 @@ class FrontendReq extends Bundle {
val currentpc = UFix(width = VADDR_BITS+1) 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 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 taken = Bool()
val xcpt_ma = Bool() val xcpt_ma = Bool()
val xcpt_if = 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 req = new PipeIO()(new FrontendReq)
val resp = new FIFOIO()(new FrontendResp).flip val resp = new FIFOIO()(new FrontendResp).flip
val ptw = new IOTLBPTW().flip val ptw = new IOTLBPTW().flip
} }
class Frontend(c: ICacheConfig) extends Component class Frontend(implicit c: ICacheConfig) extends Component
{ {
val io = new Bundle { val io = new Bundle {
val cpu = new IOCPUFrontend().flip val cpu = new IOCPUFrontend()(c).flip
val mem = new ioUncachedRequestor val mem = new ioUncachedRequestor
} }
val btb = new rocketDpathBTB(BTB_ENTRIES) val btb = new rocketDpathBTB(BTB_ENTRIES)
val icache = new ICache(c) val icache = new ICache
val tlb = new TLB(ITLB_ENTRIES) val tlb = new TLB(ITLB_ENTRIES)
val s1_pc = Reg() { UFix() } val s1_pc = Reg() { UFix() }
@ -123,7 +125,7 @@ class Frontend(c: ICacheConfig) extends Component
io.cpu.resp.bits.xcpt_if := s2_xcpt_if 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 io = new Bundle {
val req = new PipeIO()(new Bundle { val req = new PipeIO()(new Bundle {
@ -133,7 +135,7 @@ class ICache(c: ICacheConfig) extends Component
val kill = Bool() // delayed one cycle val kill = Bool() // delayed one cycle
}).flip }).flip
val resp = new FIFOIO()(new Bundle { 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 datablock = Bits(width = c.databits)
}) })
val mem = new ioUncachedRequestor val mem = new ioUncachedRequestor

View File

@ -4,162 +4,157 @@ import Chisel._
import Constants._ import Constants._
import uncore._ import uncore._
class ioReplacementWayGen extends Bundle { case class DCacheConfig(sets: Int, ways: Int, co: CoherencePolicy,
val pick_new_way = Bool(dir = INPUT) nmshr: Int, nsecondary: Int, nsdq: Int,
val way_en = Bits(width = NWAYS, dir = INPUT) reqtagbits: Int = -1)
val way_id = UFix(width = log2Up(NWAYS), dir = OUTPUT) {
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 RandomReplacementWayGen extends Component { abstract class ReplacementPolicy
val io = new ioReplacementWayGen() {
//TODO: Actually limit selection based on which ways are allowed (io.ways_en) def way: UFix
io.way_id := UFix(0) def miss: Unit
if(NWAYS > 1) def hit: Unit
{
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 }
}
} }
class StoreMaskGen extends Component { class RandomReplacement(implicit conf: DCacheConfig) extends ReplacementPolicy
val io = new Bundle { {
val typ = Bits(INPUT, 3) private val replace = Bool()
val addr = Bits(INPUT, 3) replace := Bool(false)
val wmask = Bits(OUTPUT, 8) val lfsr = LFSR16(replace)
}
val word = (io.typ === MT_W) || (io.typ === MT_WU) def way = if (conf.dm) UFix(0) else lfsr(conf.waybits-1,0)
val half = (io.typ === MT_H) || (io.typ === MT_HU) def miss = replace := Bool(true)
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU) def hit = {}
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))));
} }
class StoreDataGen extends Component { case class StoreGen(typ: Bits, addr: Bits, dat: Bits)
val io = new Bundle { {
val typ = Bits(INPUT, 3) val byte = typ === MT_B || typ === MT_BU
val din = Bits(INPUT, 64) val half = typ === MT_H || typ === MT_HU
val dout = Bits(OUTPUT, 64) val word = typ === MT_W || typ === MT_WU
} def mask =
Mux(byte, Bits( 1) << addr(2,0),
val word = (io.typ === MT_W) || (io.typ === MT_WU) Mux(half, Bits( 3) << Cat(addr(2,1), Bits(0,1)),
val half = (io.typ === MT_H) || (io.typ === MT_HU) Mux(word, Bits( 15) << Cat(addr(2), Bits(0,2)),
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU) Bits(255))))
def data =
io.dout := Mux(byte_, Fill(8, io.din( 7,0)), Mux(byte, Fill(8, dat( 7,0)),
Mux(half, Fill(4, io.din(15,0)), Mux(half, Fill(4, dat(15,0)),
Mux(word, Fill(2, io.din(31,0)), Mux(word, Fill(2, dat(31,0)),
io.din))) dat)))
} }
// this currently requires that CPU_DATA_BITS == 64 case class LoadGen(typ: Bits, addr: Bits, dat: Bits)
class LoadDataGen extends Component { {
val io = new Bundle { val t = StoreGen(typ, addr, dat)
val typ = Bits(INPUT, 3) val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D
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) || val wordShift = Mux(addr(2), dat(63,32), dat(31,0))
(io.typ === MT_W) || (io.typ === MT_D) val word = Cat(Mux(t.word, Fill(32, sign && wordShift(31)), dat(63,32)), wordShift)
val word = (io.typ === MT_W) || (io.typ === MT_WU) val halfShift = Mux(addr(1), word(31,16), word(15,0))
val half = (io.typ === MT_H) || (io.typ === MT_HU) val half = Cat(Mux(t.half, Fill(48, sign && halfShift(15)), word(63,16)), halfShift)
val byte_ = (io.typ === MT_B) || (io.typ === MT_BU) 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)
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 tag_miss = Bool()
val old_dirty = 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 tag = Bits(width = conf.tagbits)
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val way_oh = Bits(width = NWAYS) 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 cmd = Bits(width = 4)
val typ = Bits(width = 3) val typ = Bits(width = 3)
val cpu_tag = Bits(width = DCACHE_TAG_BITS) val cpu_tag = Bits(width = conf.reqtagbits)
val data = Bits(width = CPU_DATA_BITS) val data = Bits(width = conf.databits)
override def clone = new MSHRReq().asInstanceOf[this.type]
} }
class RPQEntry extends Bundle { class RPQEntry(implicit conf: DCacheConfig) extends Bundle {
val offset = Bits(width = OFFSET_BITS) val offset = Bits(width = conf.offbits)
val cmd = Bits(width = 4) val cmd = Bits(width = 4)
val typ = Bits(width = 3) val typ = Bits(width = 3)
val sdq_id = UFix(width = log2Up(NSDQ)) val sdq_id = UFix(width = log2Up(conf.nsdq))
val cpu_tag = Bits(width = DCACHE_TAG_BITS) val cpu_tag = Bits(width = conf.reqtagbits)
override def clone = new RPQEntry().asInstanceOf[this.type]
} }
class Replay extends RPQEntry { class Replay(implicit conf: DCacheConfig) extends RPQEntry {
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val way_oh = Bits(width = NWAYS) val way_oh = Bits(width = conf.ways)
override def clone = new Replay().asInstanceOf[this.type]
} }
class DataReq extends Bundle { class DataReq(implicit conf: DCacheConfig) extends Bundle {
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val offset = Bits(width = OFFSET_BITS) val offset = Bits(width = conf.offbits)
val cmd = Bits(width = 4) val cmd = Bits(width = 4)
val typ = Bits(width = 3) val typ = Bits(width = 3)
val data = Bits(width = CPU_DATA_BITS) val data = Bits(width = conf.databits)
val way_oh = Bits(width = NWAYS) val way_oh = Bits(width = conf.ways)
override def clone = new DataReq().asInstanceOf[this.type]
} }
class DataArrayReq extends Bundle { class DataArrayReq(implicit conf: DCacheConfig) extends Bundle {
val way_en = Bits(width = NWAYS) val way_en = Bits(width = conf.ways)
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val offset = Bits(width = log2Up(REFILL_CYCLES)) val offset = Bits(width = log2Up(REFILL_CYCLES))
val rw = Bool() val rw = Bool()
val wmask = Bits(width = MEM_DATA_BITS/8) val wmask = Bits(width = MEM_DATA_BITS/8)
val data = Bits(width = MEM_DATA_BITS) val data = Bits(width = MEM_DATA_BITS)
override def clone = new DataArrayReq().asInstanceOf[this.type]
} }
class WritebackReq extends Bundle { class WritebackReq(implicit conf: DCacheConfig) extends Bundle {
val tag = Bits(width = TAG_BITS) val tag = Bits(width = conf.tagbits)
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val way_oh = Bits(width = NWAYS) val way_oh = Bits(width = conf.ways)
val tile_xact_id = Bits(width = TILE_XACT_ID_BITS) 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 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 { class MetaArrayReq(implicit conf: DCacheConfig) extends Bundle {
val way_en = Bits(width = NWAYS) val way_en = Bits(width = conf.ways)
val idx = Bits(width = IDX_BITS) val idx = Bits(width = conf.idxbits)
val rw = Bool() val rw = Bool()
val data = new MetaData() 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 io = new Bundle {
val req_pri_val = Bool(INPUT) val req_pri_val = Bool(INPUT)
val req_pri_rdy = Bool(OUTPUT) val req_pri_rdy = Bool(OUTPUT)
@ -169,10 +164,10 @@ class MSHR(id: Int)(implicit conf: RocketConfiguration) extends Component {
val req_sdq_id = UFix(INPUT, log2Up(NSDQ)) val req_sdq_id = UFix(INPUT, log2Up(NSDQ))
val idx_match = Bool(OUTPUT) 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 refill_count = Bits(OUTPUT, log2Up(REFILL_CYCLES))
val tag = Bits(OUTPUT, TAG_BITS) val tag = Bits(OUTPUT, conf.tagbits)
val way_oh = Bits(OUTPUT, NWAYS) val way_oh = Bits(OUTPUT, conf.ways)
val mem_req = (new FIFOIO) { new TransactionInit } val mem_req = (new FIFOIO) { new TransactionInit }
val meta_req = (new FIFOIO) { new MetaArrayReq() } 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 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 io = new Bundle {
val req = (new FIFOIO) { new MSHRReq }.flip val req = (new FIFOIO) { new MSHRReq }.flip
val secondary_miss = Bool(OUTPUT) 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_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) val fence_rdy = Bool(OUTPUT)
@ -314,7 +309,7 @@ class MSHRFile(implicit conf: RocketConfiguration) extends Component {
val probe = (new FIFOIO) { Bool() }.flip val probe = (new FIFOIO) { Bool() }.flip
val cpu_resp_val = Bool(OUTPUT) 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)) 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 io = new Bundle {
val req = (new FIFOIO) { new WritebackReq() }.flip val req = (new FIFOIO) { new WritebackReq() }.flip
val probe = (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 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 io = new Bundle {
val req = (new FIFOIO) { new ProbeRequest }.flip val req = (new FIFOIO) { new ProbeRequest }.flip
val rep = (new FIFOIO) { new ProbeReply } val rep = (new FIFOIO) { new ProbeReply }
val meta_req = (new FIFOIO) { new MetaArrayReq } val meta_req = (new FIFOIO) { new MetaArrayReq }
val mshr_req = (new FIFOIO) { Bool() } val mshr_req = (new FIFOIO) { Bool() }
val wb_req = (new FIFOIO) { new WritebackReq } 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 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() } 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.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.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.rw := state === s_probe_rep
io.meta_req.bits.idx := req.addr io.meta_req.bits.idx := req.addr
io.meta_req.bits.data.state := conf.co.newStateOnProbeRequest(req, line_state) 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.mshr_req.valid := state === s_meta_resp || state === s_mshr_req
io.addr := req.addr io.addr := req.addr
io.wb_req.valid := state === s_writeback_req io.wb_req.valid := state === s_writeback_req
io.wb_req.bits.way_oh := way_oh io.wb_req.bits.way_oh := way_oh
io.wb_req.bits.idx := req.addr 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 io = new Bundle {
val req = (new FIFOIO) { Bool() }.flip val req = (new FIFOIO) { Bool() }.flip
val meta_req = (new FIFOIO) { new MetaArrayReq() } 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 state = Reg(resetVal = s_reset)
val idx_cnt = Reg(resetVal = UFix(0, log2Up(lines))) val idx_cnt = Reg(resetVal = UFix(0, log2Up(lines)))
val next_idx_cnt = idx_cnt + UFix(1) 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) val next_way_cnt = way_cnt + UFix(1)
switch (state) { switch (state) {
is(s_reset) { is(s_reset) {
when (io.meta_req.ready) { when (io.meta_req.ready) {
state := Mux(way_cnt === UFix(NWAYS-1) && idx_cnt.andR, s_ready, s_reset); state := Mux(way_cnt === UFix(conf.ways-1) && idx_cnt.andR, s_ready, s_reset);
when (way_cnt === UFix(NWAYS-1)) { idx_cnt := next_idx_cnt }; when (way_cnt === UFix(conf.ways-1)) { idx_cnt := next_idx_cnt };
if (NWAYS > 1) way_cnt := next_way_cnt; if (!conf.dm) way_cnt := next_way_cnt;
} }
} }
is(s_ready) { when (io.req.valid) { state := s_meta_read } } 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 state := s_meta_read
when (io.mshr_req.ready) { when (io.mshr_req.ready) {
state := s_meta_read state := s_meta_read
when (way_cnt === UFix(NWAYS-1)) { when (way_cnt === UFix(conf.ways-1)) {
when (idx_cnt.andR) { when (idx_cnt.andR) {
state := s_ready state := s_ready
} }
idx_cnt := next_idx_cnt 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.req.ready := state === s_ready
io.mshr_req.valid := state === s_meta_wait io.mshr_req.valid := state === s_meta_wait
io.meta_req.valid := (state === s_meta_read) || (state === s_reset) 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.idx := idx_cnt
io.meta_req.bits.rw := (state === s_reset) io.meta_req.bits.rw := (state === s_reset)
io.meta_req.bits.data.state := conf.co.newStateOnFlush() io.meta_req.bits.data.state := conf.co.newStateOnFlush()
io.meta_req.bits.data.tag := UFix(0) 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 io = new Bundle {
val req = (new FIFOIO) { new MetaArrayReq() }.flip 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 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 permBits = io.req.bits.data.state.width
val perms = Mem(lines) { UFix(width = permBits*NWAYS) } val perms = Mem(lines) { UFix(width = permBits*conf.ways) }
val tags = Mem(lines, seqRead = true) { Bits(width = TAG_BITS*NWAYS) } val tags = Mem(lines, seqRead = true) { Bits(width = conf.tagbits*conf.ways) }
val tag = Reg() { Bits() } val tag = Reg() { Bits() }
val raddr = 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) { 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.valid) {
when (io.req.bits.rw) { 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)) 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(NWAYS, io.req.bits.data.tag), FillInterleaved(TAG_BITS, 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 { .otherwise {
raddr := io.req.bits.idx raddr := io.req.bits.idx
@ -629,9 +624,9 @@ class MetaDataArrayArray(lines: Int) extends Component {
} }
val perm = perms(raddr) 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).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_ io.way_en := way_en_
@ -639,7 +634,7 @@ class MetaDataArrayArray(lines: Int) extends Component {
io.state_req.ready := Bool(true) 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 io = new Bundle {
val req = (new FIFOIO) { new DataArrayReq() }.flip val req = (new FIFOIO) { new DataArrayReq() }.flip
val resp = Bits(width = MEM_DATA_BITS, dir = OUTPUT) val resp = Bits(width = MEM_DATA_BITS, dir = OUTPUT)
@ -659,19 +654,19 @@ class DataArray(lines: Int) extends Component {
io.req.ready := Bool(true) 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 io = new Bundle {
val req = (new FIFOIO) { new DataArrayReq() }.flip val req = (new FIFOIO) { new DataArrayReq() }.flip
val resp = Vec(NWAYS){ Bits(dir = OUTPUT, width = MEM_DATA_BITS) } val resp = Vec(conf.ways){ Bits(OUTPUT, MEM_DATA_BITS) }
val way_en = Bits(width = NWAYS, dir = OUTPUT) 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) { when (io.req.valid && io.req.ready) {
way_en_ := io.req.bits.way_en way_en_ := io.req.bits.way_en
} }
for(w <- 0 until NWAYS) { for (w <- 0 until conf.ways) {
val way = new DataArray(lines) val way = new DataArray(lines)
way.io.req.bits <> io.req.bits way.io.req.bits <> io.req.bits
way.io.req.valid := io.req.valid && io.req.bits.way_en(w).toBool 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) 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 kill = Bool()
val typ = Bits(width = 3) val typ = Bits(width = 3)
val idx = Bits(width = PGIDX_BITS) val idx = Bits(width = conf.pgidxbits)
val ppn = Bits(width = PPN_BITS) val ppn = Bits(width = conf.ppnbits)
val data = Bits(width = 64) val data = Bits(width = conf.databits)
val tag = Bits(width = DCACHE_TAG_BITS) val tag = Bits(width = conf.reqtagbits)
val cmd = Bits(width = 4) 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 miss = Bool()
val nack = Bool() val nack = Bool()
val replay = Bool() val replay = Bool()
val typ = Bits(width = 3) val typ = Bits(width = 3)
val data = Bits(width = 64) val data = Bits(width = conf.databits)
val data_subword = Bits(width = 64) val data_subword = Bits(width = conf.databits)
val tag = Bits(width = DCACHE_TAG_BITS) val tag = Bits(width = conf.reqtagbits)
override def clone = new HellaCacheResp().asInstanceOf[this.type]
} }
class AlignmentExceptions extends Bundle { class AlignmentExceptions extends Bundle {
@ -743,29 +742,27 @@ class HellaCacheExceptions extends Bundle {
} }
// interface between D$ and processor/DTLB // interface between D$ and processor/DTLB
class ioHellaCache extends Bundle { class ioHellaCache(implicit conf: DCacheConfig) extends Bundle {
val req = (new FIFOIO){ new HellaCacheReq } val req = (new FIFOIO){ new HellaCacheReq }
val resp = (new PipeIO){ new HellaCacheResp }.flip val resp = (new PipeIO){ new HellaCacheResp }.flip
val xcpt = (new HellaCacheExceptions).asInput val xcpt = (new HellaCacheExceptions).asInput
} }
class HellaCache(implicit conf: RocketConfiguration) extends Component { class HellaCache(implicit conf: DCacheConfig) extends Component {
val io = new Bundle { val io = new Bundle {
val cpu = (new ioHellaCache).flip val cpu = (new ioHellaCache).flip
val mem = new ioTileLink val mem = new ioTileLink
} }
val lines = 1 << IDX_BITS val lines = 1 << conf.idxbits
val addrbits = PADDR_BITS val indexbits = conf.idxbits
val indexbits = IDX_BITS val tagmsb = conf.paddrbits-1
val offsetbits = OFFSET_BITS val taglsb = indexbits+conf.offbits
val tagmsb = PADDR_BITS-1
val taglsb = indexbits+offsetbits
val tagbits = tagmsb-taglsb+1 val tagbits = tagmsb-taglsb+1
val indexmsb = taglsb-1 val indexmsb = taglsb-1
val indexlsb = offsetbits val indexlsb = conf.offbits
val offsetmsb = indexlsb-1 val offsetmsb = indexlsb-1
val offsetlsb = log2Up(CPU_DATA_BITS/8) val offsetlsb = log2Up(conf.databytes)
val ramindexlsb = log2Up(MEM_DATA_BITS/8) val ramindexlsb = log2Up(MEM_DATA_BITS/8)
val early_nack = Reg { Bool() } 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 r_cpu_req_tag := io.cpu.req.bits.tag
} }
when (prober.io.meta_req.valid) { 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_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_cmd := mshr.io.data_req.bits.cmd
r_cpu_req_type := mshr.io.data_req.bits.typ 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).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.idx := io.cpu.req.bits.idx(indexmsb,indexlsb)
meta_arb.io.in(3).bits.rw := Bool(false) 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 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 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 = 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_match_way_oh = Cat(Bits(0),tag_match_arr.reverse:_*)(conf.ways-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_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 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 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 === ~UFix(0, NWAYS), tag_match_way_oh, data.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 meta_resp_mux = Mux1H(meta_resp_way_oh, meta.io.resp)
val data_resp_mux = Mux1H(data_resp_way_oh, data.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 wb.io.probe_rep_data <> io.mem.probe_rep_data
// replacement policy // replacement policy
val replacer = new RandomReplacementWayGen() val replacer = new RandomReplacement
replacer.io.way_en := ~UFix(0, NWAYS) val replaced_way_oh = Mux(flusher.io.mshr_req.valid, r_way_oh, UFixToOH(replacer.way))
val replaced_way_oh = Mux(flusher.io.mshr_req.valid, r_way_oh, UFixToOH(replacer.io.way_id, NWAYS))
val meta_wb_mux = Mux1H(replaced_way_oh, meta.io.resp) val meta_wb_mux = Mux1H(replaced_way_oh, meta.io.resp)
// refill response // 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.idx := io.cpu.req.bits.idx(indexmsb,indexlsb)
data_arb.io.in(4).bits.rw := Bool(false) 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).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 data_arb.io.in(4).bits.way_en := Fix(-1) // intiate load on all ways, mux after tag check
val early_load_nack = req_read && !data_arb.io.in(4).ready val early_load_nack = !data_arb.io.in(4).ready
// store hits and AMO hits and misses use a pending store register. // 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. // 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 mshr.io.mem_abort.bits := io.mem.xact_abort.bits
io.mem.xact_abort.ready := Bool(true) io.mem.xact_abort.ready := Bool(true)
mshr.io.meta_req <> meta_arb.io.in(1) 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 // replays
val replay = mshr.io.data_req.bits val replay = mshr.io.data_req.bits
@ -992,13 +988,11 @@ class HellaCache(implicit conf: RocketConfiguration) extends Component {
// store write mask generation. // store write mask generation.
// assumes store replays are higher-priority than pending stores. // 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) val store_offset = Mux(!replay_fire, p_store_idx(offsetmsb,0), replay.offset)
maskgen.io.typ := Mux(!replay_fire, p_store_type, replay.typ) val store_type = Mux(!replay_fire, p_store_type, replay.typ)
maskgen.io.addr := store_offset(offsetlsb-1,0) 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_wmask_wide = maskgen.io.wmask << Cat(store_offset(ramindexlsb-1,offsetlsb), Bits(0, log2Up(CPU_DATA_BITS/8))).toUFix
val store_data = Mux(!replay_fire, p_store_data, replay.data) 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.data := store_data_wide
data_arb.io.in(1).bits.wmask := store_wmask_wide data_arb.io.in(1).bits.wmask := store_wmask_wide
data_arb.io.in(2).bits.data := store_data_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. // load data subword mux/sign extension.
// subword loads are delayed by one cycle. // subword loads are delayed by one cycle.
val loadgen = new LoadDataGen val loadgen_data = data_resp_mux >> Cat(r_cpu_req_idx(log2Up(MEM_DATA_BITS/8)-1,3), Bits(0,6))
val loadgen_use_replay = Reg(replay_fire) val loadgen = LoadGen(r_cpu_req_type, r_cpu_req_idx, loadgen_data)
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
amoalu.io.cmd := p_store_cmd amoalu.io.cmd := p_store_cmd
amoalu.io.typ := p_store_type 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 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 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.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.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.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.typ := r_cpu_req_type
io.cpu.resp.bits.data := loadgen.io.dout io.cpu.resp.bits.data := loadgen.word
io.cpu.resp.bits.data_subword := loadgen.io.r_dout_subword io.cpu.resp.bits.data_subword := Reg(loadgen.byte)
val xact_init_arb = (new Arbiter(2)) { new TransactionInit } val xact_init_arb = (new Arbiter(2)) { new TransactionInit }
xact_init_arb.io.in(0) <> wb.io.mem_req xact_init_arb.io.in(0) <> wb.io.mem_req

View File

@ -5,14 +5,14 @@ import Node._
import Constants._ import Constants._
import scala.math._ 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 requestor = Vec(n) { new IOTLBPTW }.flip
val mem = new ioHellaCache val mem = new ioHellaCache()(conf.dcache)
val ptbr = UFix(INPUT, PADDR_BITS) 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) val io = new ioPTW(n)

View File

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

View File

@ -6,20 +6,26 @@ import Constants._
import uncore._ import uncore._
case class RocketConfiguration(ntiles: Int, co: CoherencePolicyWithUncached, case class RocketConfiguration(ntiles: Int, co: CoherencePolicyWithUncached,
icache: ICacheConfig) icache: ICacheConfig, dcache: DCacheConfig)
class Tile(resetSignal: Bool = null)(implicit conf: RocketConfiguration) extends Component(resetSignal)
{ {
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 io = new Bundle {
val tilelink = new ioTileLink val tilelink = new ioTileLink
val host = new ioHTIF(conf.ntiles) val host = new ioHTIF(conf.ntiles)
} }
val cpu = new rocketProc val cpu = new rocketProc
val icache = new Frontend(conf.icache) val icache = new Frontend()(confIn.icache)
val dcache = new HellaCache 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_DCACHE) <> dcache.io.mem
arbiter.io.requestor(DMEM_ICACHE) <> icache.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) 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 arbiter.io.requestor(DMEM_VICACHE) <> vicache.io.mem
cpu.io.vimem <> vicache.io.cpu cpu.io.vimem <> vicache.io.cpu
} }