SpinalHDL / VexRiscv

A FPGA friendly 32 bit RISC-V CPU implementation
MIT License
2.5k stars 417 forks source link

Vectored interrupt support #96

Open MarekPikula opened 5 years ago

MarekPikula commented 5 years ago

It would be nice if VexRiscv had support for vectored interrupts. Basically something like fast interrupts in Ibex.

Dolu1990 commented 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.

MarekPikula commented 5 years ago

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:

Dolu1990 commented 5 years ago

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 ?

MarekPikula commented 5 years ago

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.

Dolu1990 commented 5 years ago

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

MarekPikula commented 5 years ago

Wow, that is cool. I hope to test it soon.

mithro commented 5 years ago

This is super cool! I think this should help quite a bit with Linux performance?

aignacio commented 3 years ago

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? image

In the images below it should go to the external IRQ, but it's getting into sync. trap (first hit)...

image

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
    }
  }
}
piondeno commented 1 year ago

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.