From 86e0cbc1f3683be610a0c1ce9796daa82c44541c Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 29 Apr 2020 13:59:43 +0200 Subject: [PATCH] I$ with memDataWidth > cpuDataWidth now mux memWords into cpuWords before the decode stage by default. Add twoCycleRamInnerMux option to move that to the decode stage --- src/main/scala/vexriscv/ip/InstructionCache.scala | 10 ++++++---- src/test/scala/vexriscv/TestIndividualFeatures.scala | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index 469377c..7560114 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -22,6 +22,7 @@ case class InstructionCacheConfig( cacheSize : Int, asyncTagMemory : Boolean, twoCycleCache : Boolean = true, twoCycleRam : Boolean = false, + twoCycleRamInnerMux : Boolean = false, preResetFlush : Boolean = false, bypassGen : Boolean = false ){ @@ -404,7 +405,8 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ }else { way.tags.readSync(io.cpu.prefetch.pc(lineRange), !io.cpu.fetch.isStuck) } - val data = way.datas.readSync(io.cpu.prefetch.pc(lineRange.high downto memWordRange.low), !io.cpu.fetch.isStuck) + val dataMem = way.datas.readSync(io.cpu.prefetch.pc(lineRange.high downto memWordRange.low), !io.cpu.fetch.isStuck) + val data = if(!twoCycleRamInnerMux) dataMem.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange)) else dataMem } } @@ -415,7 +417,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ val id = OHToUInt(hits) val error = read.waysValues.map(_.tag.error).read(id) val data = read.waysValues.map(_.data).read(id) - val word = if(cpuDataWidth == memDataWidth) CombInit(data) else data.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange)) + val word = if(cpuDataWidth == memDataWidth || !twoCycleRamInnerMux) CombInit(data) else data.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange)) io.cpu.fetch.data := (if(p.bypassGen) (io.cpu.fetch.dataBypassValid ? io.cpu.fetch.dataBypass | word) else word) if(twoCycleCache){ io.cpu.decode.data := RegNextWhen(io.cpu.fetch.data,!io.cpu.decode.isStuck) @@ -423,7 +425,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ } if(twoCycleRam && wayCount == 1){ - val cacheData = if(cpuDataWidth == memDataWidth) CombInit(read.waysValues.head.data) else read.waysValues.head.data.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange)) + val cacheData = if(cpuDataWidth == memDataWidth || !twoCycleRamInnerMux) CombInit(read.waysValues.head.data) else read.waysValues.head.data.subdivideIn(cpuDataWidth bits).read(io.cpu.fetch.pc(memWordToCpuWordRange)) io.cpu.fetch.data := (if(p.bypassGen) (io.cpu.fetch.dataBypassValid ? io.cpu.fetch.dataBypass | cacheData) else cacheData) } @@ -459,7 +461,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ val id = OHToUInt(hits) val error = tags(id).error val data = fetchStage.read.waysValues.map(way => stage(way.data)).read(id) - val word = if(cpuDataWidth == memDataWidth) data else data.subdivideIn(cpuDataWidth bits).read(io.cpu.decode.pc(memWordToCpuWordRange)) + val word = if(cpuDataWidth == memDataWidth || !twoCycleRamInnerMux) data else data.subdivideIn(cpuDataWidth bits).read(io.cpu.decode.pc(memWordToCpuWordRange)) if(p.bypassGen) when(stage(io.cpu.fetch.dataBypassValid)){ word := stage(io.cpu.fetch.dataBypass) } diff --git a/src/test/scala/vexriscv/TestIndividualFeatures.scala b/src/test/scala/vexriscv/TestIndividualFeatures.scala index 98da229..72651b4 100644 --- a/src/test/scala/vexriscv/TestIndividualFeatures.scala +++ b/src/test/scala/vexriscv/TestIndividualFeatures.scala @@ -354,6 +354,7 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { val prediction = random(r, List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET)) val relaxedPcCalculation, twoCycleCache, injectorStage = r.nextBoolean() val twoCycleRam = r.nextBoolean() && twoCycleCache + val twoCycleRamInnerMux = r.nextBoolean() && twoCycleRam val memDataWidth = List(32,64,128)(r.nextInt(3)) val bytePerLine = Math.max(memDataWidth/8, List(8,16,32,64)(r.nextInt(4))) var cacheSize = 0 @@ -384,7 +385,8 @@ class IBusDimension(rvcRate : Double) extends VexRiscvDimension("IBus") { catchAccessFault = catchAll, asyncTagMemory = false, twoCycleRam = twoCycleRam, - twoCycleCache = twoCycleCache + twoCycleCache = twoCycleCache, + twoCycleRamInnerMux = twoCycleRamInnerMux ) ) if(tighlyCoupled) p.newTightlyCoupledPort(TightlyCoupledPortParameter("iBusTc", a => a(30 downto 28) === 0x0))