XIP is physicaly working on murax

This commit is contained in:
Dolu1990 2018-09-19 00:09:14 +02:00
parent b51ac03a5e
commit ff1d1072a7
9 changed files with 249 additions and 18 deletions

View File

@ -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];

View File

@ -0,0 +1,6 @@
*.bin
*.elf
*.map
*.d
*.asm
*.o

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)))
} }
} }

View File

@ -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)

View File

@ -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