Merge pull request #135 from zeldin/bigendian
Add support for big endian byte ordering
This commit is contained in:
commit
98de02051e
|
@ -52,8 +52,8 @@ case class MuraxConfig(coreFrequency : HertzNumber,
|
|||
|
||||
|
||||
object MuraxConfig{
|
||||
def default : MuraxConfig = default(false)
|
||||
def default(withXip : Boolean) = MuraxConfig(
|
||||
def default : MuraxConfig = default(false, false)
|
||||
def default(withXip : Boolean = false, bigEndian : Boolean = false) = MuraxConfig(
|
||||
coreFrequency = 12 MHz,
|
||||
onChipRamSize = 8 kB,
|
||||
onChipRamHexFile = null,
|
||||
|
@ -75,12 +75,14 @@ object MuraxConfig{
|
|||
cmdForkPersistence = withXip, //Required by the Xip controller
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
compressedGen = false,
|
||||
bigEndian = bigEndian
|
||||
),
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = false,
|
||||
catchAccessFault = false,
|
||||
earlyInjection = false
|
||||
earlyInjection = false,
|
||||
bigEndian = bigEndian
|
||||
),
|
||||
new CsrPlugin(CsrPluginConfig.smallest(mtvecInit = if(withXip) 0xE0040020l else 0x80000020l)),
|
||||
new DecoderSimplePlugin(
|
||||
|
@ -214,9 +216,11 @@ case class Murax(config : MuraxConfig) extends Component{
|
|||
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
|
||||
//Priority to dBus, !! cmd transactions can change on the fly !!
|
||||
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig)
|
||||
val mainBusArbiter = new MuraxMasterArbiter(pipelinedMemoryBusConfig, bigEndianDBus)
|
||||
|
||||
//Instanciate the CPU
|
||||
val cpu = new VexRiscv(
|
||||
|
@ -258,7 +262,8 @@ case class Murax(config : MuraxConfig) extends Component{
|
|||
val ram = new MuraxPipelinedMemoryBusRam(
|
||||
onChipRamSize = onChipRamSize,
|
||||
onChipRamHexFile = onChipRamHexFile,
|
||||
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig
|
||||
pipelinedMemoryBusConfig = pipelinedMemoryBusConfig,
|
||||
bigEndian = bigEndianDBus
|
||||
)
|
||||
mainBusMapping += ram.io.bus -> (0x80000000l, onChipRamSize)
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@ import spinal.lib._
|
|||
import spinal.lib.bus.simple._
|
||||
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 iBus = slave(IBusSimpleBus(null))
|
||||
val dBus = slave(DBusSimpleBus())
|
||||
val dBus = slave(DBusSimpleBus(bigEndian))
|
||||
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.address := io.dBus.cmd.valid ? io.dBus.cmd.address | io.iBus.cmd.pc
|
||||
io.masterBus.cmd.data := io.dBus.cmd.data
|
||||
io.masterBus.cmd.mask := io.dBus.cmd.size.mux(
|
||||
0 -> B"0001",
|
||||
1 -> B"0011",
|
||||
default -> B"1111"
|
||||
) |<< io.dBus.cmd.address(1 downto 0)
|
||||
io.masterBus.cmd.mask := io.dBus.genMask(io.dBus.cmd)
|
||||
io.iBus.cmd.ready := io.masterBus.cmd.ready && !io.dBus.cmd.valid
|
||||
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 bus = slave(PipelinedMemoryBus(pipelinedMemoryBusConfig))
|
||||
}
|
||||
|
@ -71,6 +67,14 @@ case class MuraxPipelinedMemoryBusRam(onChipRamSize : BigInt, onChipRamHexFile :
|
|||
|
||||
if(onChipRamHexFile != null){
|
||||
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 rsp = DBusSimpleRsp()
|
||||
|
||||
|
@ -100,12 +100,27 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
}
|
||||
|
||||
def cmdS2mPipe() : DBusSimpleBus = {
|
||||
val s = DBusSimpleBus()
|
||||
val s = DBusSimpleBus(bigEndian)
|
||||
s.cmd << this.cmd.s2mPipe()
|
||||
this.rsp := s.rsp
|
||||
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 = {
|
||||
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
||||
|
||||
|
@ -130,11 +145,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
axi.writeData.arbitrationFrom(dataStage)
|
||||
axi.writeData.last := True
|
||||
axi.writeData.data := dataStage.data
|
||||
axi.writeData.strb := (dataStage.size.mux(
|
||||
U(0) -> B"0001",
|
||||
U(1) -> B"0011",
|
||||
default -> B"1111"
|
||||
) << dataStage.address(1 downto 0)).resized
|
||||
axi.writeData.strb := genMask(dataStage).resized
|
||||
|
||||
|
||||
rsp.ready := axi.r.valid
|
||||
|
@ -158,11 +169,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
mm.write := cmdStage.valid && cmdStage.wr
|
||||
mm.address := (cmdStage.address >> 2) @@ U"00"
|
||||
mm.writeData := cmdStage.data(31 downto 0)
|
||||
mm.byteEnable := (cmdStage.size.mux (
|
||||
U(0) -> B"0001",
|
||||
U(1) -> B"0011",
|
||||
default -> B"1111"
|
||||
) << cmdStage.address(1 downto 0)).resized
|
||||
mm.byteEnable := genMask(cmdStage).resized
|
||||
|
||||
|
||||
cmdStage.ready := mm.waitRequestn
|
||||
|
@ -181,11 +188,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
bus.ADR := cmdStage.address >> 2
|
||||
bus.CTI :=B"000"
|
||||
bus.BTE := "00"
|
||||
bus.SEL := (cmdStage.size.mux (
|
||||
U(0) -> B"0001",
|
||||
U(1) -> B"0011",
|
||||
default -> B"1111"
|
||||
) << cmdStage.address(1 downto 0)).resized
|
||||
bus.SEL := genMask(cmdStage).resized
|
||||
when(!cmdStage.wr) {
|
||||
bus.SEL := "1111"
|
||||
}
|
||||
|
@ -209,11 +212,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
bus.cmd.write := cmd.wr
|
||||
bus.cmd.address := cmd.address.resized
|
||||
bus.cmd.data := cmd.data
|
||||
bus.cmd.mask := cmd.size.mux(
|
||||
0 -> B"0001",
|
||||
1 -> B"0011",
|
||||
default -> B"1111"
|
||||
) |<< cmd.address(1 downto 0)
|
||||
bus.cmd.mask := genMask(cmd)
|
||||
cmd.ready := bus.cmd.ready
|
||||
|
||||
rsp.ready := bus.rsp.valid
|
||||
|
@ -265,11 +264,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
1 -> U"01",
|
||||
default -> U"11"
|
||||
)
|
||||
bus.cmd.mask := cmd.size.mux(
|
||||
0 -> B"0001",
|
||||
1 -> B"0011",
|
||||
default -> B"1111"
|
||||
) |<< cmd.address(1 downto 0)
|
||||
bus.cmd.mask := genMask(cmd)
|
||||
|
||||
cmd.ready := bus.cmd.ready
|
||||
|
||||
|
@ -289,6 +284,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
|||
emitCmdInMemoryStage : Boolean = false,
|
||||
onlyLoadWords : Boolean = false,
|
||||
withLrSc : Boolean = false,
|
||||
val bigEndian : Boolean = false,
|
||||
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
|
||||
|
||||
var dBus : DBusSimpleBus = null
|
||||
|
@ -393,7 +389,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
dBus = master(DBusSimpleBus()).setName("dBus")
|
||||
dBus = master(DBusSimpleBus(bigEndian)).setName("dBus")
|
||||
|
||||
|
||||
decode plug new Area {
|
||||
|
@ -436,11 +432,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
|||
insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0)
|
||||
|
||||
//formal
|
||||
val formalMask = dBus.cmd.size.mux(
|
||||
U(0) -> B"0001",
|
||||
U(1) -> B"0011",
|
||||
default -> B"1111"
|
||||
) |<< dBus.cmd.address(1 downto 0)
|
||||
val formalMask = dBus.genMask(dBus.cmd)
|
||||
|
||||
insert(FORMAL_MEM_ADDR) := dBus.cmd.address & U"xFFFFFFFC"
|
||||
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()
|
||||
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)){
|
||||
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(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)),
|
||||
1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)),
|
||||
default -> rspShifted //W
|
||||
|
|
|
@ -234,7 +234,8 @@ class IBusSimplePlugin( resetVector : BigInt,
|
|||
val singleInstructionPipeline : Boolean = false,
|
||||
val memoryTranslatorPortConfig : Any = null,
|
||||
relaxPredictorAddress : Boolean = true,
|
||||
predictionBuffer : Boolean = true
|
||||
predictionBuffer : Boolean = true,
|
||||
bigEndian : Boolean = false
|
||||
) extends IBusFetcherImpl(
|
||||
resetVector = resetVector,
|
||||
keepPcPlus4 = keepPcPlus4,
|
||||
|
@ -371,6 +372,12 @@ class IBusSimplePlugin( resetVector : BigInt,
|
|||
fetchRsp.pc := stages.last.output.payload
|
||||
fetchRsp.rsp := rspBuffer.output.payload
|
||||
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 exceptionDetected = False
|
||||
|
|
Loading…
Reference in New Issue