我正在尝试修改累加器生成器示例以一次加载两个访问,例如从一个数组加载两个索引。我所做的只是当第一个内存响应进来时,我增加一个计数器并发送另一个。但我得到一个缓存异常。我的加速器代码如下。它与累加器只有一些变化。
我也感到困惑的是,第一次访问有效并且我得到了数据,而现在,我使用与第二次访问相同的地址。那么为什么这行不通呢?
val regfile = Mem(4, UInt(width = 16.W))
val busy = Reg(init = Vec.fill(4){Bool(false)})
val cmd = Queue(io.cmd)
val funct = cmd.bits.inst.funct
val addr = cmd.bits.rs2(log2Up(4)-1,0)
val doLoad = funct === UInt(0)
val doRead = funct === UInt(1)
val doWrite = funct === UInt(2)
val doAccum = funct === UInt(3)
val memRespTag = io.mem.resp.bits.tag
// datapath
val addend = cmd.bits.rs1
val accum = regfile(addr)
val wdata = Mux(doWrite, addend, accum + addend)
val counter = RegInit(0.U)
when (cmd.fire() && (doWrite || doAccum)) {
regfile(addr) := wdata
}
when (io.mem.resp.valid) {
regfile(memRespTag) := io.mem.resp.bits.data
busy(memRespTag) := Bool(false)
when(counter === 0.U) {
counter := 1.U
}
}
// control
when (io.mem.req.fire()) {
busy(counter) := Bool(true)
}
val doResp = cmd.bits.inst.xd
val stallReg = busy(counter)
val stallLoad = doLoad && !io.mem.req.ready
val stallResp = doResp && !io.resp.ready
cmd.ready := !stallReg && !stallLoad && !stallResp // command resolved if no stalls AND not issuing a load that will need a request
// PROC RESPONSE INTERFACE
io.resp.valid := cmd.valid && doResp && !stallReg && !stallLoad
// valid response if valid command, need a response, and no stalls
io.resp.bits.rd := cmd.bits.inst.rd
// Must respond with the appropriate tag or undefined behavior
io.resp.bits.data := accum
// Semantics is to always send out prior accumulator register value
io.busy := cmd.valid || busy.reduce(_||_)
// Be busy when have pending memory requests or committed possibility of pending requests
io.interrupt := Bool(false)
// Set this true to trigger an interrupt on the processor (please refer to supervisor documentation)
io.mem.req.valid := ((cmd.valid && doLoad) || counter === 1.U ) && !stallReg && !stallResp
io.mem.req.bits.addr := addend
io.mem.req.bits.tag := addr
io.mem.req.bits.cmd := M_XRD // perform a load (M_XWR for stores)
io.mem.req.bits.size := log2Ceil(8).U
io.mem.req.bits.signed := Bool(false)
io.mem.req.bits.data := Bits(0) // we're not performing any stores...
io.mem.req.bits.phys := Bool(false)