提交 f02b5115 编写于 作者: W William Wang

LoadQueueData: use separate data module

Now we have:
* paddrModule
* maskModule
* exceptionModule
* coredataModule (data & fwdmask)
上级 bf6b6e21
......@@ -21,18 +21,20 @@ class LQDataEntry extends XSBundle {
// Data module define
// These data modules are like SyncDataModuleTemplate, but support cam-like ops
class paddrModule(numEntries: Int, numRead: Int, numWrite: Int, numMatch: Int) extends XSModule {
class PaddrModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule with HasDCacheParameters {
val io = IO(new Bundle {
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(UInt((PAddrBits-3).W)))
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(UInt(log2Up(numEntries).W)))
val wdata = Vec(numWrite, Input(UInt((PAddrBits-3).W)))
val mdata = Vec(numMatch, Input(UInt((PAddrBits-3).W)))
val mmask = Vec(numMatch, Output(Vec(numEntries, Bool())))
val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
val rdata = Output(Vec(numRead, UInt((PAddrBits).W)))
val wen = Input(Vec(numWrite, Bool()))
val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
val wdata = Input(Vec(numWrite, UInt((PAddrBits).W)))
val violationMdata = Input(Vec(2, UInt((PAddrBits).W)))
val violationMmask = Output(Vec(2, Vec(numEntries, Bool())))
val refillMdata = Input(UInt((PAddrBits).W))
val refillMmask = Output(Vec(numEntries, Bool()))
})
val data = Mem(numEntries, UInt((PAddrBits-3).W))
val data = Reg(Vec(numEntries, UInt((PAddrBits).W)))
// read ports
for (i <- 0 until numRead) {
......@@ -47,56 +49,14 @@ class paddrModule(numEntries: Int, numRead: Int, numWrite: Int, numMatch: Int) e
}
// content addressed match
for (i <- 0 until numMatch) {
io.mmask(i) := 0.U.asBools
for (i <- 0 until 2) {
for (j <- 0 until numEntries) {
when (io.mdata(i) === data(j)) {
io.mmask(i)(j) := true.B
}
io.violationMmask(i)(j) := io.violationMdata(i)(PAddrBits-1, 3) === data(j)(PAddrBits-1, 3)
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for (i <- 0 until numWrite) {
for (j <- i+1 until numWrite) {
assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
}
}
}
class maskModule(numEntries: Int, numRead: Int, numWrite: Int, numMatch: Int) extends XSModule {
val io = IO(new Bundle {
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(UInt(8.W)))
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(UInt(log2Up(numEntries).W)))
val wdata = Vec(numWrite, Input(UInt(8.W)))
val mdata = Vec(numMatch, Input(UInt(8.W)))
val mmask = Vec(numMatch, Output(Vec(numEntries, Bool())))
})
val data = Mem(numEntries, UInt(8.W))
// read ports
for (i <- 0 until numRead) {
io.rdata(i) := data(io.raddr(i))
}
// below is the write ports (with priorities)
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
}
}
// content addressed match
for (i <- 0 until numMatch) {
io.mmask(i) := 0.U.asBools
for (j <- 0 until numEntries) {
when ((io.mdata(i) & data(j)).orR) {
io.mmask(i)(j) := true.B
}
}
for (j <- 0 until numEntries) {
io.refillMmask(j) := get_block_addr(io.refillMdata) === get_block_addr(data(j))
}
// DataModuleTemplate should not be used when there're any write conflicts
......@@ -107,21 +67,18 @@ class maskModule(numEntries: Int, numRead: Int, numWrite: Int, numMatch: Int) ex
}
}
class exceptionModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule {
class MaskModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule {
val io = IO(new Bundle {
// read
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(UInt(16.W)))
// address indexed write
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(UInt(log2Up(numEntries).W)))
val wdata = Vec(numWrite, Input(UInt(16.W)))
// masked write
val mwmask = Input(Vec(numEntries, Bool()))
val mwdata = Input(UInt(16.W))
val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
val rdata = Output(Vec(numRead, UInt(8.W)))
val wen = Input(Vec(numWrite, Bool()))
val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
val wdata = Input(Vec(numWrite, UInt(8.W)))
val violationMdata = Input(Vec(2, UInt((PAddrBits).W)))
val violationMmask = Output(Vec(2, Vec(numEntries, Bool())))
})
val data = Mem(numEntries, UInt(16.W))
val data = Reg(Vec(numEntries, UInt(8.W)))
// read ports
for (i <- 0 until numRead) {
......@@ -135,10 +92,10 @@ class exceptionModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMo
}
}
// masked write
for (j <- 0 until numEntries) {
when (io.mwmask(j)) {
data(j) := io.mwdata
// content addressed match
for (i <- 0 until 2) {
for (j <- 0 until numEntries) {
io.violationMmask(i)(j) := (io.violationMdata(i) & data(j)).orR
}
}
......@@ -150,26 +107,34 @@ class exceptionModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMo
}
}
class coredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule {
class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule with HasDCacheParameters {
val io = IO(new Bundle {
// data io
// read
val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W)))
val rdata = Vec(numRead, Output(UInt(XLEN.W)))
val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
val rdata = Output(Vec(numRead, UInt(XLEN.W)))
// address indexed write
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(UInt(log2Up(numEntries).W)))
val wdata = Vec(numWrite, Input(UInt(XLEN.W)))
val wen = Input(Vec(numWrite, Bool()))
val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
val wdata = Input(Vec(numWrite, UInt(XLEN.W)))
// masked write
val mwmask = Input(Vec(numEntries, Bool()))
val mwdata = Input(UInt(XLEN.W))
val refillData = Input(UInt((cfg.blockBytes * 8).W))
// fwdMask io
val fwdMaskWdata = Vec(numWrite, Input(UInt(8.W)))
val fwdMaskWdata = Input(Vec(numWrite, UInt(8.W)))
val fwdMaskWen = Input(Vec(numWrite, Bool()))
// fwdMaskWaddr = waddr
// paddr io
// 3 bits in paddr need to be stored in CoredataModule for refilling
val paddrWdata = Input(Vec(numWrite, UInt((PAddrBits).W)))
val paddrWen = Input(Vec(numWrite, Bool()))
})
val data = Mem(numEntries, UInt(XLEN.W))
val fwdMask = Mem(numEntries, UInt(8.W))
val data = Reg(Vec(numEntries, UInt(XLEN.W)))
val fwdMask = Reg(Vec(numEntries, UInt(8.W)))
val wordIndex = Reg(Vec(numEntries, UInt((blockOffBits - wordOffBits).W)))
// read ports
for (i <- 0 until numRead) {
......@@ -181,8 +146,15 @@ class coredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
}
when (io.fwdMaskWen(i)) {
fwdMask(io.waddr(i)) := io.fwdMaskWdata(i)
}
when (io.paddrWen(i)) {
wordIndex(io.waddr(i)) := get_word(io.paddrWdata(i))
}
}
// masked write
// refill missed load
def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
......@@ -193,9 +165,14 @@ class coredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
res.asUInt
}
// split dcache result into words
val words = VecInit((0 until blockWords) map { i => io.refillData(DataBits * (i + 1) - 1, DataBits * i)})
// refill data according to matchMask, refillMask and refill.vald
for (j <- 0 until numEntries) {
when (io.mwmask(j)) {
data(j) := mergeRefillData(io.mwdata, data(j), fwdMask(j))
val refillData = words(wordIndex(j)) // TODO
data(j) := mergeRefillData(refillData, data(j), fwdMask(j))
}
}
......@@ -255,26 +232,96 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
// use "this.refill.wen(ldIdx) := true.B" instead
})
val data = Reg(Vec(size, new LQDataEntry))
// val data = Reg(Vec(size, new LQDataEntry))
// data module
val paddrModule = Module(new PaddrModule(size, numRead = 3, numWrite = 2))
val maskModule = Module(new MaskModule(size, numRead = 3, numWrite = 2))
val exceptionModule = Module(new AsyncDataModuleTemplate(UInt(16.W), size, numRead = 3, numWrite = 2))
val coredataModule = Module(new CoredataModule(size, numRead = 3, numWrite = 3))
// read data
// read port 0 -> wbNumRead-1
(0 until wbNumRead).map(i => {
io.wb.rdata(i) := data(io.wb.raddr(i))
paddrModule.io.raddr(i) := io.wb.raddr(i)
maskModule.io.raddr(i) := io.wb.raddr(i)
exceptionModule.io.raddr(i) := io.wb.raddr(i)
coredataModule.io.raddr(i) := io.wb.raddr(i)
io.wb.rdata(i).paddr := paddrModule.io.rdata(i)
io.wb.rdata(i).mask := maskModule.io.rdata(i)
io.wb.rdata(i).data := coredataModule.io.rdata(i)
io.wb.rdata(i).exception := exceptionModule.io.rdata(i)
io.wb.rdata(i).fwdMask := DontCare
})
io.uncache.rdata := data(io.uncache.raddr)
// writeback to lq/sq
// read port wbNumRead
paddrModule.io.raddr(wbNumRead) := io.uncache.raddr
maskModule.io.raddr(wbNumRead) := io.uncache.raddr
exceptionModule.io.raddr(wbNumRead) := io.uncache.raddr
coredataModule.io.raddr(wbNumRead) := io.uncache.raddr
io.uncache.rdata.paddr := paddrModule.io.rdata(wbNumRead)
io.uncache.rdata.mask := maskModule.io.rdata(wbNumRead)
io.uncache.rdata.data := exceptionModule.io.rdata(wbNumRead)
io.uncache.rdata.exception := coredataModule.io.rdata(wbNumRead)
io.uncache.rdata.fwdMask := DontCare
// write data
// write port 0 -> wbNumWrite-1
(0 until wbNumWrite).map(i => {
paddrModule.io.wen(i) := false.B
maskModule.io.wen(i) := false.B
exceptionModule.io.wen(i) := false.B
coredataModule.io.wen(i) := false.B
coredataModule.io.fwdMaskWen(i) := false.B
coredataModule.io.paddrWen(i) := false.B
paddrModule.io.waddr(i) := io.wb.waddr(i)
maskModule.io.waddr(i) := io.wb.waddr(i)
exceptionModule.io.waddr(i) := io.wb.waddr(i)
coredataModule.io.waddr(i) := io.wb.waddr(i)
paddrModule.io.wdata(i) := io.wb.wdata(i).paddr
maskModule.io.wdata(i) := io.wb.wdata(i).mask
exceptionModule.io.wdata(i) := io.wb.wdata(i).exception
coredataModule.io.wdata(i) := io.wb.wdata(i).data
coredataModule.io.fwdMaskWdata(i) := io.wb.wdata(i).fwdMask.asUInt
coredataModule.io.paddrWdata(i) := io.wb.wdata(i).paddr
when(io.wb.wen(i)){
data(io.wb.waddr(i)) := io.wb.wdata(i)
paddrModule.io.wen(i) := true.B
maskModule.io.wen(i) := true.B
exceptionModule.io.wen(i) := true.B
coredataModule.io.wen(i) := true.B
coredataModule.io.fwdMaskWen(i) := true.B
coredataModule.io.paddrWen(i) := true.B
}
})
// write port wbNumWrite
// exceptionModule.io.wen(wbNumWrite) := false.B
coredataModule.io.wen(wbNumWrite) := io.uncache.wen
coredataModule.io.fwdMaskWen(wbNumWrite) := false.B
coredataModule.io.paddrWen(wbNumWrite) := false.B
when(io.uncache.wen){
data(io.uncache.waddr).data := io.uncache.wdata
}
coredataModule.io.waddr(wbNumWrite) := io.uncache.waddr
coredataModule.io.fwdMaskWdata(wbNumWrite) := DontCare
coredataModule.io.paddrWdata(wbNumWrite) := DontCare
coredataModule.io.wdata(wbNumWrite) := io.uncache.wdata
// mem access violation check, gen violationMask
(0 until StorePipelineWidth).map(i => {
paddrModule.io.violationMdata(i) := io.violation(i).paddr
maskModule.io.violationMdata(i) := io.violation(i).mask
io.violation(i).violationMask := (paddrModule.io.violationMmask(i).asUInt & maskModule.io.violationMmask(i).asUInt).asBools
// VecInit((0 until size).map(j => {
// val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
// val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k))
// Cat(violationVec).orR() && addrMatch
// }))
})
// refill missed load
def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
val res = Wire(Vec(8, UInt(8.W)))
......@@ -284,32 +331,19 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
res.asUInt
}
// split dcache result into words
val words = VecInit((0 until blockWords) map { i => io.refill.data(DataBits * (i + 1) - 1, DataBits * i)})
// gen paddr match mask
paddrModule.io.refillMdata := io.refill.paddr
(0 until size).map(i => {
io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr)
io.refill.matchMask := paddrModule.io.refillMmask
// io.refill.matchMask(i) := get_block_addr(data(i).paddr) === get_block_addr(io.refill.paddr)
})
// refill data according to matchMask, refillMask and refill.valid
coredataModule.io.refillData := io.refill.data
(0 until size).map(i => {
when(io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)){
val refillData = words(get_word(data(i).paddr))
data(i).data := mergeRefillData(refillData, data(i).data.asUInt, data(i).fwdMask.asUInt)
XSDebug("miss resp: pos %d addr %x data %x + %x(%b)\n", i.U, data(i).paddr, refillData, data(i).data.asUInt, data(i).fwdMask.asUInt)
}
coredataModule.io.mwmask(i) := io.refill.valid && io.refill.matchMask(i) && io.refill.refillMask(i)
})
// mem access violation check, gen violationMask
(0 until StorePipelineWidth).map(i => {
io.violation(i).violationMask := VecInit((0 until size).map(j => {
val addrMatch = io.violation(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
val violationVec = (0 until 8).map(k => data(j).mask(k) && io.violation(i).mask(k))
Cat(violationVec).orR() && addrMatch
}))
})
// debug data read
io.debug := data
io.debug := DontCare
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册