提交 8656be21 编写于 作者: W Wang Huizhe

noop,top: support frontend slave ports

上级 ae714544
......@@ -6,6 +6,117 @@ import chisel3.util._
import bus.axi4._
import utils._
class AXI42SimpleBusConverter() extends Module {
val io = IO(new Bundle {
val in = Flipped(new AXI4(idBits = 18))
val out = new SimpleBusUC()
})
val (axi, mem) = (io.in, io.out)
val (ar, aw, w, r, b) = (axi.ar.bits, axi.aw.bits, axi.w.bits, axi.r.bits, axi.b.bits)
val (req, resp) = (mem.req.bits, mem.resp.bits)
// Default value
val inflight_id_reg = RegInit(0.U)
val axi_na :: axi_read :: axi_write :: Nil = Enum(3)
val inflight_type = RegInit(axi_na)
private def setState(axi_type: UInt, id: UInt) = {
inflight_id_reg := id
inflight_type := axi_type;
}
private def resetState() = {
inflight_type := axi_na
inflight_id_reg := 0.U
}
private def is_inflight() = {
inflight_type =/= axi_na
}
// Default
val default_mem = 0.U.asTypeOf(new SimpleBusUC)
val default_axi = 0.U.asTypeOf(new AXI4)
req := default_mem.req.bits
r := default_axi.r.bits
b := default_axi.b.bits
// Read Path
when (axi.ar.valid) {
mem.req.valid := true.B
req.addr := ar.addr
req.cmd := Mux(ar.len === 0.U, SimpleBusCmd.read, SimpleBusCmd.readBurst)
// TODO: consider ar.burst
req.size := ar.size
req.user.foreach(_ := ar.user)
req.wmask := 0.U
req.wdata := 0.U
when (mem.req.fire) {
setState(axi_read, ar.id)
}
}
when (mem.resp.valid) {
axi.r.valid := true.B
r.data := resp.rdata
r.id := inflight_id_reg
// TODO: r.resp handling
r.resp := AXI4Parameters.RESP_OKAY
r.last := resp.isReadLast
resp.user.foreach(r.user := _)
when (axi.r.fire && resp.isReadLast) {
resetState()
}
}
// Write Path
val aw_reg = Reg(new AXI4BundleA(AXI4Parameters.idBits))
val bresp_en = RegInit(false.B)
when (axi.aw.valid && !axi.ar.valid) {
aw_reg := aw
when (axi.aw.fire) {
setState(axi_write, aw.id)
}
}
when (axi.w.valid) {
mem.req.valid := true.B
req.cmd := Mux(aw_reg.len === 0.U, SimpleBusCmd.write,
Mux(w.last, SimpleBusCmd.writeLast, SimpleBusCmd.writeBurst))
req.addr := aw_reg.addr
req.size := aw_reg.size
req.wmask := w.strb
req.wdata := w.data
req.user.foreach(_ := aw.user)
when (axi.w.fire && w.last) {
bresp_en := true.B
}
}
when (axi.b.fire) {
bresp_en := false.B
resetState()
}
// Arbitration
// Slave's ready maybe generated according to valid signal, so let valid signals go through.
mem.req.valid := axi.ar.valid || axi.w.valid
mem.resp.ready := (inflight_type === axi_read && axi.r.ready) || (inflight_type === axi_write && axi.b.ready)
axi.ar.ready := !is_inflight && mem.req.ready
axi.r.valid := inflight_type === axi_read && mem.resp.valid
// AW should be buffered so no ready is considered.
axi.aw.ready := !is_inflight && !axi.ar.valid
axi.w.ready := inflight_type === axi_write && mem.req.ready
axi.b.valid := bresp_en && mem.resp.valid
axi.b.bits.resp := AXI4Parameters.RESP_OKAY
}
class SimpleBus2AXI4Converter[OT <: AXI4Lite](outType: OT) extends Module {
val io = IO(new Bundle {
val in = Flipped(new SimpleBusUC)
......
......@@ -45,6 +45,7 @@ class NOOP(implicit val p: NOOPConfig) extends NOOPModule {
val dmem = new SimpleBusC
val mmio = new SimpleBusUC
val prefetchReq = Decoupled(new SimpleBusReqBundle)
val frontend = Flipped(new SimpleBusUC)
})
val ifu = Module(new IFU)
......@@ -88,10 +89,15 @@ class NOOP(implicit val p: NOOPConfig) extends NOOPModule {
// forward
isu.io.forward <> exu.io.forward
// Make DMA access through L1 DCache to keep coherence
val dmemXbar = Module(new SimpleBusCrossbarNto1(2))
dmemXbar.io.in(0) <> exu.io.dmem
dmemXbar.io.in(1) <> io.frontend
val mmioXbar = Module(new SimpleBusCrossbarNto1(if (HasDcache) 2 else 3))
io.imem <> Cache(ifu.io.imem, mmioXbar.io.in.take(1), Fill(2, ifu.io.flushVec(0) | ifu.io.bpFlush))(
CacheConfig(ro = true, name = "icache", userBits = AddrBits*2 + 4)) // userBits = AddrBits + BrIdxBits
io.dmem <> Cache(exu.io.dmem, mmioXbar.io.in.drop(1), "b00".U, enable = HasDcache)(CacheConfig(ro = false, name = "dcache"))
io.dmem <> Cache(dmemXbar.io.out, mmioXbar.io.in.drop(1), "b00".U, enable = HasDcache)(CacheConfig(ro = false, name = "dcache"))
io.prefetchReq.bits := exu.io.dmem.req.bits
io.prefetchReq.valid := exu.io.dmem.req.valid
io.mmio <> mmioXbar.io.out
......
......@@ -27,6 +27,7 @@ class NOOPSoC(implicit val p: NOOPConfig) extends Module with HasSoCParameter {
val io = IO(new Bundle{
val mem = new AXI4
val mmio = (if (p.FPGAPlatform) { new AXI4Lite } else { new SimpleBusUC })
val frontend = Flipped(new AXI4)
val mtip = Input(Bool())
val meip = Input(Bool())
val ila = if (p.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
......@@ -40,6 +41,10 @@ class NOOPSoC(implicit val p: NOOPConfig) extends Module with HasSoCParameter {
xbar.io.in(0) <> cohMg.io.out.mem
xbar.io.in(1) <> noop.io.dmem.mem
val axi2sb = Module(new AXI42SimpleBusConverter())
axi2sb.io.in <> io.frontend
noop.io.frontend <> axi2sb.io.out
if (HasL2cache) {
val l2cacheOut = Wire(new SimpleBusC)
val l2cacheIn = if (HasPrefetch) {
......@@ -53,7 +58,7 @@ class NOOPSoC(implicit val p: NOOPConfig) extends Module with HasSoCParameter {
xbar.io.out.resp <> l2cacheIn.resp
l2cacheIn
} else xbar.io.out
l2cacheOut <> Cache(in = l2cacheIn, mmio = 0.U.asTypeOf(new SimpleBusUC), flush = "b00".U, enable = true)(
l2cacheOut <> Cache(in = l2cacheIn, mmio = 0.U.asTypeOf(new SimpleBusUC) :: Nil, flush = "b00".U, enable = true)(
CacheConfig(name = "l2cache", totalSize = 128, cacheLevel = 2))
io.mem <> l2cacheOut.mem.toAXI4()
l2cacheOut.coh.resp.ready := true.B
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册