1
0

Rename some params, use refactored TileLink

This commit is contained in:
Henry Cook 2015-02-01 20:04:13 -08:00
parent 00e074cdd9
commit 741e6b77ad
12 changed files with 248 additions and 300 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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