未验证 提交 52eaafb4 编写于 作者: Y Yinan Xu 提交者: GitHub

Merge pull request #426 from RISCVERS/trace-debug

Trace debug
...@@ -13,6 +13,10 @@ trait HasSbufferCst extends HasXSParameter { ...@@ -13,6 +13,10 @@ trait HasSbufferCst extends HasXSParameter {
def s_prepare = 2.U(2.W) def s_prepare = 2.U(2.W)
def s_inflight = 3.U(2.W) def s_inflight = 3.U(2.W)
val evictCycle = 8192
require(isPow2(evictCycle))
val countBits = 1 + log2Up(evictCycle)
val SbufferIndexWidth: Int = log2Up(StoreBufferSize) val SbufferIndexWidth: Int = log2Up(StoreBufferSize)
// paddr = tag + offset // paddr = tag + offset
val CacheLineBytes: Int = CacheLineSize / 8 val CacheLineBytes: Int = CacheLineSize / 8
...@@ -37,7 +41,6 @@ class SbufferLine extends SbufferBundle { ...@@ -37,7 +41,6 @@ class SbufferLine extends SbufferBundle {
class ChooseReplace(nWay: Int) extends XSModule { class ChooseReplace(nWay: Int) extends XSModule {
val io = IO(new Bundle{ val io = IO(new Bundle{
val mask = Vec(nWay, Input(Bool())) val mask = Vec(nWay, Input(Bool()))
val fire = Input(Bool())
val way = Output(UInt(nWay.W)) val way = Output(UInt(nWay.W))
val flush = Input(Bool()) val flush = Input(Bool())
}) })
...@@ -113,11 +116,11 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -113,11 +116,11 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val buffer = Mem(StoreBufferSize, new SbufferLine) val buffer = Mem(StoreBufferSize, new SbufferLine)
val stateVec = RegInit(VecInit(Seq.fill(StoreBufferSize)(s_invalid))) val stateVec = RegInit(VecInit(Seq.fill(StoreBufferSize)(s_invalid)))
val cohCount = Reg(Vec(StoreBufferSize, UInt(countBits.W)))
/* /*
idle --[flush]--> drian_sbuffer --[buf empty]--> idle idle --[flush]--> drian_sbuffer --[buf empty]--> idle
--[buf full]--> replace --[dcache resp]--> idle --[buf full]--> replace --[dcache resp]--> idle
*/ */
val x_idle :: x_drain_sbuffer :: x_replace :: Nil = Enum(3) val x_idle :: x_drain_sbuffer :: x_replace :: Nil = Enum(3)
val sbuffer_state = RegInit(x_idle) val sbuffer_state = RegInit(x_idle)
...@@ -147,7 +150,6 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -147,7 +150,6 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val invalidCount = RegInit(StoreBufferSize.U((log2Up(StoreBufferSize) + 1).W)) val invalidCount = RegInit(StoreBufferSize.U((log2Up(StoreBufferSize) + 1).W))
val validCount = RegInit(0.U((log2Up(StoreBufferSize) + 1).W)) val validCount = RegInit(0.U((log2Up(StoreBufferSize) + 1).W))
val full = invalidCount === 0.U val full = invalidCount === 0.U
// val oneSpace = invalidCount === 1.U
val bufferRead = VecInit((0 until StoreBufferSize).map(i => buffer(i))) val bufferRead = VecInit((0 until StoreBufferSize).map(i => buffer(i)))
val stateRead = VecInit((0 until StoreBufferSize).map(i => stateVec(i))) val stateRead = VecInit((0 until StoreBufferSize).map(i => stateVec(i)))
...@@ -168,8 +170,7 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -168,8 +170,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val lru = Module(new ChooseReplace(StoreBufferSize)) val lru = Module(new ChooseReplace(StoreBufferSize))
val evictionIdx = lru.io.way val evictionIdx = lru.io.way
lru.io.fire := false.B
lru.io.mask := stateRead.map(_ === s_valid) lru.io.mask := stateRead.map(_ === s_valid)
val tags = io.in.map(in => getTag(in.bits.addr)) val tags = io.in.map(in => getTag(in.bits.addr))
...@@ -209,6 +210,7 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -209,6 +210,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
def wordReqToBufLine(req: DCacheWordReq, tag: UInt, insertIdx: UInt, wordOffset: UInt, flushMask: Bool): Unit = { def wordReqToBufLine(req: DCacheWordReq, tag: UInt, insertIdx: UInt, wordOffset: UInt, flushMask: Bool): Unit = {
stateUpdate(insertIdx) := s_valid stateUpdate(insertIdx) := s_valid
tagUpdate(insertIdx) := tag tagUpdate(insertIdx) := tag
cohCount(insertIdx) := 0.U
when(flushMask){ when(flushMask){
for(j <- 0 until CacheLineWords){ for(j <- 0 until CacheLineWords){
...@@ -227,6 +229,7 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -227,6 +229,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
} }
def mergeWordReq(req: DCacheWordReq, mergeIdx:UInt, wordOffset:UInt): Unit = { def mergeWordReq(req: DCacheWordReq, mergeIdx:UInt, wordOffset:UInt): Unit = {
cohCount(mergeIdx) := 0.U
for(i <- 0 until DataBytes){ for(i <- 0 until DataBytes){
when(req.mask(i)){ when(req.mask(i)){
maskUpdate(mergeIdx)(wordOffset)(i) := true.B maskUpdate(mergeIdx)(wordOffset)(i) := true.B
...@@ -264,7 +267,7 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -264,7 +267,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
for(i <- 0 until StoreBufferSize){ for(i <- 0 until StoreBufferSize){
XSDebug(stateVec(i)=/=s_invalid, XSDebug(stateVec(i)=/=s_invalid,
p"[$i] state:${stateVec(i)} buf:${bufferRead(i)}\n" p"[$i] timeout:${cohCount(i)(countBits-1)} state:${stateVec(i)} buf:${bufferRead(i)}\n"
) )
} }
...@@ -335,16 +338,14 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -335,16 +338,14 @@ class NewSbuffer extends XSModule with HasSbufferCst {
// //
// evictionEntry.bits := evictionIdx // evictionEntry.bits := evictionIdx
val prepareValid = ((do_eviction && sbuffer_state === x_replace)|| (sbuffer_state === x_drain_sbuffer)) && val prepareValid = ((do_eviction && sbuffer_state === x_replace) || (sbuffer_state === x_drain_sbuffer)) &&
stateVec(evictionIdx)===s_valid && stateVec(evictionIdx)===s_valid &&
noSameBlockInflight(evictionIdx) noSameBlockInflight(evictionIdx)
when(prepareValid){ when(prepareValid){
stateVec(evictionIdx) := s_prepare stateVec(evictionIdx) := s_prepare
lru.io.fire := true.B
} }
val prepareMask = stateVec.map(s => s === s_prepare) val prepareMask = stateVec.map(s => s === s_prepare)
val (prepareIdx, prepareEn) = PriorityEncoderWithFlag(prepareMask) val (prepareIdx, prepareEn) = PriorityEncoderWithFlag(prepareMask)
...@@ -380,6 +381,21 @@ class NewSbuffer extends XSModule with HasSbufferCst { ...@@ -380,6 +381,21 @@ class NewSbuffer extends XSModule with HasSbufferCst {
XSDebug(p"needSpace[$needSpace] invalidCount[$invalidCount] validCount[$validCount]\n") XSDebug(p"needSpace[$needSpace] invalidCount[$invalidCount] validCount[$validCount]\n")
//-------------------------cohCount-----------------------------
// insert and merge: cohCount=0
// every cycle cohCount+=1
// if cohCount(countBits-1)==1,evict
for(i <- 0 until StoreBufferSize){
when(stateVec(i) === s_valid){
when(cohCount(i)(countBits-1)){
assert(stateVec(i) === s_valid)
stateUpdate(i) := s_prepare
}
cohCount(i) := cohCount(i)+1.U
}
}
// ---------------------- Load Data Forward --------------------- // ---------------------- Load Data Forward ---------------------
for ((forward, i) <- io.forward.zipWithIndex) { for ((forward, i) <- io.forward.zipWithIndex) {
......
...@@ -44,9 +44,87 @@ class SbufferTest extends AnyFlatSpec ...@@ -44,9 +44,87 @@ class SbufferTest extends AnyFlatSpec
top.Parameters.set(top.Parameters.debugParameters) top.Parameters.set(top.Parameters.debugParameters)
it should "random req" in { // it should "random req" in {
// test(new SbufferWapper{AddSinks()}){ c =>
//
// def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) ={
// (0 until StorePipelineWidth).map { i =>
// c.io.in(i).valid.poke(true.B)
// c.io.in(i).bits.pokePartial(chiselTypeOf(c.io.in(i).bits).Lit(
// _.mask -> mask(i),
// _.addr -> addr(i),
// _.data -> data(i)
// ))
// }
// c.clock.step(1)
// for (in <- c.io.in){ in.valid.poke(false.B)}
// }
//
// def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = {
// (0 until LoadPipelineWidth).map{ i =>
// c.io.forward(i).paddr.poke(addr(i))
// c.io.forward(i).mask.poke(mask(i))
// if(c.io.in(i).ready.peek() == true.B) {
// (0 until 8).map { j =>
// c.io.forward(i).forwardData(j).expect(data(i)(j * 8 + 7, j * 8))
// }
// }
// }
// }
//
// val TEST_SIZE = 100
// for(i <- 0 until TEST_SIZE) {
// val addr = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7ffffffff8L).U)// align to block size
// val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
// val mask = Seq.fill(StorePipelineWidth)(0xff.U)
// store_enq(addr, data, mask)
// forward_req_and_resp(addr, data, mask)
// }
// }
// }
//
// it should "sequence req" in {
// test(new SbufferWapper{AddSinks()}){ c =>
//
// def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) = {
// (0 until StorePipelineWidth).map { i =>
// c.io.in(i).valid.poke(true.B)
// c.io.in(i).bits.pokePartial(chiselTypeOf(c.io.in(i).bits).Lit(
// _.mask -> mask(i),
// _.addr -> addr(i),
// _.data -> data(i)
// ))
// }
// c.clock.step(1)
// for (in <- c.io.in){ in.valid.poke(false.B)}
// }
//
// def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = {
// (0 until LoadPipelineWidth).map{ i =>
// c.io.forward(i).paddr.poke(addr(i))
// c.io.forward(i).mask.poke(mask(i))
// if(c.io.in(i).ready.peek() == true.B) {
// (0 until 8).map { j =>
// c.io.forward(i).forwardData(j).expect(data(i)(j * 8 + 7, j * 8))
// }
// }
// }
// }
//
// val TEST_SIZE = 100
// val start_addr = Random.nextLong() & 0x7ffffffff8L
// for(i <- 0 until TEST_SIZE) {
// val addr = Seq(((i<<4) + start_addr).U,((i<<4)+8+start_addr).U)
// val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
// val mask = Seq.fill(StorePipelineWidth)(0xff.U)
// store_enq(addr, data, mask)
// forward_req_and_resp(addr, data, mask)
// }
// }
// }
it should "sbuffer coherence" in {
test(new SbufferWapper{AddSinks()}){ c => test(new SbufferWapper{AddSinks()}){ c =>
def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) ={ def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) ={
(0 until StorePipelineWidth).map { i => (0 until StorePipelineWidth).map { i =>
c.io.in(i).valid.poke(true.B) c.io.in(i).valid.poke(true.B)
...@@ -59,7 +137,6 @@ class SbufferTest extends AnyFlatSpec ...@@ -59,7 +137,6 @@ class SbufferTest extends AnyFlatSpec
c.clock.step(1) c.clock.step(1)
for (in <- c.io.in){ in.valid.poke(false.B)} for (in <- c.io.in){ in.valid.poke(false.B)}
} }
def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = { def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = {
(0 until LoadPipelineWidth).map{ i => (0 until LoadPipelineWidth).map{ i =>
c.io.forward(i).paddr.poke(addr(i)) c.io.forward(i).paddr.poke(addr(i))
...@@ -71,55 +148,16 @@ class SbufferTest extends AnyFlatSpec ...@@ -71,55 +148,16 @@ class SbufferTest extends AnyFlatSpec
} }
} }
} }
val TEST_SIZE = 10
val TEST_SIZE = 100
for(i <- 0 until TEST_SIZE) { for(i <- 0 until TEST_SIZE) {
val addr = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7ffffffff8L).U)// align to block size val addr = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7ffffffff8L).U)// align to
val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U) val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
val mask = Seq.fill(StorePipelineWidth)(0xff.U) val mask = Seq.fill(StorePipelineWidth)(0xff.U)
store_enq(addr, data, mask) store_enq(addr, data, mask)
forward_req_and_resp(addr, data, mask) forward_req_and_resp(addr, data, mask)
} }
}
}
it should "sequence req" in {
test(new SbufferWapper{AddSinks()}){ c =>
def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) = {
(0 until StorePipelineWidth).map { i =>
c.io.in(i).valid.poke(true.B)
c.io.in(i).bits.pokePartial(chiselTypeOf(c.io.in(i).bits).Lit(
_.mask -> mask(i),
_.addr -> addr(i),
_.data -> data(i)
))
}
c.clock.step(1)
for (in <- c.io.in){ in.valid.poke(false.B)}
}
def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = { c.clock.step(512 + 10)
(0 until LoadPipelineWidth).map{ i =>
c.io.forward(i).paddr.poke(addr(i))
c.io.forward(i).mask.poke(mask(i))
if(c.io.in(i).ready.peek() == true.B) {
(0 until 8).map { j =>
c.io.forward(i).forwardData(j).expect(data(i)(j * 8 + 7, j * 8))
}
}
}
}
val TEST_SIZE = 100
val start_addr = Random.nextLong() & 0x7ffffffff8L
for(i <- 0 until TEST_SIZE) {
val addr = Seq(((i<<4) + start_addr).U,((i<<4)+8+start_addr).U)
val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
val mask = Seq.fill(StorePipelineWidth)(0xff.U)
store_enq(addr, data, mask)
forward_req_and_resp(addr, data, mask)
}
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册