XIP is physicaly working on murax
This commit is contained in:
parent
b51ac03a5e
commit
ff1d1072a7
|
@ -9,8 +9,8 @@ module toplevel(
|
||||||
output io_B12,
|
output io_B12,
|
||||||
input io_B10,
|
input io_B10,
|
||||||
|
|
||||||
input io_P12,
|
output io_P12,
|
||||||
output io_P11,
|
input io_P11,
|
||||||
output io_R11,
|
output io_R11,
|
||||||
output io_R12,
|
output io_R12,
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ module toplevel(
|
||||||
wire [1:0] io_xpi_data_1_write;
|
wire [1:0] io_xpi_data_1_write;
|
||||||
wire [0:0] io_xpi_ss;
|
wire [0:0] io_xpi_ss;
|
||||||
|
|
||||||
assign io_P11 = io_xpi_data_0_write[0];
|
assign io_P12 = io_xpi_data_0_write[0];
|
||||||
assign io_xpi_data_1_read[0] = io_P12;
|
assign io_xpi_data_1_read[0] = io_P11;
|
||||||
assign io_xpi_data_1_read[1] = io_P12;
|
assign io_xpi_data_1_read[1] = io_P11;
|
||||||
assign io_R11 = io_xpi_sclk_write[0];
|
assign io_R11 = io_xpi_sclk_write[0];
|
||||||
assign io_R12 = io_xpi_ss[0];
|
assign io_R12 = io_xpi_ss[0];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
*.bin
|
||||||
|
*.elf
|
||||||
|
*.map
|
||||||
|
*.d
|
||||||
|
*.asm
|
||||||
|
*.o
|
|
@ -0,0 +1,54 @@
|
||||||
|
#define CTRL_BASE 0xF001F000
|
||||||
|
#define XIP_BASE 0xE0040000
|
||||||
|
#define CTRL_DATA 0x00
|
||||||
|
#define CTRL_STATUS 0x04
|
||||||
|
#define CTRL_MODE 0x08
|
||||||
|
#define CTRL_RATE 0x20
|
||||||
|
#define CTRL_SS_SETUP 0x24
|
||||||
|
#define CTRL_SS_HOLD 0x28
|
||||||
|
#define CTRL_SS_DISABLE 0x2C
|
||||||
|
|
||||||
|
#define CTRL_XIP_CONFIG 0x40
|
||||||
|
#define CTRL_XIP_MODE 0x44
|
||||||
|
|
||||||
|
.global crtStart
|
||||||
|
.global main
|
||||||
|
|
||||||
|
#define CTRL x31
|
||||||
|
|
||||||
|
crtStart:
|
||||||
|
li x31, CTRL_BASE
|
||||||
|
sw x0, CTRL_MODE(CTRL)
|
||||||
|
li t0, 2
|
||||||
|
sw t0, CTRL_RATE(CTRL)
|
||||||
|
li t0, 4
|
||||||
|
sw t0, CTRL_SS_SETUP(CTRL)
|
||||||
|
sw t0, CTRL_SS_HOLD(CTRL)
|
||||||
|
sw t0, CTRL_SS_DISABLE(CTRL)
|
||||||
|
|
||||||
|
|
||||||
|
li a0, 0x880
|
||||||
|
call spiWrite
|
||||||
|
li a0, 0x181
|
||||||
|
call spiWrite
|
||||||
|
li a0, 0x183
|
||||||
|
call spiWrite
|
||||||
|
li a0, 0x800
|
||||||
|
call spiWrite
|
||||||
|
|
||||||
|
|
||||||
|
li t0, 0x00FF010B
|
||||||
|
sw t0, CTRL_XIP_MODE(CTRL)
|
||||||
|
li t0, 0x1
|
||||||
|
sw t0, CTRL_XIP_CONFIG(CTRL)
|
||||||
|
li t0, XIP_BASE
|
||||||
|
jr t0
|
||||||
|
|
||||||
|
|
||||||
|
spiWrite:
|
||||||
|
sw a0,CTRL_DATA(CTRL)
|
||||||
|
spiWrite_wait:
|
||||||
|
lw t0,CTRL_STATUS(CTRL)
|
||||||
|
srli t0,t0,0x10
|
||||||
|
beqz t0,spiWrite_wait
|
||||||
|
ret
|
|
@ -0,0 +1,24 @@
|
||||||
|
#define GPIO_BASE 0xF0000000
|
||||||
|
#define GPIO_OUTPUT 4
|
||||||
|
#define GPIO_OUTPUT_ENABLE 8
|
||||||
|
|
||||||
|
|
||||||
|
.global crtStart
|
||||||
|
|
||||||
|
crtStart:
|
||||||
|
|
||||||
|
|
||||||
|
li x31, GPIO_BASE
|
||||||
|
li t0, 0x000000FF
|
||||||
|
sw t0, GPIO_OUTPUT_ENABLE(x31)
|
||||||
|
|
||||||
|
li t0,0
|
||||||
|
redo:
|
||||||
|
sw t0, GPIO_OUTPUT(x31)
|
||||||
|
li t1,10000
|
||||||
|
addi t0,t0,1
|
||||||
|
loop:
|
||||||
|
addi t1,t1,-1
|
||||||
|
bnez t1, loop
|
||||||
|
j redo
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
CFLAGS= -march=rv32i -mabi=ilp32 -g -O3 -MD
|
||||||
|
LFLAGS= -nostdlib -mcmodel=medany -nostartfiles -ffreestanding -fPIC -fPIE
|
||||||
|
|
||||||
|
|
||||||
|
all: crt.S demo.S
|
||||||
|
riscv64-unknown-elf-gcc -c $(CFLAGS) -o crt.o crt.S
|
||||||
|
riscv64-unknown-elf-gcc $(CFLAGS) -o crt.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,crt.map,--print-memory-usage
|
||||||
|
riscv64-unknown-elf-objdump -S -d crt.elf > crt.asm
|
||||||
|
riscv64-unknown-elf-objcopy -O binary crt.elf crt.bin
|
||||||
|
|
||||||
|
riscv64-unknown-elf-gcc -c $(CFLAGS) -o demo.o demo.S
|
||||||
|
riscv64-unknown-elf-gcc $(CFLAGS) -o demo.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,demo.map,--print-memory-usage
|
||||||
|
riscv64-unknown-elf-objdump -S -d demo.elf > demo.asm
|
||||||
|
riscv64-unknown-elf-objcopy -O binary demo.elf demo.bin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f *.bin
|
||||||
|
rm -f *.elf
|
||||||
|
rm -f *.asm
|
||||||
|
rm -f *.map
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
*/
|
||||||
|
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
|
||||||
|
OUTPUT_ARCH(riscv)
|
||||||
|
ENTRY(crtStart)
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
|
||||||
|
.vector : {
|
||||||
|
*crt.o(.text);
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.memory : {
|
||||||
|
*(.text);
|
||||||
|
end = .;
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ctors_start = .;
|
||||||
|
KEEP(*(.init_array*))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ctors_end = .;
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* This is used by the startup in order to initialize the .bss secion */
|
||||||
|
_bss_start = .;
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_bss_end = .;
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
.noinit (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.noinit .noinit.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
._stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE (_stack_end = .);
|
||||||
|
. = . + _stack_size;
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE (_stack_start = .);
|
||||||
|
} > mem
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -44,18 +44,13 @@ case class MuraxConfig(coreFrequency : HertzNumber,
|
||||||
require(pipelineApbBridge || pipelineMainBus, "At least pipelineMainBus or pipelineApbBridge should be enable to avoid wipe transactions")
|
require(pipelineApbBridge || pipelineMainBus, "At least pipelineMainBus or pipelineApbBridge should be enable to avoid wipe transactions")
|
||||||
val genXpi = xipConfig != null
|
val genXpi = xipConfig != null
|
||||||
|
|
||||||
def addXip(): MuraxConfig = copy(xipConfig = SpiDdrMasterCtrl.MemoryMappingParameters(
|
|
||||||
SpiDdrMasterCtrl.Parameters(8, 12, SpiDdrParameter(2, 1)).addAllMods(),
|
|
||||||
cmdFifoDepth = 32,
|
|
||||||
rspFifoDepth = 32,
|
|
||||||
xip = SpiDdrMasterCtrl.XipBusParameters(addressWidth = 24, dataWidth = 32)
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
object MuraxConfig{
|
object MuraxConfig{
|
||||||
def default = MuraxConfig(
|
def default : MuraxConfig = default(false)
|
||||||
|
def default(withXip : Boolean) = MuraxConfig(
|
||||||
coreFrequency = 12 MHz,
|
coreFrequency = 12 MHz,
|
||||||
onChipRamSize = 8 kB,
|
onChipRamSize = 8 kB,
|
||||||
onChipRamHexFile = null,
|
onChipRamHexFile = null,
|
||||||
|
@ -63,10 +58,15 @@ object MuraxConfig{
|
||||||
pipelineMainBus = false,
|
pipelineMainBus = false,
|
||||||
pipelineApbBridge = true,
|
pipelineApbBridge = true,
|
||||||
gpioWidth = 32,
|
gpioWidth = 32,
|
||||||
xipConfig = null,
|
xipConfig = ifGen(withXip) (SpiDdrMasterCtrl.MemoryMappingParameters(
|
||||||
|
SpiDdrMasterCtrl.Parameters(8, 12, SpiDdrParameter(2, 1)).addAllMods(),
|
||||||
|
cmdFifoDepth = 32,
|
||||||
|
rspFifoDepth = 32,
|
||||||
|
xip = SpiDdrMasterCtrl.XipBusParameters(addressWidth = 24, dataWidth = 32)
|
||||||
|
)),
|
||||||
cpuPlugins = ArrayBuffer( //DebugPlugin added by the toplevel
|
cpuPlugins = ArrayBuffer( //DebugPlugin added by the toplevel
|
||||||
new IBusSimplePlugin(
|
new IBusSimplePlugin(
|
||||||
resetVector = 0x80000000l,
|
resetVector = if(withXip) 0xF001E000l else 0x80000000l,
|
||||||
relaxedPcCalculation = true,
|
relaxedPcCalculation = true,
|
||||||
prediction = NONE,
|
prediction = NONE,
|
||||||
catchAccessFault = false,
|
catchAccessFault = false,
|
||||||
|
@ -224,7 +224,9 @@ case class Murax(config : MuraxConfig) extends Component{
|
||||||
val timerInterrupt = False
|
val timerInterrupt = False
|
||||||
val externalInterrupt = False
|
val externalInterrupt = False
|
||||||
for(plugin <- cpu.plugins) plugin match{
|
for(plugin <- cpu.plugins) plugin match{
|
||||||
case plugin : IBusSimplePlugin => mainBusArbiter.io.iBus <> plugin.iBus
|
case plugin : IBusSimplePlugin =>
|
||||||
|
mainBusArbiter.io.iBus.cmd <> plugin.iBus.cmd.halfPipe() //TODO !!
|
||||||
|
mainBusArbiter.io.iBus.rsp <> plugin.iBus.rsp
|
||||||
case plugin : DBusSimplePlugin => {
|
case plugin : DBusSimplePlugin => {
|
||||||
if(!pipelineDBus)
|
if(!pipelineDBus)
|
||||||
mainBusArbiter.io.dBus <> plugin.dBus
|
mainBusArbiter.io.dBus <> plugin.dBus
|
||||||
|
@ -289,7 +291,7 @@ case class Murax(config : MuraxConfig) extends Component{
|
||||||
apbMapping += ctrl.io.apb -> (0x1F000, 4 kB)
|
apbMapping += ctrl.io.apb -> (0x1F000, 4 kB)
|
||||||
|
|
||||||
val accessBus = new SimpleBus(SimpleBusConfig(24,32))
|
val accessBus = new SimpleBus(SimpleBusConfig(24,32))
|
||||||
mainBusMapping += accessBus -> (0x90000000l, 16 MB)
|
mainBusMapping += accessBus -> (0xE0000000l, 16 MB)
|
||||||
|
|
||||||
ctrl.io.xip.cmd.valid <> (accessBus.cmd.valid && !accessBus.cmd.wr)
|
ctrl.io.xip.cmd.valid <> (accessBus.cmd.valid && !accessBus.cmd.wr)
|
||||||
ctrl.io.xip.cmd.ready <> accessBus.cmd.ready
|
ctrl.io.xip.cmd.ready <> accessBus.cmd.ready
|
||||||
|
@ -297,6 +299,9 @@ case class Murax(config : MuraxConfig) extends Component{
|
||||||
|
|
||||||
ctrl.io.xip.rsp.valid <> accessBus.rsp.valid
|
ctrl.io.xip.rsp.valid <> accessBus.rsp.valid
|
||||||
ctrl.io.xip.rsp.payload <> accessBus.rsp.data
|
ctrl.io.xip.rsp.payload <> accessBus.rsp.data
|
||||||
|
|
||||||
|
val bootloader = Apb3Rom("src/main/c/murax/xipBootloader/crt.bin")
|
||||||
|
apbMapping += bootloader.io.apb -> (0x1E000, 4 kB)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -327,7 +332,7 @@ object Murax{
|
||||||
|
|
||||||
object MuraxWithXip{
|
object MuraxWithXip{
|
||||||
def main(args: Array[String]) {
|
def main(args: Array[String]) {
|
||||||
SpinalVerilog(Murax(MuraxConfig.default.addXip()))
|
SpinalVerilog(Murax(MuraxConfig.default(withXip = true)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package vexriscv.demo
|
package vexriscv.demo
|
||||||
|
|
||||||
|
import java.nio.{ByteBuffer, ByteOrder}
|
||||||
|
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib.bus.amba3.apb.{Apb3, Apb3Config, Apb3SlaveFactory}
|
import spinal.lib.bus.amba3.apb.{Apb3, Apb3Config, Apb3SlaveFactory}
|
||||||
import spinal.lib.bus.misc.SizeMapping
|
import spinal.lib.bus.misc.SizeMapping
|
||||||
|
@ -96,6 +98,27 @@ class MuraxSimpleBusRam(onChipRamSize : BigInt, onChipRamHexFile : String, simpl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case class Apb3Rom(onChipRamBinFile : String) extends Component{
|
||||||
|
import java.nio.file.{Files, Paths}
|
||||||
|
val byteArray = Files.readAllBytes(Paths.get(onChipRamBinFile))
|
||||||
|
val wordCount = (byteArray.length+3)/4
|
||||||
|
val buffer = ByteBuffer.wrap(Files.readAllBytes(Paths.get(onChipRamBinFile))).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
val wordArray = (0 until wordCount).map(i => {
|
||||||
|
val v = buffer.getInt
|
||||||
|
if(v < 0) BigInt(v.toLong & 0xFFFFFFFFl) else BigInt(v)
|
||||||
|
})
|
||||||
|
|
||||||
|
val io = new Bundle{
|
||||||
|
val apb = slave(Apb3(log2Up(wordCount*4),32))
|
||||||
|
}
|
||||||
|
|
||||||
|
val rom = Mem(Bits(32 bits), wordCount) initBigInt(wordArray)
|
||||||
|
// io.apb.PRDATA := rom.readSync(io.apb.PADDR >> 2)
|
||||||
|
io.apb.PRDATA := rom.readAsync(RegNext(io.apb.PADDR >> 2))
|
||||||
|
io.apb.PREADY := True
|
||||||
|
}
|
||||||
|
|
||||||
class MuraxSimpleBusToApbBridge(apb3Config: Apb3Config, pipelineBridge : Boolean, simpleBusConfig : SimpleBusConfig) extends Component{
|
class MuraxSimpleBusToApbBridge(apb3Config: Apb3Config, pipelineBridge : Boolean, simpleBusConfig : SimpleBusConfig) extends Component{
|
||||||
assert(apb3Config.dataWidth == simpleBusConfig.dataWidth)
|
assert(apb3Config.dataWidth == simpleBusConfig.dataWidth)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import scala.collection.mutable
|
||||||
object MuraxSim {
|
object MuraxSim {
|
||||||
def main(args: Array[String]): Unit = {
|
def main(args: Array[String]): Unit = {
|
||||||
// def config = MuraxConfig.default.copy(onChipRamSize = 256 kB)
|
// def config = MuraxConfig.default.copy(onChipRamSize = 256 kB)
|
||||||
def config = MuraxConfig.default.copy(onChipRamSize = 4 kB, onChipRamHexFile = "src/main/ressource/hex/muraxDemo.hex").addXip()
|
def config = MuraxConfig.default(withXip = true).copy(onChipRamSize = 4 kB, onChipRamHexFile = "src/main/ressource/hex/muraxDemo.hex")
|
||||||
val simSlowDown = true
|
val simSlowDown = true
|
||||||
SimConfig.allOptimisation.withWave.compile(new Murax(config)).doSimUntilVoid{dut =>
|
SimConfig.allOptimisation.withWave.compile(new Murax(config)).doSimUntilVoid{dut =>
|
||||||
val mainClkPeriod = (1e12/dut.config.coreFrequency.toDouble).toLong
|
val mainClkPeriod = (1e12/dut.config.coreFrequency.toDouble).toLong
|
||||||
|
|
Loading…
Reference in New Issue