diff --git a/Makefile b/Makefile index 77bb182..c9a71da 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ test_wb_vcd: testbench_wb.vvp firmware/firmware.hex $(VVP) -N $< +vcd +trace +noerror test_verilator: testbench_verilator firmware/firmware.hex - ./testbench_verilator + ./testbench_verilator 0 + ./testbench_verilator 1 testbench_verilator: testbench_wb.v picorv32.v testbench.cc $(VERILATOR) --cc --exe -Wno-lint -trace --top-module picorv32_wrapper testbench_wb.v picorv32.v testbench.cc \ diff --git a/dhrystone/syscalls.c b/dhrystone/syscalls.c index 8ea84ca..cfecc65 100644 --- a/dhrystone/syscalls.c +++ b/dhrystone/syscalls.c @@ -2,94 +2,69 @@ // Based on riscv newlib libgloss/riscv/sys_*.c // Written by Clifford Wolf. +#include #include #include -#include #define UNIMPL_FUNC(_f) ".globl " #_f "\n.type " #_f ", @function\n" #_f ":\n" -asm ( - ".text\n" - ".align 2\n" - UNIMPL_FUNC(_open) - UNIMPL_FUNC(_openat) - UNIMPL_FUNC(_lseek) - UNIMPL_FUNC(_stat) - UNIMPL_FUNC(_lstat) - UNIMPL_FUNC(_fstatat) - UNIMPL_FUNC(_isatty) - UNIMPL_FUNC(_access) - UNIMPL_FUNC(_faccessat) - UNIMPL_FUNC(_link) - UNIMPL_FUNC(_unlink) - UNIMPL_FUNC(_execve) - UNIMPL_FUNC(_getpid) - UNIMPL_FUNC(_fork) - UNIMPL_FUNC(_kill) - UNIMPL_FUNC(_wait) - UNIMPL_FUNC(_times) - UNIMPL_FUNC(_gettimeofday) - UNIMPL_FUNC(_ftime) - UNIMPL_FUNC(_utime) - UNIMPL_FUNC(_chown) - UNIMPL_FUNC(_chmod) - UNIMPL_FUNC(_chdir) - UNIMPL_FUNC(_getcwd) - UNIMPL_FUNC(_sysconf) - "j unimplemented_syscall\n" -); +asm(".text\n" + ".align 2\n" UNIMPL_FUNC(_open) UNIMPL_FUNC(_openat) UNIMPL_FUNC(_lseek) + UNIMPL_FUNC(_stat) UNIMPL_FUNC(_lstat) UNIMPL_FUNC(_fstatat) + UNIMPL_FUNC(_isatty) UNIMPL_FUNC(_access) UNIMPL_FUNC(_faccessat) + UNIMPL_FUNC(_link) UNIMPL_FUNC(_unlink) UNIMPL_FUNC(_execve) + UNIMPL_FUNC(_getpid) UNIMPL_FUNC(_fork) UNIMPL_FUNC(_kill) + UNIMPL_FUNC(_wait) UNIMPL_FUNC(_times) UNIMPL_FUNC( + _gettimeofday) UNIMPL_FUNC(_ftime) + UNIMPL_FUNC(_utime) UNIMPL_FUNC(_chown) + UNIMPL_FUNC(_chmod) UNIMPL_FUNC(_chdir) + UNIMPL_FUNC(_getcwd) UNIMPL_FUNC( + _sysconf) "j unimplemented_syscall\n"); -void unimplemented_syscall() -{ - const char *p = "Unimplemented system call called!\n"; - while (*p) - *(volatile int*)0x10000000 = *(p++); - asm volatile ("ebreak"); - __builtin_unreachable(); +void unimplemented_syscall() { + const char *p = "Unimplemented system call called!\n"; + while (*p) *(volatile int *)0x10000000 = *(p++); + asm volatile("ebreak"); + __builtin_unreachable(); } -ssize_t _read(int file, void *ptr, size_t len) -{ - // always EOF - return 0; +ssize_t _read(int file, void *ptr, size_t len) { + // always EOF + return 0; } -ssize_t _write(int file, const void *ptr, size_t len) -{ - const void *eptr = ptr + len; - while (ptr != eptr) - *(volatile int*)0x10000000 = *(char*)(ptr++); - return len; +ssize_t _write(int file, const void *ptr, size_t len) { + const void *eptr = ptr + len; + while (ptr != eptr) *(volatile int *)0x10000000 = *(char *)(ptr++); + return len; } -int _close(int file) -{ - // close is called before _exit() - return 0; +int _close(int file) { + // close is called before _exit() + return 0; } -int _fstat(int file, struct stat *st) -{ - // fstat is called during libc startup - errno = ENOENT; - return -1; +int _fstat(int file, struct stat *st) { + // fstat is called during libc startup + errno = ENOENT; + return -1; } -void *_sbrk(ptrdiff_t incr) -{ - extern unsigned char _end[]; // Defined by linker - static unsigned long heap_end; +void *_sbrk(ptrdiff_t incr) { + extern unsigned char _end[]; // Defined by linker + static unsigned long heap_end; - if (heap_end == 0) - heap_end = (long)_end; + if (heap_end == 0) heap_end = (long)_end; - heap_end += incr; - return (void *)(heap_end - incr); + heap_end += incr; + return (void *)(heap_end - incr); } -void _exit(int exit_status) -{ - asm volatile ("ebreak"); - __builtin_unreachable(); -} +void _exit(int exit_status) { + asm volatile("li a0, 0x20000000"); + asm volatile("li a1, 123456789"); + asm volatile("sw a1,0(a0)"); + asm volatile("ebreak"); + __builtin_unreachable(); +} diff --git a/testbench.cc b/testbench.cc index 2d37492..154e3bd 100644 --- a/testbench.cc +++ b/testbench.cc @@ -1,46 +1,52 @@ +#include + #include "Vpicorv32_wrapper.h" #include "verilated_vcd_c.h" -int main(int argc, char **argv, char **env) -{ - printf("Built with %s %s.\n", Verilated::productName(), Verilated::productVersion()); - printf("Recommended: Verilator 4.0 or later.\n"); +int main(int argc, char** argv, char** env) { + printf("Built with %s %s.\n", Verilated::productName(), + Verilated::productVersion()); + printf("Recommended: Verilator 4.0 or later.\n"); - Verilated::commandArgs(argc, argv); - Vpicorv32_wrapper* top = new Vpicorv32_wrapper; + Verilated::commandArgs(argc, argv); + Vpicorv32_wrapper* top = new Vpicorv32_wrapper; - // Tracing (vcd) - VerilatedVcdC* tfp = NULL; - const char* flag_vcd = Verilated::commandArgsPlusMatch("vcd"); - if (flag_vcd && 0==strcmp(flag_vcd, "+vcd")) { - Verilated::traceEverOn(true); - tfp = new VerilatedVcdC; - top->trace (tfp, 99); - tfp->open("testbench.vcd"); - } + if (argc > 0 && argv[1][0] == '1') + top->testcase = 1; + else + top->testcase = 0; - // Tracing (data bus, see showtrace.py) - FILE *trace_fd = NULL; - const char* flag_trace = Verilated::commandArgsPlusMatch("trace"); - if (flag_trace && 0==strcmp(flag_trace, "+trace")) { - trace_fd = fopen("testbench.trace", "w"); - } + // Tracing (vcd) + VerilatedVcdC* tfp = NULL; + const char* flag_vcd = Verilated::commandArgsPlusMatch("vcd"); + if (flag_vcd && 0 == strcmp(flag_vcd, "+vcd")) { + Verilated::traceEverOn(true); + tfp = new VerilatedVcdC; + top->trace(tfp, 99); + tfp->open("testbench.vcd"); + } - top->wb_clk = 0; - top->wb_rst = 1; + // Tracing (data bus, see showtrace.py) + FILE* trace_fd = NULL; + const char* flag_trace = Verilated::commandArgsPlusMatch("trace"); + if (flag_trace && 0 == strcmp(flag_trace, "+trace")) { + trace_fd = fopen("testbench.trace", "w"); + } - int t = 0; - while (!Verilated::gotFinish()) { - if (t > 200) - top->wb_rst = 0; - top->wb_clk = !top->wb_clk; - top->eval(); - if (tfp) tfp->dump (t); - if (trace_fd && top->wb_clk && top->trace_valid) fprintf(trace_fd, "%9.9lx\n", top->trace_data); - t += 5; - } - if (tfp) tfp->close(); - delete top; - exit(0); + top->wb_clk = 0; + top->wb_rst = 1; + + int t = 0; + while (!Verilated::gotFinish()) { + if (t > 200) top->wb_rst = 0; + top->wb_clk = !top->wb_clk; + top->eval(); + if (tfp) tfp->dump(t); + if (trace_fd && top->wb_clk && top->trace_valid) + fprintf(trace_fd, "%9.9lx\n", top->trace_data); + t += 5; + } + if (tfp) tfp->close(); + delete top; + exit(0); } - diff --git a/testbench_wb.v b/testbench_wb.v index 268976b..b44e7bd 100644 --- a/testbench_wb.v +++ b/testbench_wb.v @@ -61,7 +61,8 @@ module picorv32_wrapper #( input wb_rst, output trap, output trace_valid, - output [35:0] trace_data + output [35:0] trace_data, + input testcase ); wire exit; reg [31:0] irq = 0; @@ -99,9 +100,10 @@ module picorv32_wrapper #( reg [1023:0] firmware_file; initial begin - if (!$value$plusargs("firmware=%s", firmware_file)) - firmware_file = "firmware/firmware.hex"; - // firmware_file = "dhrystone/dhry.hex"; + if (!testcase) firmware_file = "firmware/firmware.hex"; + else firmware_file = "dhrystone/dhry.hex"; + // if (!$value$plusargs("firmware=%s", firmware_file)) + // firmware_file = "firmware/firmware.hex"; $readmemh(firmware_file, uut.memory); end