Add support for big endian byte ordering
This commit is contained in:
parent
2942d0652a
commit
c489143442
|
@ -52,8 +52,8 @@ case class MuraxConfig(coreFrequency : HertzNumber,
|
||||||
|
|
||||||
|
|
||||||
object MuraxConfig{
|
object MuraxConfig{
|
||||||
def default : MuraxConfig = default(false)
|
def default : MuraxConfig = default(false, false)
|
||||||
def default(withXip : Boolean) = MuraxConfig(
|
def default(withXip : Boolean = false, bigEndian : Boolean = false) = MuraxConfig(
|
||||||
coreFrequency = 12 MHz,
|
coreFrequency = 12 MHz,
|
||||||
onChipRamSize = 8 kB,
|
onChipRamSize = 8 kB,
|
||||||
onChipRamHexFile = null,
|
onChipRamHexFile = null,
|
||||||
|
@ -75,12 +75,14 @@ object MuraxConfig{
|
||||||
cmdForkPersistence = withXip, //Required by the Xip controller
|
cmdForkPersistence = withXip, //Required by the Xip controller
|
||||||
prediction = NONE,
|
prediction = NONE,
|
||||||
catchAccessFault = false,
|
catchAccessFault = false,
|
||||||
compressedGen = false
|
compressedGen = false,
|
||||||
|
bigEndian = bigEndian
|
||||||
),
|
),
|
||||||
new DBusSimplePlugin(
|
new DBusSimplePlugin(
|
||||||
catchAddressMisaligned = false,
|
catchAddressMisaligned = false,
|
||||||
catchAccessFault = false,
|
catchAccessFault = false,
|
||||||
earlyInjection = false
|
earlyInjection = false,
|
||||||
|
bigEndian = bigEndian
|
||||||
),
|
),
|
||||||
new CsrPlugin(CsrPluginConfig.smallest(mtvecInit = if(withXip) 0xE0040020l else 0x80000020l)),
|
new CsrPlugin(CsrPluginConfig.smallest(mtvecInit = if(withXip) 0xE0040020l else 0x80000020l)),
|
||||||
new DecoderSimplePlugin(
|
new DecoderSimplePlugin(
|
||||||
|
@ -214,9 +216,11 @@ case class Murax(config : MuraxConfig) extends Component{
|
||||||
dataWidth = 32
|
dataWidth = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val bigEndianDBus = config.cpuPlugins.exists(_ match{ case plugin : DBusSimplePlugin => plugin.bigEndian case _ => false})
|
||||||
|
|
||||||
//Arbiter of the cpu dBus/iBus to drive the mainBus
|
//Arbiter of the cpu dBus/iBus to drive the mainBus
|
||||||
//Priority to dBus, !! cmd transactions can change on the fly !!
|
//Priority to dBus, !! cmd transactions can change on the fly !!
|
||||||
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig)
|
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig, bigEndianDBus)
|
||||||
|
|
||||||
//Instanciate the CPU
|
//Instanciate the CPU
|
||||||
val cpu = new VexRiscv(
|
val cpu = new VexRiscv(
|
||||||
|
@ -258,7 +262,8 @@ case class Murax(config : MuraxConfig) extends Component{
|
||||||
val ram = new MuraxPipelinedMemoryBusRam(
|
val ram = new MuraxPipelinedMemoryBusRam(
|
||||||
onChipRamSize = onChipRamSize,
|
onChipRamSize = onChipRamSize,
|
||||||
onChipRamHexFile = onChipRamHexFile,
|
onChipRamHexFile = onChipRamHexFile,
|
||||||
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig
|
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig,
|
||||||
|
bigEndian = bigEndianDBus
|
||||||
)
|
)
|
||||||
mainBusMapping += ram.io.bus -> (0x80000000l, onChipRamSize)
|
mainBusMapping += ram.io.bus -> (0x80000000l, onChipRamSize)
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@ import spinal.lib._
|
||||||
import spinal.lib.bus.simple._
|
import spinal.lib.bus.simple._
|
||||||
import vexriscv.plugin.{DBusSimpleBus, IBusSimpleBus}
|
import vexriscv.plugin.{DBusSimpleBus, IBusSimpleBus}
|
||||||
|
|
||||||
class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{
|
class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{
|
||||||
val io = new Bundle{
|
val io = new Bundle{
|
||||||
val iBus = slave(IBusSimpleBus(null))
|
val iBus = slave(IBusSimpleBus(null))
|
||||||
val dBus = slave(DBusSimpleBus())
|
val dBus = slave(DBusSimpleBus(bigEndian))
|
||||||
val masterBus = master(PipelinedMemoryBus(pipelinedMemoryBusConfig))
|
val masterBus = master(PipelinedMemoryBus(pipelinedMemoryBusConfig))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +21,7 @@ class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) ex
|
||||||
io.masterBus.cmd.write := io.dBus.cmd.valid && io.dBus.cmd.wr
|
io.masterBus.cmd.write := io.dBus.cmd.valid && io.dBus.cmd.wr
|
||||||
io.masterBus.cmd.address := io.dBus.cmd.valid ? io.dBus.cmd.address | io.iBus.cmd.pc
|
io.masterBus.cmd.address := io.dBus.cmd.valid ? io.dBus.cmd.address | io.iBus.cmd.pc
|
||||||
io.masterBus.cmd.data := io.dBus.cmd.data
|
io.masterBus.cmd.data := io.dBus.cmd.data
|
||||||
io.masterBus.cmd.mask := io.dBus.cmd.size.mux(
|
io.masterBus.cmd.mask := io.dBus.genMask(io.dBus.cmd)
|
||||||
0 -> B"0001",
|
|
||||||
1 -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) |<< io.dBus.cmd.address(1 downto 0)
|
|
||||||
io.iBus.cmd.ready := io.masterBus.cmd.ready && !io.dBus.cmd.valid
|
io.iBus.cmd.ready := io.masterBus.cmd.ready && !io.dBus.cmd.valid
|
||||||
io.dBus.cmd.ready := io.masterBus.cmd.ready
|
io.dBus.cmd.ready := io.masterBus.cmd.ready
|
||||||
|
|
||||||
|
@ -53,7 +49,7 @@ class MuraxMasterArbiter(pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) ex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig) extends Component{
|
case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, pipelinedMemoryBusConfig : PipelinedMemoryBusConfig, bigEndian : Boolean = false) extends Component{
|
||||||
val io = new Bundle{
|
val io = new Bundle{
|
||||||
val bus = slave(PipelinedMemoryBus(pipelinedMemoryBusConfig))
|
val bus = slave(PipelinedMemoryBus(pipelinedMemoryBusConfig))
|
||||||
}
|
}
|
||||||
|
@ -71,6 +67,14 @@ case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile :
|
||||||
|
|
||||||
if(onChipRamHexFile != null){
|
if(onChipRamHexFile != null){
|
||||||
HexTools.initRam(ram, onChipRamHexFile, 0x80000000l)
|
HexTools.initRam(ram, onChipRamHexFile, 0x80000000l)
|
||||||
|
if(bigEndian)
|
||||||
|
// HexTools.initRam (incorrectly) assumes little endian byte ordering
|
||||||
|
for((word, wordIndex) <- ram.initialContent.zipWithIndex)
|
||||||
|
ram.initialContent(wordIndex) =
|
||||||
|
((word & 0xffl) << 24) |
|
||||||
|
((word & 0xff00l) << 8) |
|
||||||
|
((word & 0xff0000l) >> 8) |
|
||||||
|
((word & 0xff000000l) >> 24)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ object DBusSimpleBus{
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
case class DBusSimpleBus(bigEndian : Boolean = false) extends Bundle with IMasterSlave{
|
||||||
val cmd = Stream(DBusSimpleCmd())
|
val cmd = Stream(DBusSimpleCmd())
|
||||||
val rsp = DBusSimpleRsp()
|
val rsp = DBusSimpleRsp()
|
||||||
|
|
||||||
|
@ -100,12 +100,27 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
}
|
}
|
||||||
|
|
||||||
def cmdS2mPipe() : DBusSimpleBus = {
|
def cmdS2mPipe() : DBusSimpleBus = {
|
||||||
val s = DBusSimpleBus()
|
val s = DBusSimpleBus(bigEndian)
|
||||||
s.cmd << this.cmd.s2mPipe()
|
s.cmd << this.cmd.s2mPipe()
|
||||||
this.rsp := s.rsp
|
this.rsp := s.rsp
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def genMask(cmd : DBusSimpleCmd) = {
|
||||||
|
if(bigEndian)
|
||||||
|
cmd.size.mux(
|
||||||
|
U(0) -> B"1000",
|
||||||
|
U(1) -> B"1100",
|
||||||
|
default -> B"1111"
|
||||||
|
) |>> cmd.address(1 downto 0)
|
||||||
|
else
|
||||||
|
cmd.size.mux(
|
||||||
|
U(0) -> B"0001",
|
||||||
|
U(1) -> B"0011",
|
||||||
|
default -> B"1111"
|
||||||
|
) |<< cmd.address(1 downto 0)
|
||||||
|
}
|
||||||
|
|
||||||
def toAxi4Shared(stageCmd : Boolean = false, pendingWritesMax : Int = 7): Axi4Shared = {
|
def toAxi4Shared(stageCmd : Boolean = false, pendingWritesMax : Int = 7): Axi4Shared = {
|
||||||
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
||||||
|
|
||||||
|
@ -130,11 +145,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
axi.writeData.arbitrationFrom(dataStage)
|
axi.writeData.arbitrationFrom(dataStage)
|
||||||
axi.writeData.last := True
|
axi.writeData.last := True
|
||||||
axi.writeData.data := dataStage.data
|
axi.writeData.data := dataStage.data
|
||||||
axi.writeData.strb := (dataStage.size.mux(
|
axi.writeData.strb := genMask(dataStage).resized
|
||||||
U(0) -> B"0001",
|
|
||||||
U(1) -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) << dataStage.address(1 downto 0)).resized
|
|
||||||
|
|
||||||
|
|
||||||
rsp.ready := axi.r.valid
|
rsp.ready := axi.r.valid
|
||||||
|
@ -158,11 +169,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
mm.write := cmdStage.valid && cmdStage.wr
|
mm.write := cmdStage.valid && cmdStage.wr
|
||||||
mm.address := (cmdStage.address >> 2) @@ U"00"
|
mm.address := (cmdStage.address >> 2) @@ U"00"
|
||||||
mm.writeData := cmdStage.data(31 downto 0)
|
mm.writeData := cmdStage.data(31 downto 0)
|
||||||
mm.byteEnable := (cmdStage.size.mux (
|
mm.byteEnable := genMask(cmdStage).resized
|
||||||
U(0) -> B"0001",
|
|
||||||
U(1) -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) << cmdStage.address(1 downto 0)).resized
|
|
||||||
|
|
||||||
|
|
||||||
cmdStage.ready := mm.waitRequestn
|
cmdStage.ready := mm.waitRequestn
|
||||||
|
@ -181,11 +188,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
bus.ADR := cmdStage.address >> 2
|
bus.ADR := cmdStage.address >> 2
|
||||||
bus.CTI :=B"000"
|
bus.CTI :=B"000"
|
||||||
bus.BTE := "00"
|
bus.BTE := "00"
|
||||||
bus.SEL := (cmdStage.size.mux (
|
bus.SEL := genMask(cmdStage).resized
|
||||||
U(0) -> B"0001",
|
|
||||||
U(1) -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) << cmdStage.address(1 downto 0)).resized
|
|
||||||
when(!cmdStage.wr) {
|
when(!cmdStage.wr) {
|
||||||
bus.SEL := "1111"
|
bus.SEL := "1111"
|
||||||
}
|
}
|
||||||
|
@ -209,11 +212,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
bus.cmd.write := cmd.wr
|
bus.cmd.write := cmd.wr
|
||||||
bus.cmd.address := cmd.address.resized
|
bus.cmd.address := cmd.address.resized
|
||||||
bus.cmd.data := cmd.data
|
bus.cmd.data := cmd.data
|
||||||
bus.cmd.mask := cmd.size.mux(
|
bus.cmd.mask := genMask(cmd)
|
||||||
0 -> B"0001",
|
|
||||||
1 -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) |<< cmd.address(1 downto 0)
|
|
||||||
cmd.ready := bus.cmd.ready
|
cmd.ready := bus.cmd.ready
|
||||||
|
|
||||||
rsp.ready := bus.rsp.valid
|
rsp.ready := bus.rsp.valid
|
||||||
|
@ -265,11 +264,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||||
1 -> U"01",
|
1 -> U"01",
|
||||||
default -> U"11"
|
default -> U"11"
|
||||||
)
|
)
|
||||||
bus.cmd.mask := cmd.size.mux(
|
bus.cmd.mask := genMask(cmd)
|
||||||
0 -> B"0001",
|
|
||||||
1 -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) |<< cmd.address(1 downto 0)
|
|
||||||
|
|
||||||
cmd.ready := bus.cmd.ready
|
cmd.ready := bus.cmd.ready
|
||||||
|
|
||||||
|
@ -289,6 +284,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
emitCmdInMemoryStage : Boolean = false,
|
emitCmdInMemoryStage : Boolean = false,
|
||||||
onlyLoadWords : Boolean = false,
|
onlyLoadWords : Boolean = false,
|
||||||
withLrSc : Boolean = false,
|
withLrSc : Boolean = false,
|
||||||
|
val bigEndian : Boolean = false,
|
||||||
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
|
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
|
||||||
|
|
||||||
var dBus : DBusSimpleBus = null
|
var dBus : DBusSimpleBus = null
|
||||||
|
@ -393,7 +389,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
import pipeline._
|
import pipeline._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
dBus = master(DBusSimpleBus()).setName("dBus")
|
dBus = master(DBusSimpleBus(bigEndian)).setName("dBus")
|
||||||
|
|
||||||
|
|
||||||
decode plug new Area {
|
decode plug new Area {
|
||||||
|
@ -436,11 +432,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0)
|
insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0)
|
||||||
|
|
||||||
//formal
|
//formal
|
||||||
val formalMask = dBus.cmd.size.mux(
|
val formalMask = dBus.genMask(dBus.cmd)
|
||||||
U(0) -> B"0001",
|
|
||||||
U(1) -> B"0011",
|
|
||||||
default -> B"1111"
|
|
||||||
) |<< dBus.cmd.address(1 downto 0)
|
|
||||||
|
|
||||||
insert(FORMAL_MEM_ADDR) := dBus.cmd.address & U"xFFFFFFFC"
|
insert(FORMAL_MEM_ADDR) := dBus.cmd.address & U"xFFFFFFFC"
|
||||||
insert(FORMAL_MEM_WMASK) := (dBus.cmd.valid && dBus.cmd.wr) ? formalMask | B"0000"
|
insert(FORMAL_MEM_WMASK) := (dBus.cmd.valid && dBus.cmd.wr) ? formalMask | B"0000"
|
||||||
|
@ -541,13 +533,28 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
|
|
||||||
val rspShifted = MEMORY_READ_DATA()
|
val rspShifted = MEMORY_READ_DATA()
|
||||||
rspShifted := input(MEMORY_READ_DATA)
|
rspShifted := input(MEMORY_READ_DATA)
|
||||||
|
if(bigEndian)
|
||||||
|
switch(input(MEMORY_ADDRESS_LOW)){
|
||||||
|
is(1){rspShifted(31 downto 24) := input(MEMORY_READ_DATA)(23 downto 16)}
|
||||||
|
is(2){rspShifted(31 downto 16) := input(MEMORY_READ_DATA)(15 downto 0)}
|
||||||
|
is(3){rspShifted(31 downto 24) := input(MEMORY_READ_DATA)(7 downto 0)}
|
||||||
|
}
|
||||||
|
else
|
||||||
switch(input(MEMORY_ADDRESS_LOW)){
|
switch(input(MEMORY_ADDRESS_LOW)){
|
||||||
is(1){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(15 downto 8)}
|
is(1){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(15 downto 8)}
|
||||||
is(2){rspShifted(15 downto 0) := input(MEMORY_READ_DATA)(31 downto 16)}
|
is(2){rspShifted(15 downto 0) := input(MEMORY_READ_DATA)(31 downto 16)}
|
||||||
is(3){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(31 downto 24)}
|
is(3){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(31 downto 24)}
|
||||||
}
|
}
|
||||||
|
|
||||||
val rspFormated = input(INSTRUCTION)(13 downto 12).mux(
|
val rspFormated =
|
||||||
|
if(bigEndian)
|
||||||
|
input(INSTRUCTION)(13 downto 12).mux(
|
||||||
|
0 -> B((31 downto 8) -> (rspShifted(31) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(31 downto 24)),
|
||||||
|
1 -> B((31 downto 16) -> (rspShifted(31) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(31 downto 16)),
|
||||||
|
default -> rspShifted //W
|
||||||
|
)
|
||||||
|
else
|
||||||
|
input(INSTRUCTION)(13 downto 12).mux(
|
||||||
0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)),
|
0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)),
|
||||||
1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)),
|
1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)),
|
||||||
default -> rspShifted //W
|
default -> rspShifted //W
|
||||||
|
|
|
@ -234,7 +234,8 @@ class IBusSimplePlugin( resetVector : BigInt,
|
||||||
val singleInstructionPipeline : Boolean = false,
|
val singleInstructionPipeline : Boolean = false,
|
||||||
val memoryTranslatorPortConfig : Any = null,
|
val memoryTranslatorPortConfig : Any = null,
|
||||||
relaxPredictorAddress : Boolean = true,
|
relaxPredictorAddress : Boolean = true,
|
||||||
predictionBuffer : Boolean = true
|
predictionBuffer : Boolean = true,
|
||||||
|
bigEndian : Boolean = false
|
||||||
) extends IBusFetcherImpl(
|
) extends IBusFetcherImpl(
|
||||||
resetVector = resetVector,
|
resetVector = resetVector,
|
||||||
keepPcPlus4 = keepPcPlus4,
|
keepPcPlus4 = keepPcPlus4,
|
||||||
|
@ -371,6 +372,12 @@ class IBusSimplePlugin( resetVector : BigInt,
|
||||||
fetchRsp.pc := stages.last.output.payload
|
fetchRsp.pc := stages.last.output.payload
|
||||||
fetchRsp.rsp := rspBuffer.output.payload
|
fetchRsp.rsp := rspBuffer.output.payload
|
||||||
fetchRsp.rsp.error.clearWhen(!rspBuffer.output.valid) //Avoid interference with instruction injection from the debug plugin
|
fetchRsp.rsp.error.clearWhen(!rspBuffer.output.valid) //Avoid interference with instruction injection from the debug plugin
|
||||||
|
if(bigEndian){
|
||||||
|
// inst(15 downto 0) should contain lower addressed parcel,
|
||||||
|
// and inst(31 downto 16) the higher addressed parcel
|
||||||
|
fetchRsp.rsp.inst.allowOverride
|
||||||
|
fetchRsp.rsp.inst := rspBuffer.output.payload.inst.rotateLeft(16)
|
||||||
|
}
|
||||||
|
|
||||||
val join = Stream(FetchRsp())
|
val join = Stream(FetchRsp())
|
||||||
val exceptionDetected = False
|
val exceptionDetected = False
|
||||||
|
|
Loading…
Reference in New Issue