From efb27390a7de5f47805144c7430b7fcb10e5846c Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Thu, 6 Apr 2017 01:28:52 +0200 Subject: [PATCH] Better IntAluPlugin Better SrcPlugin Better DBusCachedPlugin --- .../SpinalRiscv/Plugin/DBusCachedPlugin.scala | 2 +- .../SpinalRiscv/Plugin/DBusSimplePlugin.scala | 2 +- .../SpinalRiscv/Plugin/IntAluPlugin.scala | 33 ++++++++------ .../Plugin/PcManagerSimplePlugin.scala | 2 +- .../SpinalRiscv/Plugin/RegFilePlugin.scala | 5 ++- .../SpinalRiscv/Plugin/ShiftPlugins.scala | 6 ++- .../scala/SpinalRiscv/Plugin/SrcPlugin.scala | 4 ++ src/main/scala/SpinalRiscv/TopLevel.scala | 43 ++++++++++++++++--- src/main/scala/SpinalRiscv/VexRiscv.scala | 8 ++-- src/test/cpp/testA/main.cpp | 4 +- 10 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/main/scala/SpinalRiscv/Plugin/DBusCachedPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/DBusCachedPlugin.scala index 1d8d33f..acaa3e5 100644 --- a/src/main/scala/SpinalRiscv/Plugin/DBusCachedPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/DBusCachedPlugin.scala @@ -76,7 +76,7 @@ class DBusCachedPlugin(config : DataCacheConfig) extends Plugin[VexRiscv]{ cache.io.cpu.execute.isStuck := arbitration.isStuck // arbitration.haltIt.setWhen(cache.io.cpu.execute.haltIt) cache.io.cpu.execute.args.wr := input(INSTRUCTION)(5) - cache.io.cpu.execute.args.address := input(SRC_ADD_SUB).asUInt + cache.io.cpu.execute.args.address := input(SRC_ADD).asUInt cache.io.cpu.execute.args.data := size.mux( U(0) -> input(REG2)( 7 downto 0) ## input(REG2)( 7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0), U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0), diff --git a/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala index a812a9c..657804f 100644 --- a/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala @@ -97,7 +97,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.removeIt dBus.cmd.wr := input(INSTRUCTION)(5) - dBus.cmd.address := input(SRC_ADD_SUB).asUInt + dBus.cmd.address := input(SRC_ADD).asUInt dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt dBus.cmd.payload.data := dBus.cmd.size.mux ( U(0) -> input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0), diff --git a/src/main/scala/SpinalRiscv/Plugin/IntAluPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/IntAluPlugin.scala index 63cc3ee..1d41535 100644 --- a/src/main/scala/SpinalRiscv/Plugin/IntAluPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/IntAluPlugin.scala @@ -3,10 +3,14 @@ package SpinalRiscv.Plugin import SpinalRiscv._ import spinal.core._ object IntAluPlugin{ + object AluBitwiseCtrlEnum extends SpinalEnum(binarySequential){ + val XOR, OR, AND, SRC1 = newElement() + } object AluCtrlEnum extends SpinalEnum(binarySequential){ - val ADD_SUB, SLT_SLTU, XOR, OR, AND, SRC1 = newElement() + val ADD_SUB, SLT_SLTU, BITWISE = newElement() } + object ALU_BITWISE_CTRL extends Stageable(AluBitwiseCtrlEnum()) object ALU_CTRL extends Stageable(AluCtrlEnum()) } @@ -46,28 +50,27 @@ class IntAluPlugin extends Plugin[VexRiscv]{ val decoderService = pipeline.service(classOf[DecoderService]) - decoderService.addDefault(REGFILE_WRITE_VALID,False) decoderService.add(List( ADD -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)), SUB -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> True)), SLT -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)), SLTU -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)), - XOR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.XOR)), - OR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.OR)), - AND -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND)) + XOR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.XOR)), + OR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.OR)), + AND -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.AND)) )) decoderService.add(List( ADDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)), SLTI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)), SLTIU -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)), - XORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.XOR)), - ORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.OR)), - ANDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND)) + XORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.XOR)), + ORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.OR)), + ANDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.AND)) )) decoderService.add(List( - LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)), + LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)), AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC)) )) } @@ -80,12 +83,16 @@ class IntAluPlugin extends Plugin[VexRiscv]{ execute plug new Area{ import execute._ + val bitwise = input(ALU_BITWISE_CTRL).mux( + AluBitwiseCtrlEnum.AND -> (input(SRC1) & input(SRC2)), + AluBitwiseCtrlEnum.OR -> (input(SRC1) | input(SRC2)), + AluBitwiseCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)), + AluBitwiseCtrlEnum.SRC1 -> input(SRC1) + ) + // mux results insert(REGFILE_WRITE_DATA) := input(ALU_CTRL).mux( - AluCtrlEnum.AND -> (input(SRC1) & input(SRC2)), - AluCtrlEnum.OR -> (input(SRC1) | input(SRC2)), - AluCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)), - AluCtrlEnum.SRC1 -> input(SRC1), + AluCtrlEnum.BITWISE -> bitwise, AluCtrlEnum.SLT_SLTU -> input(SRC_LESS).asBits(32 bit), AluCtrlEnum.ADD_SUB -> input(SRC_ADD_SUB) ) diff --git a/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala index 5ed3af5..e301e8a 100644 --- a/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala @@ -34,7 +34,7 @@ class PcManagerSimplePlugin(resetVector : BigInt, fastPcCalculation : Boolean) e arbitration.isValid := True //PC calculation without Jump - val pcReg = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public") + val pcReg = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute(Verilator.public) val inc = RegInit(False) val pcBeforeJumps = if(fastPcCalculation){ val pcPlus4 = pcReg + U(4) diff --git a/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala index 0b3cf9f..15d087f 100644 --- a/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala @@ -17,6 +17,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals val decoderService = pipeline.service(classOf[DecoderService]) decoderService.addDefault(REG1_USE,False) decoderService.addDefault(REG2_USE,False) + decoderService.addDefault(REGFILE_WRITE_VALID,False) } override def build(pipeline: VexRiscv): Unit = { @@ -24,7 +25,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals import pipeline.config._ val global = pipeline plug new Area{ - val regFile = Mem(Bits(32 bits),32) addAttribute("verilator public") + val regFile = Mem(Bits(32 bits),32) addAttribute(Verilator.public) if(zeroBoot) regFile.init(List.fill(32)(B(0, 32 bits))) } @@ -59,7 +60,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals writeBack plug new Area { import writeBack._ - val regFileWrite = global.regFile.writePort.addAttribute("verilator public") + val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public) regFileWrite.valid := input(REGFILE_WRITE_VALID) && arbitration.isFiring regFileWrite.address := input(INSTRUCTION)(rdRange).asUInt regFileWrite.data := input(REGFILE_WRITE_DATA) diff --git a/src/main/scala/SpinalRiscv/Plugin/ShiftPlugins.scala b/src/main/scala/SpinalRiscv/Plugin/ShiftPlugins.scala index 2bfe95e..7f7515a 100644 --- a/src/main/scala/SpinalRiscv/Plugin/ShiftPlugins.scala +++ b/src/main/scala/SpinalRiscv/Plugin/ShiftPlugins.scala @@ -95,7 +95,8 @@ class LightShifterPlugin extends Plugin[VexRiscv]{ val immediateActions = List[(Stageable[_ <: BaseType],Any)]( SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.IMI, - ALU_CTRL -> AluCtrlEnum.SRC1, + ALU_CTRL -> AluCtrlEnum.BITWISE, + ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, @@ -105,7 +106,8 @@ class LightShifterPlugin extends Plugin[VexRiscv]{ val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)]( SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.RS, - ALU_CTRL -> AluCtrlEnum.SRC1, + ALU_CTRL -> AluCtrlEnum.BITWISE, + ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, diff --git a/src/main/scala/SpinalRiscv/Plugin/SrcPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/SrcPlugin.scala index eef7f79..38e9c11 100644 --- a/src/main/scala/SpinalRiscv/Plugin/SrcPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/SrcPlugin.scala @@ -41,6 +41,8 @@ class SrcPlugin(separatedAddSub : Boolean) extends Plugin[VexRiscv]{ Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb)) insert(SRC_ADD_SUB) := input(SRC_USE_SUB_LESS) ? sub | add + insert(SRC_ADD) := add + insert(SRC_SUB) := sub insert(SRC_LESS) := less } }else{ @@ -55,6 +57,8 @@ class SrcPlugin(separatedAddSub : Boolean) extends Plugin[VexRiscv]{ Mux(input(SRC_LESS_UNSIGNED), input(SRC2).msb, input(SRC1).msb)) insert(SRC_ADD_SUB) := addSub + insert(SRC_ADD) := addSub + insert(SRC_SUB) := addSub insert(SRC_LESS) := less } } diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index f7c390b..41f8f3b 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -199,26 +199,51 @@ object TopLevel { ) configTest.plugins ++= List( - new PcManagerSimplePlugin(0x00000000l, false), + new PcManagerSimplePlugin(0x00000000l, true), new IBusSimplePlugin( interfaceKeepData = true, catchAccessFault = false ), +// new IBusCachedPlugin( +// config = InstructionCacheConfig( +// cacheSize = 4096, +// bytePerLine =32, +// wayCount = 1, +// wrappedMemAccess = true, +// addressWidth = 32, +// cpuDataWidth = 32, +// memDataWidth = 32, +// catchAccessFault = false, +// asyncTagMemory = false +// ) +// ), new DBusSimplePlugin( catchAddressMisaligned = false, catchAccessFault = false ), +// new DBusCachedPlugin( +// config = new DataCacheConfig( +// cacheSize = 2048, +// bytePerLine = 32, +// wayCount = 1, +// addressWidth = 32, +// cpuDataWidth = 32, +// memDataWidth = 32, +// catchAccessFault = false +// ) +// ), + new DecoderSimplePlugin( catchIllegalInstruction = false ), new RegFilePlugin( - regFileReadyKind = Plugin.ASYNC, + regFileReadyKind = Plugin.SYNC, zeroBoot = false ), new IntAluPlugin, new SrcPlugin( - separatedAddSub = false + separatedAddSub = true ), new FullBarrielShifterPlugin, // new LightShifterPlugin, @@ -246,10 +271,10 @@ object TopLevel { val toplevel = new VexRiscv(configFull) // val toplevel = new VexRiscv(configLight) // val toplevel = new VexRiscv(configTest) - toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute("verilator public") - toplevel.decode.input(toplevel.config.PC).addAttribute("verilator public") - toplevel.decode.arbitration.isValid.addAttribute("verilator public") -// toplevel.writeBack.input(config.PC).addAttribute("verilator public") + toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute(Verilator.public) + toplevel.decode.input(toplevel.config.PC).addAttribute(Verilator.public) + toplevel.decode.arbitration.isValid.addAttribute(Verilator.public) +// toplevel.writeBack.input(config.PC).addAttribute(Verilator.public) // toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel) toplevel @@ -257,3 +282,7 @@ object TopLevel { } } +//TODO DivPlugin should not used MixedDivider (double twoComplement) +//TODO DivPlugin should register the twoComplement output before pipeline insertion +//TODO MulPlugin doesn't fit well on Artix (FMAX) +//TODO PcReg design is unoptimized by Artix synthesis \ No newline at end of file diff --git a/src/main/scala/SpinalRiscv/VexRiscv.scala b/src/main/scala/SpinalRiscv/VexRiscv.scala index 339bb04..443c33b 100644 --- a/src/main/scala/SpinalRiscv/VexRiscv.scala +++ b/src/main/scala/SpinalRiscv/VexRiscv.scala @@ -26,6 +26,8 @@ case class VexRiscvConfig(pcWidth : Int){ object SRC1 extends Stageable(Bits(32 bits)) object SRC2 extends Stageable(Bits(32 bits)) object SRC_ADD_SUB extends Stageable(Bits(32 bits)) + object SRC_ADD extends Stageable(Bits(32 bits)) + object SRC_SUB extends Stageable(Bits(32 bits)) object SRC_LESS extends Stageable(Bool) object SRC_USE_SUB_LESS extends Stageable(Bool) object SRC_LESS_UNSIGNED extends Stageable(Bool) @@ -53,9 +55,9 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{ plugins ++= config.plugins //regression usage - writeBack.input(config.INSTRUCTION) keep() addAttribute("verilator public") - writeBack.input(config.PC) keep() addAttribute("verilator public") - writeBack.arbitration.isValid keep() addAttribute("verilator public") + writeBack.input(config.INSTRUCTION) keep() addAttribute(Verilator.public) + writeBack.input(config.PC) keep() addAttribute(Verilator.public) + writeBack.arbitration.isValid keep() addAttribute(Verilator.public) } diff --git a/src/test/cpp/testA/main.cpp b/src/test/cpp/testA/main.cpp index cc8fcc6..daab8e9 100644 --- a/src/test/cpp/testA/main.cpp +++ b/src/test/cpp/testA/main.cpp @@ -194,7 +194,7 @@ public: virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) { - assertEq(addr % 4, 0); + if(addr % 4 != 0) cout << "Warning, unaligned IBusAccess : " << addr << endl; *data = ( (mem[addr + 0] << 0) | (mem[addr + 1] << 8) | (mem[addr + 2] << 16) @@ -372,7 +372,7 @@ public: dump(i); - dump(i+1); + dump(i+10); #ifdef TRACE tfp->close(); #endif