Add IRQ tests. Disable waves by default in runtests
This commit is contained in:
parent
9fb2af800f
commit
719c21fec3
|
@ -1,5 +1,7 @@
|
||||||
APP := hellow
|
APP := hellow
|
||||||
SRCS := ../common/init.S $(APP).c
|
SRCS := ../common/init.S $(APP).c
|
||||||
CCFLAGS = -march=rv32imac -Os
|
CCFLAGS := -march=rv32imac -Os
|
||||||
|
MAX_CYCLES := 1000000
|
||||||
|
|
||||||
|
|
||||||
include ../common/src_only_app.mk
|
include ../common/src_only_app.mk
|
||||||
|
|
|
@ -30,7 +30,15 @@ To run the tests:
|
||||||
./runtests
|
./runtests
|
||||||
```
|
```
|
||||||
|
|
||||||
This will first rebuild the simulator (`../tb_cxxrtl/`) if needed, then build and run all the software testcases, then print out a summary of test pass/fail status. The `./run_tests` executable itself returns a successful exit code if and only if all tests passed. A VCD trace and printf log will be created for each test, with the same name as the test, for debugging failures.
|
This will first rebuild the simulator (`../tb_cxxrtl/`) if needed, then build and run all the software testcases, then print out a summary of test pass/fail status. The `./run_tests` executable itself returns a successful exit code if and only if all tests passed. A printf log will be created for each test, with the same name as the test, at `tmp/test_name.log`.
|
||||||
|
|
||||||
|
VCD waveform dumping is not enabled by default, because tests run faster without waves, and dumping waves for all tests uses > 1 GB of disk space. To re-run a failing test and get wave output, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make APP=test_name
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a VCD file at `tmp/test_name_run.vcd`.
|
||||||
|
|
||||||
To clean up the junk:
|
To clean up the junk:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include "tb_cxxrtl_io.h"
|
||||||
|
#include "hazard3_csr.h"
|
||||||
|
|
||||||
|
// Pend all IRQs, enable them one-by-one and log their firing.
|
||||||
|
|
||||||
|
#define mie_meie 0x800u
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
asm volatile ("csrsi mstatus, 0x8");
|
||||||
|
write_csr(hazard3_csr_meie0, 0u);
|
||||||
|
write_csr(mie, mie_meie);
|
||||||
|
|
||||||
|
tb_set_irq_masked(-1u);
|
||||||
|
|
||||||
|
for (int i = 31; i >= 0; --i) {
|
||||||
|
tb_printf("Enabling IRQ %d\n", i);
|
||||||
|
write_csr(hazard3_csr_meie0, 1u << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((interrupt)) isr_external_irq() {
|
||||||
|
tb_puts("-> external irq handler\n");
|
||||||
|
tb_assert(read_csr(mcause) == 0x8000000bu, "mcause should indicate external IRQ\n");
|
||||||
|
tb_assert(read_csr(mip) == 0x880u, "mip should indicate external + timer IRQ\n");
|
||||||
|
|
||||||
|
// mlei updates dynamically, should be read exactly once at the start of an
|
||||||
|
// IRQ handler.
|
||||||
|
uint32_t mlei = read_csr(hazard3_csr_mlei);
|
||||||
|
tb_printf("mlei = %u\n", mlei);
|
||||||
|
tb_printf("meip0 = %08x\n", read_csr(hazard3_csr_meip0));
|
||||||
|
|
||||||
|
// mlei is scaled by 4 to make it cheaper to index a software vector table.
|
||||||
|
tb_assert(read_csr(hazard3_csr_meip0) & (1u << (mlei >> 2)), "IRQ indicated by mlei is not pending\n");
|
||||||
|
tb_clr_irq_masked(1u << (mlei >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*EXPECTED-OUTPUT***************************************************************
|
||||||
|
|
||||||
|
Enabling IRQ 31
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 124
|
||||||
|
meip0 = ffffffff
|
||||||
|
Enabling IRQ 30
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 120
|
||||||
|
meip0 = 7fffffff
|
||||||
|
Enabling IRQ 29
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 116
|
||||||
|
meip0 = 3fffffff
|
||||||
|
Enabling IRQ 28
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 112
|
||||||
|
meip0 = 1fffffff
|
||||||
|
Enabling IRQ 27
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 108
|
||||||
|
meip0 = 0fffffff
|
||||||
|
Enabling IRQ 26
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 104
|
||||||
|
meip0 = 07ffffff
|
||||||
|
Enabling IRQ 25
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 100
|
||||||
|
meip0 = 03ffffff
|
||||||
|
Enabling IRQ 24
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 96
|
||||||
|
meip0 = 01ffffff
|
||||||
|
Enabling IRQ 23
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 92
|
||||||
|
meip0 = 00ffffff
|
||||||
|
Enabling IRQ 22
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 88
|
||||||
|
meip0 = 007fffff
|
||||||
|
Enabling IRQ 21
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 84
|
||||||
|
meip0 = 003fffff
|
||||||
|
Enabling IRQ 20
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 80
|
||||||
|
meip0 = 001fffff
|
||||||
|
Enabling IRQ 19
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 76
|
||||||
|
meip0 = 000fffff
|
||||||
|
Enabling IRQ 18
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 72
|
||||||
|
meip0 = 0007ffff
|
||||||
|
Enabling IRQ 17
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 68
|
||||||
|
meip0 = 0003ffff
|
||||||
|
Enabling IRQ 16
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 64
|
||||||
|
meip0 = 0001ffff
|
||||||
|
Enabling IRQ 15
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 60
|
||||||
|
meip0 = 0000ffff
|
||||||
|
Enabling IRQ 14
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 56
|
||||||
|
meip0 = 00007fff
|
||||||
|
Enabling IRQ 13
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 52
|
||||||
|
meip0 = 00003fff
|
||||||
|
Enabling IRQ 12
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 48
|
||||||
|
meip0 = 00001fff
|
||||||
|
Enabling IRQ 11
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 44
|
||||||
|
meip0 = 00000fff
|
||||||
|
Enabling IRQ 10
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 40
|
||||||
|
meip0 = 000007ff
|
||||||
|
Enabling IRQ 9
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 36
|
||||||
|
meip0 = 000003ff
|
||||||
|
Enabling IRQ 8
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 32
|
||||||
|
meip0 = 000001ff
|
||||||
|
Enabling IRQ 7
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 28
|
||||||
|
meip0 = 000000ff
|
||||||
|
Enabling IRQ 6
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 24
|
||||||
|
meip0 = 0000007f
|
||||||
|
Enabling IRQ 5
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 20
|
||||||
|
meip0 = 0000003f
|
||||||
|
Enabling IRQ 4
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 16
|
||||||
|
meip0 = 0000001f
|
||||||
|
Enabling IRQ 3
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 12
|
||||||
|
meip0 = 0000000f
|
||||||
|
Enabling IRQ 2
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 8
|
||||||
|
meip0 = 00000007
|
||||||
|
Enabling IRQ 1
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 4
|
||||||
|
meip0 = 00000003
|
||||||
|
Enabling IRQ 0
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 0
|
||||||
|
meip0 = 00000001
|
||||||
|
|
||||||
|
*******************************************************************************/
|
|
@ -0,0 +1,169 @@
|
||||||
|
#include "tb_cxxrtl_io.h"
|
||||||
|
#include "hazard3_csr.h"
|
||||||
|
|
||||||
|
// Set IRQ mask (meie0) wide-open, then pend the IRQs one by one and log their
|
||||||
|
// firing.
|
||||||
|
|
||||||
|
#define mie_meie 0x800u
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
asm volatile ("csrsi mstatus, 0x8");
|
||||||
|
write_csr(hazard3_csr_meie0, -1u);
|
||||||
|
write_csr(mie, mie_meie);
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
tb_printf("Setting IRQ %d\n", i);
|
||||||
|
tb_set_irq_masked(1u << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((interrupt)) isr_external_irq() {
|
||||||
|
tb_puts("-> external irq handler\n");
|
||||||
|
tb_assert(read_csr(mcause) == 0x8000000bu, "mcause should indicate external IRQ\n");
|
||||||
|
tb_assert(read_csr(mip) == 0x880u, "mip should indicate external + timer IRQ\n");
|
||||||
|
|
||||||
|
// mlei updates dynamically, should be read exactly once at the start of an
|
||||||
|
// IRQ handler.
|
||||||
|
uint32_t mlei = read_csr(hazard3_csr_mlei);
|
||||||
|
tb_printf("mlei = %u\n", mlei);
|
||||||
|
tb_printf("meip0 = %08x\n", read_csr(hazard3_csr_meip0));
|
||||||
|
|
||||||
|
// mlei is scaled by 4 to make it cheaper to index a software vector table.
|
||||||
|
tb_assert(read_csr(hazard3_csr_meip0) & (1u << (mlei >> 2)), "IRQ indicated by mlei is not pending\n");
|
||||||
|
tb_clr_irq_masked(1u << (mlei >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*EXPECTED-OUTPUT***************************************************************
|
||||||
|
|
||||||
|
Setting IRQ 0
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 0
|
||||||
|
meip0 = 00000001
|
||||||
|
Setting IRQ 1
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 4
|
||||||
|
meip0 = 00000002
|
||||||
|
Setting IRQ 2
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 8
|
||||||
|
meip0 = 00000004
|
||||||
|
Setting IRQ 3
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 12
|
||||||
|
meip0 = 00000008
|
||||||
|
Setting IRQ 4
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 16
|
||||||
|
meip0 = 00000010
|
||||||
|
Setting IRQ 5
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 20
|
||||||
|
meip0 = 00000020
|
||||||
|
Setting IRQ 6
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 24
|
||||||
|
meip0 = 00000040
|
||||||
|
Setting IRQ 7
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 28
|
||||||
|
meip0 = 00000080
|
||||||
|
Setting IRQ 8
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 32
|
||||||
|
meip0 = 00000100
|
||||||
|
Setting IRQ 9
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 36
|
||||||
|
meip0 = 00000200
|
||||||
|
Setting IRQ 10
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 40
|
||||||
|
meip0 = 00000400
|
||||||
|
Setting IRQ 11
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 44
|
||||||
|
meip0 = 00000800
|
||||||
|
Setting IRQ 12
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 48
|
||||||
|
meip0 = 00001000
|
||||||
|
Setting IRQ 13
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 52
|
||||||
|
meip0 = 00002000
|
||||||
|
Setting IRQ 14
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 56
|
||||||
|
meip0 = 00004000
|
||||||
|
Setting IRQ 15
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 60
|
||||||
|
meip0 = 00008000
|
||||||
|
Setting IRQ 16
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 64
|
||||||
|
meip0 = 00010000
|
||||||
|
Setting IRQ 17
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 68
|
||||||
|
meip0 = 00020000
|
||||||
|
Setting IRQ 18
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 72
|
||||||
|
meip0 = 00040000
|
||||||
|
Setting IRQ 19
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 76
|
||||||
|
meip0 = 00080000
|
||||||
|
Setting IRQ 20
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 80
|
||||||
|
meip0 = 00100000
|
||||||
|
Setting IRQ 21
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 84
|
||||||
|
meip0 = 00200000
|
||||||
|
Setting IRQ 22
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 88
|
||||||
|
meip0 = 00400000
|
||||||
|
Setting IRQ 23
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 92
|
||||||
|
meip0 = 00800000
|
||||||
|
Setting IRQ 24
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 96
|
||||||
|
meip0 = 01000000
|
||||||
|
Setting IRQ 25
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 100
|
||||||
|
meip0 = 02000000
|
||||||
|
Setting IRQ 26
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 104
|
||||||
|
meip0 = 04000000
|
||||||
|
Setting IRQ 27
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 108
|
||||||
|
meip0 = 08000000
|
||||||
|
Setting IRQ 28
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 112
|
||||||
|
meip0 = 10000000
|
||||||
|
Setting IRQ 29
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 116
|
||||||
|
meip0 = 20000000
|
||||||
|
Setting IRQ 30
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 120
|
||||||
|
meip0 = 40000000
|
||||||
|
Setting IRQ 31
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 124
|
||||||
|
meip0 = 80000000
|
||||||
|
|
||||||
|
*******************************************************************************/
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include "tb_cxxrtl_io.h"
|
||||||
|
#include "hazard3_csr.h"
|
||||||
|
|
||||||
|
// Fire all IRQs simultaneously, and log the resulting handler calls
|
||||||
|
|
||||||
|
#define mie_meie 0x800u
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
asm volatile ("csrsi mstatus, 0x8");
|
||||||
|
write_csr(mie, mie_meie);
|
||||||
|
write_csr(hazard3_csr_meie0, -1u);
|
||||||
|
|
||||||
|
tb_puts("Firing all IRQs\n");
|
||||||
|
tb_set_irq_masked(-1u);
|
||||||
|
tb_puts("Returned OK\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((interrupt)) isr_external_irq() {
|
||||||
|
tb_puts("-> external irq handler\n");
|
||||||
|
tb_assert(read_csr(mcause) == 0x8000000bu, "mcause should indicate external IRQ\n");
|
||||||
|
tb_assert(read_csr(mip) == 0x880u, "mip should indicate external + timer IRQ\n");
|
||||||
|
|
||||||
|
// mlei updates dynamically, should be read exactly once at the start of an
|
||||||
|
// IRQ handler.
|
||||||
|
uint32_t mlei = read_csr(hazard3_csr_mlei);
|
||||||
|
tb_printf("mlei = %u\n", mlei);
|
||||||
|
tb_printf("meip0 = %08x\n", read_csr(hazard3_csr_meip0));
|
||||||
|
|
||||||
|
// mlei is scaled by 4 to make it cheaper to index a software vector table.
|
||||||
|
tb_assert(read_csr(hazard3_csr_meip0) & (1u << (mlei >> 2)), "IRQ indicated by mlei is not pending\n");
|
||||||
|
tb_clr_irq_masked(1u << (mlei >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*EXPECTED-OUTPUT***************************************************************
|
||||||
|
|
||||||
|
Firing all IRQs
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 0
|
||||||
|
meip0 = ffffffff
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 4
|
||||||
|
meip0 = fffffffe
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 8
|
||||||
|
meip0 = fffffffc
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 12
|
||||||
|
meip0 = fffffff8
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 16
|
||||||
|
meip0 = fffffff0
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 20
|
||||||
|
meip0 = ffffffe0
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 24
|
||||||
|
meip0 = ffffffc0
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 28
|
||||||
|
meip0 = ffffff80
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 32
|
||||||
|
meip0 = ffffff00
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 36
|
||||||
|
meip0 = fffffe00
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 40
|
||||||
|
meip0 = fffffc00
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 44
|
||||||
|
meip0 = fffff800
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 48
|
||||||
|
meip0 = fffff000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 52
|
||||||
|
meip0 = ffffe000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 56
|
||||||
|
meip0 = ffffc000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 60
|
||||||
|
meip0 = ffff8000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 64
|
||||||
|
meip0 = ffff0000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 68
|
||||||
|
meip0 = fffe0000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 72
|
||||||
|
meip0 = fffc0000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 76
|
||||||
|
meip0 = fff80000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 80
|
||||||
|
meip0 = fff00000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 84
|
||||||
|
meip0 = ffe00000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 88
|
||||||
|
meip0 = ffc00000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 92
|
||||||
|
meip0 = ff800000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 96
|
||||||
|
meip0 = ff000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 100
|
||||||
|
meip0 = fe000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 104
|
||||||
|
meip0 = fc000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 108
|
||||||
|
meip0 = f8000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 112
|
||||||
|
meip0 = f0000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 116
|
||||||
|
meip0 = e0000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 120
|
||||||
|
meip0 = c0000000
|
||||||
|
-> external irq handler
|
||||||
|
mlei = 124
|
||||||
|
meip0 = 80000000
|
||||||
|
Returned OK
|
||||||
|
|
||||||
|
|
||||||
|
*******************************************************************************/
|
|
@ -34,7 +34,7 @@ for test in testlist:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
test_run_ret = subprocess.run(
|
test_run_ret = subprocess.run(
|
||||||
["../tb_cxxrtl/tb", "--bin", f"tmp/{test}.bin", "--vcd", f"tmp/{test}_run.vcd", "--cycles", "1000000"],
|
["../tb_cxxrtl/tb", "--bin", f"tmp/{test}.bin", "--cycles", "1000000"],
|
||||||
stdout = subprocess.PIPE,
|
stdout = subprocess.PIPE,
|
||||||
timeout=10
|
timeout=10
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue