clean up D$ store data unit
This commit is contained in:
parent
da39810bb2
commit
52101373e0
@ -90,8 +90,8 @@ class ioTileLink extends Bundle {
|
|||||||
val xact_finish = (new ioDecoupled) { new TransactionFinish() }.flip
|
val xact_finish = (new ioDecoupled) { new TransactionFinish() }.flip
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CoherencePolicy {
|
object cpuCmdToRW {
|
||||||
def cpuCmdToRW( cmd: Bits): (Bool, Bool) = {
|
def apply(cmd: Bits): (Bool, Bool) = {
|
||||||
val store = (cmd === M_XWR)
|
val store = (cmd === M_XWR)
|
||||||
val load = (cmd === M_XRD)
|
val load = (cmd === M_XRD)
|
||||||
val amo = cmd(3).toBool
|
val amo = cmd(3).toBool
|
||||||
@ -101,6 +101,9 @@ trait CoherencePolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait CoherencePolicy {
|
||||||
|
}
|
||||||
|
|
||||||
trait ThreeStateIncoherence extends CoherencePolicy {
|
trait ThreeStateIncoherence extends CoherencePolicy {
|
||||||
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() }
|
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() }
|
||||||
|
|
||||||
|
@ -361,51 +361,34 @@ class ReplayUnit extends Component {
|
|||||||
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sdq_val = Reg(resetVal = UFix(0))
|
val sdq_val = Reg(resetVal = Bits(0, NSDQ))
|
||||||
val sdq_alloc_id = PriorityEncoder(~sdq_val(NSDQ-1,0))
|
val sdq_alloc_id = PriorityEncoder(~sdq_val(NSDQ-1,0))
|
||||||
|
|
||||||
val replay_val = Reg(resetVal = Bool(false))
|
val rpq = Queue(io.replay, 1, pipe = true)
|
||||||
val replay_retry = replay_val && !io.data_req.ready
|
rpq.ready := io.data_req.ready
|
||||||
replay_val := io.replay.valid || replay_retry
|
val (rp_read, rp_write) = cpuCmdToRW(rpq.bits.cmd)
|
||||||
|
|
||||||
val rp = Reg { new Replay() }
|
|
||||||
when (io.replay.valid && io.replay.ready) { rp := io.replay.bits }
|
|
||||||
|
|
||||||
val rp_amo = rp.cmd(3).toBool
|
|
||||||
val rp_store = (rp.cmd === M_XWR)
|
|
||||||
val rp_load = (rp.cmd === M_XRD)
|
|
||||||
val rp_write = rp_store || rp_amo
|
|
||||||
val rp_read = rp_load || rp_amo
|
|
||||||
|
|
||||||
val sdq_ren_new = io.replay.valid && (io.replay.bits.cmd != M_XRD)
|
|
||||||
val sdq_ren_retry = replay_retry && rp_write
|
|
||||||
val sdq_ren = sdq_ren_new || sdq_ren_retry
|
|
||||||
val sdq_wen = io.sdq_enq.valid && io.sdq_enq.ready
|
val sdq_wen = io.sdq_enq.valid && io.sdq_enq.ready
|
||||||
val sdq_addr = Mux(sdq_ren_retry, rp.sdq_id, Mux(sdq_ren_new, io.replay.bits.sdq_id, sdq_alloc_id))
|
val sdq = Mem(NSDQ, sdq_wen, sdq_alloc_id, io.sdq_enq.bits)
|
||||||
|
|
||||||
val sdq = Mem(NSDQ){ Bits(width=CPU_DATA_BITS) }
|
|
||||||
sdq.setReadLatency(1);
|
sdq.setReadLatency(1);
|
||||||
sdq.setTarget('inst)
|
sdq.setTarget('inst)
|
||||||
val sdq_dout = sdq.rw(sdq_addr, io.sdq_enq.bits, sdq_wen, cs = sdq_ren || sdq_wen)
|
|
||||||
|
|
||||||
val sdq_free = replay_val && !replay_retry && rp_write
|
val sdq_free = rpq.valid && rpq.ready && rp_write
|
||||||
sdq_val := sdq_val & ~(sdq_free.toUFix << rp.sdq_id) | (sdq_wen.toUFix << sdq_alloc_id)
|
sdq_val := sdq_val & ~(sdq_free.toUFix << rpq.bits.sdq_id) | (sdq_wen.toUFix << sdq_alloc_id)
|
||||||
|
|
||||||
io.sdq_enq.ready := (~sdq_val != UFix(0)) && !sdq_ren
|
io.sdq_enq.ready := !sdq_val.andR
|
||||||
io.sdq_id := sdq_alloc_id
|
io.sdq_id := sdq_alloc_id
|
||||||
|
|
||||||
io.replay.ready := !replay_retry
|
io.data_req.valid := rpq.valid
|
||||||
|
io.way_oh := rpq.bits.way_oh
|
||||||
|
io.data_req.bits.idx := rpq.bits.idx
|
||||||
|
io.data_req.bits.offset := rpq.bits.offset
|
||||||
|
io.data_req.bits.cmd := rpq.bits.cmd
|
||||||
|
io.data_req.bits.typ := rpq.bits.typ
|
||||||
|
io.data_req.bits.data := sdq.read(Mux(rpq.valid && !rpq.ready, rpq.bits.sdq_id, io.replay.bits.sdq_id))
|
||||||
|
|
||||||
io.data_req.valid := replay_val
|
io.cpu_resp_val := Reg(rpq.valid && rpq.ready && rp_read, resetVal = Bool(false))
|
||||||
io.way_oh := rp.way_oh
|
io.cpu_resp_tag := Reg(rpq.bits.tag)
|
||||||
io.data_req.bits.idx := rp.idx
|
|
||||||
io.data_req.bits.offset := rp.offset
|
|
||||||
io.data_req.bits.cmd := rp.cmd
|
|
||||||
io.data_req.bits.typ := rp.typ
|
|
||||||
io.data_req.bits.data := sdq_dout
|
|
||||||
|
|
||||||
io.cpu_resp_val := Reg(replay_val && !replay_retry && rp_read, resetVal = Bool(false))
|
|
||||||
io.cpu_resp_tag := Reg(rp.tag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WritebackUnit extends Component {
|
class WritebackUnit extends Component {
|
||||||
|
@ -79,11 +79,16 @@ class pipereg[T <: Data]()(data: => T) extends Component
|
|||||||
io.deq.bits <> Mem(1, io.enq.valid, UFix(0), io.enq.bits).read(UFix(0))
|
io.deq.bits <> Mem(1, io.enq.valid, UFix(0), io.enq.bits).read(UFix(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
object PipeReg
|
object Pipe
|
||||||
{
|
{
|
||||||
def apply[T <: Data](enq: ioValid[T]) = {
|
def apply[T <: Data](enq: ioValid[T], latency: Int = 1): ioValid[T] = {
|
||||||
val q = (new pipereg) { enq.bits.clone }
|
val q = (new pipereg) { enq.bits.clone }
|
||||||
q.io.enq <> enq
|
q.io.enq <> enq
|
||||||
q.io.deq
|
q.io.deq
|
||||||
|
|
||||||
|
if (latency > 1)
|
||||||
|
Pipe(q.io.deq, latency-1)
|
||||||
|
else
|
||||||
|
q.io.deq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class Top() extends Component {
|
|||||||
// connect hub to memory
|
// connect hub to memory
|
||||||
io.mem.req_cmd <> Queue(hub.io.mem.req_cmd)
|
io.mem.req_cmd <> Queue(hub.io.mem.req_cmd)
|
||||||
io.mem.req_data <> Queue(hub.io.mem.req_data)
|
io.mem.req_data <> Queue(hub.io.mem.req_data)
|
||||||
hub.io.mem.resp <> PipeReg(io.mem.resp)
|
hub.io.mem.resp <> Pipe(io.mem.resp)
|
||||||
|
|
||||||
|
|
||||||
if (HAVE_VEC)
|
if (HAVE_VEC)
|
||||||
|
Loading…
Reference in New Issue
Block a user