Refine tester. test common and dhry at the same time.

This commit is contained in:
colin.liang 2023-01-12 21:18:03 +08:00
parent 361dba595d
commit ce40766cbd
4 changed files with 96 additions and 112 deletions

View File

@ -27,7 +27,8 @@ test_wb_vcd: testbench_wb.vvp firmware/firmware.hex
$(VVP) -N $< +vcd +trace +noerror $(VVP) -N $< +vcd +trace +noerror
test_verilator: testbench_verilator firmware/firmware.hex test_verilator: testbench_verilator firmware/firmware.hex
./testbench_verilator ./testbench_verilator 0
./testbench_verilator 1
testbench_verilator: testbench_wb.v picorv32.v testbench.cc 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 \ $(VERILATOR) --cc --exe -Wno-lint -trace --top-module picorv32_wrapper testbench_wb.v picorv32.v testbench.cc \

View File

@ -2,94 +2,69 @@
// Based on riscv newlib libgloss/riscv/sys_*.c // Based on riscv newlib libgloss/riscv/sys_*.c
// Written by Clifford Wolf. // Written by Clifford Wolf.
#include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#define UNIMPL_FUNC(_f) ".globl " #_f "\n.type " #_f ", @function\n" #_f ":\n" #define UNIMPL_FUNC(_f) ".globl " #_f "\n.type " #_f ", @function\n" #_f ":\n"
asm ( asm(".text\n"
".text\n" ".align 2\n" UNIMPL_FUNC(_open) UNIMPL_FUNC(_openat) UNIMPL_FUNC(_lseek)
".align 2\n" UNIMPL_FUNC(_stat) UNIMPL_FUNC(_lstat) UNIMPL_FUNC(_fstatat)
UNIMPL_FUNC(_open) UNIMPL_FUNC(_isatty) UNIMPL_FUNC(_access) UNIMPL_FUNC(_faccessat)
UNIMPL_FUNC(_openat) UNIMPL_FUNC(_link) UNIMPL_FUNC(_unlink) UNIMPL_FUNC(_execve)
UNIMPL_FUNC(_lseek) UNIMPL_FUNC(_getpid) UNIMPL_FUNC(_fork) UNIMPL_FUNC(_kill)
UNIMPL_FUNC(_stat) UNIMPL_FUNC(_wait) UNIMPL_FUNC(_times) UNIMPL_FUNC(
UNIMPL_FUNC(_lstat) _gettimeofday) UNIMPL_FUNC(_ftime)
UNIMPL_FUNC(_fstatat) UNIMPL_FUNC(_utime) UNIMPL_FUNC(_chown)
UNIMPL_FUNC(_isatty) UNIMPL_FUNC(_chmod) UNIMPL_FUNC(_chdir)
UNIMPL_FUNC(_access) UNIMPL_FUNC(_getcwd) UNIMPL_FUNC(
UNIMPL_FUNC(_faccessat) _sysconf) "j unimplemented_syscall\n");
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() void unimplemented_syscall() {
{ const char *p = "Unimplemented system call called!\n";
const char *p = "Unimplemented system call called!\n"; while (*p) *(volatile int *)0x10000000 = *(p++);
while (*p) asm volatile("ebreak");
*(volatile int*)0x10000000 = *(p++); __builtin_unreachable();
asm volatile ("ebreak");
__builtin_unreachable();
} }
ssize_t _read(int file, void *ptr, size_t len) ssize_t _read(int file, void *ptr, size_t len) {
{ // always EOF
// always EOF return 0;
return 0;
} }
ssize_t _write(int file, const void *ptr, size_t len) ssize_t _write(int file, const void *ptr, size_t len) {
{ const void *eptr = ptr + len;
const void *eptr = ptr + len; while (ptr != eptr) *(volatile int *)0x10000000 = *(char *)(ptr++);
while (ptr != eptr) return len;
*(volatile int*)0x10000000 = *(char*)(ptr++);
return len;
} }
int _close(int file) int _close(int file) {
{ // close is called before _exit()
// close is called before _exit() return 0;
return 0;
} }
int _fstat(int file, struct stat *st) int _fstat(int file, struct stat *st) {
{ // fstat is called during libc startup
// fstat is called during libc startup errno = ENOENT;
errno = ENOENT; return -1;
return -1;
} }
void *_sbrk(ptrdiff_t incr) void *_sbrk(ptrdiff_t incr) {
{ extern unsigned char _end[]; // Defined by linker
extern unsigned char _end[]; // Defined by linker static unsigned long heap_end;
static unsigned long heap_end;
if (heap_end == 0) if (heap_end == 0) heap_end = (long)_end;
heap_end = (long)_end;
heap_end += incr; heap_end += incr;
return (void *)(heap_end - incr); return (void *)(heap_end - incr);
} }
void _exit(int exit_status) void _exit(int exit_status) {
{ asm volatile("li a0, 0x20000000");
asm volatile ("ebreak"); asm volatile("li a1, 123456789");
__builtin_unreachable(); asm volatile("sw a1,0(a0)");
}
asm volatile("ebreak");
__builtin_unreachable();
}

View File

@ -1,46 +1,52 @@
#include <iostream>
#include "Vpicorv32_wrapper.h" #include "Vpicorv32_wrapper.h"
#include "verilated_vcd_c.h" #include "verilated_vcd_c.h"
int main(int argc, char **argv, char **env) int main(int argc, char** argv, char** env) {
{ printf("Built with %s %s.\n", Verilated::productName(),
printf("Built with %s %s.\n", Verilated::productName(), Verilated::productVersion()); Verilated::productVersion());
printf("Recommended: Verilator 4.0 or later.\n"); printf("Recommended: Verilator 4.0 or later.\n");
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
Vpicorv32_wrapper* top = new Vpicorv32_wrapper; Vpicorv32_wrapper* top = new Vpicorv32_wrapper;
// Tracing (vcd) if (argc > 0 && argv[1][0] == '1')
VerilatedVcdC* tfp = NULL; top->testcase = 1;
const char* flag_vcd = Verilated::commandArgsPlusMatch("vcd"); else
if (flag_vcd && 0==strcmp(flag_vcd, "+vcd")) { top->testcase = 0;
Verilated::traceEverOn(true);
tfp = new VerilatedVcdC;
top->trace (tfp, 99);
tfp->open("testbench.vcd");
}
// Tracing (data bus, see showtrace.py) // Tracing (vcd)
FILE *trace_fd = NULL; VerilatedVcdC* tfp = NULL;
const char* flag_trace = Verilated::commandArgsPlusMatch("trace"); const char* flag_vcd = Verilated::commandArgsPlusMatch("vcd");
if (flag_trace && 0==strcmp(flag_trace, "+trace")) { if (flag_vcd && 0 == strcmp(flag_vcd, "+vcd")) {
trace_fd = fopen("testbench.trace", "w"); Verilated::traceEverOn(true);
} tfp = new VerilatedVcdC;
top->trace(tfp, 99);
tfp->open("testbench.vcd");
}
top->wb_clk = 0; // Tracing (data bus, see showtrace.py)
top->wb_rst = 1; 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; top->wb_clk = 0;
while (!Verilated::gotFinish()) { top->wb_rst = 1;
if (t > 200)
top->wb_rst = 0; int t = 0;
top->wb_clk = !top->wb_clk; while (!Verilated::gotFinish()) {
top->eval(); if (t > 200) top->wb_rst = 0;
if (tfp) tfp->dump (t); top->wb_clk = !top->wb_clk;
if (trace_fd && top->wb_clk && top->trace_valid) fprintf(trace_fd, "%9.9lx\n", top->trace_data); top->eval();
t += 5; if (tfp) tfp->dump(t);
} if (trace_fd && top->wb_clk && top->trace_valid)
if (tfp) tfp->close(); fprintf(trace_fd, "%9.9lx\n", top->trace_data);
delete top; t += 5;
exit(0); }
if (tfp) tfp->close();
delete top;
exit(0);
} }

View File

@ -61,7 +61,8 @@ module picorv32_wrapper #(
input wb_rst, input wb_rst,
output trap, output trap,
output trace_valid, output trace_valid,
output [35:0] trace_data output [35:0] trace_data,
input testcase
); );
wire exit; wire exit;
reg [31:0] irq = 0; reg [31:0] irq = 0;
@ -99,9 +100,10 @@ module picorv32_wrapper #(
reg [1023:0] firmware_file; reg [1023:0] firmware_file;
initial begin initial begin
if (!$value$plusargs("firmware=%s", firmware_file)) if (!testcase) firmware_file = "firmware/firmware.hex";
firmware_file = "firmware/firmware.hex"; else firmware_file = "dhrystone/dhry.hex";
// firmware_file = "dhrystone/dhry.hex"; // if (!$value$plusargs("firmware=%s", firmware_file))
// firmware_file = "firmware/firmware.hex";
$readmemh(firmware_file, uut.memory); $readmemh(firmware_file, uut.memory);
end end