VexRiscv in Briey SoC is working on FPGA (including jtag debugging)
This commit is contained in:
parent
213e154b40
commit
6b62d8da52
|
@ -7,6 +7,6 @@ scalaVersion := "2.11.8"
|
|||
EclipseKeys.withSource := true
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "0.10.11",
|
||||
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "0.10.11"
|
||||
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "0.10.13",
|
||||
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "0.10.13"
|
||||
)
|
|
@ -3,6 +3,7 @@ package SpinalRiscv.Plugin
|
|||
import SpinalRiscv._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axi._
|
||||
|
||||
|
||||
case class DBusSimpleCmd() extends Bundle{
|
||||
|
@ -22,6 +23,20 @@ case class DBusSimpleRsp() extends Bundle with IMasterSlave{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
object DBusSimpleBus{
|
||||
def getAxi4Config() = Axi4Config(
|
||||
addressWidth = 32,
|
||||
dataWidth = 32,
|
||||
useId = false,
|
||||
useRegion = false,
|
||||
useBurst = false,
|
||||
useLock = false,
|
||||
useQos = false,
|
||||
useLen = false,
|
||||
useResp = true
|
||||
)
|
||||
}
|
||||
case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
||||
val cmd = Stream(DBusSimpleCmd())
|
||||
val rsp = DBusSimpleRsp()
|
||||
|
@ -30,8 +45,56 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
master(cmd)
|
||||
slave(rsp)
|
||||
}
|
||||
|
||||
def toAxi4Shared(stageCmd : Boolean = false): Axi4Shared = {
|
||||
val axi = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
||||
val pendingWritesMax = 7
|
||||
val pendingWrites = CounterUpDown(
|
||||
stateCount = pendingWritesMax + 1,
|
||||
incWhen = axi.sharedCmd.fire && axi.sharedCmd.write,
|
||||
decWhen = axi.writeRsp.fire
|
||||
)
|
||||
|
||||
val cmdPreFork = if (stageCmd) cmd.stage.stage() else cmd
|
||||
val (cmdFork, dataFork) = StreamFork2(cmdPreFork.haltWhen((pendingWrites =/= 0 && !cmdPreFork.wr) || pendingWrites === pendingWritesMax))
|
||||
axi.sharedCmd.arbitrationFrom(cmdFork)
|
||||
axi.sharedCmd.write := cmdFork.wr
|
||||
axi.sharedCmd.prot := "010"
|
||||
axi.sharedCmd.cache := "1111"
|
||||
axi.sharedCmd.size := cmdFork.size.resized
|
||||
axi.sharedCmd.addr := cmdFork.address
|
||||
|
||||
val dataStage = dataFork.throwWhen(!dataFork.wr)
|
||||
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
|
||||
|
||||
|
||||
rsp.ready := axi.r.valid
|
||||
rsp.error := !axi.r.isOKAY()
|
||||
rsp.data := axi.r.data
|
||||
|
||||
axi.r.ready := True
|
||||
axi.b.ready := True
|
||||
|
||||
|
||||
//TODO remove
|
||||
val axi2 = Axi4Shared(DBusSimpleBus.getAxi4Config())
|
||||
axi.arw >/-> axi2.arw
|
||||
axi.w >/-> axi2.w
|
||||
axi.r <-/< axi2.r
|
||||
axi.b <-/< axi2.b
|
||||
|
||||
axi2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Boolean) extends Plugin[VexRiscv]{
|
||||
|
||||
var dBus : DBusSimpleBus = null
|
||||
|
@ -124,7 +187,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
|
||||
|
||||
insert(MEMORY_READ_DATA) := dBus.rsp.data
|
||||
arbitration.haltIt setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.rsp.ready)
|
||||
arbitration.haltIt setWhen(arbitration.isValid && input(MEMORY_ENABLE) && input(REGFILE_WRITE_VALID) && !dBus.rsp.ready)
|
||||
|
||||
if(catchAccessFault){
|
||||
memoryExceptionPort.valid := arbitration.isValid && input(MEMORY_ENABLE) && dBus.rsp.ready && dBus.rsp.error
|
||||
|
|
|
@ -5,6 +5,7 @@ import SpinalRiscv._
|
|||
import SpinalRiscv.ip._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba3.apb.{Apb3Config, Apb3}
|
||||
|
||||
|
||||
case class DebugExtensionCmd() extends Bundle{
|
||||
|
@ -24,6 +25,24 @@ case class DebugExtensionBus() extends Bundle with IMasterSlave{
|
|||
master(cmd)
|
||||
in(rsp)
|
||||
}
|
||||
|
||||
def toApb3(): Apb3 ={
|
||||
val apb = Apb3(Apb3Config(
|
||||
addressWidth = 8,
|
||||
dataWidth = 32,
|
||||
useSlaveError = false
|
||||
))
|
||||
|
||||
cmd.valid := apb.PSEL(0) && apb.PENABLE
|
||||
cmd.wr := apb.PWRITE
|
||||
cmd.address := apb.PADDR
|
||||
cmd.data := apb.PWDATA
|
||||
|
||||
apb.PREADY := cmd.ready
|
||||
apb.PRDATA := rsp.data
|
||||
|
||||
apb
|
||||
}
|
||||
}
|
||||
|
||||
case class DebugExtensionIo() extends Bundle with IMasterSlave{
|
||||
|
|
|
@ -3,6 +3,7 @@ package SpinalRiscv.Plugin
|
|||
import SpinalRiscv.{Stageable, ExceptionService, ExceptionCause, VexRiscv}
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axi._
|
||||
|
||||
|
||||
case class IBusSimpleCmd() extends Bundle{
|
||||
|
@ -19,8 +20,21 @@ case class IBusSimpleRsp() extends Bundle with IMasterSlave{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
case class IBusSimpleBus() extends Bundle with IMasterSlave{
|
||||
object IBusSimpleBus{
|
||||
def getAxi4Config() = Axi4Config(
|
||||
addressWidth = 32,
|
||||
dataWidth = 32,
|
||||
useId = false,
|
||||
useRegion = false,
|
||||
useBurst = false,
|
||||
useLock = false,
|
||||
useQos = false,
|
||||
useLen = false,
|
||||
useResp = true,
|
||||
useSize = false
|
||||
)
|
||||
}
|
||||
case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMasterSlave{
|
||||
var cmd = Stream(IBusSimpleCmd())
|
||||
var rsp = IBusSimpleRsp()
|
||||
|
||||
|
@ -28,6 +42,31 @@ case class IBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
master(cmd)
|
||||
slave(rsp)
|
||||
}
|
||||
|
||||
|
||||
def toAxi4ReadOnly(): Axi4ReadOnly = {
|
||||
assert(!interfaceKeepData)
|
||||
val axi = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
|
||||
|
||||
axi.ar.valid := cmd.valid
|
||||
axi.ar.addr := cmd.pc(axi.readCmd.addr.getWidth -1 downto 2) @@ U"00"
|
||||
axi.ar.prot := "110"
|
||||
axi.ar.cache := "1111"
|
||||
cmd.ready := axi.ar.ready
|
||||
|
||||
|
||||
rsp.ready := axi.r.valid
|
||||
rsp.inst := axi.r.data
|
||||
rsp.error := !axi.r.isOKAY()
|
||||
axi.r.ready := True
|
||||
|
||||
|
||||
//TODO remove
|
||||
val axi2 = Axi4ReadOnly(IBusSimpleBus.getAxi4Config())
|
||||
axi.ar >/-> axi2.ar
|
||||
axi.r <-/< axi2.r
|
||||
axi2
|
||||
}
|
||||
}
|
||||
|
||||
class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean) extends Plugin[VexRiscv]{
|
||||
|
@ -45,19 +84,41 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
|
|||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
iBus = master(IBusSimpleBus(interfaceKeepData)).setName("iBus")
|
||||
val pendingCmd = RegInit(False) clearWhen(iBus.rsp.ready) setWhen(iBus.cmd.fire)
|
||||
|
||||
require(interfaceKeepData)
|
||||
iBus = master(IBusSimpleBus()).setName("iBus")
|
||||
|
||||
//Emit iBus.cmd request
|
||||
iBus.cmd.valid := prefetch.arbitration.isFiring //prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers
|
||||
iBus.cmd.pc := prefetch.output(PC)
|
||||
prefetch.arbitration.haltIt setWhen(!iBus.cmd.ready)
|
||||
prefetch.arbitration.haltIt setWhen(!iBus.cmd.ready || (pendingCmd && !iBus.rsp.ready)) //TODO rework arbitration of iBusCmdvalid and halt it
|
||||
|
||||
|
||||
//Bus rsp buffer
|
||||
val rspBuffer = if(!interfaceKeepData) new Area{
|
||||
val valid = RegInit(False) setWhen(iBus.rsp.ready) clearWhen(!fetch.arbitration.isStuck)
|
||||
val error = Reg(Bool)
|
||||
val data = Reg(Bits(32 bits))
|
||||
when(!valid) {
|
||||
data := iBus.rsp.inst
|
||||
error := iBus.rsp.error
|
||||
}
|
||||
} else null
|
||||
|
||||
//Insert iBus.rsp into INSTRUCTION
|
||||
fetch.insert(INSTRUCTION) := iBus.rsp.inst
|
||||
fetch.insert(IBUS_ACCESS_ERROR) := iBus.rsp.error
|
||||
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
|
||||
if(!interfaceKeepData) {
|
||||
when(rspBuffer.valid) {
|
||||
fetch.insert(INSTRUCTION) := rspBuffer.data
|
||||
fetch.insert(IBUS_ACCESS_ERROR) := rspBuffer.error
|
||||
}
|
||||
}
|
||||
|
||||
if(interfaceKeepData)
|
||||
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
|
||||
else
|
||||
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready && !rspBuffer.valid)
|
||||
|
||||
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
|
||||
decode.insert(INSTRUCTION_READY) := True
|
||||
|
||||
|
|
|
@ -220,16 +220,17 @@ object TopLevel {
|
|||
new LightShifterPlugin,
|
||||
// new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
// new HazardSimplePlugin(
|
||||
// bypassExecute = false,
|
||||
// bypassMemory = false,
|
||||
// bypassWriteBack = false,
|
||||
// bypassWriteBackBuffer = false,
|
||||
// pessimisticUseSrc = false,
|
||||
// pessimisticWriteRegFile = false,
|
||||
// pessimisticAddressMatch = false
|
||||
// ),
|
||||
new HazardPessimisticPlugin,
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = false,
|
||||
bypassMemory = false,
|
||||
bypassWriteBack = false,
|
||||
bypassWriteBackBuffer = false,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
// new HazardPessimisticPlugin,
|
||||
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||
// new MulPlugin,
|
||||
// new DivPlugin,
|
||||
// new MachineCsr(csrConfig),
|
||||
|
@ -250,56 +251,10 @@ object TopLevel {
|
|||
interfaceKeepData = true,
|
||||
catchAccessFault = true
|
||||
),
|
||||
// new IBusCachedPlugin(
|
||||
// config = InstructionCacheConfig(
|
||||
// cacheSize = 4096,
|
||||
// bytePerLine =32,
|
||||
// wayCount = 1,
|
||||
// wrappedMemAccess = true,
|
||||
// addressWidth = 32,
|
||||
// cpuDataWidth = 32,
|
||||
// memDataWidth = 32,
|
||||
// catchIllegalAccess = true,
|
||||
// catchAccessFault = true,
|
||||
// catchMemoryTranslationMiss = true,
|
||||
// asyncTagMemory = false,
|
||||
// twoStageLogic = true
|
||||
// ),
|
||||
// askMemoryTranslation = true,
|
||||
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||
// portTlbSize = 4
|
||||
// )
|
||||
// ),
|
||||
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = true,
|
||||
catchAccessFault = true
|
||||
),
|
||||
// new DBusCachedPlugin(
|
||||
// config = new DataCacheConfig(
|
||||
// cacheSize = 4096,
|
||||
// bytePerLine = 32,
|
||||
// wayCount = 1,
|
||||
// addressWidth = 32,
|
||||
// cpuDataWidth = 32,
|
||||
// memDataWidth = 32,
|
||||
// catchAccessError = true,
|
||||
// catchIllegal = true,
|
||||
// catchUnaligned = true,
|
||||
// catchMemoryTranslationMiss = true,
|
||||
// tagSizeShift = 2
|
||||
// ),
|
||||
// askMemoryTranslation = true,
|
||||
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||
// portTlbSize = 6
|
||||
// )
|
||||
// ),
|
||||
|
||||
// new MemoryTranslatorPlugin(
|
||||
// tlbSize = 32,
|
||||
// virtualRange = _(31 downto 28) === 0xC,
|
||||
// ioRange = _(31 downto 28) === 0xF
|
||||
// ),
|
||||
new CsrPlugin(csrConfigSmall),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = true
|
||||
|
@ -336,8 +291,8 @@ object TopLevel {
|
|||
)
|
||||
)
|
||||
|
||||
val toplevel = new VexRiscv(configFull)
|
||||
// val toplevel = new VexRiscv(configLight)
|
||||
// val toplevel = new VexRiscv(configFull)
|
||||
val toplevel = new VexRiscv(configLight)
|
||||
// val toplevel = new VexRiscv(configTest)
|
||||
toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute(Verilator.public)
|
||||
toplevel.decode.input(toplevel.config.PC).addAttribute(Verilator.public)
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
package SpinalRiscv.demo
|
||||
|
||||
|
||||
import SpinalRiscv.Plugin._
|
||||
import SpinalRiscv._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba3.apb._
|
||||
import spinal.lib.bus.amba4.axi._
|
||||
import spinal.lib.com.jtag.Jtag
|
||||
import spinal.lib.com.uart.{Uart, UartCtrlGenerics, UartCtrlMemoryMappedConfig, Apb3UartCtrl}
|
||||
import spinal.lib.graphic.RgbConfig
|
||||
import spinal.lib.graphic.vga.{Vga, Axi4VgaCtrlGenerics, Axi4VgaCtrl}
|
||||
import spinal.lib.io.TriStateArray
|
||||
import spinal.lib.memory.sdram._
|
||||
import spinal.lib.soc.pinsec.{PinsecTimerCtrlExternal, PinsecTimerCtrl}
|
||||
import spinal.lib.system.debugger.{JtagAxi4SharedDebugger, SystemDebuggerConfig}
|
||||
|
||||
|
||||
case class BrieyConfig(axiFrequency : HertzNumber,
|
||||
onChipRamSize : BigInt,
|
||||
sdramLayout: SdramLayout,
|
||||
sdramTimings: SdramTimings)
|
||||
|
||||
object BrieyConfig{
|
||||
def default = {
|
||||
val config = BrieyConfig(
|
||||
axiFrequency = 50 MHz,
|
||||
onChipRamSize = 4 kB,
|
||||
sdramLayout = IS42x320D.layout,
|
||||
sdramTimings = IS42x320D.timingGrade7
|
||||
)
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Briey(config: BrieyConfig) extends Component{
|
||||
|
||||
//Legacy constructor
|
||||
def this(axiFrequency: HertzNumber) {
|
||||
this(BrieyConfig.default.copy(axiFrequency = axiFrequency))
|
||||
}
|
||||
|
||||
import config._
|
||||
val debug = true
|
||||
val interruptCount = 4
|
||||
def vgaRgbConfig = RgbConfig(5,6,5)
|
||||
|
||||
val io = new Bundle{
|
||||
//Clocks / reset
|
||||
val asyncReset = in Bool
|
||||
val axiClk = in Bool
|
||||
val vgaClk = in Bool
|
||||
|
||||
//Main components IO
|
||||
val jtag = slave(Jtag())
|
||||
val sdram = master(SdramInterface(sdramLayout))
|
||||
|
||||
//Peripherals IO
|
||||
val gpioA = master(TriStateArray(32 bits))
|
||||
val gpioB = master(TriStateArray(32 bits))
|
||||
val uart = master(Uart())
|
||||
val vga = master(Vga(vgaRgbConfig))
|
||||
val timerExternal = in(PinsecTimerCtrlExternal())
|
||||
}
|
||||
|
||||
val resetCtrlClockDomain = ClockDomain(
|
||||
clock = io.axiClk,
|
||||
config = ClockDomainConfig(
|
||||
resetKind = BOOT
|
||||
)
|
||||
)
|
||||
|
||||
val resetCtrl = new ClockingArea(resetCtrlClockDomain) {
|
||||
val axiResetUnbuffered = False
|
||||
val coreResetUnbuffered = False
|
||||
|
||||
//Implement an counter to keep the reset axiResetOrder high 64 cycles
|
||||
// Also this counter will automaticly do a reset when the system boot.
|
||||
val axiResetCounter = Reg(UInt(6 bits)) init(0)
|
||||
when(axiResetCounter =/= U(axiResetCounter.range -> true)){
|
||||
axiResetCounter := axiResetCounter + 1
|
||||
axiResetUnbuffered := True
|
||||
}
|
||||
when(BufferCC(io.asyncReset)){
|
||||
axiResetCounter := 0
|
||||
}
|
||||
|
||||
//When an axiResetOrder happen, the core reset will as well
|
||||
when(axiResetUnbuffered){
|
||||
coreResetUnbuffered := True
|
||||
}
|
||||
|
||||
//Create all reset used later in the design
|
||||
val axiReset = RegNext(axiResetUnbuffered)
|
||||
val coreReset = RegNext(coreResetUnbuffered)
|
||||
val vgaReset = BufferCC(axiResetUnbuffered)
|
||||
}
|
||||
|
||||
val axiClockDomain = ClockDomain(
|
||||
clock = io.axiClk,
|
||||
reset = resetCtrl.axiReset,
|
||||
frequency = FixedFrequency(axiFrequency) //The frequency information is used by the SDRAM controller
|
||||
)
|
||||
|
||||
val coreClockDomain = ClockDomain(
|
||||
clock = io.axiClk,
|
||||
reset = resetCtrl.coreReset
|
||||
)
|
||||
|
||||
val vgaClockDomain = ClockDomain(
|
||||
clock = io.vgaClk,
|
||||
reset = resetCtrl.vgaReset
|
||||
)
|
||||
|
||||
val jtagClockDomain = ClockDomain(
|
||||
clock = io.jtag.tck
|
||||
)
|
||||
|
||||
val axi = new ClockingArea(axiClockDomain) {
|
||||
val core = new ClockingArea(coreClockDomain){
|
||||
val configLight = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new PcManagerSimplePlugin(0x00000000l, false),
|
||||
new IBusSimplePlugin(
|
||||
interfaceKeepData = false,
|
||||
catchAccessFault = false
|
||||
),
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = false,
|
||||
catchAccessFault = false
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false
|
||||
),
|
||||
new LightShifterPlugin,
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = false,
|
||||
bypassMemory = false,
|
||||
bypassWriteBack = false,
|
||||
bypassWriteBackBuffer = false,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
new DebugPlugin(axiClockDomain),
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
catchAddressMisaligned = false,
|
||||
prediction = NONE
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val cpu = new VexRiscv(configLight)
|
||||
var iBus : Axi4Bus = null
|
||||
var dBus : Axi4Bus = null
|
||||
var debugBus : Apb3 = null
|
||||
for(plugin <- configLight.plugins) plugin match{
|
||||
case plugin : IBusSimplePlugin => iBus = plugin.iBus.toAxi4ReadOnly()
|
||||
case plugin : DBusSimplePlugin => dBus = plugin.dBus.toAxi4Shared()
|
||||
case plugin : DebugPlugin => {
|
||||
resetCtrl.coreResetUnbuffered setWhen(plugin.io.resetOut)
|
||||
debugBus = plugin.io.bus.toApb3()
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
val ram = Axi4SharedOnChipRam(
|
||||
dataWidth = 32,
|
||||
byteCount = onChipRamSize,
|
||||
idWidth = 4
|
||||
)
|
||||
|
||||
val sdramCtrl = Axi4SharedSdramCtrl(
|
||||
axiDataWidth = 32,
|
||||
axiIdWidth = 4,
|
||||
layout = sdramLayout,
|
||||
timing = sdramTimings,
|
||||
CAS = 3
|
||||
)
|
||||
|
||||
val jtagCtrl = JtagAxi4SharedDebugger(SystemDebuggerConfig(
|
||||
memAddressWidth = 32,
|
||||
memDataWidth = 32,
|
||||
remoteCmdWidth = 1
|
||||
))
|
||||
|
||||
|
||||
val apbBridge = Axi4SharedToApb3Bridge(
|
||||
addressWidth = 20,
|
||||
dataWidth = 32,
|
||||
idWidth = 4
|
||||
)
|
||||
|
||||
val gpioACtrl = Apb3Gpio(
|
||||
gpioWidth = 32
|
||||
)
|
||||
val gpioBCtrl = Apb3Gpio(
|
||||
gpioWidth = 32
|
||||
)
|
||||
val timerCtrl = PinsecTimerCtrl()
|
||||
|
||||
val uartCtrlConfig = UartCtrlMemoryMappedConfig(
|
||||
uartCtrlConfig = UartCtrlGenerics(
|
||||
dataWidthMax = 8,
|
||||
clockDividerWidth = 20,
|
||||
preSamplingSize = 1,
|
||||
samplingSize = 5,
|
||||
postSamplingSize = 2
|
||||
),
|
||||
txFifoDepth = 16,
|
||||
rxFifoDepth = 16
|
||||
)
|
||||
val uartCtrl = Apb3UartCtrl(uartCtrlConfig)
|
||||
|
||||
|
||||
val vgaCtrlConfig = Axi4VgaCtrlGenerics(
|
||||
axiAddressWidth = 32,
|
||||
axiDataWidth = 32,
|
||||
burstLength = 8,
|
||||
frameSizeMax = 2048*1512*2,
|
||||
fifoSize = 512,
|
||||
rgbConfig = vgaRgbConfig,
|
||||
vgaClock = vgaClockDomain
|
||||
)
|
||||
val vgaCtrl = Axi4VgaCtrl(vgaCtrlConfig)
|
||||
|
||||
val axiCrossbar = Axi4CrossbarFactory()
|
||||
|
||||
axiCrossbar.addSlaves(
|
||||
ram.io.axi -> (0x00000000L, onChipRamSize),
|
||||
sdramCtrl.io.axi -> (0x40000000L, sdramLayout.capacity),
|
||||
apbBridge.io.axi -> (0xF0000000L, 1 MB)
|
||||
)
|
||||
|
||||
axiCrossbar.addConnections(
|
||||
core.iBus -> List(ram.io.axi, sdramCtrl.io.axi),
|
||||
core.dBus -> List(ram.io.axi, sdramCtrl.io.axi, apbBridge.io.axi),
|
||||
jtagCtrl.io.axi -> List(ram.io.axi, sdramCtrl.io.axi, apbBridge.io.axi),
|
||||
vgaCtrl.io.axi -> List( sdramCtrl.io.axi)
|
||||
)
|
||||
|
||||
|
||||
axiCrossbar.addPipelining(apbBridge.io.axi,(crossbar,bridge) => {
|
||||
crossbar.sharedCmd.halfPipe() >> bridge.sharedCmd
|
||||
crossbar.writeData.halfPipe() >> bridge.writeData
|
||||
crossbar.writeRsp << bridge.writeRsp
|
||||
crossbar.readRsp << bridge.readRsp
|
||||
})
|
||||
|
||||
axiCrossbar.addPipelining(sdramCtrl.io.axi,(crossbar,ctrl) => {
|
||||
crossbar.sharedCmd.halfPipe() >> ctrl.sharedCmd
|
||||
crossbar.writeData >/-> ctrl.writeData
|
||||
crossbar.writeRsp << ctrl.writeRsp
|
||||
crossbar.readRsp << ctrl.readRsp
|
||||
})
|
||||
|
||||
axiCrossbar.build()
|
||||
|
||||
|
||||
val apbDecoder = Apb3Decoder(
|
||||
master = apbBridge.io.apb,
|
||||
slaves = List(
|
||||
gpioACtrl.io.apb -> (0x00000, 4 kB),
|
||||
gpioBCtrl.io.apb -> (0x01000, 4 kB),
|
||||
uartCtrl.io.apb -> (0x10000, 4 kB),
|
||||
timerCtrl.io.apb -> (0x20000, 4 kB),
|
||||
vgaCtrl.io.apb -> (0x30000, 4 kB),
|
||||
core.debugBus -> (0xF0000, 4 kB)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
io.gpioA <> axi.gpioACtrl.io.gpio
|
||||
io.gpioB <> axi.gpioBCtrl.io.gpio
|
||||
io.timerExternal <> axi.timerCtrl.io.external
|
||||
io.jtag <> axi.jtagCtrl.io.jtag
|
||||
io.uart <> axi.uartCtrl.io.uart
|
||||
io.sdram <> axi.sdramCtrl.io.sdram
|
||||
io.vga <> axi.vgaCtrl.io.vga
|
||||
}
|
||||
|
||||
|
||||
object Briey{
|
||||
def main(args: Array[String]) {
|
||||
val config = SpinalConfig().dumpWave()
|
||||
config.generateVerilog({
|
||||
val toplevel = new Briey(BrieyConfig.default)
|
||||
/*toplevel.axi.ram.ram.initialContent = new Array[BigInt](toplevel.axi.ram.ram.wordCount)
|
||||
toplevel.axi.ram.ram.initialContent(0) = 0x00000013
|
||||
toplevel.axi.ram.ram.initialContent(1) = 0x10000013
|
||||
toplevel.axi.ram.ram.initialContent(2) = 0x20000013
|
||||
toplevel.axi.ram.ram.initialContent(3) = 0x30000013
|
||||
toplevel.axi.ram.ram.initialContent(4) = 0x40000013
|
||||
toplevel.axi.ram.ram.initialContent(5) = 0x50000013
|
||||
toplevel.axi.ram.ram.initialContent(6) = 0x60000013
|
||||
toplevel.axi.ram.ram.initialContent(7) = 0x70000013*/
|
||||
|
||||
toplevel
|
||||
})
|
||||
}
|
||||
}
|
|
@ -466,7 +466,7 @@ public:
|
|||
ws->iBusAccess(top->iBus_cmd_payload_pc,&inst_next,&error_next);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO doesn't catch when instruction removed ?
|
||||
virtual void postCycle(){
|
||||
top->iBus_rsp_ready = !pending;
|
||||
if(pending && (!ws->iStall || VL_RANDOM_I(7) < 100)){
|
||||
|
@ -772,7 +772,7 @@ public:
|
|||
uint32_t address = *((uint32_t*)(buffer + 2));
|
||||
uint32_t data = *((uint32_t*)(buffer + 6));
|
||||
|
||||
if((address & ~ 0x4) == 0xFFF00000){
|
||||
if((address & ~ 0x4) == 0xF00F0000){
|
||||
assert(size == 2);
|
||||
|
||||
top->debug_bus_cmd_valid = 1;
|
||||
|
@ -1035,7 +1035,7 @@ public:
|
|||
socklen_t addr_size = sizeof serverAddr;
|
||||
int error = connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
|
||||
// printf("!! %x\n",readCmd(2,0x8));
|
||||
uint32_t debugAddress = 0xFFF00000;
|
||||
uint32_t debugAddress = 0xF00F0000;
|
||||
uint32_t readValue;
|
||||
|
||||
while(resetDone != true){usleep(100);}
|
||||
|
|
|
@ -3,8 +3,8 @@ DBUS=DBUS_SIMPLE
|
|||
TRACE?=no
|
||||
TRACE_ACCESS?=no
|
||||
TRACE_START=0
|
||||
CSR=yes
|
||||
MMU=yes
|
||||
CSR=no
|
||||
MMU=no
|
||||
DEBUG_PLUGIN=yes
|
||||
DEBUG_PLUGIN_EXTERNAL?=no
|
||||
DHRYSTONE=yes
|
||||
|
|
Loading…
Reference in New Issue