From 40498de38d519ab1ec7257fc2003a35a8e2071ce Mon Sep 17 00:00:00 2001 From: Richard Yan Date: Sun, 10 Nov 2024 00:23:34 -0800 Subject: [PATCH] dma no longer forces spad write --- .../scala/gemmini/ExecuteController.scala | 4 +-- src/main/scala/gemmini/Scratchpad.scala | 32 +++++++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/main/scala/gemmini/ExecuteController.scala b/src/main/scala/gemmini/ExecuteController.scala index 6c01422d..90b8a283 100644 --- a/src/main/scala/gemmini/ExecuteController.scala +++ b/src/main/scala/gemmini/ExecuteController.scala @@ -934,12 +934,12 @@ class ExecuteController[T <: Data, U <: Data, V <: Data](xLen: Int, tagWidth: In }))) if (ex_write_to_spad) { - io.srams.write(i).en := start_array_outputting && w_bank === i.U && !write_to_acc && !is_garbage_addr && write_this_row + io.srams.write(i).valid := start_array_outputting && w_bank === i.U && !write_to_acc && !is_garbage_addr && write_this_row io.srams.write(i).addr := w_row io.srams.write(i).data := activated_wdata.asUInt io.srams.write(i).mask := w_mask.flatMap(b => Seq.fill(inputType.getWidth / (aligned_to * 8))(b)) } else { - io.srams.write(i).en := false.B + io.srams.write(i).valid := false.B io.srams.write(i).addr := DontCare io.srams.write(i).data := DontCare io.srams.write(i).mask := DontCare diff --git a/src/main/scala/gemmini/Scratchpad.scala b/src/main/scala/gemmini/Scratchpad.scala index d00dec08..b6b22ea7 100644 --- a/src/main/scala/gemmini/Scratchpad.scala +++ b/src/main/scala/gemmini/Scratchpad.scala @@ -89,10 +89,12 @@ class ScratchpadReadIO(val n: Int, val w: Int) extends Bundle { } class ScratchpadWriteIO(val n: Int, val w: Int, val mask_len: Int) extends Bundle { - val en = Output(Bool()) + val valid = Output(Bool()) + val ready = Input(Bool()) val addr = Output(UInt(log2Ceil(n).W)) val mask = Output(Vec(mask_len, Bool())) val data = Output(UInt(w.W)) + def fire = valid && ready } class ScratchpadBank(n: Int, w: Int, aligned_to: Int, single_ported: Boolean, use_shared_ext_mem: Boolean, is_dummy: Boolean) extends Module { @@ -115,7 +117,7 @@ class ScratchpadBank(n: Int, w: Int, aligned_to: Int, single_ported: Boolean, us val q = Module(new Queue(new ScratchpadReadResp(w), 1, true, true)) val q_will_be_empty = (q.io.count +& q.io.enq.fire) - q.io.deq.fire === 0.U // When the scratchpad is single-ported, the writes take precedence - val singleport_busy_with_write = single_ported.B && io.write.en + val singleport_busy_with_write = single_ported.B && io.write.fire if (is_dummy) { q.io.enq.valid := RegNext(ren) @@ -144,10 +146,11 @@ class ScratchpadBank(n: Int, w: Int, aligned_to: Int, single_ported: Boolean, us ext_mem.read_resp.ready := q.io.enq.ready /* WRITE */ - val wq = Module(new Queue(ext_mem.write_req.bits.cloneType, 32, pipe=true, flow=true)) + val wq = Module(new Queue(ext_mem.write_req.bits.cloneType, 4, pipe=true, flow=true)) ext_mem.write_req <> wq.io.deq - wq.io.enq.valid := io.write.en + wq.io.enq.valid := io.write.valid + io.write.ready := wq.io.enq.ready wq.io.enq.bits.addr := io.write.addr wq.io.enq.bits.data := io.write.data if (aligned_to >= w) { @@ -155,14 +158,14 @@ class ScratchpadBank(n: Int, w: Int, aligned_to: Int, single_ported: Boolean, us } else { wq.io.enq.bits.mask := io.write.mask.asUInt } - assert(wq.io.enq.ready || (!io.write.en), "TODO (richard): fix this if triggered") + // assert(wq.io.enq.ready || (!io.write.en), "TODO (richard): fix this if triggered") } else { // use valid only interface val mem = SyncReadMem(n, Vec(mask_len, mask_elem)) val raddr = io.read.req.bits.addr val rdata = if (single_ported) { - assert(!(ren && io.write.en)) - mem.read(raddr, ren && !io.write.en).asUInt + assert(!(ren && io.write.fire)) + mem.read(raddr, ren && !io.write.fire).asUInt } else { mem.read(raddr, ren).asUInt } @@ -172,7 +175,8 @@ class ScratchpadBank(n: Int, w: Int, aligned_to: Int, single_ported: Boolean, us io.read.req.ready := q_will_be_empty && !singleport_busy_with_write - when(io.write.en) { + io.write.ready := true.B + when(io.write.fire) { if (aligned_to >= w) mem.write(io.write.addr, io.write.data.asTypeOf(Vec(mask_len, mask_elem)), VecInit((~(0.U(mask_len.W))).asBools)) else @@ -502,7 +506,7 @@ class Scratchpad[T <: Data, U <: Data, V <: Data](config: GemminiArrayConfig[T, // TODO we tie the write dispatch queue's, and write issue queue's, ready and valid signals together here val dmawrite = write_dispatch_q.valid && write_norm_q.io.enq.ready && !write_dispatch_q.bits.laddr.is_garbage() && - !(bio.write.en && config.sp_singleported.B) && + !(bio.write.fire && config.sp_singleported.B) && !write_dispatch_q.bits.laddr.is_acc_addr && write_dispatch_q.bits.laddr.sp_bank() === i.U bio.read.req.valid := exread || dmawrite @@ -554,14 +558,15 @@ class Scratchpad[T <: Data, U <: Data, V <: Data](config: GemminiArrayConfig[T, // Writing to the SRAM banks bank_ios.zipWithIndex.foreach { case (bio, i) => - val exwrite = io.srams.write(i).en + val exwrite = io.srams.write(i).valid + io.srams.write(i).ready := bio.write.ready // val laddr = mvin_scale_out.bits.tag.addr.asTypeOf(local_addr_t) + mvin_scale_out.bits.row val laddr = mvin_scale_pixel_repeater.io.resp.bits.laddr // val dmaread = mvin_scale_out.valid && !mvin_scale_out.bits.tag.is_acc && val dmaread = mvin_scale_pixel_repeater.io.resp.valid && !mvin_scale_pixel_repeater.io.resp.bits.tag.is_acc && - laddr.sp_bank() === i.U + (laddr.sp_bank() === i.U) && bio.write.ready // We need to make sure that we don't try to return a dma read resp from both zero_writer and either mvin_scale // or mvin_acc_scale at the same time. The scalers always get priority in those cases @@ -570,9 +575,10 @@ class Scratchpad[T <: Data, U <: Data, V <: Data](config: GemminiArrayConfig[T, val zerowrite = zero_writer_pixel_repeater.io.resp.valid && !zero_writer_pixel_repeater.io.resp.bits.laddr.is_acc_addr && zero_writer_pixel_repeater.io.resp.bits.laddr.sp_bank() === i.U && // !((mvin_scale_out.valid && mvin_scale_out.bits.last) || (mvin_scale_acc_out.valid && mvin_scale_acc_out.bits.last)) - !((mvin_scale_pixel_repeater.io.resp.valid && mvin_scale_pixel_repeater.io.resp.bits.last) || (mvin_scale_acc_out.valid && mvin_scale_acc_out.bits.last)) + !((mvin_scale_pixel_repeater.io.resp.valid && mvin_scale_pixel_repeater.io.resp.bits.last) || (mvin_scale_acc_out.valid && mvin_scale_acc_out.bits.last)) && + bio.write.ready - bio.write.en := exwrite || dmaread || zerowrite + bio.write.valid := exwrite || dmaread || zerowrite when (exwrite) { bio.write.addr := io.srams.write(i).addr