merge Aqcuire and AcquireData. cache line size coupled to tilelink data size
This commit is contained in:
parent
e90f2484aa
commit
ebdc0a2692
@ -7,17 +7,19 @@ import Util._
|
|||||||
case class ICacheConfig(sets: Int, assoc: Int,
|
case class ICacheConfig(sets: Int, assoc: Int,
|
||||||
ibytes: Int = 4,
|
ibytes: Int = 4,
|
||||||
ntlb: Int = 8, btb: BTBConfig = BTBConfig(8),
|
ntlb: Int = 8, btb: BTBConfig = BTBConfig(8),
|
||||||
|
tl: TileLinkConfiguration,
|
||||||
code: Code = new IdentityCode)
|
code: Code = new IdentityCode)
|
||||||
{
|
{
|
||||||
val w = 1
|
val w = 1
|
||||||
|
|
||||||
val dm = assoc == 1
|
val dm = assoc == 1
|
||||||
val lines = sets * assoc
|
val lines = sets * assoc
|
||||||
val databits = MEM_DATA_BITS
|
val databits = tl.dataBits
|
||||||
val idxbits = log2Up(sets)
|
val idxbits = log2Up(sets)
|
||||||
val offbits = OFFSET_BITS
|
val offbits = OFFSET_BITS
|
||||||
val untagbits = idxbits + offbits
|
val untagbits = idxbits + offbits
|
||||||
val tagbits = PADDR_BITS - untagbits
|
val tagbits = PADDR_BITS - untagbits
|
||||||
|
def refillcycles = CACHE_DATA_SIZE_IN_BYTES*8/tl.dataBits
|
||||||
|
|
||||||
require(isPow2(sets) && isPow2(assoc))
|
require(isPow2(sets) && isPow2(assoc))
|
||||||
require(isPow2(w) && isPow2(ibytes))
|
require(isPow2(w) && isPow2(ibytes))
|
||||||
@ -133,9 +135,9 @@ class ICacheResp(implicit c: ICacheConfig) extends Bundle {
|
|||||||
override def clone = new ICacheResp().asInstanceOf[this.type]
|
override def clone = new ICacheResp().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
class ICache(implicit c: ICacheConfig) extends Module
|
||||||
{
|
{
|
||||||
implicit val lnConf = tl.ln
|
implicit val (tl, ln) = (c.tl, c.tl.ln)
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Valid(new ICacheReq).flip
|
val req = Valid(new ICacheReq).flip
|
||||||
val resp = Decoupled(new ICacheResp)
|
val resp = Decoupled(new ICacheResp)
|
||||||
@ -179,7 +181,7 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
|||||||
rdy := state === s_ready && !s2_miss
|
rdy := state === s_ready && !s2_miss
|
||||||
|
|
||||||
//assert(!co.isVoluntary(io.mem.grant.bits.payload) || !io.mem.grant.valid, "UncachedRequestors shouldn't get voluntary grants.")
|
//assert(!co.isVoluntary(io.mem.grant.bits.payload) || !io.mem.grant.valid, "UncachedRequestors shouldn't get voluntary grants.")
|
||||||
val (rf_cnt, refill_done) = Counter(io.mem.grant.valid, REFILL_CYCLES)
|
val (rf_cnt, refill_done) = (if(c.refillcycles > 1) Counter(io.mem.grant.valid, c.refillcycles) else (UInt(0), state === s_refill))
|
||||||
val repl_way = if (c.dm) UInt(0) else LFSR16(s2_miss)(log2Up(c.assoc)-1,0)
|
val repl_way = if (c.dm) UInt(0) else LFSR16(s2_miss)(log2Up(c.assoc)-1,0)
|
||||||
|
|
||||||
val enc_tagbits = c.code.width(c.tagbits)
|
val enc_tagbits = c.code.width(c.tagbits)
|
||||||
@ -229,15 +231,16 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
|||||||
s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_)
|
s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_)
|
||||||
|
|
||||||
for (i <- 0 until c.assoc) {
|
for (i <- 0 until c.assoc) {
|
||||||
val data_array = Mem(Bits(width = c.code.width(c.databits)), c.sets*REFILL_CYCLES, seqRead = true)
|
val data_array = Mem(Bits(width = c.code.width(c.databits)), c.sets*c.refillcycles, seqRead = true)
|
||||||
val s1_raddr = Reg(UInt())
|
val s1_raddr = Reg(UInt())
|
||||||
when (io.mem.grant.valid && repl_way === UInt(i)) {
|
when (io.mem.grant.valid && repl_way === UInt(i)) {
|
||||||
val d = io.mem.grant.bits.payload.data
|
val d = io.mem.grant.bits.payload.data
|
||||||
data_array(Cat(s2_idx,rf_cnt)) := c.code.encode(d)
|
if(c.refillcycles > 1) data_array(Cat(s2_idx,rf_cnt)) := c.code.encode(d)
|
||||||
|
else data_array(s2_idx) := c.code.encode(d)
|
||||||
}
|
}
|
||||||
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
// /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM
|
||||||
.elsewhen (s0_valid) {
|
.elsewhen (s0_valid) {
|
||||||
s1_raddr := s0_pgoff(c.untagbits-1,c.offbits-rf_cnt.getWidth)
|
s1_raddr := s0_pgoff(c.untagbits-1,c.offbits-(if(c.refillcycles > 1) rf_cnt.getWidth else 0))
|
||||||
}
|
}
|
||||||
// if s1_tag_match is critical, replace with partial tag check
|
// if s1_tag_match is critical, replace with partial tag check
|
||||||
when (s1_valid && rdy && !stall && (Bool(c.dm) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) }
|
when (s1_valid && rdy && !stall && (Bool(c.dm) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) }
|
||||||
@ -246,16 +249,16 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
|||||||
io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word)
|
io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word)
|
||||||
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout)
|
||||||
|
|
||||||
val finish_q = Module(new Queue(new GrantAck, 1))
|
val ack_q = Module(new Queue(new LogicalNetworkIO(new GrantAck), 1))
|
||||||
finish_q.io.enq.valid := refill_done && tl.co.requiresAckForGrant(io.mem.grant.bits.payload.g_type)
|
ack_q.io.enq.valid := refill_done && tl.co.requiresAckForGrant(io.mem.grant.bits.payload.g_type)
|
||||||
finish_q.io.enq.bits.master_xact_id := io.mem.grant.bits.payload.master_xact_id
|
ack_q.io.enq.bits.payload.master_xact_id := io.mem.grant.bits.payload.master_xact_id
|
||||||
|
ack_q.io.enq.bits.header.dst := io.mem.grant.bits.header.src
|
||||||
|
|
||||||
// output signals
|
// output signals
|
||||||
io.resp.valid := s2_hit
|
io.resp.valid := s2_hit
|
||||||
io.mem.acquire.meta.valid := (state === s_request) && finish_q.io.enq.ready
|
io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready
|
||||||
io.mem.acquire.meta.bits.payload := Acquire(tl.co.getUncachedReadAcquireType, s2_addr >> UInt(c.offbits), UInt(0))
|
io.mem.acquire.bits.payload := Acquire(tl.co.getUncachedReadAcquireType, s2_addr >> UInt(c.offbits), UInt(0))
|
||||||
io.mem.acquire.data.valid := Bool(false)
|
io.mem.grant_ack <> ack_q.io.deq
|
||||||
io.mem.grant_ack <> FIFOedLogicalNetworkIOWrapper(finish_q.io.deq)
|
|
||||||
io.mem.grant.ready := Bool(true)
|
io.mem.grant.ready := Bool(true)
|
||||||
|
|
||||||
// control state machine
|
// control state machine
|
||||||
@ -265,7 +268,7 @@ class ICache(implicit c: ICacheConfig, tl: TileLinkConfiguration) extends Module
|
|||||||
invalidated := Bool(false)
|
invalidated := Bool(false)
|
||||||
}
|
}
|
||||||
is (s_request) {
|
is (s_request) {
|
||||||
when (io.mem.acquire.meta.ready && finish_q.io.enq.ready) { state := s_refill_wait }
|
when (io.mem.acquire.ready && ack_q.io.enq.ready) { state := s_refill_wait }
|
||||||
}
|
}
|
||||||
is (s_refill_wait) {
|
is (s_refill_wait) {
|
||||||
when (io.mem.grant.valid) { state := s_refill }
|
when (io.mem.grant.valid) { state := s_refill }
|
||||||
|
@ -6,7 +6,7 @@ import Util._
|
|||||||
|
|
||||||
case class DCacheConfig(sets: Int, ways: Int,
|
case class DCacheConfig(sets: Int, ways: Int,
|
||||||
nmshr: Int, nrpq: Int, nsdq: Int, ntlb: Int,
|
nmshr: Int, nrpq: Int, nsdq: Int, ntlb: Int,
|
||||||
states: Int = 2,
|
tl: TileLinkConfiguration,
|
||||||
code: Code = new IdentityCode,
|
code: Code = new IdentityCode,
|
||||||
narrowRead: Boolean = true,
|
narrowRead: Boolean = true,
|
||||||
reqtagbits: Int = -1, databits: Int = -1)
|
reqtagbits: Int = -1, databits: Int = -1)
|
||||||
@ -17,6 +17,7 @@ case class DCacheConfig(sets: Int, ways: Int,
|
|||||||
require(log2Up(OFFSET_BITS) <= ACQUIRE_SUBWORD_ADDR_BITS)
|
require(log2Up(OFFSET_BITS) <= ACQUIRE_SUBWORD_ADDR_BITS)
|
||||||
require(isPow2(sets))
|
require(isPow2(sets))
|
||||||
require(isPow2(ways)) // TODO: relax this
|
require(isPow2(ways)) // TODO: relax this
|
||||||
|
def states = tl.co.nClientStates
|
||||||
def lines = sets*ways
|
def lines = sets*ways
|
||||||
def dm = ways == 1
|
def dm = ways == 1
|
||||||
def ppnbits = PADDR_BITS - PGIDX_BITS
|
def ppnbits = PADDR_BITS - PGIDX_BITS
|
||||||
@ -30,15 +31,16 @@ case class DCacheConfig(sets: Int, ways: Int,
|
|||||||
def waybits = log2Up(ways)
|
def waybits = log2Up(ways)
|
||||||
def untagbits = offbits + idxbits
|
def untagbits = offbits + idxbits
|
||||||
def tagbits = lineaddrbits - idxbits
|
def tagbits = lineaddrbits - idxbits
|
||||||
def ramoffbits = log2Up(MEM_DATA_BITS/8)
|
def ramoffbits = log2Up(tl.dataBits/8)
|
||||||
def databytes = databits/8
|
def databytes = databits/8
|
||||||
def wordoffbits = log2Up(databytes)
|
def wordoffbits = log2Up(databytes)
|
||||||
def isNarrowRead = narrowRead && databits*ways % MEM_DATA_BITS == 0
|
def isNarrowRead = narrowRead && databits*ways % tl.dataBits == 0
|
||||||
|
def refillcycles = CACHE_DATA_SIZE_IN_BYTES*8/tl.dataBits
|
||||||
val statebits = log2Up(states)
|
val statebits = log2Up(states)
|
||||||
val metabits = statebits + tagbits
|
val metabits = statebits + tagbits
|
||||||
val encdatabits = code.width(databits)
|
val encdatabits = code.width(databits)
|
||||||
val encmetabits = code.width(metabits)
|
val encmetabits = code.width(metabits)
|
||||||
val wordsperrow = MEM_DATA_BITS/databits
|
val wordsperrow = tl.dataBits/databits
|
||||||
val bitsperrow = wordsperrow*encdatabits
|
val bitsperrow = wordsperrow*encdatabits
|
||||||
val lrsc_cycles = 32 // ISA requires 16-insn LRSC sequences to succeed
|
val lrsc_cycles = 32 // ISA requires 16-insn LRSC sequences to succeed
|
||||||
}
|
}
|
||||||
@ -120,18 +122,19 @@ class DataWriteReq(implicit val conf: DCacheConfig) extends DCacheBundle {
|
|||||||
val data = Bits(width = conf.bitsperrow)
|
val data = Bits(width = conf.bitsperrow)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InternalProbe(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Probe {
|
class InternalProbe(implicit conf: DCacheConfig) extends Probe()(conf.tl) {
|
||||||
val client_xact_id = Bits(width = tl.clientXactIdBits)
|
val client_xact_id = Bits(width = conf.tl.clientXactIdBits)
|
||||||
|
|
||||||
override def clone = new InternalProbe().asInstanceOf[this.type]
|
override def clone = new InternalProbe().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class WritebackReq(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Bundle {
|
class WritebackReq(implicit conf: DCacheConfig) extends Bundle {
|
||||||
val tag = Bits(width = conf.tagbits)
|
val tag = Bits(width = conf.tagbits)
|
||||||
val idx = Bits(width = conf.idxbits)
|
val idx = Bits(width = conf.idxbits)
|
||||||
val way_en = Bits(width = conf.ways)
|
val way_en = Bits(width = conf.ways)
|
||||||
val client_xact_id = Bits(width = tl.clientXactIdBits)
|
val client_xact_id = Bits(width = conf.tl.clientXactIdBits)
|
||||||
val r_type = UInt(width = tl.co.releaseTypeWidth)
|
val master_xact_id = Bits(width = conf.tl.masterXactIdBits)
|
||||||
|
val r_type = UInt(width = conf.tl.co.releaseTypeWidth)
|
||||||
|
|
||||||
override def clone = new WritebackReq().asInstanceOf[this.type]
|
override def clone = new WritebackReq().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
@ -159,8 +162,8 @@ class MetaWriteReq(implicit val conf: DCacheConfig) extends DCacheBundle {
|
|||||||
val data = new MetaData()
|
val data = new MetaData()
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val (tl, ln) = (conf.tl, conf.tl.ln)
|
||||||
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)
|
||||||
@ -189,7 +192,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
val acquire_type = Reg(UInt())
|
val acquire_type = Reg(UInt())
|
||||||
val release_type = Reg(UInt())
|
val release_type = Reg(UInt())
|
||||||
val line_state = Reg(UInt())
|
val line_state = Reg(UInt())
|
||||||
val refill_count = Reg(UInt(width = log2Up(REFILL_CYCLES)))
|
val refill_count = Reg(UInt(width = log2Up(conf.refillcycles))) // TODO: zero-width wire
|
||||||
val req = Reg(new MSHRReq())
|
val req = Reg(new MSHRReq())
|
||||||
|
|
||||||
val req_cmd = io.req_bits.cmd
|
val req_cmd = io.req_bits.cmd
|
||||||
@ -198,7 +201,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
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) && !tl.co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits))
|
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) && !tl.co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits))
|
||||||
|
|
||||||
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
|
val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id)
|
||||||
val refill_done = reply && refill_count.andR
|
val refill_done = reply && (if(conf.refillcycles > 1) refill_count.andR else Bool(true))
|
||||||
val wb_done = reply && (state === s_wb_resp)
|
val wb_done = reply && (state === s_wb_resp)
|
||||||
|
|
||||||
val rpq = Module(new Queue(new Replay, conf.nrpq))
|
val rpq = Module(new Queue(new Replay, conf.nrpq))
|
||||||
@ -220,7 +223,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
when (state === s_refill_resp) {
|
when (state === s_refill_resp) {
|
||||||
when (refill_done) { state := s_meta_write_req }
|
when (refill_done) { state := s_meta_write_req }
|
||||||
when (reply) {
|
when (reply) {
|
||||||
refill_count := refill_count + UInt(1)
|
if(conf.refillcycles > 1) refill_count := refill_count + UInt(1)
|
||||||
line_state := tl.co.newStateOnGrant(io.mem_grant.bits.payload, io.mem_req.bits)
|
line_state := tl.co.newStateOnGrant(io.mem_grant.bits.payload, io.mem_req.bits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +273,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
|
|
||||||
io.idx_match := (state != s_invalid) && idx_match
|
io.idx_match := (state != s_invalid) && idx_match
|
||||||
io.mem_resp := req
|
io.mem_resp := req
|
||||||
io.mem_resp.addr := Cat(req_idx, refill_count) << conf.ramoffbits
|
io.mem_resp.addr := (if(conf.refillcycles > 1) Cat(req_idx, refill_count) else req_idx) << conf.ramoffbits
|
||||||
io.tag := req.addr >> conf.untagbits
|
io.tag := req.addr >> conf.untagbits
|
||||||
io.req_pri_rdy := state === s_invalid
|
io.req_pri_rdy := state === s_invalid
|
||||||
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
||||||
@ -291,6 +294,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
io.wb_req.bits.idx := req_idx
|
io.wb_req.bits.idx := req_idx
|
||||||
io.wb_req.bits.way_en := req.way_en
|
io.wb_req.bits.way_en := req.way_en
|
||||||
io.wb_req.bits.client_xact_id := Bits(id)
|
io.wb_req.bits.client_xact_id := Bits(id)
|
||||||
|
io.wb_req.bits.master_xact_id := Bits(0) // DNC
|
||||||
io.wb_req.bits.r_type := tl.co.getReleaseTypeOnVoluntaryWriteback()
|
io.wb_req.bits.r_type := tl.co.getReleaseTypeOnVoluntaryWriteback()
|
||||||
|
|
||||||
io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready
|
io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready
|
||||||
@ -314,8 +318,8 @@ class MSHR(id: Int)(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class MSHRFile(implicit conf: DCacheConfig) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val (tl, ln) = (conf.tl, conf.tl.ln)
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new MSHRReq).flip
|
val req = Decoupled(new MSHRReq).flip
|
||||||
val secondary_miss = Bool(OUTPUT)
|
val secondary_miss = Bool(OUTPUT)
|
||||||
@ -416,22 +420,23 @@ class MSHRFile(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends M
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class WritebackUnit(implicit conf: DCacheConfig) extends Module {
|
||||||
|
implicit val tl = conf.tl
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new WritebackReq()).flip
|
val req = Decoupled(new WritebackReq()).flip
|
||||||
val probe = Decoupled(new WritebackReq()).flip
|
|
||||||
val meta_read = Decoupled(new MetaReadReq)
|
val meta_read = Decoupled(new MetaReadReq)
|
||||||
val data_req = Decoupled(new DataReadReq())
|
val data_req = Decoupled(new DataReadReq())
|
||||||
val data_resp = Bits(INPUT, conf.bitsperrow)
|
val data_resp = Bits(INPUT, conf.bitsperrow)
|
||||||
val release = Decoupled(new Release)
|
val release = Decoupled(new Release)
|
||||||
val release_data = Decoupled(new ReleaseData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require(conf.refillcycles == 1) // TODO Currently will issue refillcycles distinct releases; need to merge if rowsize < tilelink.dataSize
|
||||||
|
|
||||||
val valid = Reg(init=Bool(false))
|
val valid = Reg(init=Bool(false))
|
||||||
val r1_data_req_fired = Reg(init=Bool(false))
|
val r1_data_req_fired = Reg(init=Bool(false))
|
||||||
val r2_data_req_fired = Reg(init=Bool(false))
|
val r2_data_req_fired = Reg(init=Bool(false))
|
||||||
val cmd_sent = Reg(Bool())
|
val cmd_sent = Reg(Bool())
|
||||||
val cnt = Reg(UInt(width = log2Up(REFILL_CYCLES+1)))
|
val cnt = Reg(UInt(width = log2Up(conf.refillcycles+1)))
|
||||||
val req = Reg(new WritebackReq)
|
val req = Reg(new WritebackReq)
|
||||||
|
|
||||||
when (valid) {
|
when (valid) {
|
||||||
@ -441,26 +446,18 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
r1_data_req_fired := true
|
r1_data_req_fired := true
|
||||||
cnt := cnt + 1
|
cnt := cnt + 1
|
||||||
}
|
}
|
||||||
|
when (r2_data_req_fired && !io.release.ready) {
|
||||||
when (r2_data_req_fired && !io.release_data.ready) {
|
|
||||||
r1_data_req_fired := false
|
r1_data_req_fired := false
|
||||||
r2_data_req_fired := false
|
r2_data_req_fired := false
|
||||||
cnt := cnt - Mux[UInt](r1_data_req_fired, 2, 1)
|
cnt := (if(conf.refillcycles > 1) cnt - Mux[UInt](r1_data_req_fired, 2, 1) else UInt(0))
|
||||||
}
|
}
|
||||||
|
when (io.release.fire()) {
|
||||||
when (!r1_data_req_fired && !r2_data_req_fired && cmd_sent && cnt === REFILL_CYCLES) {
|
cmd_sent := true
|
||||||
|
}
|
||||||
|
when (!r1_data_req_fired && !r2_data_req_fired && cmd_sent && cnt === conf.refillcycles) {
|
||||||
valid := false
|
valid := false
|
||||||
}
|
}
|
||||||
|
|
||||||
when (valid && io.release.ready) {
|
|
||||||
cmd_sent := true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
when (io.probe.fire()) {
|
|
||||||
valid := true
|
|
||||||
cmd_sent := true
|
|
||||||
cnt := 0
|
|
||||||
req := io.probe.bits
|
|
||||||
}
|
}
|
||||||
when (io.req.fire()) {
|
when (io.req.fire()) {
|
||||||
valid := true
|
valid := true
|
||||||
@ -469,26 +466,27 @@ class WritebackUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) exte
|
|||||||
req := io.req.bits
|
req := io.req.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
val fire = valid && cnt < UInt(REFILL_CYCLES)
|
val fire = valid && cnt < UInt(conf.refillcycles)
|
||||||
io.req.ready := !valid && !io.probe.valid
|
io.req.ready := !valid
|
||||||
io.probe.ready := !valid
|
|
||||||
io.data_req.valid := fire
|
io.data_req.valid := fire
|
||||||
io.data_req.bits.way_en := req.way_en
|
io.data_req.bits.way_en := req.way_en
|
||||||
io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(REFILL_CYCLES)-1,0)) << conf.ramoffbits
|
io.data_req.bits.addr := (if(conf.refillcycles > 1) Cat(req.idx, cnt(log2Up(conf.refillcycles)-1,0))
|
||||||
|
else req.idx) << conf.ramoffbits
|
||||||
|
|
||||||
io.release.valid := valid && !cmd_sent
|
io.release.valid := valid && r2_data_req_fired
|
||||||
io.release.bits.r_type := req.r_type
|
io.release.bits.r_type := req.r_type
|
||||||
io.release.bits.addr := Cat(req.tag, req.idx).toUInt
|
io.release.bits.addr := Cat(req.tag, req.idx).toUInt
|
||||||
io.release.bits.client_xact_id := req.client_xact_id
|
io.release.bits.client_xact_id := req.client_xact_id
|
||||||
io.release.bits.master_xact_id := UInt(0)
|
io.release.bits.master_xact_id := req.master_xact_id
|
||||||
io.release_data.valid := r2_data_req_fired
|
io.release.bits.data := io.data_resp
|
||||||
io.release_data.bits.data := io.data_resp
|
|
||||||
|
|
||||||
|
// We reissue the meta read as it sets up the muxing for s2_data_muxed
|
||||||
io.meta_read.valid := fire
|
io.meta_read.valid := fire
|
||||||
io.meta_read.bits.addr := io.release.bits.addr << conf.offbits
|
io.meta_read.bits.addr := io.release.bits.addr << conf.offbits
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class ProbeUnit(implicit conf: DCacheConfig) extends Module {
|
||||||
|
implicit val tl = conf.tl
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Decoupled(new InternalProbe).flip
|
val req = Decoupled(new InternalProbe).flip
|
||||||
val rep = Decoupled(new Release)
|
val rep = Decoupled(new Release)
|
||||||
@ -543,7 +541,7 @@ class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
io.req.ready := state === s_invalid
|
io.req.ready := state === s_invalid
|
||||||
io.rep.valid := state === s_release
|
io.rep.valid := state === s_release && !tl.co.needsWriteback(line_state)
|
||||||
io.rep.bits := Release(tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.newStateOnFlush)), req.addr, req.client_xact_id, req.master_xact_id)
|
io.rep.bits := Release(tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.newStateOnFlush)), req.addr, req.client_xact_id, req.master_xact_id)
|
||||||
|
|
||||||
io.meta_read.valid := state === s_meta_read
|
io.meta_read.valid := state === s_meta_read
|
||||||
@ -559,11 +557,13 @@ class ProbeUnit(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
io.wb_req.bits.way_en := way_en
|
io.wb_req.bits.way_en := way_en
|
||||||
io.wb_req.bits.idx := req.addr
|
io.wb_req.bits.idx := req.addr
|
||||||
io.wb_req.bits.tag := req.addr >> UInt(conf.idxbits)
|
io.wb_req.bits.tag := req.addr >> UInt(conf.idxbits)
|
||||||
io.wb_req.bits.r_type := UInt(0) // DNC
|
io.wb_req.bits.r_type := tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.newStateOnFlush))
|
||||||
io.wb_req.bits.client_xact_id := UInt(0) // DNC
|
io.wb_req.bits.client_xact_id := req.client_xact_id
|
||||||
|
io.wb_req.bits.master_xact_id := req.master_xact_id
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetaDataArray(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class MetaDataArray(implicit conf: DCacheConfig) extends Module {
|
||||||
|
implicit val tl = conf.tl
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val read = Decoupled(new MetaReadReq).flip
|
val read = Decoupled(new MetaReadReq).flip
|
||||||
val write = Decoupled(new MetaWriteReq).flip
|
val write = Decoupled(new MetaWriteReq).flip
|
||||||
@ -612,7 +612,7 @@ class DataArray(implicit conf: DCacheConfig) extends Module {
|
|||||||
val resp = Vec.fill(conf.wordsperrow){Bits(width = conf.bitsperrow)}
|
val resp = Vec.fill(conf.wordsperrow){Bits(width = conf.bitsperrow)}
|
||||||
val r_raddr = RegEnable(io.read.bits.addr, io.read.valid)
|
val r_raddr = RegEnable(io.read.bits.addr, io.read.valid)
|
||||||
for (p <- 0 until resp.size) {
|
for (p <- 0 until resp.size) {
|
||||||
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*REFILL_CYCLES, seqRead = true)
|
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*conf.refillcycles, seqRead = true)
|
||||||
when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) {
|
when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) {
|
||||||
val data = Fill(conf.wordsperrow, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p))
|
val data = Fill(conf.wordsperrow, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p))
|
||||||
val mask = FillInterleaved(conf.encdatabits, wway_en)
|
val mask = FillInterleaved(conf.encdatabits, wway_en)
|
||||||
@ -631,7 +631,7 @@ class DataArray(implicit conf: DCacheConfig) extends Module {
|
|||||||
} else {
|
} else {
|
||||||
val wmask = FillInterleaved(conf.encdatabits, io.write.bits.wmask)
|
val wmask = FillInterleaved(conf.encdatabits, io.write.bits.wmask)
|
||||||
for (w <- 0 until conf.ways) {
|
for (w <- 0 until conf.ways) {
|
||||||
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*REFILL_CYCLES, seqRead = true)
|
val array = Mem(Bits(width=conf.bitsperrow), conf.sets*conf.refillcycles, seqRead = true)
|
||||||
when (io.write.bits.way_en(w) && io.write.valid) {
|
when (io.write.bits.way_en(w) && io.write.valid) {
|
||||||
array.write(waddr, io.write.bits.data, wmask)
|
array.write(waddr, io.write.bits.data, wmask)
|
||||||
}
|
}
|
||||||
@ -727,8 +727,8 @@ class HellaCacheIO(implicit conf: DCacheConfig) extends Bundle {
|
|||||||
val ordered = Bool(INPUT)
|
val ordered = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends Module {
|
class HellaCache(implicit conf: DCacheConfig) extends Module {
|
||||||
implicit val ln = tl.ln
|
implicit val (tl, ln) = (conf.tl, conf.tl.ln)
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
val mem = new TileLinkIO
|
val mem = new TileLinkIO
|
||||||
@ -930,16 +930,11 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
mshrs.io.req.bits.old_meta := Mux(s2_tag_match, MetaData(s2_repl_meta.tag, s2_hit_state), s2_repl_meta)
|
mshrs.io.req.bits.old_meta := Mux(s2_tag_match, MetaData(s2_repl_meta.tag, s2_hit_state), s2_repl_meta)
|
||||||
mshrs.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
|
mshrs.io.req.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
|
||||||
mshrs.io.req.bits.data := s2_req.data
|
mshrs.io.req.bits.data := s2_req.data
|
||||||
|
when (mshrs.io.req.fire()) { replacer.miss }
|
||||||
|
|
||||||
mshrs.io.mem_grant.valid := io.mem.grant.fire()
|
mshrs.io.mem_grant.valid := io.mem.grant.fire()
|
||||||
mshrs.io.mem_grant.bits := io.mem.grant.bits
|
mshrs.io.mem_grant.bits := io.mem.grant.bits
|
||||||
when (mshrs.io.req.fire()) { replacer.miss }
|
io.mem.acquire <> DecoupledLogicalNetworkIOWrapper(mshrs.io.mem_req)
|
||||||
|
|
||||||
io.mem.acquire.meta <> FIFOedLogicalNetworkIOWrapper(mshrs.io.mem_req)
|
|
||||||
//TODO io.mem.acquire.data should be connected to uncached store data generator
|
|
||||||
//io.mem.acquire.data <> FIFOedLogicalNetworkIOWrapper(TODO)
|
|
||||||
io.mem.acquire.data.valid := Bool(false)
|
|
||||||
io.mem.acquire.data.bits.payload.data := UInt(0)
|
|
||||||
|
|
||||||
// replays
|
// replays
|
||||||
readArb.io.in(1).valid := mshrs.io.replay.valid
|
readArb.io.in(1).valid := mshrs.io.replay.valid
|
||||||
@ -951,14 +946,13 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
metaWriteArb.io.in(0) <> mshrs.io.meta_write
|
||||||
// probes
|
// probes
|
||||||
val releaseArb = Module(new Arbiter(new Release, 2))
|
val releaseArb = Module(new Arbiter(new Release, 2))
|
||||||
FIFOedLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release.meta
|
DecoupledLogicalNetworkIOWrapper(releaseArb.io.out) <> io.mem.release
|
||||||
|
|
||||||
val probe = FIFOedLogicalNetworkIOUnwrapper(io.mem.probe)
|
val probe = DecoupledLogicalNetworkIOUnwrapper(io.mem.probe)
|
||||||
prober.io.req.valid := probe.valid && !lrsc_valid
|
prober.io.req.valid := probe.valid && !lrsc_valid
|
||||||
probe.ready := prober.io.req.ready && !lrsc_valid
|
probe.ready := prober.io.req.ready && !lrsc_valid
|
||||||
prober.io.req.bits := probe.bits
|
prober.io.req.bits := probe.bits
|
||||||
prober.io.rep <> releaseArb.io.in(1)
|
prober.io.rep <> releaseArb.io.in(1)
|
||||||
prober.io.wb_req <> wb.io.probe
|
|
||||||
prober.io.way_en := s2_tag_match_way
|
prober.io.way_en := s2_tag_match_way
|
||||||
prober.io.line_state := s2_hit_state
|
prober.io.line_state := s2_hit_state
|
||||||
prober.io.meta_read <> metaReadArb.io.in(2)
|
prober.io.meta_read <> metaReadArb.io.in(2)
|
||||||
@ -974,12 +968,14 @@ class HellaCache(implicit conf: DCacheConfig, tl: TileLinkConfiguration) extends
|
|||||||
writeArb.io.in(1).bits.data := io.mem.grant.bits.payload.data
|
writeArb.io.in(1).bits.data := io.mem.grant.bits.payload.data
|
||||||
|
|
||||||
// writebacks
|
// writebacks
|
||||||
wb.io.req <> mshrs.io.wb_req
|
val wbArb = Module(new Arbiter(new WritebackReq, 2))
|
||||||
|
prober.io.wb_req <> wbArb.io.in(0)
|
||||||
|
mshrs.io.wb_req <> wbArb.io.in(1)
|
||||||
|
wbArb.io.out <> wb.io.req
|
||||||
wb.io.meta_read <> metaReadArb.io.in(3)
|
wb.io.meta_read <> metaReadArb.io.in(3)
|
||||||
wb.io.data_req <> readArb.io.in(2)
|
wb.io.data_req <> readArb.io.in(2)
|
||||||
wb.io.data_resp := s2_data_corrected
|
wb.io.data_resp := s2_data_corrected
|
||||||
releaseArb.io.in(0) <> wb.io.release
|
releaseArb.io.in(0) <> wb.io.release
|
||||||
FIFOedLogicalNetworkIOWrapper(wb.io.release_data) <> io.mem.release.data
|
|
||||||
|
|
||||||
// store->load bypassing
|
// store->load bypassing
|
||||||
val s4_valid = Reg(next=s3_valid, init=Bool(false))
|
val s4_valid = Reg(next=s3_valid, init=Bool(false))
|
||||||
|
@ -77,9 +77,8 @@ class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Module
|
|||||||
memArb.io.out.grant <> io.tilelink.grant
|
memArb.io.out.grant <> io.tilelink.grant
|
||||||
io.tilelink.grant_ack <> memArb.io.out.grant_ack
|
io.tilelink.grant_ack <> memArb.io.out.grant_ack
|
||||||
dcache.io.mem.probe <> io.tilelink.probe
|
dcache.io.mem.probe <> io.tilelink.probe
|
||||||
io.tilelink.release.data <> dcache.io.mem.release.data
|
io.tilelink.release.valid := dcache.io.mem.release.valid
|
||||||
io.tilelink.release.meta.valid := dcache.io.mem.release.meta.valid
|
dcache.io.mem.release.ready := io.tilelink.release.ready
|
||||||
dcache.io.mem.release.meta.ready := io.tilelink.release.meta.ready
|
io.tilelink.release.bits := dcache.io.mem.release.bits
|
||||||
io.tilelink.release.meta.bits := dcache.io.mem.release.meta.bits
|
io.tilelink.release.bits.payload.client_xact_id := Cat(dcache.io.mem.release.bits.payload.client_xact_id, UInt(dcachePortId, log2Up(memPorts))) // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client)
|
||||||
io.tilelink.release.meta.bits.payload.client_xact_id := Cat(dcache.io.mem.release.meta.bits.payload.client_xact_id, UInt(dcachePortId, log2Up(memPorts))) // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user