implement transaction finish messages
This commit is contained in:
parent
dba99e07a9
commit
6e16b04ada
@ -397,6 +397,7 @@ class CoherenceHubNull extends CoherenceHub {
|
|||||||
x_rep.valid := io.mem.resp.valid || x_init.valid && is_write
|
x_rep.valid := io.mem.resp.valid || x_init.valid && is_write
|
||||||
|
|
||||||
io.tiles(0).xact_abort.valid := Bool(false)
|
io.tiles(0).xact_abort.valid := Bool(false)
|
||||||
|
io.tiles(0).xact_finish.ready := Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,11 +79,12 @@ class rocketHTIF(w: Int, ncores: Int) extends Component
|
|||||||
val tx_done = packet_ram_raddr - UFix(1) === tx_size
|
val tx_done = packet_ram_raddr - UFix(1) === tx_size
|
||||||
|
|
||||||
val mem_acked = Reg(resetVal = Bool(false))
|
val mem_acked = Reg(resetVal = Bool(false))
|
||||||
|
val mem_gxid = Reg() { Bits() }
|
||||||
val mem_nacked = Reg(resetVal = Bool(false))
|
val mem_nacked = Reg(resetVal = Bool(false))
|
||||||
when (io.mem.xact_rep.valid) { mem_acked := Bool(true) }
|
when (io.mem.xact_rep.valid) { mem_acked := Bool(true); mem_gxid := io.mem.xact_rep.bits.global_xact_id }
|
||||||
when (io.mem.xact_abort.valid) { mem_nacked := Bool(true) }
|
when (io.mem.xact_abort.valid) { mem_nacked := Bool(true) }
|
||||||
|
|
||||||
val state_rx :: state_pcr :: state_mem_req :: state_mem_wdata :: state_mem_wresp :: state_mem_rdata :: state_tx :: Nil = Enum(7) { UFix() }
|
val state_rx :: state_pcr :: state_mem_req :: state_mem_wdata :: state_mem_wresp :: state_mem_rdata :: state_mem_finish :: state_tx :: Nil = Enum(8) { UFix() }
|
||||||
val state = Reg(resetVal = state_rx)
|
val state = Reg(resetVal = state_rx)
|
||||||
|
|
||||||
when (state === state_rx && rx_done) {
|
when (state === state_rx && rx_done) {
|
||||||
@ -113,7 +114,7 @@ class rocketHTIF(w: Int, ncores: Int) extends Component
|
|||||||
mem_nacked := Bool(false)
|
mem_nacked := Bool(false)
|
||||||
}
|
}
|
||||||
when (mem_acked) {
|
when (mem_acked) {
|
||||||
state := state_tx
|
state := state_mem_finish
|
||||||
mem_acked := Bool(false)
|
mem_acked := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,12 +125,15 @@ class rocketHTIF(w: Int, ncores: Int) extends Component
|
|||||||
}
|
}
|
||||||
when (io.mem.xact_rep.valid) {
|
when (io.mem.xact_rep.valid) {
|
||||||
when (mem_cnt.andR) {
|
when (mem_cnt.andR) {
|
||||||
state := state_tx
|
state := state_mem_finish
|
||||||
}
|
}
|
||||||
mem_cnt := mem_cnt + UFix(1)
|
mem_cnt := mem_cnt + UFix(1)
|
||||||
}
|
}
|
||||||
mem_acked := Bool(false)
|
mem_acked := Bool(false)
|
||||||
}
|
}
|
||||||
|
when (state === state_mem_finish && io.mem.xact_finish.ready) {
|
||||||
|
state := state_tx
|
||||||
|
}
|
||||||
when (state === state_tx && tx_done) {
|
when (state === state_tx && tx_done) {
|
||||||
rx_count := UFix(0)
|
rx_count := UFix(0)
|
||||||
tx_count := UFix(0)
|
tx_count := UFix(0)
|
||||||
@ -146,9 +150,10 @@ class rocketHTIF(w: Int, ncores: Int) extends Component
|
|||||||
io.mem.xact_init.valid := state === state_mem_req
|
io.mem.xact_init.valid := state === state_mem_req
|
||||||
io.mem.xact_init.bits.t_type := Mux(cmd === cmd_writemem, X_INIT_WRITE_UNCACHED, X_INIT_READ_UNCACHED)
|
io.mem.xact_init.bits.t_type := Mux(cmd === cmd_writemem, X_INIT_WRITE_UNCACHED, X_INIT_READ_UNCACHED)
|
||||||
io.mem.xact_init.bits.address := addr >> UFix(OFFSET_BITS-3)
|
io.mem.xact_init.bits.address := addr >> UFix(OFFSET_BITS-3)
|
||||||
|
|
||||||
io.mem.xact_init_data.valid:= state === state_mem_wdata
|
io.mem.xact_init_data.valid:= state === state_mem_wdata
|
||||||
io.mem.xact_init_data.bits.data := mem_req_data
|
io.mem.xact_init_data.bits.data := mem_req_data
|
||||||
|
io.mem.xact_finish.valid := state === state_mem_finish
|
||||||
|
io.mem.xact_finish.bits.global_xact_id := mem_gxid
|
||||||
|
|
||||||
pcr_done := Bool(false)
|
pcr_done := Bool(false)
|
||||||
val pcr_mux = (new Mux1H(ncores)) { Bits(width = 64) }
|
val pcr_mux = (new Mux1H(ncores)) { Bits(width = 64) }
|
||||||
|
@ -83,7 +83,7 @@ class rocketICache(sets: Int, assoc: Int) extends Component {
|
|||||||
|
|
||||||
val repl_way = LFSR16(state === s_ready && r_cpu_req_val && !io.cpu.itlb_miss && !tag_hit)(log2up(assoc)-1,0)
|
val repl_way = LFSR16(state === s_ready && r_cpu_req_val && !io.cpu.itlb_miss && !tag_hit)(log2up(assoc)-1,0)
|
||||||
val word_shift = Cat(r_cpu_req_idx(offsetmsb-rf_cnt_bits,offsetlsb), UFix(0, log2up(databits))).toUFix
|
val word_shift = Cat(r_cpu_req_idx(offsetmsb-rf_cnt_bits,offsetlsb), UFix(0, log2up(databits))).toUFix
|
||||||
val tag_we = (state === s_refill) && refill_done
|
val tag_we = refill_done
|
||||||
val tag_addr =
|
val tag_addr =
|
||||||
Mux((state === s_refill), r_cpu_req_idx(indexmsb,indexlsb),
|
Mux((state === s_refill), r_cpu_req_idx(indexmsb,indexlsb),
|
||||||
io.cpu.req_idx(indexmsb,indexlsb)).toUFix;
|
io.cpu.req_idx(indexmsb,indexlsb)).toUFix;
|
||||||
@ -126,13 +126,18 @@ class rocketICache(sets: Int, assoc: Int) extends Component {
|
|||||||
}
|
}
|
||||||
tag_hit := any_hit
|
tag_hit := any_hit
|
||||||
|
|
||||||
|
val finish_q = (new queue(1)) { new TransactionFinish }
|
||||||
|
finish_q.io.enq.valid := refill_done
|
||||||
|
finish_q.io.enq.bits.global_xact_id := io.mem.xact_rep.bits.global_xact_id
|
||||||
|
|
||||||
// output signals
|
// output signals
|
||||||
io.cpu.resp_val := !io.cpu.itlb_miss && (state === s_ready) && r_cpu_req_val && tag_hit;
|
io.cpu.resp_val := !io.cpu.itlb_miss && (state === s_ready) && r_cpu_req_val && tag_hit;
|
||||||
rdy := !io.cpu.itlb_miss && (state === s_ready) && (!r_cpu_req_val || tag_hit);
|
rdy := !io.cpu.itlb_miss && (state === s_ready) && (!r_cpu_req_val || tag_hit);
|
||||||
io.cpu.resp_data := data_mux.io.out
|
io.cpu.resp_data := data_mux.io.out
|
||||||
io.mem.xact_init.valid := (state === s_request)
|
io.mem.xact_init.valid := (state === s_request) && finish_q.io.enq.ready
|
||||||
io.mem.xact_init.bits.t_type := X_INIT_READ_UNCACHED
|
io.mem.xact_init.bits.t_type := X_INIT_READ_UNCACHED
|
||||||
io.mem.xact_init.bits.address := r_cpu_miss_addr(tagmsb,indexlsb).toUFix
|
io.mem.xact_init.bits.address := r_cpu_miss_addr(tagmsb,indexlsb).toUFix
|
||||||
|
io.mem.xact_finish <> finish_q.io.deq
|
||||||
|
|
||||||
// control state machine
|
// control state machine
|
||||||
when (io.cpu.invalidate) {
|
when (io.cpu.invalidate) {
|
||||||
@ -150,7 +155,7 @@ class rocketICache(sets: Int, assoc: Int) extends Component {
|
|||||||
}
|
}
|
||||||
is (s_request)
|
is (s_request)
|
||||||
{
|
{
|
||||||
when (io.mem.xact_init.ready) {
|
when (io.mem.xact_init.ready && finish_q.io.enq.ready) {
|
||||||
state := s_refill_wait;
|
state := s_refill_wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,20 +30,29 @@ class rocketIPrefetcher extends Component() {
|
|||||||
val ip_mem_resp_val = io.mem.xact_rep.valid && io.mem.xact_rep.bits.tile_xact_id(0)
|
val ip_mem_resp_val = io.mem.xact_rep.valid && io.mem.xact_rep.bits.tile_xact_id(0)
|
||||||
val ip_mem_req_rdy = io.mem.xact_init.ready && !prefetch_miss
|
val ip_mem_req_rdy = io.mem.xact_init.ready && !prefetch_miss
|
||||||
|
|
||||||
|
val finish_q = (new queue(1)) { new TransactionFinish }
|
||||||
io.mem.xact_abort.ready := Bool(true)
|
io.mem.xact_abort.ready := Bool(true)
|
||||||
io.mem.xact_init.valid := prefetch_miss || (state === s_req_wait)
|
io.mem.xact_init.valid := prefetch_miss || (state === s_req_wait) && finish_q.io.enq.ready
|
||||||
io.mem.xact_init.bits.t_type := X_INIT_READ_UNCACHED
|
io.mem.xact_init.bits.t_type := X_INIT_READ_UNCACHED
|
||||||
io.mem.xact_init.bits.tile_xact_id := Mux(prefetch_miss, UFix(0), UFix(1))
|
io.mem.xact_init.bits.tile_xact_id := Mux(prefetch_miss, UFix(0), UFix(1))
|
||||||
io.mem.xact_init.bits.address := Mux(prefetch_miss, io.icache.xact_init.bits.address, prefetch_addr);
|
io.mem.xact_init.bits.address := Mux(prefetch_miss, io.icache.xact_init.bits.address, prefetch_addr);
|
||||||
|
|
||||||
val fill_cnt = Reg(resetVal = UFix(0, ceil(log(REFILL_CYCLES)/log(2)).toInt));
|
val finish_arb = (new Arbiter(2)) { new TransactionFinish }
|
||||||
when (ip_mem_resp_val.toBool) { fill_cnt := fill_cnt + UFix(1); }
|
finish_arb.io.in(0) <> io.icache.xact_finish
|
||||||
val fill_done = (~fill_cnt === UFix(0)) & ip_mem_resp_val;
|
finish_arb.io.in(1) <> finish_q.io.deq
|
||||||
|
io.mem.xact_finish <> finish_arb.io.out
|
||||||
|
|
||||||
val forward = Reg(resetVal = Bool(false));
|
val fill_cnt = Reg(resetVal = UFix(0, log2up(REFILL_CYCLES)))
|
||||||
val forward_cnt = Reg(resetVal = UFix(0, ceil(log(REFILL_CYCLES)/log(2)).toInt));
|
when (ip_mem_resp_val) { fill_cnt := fill_cnt + UFix(1) }
|
||||||
when (forward & pdq.io.deq.valid) { forward_cnt := forward_cnt + UFix(1); }
|
val fill_done = fill_cnt.andR && ip_mem_resp_val
|
||||||
val forward_done = (~forward_cnt === UFix(0)) & pdq.io.deq.valid;
|
|
||||||
|
finish_q.io.enq.valid := fill_done
|
||||||
|
finish_q.io.enq.bits.global_xact_id := io.mem.xact_rep.bits.global_xact_id
|
||||||
|
|
||||||
|
val forward = Reg(resetVal = Bool(false))
|
||||||
|
val forward_cnt = Reg(resetVal = UFix(0, log2up(REFILL_CYCLES)))
|
||||||
|
when (forward && pdq.io.deq.valid) { forward_cnt := forward_cnt + UFix(1) }
|
||||||
|
val forward_done = forward_cnt.andR && pdq.io.deq.valid
|
||||||
forward := demand_miss && hit || forward && !forward_done
|
forward := demand_miss && hit || forward && !forward_done
|
||||||
|
|
||||||
io.icache.xact_abort.valid := io.mem.xact_abort.valid && !io.mem.xact_abort.bits.tile_xact_id(0) ||
|
io.icache.xact_abort.valid := io.mem.xact_abort.valid && !io.mem.xact_abort.bits.tile_xact_id(0) ||
|
||||||
@ -61,29 +70,24 @@ class rocketIPrefetcher extends Component() {
|
|||||||
when (demand_miss) { state := s_req_wait; }
|
when (demand_miss) { state := s_req_wait; }
|
||||||
}
|
}
|
||||||
is (s_valid) {
|
is (s_valid) {
|
||||||
when (demand_miss | (forward & forward_done)) { state := s_req_wait; }
|
when (demand_miss || forward && forward_done) { state := s_req_wait }
|
||||||
|
.elsewhen (io.invalidate && !forward) { state := s_invalid }
|
||||||
}
|
}
|
||||||
is (s_refilling) {
|
is (s_refilling) {
|
||||||
when (demand_miss & ~addr_match & fill_done.toBool) { state := s_req_wait; }
|
when (demand_miss && !addr_match && fill_done) { state := s_req_wait }
|
||||||
.elsewhen (demand_miss & ~addr_match) { state := s_bad_resp_wait; }
|
.elsewhen (fill_done) { state := Mux(io.invalidate, s_invalid, s_valid) }
|
||||||
.elsewhen (fill_done.toBool) { state := s_valid; }
|
.elsewhen (demand_miss && !addr_match || io.invalidate) { state := s_bad_resp_wait }
|
||||||
}
|
}
|
||||||
is (s_req_wait) {
|
is (s_req_wait) {
|
||||||
when (ip_mem_req_rdy) { state := s_resp_wait; }
|
when (ip_mem_req_rdy && finish_q.io.enq.ready) { state := s_resp_wait }
|
||||||
}
|
}
|
||||||
is (s_resp_wait) {
|
is (s_resp_wait) {
|
||||||
when (ip_mem_resp_abort) {
|
when (ip_mem_resp_abort) { state := s_invalid }
|
||||||
state := s_invalid
|
.elsewhen (demand_miss && !addr_match || io.invalidate) { state := s_bad_resp_wait }
|
||||||
}
|
|
||||||
.elsewhen (demand_miss && !addr_match) { state := s_bad_resp_wait }
|
|
||||||
.elsewhen (ip_mem_resp_val) { state := s_refilling }
|
.elsewhen (ip_mem_resp_val) { state := s_refilling }
|
||||||
}
|
}
|
||||||
is (s_bad_resp_wait) {
|
is (s_bad_resp_wait) {
|
||||||
when (fill_done || ip_mem_resp_abort) { state := s_req_wait }
|
when (fill_done || ip_mem_resp_abort) { state := s_req_wait }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (io.invalidate) {
|
|
||||||
state := s_invalid
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -174,20 +174,23 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence {
|
|||||||
|
|
||||||
val idx_match = Bool(OUTPUT)
|
val idx_match = Bool(OUTPUT)
|
||||||
val idx = Bits(IDX_BITS, OUTPUT)
|
val idx = Bits(IDX_BITS, OUTPUT)
|
||||||
|
val refill_count = Bits(log2up(REFILL_CYCLES), OUTPUT)
|
||||||
val tag = Bits(TAG_BITS, OUTPUT)
|
val tag = Bits(TAG_BITS, OUTPUT)
|
||||||
val way_oh = Bits(NWAYS, OUTPUT)
|
val way_oh = Bits(NWAYS, OUTPUT)
|
||||||
|
|
||||||
val mem_resp_val = Bool(INPUT)
|
|
||||||
val mem_abort_val = Bool(INPUT)
|
|
||||||
val mem_req = (new ioDecoupled) { new TransactionInit }
|
val mem_req = (new ioDecoupled) { new TransactionInit }
|
||||||
val meta_req = (new ioDecoupled) { new MetaArrayArrayReq() }
|
val meta_req = (new ioDecoupled) { new MetaArrayArrayReq() }
|
||||||
val replay = (new ioDecoupled) { new Replay() }
|
val replay = (new ioDecoupled) { new Replay() }
|
||||||
|
val mem_abort = (new ioPipe) { new TransactionAbort }.flip
|
||||||
|
val mem_rep = (new ioPipe) { new TransactionReply }.flip
|
||||||
|
val mem_finish = (new ioDecoupled) { new TransactionFinish }
|
||||||
}
|
}
|
||||||
|
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = Reg(resetVal = Bool(false))
|
||||||
val state = Reg { UFix() }
|
val state = Reg { UFix() }
|
||||||
val requested = Reg { Bool() }
|
val requested = Reg { Bool() }
|
||||||
val refilled = Reg { Bool() }
|
val refilled = Reg { Bool() }
|
||||||
|
val refill_count = Reg { UFix(width = log2up(REFILL_CYCLES)) }
|
||||||
val ppn = Reg { Bits() }
|
val ppn = Reg { Bits() }
|
||||||
val idx_ = Reg { Bits() }
|
val idx_ = Reg { Bits() }
|
||||||
val way_oh_ = Reg { Bits() }
|
val way_oh_ = Reg { Bits() }
|
||||||
@ -204,11 +207,18 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence {
|
|||||||
rpq.io.enq.bits.sdq_id := io.req_sdq_id
|
rpq.io.enq.bits.sdq_id := io.req_sdq_id
|
||||||
rpq.io.deq.ready := io.replay.ready && refilled
|
rpq.io.deq.ready := io.replay.ready && refilled
|
||||||
|
|
||||||
|
val refill_done = io.mem_rep.valid && io.mem_rep.bits.tile_xact_id === UFix(id) && refill_count.andR
|
||||||
|
|
||||||
|
val finish_q = (new queue(1)) { new TransactionFinish }
|
||||||
|
finish_q.io.enq.valid := refill_done
|
||||||
|
finish_q.io.enq.bits := io.mem_rep.bits.global_xact_id
|
||||||
|
|
||||||
when (io.req_pri_val && io.req_pri_rdy) {
|
when (io.req_pri_val && io.req_pri_rdy) {
|
||||||
valid := Bool(true)
|
valid := Bool(true)
|
||||||
state := newStateOnPrimaryMiss(req_cmd)
|
state := newStateOnPrimaryMiss(req_cmd)
|
||||||
requested := Bool(false)
|
requested := Bool(false)
|
||||||
refilled := Bool(false)
|
refilled := Bool(false)
|
||||||
|
refill_count := UFix(0)
|
||||||
ppn := io.req_bits.ppn
|
ppn := io.req_bits.ppn
|
||||||
idx_ := io.req_bits.idx
|
idx_ := io.req_bits.idx
|
||||||
way_oh_ := io.req_bits.way_oh
|
way_oh_ := io.req_bits.way_oh
|
||||||
@ -217,10 +227,13 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence {
|
|||||||
when (io.mem_req.valid && io.mem_req.ready) {
|
when (io.mem_req.valid && io.mem_req.ready) {
|
||||||
requested := Bool(true)
|
requested := Bool(true)
|
||||||
}
|
}
|
||||||
when (io.mem_abort_val) {
|
when (io.mem_abort.valid && io.mem_abort.bits.tile_xact_id === UFix(id)) {
|
||||||
requested := Bool(false)
|
requested := Bool(false)
|
||||||
}
|
}
|
||||||
when (io.mem_resp_val) {
|
when (io.mem_rep.valid && io.mem_rep.bits.tile_xact_id === UFix(id)) {
|
||||||
|
refill_count := refill_count + UFix(1)
|
||||||
|
}
|
||||||
|
when (refill_done) {
|
||||||
refilled := Bool(true)
|
refilled := Bool(true)
|
||||||
}
|
}
|
||||||
when (io.meta_req.valid && io.meta_req.ready) {
|
when (io.meta_req.valid && io.meta_req.ready) {
|
||||||
@ -233,7 +246,8 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence {
|
|||||||
io.idx := idx_
|
io.idx := idx_
|
||||||
io.tag := ppn
|
io.tag := ppn
|
||||||
io.way_oh := way_oh_
|
io.way_oh := way_oh_
|
||||||
io.req_pri_rdy := !valid
|
io.refill_count := refill_count
|
||||||
|
io.req_pri_rdy := !valid && finish_q.io.enq.ready
|
||||||
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
io.req_sec_rdy := sec_rdy && rpq.io.enq.ready
|
||||||
|
|
||||||
io.meta_req.valid := valid && refilled && !rpq.io.deq.valid
|
io.meta_req.valid := valid && refilled && !rpq.io.deq.valid
|
||||||
@ -247,6 +261,7 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence {
|
|||||||
io.mem_req.bits.t_type := Mux(needsWriteback(next_state), X_INIT_READ_EXCLUSIVE, X_INIT_READ_SHARED)
|
io.mem_req.bits.t_type := Mux(needsWriteback(next_state), X_INIT_READ_EXCLUSIVE, X_INIT_READ_SHARED)
|
||||||
io.mem_req.bits.address := Cat(ppn, idx_).toUFix
|
io.mem_req.bits.address := Cat(ppn, idx_).toUFix
|
||||||
io.mem_req.bits.tile_xact_id := Bits(id)
|
io.mem_req.bits.tile_xact_id := Bits(id)
|
||||||
|
io.mem_finish <> finish_q.io.deq
|
||||||
|
|
||||||
io.replay.valid := rpq.io.deq.valid && refilled
|
io.replay.valid := rpq.io.deq.valid && refilled
|
||||||
io.replay.bits <> rpq.io.deq.bits
|
io.replay.bits <> rpq.io.deq.bits
|
||||||
@ -258,9 +273,8 @@ class MSHRFile extends Component {
|
|||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = (new ioDecoupled) { new MSHRReq }.flip
|
val req = (new ioDecoupled) { new MSHRReq }.flip
|
||||||
|
|
||||||
val mem_resp_val = Bool(INPUT)
|
|
||||||
val mem_resp_tag = Bits(MEM_TAG_BITS, INPUT)
|
|
||||||
val mem_resp_idx = Bits(IDX_BITS, OUTPUT)
|
val mem_resp_idx = Bits(IDX_BITS, OUTPUT)
|
||||||
|
val mem_resp_offset = Bits(log2up(REFILL_CYCLES), OUTPUT)
|
||||||
val mem_resp_way_oh = Bits(NWAYS, OUTPUT)
|
val mem_resp_way_oh = Bits(NWAYS, OUTPUT)
|
||||||
|
|
||||||
val fence_rdy = Bool(OUTPUT)
|
val fence_rdy = Bool(OUTPUT)
|
||||||
@ -269,6 +283,8 @@ class MSHRFile extends Component {
|
|||||||
val meta_req = (new ioDecoupled) { new MetaArrayArrayReq() }
|
val meta_req = (new ioDecoupled) { new MetaArrayArrayReq() }
|
||||||
val data_req = (new ioDecoupled) { new DataReq() }
|
val data_req = (new ioDecoupled) { new DataReq() }
|
||||||
val mem_abort = (new ioPipe) { new TransactionAbort }.flip
|
val mem_abort = (new ioPipe) { new TransactionAbort }.flip
|
||||||
|
val mem_rep = (new ioPipe) { new TransactionReply }.flip
|
||||||
|
val mem_finish = (new ioDecoupled) { new TransactionFinish }
|
||||||
|
|
||||||
val cpu_resp_val = Bool(OUTPUT)
|
val cpu_resp_val = Bool(OUTPUT)
|
||||||
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT)
|
||||||
@ -284,10 +300,10 @@ class MSHRFile extends Component {
|
|||||||
sdq.setTarget('inst)
|
sdq.setTarget('inst)
|
||||||
|
|
||||||
val tag_mux = (new Mux1H(NMSHR)){ Bits(width = TAG_BITS) }
|
val tag_mux = (new Mux1H(NMSHR)){ Bits(width = TAG_BITS) }
|
||||||
val mem_resp_idx_mux = (new Mux1H(NMSHR)){ Bits(width = IDX_BITS) }
|
val mem_resp_mux = (new Mux1H(NMSHR)){ new DataArrayArrayReq }
|
||||||
val mem_resp_way_oh_mux = (new Mux1H(NMSHR)){ Bits(width = NWAYS) }
|
|
||||||
val meta_req_arb = (new Arbiter(NMSHR)) { new MetaArrayArrayReq() }
|
val meta_req_arb = (new Arbiter(NMSHR)) { new MetaArrayArrayReq() }
|
||||||
val mem_req_arb = (new Arbiter(NMSHR)) { new TransactionInit }
|
val mem_req_arb = (new Arbiter(NMSHR)) { new TransactionInit }
|
||||||
|
val mem_finish_arb = (new Arbiter(NMSHR)) { new TransactionFinish }
|
||||||
val replay_arb = (new Arbiter(NMSHR)) { new Replay() }
|
val replay_arb = (new Arbiter(NMSHR)) { new Replay() }
|
||||||
val alloc_arb = (new Arbiter(NMSHR)) { Bool() }
|
val alloc_arb = (new Arbiter(NMSHR)) { Bool() }
|
||||||
|
|
||||||
@ -313,14 +329,15 @@ class MSHRFile extends Component {
|
|||||||
|
|
||||||
mshr.io.meta_req <> meta_req_arb.io.in(i)
|
mshr.io.meta_req <> meta_req_arb.io.in(i)
|
||||||
mshr.io.mem_req <> mem_req_arb.io.in(i)
|
mshr.io.mem_req <> mem_req_arb.io.in(i)
|
||||||
|
mshr.io.mem_finish <> mem_finish_arb.io.in(i)
|
||||||
mshr.io.replay <> replay_arb.io.in(i)
|
mshr.io.replay <> replay_arb.io.in(i)
|
||||||
|
|
||||||
mshr.io.mem_resp_val := io.mem_resp_val && (UFix(i) === io.mem_resp_tag)
|
mshr.io.mem_abort <> io.mem_abort
|
||||||
mshr.io.mem_abort_val := io.mem_abort.valid && (UFix(i) === io.mem_abort.bits.tile_xact_id)
|
mshr.io.mem_rep <> io.mem_rep
|
||||||
mem_resp_idx_mux.io.sel(i) := (UFix(i) === io.mem_resp_tag)
|
mem_resp_mux.io.sel(i) := UFix(i) === io.mem_rep.bits.tile_xact_id
|
||||||
mem_resp_idx_mux.io.in(i) := mshr.io.idx
|
mem_resp_mux.io.in(i).inner_req.idx := mshr.io.idx
|
||||||
mem_resp_way_oh_mux.io.sel(i) := (UFix(i) === io.mem_resp_tag)
|
mem_resp_mux.io.in(i).inner_req.offset := mshr.io.refill_count
|
||||||
mem_resp_way_oh_mux.io.in(i) := mshr.io.way_oh
|
mem_resp_mux.io.in(i).way_en := mshr.io.way_oh
|
||||||
|
|
||||||
pri_rdy = pri_rdy || mshr.io.req_pri_rdy
|
pri_rdy = pri_rdy || mshr.io.req_pri_rdy
|
||||||
sec_rdy = sec_rdy || mshr.io.req_sec_rdy
|
sec_rdy = sec_rdy || mshr.io.req_sec_rdy
|
||||||
@ -332,10 +349,12 @@ class MSHRFile extends Component {
|
|||||||
|
|
||||||
meta_req_arb.io.out <> io.meta_req
|
meta_req_arb.io.out <> io.meta_req
|
||||||
mem_req_arb.io.out <> io.mem_req
|
mem_req_arb.io.out <> io.mem_req
|
||||||
|
mem_finish_arb.io.out <> io.mem_finish
|
||||||
|
|
||||||
io.req.ready := Mux(idx_match, tag_match && sec_rdy, pri_rdy) && sdq_rdy
|
io.req.ready := Mux(idx_match, tag_match && sec_rdy, pri_rdy) && sdq_rdy
|
||||||
io.mem_resp_idx := mem_resp_idx_mux.io.out
|
io.mem_resp_idx := mem_resp_mux.io.out.inner_req.idx
|
||||||
io.mem_resp_way_oh := mem_resp_way_oh_mux.io.out
|
io.mem_resp_offset := mem_resp_mux.io.out.inner_req.offset
|
||||||
|
io.mem_resp_way_oh := mem_resp_mux.io.out.way_en
|
||||||
io.fence_rdy := !fence
|
io.fence_rdy := !fence
|
||||||
|
|
||||||
val replay = Queue(replay_arb.io.out, 1, pipe = true)
|
val replay = Queue(replay_arb.io.out, 1, pipe = true)
|
||||||
@ -361,6 +380,7 @@ class WritebackUnit extends Component {
|
|||||||
val mem_req_data = (new ioDecoupled) { new TransactionInitData }
|
val mem_req_data = (new ioDecoupled) { new TransactionInitData }
|
||||||
val mem_abort = (new ioPipe) { new TransactionAbort }.flip
|
val mem_abort = (new ioPipe) { new TransactionAbort }.flip
|
||||||
val mem_rep = (new ioPipe) { new TransactionReply }.flip
|
val mem_rep = (new ioPipe) { new TransactionReply }.flip
|
||||||
|
val mem_finish = (new ioDecoupled) { new TransactionFinish }
|
||||||
}
|
}
|
||||||
|
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = Reg(resetVal = Bool(false))
|
||||||
@ -374,6 +394,10 @@ class WritebackUnit extends Component {
|
|||||||
when (io.mem_rep.valid && io.mem_rep.bits.tile_xact_id === UFix(NMSHR)) { acked := Bool(true) }
|
when (io.mem_rep.valid && io.mem_rep.bits.tile_xact_id === UFix(NMSHR)) { acked := Bool(true) }
|
||||||
when (io.mem_abort.valid && io.mem_abort.bits.tile_xact_id === UFix(NMSHR)) { nacked := Bool(true) }
|
when (io.mem_abort.valid && io.mem_abort.bits.tile_xact_id === UFix(NMSHR)) { nacked := Bool(true) }
|
||||||
|
|
||||||
|
val finish_q = (new queue(1)) { new TransactionFinish }
|
||||||
|
finish_q.io.enq.valid := io.mem_rep.valid && io.mem_rep.bits.tile_xact_id === UFix(NMSHR)
|
||||||
|
finish_q.io.enq.bits.global_xact_id := io.mem_rep.bits.global_xact_id
|
||||||
|
|
||||||
data_req_fired := Bool(false)
|
data_req_fired := Bool(false)
|
||||||
when (valid && io.mem_req.ready) {
|
when (valid && io.mem_req.ready) {
|
||||||
cmd_sent := Bool(true)
|
cmd_sent := Bool(true)
|
||||||
@ -405,7 +429,7 @@ class WritebackUnit extends Component {
|
|||||||
addr := io.req.bits
|
addr := io.req.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
io.req.ready := !valid
|
io.req.ready := !valid && finish_q.io.enq.ready
|
||||||
io.data_req.valid := valid && (cnt < UFix(REFILL_CYCLES))
|
io.data_req.valid := valid && (cnt < UFix(REFILL_CYCLES))
|
||||||
io.data_req.bits.way_en := addr.way_oh
|
io.data_req.bits.way_en := addr.way_oh
|
||||||
io.data_req.bits.inner_req.idx := addr.idx
|
io.data_req.bits.inner_req.idx := addr.idx
|
||||||
@ -420,9 +444,9 @@ class WritebackUnit extends Component {
|
|||||||
io.mem_req.bits.t_type := Mux(wb_req_val, X_INIT_WRITE_UNCACHED, io.refill_req.bits.t_type)
|
io.mem_req.bits.t_type := Mux(wb_req_val, X_INIT_WRITE_UNCACHED, io.refill_req.bits.t_type)
|
||||||
io.mem_req.bits.address := Mux(wb_req_val, Cat(addr.ppn, addr.idx).toUFix, io.refill_req.bits.address)
|
io.mem_req.bits.address := Mux(wb_req_val, Cat(addr.ppn, addr.idx).toUFix, io.refill_req.bits.address)
|
||||||
io.mem_req.bits.tile_xact_id := Mux(wb_req_val, Bits(NMSHR), io.refill_req.bits.tile_xact_id)
|
io.mem_req.bits.tile_xact_id := Mux(wb_req_val, Bits(NMSHR), io.refill_req.bits.tile_xact_id)
|
||||||
|
|
||||||
io.mem_req_data.valid := data_req_fired
|
io.mem_req_data.valid := data_req_fired
|
||||||
io.mem_req_data.bits.data := io.data_resp
|
io.mem_req_data.bits.data := io.data_resp
|
||||||
|
io.mem_finish <> finish_q.io.deq
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlushUnit(lines: Int) extends Component with ThreeStateIncoherence{
|
class FlushUnit(lines: Int) extends Component with ThreeStateIncoherence{
|
||||||
@ -713,12 +737,6 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence {
|
|||||||
}
|
}
|
||||||
val cpu_req_data = Mux(r_replay_amo, r_amo_replay_data, io.cpu.req_data)
|
val cpu_req_data = Mux(r_replay_amo, r_amo_replay_data, io.cpu.req_data)
|
||||||
|
|
||||||
// refill counter
|
|
||||||
val refill_val = io.mem.xact_rep.valid && io.mem.xact_rep.bits.tile_xact_id < UFix(NMSHR)
|
|
||||||
val rr_count = Reg(resetVal = UFix(0, log2up(REFILL_CYCLES)))
|
|
||||||
val rr_count_next = rr_count + UFix(1)
|
|
||||||
when (refill_val) { rr_count := rr_count_next }
|
|
||||||
|
|
||||||
val misaligned =
|
val misaligned =
|
||||||
(((r_cpu_req_type === MT_H) || (r_cpu_req_type === MT_HU)) && (r_cpu_req_idx(0) != Bits(0))) ||
|
(((r_cpu_req_type === MT_H) || (r_cpu_req_type === MT_HU)) && (r_cpu_req_idx(0) != Bits(0))) ||
|
||||||
(((r_cpu_req_type === MT_W) || (r_cpu_req_type === MT_WU)) && (r_cpu_req_idx(1,0) != Bits(0))) ||
|
(((r_cpu_req_type === MT_W) || (r_cpu_req_type === MT_WU)) && (r_cpu_req_idx(1,0) != Bits(0))) ||
|
||||||
@ -757,12 +775,14 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence {
|
|||||||
val data_resp_mux = Mux1H(NWAYS, data_resp_way_oh, data.io.resp)
|
val data_resp_mux = Mux1H(NWAYS, data_resp_way_oh, data.io.resp)
|
||||||
|
|
||||||
// writeback unit
|
// writeback unit
|
||||||
|
val finish_arb = (new Arbiter(2)) { new TransactionFinish }
|
||||||
val wb = new WritebackUnit
|
val wb = new WritebackUnit
|
||||||
val wb_arb = (new Arbiter(2)) { new WritebackReq() }
|
val wb_arb = (new Arbiter(2)) { new WritebackReq() }
|
||||||
wb_arb.io.out <> wb.io.req
|
wb_arb.io.out <> wb.io.req
|
||||||
wb.io.data_req <> data_arb.io.in(3)
|
wb.io.data_req <> data_arb.io.in(3)
|
||||||
wb.io.data_resp <> data_resp_mux
|
wb.io.data_resp <> data_resp_mux
|
||||||
wb.io.mem_rep <> io.mem.xact_rep
|
wb.io.mem_rep <> io.mem.xact_rep
|
||||||
|
wb.io.mem_finish <> finish_arb.io.in(0)
|
||||||
wb.io.mem_abort.valid := io.mem.xact_abort.valid
|
wb.io.mem_abort.valid := io.mem.xact_abort.valid
|
||||||
wb.io.mem_abort.bits := io.mem.xact_abort.bits
|
wb.io.mem_abort.bits := io.mem.xact_abort.bits
|
||||||
|
|
||||||
@ -775,14 +795,13 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence {
|
|||||||
val needs_writeback = needsWriteback(meta_wb_mux.state)
|
val needs_writeback = needsWriteback(meta_wb_mux.state)
|
||||||
|
|
||||||
// refill response
|
// refill response
|
||||||
val block_during_refill = !refill_val && (rr_count != UFix(0))
|
data_arb.io.in(0).bits.inner_req.offset := mshr.io.mem_resp_offset
|
||||||
data_arb.io.in(0).bits.inner_req.offset := rr_count
|
|
||||||
data_arb.io.in(0).bits.inner_req.idx := mshr.io.mem_resp_idx
|
data_arb.io.in(0).bits.inner_req.idx := mshr.io.mem_resp_idx
|
||||||
data_arb.io.in(0).bits.inner_req.rw := !block_during_refill
|
data_arb.io.in(0).bits.inner_req.rw := Bool(true)
|
||||||
data_arb.io.in(0).bits.inner_req.wmask := ~UFix(0, MEM_DATA_BITS/8)
|
data_arb.io.in(0).bits.inner_req.wmask := ~UFix(0, MEM_DATA_BITS/8)
|
||||||
data_arb.io.in(0).bits.inner_req.data := io.mem.xact_rep.bits.data
|
data_arb.io.in(0).bits.inner_req.data := io.mem.xact_rep.bits.data
|
||||||
data_arb.io.in(0).bits.way_en := mshr.io.mem_resp_way_oh
|
data_arb.io.in(0).bits.way_en := mshr.io.mem_resp_way_oh
|
||||||
data_arb.io.in(0).valid := refill_val || block_during_refill
|
data_arb.io.in(0).valid := io.mem.xact_rep.valid && io.mem.xact_rep.bits.tile_xact_id < UFix(NMSHR)
|
||||||
|
|
||||||
// load hits
|
// load hits
|
||||||
data_arb.io.in(4).bits.inner_req.offset := io.cpu.req_idx(offsetmsb,ramindexlsb)
|
data_arb.io.in(4).bits.inner_req.offset := io.cpu.req_idx(offsetmsb,ramindexlsb)
|
||||||
@ -855,8 +874,8 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence {
|
|||||||
mshr.io.req.bits.way_oh := replaced_way_oh
|
mshr.io.req.bits.way_oh := replaced_way_oh
|
||||||
mshr.io.req.bits.data := cpu_req_data
|
mshr.io.req.bits.data := cpu_req_data
|
||||||
|
|
||||||
mshr.io.mem_resp_val := refill_val && (~rr_count === UFix(0))
|
mshr.io.mem_rep <> io.mem.xact_rep
|
||||||
mshr.io.mem_resp_tag := io.mem.xact_rep.bits.tile_xact_id
|
mshr.io.mem_finish <> finish_arb.io.in(1)
|
||||||
mshr.io.mem_abort.valid := io.mem.xact_abort.valid
|
mshr.io.mem_abort.valid := io.mem.xact_abort.valid
|
||||||
mshr.io.mem_abort.bits := io.mem.xact_abort.bits
|
mshr.io.mem_abort.bits := io.mem.xact_abort.bits
|
||||||
mshr.io.mem_req <> wb.io.refill_req
|
mshr.io.mem_req <> wb.io.refill_req
|
||||||
@ -939,4 +958,5 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence {
|
|||||||
|
|
||||||
io.mem.xact_init <> wb.io.mem_req
|
io.mem.xact_init <> wb.io.mem_req
|
||||||
io.mem.xact_init_data <> wb.io.mem_req_data
|
io.mem.xact_init_data <> wb.io.mem_req_data
|
||||||
|
io.mem.xact_finish <> finish_arb.io.out
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ class Top() extends Component {
|
|||||||
hub.io.tiles(0).xact_init <> Queue(arbiter.io.mem.xact_init)
|
hub.io.tiles(0).xact_init <> Queue(arbiter.io.mem.xact_init)
|
||||||
arbiter.io.mem.xact_abort <> Queue(hub.io.tiles(0).xact_abort)
|
arbiter.io.mem.xact_abort <> Queue(hub.io.tiles(0).xact_abort)
|
||||||
arbiter.io.mem.xact_rep <> Pipe(hub.io.tiles(0).xact_rep)
|
arbiter.io.mem.xact_rep <> Pipe(hub.io.tiles(0).xact_rep)
|
||||||
|
hub.io.tiles(0).xact_finish <> Queue(arbiter.io.mem.xact_finish)
|
||||||
// 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)
|
||||||
|
Loading…
Reference in New Issue
Block a user