From 5f12990dfb2edde6f01156cbe7cdf5226e22e4d3 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 6 Mar 2012 00:31:44 -0800 Subject: [PATCH] support memory transaction aborts --- rocket/src/main/scala/arbiter.scala | 86 ++++++++++++--------- rocket/src/main/scala/coherence.scala | 2 + rocket/src/main/scala/consts.scala | 2 +- rocket/src/main/scala/htif.scala | 35 ++++++++- rocket/src/main/scala/icache.scala | 27 ++++--- rocket/src/main/scala/icache_prefetch.scala | 24 +++--- rocket/src/main/scala/nbdcache.scala | 78 +++++++++++++++---- rocket/src/main/scala/top.scala | 7 +- 8 files changed, 183 insertions(+), 78 deletions(-) diff --git a/rocket/src/main/scala/arbiter.scala b/rocket/src/main/scala/arbiter.scala index 9cdeb58f..9c0211a5 100644 --- a/rocket/src/main/scala/arbiter.scala +++ b/rocket/src/main/scala/arbiter.scala @@ -4,62 +4,74 @@ import Chisel._; import Node._; import Constants._; +class ioUncachedRequestor extends Bundle { + val xact_init = (new ioDecoupled) { new TransactionInit() } + val xact_abort = (new ioDecoupled) { new TransactionAbort() }.flip + val xact_rep = (new ioPipe) { new TransactionReply() }.flip + val xact_finish = (new ioDecoupled) { new TransactionFinish() } +} + class rocketMemArbiter(n: Int) extends Component { val io = new Bundle { - val mem = new ioTileLink - val requestor = Vec(n) { new ioTileLink().flip } + val mem = new ioUncachedRequestor + val requestor = Vec(n) { new ioUncachedRequestor().flip } } - var req_val = Bool(false) - var req_rdy = io.mem.xact_init.ready + var xi_val = Bool(false) + var xi_rdy = io.mem.xact_init.ready for (i <- 0 until n) { - io.requestor(i).xact_init.ready := req_rdy - req_val = req_val || io.requestor(i).xact_init.valid - req_rdy = req_rdy && !io.requestor(i).xact_init.valid + io.requestor(i).xact_init.ready := xi_rdy + xi_val = xi_val || io.requestor(i).xact_init.valid + xi_rdy = xi_rdy && !io.requestor(i).xact_init.valid } - // if more than one requestor at a time can write back, the data - // arbiter needs to be made stateful: one xact's write data must - // be sent to the memory system contiguously. - var req_data_val = Bool(false) - var req_data_rdy = io.mem.xact_init_data.ready + var xi_bits = Wire() { new TransactionInit } + xi_bits := io.requestor(n-1).xact_init.bits + xi_bits.tile_xact_id := Cat(io.requestor(n-1).xact_init.bits.tile_xact_id, UFix(n-1, log2up(n))) + for (i <- n-2 to 0 by -1) + { + var my_xi_bits = Wire() { new TransactionInit } + my_xi_bits := io.requestor(i).xact_init.bits + my_xi_bits.tile_xact_id := Cat(io.requestor(i).xact_init.bits.tile_xact_id, UFix(i, log2up(n))) + + xi_bits = Mux(io.requestor(i).xact_init.valid, my_xi_bits, xi_bits) + } + + io.mem.xact_init.valid := xi_val + io.mem.xact_init.bits := xi_bits + + var xf_val = Bool(false) + var xf_rdy = io.mem.xact_finish.ready for (i <- 0 until n) { - io.requestor(i).xact_init_data.ready := req_data_rdy - req_data_val = req_data_val || io.requestor(i).xact_init_data.valid - req_data_rdy = req_data_rdy && !io.requestor(i).xact_init_data.valid + io.requestor(i).xact_finish.ready := xf_rdy + xf_val = xf_val || io.requestor(i).xact_finish.valid + xf_rdy = xf_rdy && !io.requestor(i).xact_finish.valid } - var req_bits = Wire() { new TransactionInit } - req_bits := io.requestor(n-1).xact_init.bits - req_bits.tile_xact_id := Cat(io.requestor(n-1).xact_init.bits.tile_xact_id, UFix(n-1, log2up(n))) + var xf_bits = io.requestor(n-1).xact_finish.bits for (i <- n-2 to 0 by -1) - { - var my_req_bits = Wire() { new TransactionInit } - my_req_bits := io.requestor(i).xact_init.bits - my_req_bits.tile_xact_id := Cat(io.requestor(i).xact_init.bits.tile_xact_id, UFix(i, log2up(n))) + xf_bits = Mux(io.requestor(i).xact_finish.valid, io.requestor(i).xact_finish.bits, xf_bits) - req_bits = Mux(io.requestor(i).xact_init.valid, my_req_bits, req_bits) - } - - var req_data_bits = io.requestor(n-1).xact_init_data.bits - for (i <- n-2 to 0 by -1) - req_data_bits = Mux(io.requestor(i).xact_init_data.valid, io.requestor(i).xact_init_data.bits, req_data_bits) - - io.mem.xact_init.valid := req_val - io.mem.xact_init.bits := req_bits - - io.mem.xact_init_data.valid := req_data_val - io.mem.xact_init_data.bits := req_data_bits + io.mem.xact_finish.valid := xf_val + io.mem.xact_finish.bits := xf_bits for (i <- 0 until n) { val tag = io.mem.xact_rep.bits.tile_xact_id io.requestor(i).xact_rep.valid := io.mem.xact_rep.valid && tag(log2up(n)-1,0) === UFix(i) - io.requestor(i).xact_rep.bits.data := io.mem.xact_rep.bits.data - io.requestor(i).xact_rep.bits.t_type := io.mem.xact_rep.bits.t_type + io.requestor(i).xact_rep.bits := io.mem.xact_rep.bits io.requestor(i).xact_rep.bits.tile_xact_id := tag >> UFix(log2up(n)) - io.requestor(i).xact_rep.bits.global_xact_id := io.mem.xact_rep.bits.global_xact_id } + + for (i <- 0 until n) + { + val tag = io.mem.xact_abort.bits.tile_xact_id + io.requestor(i).xact_abort.valid := io.mem.xact_abort.valid && tag(log2up(n)-1,0) === UFix(i) + io.requestor(i).xact_abort.bits := io.mem.xact_abort.bits + io.requestor(i).xact_abort.bits.tile_xact_id := tag >> UFix(log2up(n)) + } + + io.mem.xact_abort.ready := Bool(true) } diff --git a/rocket/src/main/scala/coherence.scala b/rocket/src/main/scala/coherence.scala index fc4f3570..7bcd19c3 100644 --- a/rocket/src/main/scala/coherence.scala +++ b/rocket/src/main/scala/coherence.scala @@ -395,6 +395,8 @@ class CoherenceHubNull extends CoherenceHub { x_rep.bits.global_xact_id := UFix(0) // don't care x_rep.bits.data := io.mem.resp.bits.data x_rep.valid := io.mem.resp.valid || x_init.valid && is_write + + io.tiles(0).xact_abort.valid := Bool(false) } diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 5ba224bf..f7a094fe 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -186,7 +186,7 @@ object Constants val NTILES = 1 val COHERENCE_DATA_BITS = (1 << OFFSET_BITS)*8 val TILE_ID_BITS = 1 - val TILE_XACT_ID_BITS = log2up(NMSHR)+2 + val TILE_XACT_ID_BITS = log2up(NMSHR)+3 val GLOBAL_XACT_ID_BITS = 4 val NGLOBAL_XACTS = 1 << GLOBAL_XACT_ID_BITS diff --git a/rocket/src/main/scala/htif.scala b/rocket/src/main/scala/htif.scala index 6dedbc16..ca847376 100644 --- a/rocket/src/main/scala/htif.scala +++ b/rocket/src/main/scala/htif.scala @@ -78,7 +78,12 @@ class rocketHTIF(w: Int, ncores: Int) extends Component Mux(!nack && cmd === cmd_readcr, UFix(1), UFix(0))) val tx_done = packet_ram_raddr - UFix(1) === tx_size - val state_rx :: state_pcr :: state_mem_req :: state_mem_wdata :: state_mem_rdata :: state_tx :: Nil = Enum(6) { UFix() } + val mem_acked = 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_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 = Reg(resetVal = state_rx) when (state === state_rx && rx_done) { @@ -96,13 +101,35 @@ class rocketHTIF(w: Int, ncores: Int) extends Component when (state === state_mem_req && io.mem.xact_init.ready) { state := Mux(cmd === cmd_writemem, state_mem_wdata, state_mem_rdata) } - when (state === state_mem_wdata && io.mem.xact_init_data.ready || - state === state_mem_rdata && io.mem.xact_rep.valid) { + when (state === state_mem_wdata && io.mem.xact_init_data.ready) { when (mem_cnt.andR) { - state := state_tx + state := state_mem_wresp } mem_cnt := mem_cnt + UFix(1) } + when (state === state_mem_wresp) { + when (mem_nacked) { + state := state_mem_req + mem_nacked := Bool(false) + } + when (mem_acked) { + state := state_tx + mem_acked := Bool(false) + } + } + when (state === state_mem_rdata) { + when (mem_nacked) { + state := state_mem_req + mem_nacked := Bool(false) + } + when (io.mem.xact_rep.valid) { + when (mem_cnt.andR) { + state := state_tx + } + mem_cnt := mem_cnt + UFix(1) + } + mem_acked := Bool(false) + } when (state === state_tx && tx_done) { rx_count := UFix(0) tx_count := UFix(0) diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index 6ca20c3e..b9cf197d 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -20,7 +20,7 @@ class ioImem(view: List[String] = null) extends Bundle (view) class ioRocketICache extends Bundle() { val cpu = new ioImem(); - val mem = new ioTileLink + val mem = new ioUncachedRequestor } // basic direct mapped instruction cache @@ -49,6 +49,7 @@ class rocketICache(sets: Int, assoc: Int) extends Component { val s_reset :: s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(5) { UFix() }; val state = Reg(resetVal = s_reset); + val invalidated = Reg() { Bool() } val r_cpu_req_idx = Reg { Bits() } val r_cpu_req_ppn = Reg { Bits() } @@ -78,13 +79,14 @@ class rocketICache(sets: Int, assoc: Int) extends Component { when (io.mem.xact_rep.valid) { refill_count := refill_count + UFix(1); } + val refill_done = io.mem.xact_rep.valid && refill_count.andR 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 tag_we = (state === s_refill) && refill_done val tag_addr = - Mux((state === s_refill_wait), r_cpu_req_idx(indexmsb,indexlsb), + Mux((state === s_refill), r_cpu_req_idx(indexmsb,indexlsb), io.cpu.req_idx(indexmsb,indexlsb)).toUFix; - val tag_we = (state === s_refill_wait) && io.mem.xact_rep.valid; val data_addr = Mux((state === s_refill_wait) || (state === s_refill), Cat(r_cpu_req_idx(indexmsb,offsetbits), refill_count), io.cpu.req_idx(indexmsb, offsetbits-rf_cnt_bits)).toUFix; @@ -102,10 +104,10 @@ class rocketICache(sets: Int, assoc: Int) extends Component { // valid bit array val vb_array = Reg(resetVal = Bits(0, sets)); when (io.cpu.invalidate) { - vb_array := Bits(0,sets); + vb_array := Bits(0) } .elsewhen (tag_we && repl_me) { - vb_array := vb_array.bitSet(r_cpu_req_idx(indexmsb,indexlsb).toUFix, UFix(1,1)); + vb_array := vb_array.bitSet(r_cpu_req_idx(indexmsb,indexlsb).toUFix, !invalidated) } val valid = vb_array(r_cpu_req_idx(indexmsb,indexlsb)).toBool; @@ -131,20 +133,20 @@ class rocketICache(sets: Int, assoc: Int) extends Component { io.mem.xact_init.valid := (state === s_request) 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_data.valid := Bool(false) // control state machine + when (io.cpu.invalidate) { + invalidated := Bool(true) + } switch (state) { is (s_reset) { state := s_ready; } is (s_ready) { - when (io.cpu.itlb_miss) { - state := s_ready; - } - .elsewhen (r_cpu_req_val && !tag_hit) { + when (r_cpu_req_val && !tag_hit && !io.cpu.itlb_miss) { state := s_request; } + invalidated := Bool(false) } is (s_request) { @@ -153,12 +155,15 @@ class rocketICache(sets: Int, assoc: Int) extends Component { } } is (s_refill_wait) { + when (io.mem.xact_abort.valid) { + state := s_request + } when (io.mem.xact_rep.valid) { state := s_refill; } } is (s_refill) { - when (io.mem.xact_rep.valid && refill_count.andR) { + when (refill_done) { state := s_ready; } } diff --git a/rocket/src/main/scala/icache_prefetch.scala b/rocket/src/main/scala/icache_prefetch.scala index 9ad85d82..b9d96a81 100644 --- a/rocket/src/main/scala/icache_prefetch.scala +++ b/rocket/src/main/scala/icache_prefetch.scala @@ -18,22 +18,23 @@ class rocketIPrefetcher extends Component() { val s_invalid :: s_valid :: s_refilling :: s_req_wait :: s_resp_wait :: s_bad_resp_wait :: Nil = Enum(6) { UFix() }; val state = Reg(resetVal = s_invalid); + val ip_mem_resp_abort = io.mem.xact_abort.valid && io.mem.xact_abort.bits.tile_xact_id(0) val demand_miss = io.icache.xact_init.valid && io.icache.xact_init.ready val prefetch_addr = Reg() { UFix(width = io.icache.xact_init.bits.address.width) }; val addr_match = (prefetch_addr === io.icache.xact_init.bits.address); - val hit = (state != s_invalid) & (state != s_req_wait) & addr_match; + val hit = (state != s_invalid) && (state != s_req_wait) && addr_match && !ip_mem_resp_abort val prefetch_miss = io.icache.xact_init.valid && !hit when (demand_miss) { prefetch_addr := io.icache.xact_init.bits.address + UFix(1); } - + io.icache.xact_init.ready := io.mem.xact_init.ready - val ip_mem_req_rdy = io.mem.xact_init.ready && !prefetch_miss 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 + + io.mem.xact_abort.ready := Bool(true) io.mem.xact_init.valid := prefetch_miss || (state === s_req_wait) 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.address := Mux(prefetch_miss, io.icache.xact_init.bits.address, prefetch_addr); - io.mem.xact_init_data.valid := Bool(false) val fill_cnt = Reg(resetVal = UFix(0, ceil(log(REFILL_CYCLES)/log(2)).toInt)); when (ip_mem_resp_val.toBool) { fill_cnt := fill_cnt + UFix(1); } @@ -43,8 +44,10 @@ class rocketIPrefetcher extends Component() { val forward_cnt = Reg(resetVal = UFix(0, ceil(log(REFILL_CYCLES)/log(2)).toInt)); when (forward & pdq.io.deq.valid) { forward_cnt := forward_cnt + UFix(1); } val forward_done = (~forward_cnt === UFix(0)) & 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) || + forward && ip_mem_resp_abort io.icache.xact_rep.valid := io.mem.xact_rep.valid && !io.mem.xact_rep.bits.tile_xact_id(0) || (forward && pdq.io.deq.valid) io.icache.xact_rep.bits.data := Mux(forward, pdq.io.deq.bits, io.mem.xact_rep.bits.data) @@ -69,11 +72,14 @@ class rocketIPrefetcher extends Component() { when (ip_mem_req_rdy) { state := s_resp_wait; } } is (s_resp_wait) { - when (demand_miss & ~addr_match) { state := s_bad_resp_wait; } - .elsewhen (ip_mem_resp_val.toBool) { state := s_refilling; } + when (ip_mem_resp_abort) { + state := s_invalid + } + .elsewhen (demand_miss && !addr_match) { state := s_bad_resp_wait } + .elsewhen (ip_mem_resp_val) { state := s_refilling } } is (s_bad_resp_wait) { - when (fill_done.toBool & ip_mem_resp_val.toBool) { state := s_req_wait; } + when (fill_done || ip_mem_resp_abort) { state := s_req_wait } } } diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index a5dc640b..ef2e7a08 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -178,6 +178,7 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence { 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 meta_req = (new ioDecoupled) { new MetaArrayArrayReq() } val replay = (new ioDecoupled) { new Replay() } @@ -216,6 +217,9 @@ class MSHR(id: Int) extends Component with ThreeStateIncoherence { when (io.mem_req.valid && io.mem_req.ready) { requested := Bool(true) } + when (io.mem_abort_val) { + requested := Bool(false) + } when (io.mem_resp_val) { refilled := Bool(true) } @@ -264,6 +268,7 @@ class MSHRFile extends Component { val mem_req = (new ioDecoupled) { new TransactionInit } val meta_req = (new ioDecoupled) { new MetaArrayArrayReq() } val data_req = (new ioDecoupled) { new DataReq() } + val mem_abort = (new ioPipe) { new TransactionAbort }.flip val cpu_resp_val = Bool(OUTPUT) val cpu_resp_tag = Bits(DCACHE_TAG_BITS, OUTPUT) @@ -310,8 +315,8 @@ class MSHRFile extends Component { mshr.io.mem_req <> mem_req_arb.io.in(i) mshr.io.replay <> replay_arb.io.in(i) - val mem_resp_val = io.mem_resp_val && (UFix(i) === io.mem_resp_tag) - mshr.io.mem_resp_val := mem_resp_val + mshr.io.mem_resp_val := io.mem_resp_val && (UFix(i) === io.mem_resp_tag) + mshr.io.mem_abort_val := io.mem_abort.valid && (UFix(i) === io.mem_abort.bits.tile_xact_id) mem_resp_idx_mux.io.sel(i) := (UFix(i) === io.mem_resp_tag) mem_resp_idx_mux.io.in(i) := mshr.io.idx mem_resp_way_oh_mux.io.sel(i) := (UFix(i) === io.mem_resp_tag) @@ -352,22 +357,55 @@ class WritebackUnit extends Component { val data_req = (new ioDecoupled) { new DataArrayArrayReq() } val data_resp = Bits(MEM_DATA_BITS, INPUT) val refill_req = (new ioDecoupled) { new TransactionInit }.flip - val mem_req = (new ioDecoupled) { new TransactionInit } + val mem_req = (new ioDecoupled) { new TransactionInit } val mem_req_data = (new ioDecoupled) { new TransactionInitData } + val mem_abort = (new ioPipe) { new TransactionAbort }.flip + val mem_rep = (new ioPipe) { new TransactionReply }.flip } val valid = Reg(resetVal = Bool(false)) val data_req_fired = Reg(resetVal = Bool(false)) + val cmd_sent = Reg() { Bool() } val cnt = Reg() { UFix(width = log2up(REFILL_CYCLES+1)) } val addr = Reg() { new WritebackReq() } - data_req_fired := Bool(false) - when (io.data_req.valid && io.data_req.ready) { data_req_fired := Bool(true); cnt := cnt + UFix(1) } - when (data_req_fired && !io.mem_req_data.ready) { data_req_fired := Bool(false); cnt := cnt - UFix(1) } - when ((cnt === UFix(REFILL_CYCLES)) && io.mem_req_data.ready) { valid := Bool(false) } - when (io.req.valid && io.req.ready) { valid := Bool(true); cnt := UFix(0); addr := io.req.bits } + val acked = Reg() { Bool() } + val nacked = Reg() { Bool() } + 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) } - io.req.ready := !valid && io.mem_req.ready + data_req_fired := Bool(false) + when (valid && io.mem_req.ready) { + cmd_sent := Bool(true) + } + when (io.data_req.valid && io.data_req.ready) { + data_req_fired := Bool(true) + cnt := cnt + UFix(1) + } + when (data_req_fired && !io.mem_req_data.ready) { + data_req_fired := Bool(false) + cnt := cnt - UFix(1) + } + when ((cnt === UFix(REFILL_CYCLES)) && (!data_req_fired || io.mem_req_data.ready)) { + when (acked) { + valid := Bool(false) + } + when (nacked) { + cmd_sent := Bool(false) + nacked := Bool(false) + cnt := UFix(0) + } + } + when (io.req.valid && io.req.ready) { + valid := Bool(true) + acked := Bool(false) + nacked := Bool(false) + cmd_sent := Bool(false) + cnt := UFix(0) + addr := io.req.bits + } + + io.req.ready := !valid io.data_req.valid := valid && (cnt < UFix(REFILL_CYCLES)) io.data_req.bits.way_en := addr.way_oh io.data_req.bits.inner_req.idx := addr.idx @@ -376,11 +414,12 @@ class WritebackUnit extends Component { io.data_req.bits.inner_req.wmask := Bits(0) io.data_req.bits.inner_req.data := Bits(0) - val wb_req_val = io.req.valid && !valid - io.refill_req.ready := io.mem_req.ready && !wb_req_val - io.mem_req.valid := io.refill_req.valid || wb_req_val + val wb_req_val = valid && !cmd_sent + io.refill_req.ready := io.mem_req.ready && !(valid && !acked) + io.mem_req.valid := io.refill_req.valid && !(valid && !acked) || wb_req_val 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(io.req.bits.ppn, io.req.bits.idx).toUFix, io.refill_req.bits.address) + io.mem_req.bits.has_data := wb_req_val + 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_data.valid := data_req_fired @@ -676,8 +715,12 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence { val cpu_req_data = Mux(r_replay_amo, r_amo_replay_data, io.cpu.req_data) // refill counter +<<<<<<< HEAD val mem_resp_type = io.mem.xact_rep.bits.t_type val refill_val = io.mem.xact_rep.valid && (mem_resp_type === X_REP_READ_SHARED || mem_resp_type === X_REP_READ_EXCLUSIVE) +======= + val refill_val = io.mem.xact_rep.valid && io.mem.xact_rep.bits.tile_xact_id < UFix(NMSHR) +>>>>>>> support memory transaction aborts 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 } @@ -725,6 +768,9 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence { wb_arb.io.out <> wb.io.req wb.io.data_req <> data_arb.io.in(3) wb.io.data_resp <> data_resp_mux + wb.io.mem_rep <> io.mem.xact_rep + wb.io.mem_abort.valid := io.mem.xact_abort.valid + wb.io.mem_abort.bits := io.mem.xact_abort.bits // replacement policy val replacer = new RandomReplacementWayGen() @@ -737,9 +783,11 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence { // refill response val block_during_refill = !refill_val && (rr_count != UFix(0)) 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.rw := !block_during_refill 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.way_en := mshr.io.mem_resp_way_oh data_arb.io.in(0).valid := refill_val || block_during_refill // load hits @@ -815,10 +863,10 @@ class HellaCacheUniproc extends HellaCache with ThreeStateIncoherence { mshr.io.mem_resp_val := refill_val && (~rr_count === UFix(0)) mshr.io.mem_resp_tag := io.mem.xact_rep.bits.tile_xact_id + mshr.io.mem_abort.valid := io.mem.xact_abort.valid + mshr.io.mem_abort.bits := io.mem.xact_abort.bits mshr.io.mem_req <> wb.io.refill_req mshr.io.meta_req <> meta_arb.io.in(1) - data_arb.io.in(0).bits.inner_req.idx := mshr.io.mem_resp_idx - data_arb.io.in(0).bits.way_en := mshr.io.mem_resp_way_oh replacer.io.pick_new_way := mshr.io.req.valid && mshr.io.req.ready // replays diff --git a/rocket/src/main/scala/top.scala b/rocket/src/main/scala/top.scala index 526dc4e8..87cd901c 100644 --- a/rocket/src/main/scala/top.scala +++ b/rocket/src/main/scala/top.scala @@ -29,13 +29,18 @@ class Top() extends Component { val hub = new CoherenceHubNull // connect tile to hub hub.io.tiles(0).xact_init <> Queue(arbiter.io.mem.xact_init) - hub.io.tiles(0).xact_init_data <> Queue(arbiter.io.mem.xact_init_data) + arbiter.io.mem.xact_abort <> Queue(hub.io.tiles(0).xact_abort) arbiter.io.mem.xact_rep <> Pipe(hub.io.tiles(0).xact_rep) // connect hub to memory io.mem.req_cmd <> Queue(hub.io.mem.req_cmd) io.mem.req_data <> Queue(hub.io.mem.req_data) hub.io.mem.resp <> Pipe(io.mem.resp) + // temporary HTIF data connection + val data_arb = (new Arbiter(2)) { new TransactionInitData } + data_arb.io.in(0) <> Queue(dcache.io.mem.xact_init_data) + data_arb.io.in(1) <> Queue(htif.io.mem.xact_init_data) + hub.io.tiles(0).xact_init_data <> data_arb.io.out if (HAVE_VEC) {