From 8913ae5da09990a707b3d37c3deaeec741dd2336 Mon Sep 17 00:00:00 2001 From: Liphen Date: Sun, 12 Nov 2023 15:50:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E8=AE=BE=E8=AE=A1=EF=BC=8C=E5=8E=BB=E9=99=A4?= =?UTF-8?q?cache=E3=80=81tlb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chisel/difftest | 2 +- chisel/playground/resources/top_axi_wrapper.v | 98 ++++ chisel/playground/src/Core.scala | 35 +- chisel/playground/src/cache/DCache.scala | 434 +----------------- chisel/playground/src/cache/ICache.scala | 272 ++--------- chisel/playground/src/ctrl/Ctrl.scala | 2 - chisel/playground/src/defines/Bundles.scala | 196 ++++---- chisel/playground/src/defines/Const.scala | 38 +- chisel/playground/src/mmu/TlbL1D.scala | 70 --- chisel/playground/src/mmu/TlbL1I.scala | 59 --- chisel/playground/src/mmu/TlbL2.scala | 69 --- .../src/pipeline/decoder/DecoderUnit.scala | 12 +- .../src/pipeline/decoder/Issue.scala | 3 - .../pipeline/fetch/BranchPredictorUnit.scala | 8 +- .../src/pipeline/fetch/FetchUnit.scala | 2 +- .../src/pipeline/fetch/InstFifo.scala | 69 +-- .../src/pipeline/fetch/PreDecoder.scala | 94 ---- .../src/pipeline/memory/MemoryUnit.scala | 23 +- 18 files changed, 277 insertions(+), 1209 deletions(-) create mode 100644 chisel/playground/resources/top_axi_wrapper.v delete mode 100644 chisel/playground/src/mmu/TlbL1D.scala delete mode 100644 chisel/playground/src/mmu/TlbL1I.scala delete mode 100644 chisel/playground/src/mmu/TlbL2.scala delete mode 100644 chisel/playground/src/pipeline/fetch/PreDecoder.scala diff --git a/chisel/difftest b/chisel/difftest index f41fe98..1f6c6a6 160000 --- a/chisel/difftest +++ b/chisel/difftest @@ -1 +1 @@ -Subproject commit f41fe9897f5b0ed213e270ffdd2f8b179ef37a29 +Subproject commit 1f6c6a632c18a0fd1daf6b1c09a8fa56717b7679 diff --git a/chisel/playground/resources/top_axi_wrapper.v b/chisel/playground/resources/top_axi_wrapper.v new file mode 100644 index 0000000..0228122 --- /dev/null +++ b/chisel/playground/resources/top_axi_wrapper.v @@ -0,0 +1,98 @@ +module top_axi_wrapper( + input clock, + input reset, + // Interrupts + input MEI, // to PLIC + input MSI, // to CLINT + input MTI, // to CLINT + // aw + output [3:0]MAXI_awid, + output[31:0]MAXI_awaddr, + output [7:0]MAXI_awlen, + output [2:0]MAXI_awsize, + output [1:0]MAXI_awburst, + output MAXI_awvalid, + input MAXI_awready, + // w + output[63:0]MAXI_wdata, + output [7:0]MAXI_wstrb, + output MAXI_wlast, + output MAXI_wvalid, + input MAXI_wready, + // b + input [3:0]MAXI_bid, + input [1:0]MAXI_bresp, + input MAXI_bvalid, + output MAXI_bready, + // ar + output [3:0]MAXI_arid, + output[31:0]MAXI_araddr, + output [7:0]MAXI_arlen, + output [2:0]MAXI_arsize, + output [1:0]MAXI_arburst, + output MAXI_arvalid, + input MAXI_arready, + // r + input [3:0]MAXI_rid, + input [63:0]MAXI_rdata, + input [1:0]MAXI_rresp, + input MAXI_rlast, + input MAXI_rvalid, + output MAXI_rready, + // debug + output debug_commit, + output[63:0]debug_pc, + output[4:0] debug_reg_num, + output[63:0]debug_wdata +); + + +RiscVTop core( + .aclk (clock), + .aresetn (~reset), + // Interrupts + .MEI (MEI), // to PLIC + .MSI (MSI), // to CLINT + .MTI (MTI), // to CLINT + // aw + .awid (MAXI_awid), + .awaddr (MAXI_awaddr), + .awlen (MAXI_awlen), + .awsize (MAXI_awsize), + .awburst (MAXI_awburst), + .awvalid (MAXI_awvalid), + .awready (MAXI_awready), + // w + .wdata (MAXI_wdata), + .wstrb (MAXI_wstrb), + .wlast (MAXI_wlast), + .wvalid (MAXI_wvalid), + .wready (MAXI_wready), + // b + .bid (MAXI_bid), + .bresp (MAXI_bresp), + .bvalid (MAXI_bvalid), + .bready (MAXI_bready), + // ar + .arid (MAXI_arid), + .araddr (MAXI_araddr), + .arlen (MAXI_arlen), + .arsize (MAXI_arsize), + .arburst (MAXI_arburst), + .arvalid (MAXI_arvalid), + .arready (MAXI_arready), + // r + .rid (MAXI_rid), + .rdata (MAXI_rdata), + .rresp (MAXI_rresp), + .rlast (MAXI_rlast), + .rvalid (MAXI_rvalid), + .rready (MAXI_rready), + // debug + .debug_commit (debug_commit), + .debug_pc (debug_pc), + .debug_reg_num (debug_reg_num), + .debug_wdata (debug_wdata) +); + +endmodule diff --git a/chisel/playground/src/Core.scala b/chisel/playground/src/Core.scala index e667c3b..686efb3 100644 --- a/chisel/playground/src/Core.scala +++ b/chisel/playground/src/Core.scala @@ -38,22 +38,6 @@ class Core(implicit val config: CpuConfig) extends Module { val memoryUnit = Module(new MemoryUnit()).io val writeBackStage = Module(new WriteBackStage()).io val writeBackUnit = Module(new WriteBackUnit()).io - val tlbL1I = Module(new TlbL1I()).io - val tlbL1D = Module(new TlbL1D()).io - - tlbL1I.addr := fetchUnit.iCache.pc - tlbL1I.fence := executeUnit.executeStage.inst0.inst_info.tlbfence - tlbL1I.cpu_stall := !ctrl.fetchUnit.allow_to_go - tlbL1I.icache_stall := io.inst.icache_stall - tlbL1I.cache <> io.inst.tlb - - tlbL1D.addr := memoryUnit.dataMemory.out.addr - tlbL1D.fence := memoryUnit.memoryStage.inst0.inst_info.tlbfence - tlbL1D.cpu_stall := !ctrl.memoryUnit.allow_to_go - tlbL1D.dcache_stall := io.data.dcache_stall - tlbL1D.mem_write := memoryUnit.dataMemory.out.wen.orR - tlbL1D.mem_en := memoryUnit.dataMemory.out.en - tlbL1D.cache <> io.data.tlb ctrl.instFifo.has2insts := !(instFifo.empty || instFifo.almost_empty) ctrl.decoderUnit <> decoderUnit.ctrl @@ -92,16 +76,8 @@ class Core(implicit val config: CpuConfig) extends Module { decoderUnit.bpu.branch_target := bpu.decoder.branch_target instFifo.do_flush := ctrl.decoderUnit.do_flush - instFifo.flush_delay_slot := ctrl.instFifo.delay_slot_do_flush instFifo.icache_stall := io.inst.icache_stall instFifo.jump_branch_inst := decoderUnit.instFifo.jump_branch_inst - instFifo.delay_sel_flush := Mux( - ctrl.executeUnit.branch, - !(executeUnit.memoryStage.inst1.ex.bd || decoderUnit.executeStage.inst0.ex.bd), - Mux(ctrl.decoderUnit.branch, !decoderUnit.instFifo.allow_to_go(1), false.B), - ) - instFifo.decoder_delay_flush := ctrl.decoderUnit.branch - instFifo.execute_delay_flush := ctrl.executeUnit.branch instFifo.ren <> decoderUnit.instFifo.allow_to_go decoderUnit.instFifo.inst <> instFifo.read @@ -109,15 +85,12 @@ class Core(implicit val config: CpuConfig) extends Module { instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i) bpu.instBuffer.pc(i) := instFifo.write(i).pc instFifo.wen(i) := io.inst.inst_valid(i) - instFifo.write(i).tlb.refill := tlbL1I.tlb1.refill - instFifo.write(i).tlb.invalid := tlbL1I.tlb1.invalid instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U instFifo.write(i).inst := io.inst.inst(i) } decoderUnit.instFifo.info.empty := instFifo.empty decoderUnit.instFifo.info.almost_empty := instFifo.almost_empty - decoderUnit.instFifo.info.inst0_is_in_delayslot := instFifo.inst0_is_in_delayslot decoderUnit.regfile <> regfile.read for (i <- 0 until (config.fuNum)) { decoderUnit.forward(i).exe := executeUnit.decoderUnit.forward(i).exe @@ -142,13 +115,8 @@ class Core(implicit val config: CpuConfig) extends Module { cp0.ctrl.exe_stall := !ctrl.executeUnit.allow_to_go cp0.ctrl.mem_stall := !ctrl.memoryUnit.allow_to_go - cp0.tlb(0).vpn2 := tlbL1I.tlb2.vpn2 - cp0.tlb(1).vpn2 := tlbL1D.tlb2.vpn2 cp0.ext_int := io.ext_int - tlbL1I.tlb2.found := cp0.tlb(0).found - tlbL1D.tlb2.found := cp0.tlb(1).found - tlbL1I.tlb2.entry := cp0.tlb(0).info - tlbL1D.tlb2.entry := cp0.tlb(1).info + memoryStage.ctrl.allow_to_go := ctrl.memoryUnit.allow_to_go memoryStage.ctrl.clear := ctrl.memoryUnit.do_flush @@ -157,7 +125,6 @@ class Core(implicit val config: CpuConfig) extends Module { memoryUnit.cp0 <> cp0.memoryUnit memoryUnit.writeBackStage <> writeBackStage.memoryUnit - memoryUnit.dataMemory.in.tlb <> tlbL1D.tlb1 memoryUnit.dataMemory.in.rdata := io.data.rdata io.data.en := memoryUnit.dataMemory.out.en io.data.rlen := memoryUnit.dataMemory.out.rlen diff --git a/chisel/playground/src/cache/DCache.scala b/chisel/playground/src/cache/DCache.scala index 0c27d4a..4826975 100644 --- a/chisel/playground/src/cache/DCache.scala +++ b/chisel/playground/src/cache/DCache.scala @@ -17,442 +17,12 @@ class WriteBufferUnit extends Bundle { } class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Module { - val nway: Int = cacheConfig.nway - val nset: Int = cacheConfig.nset - val nbank: Int = cacheConfig.nbank - val bankWidthBits: Int = cacheConfig.bankWidthBits - val tagWidth: Int = cacheConfig.tagWidth - val burstSize: Int = cacheConfig.burstSize - val io = IO(new Bundle { val cpu = Flipped(new Cache_DCache()) val axi = new DCache_AXIInterface() - val statistic = if (!config.build) Some(new DCacheStatistic()) else None }) - val tlb_fill = RegInit(false.B) // * fsm * // - val s_idle :: s_uncached :: s_writeback :: s_replace :: s_save :: Nil = Enum(5) - val state = RegInit(s_idle) - - io.cpu.tlb.fill := tlb_fill - io.cpu.tlb.dcache_is_idle := state === s_idle - io.cpu.tlb.dcache_is_save := state === s_save - - // * valid dirty * // - val valid = RegInit(VecInit(Seq.fill(nset)(VecInit(Seq.fill(nway)(false.B))))) - val dirty = RegInit(VecInit(Seq.fill(nset)(VecInit(Seq.fill(nway)(false.B))))) - val lru = RegInit(VecInit(Seq.fill(nset)(0.U(1.W)))) - - val should_next_addr = (state === s_idle && !tlb_fill) || (state === s_save) - - val write_fifo = Module(new Queue(new WriteBufferUnit(), 4)) - - write_fifo.io.enq.valid := false.B - write_fifo.io.enq.bits := 0.U.asTypeOf(new WriteBufferUnit()) - write_fifo.io.deq.ready := false.B - - val axi_cnt = Counter(burstSize) - val read_ready_cnt = RegInit(0.U(4.W)) - val read_ready_set = RegInit(0.U(6.W)) - - // * victim cache * // - val victim = RegInit(0.U.asTypeOf(new Bundle { - val valid = Bool() - val set = UInt(6.W) - val waddr = UInt(10.W) - val wstrb = Vec(nway, UInt(4.W)) - val working = Bool() - val writeback = Bool() - })) - val victim_cnt = Counter(burstSize) - val victim_addr = Cat(victim.set, victim_cnt.value) - - val fset = io.cpu.fence_addr(11, 6) - val fence = RegInit(0.U.asTypeOf(new Bundle { - val working = Bool() - })) - - val read_buffer = RegInit(VecInit(Seq.fill(16)(0.U(DATA_WID.W)))) - val ar_handshake = RegInit(false.B) - val aw_handshake = RegInit(false.B) - - val data_raddr = Mux(victim.valid, victim_addr, Mux(should_next_addr, io.cpu.execute_addr(11, 2), io.cpu.addr(11, 2))) - val data_wstrb = Wire(Vec(nway, UInt(4.W))) - val data_waddr = Mux(victim.valid, victim.waddr, io.cpu.addr(11, 2)) - val data_wdata = Mux(state === s_replace, io.axi.r.bits.data, io.cpu.wdata) - - val tag_raddr = Mux(victim.valid, victim.set, Mux(should_next_addr, io.cpu.execute_addr(11, 6), io.cpu.addr(11, 6))) - val tag_wstrb = RegInit(VecInit(Seq.fill(nway)(false.B))) - val tag_wdata = RegInit(0.U(tagWidth.W)) - - val data = Wire(Vec(nway, UInt(DATA_WID.W))) - val tag = RegInit(VecInit(Seq.fill(nway)(0.U(tagWidth.W)))) - - val tag_compare_valid = Wire(Vec(nway, Bool())) - val cache_hit = tag_compare_valid.contains(true.B) - - val mmio_read_stall = io.cpu.tlb.uncached && !io.cpu.wen.orR - val mmio_write_stall = io.cpu.tlb.uncached && io.cpu.wen.orR && !write_fifo.io.enq.ready - val cached_stall = !io.cpu.tlb.uncached && !cache_hit - - val sel = tag_compare_valid(1) - - // * physical set * // - val pset = io.cpu.addr(11, 6) - - io.cpu.dcache_stall := Mux( - state === s_idle && !tlb_fill, - Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.translation_ok), io.cpu.fence), - state =/= s_save, - ) - - val saved_rdata = RegInit(0.U(DATA_WID.W)) - - // forward last stored data in data bram - val last_waddr = RegNext(data_waddr) - val last_wstrb = RegInit(VecInit(Seq.fill(nway)(0.U(DATA_WID.W)))) - val last_wdata = RegNext(data_wdata) - val cache_data_forward = Wire(Vec(nway, UInt(DATA_WID.W))) - - io.cpu.rdata := Mux(state === s_save, saved_rdata, cache_data_forward(sel)) - - // bank tagv ram - for { i <- 0 until nway } { - val bank_ram = Module(new SimpleDualPortRam(nset * nbank, bankWidthBits, byteAddressable = true)) - bank_ram.io.ren := true.B - bank_ram.io.raddr := data_raddr - data(i) := bank_ram.io.rdata - - bank_ram.io.wen := data_wstrb(i).orR - bank_ram.io.waddr := data_waddr - bank_ram.io.wdata := data_wdata - bank_ram.io.wstrb := data_wstrb(i) - - val tag_ram = Module(new LUTRam(nset, tagWidth)) - tag_ram.io.raddr := tag_raddr - tag(i) := tag_ram.io.rdata - - tag_ram.io.wen := tag_wstrb(i) - tag_ram.io.waddr := victim.set - tag_ram.io.wdata := tag_wdata - - tag_compare_valid(i) := tag(i) === io.cpu.tlb.tag && valid(pset)(i) && io.cpu.tlb.translation_ok - cache_data_forward(i) := Mux( - last_waddr === io.cpu.addr(11, 2), - ((last_wstrb(i) & last_wdata) | (data(i) & (~last_wstrb(i)))), - data(i), - ) - - data_wstrb(i) := Mux( - tag_compare_valid(i) && io.cpu.en && io.cpu.wen.orR && !io.cpu.tlb.uncached && state === s_idle && !tlb_fill, - io.cpu.wen, - victim.wstrb(i), - ) - - last_wstrb(i) := Cat( - Fill(8, data_wstrb(i)(3)), - Fill(8, data_wstrb(i)(2)), - Fill(8, data_wstrb(i)(1)), - Fill(8, data_wstrb(i)(0)), - ) - } - val write_buffer_axi_busy = RegInit(false.B) - - val ar = RegInit(0.U.asTypeOf(new AR())) - val arvalid = RegInit(false.B) - io.axi.ar.bits <> ar - io.axi.ar.valid := arvalid - val rready = RegInit(false.B) - io.axi.r.ready := rready - val aw = RegInit(0.U.asTypeOf(new AW())) - val awvalid = RegInit(false.B) - io.axi.aw.bits <> aw - io.axi.aw.valid := awvalid - val w = RegInit(0.U.asTypeOf(new W())) - val wvalid = RegInit(false.B) - io.axi.w.bits <> w - io.axi.w.valid := wvalid - - io.axi.b.ready := true.B - - val current_mmio_write_saved = RegInit(false.B) - - // write buffer - when(write_buffer_axi_busy) { // To implement SC memory ordering, when store buffer busy, axi is unseable. - when(io.axi.aw.fire) { - awvalid := false.B - } - when(io.axi.w.fire) { - wvalid := false.B - w.last := false.B - } - when(io.axi.b.fire) { - write_buffer_axi_busy := false.B - } - }.elsewhen(write_fifo.io.deq.valid) { - write_fifo.io.deq.ready := write_fifo.io.deq.valid - when(write_fifo.io.deq.fire) { - aw.addr := write_fifo.io.deq.bits.addr - aw.size := Cat(0.U(1.W), write_fifo.io.deq.bits.size) - w.data := write_fifo.io.deq.bits.data - w.strb := write_fifo.io.deq.bits.strb - } - aw.len := 0.U - awvalid := true.B - w.last := true.B - wvalid := true.B - write_buffer_axi_busy := true.B - } - - switch(state) { - is(s_idle) { - when(tlb_fill) { - tlb_fill := false.B - when(!io.cpu.tlb.hit) { - state := s_save - } - }.elsewhen(io.cpu.en) { - when(!io.cpu.tlb.translation_ok) { - when(io.cpu.tlb.tlb1_ok) { - state := s_save - }.otherwise { - tlb_fill := true.B - } - }.elsewhen(io.cpu.tlb.uncached) { - when(io.cpu.wen.orR) { - when(write_fifo.io.enq.ready && !current_mmio_write_saved) { - write_fifo.io.enq.valid := true.B - write_fifo.io.enq.bits.addr := Mux( - io.cpu.rlen === 2.U, - Cat(io.cpu.tlb.pa(31, 2), 0.U(2.W)), - io.cpu.tlb.pa, - ) - write_fifo.io.enq.bits.size := io.cpu.rlen - write_fifo.io.enq.bits.strb := io.cpu.wen - write_fifo.io.enq.bits.data := io.cpu.wdata - - current_mmio_write_saved := true.B - } - when(!io.cpu.dcache_stall && !io.cpu.cpu_stall) { - current_mmio_write_saved := false.B - } - }.elsewhen(!(write_fifo.io.deq.valid || write_buffer_axi_busy)) { - ar.addr := Mux(io.cpu.rlen === 2.U, Cat(io.cpu.tlb.pa(31, 2), 0.U(2.W)), io.cpu.tlb.pa) - ar.len := 0.U - ar.size := Cat(0.U(1.W), io.cpu.rlen) - arvalid := true.B - state := s_uncached - rready := true.B - } // when store buffer busy, read will stop at s_idle but stall pipeline. - }.otherwise { - when(!cache_hit) { - state := s_replace - axi_cnt.reset() - victim.set := pset - victim_cnt.reset() - read_ready_set := pset - read_ready_cnt := 0.U - victim.waddr := Cat(pset, 0.U(4.W)) - victim.valid := true.B - victim.writeback := dirty(pset)(lru(pset)) - }.otherwise { - when(!io.cpu.dcache_stall) { - // update lru and mark dirty - lru(pset) := ~sel - when(io.cpu.wen.orR) { - dirty(pset)(sel) := true.B - } - when(io.cpu.cpu_stall) { - saved_rdata := cache_data_forward(sel) - state := s_save - } - } - } - } - }.elsewhen(io.cpu.fence) { - when(dirty(fset).contains(true.B)) { - when(!(write_fifo.io.deq.valid || write_buffer_axi_busy)) { - state := s_writeback - axi_cnt.reset() - victim.set := fset - victim_cnt.reset() - read_ready_set := fset - read_ready_cnt := 0.U - victim.valid := true.B - } - }.otherwise { - when(valid(fset).contains(true.B)) { - valid(fset)(0) := false.B - valid(fset)(1) := false.B - } - state := s_save - } - } - } - is(s_uncached) { - when(arvalid && io.axi.ar.ready) { - arvalid := false.B - } - when(io.axi.r.valid) { - saved_rdata := io.axi.r.bits.data - state := s_save - } - } - is(s_writeback) { - when(fence.working) { - when(victim_cnt.value =/= (burstSize - 1).U) { - victim_cnt.inc() - } - read_ready_set := victim.set - read_ready_cnt := victim_cnt.value - read_buffer(read_ready_cnt) := data(dirty(fset)(1)) - when(!aw_handshake) { - aw.addr := Cat(tag(dirty(fset)(1)), fset, 0.U(6.W)) - aw.len := 15.U - aw.size := 2.U(3.W) - awvalid := true.B - w.data := data(dirty(fset)(1)) - w.strb := 15.U - w.last := false.B - wvalid := true.B - aw_handshake := true.B - } - when(io.axi.aw.fire) { - awvalid := false.B - } - when(io.axi.w.fire) { - when(w.last) { - wvalid := false.B - }.otherwise { - w.data := Mux( - ((axi_cnt.value + 1.U) === read_ready_cnt), - data(dirty(fset)(1)), - read_buffer(axi_cnt.value + 1.U), - ) - axi_cnt.inc() - when(axi_cnt.value + 1.U === (burstSize - 1).U) { - w.last := true.B - } - } - } - when(io.axi.b.valid) { - dirty(fset)(dirty(fset)(1)) := false.B - fence.working := false.B - victim.valid := false.B - state := s_idle - } - }.otherwise { - aw_handshake := false.B - fence.working := true.B - victim_cnt.inc() - } - } - is(s_replace) { - when(!(write_fifo.io.deq.valid || write_buffer_axi_busy)) { - when(victim.working) { - when(victim.writeback) { - when(victim_cnt.value =/= (burstSize - 1).U) { - victim_cnt.inc() - } - read_ready_set := victim.set - read_ready_cnt := victim_cnt.value - read_buffer(read_ready_cnt) := data(lru(pset)) - when(!aw_handshake) { - aw.addr := Cat(tag(lru(pset)), pset, 0.U(6.W)) - aw.len := 15.U - aw.size := 2.U(3.W) - awvalid := true.B - aw_handshake := true.B - w.data := data(lru(pset)) - w.strb := 15.U - w.last := false.B - wvalid := true.B - } - when(io.axi.aw.fire) { - awvalid := false.B - } - when(io.axi.w.fire) { - when(w.last) { - wvalid := false.B - }.otherwise { - w.data := Mux( - ((axi_cnt.value + 1.U) === read_ready_cnt), - data(lru(pset)), - read_buffer(axi_cnt.value + 1.U), - ) - axi_cnt.inc() - when(axi_cnt.value + 1.U === (burstSize - 1).U) { - w.last := true.B - } - } - } - when(io.axi.b.valid) { - dirty(pset)(lru(pset)) := false.B - victim.writeback := false.B - } - } - when(!ar_handshake) { - ar.addr := Cat(io.cpu.tlb.pa(31, 6), 0.U(6.W)) - ar.len := 15.U - ar.size := 2.U(3.W) - arvalid := true.B - rready := true.B - ar_handshake := true.B - victim.wstrb(lru(pset)) := 15.U - tag_wstrb(lru(pset)) := true.B - tag_wdata := io.cpu.tlb.pa(31, 12) - } - when(io.axi.ar.fire) { - tag_wstrb(lru(pset)) := false.B - arvalid := false.B - } - when(io.axi.r.fire) { - when(io.axi.r.bits.last) { - rready := false.B - victim.wstrb(lru(pset)) := 0.U - }.otherwise { - victim.waddr := victim.waddr + 1.U - } - } - when( - (!victim.writeback || io.axi.b.valid) && ((ar_handshake && io.axi.r.valid && io.axi.r.bits.last) || (ar_handshake && !rready)), - ) { - victim.valid := false.B - valid(pset)(lru(pset)) := true.B - } - when(!victim.valid) { - victim.working := false.B - state := s_idle - } - }.otherwise { - ar_handshake := false.B - aw_handshake := false.B - victim.working := true.B - victim_cnt.inc() - } - } - } - is(s_save) { - when(!io.cpu.dcache_stall && !io.cpu.cpu_stall) { - state := s_idle - } - } - } - - // ===----------------------------------------------------------------=== - // statistic - // ===----------------------------------------------------------------=== - val req_cnt = RegInit(0.U(32.W)) - when(io.cpu.en) { - req_cnt := req_cnt + 1.U - } - val hit_cnt = RegInit(0.U(32.W)) - when(cache_hit) { - hit_cnt := hit_cnt + 1.U - } - if (!config.build) { - io.statistic.get.request := req_cnt - io.statistic.get.hit := hit_cnt - } + val s_idle :: s_read :: s_write :: s_finishwait :: Nil = Enum(4) + val state = RegInit(s_idle) } diff --git a/chisel/playground/src/cache/ICache.scala b/chisel/playground/src/cache/ICache.scala index 1511753..c99d1b8 100644 --- a/chisel/playground/src/cache/ICache.scala +++ b/chisel/playground/src/cache/ICache.scala @@ -4,246 +4,66 @@ package cache import chisel3._ import chisel3.util._ import memory._ -import cpu.CacheConfig import cpu.defines._ import cpu.CpuConfig import cpu.defines.Const._ -class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Module { - val nway: Int = cacheConfig.nway - val nset: Int = cacheConfig.nset - val nbank: Int = cacheConfig.nbank - val ninst: Int = cacheConfig.ninst // 取指令的数量 - val bankOffsetWidth: Int = cacheConfig.bankOffsetWidth - val bankWidth: Int = cacheConfig.bankWidth - val tagWidth: Int = cacheConfig.tagWidth - val indexWidth: Int = cacheConfig.indexWidth - val offsetWidth: Int = cacheConfig.offsetWidth +class ICache(implicit config: CpuConfig) extends Module { val io = IO(new Bundle { - val cpu = Flipped(new Cache_ICache()) - val axi = new ICache_AXIInterface() - val statistic = if (!config.build) Some(new ICacheStatistic()) else None + val cpu = Flipped(new Cache_ICache()) + val axi = new ICache_AXIInterface() }) - require(isPow2(ninst), "ninst must be power of 2") - // * addr organization * // - // ====================================== - // | tag | index |offset| - // |31 12|11 6|5 0| - // ====================================== - // | offset | - // | bank index | bank offset | - // | 5 4 | 3 2 | - // ============================ - val tlb_fill = RegInit(false.B) - // * fsm * // - val s_idle :: s_uncached :: s_replace :: s_save :: Nil = Enum(4) - val state = RegInit(s_idle) + val s_idle :: s_read :: s_finishwait :: Nil = Enum(3) + val status = RegInit(s_idle) - // * nway * nset * // - // * 128 bit for 4 inst * // - // ========================================================= - // | valid | tag | bank 0 | bank 1 | bank 2 | bank 3 | - // | 1 | 20 | 128 | 128 | 128 | 128 | - // ========================================================= - // | bank | - // | inst 0 | inst 1 | inst 2 | inst 3 | - // | 32 | 32 | 32 | 32 | - // ===================================== - val instperbank = bankWidth / 4 // 每个bank存储的指令数 - val valid = RegInit(VecInit(Seq.fill(nset * nbank)(VecInit(Seq.fill(instperbank)(false.B))))) + io.cpu.valid := status === s_finishwait + val addr_err = io.cpu.addr.orR - val data = Wire(Vec(nway, Vec(instperbank, UInt(DATA_WID.W)))) - val tag = RegInit(VecInit(Seq.fill(nway)(0.U(tagWidth.W)))) + io.axi.ar.addr := 0.U + io.axi.ar.len := 0.U + io.axi.ar.size := 2.U + io.axi.ar.burst := BURST_FIXED.U + io.axi.ar.valid := false.B + io.axi.r.ready := true.B + io.cpu.rdata := 0.U + io.cpu.acc_err := false.B - // * should choose next addr * // - val should_next_addr = (state === s_idle && !tlb_fill) || (state === s_save) - - val data_raddr = io.cpu.addr(should_next_addr)(indexWidth + offsetWidth - 1, bankOffsetWidth) - val data_wstrb = RegInit(VecInit(Seq.fill(nway)(VecInit(Seq.fill(instperbank)(0.U(4.W)))))) - - val tag_raddr = io.cpu.addr(should_next_addr)(indexWidth + offsetWidth - 1, offsetWidth) - val tag_wstrb = RegInit(VecInit(Seq.fill(nway)(false.B))) - val tag_wdata = RegInit(0.U(tagWidth.W)) - - // * lru * // - val lru = RegInit(VecInit(Seq.fill(nset * nbank)(false.B))) - - // * itlb * // - when(tlb_fill) { tlb_fill := false.B } - io.cpu.tlb.fill := tlb_fill - io.cpu.tlb.icache_is_save := (state === s_save) - - // * fence * // - val fence_index = io.cpu.fence_addr(indexWidth + offsetWidth - 1, offsetWidth) - when(io.cpu.fence && !io.cpu.icache_stall && !io.cpu.cpu_stall) { - valid(fence_index) := VecInit(Seq.fill(instperbank)(false.B)) - } - - // * replace set * // - val rset = RegInit(0.U(6.W)) - - // * virtual set * // - val vset = io.cpu.addr(0)(indexWidth + offsetWidth - 1, offsetWidth) - - // * cache hit * // - val tag_compare_valid = VecInit(Seq.tabulate(nway)(i => tag(i) === io.cpu.tlb.tag && valid(vset)(i))) - val cache_hit = tag_compare_valid.contains(true.B) - val cache_hit_available = cache_hit && io.cpu.tlb.translation_ok && !io.cpu.tlb.uncached - val sel = tag_compare_valid(1) - - val bank_offset = io.cpu.addr(0)(log2Ceil(instperbank) + 1, 2) - val inst = VecInit(Seq.tabulate(instperbank)(i => Mux(i.U <= (3.U - bank_offset), data(sel)(i.U + bank_offset), 0.U))) - - val inst_valid = VecInit(Seq.tabulate(instperbank)(i => cache_hit_available && i.U <= (3.U - bank_offset))) - - val saved = RegInit(VecInit(Seq.fill(instperbank)(0.U.asTypeOf(new Bundle { - val inst = UInt(PC_WID.W) - val valid = Bool() - })))) - - val axi_cnt = Counter(cacheConfig.burstSize) - - // bank tag ram - for { i <- 0 until nway; j <- 0 until instperbank } { - val bank = Module(new SimpleDualPortRam(nset * nbank, DATA_WID, byteAddressable = true)) - bank.io.ren := true.B - bank.io.raddr := data_raddr - data(i)(j) := bank.io.rdata - - bank.io.wen := data_wstrb(i)(j).orR - bank.io.waddr := Cat(rset, axi_cnt.value(log2Ceil(cacheConfig.burstSize) - 1, log2Ceil(instperbank))) - bank.io.wdata := Mux(j.U === axi_cnt.value(log2Ceil(instperbank) - 1, 0), io.axi.r.bits.data, 0.U) - bank.io.wstrb := data_wstrb(i)(j) - } - - for { i <- 0 until ninst } { - io.cpu.inst_valid(i) := Mux(state === s_idle && !tlb_fill, inst_valid(i), saved(i).valid) && io.cpu.req - io.cpu.inst(i) := Mux(state === s_idle && !tlb_fill, inst(i), saved(i).inst) - } - - for { i <- 0 until nway } { - val tag_bram = Module(new LUTRam(nset, tagWidth)) - tag_bram.io.raddr := tag_raddr - tag(i) := tag_bram.io.rdata - - tag_bram.io.wen := tag_wstrb(i) - tag_bram.io.waddr := rset - tag_bram.io.wdata := tag_wdata - } - - io.cpu.icache_stall := Mux(state === s_idle && !tlb_fill, (!cache_hit_available && io.cpu.req), state =/= s_save) - - val ar = RegInit(0.U.asTypeOf(new AR())) - val arvalid = RegInit(false.B) - ar <> io.axi.ar.bits - arvalid <> io.axi.ar.valid - - val r = RegInit(0.U.asTypeOf(new R())) - val rready = RegInit(false.B) - r <> io.axi.r.bits - rready <> io.axi.r.ready - - when(tlb_fill === true.B) { - tlb_fill := false.B - } - - switch(state) { + switch(status) { is(s_idle) { - when(tlb_fill) { - when(!io.cpu.tlb.hit) { - state := s_save - saved(0).inst := 0.U - saved(0).valid := true.B - } - }.elsewhen(io.cpu.req) { - when(!io.cpu.tlb.translation_ok) { - tlb_fill := true.B - }.elsewhen(io.cpu.tlb.uncached) { - state := s_uncached - ar.addr := io.cpu.tlb.pa - ar.len := 0.U(log2Ceil((nbank * bankWidth) / 4).W) - ar.size := 2.U(bankOffsetWidth.W) - arvalid := true.B - }.elsewhen(!cache_hit) { - state := s_replace - ar.addr := Cat(io.cpu.tlb.pa(31, 6), 0.U(6.W)) - ar.len := 15.U(log2Ceil((nbank * bankWidth) / 4).W) - ar.size := 2.U(bankOffsetWidth.W) - arvalid := true.B - - rset := vset - (0 until instperbank).foreach(i => data_wstrb(lru(vset))(i) := Mux(i.U === 0.U, 0xf.U, 0x0.U)) - tag_wstrb(lru(vset)) := true.B - tag_wdata := io.cpu.tlb.tag - valid(vset)(lru(vset)) := true.B - axi_cnt.reset() - }.elsewhen(!io.cpu.icache_stall) { - lru(vset) := ~sel - when(io.cpu.cpu_stall) { - state := s_save - (1 until instperbank).foreach(i => saved(i).inst := data(sel)(i)) - (0 until instperbank).foreach(i => saved(i).valid := inst_valid(i)) + when(io.cpu.en) { + io.cpu.acc_err := true.B + status := s_finishwait + }.otherwise { + io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W)) + io.axi.ar.valid := true.B + status := s_read + } + } + is(s_read) { + when(io.axi.ar.ready) { + io.axi.ar.valid := false.B + } + when(io.axi.r.valid) { + io.cpu.rdata := Mux(io.axi.ar.addr(2), io.axi.r.data(63, 32), io.axi.r.data(31, 0)) + io.cpu.acc_err := io.axi.r.resp =/= RESP_OKEY.U + status := s_finishwait + } + } + is(s_finishwait) { + when(io.cpu.ready) { + io.cpu.acc_err := false.B + when(io.cpu.en) { + when(addr_err) { + io.cpu.acc_err := true.B + status := s_finishwait + }.otherwise { + io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W)) + io.axi.ar.valid := true.B + status := s_read } } } } - is(s_uncached) { - when(io.axi.ar.valid) { - when(io.axi.ar.ready) { - arvalid := false.B - rready := true.B - } - }.elsewhen(io.axi.r.fire) { - // * uncached not support burst transport * // - state := s_save - saved(0).inst := io.axi.r.bits.data - saved(0).valid := true.B - rready := false.B - } - } - is(s_replace) { - when(io.axi.ar.valid) { - when(io.axi.ar.ready) { - arvalid := false.B - rready := true.B - } - }.elsewhen(io.axi.r.fire) { - // * burst transport * // - when(!io.axi.r.bits.last) { - axi_cnt.inc() - data_wstrb(lru(vset))(0) := data_wstrb(lru(vset))(instperbank - 1) - (1 until instperbank).foreach(i => data_wstrb(lru(vset))(i) := data_wstrb(lru(vset))(i - 1)) - }.otherwise { - rready := false.B - data_wstrb(lru(vset)) := 0.U.asTypeOf(Vec(instperbank, UInt(4.W))) - tag_wstrb(lru(vset)) := false.B - } - }.elsewhen(!io.axi.r.ready) { - state := s_idle - } - } - is(s_save) { - when(!io.cpu.cpu_stall && !io.cpu.icache_stall) { - state := s_idle - (0 until instperbank).foreach(i => saved(i).valid := false.B) - } - } - } - - // ===----------------------------------------------------------------=== - // statistic - // ===----------------------------------------------------------------=== - val req_cnt = RegInit(0.U(32.W)) - when(io.cpu.req) { - req_cnt := req_cnt + 1.U - } - val hit_cnt = RegInit(0.U(32.W)) - when(io.cpu.req && cache_hit) { - hit_cnt := hit_cnt + 1.U - } - if (!config.build) { - io.statistic.get.request := req_cnt - io.statistic.get.hit := hit_cnt } } diff --git a/chisel/playground/src/ctrl/Ctrl.scala b/chisel/playground/src/ctrl/Ctrl.scala index 0a7f052..35289b7 100644 --- a/chisel/playground/src/ctrl/Ctrl.scala +++ b/chisel/playground/src/ctrl/Ctrl.scala @@ -39,8 +39,6 @@ class Ctrl(implicit val config: CpuConfig) extends Module { io.memoryUnit.do_flush := io.memoryUnit.flush_req io.writeBackUnit.do_flush := false.B - io.instFifo.delay_slot_do_flush := io.memoryUnit.flush_req - io.executeUnit.fu.do_flush := io.memoryUnit.do_flush io.executeUnit.fu.eret := io.memoryUnit.eret io.executeUnit.fu.allow_to_go := io.memoryUnit.allow_to_go diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index 2d4bafb..acd5293 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -5,23 +5,12 @@ import chisel3.util._ import cpu.defines.Const._ import cpu.CpuConfig -class TlbEntry extends Bundle { - val vpn2 = UInt(VPN2_WID.W) - val asid = UInt(ASID_WID.W) - val g = Bool() - val pfn = Vec(2, UInt(PFN_WID.W)) - val c = Vec(2, Bool()) - val d = Vec(2, Bool()) - val v = Vec(2, Bool()) -} - class ExceptionInfo extends Bundle { - val flush_req = Bool() - val tlb_refill = Bool() - val eret = Bool() - val badvaddr = UInt(PC_WID.W) - val bd = Bool() - val excode = UInt(EXCODE_WID.W) + val flush_req = Bool() + val eret = Bool() + val badvaddr = UInt(PC_WID.W) + val bd = Bool() + val excode = UInt(EXCODE_WID.W) } class SrcInfo extends Bundle { @@ -54,7 +43,6 @@ class InstInfo extends Bundle { val branch_link = Bool() val ifence = Bool() val dfence = Bool() - val tlbfence = Bool() val mem_addr = UInt(DATA_ADDR_WID.W) val mem_wreg = Bool() val inst = UInt(INST_WID.W) @@ -81,8 +69,6 @@ class FetchUnitCtrl extends Bundle { } class InstFifoCtrl extends Bundle { - val delay_slot_do_flush = Input(Bool()) - val has2insts = Output(Bool()) } @@ -127,65 +113,18 @@ class WriteBackCtrl extends Bundle { val do_flush = Input(Bool()) } -class Tlb1InfoI extends Bundle { - val invalid = Bool() - val refill = Bool() -} - -class Tlb1InfoD extends Tlb1InfoI { - val modify = Bool() -} - -class Tlb2Info extends Bundle { - val vpn2 = Input(UInt(19.W)) - val found = Output(Bool()) - val entry = Output(new TlbEntry()) -} - -class Tlb_ICache extends Bundle { - val fill = Input(Bool()) - val icache_is_save = Input(Bool()) - val uncached = Output(Bool()) - - val translation_ok = Output(Bool()) - val hit = Output(Bool()) - val tag = Output(UInt(20.W)) - val pa = Output(UInt(32.W)) -} - -class Tlb_DCache extends Bundle { - val fill = Input(Bool()) - val dcache_is_idle = Input(Bool()) - val dcache_is_save = Input(Bool()) - val uncached = Output(Bool()) - val tlb1_ok = Output(Bool()) - - val translation_ok = Output(Bool()) - val hit = Output(Bool()) - val tag = Output(UInt(20.W)) - val pa = Output(UInt(32.W)) -} - // cpu to icache -class Cache_ICache(implicit - val config: CpuConfig, -) extends Bundle { +class Cache_ICache(implicit val config: CpuConfig) extends Bundle { // read inst request from cpu - val req = Output(Bool()) - val addr = Output(Vec(config.instFetchNum, UInt(32.W))) // virtual address and next virtual address + val en = Output(Bool()) + val ready = Output(Bool()) + val addr = Output(UInt(INST_ADDR_WID.W)) // virtual address and next virtual address + val fence = Output(Bool()) // read inst result - val inst = Input(Vec(config.instFetchNum, UInt(32.W))) - val inst_valid = Input(Vec(config.instFetchNum, Bool())) - - // control - val cpu_stall = Output(Bool()) - val icache_stall = Input(Bool()) - - val tlb = new Tlb_ICache() - - val fence = Output(Bool()) - val fence_addr = Output(UInt(32.W)) + val rdata = Input(UInt(INST_WID.W)) + val valid = Input(Bool()) + val acc_err = Input(Bool()) } // cpu to dcache @@ -202,41 +141,72 @@ class Cache_DCache extends Bundle { val wdata = Output(UInt(32.W)) val addr = Output(UInt(32.W)) - val tlb = new Tlb_DCache() - val fence = Output(Bool()) val fence_addr = Output(UInt(32.W)) } // axi -// master +// master -> slave class AR extends Bundle { - val addr = UInt(32.W) - val len = UInt(8.W) - val size = UInt(3.W) + val id = Output(UInt(4.W)) + val addr = Output(UInt(32.W)) + val len = Output(UInt(8.W)) + val size = Output(UInt(3.W)) + val burst = Output(UInt(2.W)) + val lock = Output(UInt(2.W)) + val cache = Output(UInt(4.W)) + val prot = Output(UInt(3.W)) + val valid = Output(Bool()) + + val ready = Input(Bool()) } class R extends Bundle { - val data = UInt(32.W) - val last = Bool() + val ready = Output(Bool()) + + val id = Input(UInt(4.W)) + val data = Input(UInt(32.W)) + val resp = Input(UInt(2.W)) + val last = Input(Bool()) + val valid = Input(Bool()) } class AW extends Bundle { - val addr = UInt(32.W) - val len = UInt(8.W) - val size = UInt(3.W) + val id = Output(UInt(4.W)) + val addr = Output(UInt(32.W)) + val len = Output(UInt(8.W)) + val size = Output(UInt(3.W)) + val burst = Output(UInt(2.W)) + val lock = Output(UInt(2.W)) + val cache = Output(UInt(4.W)) + val prot = Output(UInt(3.W)) + val valid = Output(Bool()) + + val ready = Input(Bool()) } class W extends Bundle { - val data = UInt(32.W) - val strb = UInt(4.W) - val last = Bool() + val id = Output(UInt(4.W)) + val data = Output(UInt(32.W)) + val strb = Output(UInt(4.W)) + val last = Output(Bool()) + val valid = Output(Bool()) + + val ready = Input(Bool()) +} + +class B extends Bundle { + val ready = Output(Bool()) + + val id = Input(UInt(4.W)) + val resp = Input(UInt(2.W)) + val valid = Input(Bool()) } class ICache_AXIInterface extends Bundle { - val ar = Decoupled(new AR()) - val r = Flipped(Decoupled(new R())) + val ar = new AR() + val r = new R() } class DCache_AXIInterface extends ICache_AXIInterface { @@ -255,42 +225,42 @@ class Cache_AXIInterface extends Bundle { // AXI read address channel class AXI_AR extends Bundle { - val id = UInt(4.W) // transaction ID + val id = UInt(4.W) // transaction ID val addr = UInt(32.W) // address - val len = UInt(8.W) // burst length - val size = UInt(3.W) // transfer size - val burst = UInt(2.W) // burst type - val lock = UInt(2.W) // lock type - val cache = UInt(4.W) // cache type - val prot = UInt(3.W) // protection type + val len = UInt(8.W) // burst length + val size = UInt(3.W) // transfer size + val burst = UInt(2.W) // burst type + val lock = UInt(2.W) // lock type + val cache = UInt(4.W) // cache type + val prot = UInt(3.W) // protection type } // AXI read data channel class AXI_R extends Bundle { - val id = UInt(4.W) // transaction ID + val id = UInt(4.W) // transaction ID val data = UInt(32.W) // read data - val resp = UInt(2.W) // response type - val last = Bool() // last beat of burst + val resp = UInt(2.W) // response type + val last = Bool() // last beat of burst } // AXI write address channel class AXI_AW extends Bundle { - val id = UInt(4.W) // transaction ID + val id = UInt(4.W) // transaction ID val addr = UInt(32.W) // address - val len = UInt(8.W) // burst length - val size = UInt(3.W) // transfer size - val burst = UInt(2.W) // burst type - val lock = UInt(2.W) // lock type - val cache = UInt(4.W) // cache type - val prot = UInt(3.W) // protection type + val len = UInt(8.W) // burst length + val size = UInt(3.W) // transfer size + val burst = UInt(2.W) // burst type + val lock = UInt(2.W) // lock type + val cache = UInt(4.W) // cache type + val prot = UInt(3.W) // protection type } // AXI write data channel class AXI_W extends Bundle { - val id = UInt(4.W) // transaction ID + val id = UInt(4.W) // transaction ID val data = UInt(32.W) // write data - val strb = UInt(4.W) // byte enable - val last = Bool() // last beat of burst + val strb = UInt(4.W) // byte enable + val last = Bool() // last beat of burst } // AXI write response channel @@ -301,10 +271,10 @@ class AXI_B extends Bundle { // AXI interface class AXI extends Bundle { - val ar = Decoupled(new AXI_AR()) // read address channel + val ar = Decoupled(new AXI_AR()) // read address channel val r = Flipped(Decoupled(new AXI_R())) // read data channel - val aw = Decoupled(new AXI_AW()) // write address channel - val w = Decoupled(new AXI_W()) // write data channel + val aw = Decoupled(new AXI_AW()) // write address channel + val w = Decoupled(new AXI_W()) // write data channel val b = Flipped(Decoupled(new AXI_B())) // write response channel } diff --git a/chisel/playground/src/defines/Const.scala b/chisel/playground/src/defines/Const.scala index 3430d66..7b339fe 100644 --- a/chisel/playground/src/defines/Const.scala +++ b/chisel/playground/src/defines/Const.scala @@ -8,8 +8,8 @@ import cpu.CpuConfig trait Constants { val config = new CpuConfig // 全局 - val PC_WID = 32 - val PC_INIT = "hbfc00000".U(PC_WID.W) + val PC_WID = 64 + val PC_INIT = "h60000000".U(PC_WID.W) val EXT_INT_WID = 6 @@ -142,7 +142,8 @@ trait Constants { val DIV_STOP = false.B // inst rom - val INST_WID = 32 + val INST_WID = 32 + val INST_ADDR_WID = PC_WID // data ram val DATA_ADDR_WID = 32 @@ -197,16 +198,16 @@ trait Constants { // 例外类型 val EXCODE_WID = 5 - val EX_NO = 0.U(EXCODE_WID.W) // 无异常 - val EX_INT = 1.U(EXCODE_WID.W) // 中断异常 - val EX_MOD = 2.U(EXCODE_WID.W) // TLB 条目修改异常 - val EX_TLBL = 3.U(EXCODE_WID.W) // TLB 非法取指令或访问异常 - val EX_TLBS = 4.U(EXCODE_WID.W) // TLB 非法存储访问异常 - val EX_ADEL = 5.U(EXCODE_WID.W) // 地址未对齐异常(取指令或访问异常) - val EX_ADES = 6.U(EXCODE_WID.W) // 地址未对齐异常(存储访问异常) - val EX_SYS = 7.U(EXCODE_WID.W) // 系统调用异常 - val EX_BP = 8.U(EXCODE_WID.W) // 断点异常 - val EX_RI = 9.U(EXCODE_WID.W) // 保留指令异常 + val EX_NO = 0.U(EXCODE_WID.W) // 无异常 + val EX_INT = 1.U(EXCODE_WID.W) // 中断异常 + val EX_MOD = 2.U(EXCODE_WID.W) // TLB 条目修改异常 + val EX_TLBL = 3.U(EXCODE_WID.W) // TLB 非法取指令或访问异常 + val EX_TLBS = 4.U(EXCODE_WID.W) // TLB 非法存储访问异常 + val EX_ADEL = 5.U(EXCODE_WID.W) // 地址未对齐异常(取指令或访问异常) + val EX_ADES = 6.U(EXCODE_WID.W) // 地址未对齐异常(存储访问异常) + val EX_SYS = 7.U(EXCODE_WID.W) // 系统调用异常 + val EX_BP = 8.U(EXCODE_WID.W) // 断点异常 + val EX_RI = 9.U(EXCODE_WID.W) // 保留指令异常 val EX_CPU = 10.U(EXCODE_WID.W) // 协处理器不可用异常 val EX_OV = 11.U(EXCODE_WID.W) // 算术溢出异常 @@ -232,6 +233,17 @@ trait Constants { val C_WID = 3 val ASID_WID = 8 val VPN2_WID = 19 + + // AXI + val BURST_FIXED = 0 + val BURST_INCR = 1 + val BURST_WRAP = 2 + val BURST_RESERVED = 3 + + val RESP_OKEY = 0 + val RESP_EXOKEY = 1 + val RESP_SLVERR = 2 + val RESP_DECERR = 3 } trait OptionConst { diff --git a/chisel/playground/src/mmu/TlbL1D.scala b/chisel/playground/src/mmu/TlbL1D.scala deleted file mode 100644 index b633733..0000000 --- a/chisel/playground/src/mmu/TlbL1D.scala +++ /dev/null @@ -1,70 +0,0 @@ -package cpu.mmu - -import chisel3._ -import chisel3.util._ -import cpu.defines._ - -class DTLB extends ITLB { - val dirty = Bool() -} - -class TlbL1D extends Module { - val io = IO(new Bundle { - val cache = new Tlb_DCache() - val fence = Input(Bool()) - val cpu_stall = Input(Bool()) - val dcache_stall = Input(Bool()) - val addr = Input(UInt(32.W)) - - val mem_en = Input(Bool()) - val mem_write = Input(Bool()) - - val tlb1 = Output(new Tlb1InfoD()) - val tlb2 = Flipped(new Tlb2Info()) - }) - val dtlb = RegInit(0.U.asTypeOf(new DTLB())) - val vpn = io.addr(31, 12) - val direct_mapped = io.addr(31, 30) === 2.U(2.W) - - io.cache.uncached := Mux(direct_mapped, io.addr(29), dtlb.uncached) - io.cache.translation_ok := direct_mapped || (dtlb.vpn === vpn && dtlb.valid && (!io.mem_write || dtlb.dirty)) - - io.cache.tag := Mux(direct_mapped, Cat(0.U(3.W), io.addr(28, 12)), dtlb.ppn) - io.cache.pa := Cat(io.cache.tag, io.addr(11, 0)) - io.cache.tlb1_ok := dtlb.vpn === vpn && dtlb.valid - io.cache.hit := io.cache.fill && io.tlb2.found && io.tlb2.entry.v(vpn(0)) - - when(io.fence) { dtlb.valid := false.B } - - val tlb1 = RegInit(0.U.asTypeOf(new Tlb1InfoD())) - io.tlb1 <> tlb1 - - val tlb2 = RegInit(0.U.asTypeOf(new Bundle { val vpn2 = UInt(19.W) })) - io.tlb2.vpn2 <> tlb2.vpn2 - - when(io.cache.dcache_is_idle && !io.cache.fill && io.mem_en && !io.cache.translation_ok) { - when(io.cache.tlb1_ok) { - tlb1.modify := true.B - }.otherwise { - tlb2.vpn2 := vpn(19, 1) - } - }.elsewhen(io.cache.fill) { - when(io.tlb2.found) { - when(io.tlb2.entry.v(vpn(0))) { - dtlb.vpn := vpn - dtlb.ppn := io.tlb2.entry.pfn(vpn(0)) - dtlb.uncached := !io.tlb2.entry.c(vpn(0)) - dtlb.dirty := io.tlb2.entry.d(vpn(0)) - dtlb.valid := true.B - }.otherwise { - tlb1.invalid := true.B - } - }.otherwise { - tlb1.refill := true.B - } - }.elsewhen(io.cache.dcache_is_save && !io.cpu_stall && !io.dcache_stall) { - tlb1.invalid := false.B - tlb1.refill := false.B - tlb1.modify := false.B - } -} diff --git a/chisel/playground/src/mmu/TlbL1I.scala b/chisel/playground/src/mmu/TlbL1I.scala deleted file mode 100644 index 3c27cb8..0000000 --- a/chisel/playground/src/mmu/TlbL1I.scala +++ /dev/null @@ -1,59 +0,0 @@ -package cpu.mmu - -import chisel3._ -import chisel3.util._ -import cpu.defines._ - -class ITLB extends Bundle { - val vpn = UInt(20.W) - val ppn = UInt(20.W) - val uncached = Bool() - val valid = Bool() -} - -class TlbL1I extends Module { - val io = IO(new Bundle { - val addr = Input(UInt(32.W)) - val fence = Input(Bool()) - val cpu_stall = Input(Bool()) - val icache_stall = Input(Bool()) - val cache = new Tlb_ICache() - val tlb1 = Output(new Tlb1InfoI()) - val tlb2 = Flipped(new Tlb2Info()) - }) - val itlb = RegInit(0.U.asTypeOf(new ITLB())) - val vpn = io.addr(31, 12) - val direct_mapped = io.addr(31, 30) === 2.U(2.W) - - io.cache.uncached := Mux(direct_mapped, io.addr(29), itlb.uncached) - io.cache.translation_ok := direct_mapped || (itlb.vpn === vpn && itlb.valid) - io.cache.hit := io.tlb2.found && io.tlb2.entry.v(vpn(0)) - io.cache.tag := Mux(direct_mapped, Cat(0.U(3.W), io.addr(28, 12)), itlb.ppn) - io.cache.pa := Cat(io.cache.tag, io.addr(11, 0)) - - when(io.fence && !io.icache_stall && !io.cpu_stall) { itlb.valid := false.B } - - // * tlb1 * // - val tlb1 = RegInit(0.U.asTypeOf(new Tlb1InfoI())) - tlb1 <> io.tlb1 - - io.tlb2.vpn2 := vpn(19, 1) - - when(io.cache.fill) { - when(io.tlb2.found) { - when(io.tlb2.entry.v(vpn(0))) { - itlb.vpn := vpn - itlb.ppn := io.tlb2.entry.pfn(vpn(0)) - itlb.uncached := !io.tlb2.entry.c(vpn(0)) - itlb.valid := true.B - }.otherwise { - tlb1.invalid := true.B - } - }.otherwise { - tlb1.refill := true.B - } - }.elsewhen(io.cache.icache_is_save && !io.cpu_stall && !io.icache_stall) { - tlb1.invalid := false.B - tlb1.refill := false.B - } -} diff --git a/chisel/playground/src/mmu/TlbL2.scala b/chisel/playground/src/mmu/TlbL2.scala deleted file mode 100644 index e83225c..0000000 --- a/chisel/playground/src/mmu/TlbL2.scala +++ /dev/null @@ -1,69 +0,0 @@ -package cpu.pipeline.execute - -import chisel3._ -import chisel3.util._ -import cpu.defines._ -import cpu.defines.TlbEntry -import cpu.defines.Const._ - -class TlbL2 extends Module { - val io = IO(new Bundle { - val in = Input(new Bundle { - val write = new Bundle { - val en = Bool() - val index = UInt(log2Ceil(TLB_NUM).W) - val entry = new TlbEntry() - } - val read = new Bundle { - val index = UInt(log2Ceil(TLB_NUM).W) - } - val entry_hi = new Bundle { - val vpn2 = UInt(VPN2_WID.W) - val asid = UInt(ASID_WID.W) - } - val tlb1_vpn2 = UInt(VPN2_WID.W) - val tlb2_vpn2 = UInt(VPN2_WID.W) - }) - val out = Output(new Bundle { - val read = new Bundle { - val entry = new TlbEntry() - } - val tlb1_found = Bool() - val tlb2_found = Bool() - val tlb1_entry = new TlbEntry() - val tlb2_entry = new TlbEntry() - val tlb_found = Bool() - val tlb_match_index = UInt(log2Ceil(TLB_NUM).W) - }) - }) - // tlb l2 - val tlb_l2 = RegInit(VecInit(Seq.fill(TLB_NUM)(0.U.asTypeOf(new TlbEntry())))) - - val tlb_match = Seq.fill(3)(Wire(Vec(TLB_NUM, Bool()))) - val tlb_find_vpn2 = Wire(Vec(3, UInt(VPN2_WID.W))) - val tlb_match_index = Wire(Vec(3, UInt(log2Ceil(TLB_NUM).W))) - - tlb_find_vpn2(0) := io.in.entry_hi.vpn2 - tlb_find_vpn2(1) := io.in.tlb1_vpn2 - tlb_find_vpn2(2) := io.in.tlb2_vpn2 - - io.out.tlb1_found := tlb_match(1).asUInt.orR - io.out.tlb2_found := tlb_match(2).asUInt.orR - io.out.tlb1_entry := tlb_l2(tlb_match_index(1)) - io.out.tlb2_entry := tlb_l2(tlb_match_index(2)) - io.out.tlb_found := tlb_match(0).asUInt.orR - io.out.tlb_match_index := tlb_match_index(0) - io.out.read.entry := tlb_l2(io.in.read.index) - - for (i <- 0 until (3)) { - for (j <- 0 until (TLB_NUM)) { - tlb_match(i)(j) := (tlb_l2(j).g || tlb_l2(j).asid === io.in.entry_hi.asid) && - (tlb_l2(j).vpn2 === tlb_find_vpn2(i)) - } - tlb_match_index(i) := PriorityEncoder(tlb_match(i)) - } - - when(io.in.write.en) { - tlb_l2(io.in.write.index) := io.in.write.entry - } -} diff --git a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala index 84ef201..d2f9d11 100644 --- a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala +++ b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala @@ -12,7 +12,6 @@ class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle { val allow_to_go = Output(Vec(config.decoderNum, Bool())) val inst = Input(Vec(config.decoderNum, new BufferUnit())) val info = Input(new Bundle { - val inst0_is_in_delayslot = Bool() val empty = Bool() val almost_empty = Bool() }) @@ -108,8 +107,6 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module { val pc = io.instFifo.inst.map(_.pc) val inst = io.instFifo.inst.map(_.inst) val inst_info = decoder.map(_.io.out) - val tlb_refill = io.instFifo.inst.map(_.tlb.refill) - val tlb_invalid = io.instFifo.inst.map(_.tlb.invalid) val interrupt = io.cp0.intterupt_allowed && (io.cp0.cause_ip & io.cp0.status_im).orR && !io.instFifo.info.empty for (i <- 0 until (config.decoderNum)) { @@ -141,12 +138,9 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module { ) io.executeStage.inst0.ex.flush_req := io.executeStage.inst0.ex.excode =/= EX_NO || - io.executeStage.inst0.ex.tlb_refill || io.executeStage.inst0.ex.eret - io.executeStage.inst0.ex.tlb_refill := tlb_refill(0) io.executeStage.inst0.ex.eret := inst_info(0).op === EXE_ERET io.executeStage.inst0.ex.badvaddr := pc(0) - io.executeStage.inst0.ex.bd := io.instFifo.info.inst0_is_in_delayslot val inst0_ex_cpu = !io.cp0.access_allowed && VecInit(EXE_MFC0, EXE_MTC0, EXE_TLBR, EXE_TLBWI, EXE_TLBWR, EXE_TLBP, EXE_ERET, EXE_WAIT) .contains(inst_info(0).op) @@ -154,7 +148,6 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module { EX_NO, Seq( interrupt -> EX_INT, - (tlb_refill(0) || tlb_invalid(0)) -> EX_TLBL, (pc(0)(1, 0).orR || (pc(0)(31) && !io.cp0.kernel_mode)) -> EX_ADEL, (inst_info(0).inst_valid === INST_INVALID) -> EX_RI, (inst_info(0).op === EXE_SYSCALL) -> EX_SYS, @@ -189,18 +182,15 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module { forwardCtrl.out.inst(1).src2.rdata, decoder(1).io.out.imm32 ) - io.executeStage.inst1.ex.flush_req := io.executeStage.inst1.ex.excode =/= EX_NO || io.executeStage.inst1.ex.tlb_refill - io.executeStage.inst1.ex.tlb_refill := tlb_refill(1) + io.executeStage.inst1.ex.flush_req := io.executeStage.inst1.ex.excode =/= EX_NO io.executeStage.inst1.ex.eret := inst_info(1).op === EXE_ERET io.executeStage.inst1.ex.badvaddr := pc(1) - io.executeStage.inst1.ex.bd := issue.inst1.is_in_delayslot val inst1_ex_cpu = !io.cp0.access_allowed && VecInit(EXE_MFC0, EXE_MTC0, EXE_TLBR, EXE_TLBWI, EXE_TLBWR, EXE_TLBP, EXE_ERET, EXE_WAIT) .contains(inst_info(1).op) io.executeStage.inst1.ex.excode := MuxCase( EX_NO, Seq( - (tlb_refill(1) || tlb_invalid(1)) -> EX_TLBL, (pc(1)(1, 0).orR || (pc(1)(31) && !io.cp0.kernel_mode)) -> EX_ADEL, (inst_info(1).inst_valid === INST_INVALID) -> EX_RI, (inst_info(1).op === EXE_SYSCALL) -> EX_SYS, diff --git a/chisel/playground/src/pipeline/decoder/Issue.scala b/chisel/playground/src/pipeline/decoder/Issue.scala index 91e73a2..279c721 100644 --- a/chisel/playground/src/pipeline/decoder/Issue.scala +++ b/chisel/playground/src/pipeline/decoder/Issue.scala @@ -18,7 +18,6 @@ class Issue(implicit val config: CpuConfig) extends Module { val execute = Input(Vec(config.fuNum, new MemRead())) // 输出 val inst1 = Output(new Bundle { - val is_in_delayslot = Bool() val allow_to_go = Bool() }) }) @@ -49,8 +48,6 @@ class Issue(implicit val config: CpuConfig) extends Module { inst0.op === EXE_MTC0 && inst1.op === EXE_MFC0 && inst0.cp0_addr === inst1.cp0_addr val data_conflict = raw_reg || raw_hilo || raw_cp0 || load_stall - // 指令1是否在延迟槽中 - io.inst1.is_in_delayslot := inst0.fusel === FU_BR && io.inst1.allow_to_go // 指令1是否允许执行 io.inst1.allow_to_go := io.allow_to_go && !instFifo_invalid && diff --git a/chisel/playground/src/pipeline/fetch/BranchPredictorUnit.scala b/chisel/playground/src/pipeline/fetch/BranchPredictorUnit.scala index 32ccb75..6a4db7b 100644 --- a/chisel/playground/src/pipeline/fetch/BranchPredictorUnit.scala +++ b/chisel/playground/src/pipeline/fetch/BranchPredictorUnit.scala @@ -8,7 +8,7 @@ import cpu.pipeline.decoder.Src12Read class ExecuteUnitBranchPredictor extends Bundle { val bpuConfig = new BranchPredictorConfig() - val pc = Output(UInt(DATA_ADDR_WID.W)) + val pc = Output(UInt(PC_WID.W)) val update_pht_index = Output(UInt(bpuConfig.phtDepth.W)) val branch_inst = Output(Bool()) val branch = Output(Bool()) @@ -20,8 +20,8 @@ class BranchPredictorIO(implicit config: CpuConfig) extends Bundle { val inst = Input(UInt(INST_WID.W)) val op = Input(UInt(OP_WID.W)) val ena = Input(Bool()) - val pc = Input(UInt(DATA_ADDR_WID.W)) - val pc_plus4 = Input(UInt(DATA_ADDR_WID.W)) + val pc = Input(UInt(PC_WID.W)) + val pc_plus4 = Input(UInt(PC_WID.W)) val pht_index = Input(UInt(bpuConfig.phtDepth.W)) val rs1 = Input(UInt(REG_ADDR_WID.W)) @@ -29,7 +29,7 @@ class BranchPredictorIO(implicit config: CpuConfig) extends Bundle { val branch_inst = Output(Bool()) val pred_branch = Output(Bool()) - val branch_target = Output(UInt(DATA_ADDR_WID.W)) + val branch_target = Output(UInt(PC_WID.W)) val update_pht_index = Output(UInt(bpuConfig.phtDepth.W)) } diff --git a/chisel/playground/src/pipeline/fetch/FetchUnit.scala b/chisel/playground/src/pipeline/fetch/FetchUnit.scala index 6b48e3a..3388875 100644 --- a/chisel/playground/src/pipeline/fetch/FetchUnit.scala +++ b/chisel/playground/src/pipeline/fetch/FetchUnit.scala @@ -31,7 +31,7 @@ class FetchUnit(implicit } }) - val pc = RegNext(io.iCache.pc_next, "h_bfc00000".U(32.W)) + val pc = RegNext(io.iCache.pc_next, PC_INIT) io.iCache.pc := pc // when inst_valid(1) is true, inst_valid(0) must be true diff --git a/chisel/playground/src/pipeline/fetch/InstFifo.scala b/chisel/playground/src/pipeline/fetch/InstFifo.scala index 546fbda..b0926d2 100644 --- a/chisel/playground/src/pipeline/fetch/InstFifo.scala +++ b/chisel/playground/src/pipeline/fetch/InstFifo.scala @@ -2,29 +2,21 @@ package cpu.pipeline.fetch import chisel3._ import chisel3.util._ -import cpu.{CpuConfig, BranchPredictorConfig} +import cpu.defines.Const._ +import cpu.{BranchPredictorConfig, CpuConfig} class BufferUnit extends Bundle { val bpuConfig = new BranchPredictorConfig() - val tlb = new Bundle { - val refill = Bool() - val invalid = Bool() - } - val inst = UInt(32.W) + val inst = UInt(INST_WID.W) val pht_index = UInt(bpuConfig.phtDepth.W) - val pc = UInt(32.W) + val pc = UInt(PC_WID.W) } class InstFifo(implicit val config: CpuConfig) extends Module { val io = IO(new Bundle { val do_flush = Input(Bool()) - val flush_delay_slot = Input(Bool()) - val delay_sel_flush = Input(Bool()) - val decoder_delay_flush = Input(Bool()) - val execute_delay_flush = Input(Bool()) val icache_stall = Input(Bool()) val jump_branch_inst = Input(Bool()) // 译码阶段的inst0是否为跳转指令 - val inst0_is_in_delayslot = Output(Bool()) val ren = Input(Vec(config.decoderNum, Bool())) val read = Output(Vec(config.decoderNum, new BufferUnit())) @@ -50,63 +42,28 @@ class InstFifo(implicit val config: CpuConfig) extends Module { io.empty := count === 0.U io.almost_empty := count === 1.U - val inst0_is_in_delayslot = RegInit(false.B) - io.inst0_is_in_delayslot := inst0_is_in_delayslot - inst0_is_in_delayslot := MuxCase( - false.B, - Seq( - io.flush_delay_slot -> false.B, - !io.ren(0) -> inst0_is_in_delayslot, - (io.jump_branch_inst && !io.ren(1)) -> true.B, - ), - ) - - val delayslot_stall = RegInit(false.B) - val delayslot_enable = RegInit(false.B) - val delayslot_line = RegInit(0.U.asTypeOf(new BufferUnit())) - when(io.do_flush && io.delay_sel_flush && !io.flush_delay_slot && io.icache_stall && (io.empty || io.almost_empty)) { - delayslot_stall := true.B - }.elsewhen(delayslot_stall && io.wen(0)) { - delayslot_stall := false.B - } - - when(io.do_flush && !io.flush_delay_slot && io.delay_sel_flush) { - when(io.execute_delay_flush) { - delayslot_enable := true.B - delayslot_line := Mux(io.empty, io.write(0), buffer(deq_ptr)) - }.elsewhen(io.decoder_delay_flush) { - delayslot_enable := true.B - delayslot_line := Mux(io.almost_empty, io.write(0), buffer(deq_ptr + 1.U)) - }.otherwise { - delayslot_enable := false.B - } - }.elsewhen(!delayslot_stall && io.ren(0)) { - delayslot_enable := false.B - } - // * deq * // io.read(0) := MuxCase( buffer(deq_ptr), Seq( - delayslot_enable -> delayslot_line, - io.empty -> 0.U.asTypeOf(new BufferUnit()), - io.almost_empty -> buffer(deq_ptr), - ), + io.empty -> 0.U.asTypeOf(new BufferUnit()), + io.almost_empty -> buffer(deq_ptr) + ) ) io.read(1) := MuxCase( buffer(deq_ptr + 1.U), Seq( - (delayslot_enable || io.empty || io.almost_empty) -> 0.U.asTypeOf(new BufferUnit()), - ), + (io.empty || io.almost_empty) -> 0.U.asTypeOf(new BufferUnit()) + ) ) val deq_num = MuxCase( 0.U, Seq( - (io.empty || delayslot_enable) -> 0.U, - io.ren(1) -> 2.U, - io.ren(0) -> 1.U, - ), + (io.empty) -> 0.U, + io.ren(1) -> 2.U, + io.ren(0) -> 1.U + ) ) when(io.do_flush) { diff --git a/chisel/playground/src/pipeline/fetch/PreDecoder.scala b/chisel/playground/src/pipeline/fetch/PreDecoder.scala deleted file mode 100644 index cefd89a..0000000 --- a/chisel/playground/src/pipeline/fetch/PreDecoder.scala +++ /dev/null @@ -1,94 +0,0 @@ -package cpu.pipeline.fetch - -import chisel3._ -import chisel3.util._ -import cpu.defines.Const._ -import cpu.CpuConfig -import cpu.pipeline.fetch.BufferUnit - -class BufferEnq extends Bundle { - val valid = Bool() - val jump_branch_inst = Bool() - val op = UInt(OP_WID.W) - val is_in_delayslot = Bool() - - val tlb = new Bundle { - val refill = Bool() - val invalid = Bool() - } - val inst = UInt(32.W) - val pc = UInt(32.W) -} - -class PreDecoder(implicit val config: CpuConfig) extends Module { - val io = IO(new Bundle { - val flush = Input(Bool()) - - val full = new Bundle { - val fromInstFifo = Input(Bool()) - val toIcache = Output(Bool()) - } - val read = Output(Vec(config.instFetchNum, new BufferEnq())) - - val wen = Input(Vec(config.instFetchNum, Bool())) - val write = Input(Vec(config.instFetchNum, new BufferUnit())) - }) - - val buffer = RegInit(VecInit(Seq.fill(config.instFetchNum)(0.U.asTypeOf(new BufferEnq())))) - - for (i <- 0 until config.instFetchNum) { - when(io.wen(i) && !io.full.fromInstFifo) { - buffer(i).tlb.refill := io.write(i).tlb.refill - buffer(i).tlb.invalid := io.write(i).tlb.invalid - buffer(i).inst := io.write(i).inst - buffer(i).pc := io.write(i).pc - } - when(!io.full.fromInstFifo) { - buffer(i).valid := io.wen(i) - } - } - io.full.toIcache := io.full.fromInstFifo - - for (i <- 0 until config.instFetchNum) { - val signals: List[UInt] = ListLookup( - buffer(i).inst, - List(EXE_NOP, false.B), - Array( // 跳转指令 - J -> List(EXE_J, true.B), - JAL -> List(EXE_JAL, true.B), - JR -> List(EXE_JR, true.B), - JALR -> List(EXE_JALR, true.B), - BEQ -> List(EXE_BEQ, true.B), - BNE -> List(EXE_BNE, true.B), - BGTZ -> List(EXE_BGTZ, true.B), - BLEZ -> List(EXE_BLEZ, true.B), - BGEZ -> List(EXE_BGEZ, true.B), - BGEZAL -> List(EXE_BGEZAL, true.B), - BLTZ -> List(EXE_BLTZ, true.B), - BLTZAL -> List(EXE_BLTZAL, true.B), - ), - ) - val op :: jump_branch_inst :: Nil = signals - - io.read(i).tlb.refill := buffer(i).tlb.refill - io.read(i).tlb.invalid := buffer(i).tlb.invalid - io.read(i).inst := buffer(i).inst - io.read(i).pc := buffer(i).pc - io.read(i).valid := buffer(i).valid - io.read(i).jump_branch_inst := jump_branch_inst - io.read(i).op := op - } - - val inst0_is_in_delayslot = RegNext(buffer(config.instFetchNum - 1).jump_branch_inst) - - for (i <- 1 until config.instFetchNum) { - io.read(i).is_in_delayslot := buffer(i - 1).jump_branch_inst - } - io.read(0).is_in_delayslot := inst0_is_in_delayslot - - when(io.flush) { - for (i <- 0 until config.instFetchNum) { - buffer(i).valid := false.B - } - } -} diff --git a/chisel/playground/src/pipeline/memory/MemoryUnit.scala b/chisel/playground/src/pipeline/memory/MemoryUnit.scala index 0e9150c..1b10ad0 100644 --- a/chisel/playground/src/pipeline/memory/MemoryUnit.scala +++ b/chisel/playground/src/pipeline/memory/MemoryUnit.scala @@ -22,11 +22,6 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { val writeBackStage = Output(new MemoryUnitWriteBackUnit()) val dataMemory = new Bundle { val in = Input(new Bundle { - val tlb = new Bundle { - val invalid = Bool() - val refill = Bool() - val modify = Bool() - } val rdata = UInt(DATA_WID.W) }) val out = Output(new Bundle { @@ -66,20 +61,13 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { io.memoryStage.inst0.rd_info.wdata, ) io.writeBackStage.inst0.ex := io.memoryStage.inst0.ex - val inst0_access_mem = - (io.dataMemory.out.en && (io.dataMemory.in.tlb.invalid || io.dataMemory.in.tlb.refill) && io.memoryStage.inst0.inst_info.fusel === FU_MEM) - val inst0_tlbmod = - (io.dataMemory.in.tlb.modify && io.dataMemory.out.wen.orR && io.memoryStage.inst0.inst_info.fusel === FU_MEM) io.writeBackStage.inst0.ex.excode := MuxCase( io.memoryStage.inst0.ex.excode, Seq( (io.memoryStage.inst0.ex.excode =/= EX_NO) -> io.memoryStage.inst0.ex.excode, - inst0_access_mem -> Mux(io.dataMemory.out.wen.orR, EX_TLBS, EX_TLBL), - inst0_tlbmod -> EX_MOD, ), ) - io.writeBackStage.inst0.ex.tlb_refill := io.memoryStage.inst0.ex.tlb_refill && io.memoryStage.inst0.ex.excode === EX_TLBL || io.dataMemory.in.tlb.refill && io.memoryStage.inst0.inst_info.fusel === FU_MEM - io.writeBackStage.inst0.ex.flush_req := io.memoryStage.inst0.ex.flush_req || io.writeBackStage.inst0.ex.excode =/= EX_NO || io.writeBackStage.inst0.ex.tlb_refill + io.writeBackStage.inst0.ex.flush_req := io.memoryStage.inst0.ex.flush_req || io.writeBackStage.inst0.ex.excode =/= EX_NO io.writeBackStage.inst0.cp0 := io.memoryStage.inst0.cp0 io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc @@ -90,20 +78,13 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { io.memoryStage.inst1.rd_info.wdata, ) io.writeBackStage.inst1.ex := io.memoryStage.inst1.ex - val inst1_access_mem = - (io.dataMemory.out.en && (io.dataMemory.in.tlb.invalid || io.dataMemory.in.tlb.refill) && io.memoryStage.inst1.inst_info.fusel === FU_MEM) - val inst1_tlbmod = - (io.dataMemory.in.tlb.modify && io.dataMemory.out.wen.orR && io.memoryStage.inst1.inst_info.fusel === FU_MEM) io.writeBackStage.inst1.ex.excode := MuxCase( io.memoryStage.inst1.ex.excode, Seq( (io.memoryStage.inst1.ex.excode =/= EX_NO) -> io.memoryStage.inst1.ex.excode, - inst1_access_mem -> Mux(io.dataMemory.out.wen.orR, EX_TLBS, EX_TLBL), - inst1_tlbmod -> EX_MOD, ), ) - io.writeBackStage.inst1.ex.tlb_refill := io.memoryStage.inst1.ex.tlb_refill && io.memoryStage.inst1.ex.excode === EX_TLBL || io.dataMemory.in.tlb.refill && io.memoryStage.inst1.inst_info.fusel === FU_MEM - io.writeBackStage.inst1.ex.flush_req := io.memoryStage.inst1.ex.flush_req || io.writeBackStage.inst1.ex.excode =/= EX_NO || io.writeBackStage.inst1.ex.tlb_refill + io.writeBackStage.inst1.ex.flush_req := io.memoryStage.inst1.ex.flush_req || io.writeBackStage.inst1.ex.excode =/= EX_NO io.cp0.in.inst(0).pc := io.writeBackStage.inst0.pc io.cp0.in.inst(0).ex := io.writeBackStage.inst0.ex