Open MarekPikula opened 5 years ago
I think it already support vectored interrupts as specified by the RISC-V previlegied spec https://github.com/SpinalHDL/VexRiscv/blob/master/src/main/scala/vexriscv/plugin/CsrPlugin.scala#L476, and new interrupts can be added via the plugin system and https://github.com/SpinalHDL/VexRiscv/blob/master/src/main/scala/vexriscv/plugin/CsrPlugin.scala#L369
So, technicaly speaking, it is already there, but was never experimented.
Interesting :+1:
It would be great if there was some example configuration available somewhere. Maybe I'll look into it sometime next week on my own as well, but my SpinalHDL knowledge is rather limited for now :wink:
I can do a example plugin, the issue i currently have is that i don't realy have time to test things properly. And that often hold me back from implementing new things. So if you want, i can do the plugin and you test it ?
Sure :+1: I'm finishing my internship next week, so I I won't be very much available, but afterwards I should have some time to test.
There is : Usage : https://github.com/SpinalHDL/VexRiscv/blob/dev/src/main/scala/vexriscv/demo/GenCustomInterrupt.scala How its done : https://github.com/SpinalHDL/VexRiscv/blob/dev/src/main/scala/vexriscv/plugin/CsrPlugin.scala#L1049
This is untested, but the emited verilog seem right
Wow, that is cool. I hope to test it soon.
This is super cool! I think this should help quite a bit with Linux performance?
Hey @Dolu1990, when setting mtvec [1:0] to 1'b1 the core isn't jumping to a vectored IRQ. Is there some cfg I'm missing?
In the images below it should go to the external IRQ, but it's getting into sync. trap (first hit)...
My cfg:
object vexriscvaxi4{
def main(args: array[string]) {
val report = spinalconfig(mode = if(args.contains("--vhdl")) vhdl else verilog).generate{
//cpu configuration
val cpuconfig = vexriscvconfig(
plugins = list(
new ibussimpleplugin(
resetvector = 0x80000000l,
cmdforkonsecondstage = false,
cmdforkpersistence = true,
prediction = static,
catchaccessfault = false,
compressedgen = false
),
new dbussimpleplugin(
catchaddressmisaligned = false,
catchaccessfault = false
),
new staticmemorytranslatorplugin(
iorange = _(31 downto 28) === 0xf
),
new decodersimpleplugin(
catchillegalinstruction = true
),
new regfileplugin(
regfilereadykind = plugin.sync,
zeroboot = false
),
new intaluplugin,
new srcplugin(
separatedaddsub = false,
executeinsertion = true
),
new fullbarrelshifterplugin,
new mulplugin,
new divplugin,
new hazardsimpleplugin(
bypassexecute = true,
bypassmemory = true,
bypasswriteback = true,
bypasswritebackbuffer = true,
pessimisticusesrc = false,
pessimisticwriteregfile = false,
pessimisticaddressmatch = false
),
new branchplugin(
earlybranch = false,
catchaddressmisaligned = true
),
new csrplugin(
config = csrpluginconfig(
catchillegalaccess = false,
mvendorid = null,
marchid = null,
mimpid = null,
mhartid = null,
misaextensionsinit = 66,
misaaccess = csraccess.none,
mtvecaccess = csraccess.read_write,
mtvecinit = 0x00000020l,
mepcaccess = csraccess.read_write,
mscratchgen = false,
mcauseaccess = csraccess.read_only,
mbadaddraccess = csraccess.read_only,
mcycleaccess = csraccess.none,
minstretaccess = csraccess.none,
ecallgen = false,
wfigenaswait = false,
ucycleaccess = csraccess.none,
uinstretaccess = csraccess.none
)
),
new yamlplugin("cpu0.yaml")
)
)
//cpu instanciation
val cpu = new vexriscv(cpuconfig)
//cpu modifications to be an ahblite3 one
cpu.rework {
for (plugin <- cpuconfig.plugins) plugin match {
case plugin: ibussimpleplugin => {
plugin.ibus.setasdirectionless() //unset io properties of ibus
master(plugin.ibus.toaxi4readonly()).setname("ibusaxi")
}
case plugin: dbussimpleplugin => {
plugin.dbus.setasdirectionless()
master(plugin.dbus.toaxi4()).setname("dbusaxi")
}
case plugin: debugplugin if args.contains("--jtag")=> plugin.debugclockdomain {
plugin.io.bus.setasdirectionless()
val jtag = slave(new jtag()).setname("jtag")
jtag <> plugin.io.bus.fromjtag()
}
case _ =>
}
}
cpu
}
}
}
The following code is used for vectored interrupt: case plugin : CsrPlugin => { plugin.externalInterrupt := BufferCC(coreInterrupt) plugin.timerInterrupt := timerCtrl.io.interrupt } case plugin : UserInterruptPlugin => { plugin.interrupt := io.vectoredInt }
According C code, please refer to https://five-embeddev.com/baremetal/vectored_interrupts/
After simulation, the Vector Interrupt of Vexriscv is worked.
It would be nice if VexRiscv had support for vectored interrupts. Basically something like fast interrupts in Ibex.