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