Mikael Ågren 5535323b06
PoC: PicoRV32 interrupts
A proof-of-concept of enabling PicoRV32 interrupts. Two interrupt
sources, which can be triggered by writes to memory addresses, are
added.  The design has only been simulated, not run on hardware.

Synthesis:

Ice40 LC utilization is 93% (4934/5280) when built using tkey-builder:4

Simulation:

A `tb_application_fpga_irqpoc` target is added. Running `make
tb_application_fpga_irqpoc` creates `tb_application_fpga_sim.fst` which
can be inspected in GTKWave or Surfer.

Firmware:

A simple firmware is added in `fw/irqpoc`. It enables both interrupts
and triggers each interrupt once.

Custom PicoRV32 instructions are located in `custom_ops.S`. It is
imported from upstream PicoRV32 commit:
70f3c33ac8
2025-02-04 12:25:57 +01:00

43 lines
1.2 KiB
ArmAsm

/*
* Copyright (C) 2022, 2023 - Tillitis AB
* SPDX-License-Identifier: GPL-2.0-only
*/
#include "custom_ops.S" // PicoRV32 custom instructions
.section ".text.init"
.globl _start
_start:
j init
.=0x10 // IRQ handler at fixed address 0x10
irq_handler:
// PicoRV32 stores the IRQ bitmask in x4.
// If bit 31 is 1: IRQ31 was triggered.
// If bit 30 is 1: IRQ30 was triggered.
nop // NOPs are not necessary. Only added to make it easier to find
nop // when simulating.
nop
picorv32_retirq_insn() // Return from interrupt
.=0x20 // Setting location of init to 0x20. Makes it easier to find when
// simulating.
init:
li t0, 0x3fffffff // IRQ31 & IRQ30 mask
picorv32_maskirq_insn(zero, t0) // Enable IRQs
li t0, 0xe1000000 // IRQ31 trigger address
sw zero, 0(t0) // Raise IRQ by writing to interrupt trigger address.
// Writing any data triggers an interrupt.
li t0, 0xe0000000 // IRQ30 trigger address
sw zero, 0(t0) // Raise IRQ by writing to interrupt trigger address.
// Writing any data triggers an interrupt.
loop:
j loop
.align 4 // Padding to please makehex.py which requires even 4-byte file
// sizes.