Skip to content

Commit 7c9cf7d

Browse files
author
Mario
committed
Add tohost and adapt existing tests
* 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
1 parent 69fca51 commit 7c9cf7d

File tree

40 files changed

+652
-487
lines changed

40 files changed

+652
-487
lines changed

cv32e20/bsp/Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ RISCV ?= $(CV_SW_TOOLCHAIN)
1010
RISCV_EXE_PREFIX ?= $(RISCV)/bin/riscv32-unknown-elf-
1111
RISCV_GCC = $(RISCV_EXE_PREFIX)gcc
1212
RISCV_AR = $(RISCV_EXE_PREFIX)ar
13-
SRC = crt0.S handlers.S syscalls.c vectors.S
14-
OBJ = crt0.o handlers.o syscalls.o vectors.o
15-
LIBCV-VERIF = libcv-verif.a
13+
SRC = crt0.S handlers.S syscalls.c vectors.S utils.c
14+
OBJ = crt0.o handlers.o syscalls.o vectors.o utils.o
15+
LIBCV-VERIF = libcv-verif.a
1616
CFLAGS ?= -Os -g -static -mabi=ilp32 -march=$(CV_SW_MARCH) -Wall -pedantic
1717

1818
all: $(LIBCV-VERIF)
1919

20-
$(LIBCV-VERIF): $(OBJ)
20+
$(LIBCV-VERIF): $(OBJ)
2121
$(RISCV_AR) rcs $@ $(OBJ)
2222

2323
%.o : %.c
2424
$(RISCV_GCC) $(CFLAGS) -c $< -o $@
25-
25+
2626
%.o : %.S
2727
$(RISCV_GCC) $(CFLAGS) -c $< -o $@
2828

cv32e20/bsp/crt0.S

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ _start:
5555
li a2, 0
5656

5757
call main
58-
tail exit
58+
tail _exit
5959

6060
.size _start, .-_start
6161

@@ -70,3 +70,11 @@ _fini:
7070
ret
7171
.size _init, .-_init
7272
.size _fini, .-_fini
73+
74+
.section ".tohost","aw",@progbits
75+
.align 6
76+
.globl tohost
77+
tohost: .dword 0
78+
.align 6
79+
.globl fromhost
80+
fromhost: .dword 0

cv32e20/bsp/link.ld

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ SECTIONS
5858
KEEP (*(.text.start))
5959
} >ram
6060

61-
/* CORE-V: interrupt vectors */
61+
/* CORE-V: interrupt vectors */
6262
.vectors : ALIGN(256)
6363
{
6464
PROVIDE(__vector_start = .);
@@ -119,6 +119,10 @@ SECTIONS
119119
{
120120
KEEP (*(SORT_NONE(.fini)))
121121
} >ram
122+
123+
/* tohost symbol to detect end-of-test */
124+
.tohost : { *(.tohost) } >ram
125+
122126
PROVIDE (__etext = .);
123127
PROVIDE (_etext = .);
124128
PROVIDE (etext = .);

cv32e20/bsp/syscalls.c

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,8 @@
1919
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2020
* PERFORMANCE OF THIS SOFTWARE.
2121
*/
22+
#include "syscalls.h"
2223

23-
#include <sys/stat.h>
24-
#include <sys/timeb.h>
25-
#include <sys/times.h>
26-
#include <sys/utime.h>
27-
#include <newlib.h>
28-
#include <unistd.h>
29-
#include <errno.h>
30-
#include <machine/syscall.h>
31-
#include <assert.h>
32-
#undef errno
33-
extern int errno;
34-
35-
/* write to this reg for outputting strings */
36-
#define STDOUT_REG 0x10000000
37-
/* write test result of program to this reg */
38-
#define RESULT_REG 0x20000000
39-
/* write exit value of program to this reg */
40-
#define EXIT_REG 0x20000004
41-
42-
#define STDOUT_FILENO 1
43-
44-
/* It turns out that older newlib versions use different symbol names which goes
45-
* against newlib recommendations. Anyway this is fixed in later version.
46-
*/
47-
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
48-
#define _sbrk sbrk
49-
#define _write write
50-
#define _close close
51-
#define _lseek lseek
52-
#define _read read
53-
#define _fstat fstat
54-
#define _isatty isatty
55-
#endif
5624
/* Upstream newlib now defines this in libgloss/riscv/internal_syscall.h. */
5725
long
5826
__syscall_error(long a0)
@@ -111,6 +79,7 @@ int _execve(const char *name, char *const argv[], char *const env[])
11179

11280
void _exit(int exit_status)
11381
{
82+
tohost = (exit_status << 1) | 1;
11483
*(volatile int *)EXIT_REG = exit_status;
11584
asm volatile("wfi");
11685
/* _exit should not return */

cv32e20/bsp/syscalls.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <sys/stat.h>
4+
#include <sys/timeb.h>
5+
#include <sys/times.h>
6+
#include <sys/utime.h>
7+
#include <newlib.h>
8+
#include <unistd.h>
9+
#include <errno.h>
10+
#include <machine/syscall.h>
11+
#include <assert.h>
12+
#undef errno
13+
extern int errno;
14+
extern volatile uint64_t tohost;
15+
extern volatile uint64_t fromhost;
16+
17+
/* write to this reg for outputting strings */
18+
#define STDOUT_REG 0x10000000
19+
/* write test result of program to this reg */
20+
#define RESULT_REG 0x20000000
21+
/* write exit value of program to this reg */
22+
#define EXIT_REG 0x20000004
23+
24+
#define STDOUT_FILENO 1
25+
26+
/* It turns out that older newlib versions use different symbol names which goes
27+
* against newlib recommendations. Anyway this is fixed in later version.
28+
*/
29+
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
30+
#define _sbrk sbrk
31+
#define _write write
32+
#define _close close
33+
#define _lseek lseek
34+
#define _read read
35+
#define _fstat fstat
36+
#define _isatty isatty
37+
#endif
38+

cv32e20/bsp/utils.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "utils.h"
2+
3+
void test_exit(int value) {
4+
asm inline(" \
5+
mv a7, %0; \
6+
mv t0, %0; \
7+
mv a0, %1; \
8+
ecall;"
9+
:
10+
: "r" (SYS_exit), "r" (value) );
11+
}
12+
13+
void test_fail() { test_exit(1); }
14+
15+
void test_pass() { test_exit(0); }
16+

cv32e20/bsp/utils.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include <sys/stat.h>
5+
#include <sys/timeb.h>
6+
#include <sys/times.h>
7+
#include <sys/utime.h>
8+
#include <newlib.h>
9+
#include <unistd.h>
10+
#include <errno.h>
11+
#include <machine/syscall.h>
12+
#include <assert.h>
13+
#undef errno
14+
15+
void test_exit(int value);
16+
17+
void test_fail();
18+
void test_pass();

cv32e20/env/corev-dv/cv32e20_instr_gen_config.sv

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
4242
// Debug pointer may not be the return address, stack pointer, nor thread pointer
4343
if (!gen_debug_section) {
4444
dp == ZERO;
45-
} else {
45+
} else {
4646
!(dp inside {sp, tp, ra, scratch_reg, GP, RA, ZERO});
4747
foreach (gpr[i]) {
4848
!(gpr[i] inside {dp});
@@ -64,15 +64,19 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
6464
};
6565
}
6666

67+
constraint scratch_reg_c_not_zero {
68+
scratch_reg != ZERO;
69+
}
70+
6771
constraint fast_intr_handler_c {
6872
if (!enable_fast_interrupt_handler) {
6973
knob_zero_fast_intr_handlers == 1;
7074
}
71-
75+
7276
// Nver use fast handler for exceptions (interrupt 0)
7377
use_fast_intr_handler[0] == 0;
7478

75-
knob_zero_fast_intr_handlers -> !use_fast_intr_handler;
79+
knob_zero_fast_intr_handlers -> !use_fast_intr_handler;
7680

7781
// VECTORED mode required for any fast interrupts
7882
if (use_fast_intr_handler) {
@@ -86,7 +90,7 @@ class cv32e20_instr_gen_config extends riscv_instr_gen_config;
8690
`uvm_field_enum(riscv_reg_t, dp, UVM_DEFAULT)
8791
`uvm_field_enum(riscv_reg_t, scratch_reg, UVM_DEFAULT)
8892
`uvm_field_int(enable_fast_interrupt_handler, UVM_DEFAULT)
89-
`uvm_field_int(use_fast_intr_handler, UVM_DEFAULT)
93+
`uvm_field_int(use_fast_intr_handler, UVM_DEFAULT)
9094
`uvm_object_utils_end
9195

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

106110
// In the debug ROM some combinations are not valid because they use the same register (dscratch0)
107111
if (gen_debug_section) begin
108-
if ((enable_ebreak_in_debug_rom || set_dcsr_ebreak) &&
112+
if ((enable_ebreak_in_debug_rom || set_dcsr_ebreak) &&
109113
enable_debug_single_step) begin
110-
`uvm_fatal("CVINSTGENCFG",
114+
`uvm_fatal("CVINSTGENCFG",
111115
$sformatf("Illegal combination of debug plusargs: enable_ebreak_in_debug_rom = %0d, set_dcsr_ebreakl = %0d, enable_debug_single_step = %0d",
112116
enable_ebreak_in_debug_rom, set_dcsr_ebreak, enable_debug_single_step))
113117
end
114-
end
118+
end
115119
endfunction : post_randomize
116120

117121
endclass : cv32e20_instr_gen_config

cv32e20/env/uvme/uvme_cv32e20_env.sv

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ typedef class uvme_cv32e20_vp_sig_writer_seq_c;
2626
typedef class uvme_cv32e20_vp_status_flags_seq_c;
2727
typedef class uvme_cv32e20_vp_rand_num_seq_c;
2828

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

5254

55+
longint unsigned vp_rand_num, vp_sig_writer, vp_status_flags_tohost, vp_status_flags_legacy, vp_interrupt_timer, vp_debug_control;
56+
byte vp_status_flags_tohost_present = 0;
5357

5458
`uvm_component_utils_begin(uvme_cv32e20_env_c)
5559
`uvm_field_object(cfg , UVM_DEFAULT)
@@ -142,6 +146,11 @@ class uvme_cv32e20_env_c extends uvm_env;
142146
*/
143147
extern virtual function void assemble_vsequencer();
144148

149+
/**
150+
* Load binary into elfloader to enable aux functions
151+
*/
152+
extern virtual function void load_binary();
153+
145154
endclass : uvme_cv32e20_env_c
146155

147156

@@ -181,6 +190,7 @@ function void uvme_cv32e20_env_c::build_phase(uvm_phase phase);
181190
create_env_components();
182191

183192
if (cfg.is_active) begin
193+
load_binary();
184194
create_vsequencer();
185195
end
186196

@@ -250,39 +260,51 @@ task uvme_cv32e20_env_c::run_phase(uvm_phase phase);
250260
//void'(data_slv_seq.register_vp_vseq("vp_rand_num", 32'h1500_1000, 1, uvma_obi_memory_vp_rand_num_seq_c::get_type()));
251261
begin
252262
uvme_cv32e20_vp_rand_num_seq_c vp_seq;
253-
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
263+
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
254264
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_rand_num correctly"));
255265
end
256266
vp_seq.cv32e20_cntxt = cntxt;
257267
end
258268

259269
begin
260270
uvme_cv32e20_vp_sig_writer_seq_c vp_seq;
261-
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
271+
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
262272
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_sig_writes correctly"));
263273
end
264274
vp_seq.cv32e20_cntxt = cntxt;
265275
end
266276

277+
begin
278+
if (vp_status_flags_tohost_present) begin
279+
uvme_cv32e20_vp_status_flags_seq_c vp_seq;
280+
`uvm_info("CV32E20VPSEQ", $sformatf("Setting up vp_status with addr %h", vp_status_flags_tohost), UVM_LOW)
281+
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
282+
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_status_flags correctly"));
283+
end
284+
vp_seq.cv32e20_cntxt = cntxt;
285+
end
286+
end
287+
267288
begin
268289
uvme_cv32e20_vp_status_flags_seq_c vp_seq;
269-
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
290+
`uvm_info("CV32E20VPSEQ", $sformatf("Setting up vp_status with addr %h", vp_status_flags_legacy), UVM_LOW)
291+
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
270292
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_status_flags correctly"));
271293
end
272294
vp_seq.cv32e20_cntxt = cntxt;
273295
end
274296

275297
begin
276298
uvme_cv32e20_vp_interrupt_timer_seq_c vp_seq;
277-
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
299+
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
278300
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_interrupt_timer correctly"));
279301
end
280302
vp_seq.cv32e20_cntxt = cntxt;
281303
end
282304

283305
begin
284306
uvme_cv32e20_vp_debug_control_seq_c vp_seq;
285-
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
307+
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
286308
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_debug_control correctly"));
287309
end
288310
vp_seq.cv32e20_cntxt = cntxt;
@@ -449,5 +471,28 @@ function void uvme_cv32e20_env_c::assemble_vsequencer();
449471
endfunction: assemble_vsequencer
450472

451473

474+
function void uvme_cv32e20_env_c::load_binary();
475+
476+
string binary;
477+
vp_rand_num = 32'h1500_1000;
478+
vp_sig_writer = 32'h2000_0008;
479+
vp_status_flags_tohost = 32'h0000_0000;
480+
vp_status_flags_legacy = 32'h2000_0000;
481+
vp_interrupt_timer = 32'h1500_0000;
482+
vp_debug_control = 32'h1500_0008;
483+
484+
if ($value$plusargs("elf_file=%s", binary))
485+
begin
486+
read_elf(binary);
487+
vp_status_flags_tohost_present = ! read_symbol("tohost", vp_status_flags_tohost);
488+
if (vp_status_flags_tohost_present) begin
489+
`uvm_info("cv32e20_env", $sformatf("Loading TOHOST symbol: %h", vp_status_flags_tohost), UVM_LOW)
490+
end else begin
491+
`uvm_info("cv32e20_env", "TOHOST symbol not present" , UVM_LOW)
492+
end
493+
end
494+
495+
endfunction: load_binary
496+
452497
`endif // __UVME_CV32E20_ENV_SV__
453498

0 commit comments

Comments
 (0)