Skip to content

Commit b6df6c5

Browse files
author
Mario
committed
Add tohost capabilities to the UVM env
* 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
1 parent 54a127c commit b6df6c5

File tree

16 files changed

+326
-79
lines changed

16 files changed

+326
-79
lines changed

cv32e20/bsp/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ RISCV_GCC = $(RISCV_EXE_PREFIX)gcc
1212
RISCV_AR = $(RISCV_EXE_PREFIX)ar
1313
SRC = crt0.S handlers.S syscalls.c vectors.S
1414
OBJ = crt0.o handlers.o syscalls.o vectors.o
15-
LIBCV-VERIF = libcv-verif.a
16-
CFLAGS ?= -Os -g -static -mabi=ilp32 -march=$(CV_SW_MARCH) -Wall -pedantic
15+
LIBCV-VERIF = libcv-verif.a
16+
CFLAGS ?= -Os -g -static -mabi=ilp32 -march=$(RISCV_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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ SECTIONS
6565
KEEP(*(.vectors));
6666
} >ram
6767

68+
.tohost : { *(.tohost) } >ram
69+
6870
/* Read-only sections, merged into text segment: */
6971
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x10000)); . = SEGMENT_START("text-segment", 0x10000) + SIZEOF_HEADERS;
7072
.interp : { *(.interp) } >ram

cv32e20/bsp/syscalls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <assert.h>
3232
#undef errno
3333
extern int errno;
34+
extern volatile uint64_t tohost;
35+
extern volatile uint64_t fromhost;
3436

3537
/* write to this reg for outputting strings */
3638
#define STDOUT_REG 0x10000000
@@ -111,6 +113,7 @@ int _execve(const char *name, char *const argv[], char *const env[])
111113

112114
void _exit(int exit_status)
113115
{
116+
tohost = (exit_status << 1) | 1;
114117
*(volatile int *)EXIT_REG = exit_status;
115118
asm volatile("wfi");
116119
/* _exit should not return */

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: 33 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,7 @@ 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, vp_interrupt_timer, vp_debug_control;
5356

5457
`uvm_component_utils_begin(uvme_cv32e20_env_c)
5558
`uvm_field_object(cfg , UVM_DEFAULT)
@@ -142,6 +145,11 @@ class uvme_cv32e20_env_c extends uvm_env;
142145
*/
143146
extern virtual function void assemble_vsequencer();
144147

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

147155

@@ -181,6 +189,7 @@ function void uvme_cv32e20_env_c::build_phase(uvm_phase phase);
181189
create_env_components();
182190

183191
if (cfg.is_active) begin
192+
load_binary();
184193
create_vsequencer();
185194
end
186195

@@ -250,39 +259,39 @@ task uvme_cv32e20_env_c::run_phase(uvm_phase phase);
250259
//void'(data_slv_seq.register_vp_vseq("vp_rand_num", 32'h1500_1000, 1, uvma_obi_memory_vp_rand_num_seq_c::get_type()));
251260
begin
252261
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
262+
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
254263
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_rand_num correctly"));
255264
end
256265
vp_seq.cv32e20_cntxt = cntxt;
257266
end
258267

259268
begin
260269
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
270+
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
262271
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_sig_writes correctly"));
263272
end
264273
vp_seq.cv32e20_cntxt = cntxt;
265274
end
266275

267276
begin
268277
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
278+
if (!$cast(vp_seq, data_slv_seq.register_vp_vseq("vp_status_flags", vp_status_flags, uvme_cv32e20_vp_status_flags_seq_c::get_type()))) begin
270279
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_status_flags correctly"));
271280
end
272281
vp_seq.cv32e20_cntxt = cntxt;
273282
end
274283

275284
begin
276285
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
286+
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
278287
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_interrupt_timer correctly"));
279288
end
280289
vp_seq.cv32e20_cntxt = cntxt;
281290
end
282291

283292
begin
284293
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
294+
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
286295
`uvm_fatal("CV32E20VPSEQ", $sformatf("Could not cast vp_debug_control correctly"));
287296
end
288297
vp_seq.cv32e20_cntxt = cntxt;
@@ -449,5 +458,24 @@ function void uvme_cv32e20_env_c::assemble_vsequencer();
449458
endfunction: assemble_vsequencer
450459

451460

461+
function void uvme_cv32e20_env_c::load_binary();
462+
string binary;
463+
464+
vp_rand_num = 32'h1500_1000;
465+
vp_sig_writer = 32'h2000_0008;
466+
vp_status_flags = 32'h2000_0000;
467+
vp_interrupt_timer = 32'h1500_0000;
468+
vp_debug_control = 32'h1500_0008;
469+
470+
if ($value$plusargs("elf_file=%s", binary))
471+
begin
472+
read_elf(binary);
473+
read_symbol("tohost", vp_status_flags);
474+
`uvm_info("cv32e20_env", $sformatf("Loading TOHOST symbol: %h", vp_status_flags), UVM_LOW)
475+
end
476+
477+
478+
endfunction: load_binary
479+
452480
`endif // __UVME_CV32E20_ENV_SV__
453481

cv32e20/env/uvme/vseq/uvme_cv32e20_vp_status_flags_seq.sv

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
//
1+
//
22
// Copyright 2021 OpenHW Group
33
// Copyright 2021 Silicon Labs
44
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
5-
//
5+
//
66
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
77
// not use this file except in compliance with the License, or, at your option,
88
// the Apache License version 2.0. You may obtain a copy of the License at
9-
//
9+
//
1010
// https://solderpad.org/licenses/SHL-2.1/
11-
//
11+
//
1212
// Unless required by applicable law or agreed to in writing, any work
1313
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1414
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1515
// License for the specific language governing permissions and limitations
1616
// under the License.
17-
//
17+
//
1818

1919
`ifndef __UVME_CV32E20_VP_STATUS_FLAGS_SEQ_SV__
2020
`define __UVME_CV32E20_VP_STATUS_FLAGS_SEQ_SV__
2121

2222

2323
/**
24-
* Sequence implementing the virtual status flags decoding
24+
* Sequence implementing the virtual status flags decoding
2525
*/
2626
class uvme_cv32e20_vp_status_flags_seq_c extends uvma_obi_memory_vp_base_seq_c;
2727

@@ -31,7 +31,7 @@ class uvme_cv32e20_vp_status_flags_seq_c extends uvma_obi_memory_vp_base_seq_c;
3131

3232
`uvm_object_utils_begin(uvme_cv32e20_vp_status_flags_seq_c)
3333
`uvm_object_utils_end
34-
34+
3535
/**
3636
* Default constructor.
3737
*/
@@ -55,9 +55,9 @@ class uvme_cv32e20_vp_status_flags_seq_c extends uvma_obi_memory_vp_base_seq_c;
5555
endclass : uvme_cv32e20_vp_status_flags_seq_c
5656

5757
function uvme_cv32e20_vp_status_flags_seq_c::new(string name="uvme_cv32e20_vp_status_flags_seq_c");
58-
58+
5959
super.new(name);
60-
60+
6161
endfunction : new
6262

6363
function int unsigned uvme_cv32e20_vp_status_flags_seq_c::get_num_words();
@@ -81,31 +81,26 @@ task uvme_cv32e20_vp_status_flags_seq_c::vp_body(uvma_obi_memory_mon_trn_c mon_t
8181
uvma_obi_memory_slv_seq_item_c slv_rsp;
8282

8383
`uvm_create(slv_rsp)
84-
85-
slv_rsp.orig_trn = mon_trn;
84+
85+
slv_rsp.orig_trn = mon_trn;
8686
slv_rsp.err = 1'b0;
8787

8888
if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin
8989
`uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'vp_status_flags':\n%s", mon_trn.sprint()), UVM_DEBUG)
9090
case (get_vp_index(mon_trn))
9191
0: begin
92-
if (mon_trn.data == 'd123456789) begin
93-
`uvm_info("VP_VSEQ", "virtual peripheral: TEST PASSED", UVM_DEBUG)
92+
if (mon_trn.data[0] == 1) begin
9493
cv32e20_cntxt.vp_status_vif.tests_passed = 1;
9594
cv32e20_cntxt.vp_status_vif.exit_valid = 1;
96-
cv32e20_cntxt.vp_status_vif.exit_value = 0;
97-
end
98-
else if (mon_trn.data == 'd1) begin
99-
cv32e20_cntxt.vp_status_vif.tests_failed = 1;
100-
cv32e20_cntxt.vp_status_vif.exit_valid = 1;
101-
cv32e20_cntxt.vp_status_vif.exit_value = 1;
95+
cv32e20_cntxt.vp_status_vif.exit_value = mon_trn.data >> 1;
96+
`uvm_info("VP_VSEQ", $sformatf("virtual peripheral: TEST PASSED WITH CODE %h", cv32e20_cntxt.vp_status_vif.exit_value), UVM_DEBUG)
10297
end
10398
end
10499
1: begin
105100
`uvm_info("VP_VSEQ", "virtual peripheral: END OF SIM", UVM_DEBUG)
106101
cv32e20_cntxt.vp_status_vif.exit_valid = 1;
107102
cv32e20_cntxt.vp_status_vif.exit_value = mon_trn.data;
108-
end
103+
end
109104
endcase
110105
end
111106
else if (mon_trn.access_type == UVMA_OBI_MEMORY_ACCESS_READ) begin

cv32e20/tb/uvmt/uvmt_cv32e20_dut_wrap.sv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ module uvmt_cv32e20_dut_wrap #(
117117

118118
// ------------------------------------------------------------------------
119119
// Instantiate the core
120-
// cve2_top #(
121-
cve2_top_tracing #(
120+
// cve2_top #(
121+
cve2_top_tracing #(
122122
.MHPMCounterNum (MHPMCounterNum),
123123
.MHPMCounterWidth (MHPMCounterWidth),
124124
.RV32E (RV32E),
@@ -136,7 +136,7 @@ module uvmt_cv32e20_dut_wrap #(
136136
.ram_cfg_i ( prim_ram_1p_pkg::RAM_1P_CFG_DEFAULT ),
137137

138138
.hart_id_i ( 32'h0000_0000 ),
139-
.boot_addr_i ( 32'h0000_0000 ), //<---MJS changing to 0
139+
.boot_addr_i ( 32'h0000_0000 ), //<---MJS changing to 0
140140

141141
// Instruction memory interface
142142
.instr_req_o ( obi_memory_instr_if.req ), // core to agent

cv32e40p/env/uvme/uvme_rv32isa_covg_trn.sv

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright 2020 OpenHW Group
22
// Copyright 2020 Silicon Labs, Inc.
3-
//
3+
//
44
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
66
// You may obtain a copy of the License at
7-
//
7+
//
88
// https://solderpad.org/licenses/
9-
//
9+
//
1010
// Unless required by applicable law or agreed to in writing, software
1111
// distributed under the License is distributed on an "AS IS" BASIS,
1212
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,18 +25,17 @@
2525
through UVM testbench
2626
*/
2727
class uvme_rv32isa_covg_trn_c extends uvml_trn_mon_trn_c;
28-
28+
// Note, structs are not supported in the uvm field macros
29+
`uvm_object_utils(uvme_rv32isa_covg_trn_c)
30+
2931
ins_t ins;
3032

31-
// Note, structs are not supported in the uvm field macros
32-
`uvm_object_utils_begin(uvme_rv32isa_covg_trn_c)
33-
`uvm_object_utils_end
34-
33+
3534
/**
3635
* Default constructor.
3736
*/
3837
extern function new(string name="uvme_rv32isa_covg_trn");
39-
38+
4039
extern function void do_copy(uvm_object rhs);
4140
extern function void do_print(uvm_printer printer);
4241

@@ -46,9 +45,9 @@ endclass : uvme_rv32isa_covg_trn_c
4645
`pragma protect begin
4746

4847
function uvme_rv32isa_covg_trn_c::new(string name="uvme_rv32isa_covg_trn");
49-
48+
5049
super.new(name);
51-
50+
5251
endfunction : new
5352

5453
function void uvme_rv32isa_covg_trn_c::do_copy(uvm_object rhs);
@@ -57,7 +56,7 @@ function void uvme_rv32isa_covg_trn_c::do_copy(uvm_object rhs);
5756
super.do_copy(rhs);
5857
assert($cast(rhs_trn, rhs));
5958

60-
this.ins.ins_str = rhs_trn.ins.ins_str;
59+
this.ins.ins_str = rhs_trn.ins.ins_str;
6160
this.ins.asm = rhs_trn.ins.asm;
6261
foreach (this.ins.ops[i]) begin
6362
this.ins.ops[i].key = rhs_trn.ins.ops[i].key;

0 commit comments

Comments
 (0)