summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-12-13 23:21:32 -0600
committerAlejandro Soto <alejandro@34project.org>2022-12-16 16:29:10 -0600
commit8c06c97c81339f68e06ff465aac2d8b1f2da4e27 (patch)
tree05e71f5508f4f00cb0abd6b0ec0d35d441313de8
parentf3c153f342ed969b1abfbe79d1017b651f21a649 (diff)
Implement interrupt emulation
Diffstat (limited to '')
-rw-r--r--rtl/core/control/exception.sv4
-rw-r--r--sim/start.S8
-rw-r--r--tb/avalon.hpp2
-rw-r--r--tb/interval_timer.cpp5
-rw-r--r--tb/interval_timer.hpp2
-rw-r--r--tb/jtag_uart.cpp5
-rw-r--r--tb/jtag_uart.hpp2
-rw-r--r--tb/sim/irq.S44
-rw-r--r--tb/sim/irq.py4
9 files changed, 71 insertions, 5 deletions
diff --git a/rtl/core/control/exception.sv b/rtl/core/control/exception.sv
index 76abc5c..02560a6 100644
--- a/rtl/core/control/exception.sv
+++ b/rtl/core/control/exception.sv
@@ -35,8 +35,8 @@ module core_control_exception
exception_mode <= 0;
exception_offset_pc <= 0;
end begin
- if(issue)
- pending_irq <= irq && !intmask.i;
+ if(next_cycle.issue)
+ pending_irq <= issue && irq && !intmask.i;
// A2.6.10 Exception priorities
if(mem_fault) begin
diff --git a/sim/start.S b/sim/start.S
index b909d75..65c49c1 100644
--- a/sim/start.S
+++ b/sim/start.S
@@ -15,9 +15,12 @@ __prefetch_abort:
__data_abort:
b data_abort
-__irq:
+__reserved:
b .
+__irq:
+ b irq
+
__fiq:
b .
@@ -33,7 +36,8 @@ halt:
exc_default:
b .
-.weak undefined, data_abort, prefetch_abort
+.weak undefined, data_abort, prefetch_abort, irq
.set undefined, exc_default
.set data_abort, exc_default
.set prefetch_abort, exc_default
+.set irq, exc_default
diff --git a/tb/avalon.hpp b/tb/avalon.hpp
index 95bbe78..323bd47 100644
--- a/tb/avalon.hpp
+++ b/tb/avalon.hpp
@@ -89,7 +89,7 @@ namespace taller::avalon
virtual bool read(std::uint32_t addr, std::uint32_t &data) noexcept final override;
virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept final override;
- virtual bool irq() noexcept;
+ virtual bool irq() noexcept final override;
inline slave &as_slave() noexcept
{
diff --git a/tb/interval_timer.cpp b/tb/interval_timer.cpp
index f790030..88c24f7 100644
--- a/tb/interval_timer.cpp
+++ b/tb/interval_timer.cpp
@@ -96,4 +96,9 @@ namespace taller::avalon
return true;
}
+
+ bool interval_timer::irq() noexcept
+ {
+ return control_ito && status_to;
+ }
}
diff --git a/tb/interval_timer.hpp b/tb/interval_timer.hpp
index eec9364..8d6f8c7 100644
--- a/tb/interval_timer.hpp
+++ b/tb/interval_timer.hpp
@@ -17,6 +17,8 @@ namespace taller::avalon
virtual bool read(std::uint32_t addr, std::uint32_t &data) noexcept final override;
virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept final override;
+ virtual bool irq() noexcept final override;
+
private:
std::uint32_t count;
std::uint32_t period;
diff --git a/tb/jtag_uart.cpp b/tb/jtag_uart.cpp
index f33a7ab..f661cdf 100644
--- a/tb/jtag_uart.cpp
+++ b/tb/jtag_uart.cpp
@@ -124,6 +124,11 @@ namespace taller::avalon
return true;
}
+ bool jtag_uart::irq() noexcept
+ {
+ return ctrl_we || (ctrl_re && rx_avail > 0);
+ }
+
void jtag_uart::takeover() noexcept
{
if(took_over)
diff --git a/tb/jtag_uart.hpp b/tb/jtag_uart.hpp
index 79032a2..3b8e7e2 100644
--- a/tb/jtag_uart.hpp
+++ b/tb/jtag_uart.hpp
@@ -23,6 +23,8 @@ namespace taller::avalon
virtual bool read(std::uint32_t addr, std::uint32_t &data) noexcept final override;
virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept final override;
+ virtual bool irq() noexcept final override;
+
void takeover() noexcept;
void release() noexcept;
diff --git a/tb/sim/irq.S b/tb/sim/irq.S
new file mode 100644
index 0000000..35ce2c9
--- /dev/null
+++ b/tb/sim/irq.S
@@ -0,0 +1,44 @@
+.global reset
+reset:
+ # Stop and reset timer
+ ldr r2, =0x30020000
+ mov r1, #(1 << 3)
+ str r1, [r2, #4]
+ mov r1, #0
+ str r1, [r2, #0]
+
+ # Enable timer interrupts
+ ldr r3, =0x30070000
+ ldr r1, =(1 << 0)
+ str r1, [r3, #4]
+
+ # Enable IRQs
+ mov r0, #0
+ mrs r1, cpsr
+ and r1, #~(1 << 7)
+ msr cpsr_c, r1
+
+ # Program timer with timeout value of 128 cycles
+ mov r1, #4
+ str r1, [r2, #8]
+ mov r1, #0
+ str r1, [r2, #12]
+
+ # Start timer
+ mov r1, #(1 << 0 | 1 << 2)
+ str r1, [r2, #4]
+
+ .wfi:
+ tst r0, r0
+ beq .wfi
+
+ mov r2, #2
+ mov pc, lr
+
+.global irq
+irq:
+ mov r0, #1
+ ldr r1, [r2, #0]
+ mov r4, #0
+ str r4, [r2, #0]
+ subs pc, lr, #4
diff --git a/tb/sim/irq.py b/tb/sim/irq.py
new file mode 100644
index 0000000..9691e4c
--- /dev/null
+++ b/tb/sim/irq.py
@@ -0,0 +1,4 @@
+def final():
+ assert_reg(r0, 1)
+ assert_reg(r1, 0b01)
+ assert_reg(r2, 2)