Skip to content

Commit

Permalink
Add tohost and adapt existing tests
Browse files Browse the repository at this point in the history
* cv32e20/bsp/crt0.s: add tohost symbol declaration
* cv32e20/bsp/link.ld: add tohost symbol linking address
* cv32e20/bsp/syscalls.c: add tohost store in the exit function
* cv32e20/env/corev-dv/cv32e20_instr_gen_config.sv: add rule to enforce
not ZERO reg used in the scratch reg. This constraint was already
implemented but not working with vsim
* cv32e20/env/uvme/uvme_cv32e20_env.sv: add mechanism to load symbols
from the binary for the execution exit.
* cv32e20/env/uvme/vseq/uvme_cv32e20_vp_status_flags_seq.sv: Adapt code
to host format ( {exit_value, 1} )
* cv32e40p/env/uvme/uvme_rv32isa_covg_trn.sv: substitute
uvm_objects_utils(begin/end) for a simple uvm_object_utils
* lib/corev-dv/corev_asm_program_gen.sv: delete wfi for locking the core
and add tohost mechanism
* lib/uvm_agents/uvma_obi_memory/src/comps/uvma_obi_memory_mon.sv: vsim
complaining for using passive_mp
* lib/uvm_libs/uvml_sb/uvml_sb_cntxt.sv: delete T_TRN type for event as
it causes vsim to fail simulation
* mk/Common.mk: add compilation for elfloader vendor
* mk/uvmt/vsim.mk: add comilation for elfloader vendor and delete
clean_riscv-dv on each corev-dv generation
* vendor/elfloader/Makefile: add elfloader vendor
* vendor/elfloader/elfloader.cc: add elfloader vendor
* lib/corev-dv/corev_asm_program_gen.sv: delete wfi and add syscall on ecall
* cv32e20/tests/programs/custom/riscv_arithmetic_basic_test_*: change align of trap handler to 8
  • Loading branch information
MarioOpenHWGroup committed Nov 15, 2023
1 parent 69fca51 commit 7c9cf7d
Show file tree
Hide file tree
Showing 40 changed files with 652 additions and 487 deletions.
10 changes: 5 additions & 5 deletions cv32e20/bsp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ RISCV ?= $(CV_SW_TOOLCHAIN)
RISCV_EXE_PREFIX ?= $(RISCV)/bin/riscv32-unknown-elf-
RISCV_GCC = $(RISCV_EXE_PREFIX)gcc
RISCV_AR = $(RISCV_EXE_PREFIX)ar
SRC = crt0.S handlers.S syscalls.c vectors.S
OBJ = crt0.o handlers.o syscalls.o vectors.o
LIBCV-VERIF = libcv-verif.a
SRC = crt0.S handlers.S syscalls.c vectors.S utils.c
OBJ = crt0.o handlers.o syscalls.o vectors.o utils.o
LIBCV-VERIF = libcv-verif.a
CFLAGS ?= -Os -g -static -mabi=ilp32 -march=$(CV_SW_MARCH) -Wall -pedantic

all: $(LIBCV-VERIF)

$(LIBCV-VERIF): $(OBJ)
$(LIBCV-VERIF): $(OBJ)
$(RISCV_AR) rcs $@ $(OBJ)

%.o : %.c
$(RISCV_GCC) $(CFLAGS) -c $< -o $@

%.o : %.S
$(RISCV_GCC) $(CFLAGS) -c $< -o $@

Expand Down
10 changes: 9 additions & 1 deletion cv32e20/bsp/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ _start:
li a2, 0

call main
tail exit
tail _exit

.size _start, .-_start

Expand All @@ -70,3 +70,11 @@ _fini:
ret
.size _init, .-_init
.size _fini, .-_fini

.section ".tohost","aw",@progbits
.align 6
.globl tohost
tohost: .dword 0
.align 6
.globl fromhost
fromhost: .dword 0
6 changes: 5 additions & 1 deletion cv32e20/bsp/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ SECTIONS
KEEP (*(.text.start))
} >ram

/* CORE-V: interrupt vectors */
/* CORE-V: interrupt vectors */
.vectors : ALIGN(256)
{
PROVIDE(__vector_start = .);
Expand Down Expand Up @@ -119,6 +119,10 @@ SECTIONS
{
KEEP (*(SORT_NONE(.fini)))
} >ram

/* tohost symbol to detect end-of-test */
.tohost : { *(.tohost) } >ram

PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
Expand Down
35 changes: 2 additions & 33 deletions cv32e20/bsp/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,8 @@
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "syscalls.h"

#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/times.h>
#include <sys/utime.h>
#include <newlib.h>
#include <unistd.h>
#include <errno.h>
#include <machine/syscall.h>
#include <assert.h>
#undef errno
extern int errno;

/* write to this reg for outputting strings */
#define STDOUT_REG 0x10000000
/* write test result of program to this reg */
#define RESULT_REG 0x20000000
/* write exit value of program to this reg */
#define EXIT_REG 0x20000004

#define STDOUT_FILENO 1

/* It turns out that older newlib versions use different symbol names which goes
* against newlib recommendations. Anyway this is fixed in later version.
*/
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
#define _sbrk sbrk
#define _write write
#define _close close
#define _lseek lseek
#define _read read
#define _fstat fstat
#define _isatty isatty
#endif
/* Upstream newlib now defines this in libgloss/riscv/internal_syscall.h. */
long
__syscall_error(long a0)
Expand Down Expand Up @@ -111,6 +79,7 @@ int _execve(const char *name, char *const argv[], char *const env[])

void _exit(int exit_status)
{
tohost = (exit_status << 1) | 1;
*(volatile int *)EXIT_REG = exit_status;
asm volatile("wfi");
/* _exit should not return */
Expand Down
38 changes: 38 additions & 0 deletions cv32e20/bsp/syscalls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/times.h>
#include <sys/utime.h>
#include <newlib.h>
#include <unistd.h>
#include <errno.h>
#include <machine/syscall.h>
#include <assert.h>
#undef errno
extern int errno;
extern volatile uint64_t tohost;
extern volatile uint64_t fromhost;

/* write to this reg for outputting strings */
#define STDOUT_REG 0x10000000
/* write test result of program to this reg */
#define RESULT_REG 0x20000000
/* write exit value of program to this reg */
#define EXIT_REG 0x20000004

#define STDOUT_FILENO 1

/* It turns out that older newlib versions use different symbol names which goes
* against newlib recommendations. Anyway this is fixed in later version.
*/
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
#define _sbrk sbrk
#define _write write
#define _close close
#define _lseek lseek
#define _read read
#define _fstat fstat
#define _isatty isatty
#endif

16 changes: 16 additions & 0 deletions cv32e20/bsp/utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "utils.h"

void test_exit(int value) {
asm inline(" \
mv a7, %0; \
mv t0, %0; \
mv a0, %1; \
ecall;"
:
: "r" (SYS_exit), "r" (value) );
}

void test_fail() { test_exit(1); }

void test_pass() { test_exit(0); }

18 changes: 18 additions & 0 deletions cv32e20/bsp/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <stdint.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/times.h>
#include <sys/utime.h>
#include <newlib.h>
#include <unistd.h>
#include <errno.h>
#include <machine/syscall.h>
#include <assert.h>
#undef errno

void test_exit(int value);

void test_fail();
void test_pass();
18 changes: 11 additions & 7 deletions cv32e20/env/corev-dv/cv32e20_instr_gen_config.sv
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
// Debug pointer may not be the return address, stack pointer, nor thread pointer
if (!gen_debug_section) {
dp == ZERO;
} else {
} else {
!(dp inside {sp, tp, ra, scratch_reg, GP, RA, ZERO});
foreach (gpr[i]) {
!(gpr[i] inside {dp});
Expand All @@ -64,15 +64,19 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
};
}

constraint scratch_reg_c_not_zero {
scratch_reg != ZERO;
}

constraint fast_intr_handler_c {
if (!enable_fast_interrupt_handler) {
knob_zero_fast_intr_handlers == 1;
}

// Nver use fast handler for exceptions (interrupt 0)
use_fast_intr_handler[0] == 0;

knob_zero_fast_intr_handlers -> !use_fast_intr_handler;
knob_zero_fast_intr_handlers -> !use_fast_intr_handler;

// VECTORED mode required for any fast interrupts
if (use_fast_intr_handler) {
Expand All @@ -86,7 +90,7 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
`uvm_field_enum(riscv_reg_t, dp, UVM_DEFAULT)
`uvm_field_enum(riscv_reg_t, scratch_reg, UVM_DEFAULT)
`uvm_field_int(enable_fast_interrupt_handler, UVM_DEFAULT)
`uvm_field_int(use_fast_intr_handler, UVM_DEFAULT)
`uvm_field_int(use_fast_intr_handler, UVM_DEFAULT)
`uvm_object_utils_end

function new(string name="");
Expand All @@ -105,13 +109,13 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;

// In the debug ROM some combinations are not valid because they use the same register (dscratch0)
if (gen_debug_section) begin
if ((enable_ebreak_in_debug_rom || set_dcsr_ebreak) &&
if ((enable_ebreak_in_debug_rom || set_dcsr_ebreak) &&
enable_debug_single_step) begin
`uvm_fatal("CVINSTGENCFG",
`uvm_fatal("CVINSTGENCFG",
$sformatf("Illegal combination of debug plusargs: enable_ebreak_in_debug_rom = %0d, set_dcsr_ebreakl = %0d, enable_debug_single_step = %0d",
enable_ebreak_in_debug_rom, set_dcsr_ebreak, enable_debug_single_step))
end
end
end
endfunction : post_randomize

endclass : cv32e20_instr_gen_config
55 changes: 50 additions & 5 deletions cv32e20/env/uvme/uvme_cv32e20_env.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ typedef class uvme_cv32e20_vp_sig_writer_seq_c;
typedef class uvme_cv32e20_vp_status_flags_seq_c;
typedef class uvme_cv32e20_vp_rand_num_seq_c;

import "DPI-C" function longint read_symbol(input string symbol, output longint unsigned address);
import "DPI-C" function read_elf(input string filename);
/**
* Top-level component that encapsulates, builds and connects all other
* CV32E20 environment components.
Expand All @@ -50,6 +52,8 @@ class uvme_cv32e20_env_c extends uvm_env;
uvma_obi_memory_agent_c obi_memory_data_agent ;


longint unsigned vp_rand_num, vp_sig_writer, vp_status_flags_tohost, vp_status_flags_legacy, vp_interrupt_timer, vp_debug_control;
byte vp_status_flags_tohost_present = 0;

`uvm_component_utils_begin(uvme_cv32e20_env_c)
`uvm_field_object(cfg , UVM_DEFAULT)
Expand Down Expand Up @@ -142,6 +146,11 @@ class uvme_cv32e20_env_c extends uvm_env;
*/
extern virtual function void assemble_vsequencer();

/**
* Load binary into elfloader to enable aux functions
*/
extern virtual function void load_binary();

endclass : uvme_cv32e20_env_c


Expand Down Expand Up @@ -181,6 +190,7 @@ function void uvme_cv32e20_env_c::build_phase(uvm_phase phase);
create_env_components();

if (cfg.is_active) begin
load_binary();
create_vsequencer();
end

Expand Down Expand Up @@ -250,39 +260,51 @@ task uvme_cv32e20_env_c::run_phase(uvm_phase phase);
//void'(data_slv_seq.register_vp_vseq("vp_rand_num", 32'h1500_1000, 1, uvma_obi_memory_vp_rand_num_seq_c::get_type()));
begin
uvme_cv32e20_vp_rand_num_seq_c vp_seq;
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_rand_num", 32'h1500_1000, uvme_cv32e20_vp_rand_num_seq_c::get_type()))) begin
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_rand_num", vp_rand_num, uvme_cv32e20_vp_rand_num_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_rand_num correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
end

begin
uvme_cv32e20_vp_sig_writer_seq_c vp_seq;
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_sig_writer", 32'h2000_0008, uvme_cv32e20_vp_sig_writer_seq_c::get_type()))) begin
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_sig_writer", vp_sig_writer, uvme_cv32e20_vp_sig_writer_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_sig_writes correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
end

begin
if (vp_status_flags_tohost_present) begin
uvme_cv32e20_vp_status_flags_seq_c vp_seq;
`uvm_info("CV32E20VPSEQ", $sformatf("Setting up vp_status with addr %h", vp_status_flags_tohost), UVM_LOW)
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_status_flags", vp_status_flags_tohost, uvme_cv32e20_vp_status_flags_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_status_flags correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
end
end

begin
uvme_cv32e20_vp_status_flags_seq_c vp_seq;
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_status_flags", 32'h2000_0000, uvme_cv32e20_vp_status_flags_seq_c::get_type()))) begin
`uvm_info("CV32E20VPSEQ", $sformatf("Setting up vp_status with addr %h", vp_status_flags_legacy), UVM_LOW)
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_status_flags", vp_status_flags_legacy, uvme_cv32e20_vp_status_flags_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_status_flags correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
end

begin
uvme_cv32e20_vp_interrupt_timer_seq_c vp_seq;
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_interrupt_timer", 32'h1500_0000, uvme_cv32e20_vp_interrupt_timer_seq_c::get_type()))) begin
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_interrupt_timer", vp_interrupt_timer, uvme_cv32e20_vp_interrupt_timer_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_interrupt_timer correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
end

begin
uvme_cv32e20_vp_debug_control_seq_c vp_seq;
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_debug_control", 32'h1500_0008, uvme_cv32e20_vp_debug_control_seq_c::get_type()))) begin
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_debug_control", vp_debug_control, uvme_cv32e20_vp_debug_control_seq_c::get_type()))) begin
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_debug_control correctly"));
end
vp_seq.cv32e20_cntxt = cntxt;
Expand Down Expand Up @@ -449,5 +471,28 @@ function void uvme_cv32e20_env_c::assemble_vsequencer();
endfunction: assemble_vsequencer


function void uvme_cv32e20_env_c::load_binary();

string binary;
vp_rand_num = 32'h1500_1000;
vp_sig_writer = 32'h2000_0008;
vp_status_flags_tohost = 32'h0000_0000;
vp_status_flags_legacy = 32'h2000_0000;
vp_interrupt_timer = 32'h1500_0000;
vp_debug_control = 32'h1500_0008;

if ($value$plusargs("elf_file=%s", binary))
begin
read_elf(binary);
vp_status_flags_tohost_present = ! read_symbol("tohost", vp_status_flags_tohost);
if (vp_status_flags_tohost_present) begin
`uvm_info("cv32e20_env", $sformatf("Loading TOHOST symbol: %h", vp_status_flags_tohost), UVM_LOW)
end else begin
`uvm_info("cv32e20_env", "TOHOST symbol not present" , UVM_LOW)
end
end

endfunction: load_binary

`endif // __UVME_CV32E20_ENV_SV__

Loading

0 comments on commit 7c9cf7d

Please sign in to comment.