Fix DataCache bug (interaction between the victim buffer and the memory read request in execute/memory stages)

freeRTOS pass
This commit is contained in:
Charles Papon 2017-07-23 22:58:26 +02:00
parent 9fe4e1d54d
commit 6d117f5c81
4 changed files with 2435 additions and 2351 deletions

View file

@ -277,7 +277,7 @@ object TestsWorkspace {
}*/
// toplevel.writeBack.input(config.PC).addAttribute(Verilator.public)
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
// toplevel.children.find(_.isInstanceOf[DataCache]).get.asInstanceOf[DataCache].io.cpu.execute.addAttribute(Verilator.public)
toplevel
}
}

View file

@ -59,7 +59,7 @@ object Bypasser{
}
//shot readValid path
//short readValid path
def writeFirstMemWrap(readValid : Bool, readLastAddress : UInt, readLastData : Bits,writeValid : Bool, writeAddress : UInt, writeData : Bits,writeMask : Bits) : Bits = {
val writeHit = writeValid && writeAddress === readLastAddress
val writeSample = readValid || writeHit
@ -412,6 +412,8 @@ class DataCache(p : DataCacheConfig) extends Component{
}
val cpuMemoryStageNeedReadData = Bool()
val victim = new Area{
val requestIn = Stream(cloneable(new Bundle{
// val way = UInt(log2Up(wayCount) bits)
@ -438,7 +440,7 @@ class DataCache(p : DataCacheConfig) extends Component{
dataReadCmd.payload := request.address(lineRange) @@ readLineCmdCounter(readLineCmdCounter.high - 1 downto 0)
way.dataReadRspOneKeepAddress := True
} otherwise {
when(!dataReadRestored) {
when(!dataReadRestored && cpuMemoryStageNeedReadData) {
dataReadCmd.valid := True
dataReadCmd.payload := way.dataReadRspOneAddress //Restore stage one readed value
}
@ -447,6 +449,7 @@ class DataCache(p : DataCacheConfig) extends Component{
}
dataReadRestored clearWhen(request.ready)
io.cpu.memory.haltIt := cpuMemoryStageNeedReadData && request.valid && !dataReadRestored
//Fill the buffer with line read responses
val readLineRspCounter = Reg(UInt(log2Up(memTransactionPerLine + 1) bits)) init(0)
@ -503,8 +506,7 @@ class DataCache(p : DataCacheConfig) extends Component{
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid && request.kind === MEMORY //TODO filter request kind
io.cpu.memory.mmuBus.cmd.virtualAddress := request.address
io.cpu.memory.mmuBus.cmd.bypassTranslation := request.way
io.cpu.memory.haltIt := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr && victim.request.valid && !victim.dataReadRestored
cpuMemoryStageNeedReadData := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr
}
val stageB = new Area {
@ -567,7 +569,7 @@ class DataCache(p : DataCacheConfig) extends Component{
when(delayedIsStuck && !mmuRsp.miss) {
when(delayedWaysHitValid || (request.way && way.tagReadRspTwo.used)) {
io.cpu.writeBack.haltIt.clearWhen(!(victim.requestIn.valid && !victim.requestIn.ready))
victim.requestIn.valid := request.clean && way.tagReadRspTwo.dirty
victim.requestIn.valid := request.clean && way.tagReadRspTwo.dirty
tagsWriteCmd.valid := victim.requestIn.ready
} otherwise{
io.cpu.writeBack.haltIt := False

View file

@ -746,6 +746,9 @@ public:
#ifdef DBUS_CACHED
//#include "VVexRiscv_DataCache.h"
class DBusCached : public SimElement{
public:
uint32_t address;
@ -766,6 +769,23 @@ public:
}
virtual void preCycle(){
VL_IN8(io_cpu_execute_isValid,0,0);
VL_IN8(io_cpu_execute_isStuck,0,0);
VL_IN8(io_cpu_execute_args_kind,0,0);
VL_IN8(io_cpu_execute_args_wr,0,0);
VL_IN8(io_cpu_execute_args_size,1,0);
VL_IN8(io_cpu_execute_args_forceUncachedAccess,0,0);
VL_IN8(io_cpu_execute_args_clean,0,0);
VL_IN8(io_cpu_execute_args_invalidate,0,0);
VL_IN8(io_cpu_execute_args_way,0,0);
// if(top->VexRiscv->dataCache_1->io_cpu_execute_isValid && !top->VexRiscv->dataCache_1->io_cpu_execute_isStuck
// && top->VexRiscv->dataCache_1->io_cpu_execute_args_wr){
// if(top->VexRiscv->dataCache_1->io_cpu_execute_args_address == 0x80025978)
// cout << "WR 0x80025978 = " << hex << setw(8) << top->VexRiscv->dataCache_1->io_cpu_execute_args_data << endl;
// if(top->VexRiscv->dataCache_1->io_cpu_execute_args_address == 0x8002596c)
// cout << "WR 0x8002596c = " << hex << setw(8) << top->VexRiscv->dataCache_1->io_cpu_execute_args_data << endl;
// }
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
if(pendingCount == 0){
pendingCount = top->dBus_cmd_payload_length+1;
@ -1583,6 +1603,9 @@ int main(int argc, char **argv, char **env) {
Workspace w("debugPluginExternal");
w.loadHex("../../resources/hex/debugPluginExternal.hex");
w.noInstructionReadCheck();
//w.setIStall(false);
//w.setDStall(false);
#if defined(TRACE) || defined(TRACE_ACCESS)
//w.setCyclesPerSecond(5e3);
//printf("Speed reduced 5Khz\n");
@ -1593,7 +1616,7 @@ int main(int argc, char **argv, char **env) {
TestA().run();
redo(REDO,TestA().run();)

File diff suppressed because it is too large Load diff