SpinalHDL 1.1.4

Now the CsrPlugin is waiting that the memory/writeback stages are empty before reading/writing things
This commit is contained in:
Dolu1990 2018-03-05 14:34:56 +01:00
parent b159ccf8ed
commit 53970dd284
4 changed files with 27 additions and 22 deletions

View File

@ -9,8 +9,8 @@ scalaVersion := "2.11.6"
EclipseKeys.withSource := true EclipseKeys.withSource := true
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.1.3", "com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.1.4",
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.1.3", "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.1.4",
"org.yaml" % "snakeyaml" % "1.8" "org.yaml" % "snakeyaml" % "1.8"
) )

View File

@ -6,7 +6,7 @@ import spinal.lib.bus.amba3.apb._
import spinal.lib.bus.misc.SizeMapping import spinal.lib.bus.misc.SizeMapping
import spinal.lib.com.jtag.Jtag import spinal.lib.com.jtag.Jtag
import spinal.lib.com.uart._ import spinal.lib.com.uart._
import spinal.lib.io.TriStateArray import spinal.lib.io.{InOutWrapper, TriStateArray}
import spinal.lib.misc.{InterruptCtrl, Prescaler, Timer} import spinal.lib.misc.{InterruptCtrl, Prescaler, Timer}
import spinal.lib.soc.pinsec.{PinsecTimerCtrl, PinsecTimerCtrlExternal} import spinal.lib.soc.pinsec.{PinsecTimerCtrl, PinsecTimerCtrlExternal}
import vexriscv.plugin._ import vexriscv.plugin._
@ -291,7 +291,7 @@ case class Murax(config : MuraxConfig) extends Component{
object Murax{ object Murax{
def main(args: Array[String]) { def main(args: Array[String]) {
SpinalVerilog(Murax(MuraxConfig.default)) SpinalVerilog(InOutWrapper(Murax(MuraxConfig.default)))
} }
} }

View File

@ -13,7 +13,7 @@ import scala.collection.mutable.ArrayBuffer
object VexRiscvSynthesisBench { object VexRiscvSynthesisBench {
def main(args: Array[String]) { def main(args: Array[String]) {
// def wrap(that : => Component) : Component = that def wrap(that : => Component) : Component = that
// Wrap with input/output registers // Wrap with input/output registers
// def wrap(that : => Component) : Component = { // def wrap(that : => Component) : Component = {
// //new WrapWithReg.Wrapper(that) // //new WrapWithReg.Wrapper(that)
@ -34,11 +34,11 @@ object VexRiscvSynthesisBench {
// } // }
// Wrap to do a decoding bench // Wrap to do a decoding bench
def wrap(that : => VexRiscv) : VexRiscv = { // def wrap(that : => VexRiscv) : VexRiscv = {
val top = that // val top = that
top.service(classOf[DecoderSimplePlugin]).bench(top) // top.service(classOf[DecoderSimplePlugin]).bench(top)
top // top
} // }
val smallestNoCsr = new Rtl { val smallestNoCsr = new Rtl {
override def getName(): String = "VexRiscv smallest no CSR" override def getName(): String = "VexRiscv smallest no CSR"
@ -94,10 +94,10 @@ object VexRiscvSynthesisBench {
} }
// val rtls = List(smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full) val rtls = List(smallestNoCsr, smallest, smallAndProductive, smallAndProductiveWithICache, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full)
// val rtls = List(noCacheNoMmuMaxPerf, fullNoMmuMaxPerf) // val rtls = List(noCacheNoMmuMaxPerf, fullNoMmuMaxPerf)
// val rtls = List(smallAndProductive, smallAndProductiveWithICache, fullNoMmuMaxPerf, fullNoMmu, full) // val rtls = List(smallAndProductive, smallAndProductiveWithICache, fullNoMmuMaxPerf, fullNoMmu, full)
val rtls = List(smallAndProductive, full) // val rtls = List(smallAndProductive, full)
val targets = XilinxStdTargets( val targets = XilinxStdTargets(

View File

@ -209,6 +209,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
object ENV_CTRL extends Stageable(EnvCtrlEnum()) object ENV_CTRL extends Stageable(EnvCtrlEnum())
object IS_CSR extends Stageable(Bool) object IS_CSR extends Stageable(Bool)
object CSR_WRITE_OPCODE extends Stageable(Bool) object CSR_WRITE_OPCODE extends Stageable(Bool)
object CSR_READ_OPCODE extends Stageable(Bool)
var allowInterrupts : Bool = null var allowInterrupts : Bool = null
var allowException : Bool = null var allowException : Bool = null
@ -230,8 +231,8 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
val defaultCsrActions = List[(Stageable[_ <: BaseType],Any)]( val defaultCsrActions = List[(Stageable[_ <: BaseType],Any)](
IS_CSR -> True, IS_CSR -> True,
REGFILE_WRITE_VALID -> True, REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> False BYPASSABLE_MEMORY_STAGE -> True
) )
val nonImmediatActions = defaultCsrActions ++ List( val nonImmediatActions = defaultCsrActions ++ List(
@ -531,13 +532,17 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
contextSwitching := jumpInterface.valid contextSwitching := jumpInterface.valid
//CSR read/write instructions management //CSR read/write instructions management
decode plug new Area{ decode plug new Area{
import decode._ import decode._
val imm = IMM(input(INSTRUCTION)) val imm = IMM(input(INSTRUCTION))
insert(CSR_WRITE_OPCODE) := (!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0) insert(CSR_WRITE_OPCODE) := ! (
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0))) (input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)
)
insert(CSR_READ_OPCODE) := input(INSTRUCTION)(13 downto 7) =/= B"0100000"
//Assure that the CSR access are in the execute stage when there is nothing left in memory/writeback stages to avoid exception hazard
arbitration.haltItself setWhen(arbitration.isValid && input(IS_CSR) && (execute.arbitration.isValid || memory.arbitration.isValid))
} }
execute plug new Area { execute plug new Area {
import execute._ import execute._
@ -555,18 +560,18 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
val writeSrc = input(INSTRUCTION)(14) ? imm.z.asBits.resized | input(SRC1) val writeSrc = input(INSTRUCTION)(14) ? imm.z.asBits.resized | input(SRC1)
val readData = B(0, 32 bits) val readData = B(0, 32 bits)
def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT
val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid && !memory.arbitration.isStuck) clearWhen(!arbitration.isStuck) val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid) clearWhen(!arbitration.isStuck)
val writeData = input(INSTRUCTION)(13).mux( val writeData = input(INSTRUCTION)(13).mux(
False -> writeSrc, False -> writeSrc,
True -> Mux(input(INSTRUCTION)(12), readDataReg & ~writeSrc, readDataReg | writeSrc) True -> Mux(input(INSTRUCTION)(12), readDataReg & ~writeSrc, readDataReg | writeSrc)
) )
val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE) val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE)
val readInstruction = arbitration.isValid && input(IS_CSR) && !input(CSR_WRITE_OPCODE) val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE)
arbitration.haltItself setWhen(writeInstruction && !readDataRegValid) arbitration.haltItself setWhen(writeInstruction && !readDataRegValid)
val writeEnable = writeInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt && readDataRegValid val writeEnable = writeInstruction && readDataRegValid
val readEnable = readInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt val readEnable = readInstruction && !readDataRegValid
when(arbitration.isValid && input(IS_CSR)) { when(arbitration.isValid && input(IS_CSR)) {
output(REGFILE_WRITE_DATA) := readData output(REGFILE_WRITE_DATA) := readData
@ -584,7 +589,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
illegalAccess := False illegalAccess := False
} else { } else {
if (withWrite) illegalAccess.clearWhen(input(CSR_WRITE_OPCODE)) if (withWrite) illegalAccess.clearWhen(input(CSR_WRITE_OPCODE))
if (withRead) illegalAccess.clearWhen(!input(CSR_WRITE_OPCODE)) if (withRead) illegalAccess.clearWhen(input(CSR_READ_OPCODE))
} }
when(writeEnable) { when(writeEnable) {