提交 09c23835 编写于 作者: Z Zihao Yu

refactor AddrBits and DataBits for the whole system

上级 6094e777
......@@ -5,7 +5,9 @@ package bus.axi4
import chisel3._
import chisel3.util._
object AXI4Parameters {
import noop.HasNOOPParameter
object AXI4Parameters extends HasNOOPParameter {
// These are all fixed by the AXI4 standard:
val lenBits = 8
val sizeBits = 3
......@@ -17,8 +19,8 @@ object AXI4Parameters {
// These are not fixed:
val idBits = 1
val addrBits = 64
val dataBits = 64
val addrBits = AddrBits
val dataBits = DataBits
val userBits = 1
def CACHE_RALLOCATE = 8.U(cacheBits.W)
......
......@@ -4,50 +4,36 @@ import chisel3._
import chisel3.util._
import chisel3.util.experimental.loadMemoryFromFile
class DistributedMem(memByte: Int, dualPort: Boolean, delayCycles: Int = 0, dataFile: String = "") extends Module {
import noop.HasNOOPParameter
class DistributedMem(memByte: Int, dualPort: Boolean, delayCycles: Int = 0, dataFile: String = "")
extends Module with HasNOOPParameter {
val io = IO(new Bundle {
val rw = Flipped(new SimpleBusUC)
val ro = Flipped(new SimpleBusUC)
})
val useTreadle = false
val wordNum = memByte / 8
val nBank = XLEN / 8
val memAddrBits = log2Up(wordNum)
def Index(addr: UInt): UInt = addr(memAddrBits + 2 - 1, 2)
val rwIdx = Index(io.rw.req.bits.addr)
val roIdx = Index(io.ro.req.bits.addr)
val wen = io.rw.isWrite()
val wdataVec = VecInit.tabulate(8) { i => io.rw.req.bits.wdata(8 * (i + 1) - 1, 8 * i) }
val wmask = VecInit.tabulate(8) { i => io.rw.req.bits.wmask(i).toBool }
val wdataVec = VecInit.tabulate(nBank) { i => io.rw.req.bits.wdata(8 * (i + 1) - 1, 8 * i) }
val wmask = VecInit.tabulate(nBank) { i => io.rw.req.bits.wmask(i).toBool }
val rwData = Wire(UInt(64.W))
val roData = Wire(UInt(64.W))
val rwData = Wire(UInt(XLEN.W))
val roData = Wire(UInt(XLEN.W))
if (useTreadle) {
val mem = Mem(memByte, UInt(8.W))
if (dataFile != "")
loadMemoryFromFile(mem, dataFile)
def read(idx: UInt) = Cat(mem(idx + 7.U), mem(idx + 6.U), mem(idx + 5.U), mem(idx + 4.U), mem(idx + 3.U), mem(idx + 2.U), mem(idx + 1.U), mem(idx + 0.U))
val mem = Mem(wordNum, Vec(nBank, UInt(8.W)))
if (dataFile != "")
loadMemoryFromFile(mem, dataFile)
rwData := read(rwIdx << 3)
roData := read(roIdx << 3)
wmask.zipWithIndex.map { case(m, i) => {
when (m && wen) {
mem((rwIdx << 3) + i.U) := wdataVec(i)
}
}}
}
else {
val mem = Mem(wordNum, Vec(8, UInt(8.W)))
if (dataFile != "")
loadMemoryFromFile(mem, dataFile)
rwData := Cat(mem.read(rwIdx).reverse)
roData := Cat(mem.read(roIdx).reverse)
when (wen) { mem.write(rwIdx, wdataVec, wmask) }
}
rwData := Cat(mem.read(rwIdx).reverse)
roData := Cat(mem.read(roIdx).reverse)
when (wen) { mem.write(rwIdx, wdataVec, wmask) }
def readPort(p: SimpleBusUC, rdata: UInt) = {
val s_idle :: s_reading :: Nil = Enum(2)
......
......@@ -3,9 +3,12 @@ package bus.simplebus
import chisel3._
import chisel3.util._
import noop.HasNOOPParameter
import utils._
import bus.axi4._
sealed abstract class SimpleBusBundle extends Bundle with HasNOOPParameter
object SimpleBusCmd {
// req
// hit | miss
......@@ -24,15 +27,15 @@ object SimpleBusCmd {
def apply() = UInt(4.W)
}
class SimpleBusReqBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
class SimpleBusReqBundle(userBits: Int = 0) extends SimpleBusBundle {
val addr = Output(UInt(64.W))
val size = Output(UInt(3.W))
val cmd = Output(SimpleBusCmd())
val wmask = Output(UInt((dataBits / 8).W))
val wdata = Output(UInt(dataBits.W))
val wmask = Output(UInt((DataBits / 8).W))
val wdata = Output(UInt(DataBits.W))
val user = Output(UInt(userBits.W))
override def cloneType = new SimpleBusReqBundle(dataBits, userBits).asInstanceOf[this.type]
override def cloneType = new SimpleBusReqBundle(userBits).asInstanceOf[this.type]
override def toPrintable: Printable = {
p"addr = 0x${Hexadecimal(addr)}, cmd = ${cmd}, size = ${size}, " +
p"wmask = 0x${Hexadecimal(wmask)}, wdata = 0x${Hexadecimal(wdata)}"
......@@ -45,12 +48,12 @@ class SimpleBusReqBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
def isProbe() = cmd === SimpleBusCmd.probe
}
class SimpleBusRespBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
class SimpleBusRespBundle(userBits: Int = 0) extends SimpleBusBundle {
val cmd = Output(SimpleBusCmd())
val rdata = Output(UInt(dataBits.W))
val rdata = Output(UInt(DataBits.W))
val user = Output(UInt(userBits.W))
override def cloneType = new SimpleBusRespBundle(dataBits, userBits).asInstanceOf[this.type]
override def cloneType = new SimpleBusRespBundle(userBits).asInstanceOf[this.type]
override def toPrintable: Printable = p"rdata = ${Hexadecimal(rdata)}, cmd = ${cmd}"
def isReadLast() = cmd === SimpleBusCmd.readLast
......@@ -59,11 +62,11 @@ class SimpleBusRespBundle(dataBits: Int, userBits: Int = 0) extends Bundle {
}
// Uncache
class SimpleBusUC(dataBits: Int = 64, userBits: Int = 0) extends Bundle {
val req = Decoupled(new SimpleBusReqBundle(dataBits, userBits))
val resp = Flipped(Decoupled(new SimpleBusRespBundle(dataBits, userBits)))
class SimpleBusUC(userBits: Int = 0) extends SimpleBusBundle {
val req = Decoupled(new SimpleBusReqBundle(userBits))
val resp = Flipped(Decoupled(new SimpleBusRespBundle(userBits)))
override def cloneType = new SimpleBusUC(dataBits, userBits).asInstanceOf[this.type]
override def cloneType = new SimpleBusUC(userBits).asInstanceOf[this.type]
def isWrite() = req.valid && req.bits.isWrite()
def isRead() = req.valid && req.bits.isRead()
def toAXI4Lite() = SimpleBus2AXI4Converter(this, new AXI4Lite)
......@@ -76,9 +79,9 @@ class SimpleBusUC(dataBits: Int = 64, userBits: Int = 0) extends Bundle {
}
// Cache
class SimpleBusC(dataBits: Int = 64, userBits: Int = 0) extends Bundle {
val mem = new SimpleBusUC(dataBits, userBits)
val coh = Flipped(new SimpleBusUC(dataBits, userBits))
class SimpleBusC(userBits: Int = 0) extends SimpleBusBundle {
val mem = new SimpleBusUC(userBits)
val coh = Flipped(new SimpleBusUC(userBits))
override def cloneType = new SimpleBusC(dataBits, userBits).asInstanceOf[this.type]
override def cloneType = new SimpleBusC(userBits).asInstanceOf[this.type]
}
......@@ -4,27 +4,28 @@ import chisel3._
import chisel3.util._
import chisel3.util.experimental.loadMemoryFromFile
import noop.HasNOOPParameter
import bus.axi4._
import utils._
class RAMHelper(memByte: Int) extends BlackBox {
class RAMHelper(memByte: Int) extends BlackBox with HasNOOPParameter {
val io = IO(new Bundle {
val clk = Input(Clock())
val rIdx = Input(UInt(64.W))
val rdata = Output(UInt(64.W))
val wIdx = Input(UInt(64.W))
val wdata = Input(UInt(64.W))
val wmask = Input(UInt(64.W))
val rIdx = Input(UInt(DataBits.W))
val rdata = Output(UInt(DataBits.W))
val wIdx = Input(UInt(DataBits.W))
val wdata = Input(UInt(DataBits.W))
val wmask = Input(UInt(DataBits.W))
val wen = Input(Bool())
})
}
class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, beatBytes: Int = 8,
useBlackBox: Boolean = false) extends AXI4SlaveModule(_type) {
class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int,
useBlackBox: Boolean = false) extends AXI4SlaveModule(_type) with HasNOOPParameter {
val offsetBits = log2Up(memByte)
val offsetMask = (1 << offsetBits) - 1
def index(addr: UInt) = (addr & offsetMask.U) >> log2Ceil(beatBytes)
def index(addr: UInt) = (addr & offsetMask.U) >> log2Ceil(DataBytes)
def inRange(idx: UInt) = idx < (memByte / 8).U
val wIdx = index(waddr) + writeBeatCnt
......@@ -37,13 +38,13 @@ class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, beatBytes: Int =
mem.io.rIdx := rIdx
mem.io.wIdx := wIdx
mem.io.wdata := in.w.bits.data
mem.io.wmask := Cat(in.w.bits.strb.asBools.map(Mux(_, 0xff.U, 0.U)).reverse)
mem.io.wmask := Cat(in.w.bits.strb.asBools.map(Fill(8, _)).reverse)
mem.io.wen := wen
mem.io.rdata
} else {
val mem = Mem(memByte / beatBytes, Vec(beatBytes, UInt(8.W)))
val mem = Mem(memByte / DataBytes, Vec(DataBytes, UInt(8.W)))
val wdata = VecInit.tabulate(beatBytes) { i => in.w.bits.data(8*(i+1)-1, 8*i) }
val wdata = VecInit.tabulate(DataBytes) { i => in.w.bits.data(8*(i+1)-1, 8*i) }
when (wen) { mem.write(wIdx, wdata, in.w.bits.strb.asBools) }
Cat(mem.read(rIdx).reverse)
......
......@@ -3,10 +3,12 @@ package device
import chisel3._
import chisel3.util._
import noop.HasNOOPParameter
import bus.axi4._
import utils._
abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _extra: B = null) extends Module {
abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _extra: B = null)
extends Module with HasNOOPParameter {
val io = IO(new Bundle{
val in = Flipped(_type)
val extra = if (_extra != null) Some(Flipped(Flipped(_extra))) else None
......@@ -14,7 +16,7 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e
val in = io.in
def genWdata(originData: UInt) = {
val fullMask = Cat(in.w.bits.strb.toBools.map(Mux(_, 0xff.U(8.W), 0x0.U(8.W))).reverse)
val fullMask = Cat(in.w.bits.strb.toBools.map(Fill(8, _)).reverse)
(originData & ~fullMask) | (in.w.bits.data & fullMask)
}
val raddr = Wire(UInt())
......@@ -25,7 +27,7 @@ abstract class AXI4SlaveModule[T <: AXI4Lite, B <: Data](_type :T = new AXI4, _e
val beatCnt = Counter(256)
val len = HoldUnless(axi4.ar.bits.len, axi4.ar.fire())
val burst = HoldUnless(axi4.ar.bits.burst, axi4.ar.fire())
val wrapAddr = axi4.ar.bits.addr & ~(axi4.ar.bits.len.asTypeOf(UInt(64.W)) << axi4.ar.bits.size)
val wrapAddr = axi4.ar.bits.addr & ~(axi4.ar.bits.len.asTypeOf(UInt(AddrBits.W)) << axi4.ar.bits.size)
raddr := HoldUnless(wrapAddr, axi4.ar.fire())
axi4.r.bits.last := (c.value === len)
when (ren) {
......
......@@ -9,6 +9,8 @@ import bus.axi4._
import utils._
sealed trait HasCacheConst {
val AddrBits: Int
val TotalSize = 32 // Kbytes
val LineSize = 32 // byte
val LineBeats = LineSize / 8 //DATA WIDTH 64
......@@ -17,8 +19,7 @@ sealed trait HasCacheConst {
val OffsetBits = log2Up(LineSize)
val IndexBits = log2Up(Sets)
val WordIndexBits = log2Up(LineBeats)
val TagBits = 64 - OffsetBits - IndexBits
val dataBits = 64
val TagBits = AddrBits - OffsetBits - IndexBits
val debug = false
......@@ -39,38 +40,41 @@ sealed trait HasCacheConst {
def isSetConflict(a1: UInt, a2: UInt) = (a1.asTypeOf(addrBundle).index === a2.asTypeOf(addrBundle).index)
}
sealed class MetaBundle extends Bundle with HasCacheConst {
sealed abstract class CacheBundle extends Bundle with HasNOOPParameter with HasCacheConst
sealed abstract class CacheModule extends Module with HasNOOPParameter with HasCacheConst
sealed class MetaBundle extends CacheBundle {
val tag = Output(UInt(TagBits.W))
val valid = Output(Bool())
val dirty = Output(Bool())
}
sealed class MetaPipelineBundle extends Bundle with HasCacheConst {
sealed class MetaPipelineBundle extends CacheBundle {
val tag = Output(UInt(TagBits.W))
val hit = Output(Bool())
val dirty = Output(Bool())
}
sealed class DataBundle extends Bundle {
val data = Output(UInt(64.W))
sealed class DataBundle extends CacheBundle {
val data = Output(UInt(DataBits.W))
}
sealed class Stage1IO(userBits: Int = 0) extends Bundle with HasCacheConst {
val req = new SimpleBusReqBundle(dataBits = dataBits, userBits = userBits)
sealed class Stage1IO(userBits: Int = 0) extends CacheBundle {
val req = new SimpleBusReqBundle(userBits = userBits)
override def cloneType = new Stage1IO(userBits).asInstanceOf[this.type]
}
// meta read
sealed class CacheStage1(ro: Boolean, name: String, userBits: Int = 0) extends Module with HasCacheConst {
sealed class CacheStage1(ro: Boolean, name: String, userBits: Int = 0) extends CacheModule {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new SimpleBusReqBundle(dataBits, userBits)))
val in = Flipped(Decoupled(new SimpleBusReqBundle(userBits = userBits)))
val out = Decoupled(new Stage1IO(userBits))
val metaReadBus = CacheMetaArrayReadBus()
val dataReadBus = CacheDataArrayReadBus()
val s2Req = Flipped(Valid(new SimpleBusReqBundle(dataBits)))
val s3Req = Flipped(Valid(new SimpleBusReqBundle(dataBits)))
val s2Req = Flipped(Valid(new SimpleBusReqBundle))
val s3Req = Flipped(Valid(new SimpleBusReqBundle))
val s2s3Miss = Input(Bool())
})
......@@ -99,15 +103,15 @@ sealed class CacheStage1(ro: Boolean, name: String, userBits: Int = 0) extends M
io.in.ready := (!io.in.valid || io.out.fire()) && io.metaReadBus.req.ready && io.dataReadBus.req.ready
}
sealed class Stage2IO(userBits: Int = 0) extends Bundle with HasCacheConst {
val req = new SimpleBusReqBundle(dataBits, userBits)
sealed class Stage2IO(userBits: Int = 0) extends CacheBundle {
val req = new SimpleBusReqBundle(userBits = userBits)
val meta = new MetaPipelineBundle
override def cloneType = new Stage2IO(userBits).asInstanceOf[this.type]
}
// check
sealed class CacheStage2(ro: Boolean, name: String, userBits: Int = 0) extends Module with HasCacheConst {
sealed class CacheStage2(ro: Boolean, name: String, userBits: Int = 0) extends CacheModule {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new Stage1IO(userBits)))
val out = Decoupled(new Stage2IO(userBits))
......@@ -131,17 +135,17 @@ sealed class CacheStage2(ro: Boolean, name: String, userBits: Int = 0) extends M
}
// writeback
sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends Module with HasCacheConst {
sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends CacheModule {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new Stage2IO(userBits)))
val out = Decoupled(new SimpleBusRespBundle(dataBits = dataBits, userBits = userBits))
val out = Decoupled(new SimpleBusRespBundle(userBits = userBits))
val isFinish = Output(Bool())
val addr = Output(UInt(64.W))
val addr = Output(UInt(AddrBits.W))
val flush = Input(Bool())
val dataBlock = Flipped(Vec(Ways * LineBeats, new DataBundle))
val dataWriteBus = CacheDataArrayWriteBus()
val metaWriteBus = CacheMetaArrayWriteBus()
val mem = new SimpleBusUC(dataBits)
val mem = new SimpleBusUC
})
val req = io.in.bits.req
......@@ -152,7 +156,7 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
val dataBlockIdx = Wire(UInt(WordIndexBits.W))
val dataRead = io.dataBlock(dataBlockIdx).data
val wordMask = Mux(req.isWrite(), maskExpand(req.wmask), 0.U(64.W))
val wordMask = Mux(req.isWrite(), maskExpand(req.wmask), 0.U(DataBits.W))
val dataHitWriteBus = WireInit(0.U.asTypeOf(CacheDataArrayWriteBus()))
val metaHitWriteBus = WireInit(0.U.asTypeOf(CacheMetaArrayWriteBus()))
......@@ -187,12 +191,12 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
dataBlockIdx := Mux(state === s_memWriteReq, writeBeatCnt.value, addr.wordIndex)
io.mem.req.bits.wdata := dataRead
io.mem.req.bits.wmask := 0xff.U
io.mem.req.bits.wmask := Fill(DataBytes, 1.U)
io.mem.req.bits.cmd := Mux(state === s_memReadReq, SimpleBusCmd.readBurst,
Mux((writeBeatCnt.value === (LineBeats - 1).U), SimpleBusCmd.writeLast, SimpleBusCmd.writeBurst))
// critical word first
val raddr = Cat(req.addr(63, 3), 0.U(3.W))
val raddr = req.addr //Cat(req.addr(63, 3), 0.U(3.W))
// dirty block addr
val waddr = Cat(meta.tag, addr.index, 0.U(OffsetBits.W))
io.mem.req.bits.addr := Mux(state === s_memReadReq, raddr, waddr)
......@@ -300,10 +304,10 @@ sealed class CacheStage3(ro: Boolean, name: String, userBits: Int = 0) extends M
}
// probe
sealed class CacheProbeStage(ro: Boolean, name: String) extends Module with HasCacheConst {
sealed class CacheProbeStage(ro: Boolean, name: String) extends CacheModule {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new SimpleBusReqBundle(dataBits = 32)))
val out = Decoupled(new SimpleBusRespBundle(dataBits = 32))
val in = Flipped(Decoupled(new SimpleBusReqBundle))
val out = Decoupled(new SimpleBusRespBundle)
val metaReadBus = CacheMetaArrayReadBus()
val dataReadBus = CacheDataArrayReadBus()
//val metaWriteBus = CacheMetaArrayWriteBus()
......@@ -367,12 +371,12 @@ sealed class CacheProbeStage(ro: Boolean, name: String) extends Module with HasC
// FIXME: should invalidate the meta array
}
class Cache(ro: Boolean, name: String, dataBits: Int = 64, userBits: Int = 0) extends Module with HasCacheConst {
class Cache(ro: Boolean, name: String, userBits: Int = 0) extends CacheModule {
val io = IO(new Bundle {
val in = Flipped(new SimpleBusUC(dataBits, userBits))
val addr = Output(UInt(64.W))
val in = Flipped(new SimpleBusUC(userBits = userBits))
val addr = Output(UInt(AddrBits.W))
val flush = Input(UInt(2.W))
val out = new SimpleBusC(dataBits)
val out = new SimpleBusC
})
// cpu pipeline
......
......@@ -11,7 +11,9 @@ import utils._
trait HasNOOPParameter {
val XLEN = 64
val AddrBits = 64
val AddrBytes = AddrBits / 8
val DataBits = XLEN
val DataBytes = DataBits / 8
}
abstract class NOOPModule extends Module with HasNOOPParameter
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册