From 1ee5a6ae500ce70a437e4bb5c4cbc8c3a11f4763 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 19:55:50 -0400 Subject: [PATCH 01/10] PoC of calling vvp programatically, and calling back --- vvp/Makefile.in | 10 +- vvp/hello.sv | 64 ++++++++++++ vvp/lib_entry.cc | 250 ++++++++++++++++++++++++++++++++++++++++++++ vvp/run.sh | 9 ++ vvp/test_client.cpp | 183 ++++++++++++++++++++++++++++++++ 5 files changed, 514 insertions(+), 2 deletions(-) create mode 100644 vvp/hello.sv create mode 100644 vvp/lib_entry.cc create mode 100755 vvp/run.sh create mode 100644 vvp/test_client.cpp diff --git a/vvp/Makefile.in b/vvp/Makefile.in index 3dbd57b2fe..a3d1ebe13a 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -72,7 +72,7 @@ VPI = vpi_modules.o vpi_bit.o vpi_callback.o vpi_cobject.o vpi_const.o vpi_darra O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o compile.o \ concat.o dff.o class_type.o enum_type.o extend.o file_line.o latch.o npmos.o part.o \ - permaheap.o reduce.o resolv.o \ + permaheap.o reduce.o resolv.o lib_entry.o \ sfunc.o stop.o \ substitute.o \ symbols.o ufunc.o codes.o vthread.o schedule.o \ @@ -80,7 +80,7 @@ O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o c vvp_object.o vvp_cobject.o vvp_darray.o event.o logic.o delay.o \ words.o island_tran.o $(VPI) -all: dep vvp@EXEEXT@ vvp.man +all: dep vvp@EXEEXT@ vvp.man vvp.so check: all ifeq (@WIN32@,yes) @@ -131,10 +131,16 @@ vvp@EXEEXT@: $O $(srcdir)/vvp.def $(DLLTOOL) --dllname vvp$(suffix)@EXEEXT@ --def $(srcdir)/vvp.def \ --output-exp vvp.exp rm -f vvp$(suffix)@EXEEXT@ + echo vvp exe ext vvp$(suffix)@EXEEXT@ $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ vvp.exp $(LDFLAGS) $O $(dllib) $(LIBS) else vvp@EXEEXT@: $O + echo vvp exe ext vvp@EXEEXT@ CXX $(CXX) $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ $O $(LIBS) $(dllib) + +vvp.so: $O + echo vvp exe ext vvp@EXEEXT@ + $(CXX) -shared $(LDFLAGS) -o libvvp.so $O $(LIBS) $(dllib) endif %.o: %.cc config.h diff --git a/vvp/hello.sv b/vvp/hello.sv new file mode 100644 index 0000000000..570217cbb2 --- /dev/null +++ b/vvp/hello.sv @@ -0,0 +1,64 @@ +module main(); + // reg int foo; + reg clk; + reg rst; + + reg [31:0] cpp_in; + reg [31:0] cpp_out; + reg [31:0] cpp_mem_wr_req; + reg [31:0] cpp_mem_wr_addr; + reg [31:0] cpp_mem_wr_data; + + reg [31:0] n_cpp_in; + + reg [31:0] mem [1024]; + + task tick(); + #5 clk = 0; + #5 clk = 1; + endtask + + always @(*) begin + n_cpp_in = 0; + end + + always @(posedge clk, posedge rst) begin + if(rst) begin + cpp_in <= 0; + end else begin + cpp_in <= n_cpp_in; + end + if(cpp_mem_wr_req) begin + mem[cpp_mem_wr_addr] = cpp_mem_wr_data; + end + end + + initial begin + rst = 1; + tick(); + + rst <= 0; + tick(); + + $hello; + cpp_in = 23; + $giveme5(cpp_in, cpp_out); + $display("cpp_out %0d", cpp_out); + + tick(); + for(int i = 0; i < 4; i++) begin + $cpp_memread(i, cpp_mem_wr_req, cpp_mem_wr_addr, cpp_mem_wr_data); + tick(); + end + tick(); + tick(); + tick(); + tick(); + tick(); + tick(); + + for(int i = 0; i < 16; i++) begin + $display("i %0d %0d", i, mem[i]); + end + end +endmodule diff --git a/vvp/lib_entry.cc b/vvp/lib_entry.cc new file mode 100644 index 0000000000..02c804b0f6 --- /dev/null +++ b/vvp/lib_entry.cc @@ -0,0 +1,250 @@ +# include "version_base.h" +# include "version_tag.h" +# include "config.h" +# include "parse_misc.h" +# include "compile.h" +# include "schedule.h" +# include "vpi_priv.h" +# include "statistics.h" +# include "vvp_cleanup.h" +# include "vvp_object.h" +# include +# include +# include +# include +# include +#ifdef CHECK_WITH_VALGRIND +# include +#endif + +#if defined(HAVE_SYS_RESOURCE_H) +# include +# include +#endif // defined(HAVE_SYS_RESOURCE_H) + +#if defined(HAVE_GETOPT_H) +# include +#endif + +#if defined(__MINGW32__) +# include +#endif + +using namespace std; + +// ofstream debug_file; + +#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H) +extern "C" int getopt(int argc, char*argv[], const char*fmt); +extern "C" int optind; +extern "C" const char*optarg; +#endif + +static void my_getrusage(struct rusage *a) +{ + getrusage(RUSAGE_SELF, a); + +# if defined(LINUX) + { + FILE *statm; + unsigned siz, rss, shd; + long page_size = sysconf(_SC_PAGESIZE); + if (page_size==-1) page_size=0; + statm = fopen("/proc/self/statm", "r"); + if (!statm) { + perror("/proc/self/statm"); + return; + } + /* Given that these are in pages we'll limit the value to + * what will fit in a 32 bit integer to prevent undefined + * behavior in fscanf(). */ + if (3 == fscanf(statm, "%9u %9u %9u", &siz, &rss, &shd)) { + a->ru_maxrss = page_size * siz; + a->ru_idrss = page_size * rss; + a->ru_ixrss = page_size * shd; + } + fclose(statm); + } +# endif +} + +static void final_cleanup() +{ + vvp_object::cleanup(); + + /* + * We only need to cleanup the memory if we are checking with valgrind. + */ +#ifdef CHECK_WITH_VALGRIND + /* Clean up the file name table. */ + for (vector::iterator cur = file_names.begin(); + cur != file_names.end() ; ++ cur ) { + delete[] *cur; + } + /* Clear the static result buffer. */ + (void)need_result_buf(0, RBUF_DEL); + codespace_delete(); + root_table_delete(); + def_table_delete(); + vpi_mcd_delete(); + dec_str_delete(); + modpath_delete(); + vpi_handle_delete(); + vpi_stack_delete(); + udp_defns_delete(); + island_delete(); + signal_pool_delete(); + vvp_net_pool_delete(); + ufunc_pool_delete(); +#endif + /* + * Unload the VPI modules. This is essential for MinGW, to ensure + * dump files are flushed before the main process terminates, as + * the DLL termination code is called after all remaining open + * files are automatically closed. + */ + load_module_delete(); + +#ifdef CHECK_WITH_VALGRIND + simulator_cb_delete(); + /* This is needed to prevent valgrind from complaining about + * _dlerror_run() having a memory leak. */ +// HERE: Is this portable? Does it break anything? + pthread_exit(NULL); +#endif +} + +static void print_rusage(struct rusage *a, struct rusage *b) +{ + double delta = a->ru_utime.tv_sec + + a->ru_utime.tv_usec/1E6 + + a->ru_stime.tv_sec + + a->ru_stime.tv_usec/1E6 + - b->ru_utime.tv_sec + - b->ru_utime.tv_usec/1E6 + - b->ru_stime.tv_sec + - b->ru_stime.tv_usec/1E6 + ; + + vpi_mcd_printf(1, + " ... %G seconds," + " %.1f/%.1f/%.1f KBytes size/rss/shared\n", + delta, + a->ru_maxrss/1024.0, + (a->ru_idrss+a->ru_isrss)/1024.0, + a->ru_ixrss/1024.0 ); +} + +static bool have_ivl_version = false; + +extern unsigned module_cnt; +extern const char*module_tab[64]; + +extern void vpip_mcd_init(FILE *log); +extern void vvp_vpi_init(void); + +void compile() { + // int opt; + // unsigned flag_errors = 0; + const char*design_path = 0; + struct rusage cycles[3]; + // const char *logfile_name = 0x0; + FILE *logfile = 0x0; + extern void vpi_set_vlog_info(int, char**); + extern bool stop_is_finish; + extern int stop_is_finish_exit_code; + + design_path = "hello.vvp"; + + vpip_add_env_and_default_module_paths(); + + vpip_mcd_init(logfile); + vvp_vpi_init(); + compile_init(); + for (unsigned idx = 0 ; idx < module_cnt ; idx += 1) + vpip_load_module(module_tab[idx]); + compile_design(design_path); + destroy_lexor(); + print_vpi_call_errors(); + + if (!have_ivl_version) { + if (verbose_flag) vpi_mcd_printf(1, "... "); + vpi_mcd_printf(1, "Warning: vvp input file may not be correct " + "version!\n"); + } + + if (verbose_flag) { + vpi_mcd_printf(1, "Compile cleanup...\n"); + } + + compile_cleanup(); + + if (compile_errors > 0) { + vpi_mcd_printf(1, "%s: Program not runnable, %u errors.\n", + design_path, compile_errors); + final_cleanup(); + return; + } + + if (verbose_flag) { + vpi_mcd_printf(1, " ... %8lu functors (net_fun pool=%zu bytes)\n", + count_functors, vvp_net_fun_t::heap_total()); + vpi_mcd_printf(1, " %8lu logic\n", count_functors_logic); + vpi_mcd_printf(1, " %8lu bufif\n", count_functors_bufif); + vpi_mcd_printf(1, " %8lu resolv\n",count_functors_resolv); + vpi_mcd_printf(1, " %8lu signals\n", count_functors_sig); + vpi_mcd_printf(1, " ... %8lu filters (net_fil pool=%zu bytes)\n", + count_filters, vvp_net_fil_t::heap_total()); + vpi_mcd_printf(1, " ... %8lu opcodes (%zu bytes)\n", + count_opcodes, size_opcodes); + vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets); + vpi_mcd_printf(1, " ... %8lu vvp_nets (%zu bytes)\n", + count_vvp_nets, size_vvp_nets); + vpi_mcd_printf(1, " ... %8lu arrays (%lu words)\n", + count_net_arrays, count_net_array_words); + vpi_mcd_printf(1, " ... %8lu memories\n", + count_var_arrays+count_real_arrays); + vpi_mcd_printf(1, " %8lu logic (%lu words)\n", + count_var_arrays, count_var_array_words); + vpi_mcd_printf(1, " %8lu real (%lu words)\n", + count_real_arrays, count_real_array_words); + vpi_mcd_printf(1, " ... %8lu scopes\n", count_vpi_scopes); + } + + if (verbose_flag) { + my_getrusage(cycles+1); + print_rusage(cycles+1, cycles+0); + vpi_mcd_printf(1, "Running ...\n"); + } + + + schedule_simulate(); + + if (verbose_flag) { + my_getrusage(cycles+2); + print_rusage(cycles+2, cycles+1); + + vpi_mcd_printf(1, "Event counts:\n"); + vpi_mcd_printf(1, " %8lu time steps (pool=%lu)\n", + count_time_events, count_time_pool()); + vpi_mcd_printf(1, " %8lu thread schedule events\n", + count_thread_events); + vpi_mcd_printf(1, " %8lu assign events\n", + count_assign_events); + vpi_mcd_printf(1, " ...assign(vec4) pool=%lu\n", + count_assign4_pool()); + vpi_mcd_printf(1, " ...assign(vec8) pool=%lu\n", + count_assign8_pool()); + vpi_mcd_printf(1, " ...assign(real) pool=%lu\n", + count_assign_real_pool()); + vpi_mcd_printf(1, " ...assign(word) pool=%lu\n", + count_assign_aword_pool()); + vpi_mcd_printf(1, " ...assign(word/r) pool=%lu\n", + count_assign_arword_pool()); + vpi_mcd_printf(1, " %8lu other events (pool=%lu)\n", + count_gen_events, count_gen_pool()); + } + + final_cleanup(); + +} diff --git a/vvp/run.sh b/vvp/run.sh new file mode 100755 index 0000000000..749f480242 --- /dev/null +++ b/vvp/run.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +make +iverilog -g2012 -ohello.vvp hello.sv +g++ -I../install.d/include/iverilog -c test_client.cpp +g++ -o test_client test_client.o -L../vvp -lvvp +./test_client diff --git a/vvp/test_client.cpp b/vvp/test_client.cpp new file mode 100644 index 0000000000..d008c6b7e6 --- /dev/null +++ b/vvp/test_client.cpp @@ -0,0 +1,183 @@ +#include +#include + +void compile(); + +void hello_register(); +void giveme5_register(); +void cpp_memread_register(); + +static int hello_compiletf(char *) { + return 0; +} + + +void hello(); + +static int hello_calltf(char *) +{ + hello(); + return 0; +} + +void hello_register() { + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$hello"; + tf_data.calltf = hello_calltf; + tf_data.compiletf= hello_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = 0; + vpi_register_systf(&tf_data); +} + +static int giveme5_compiletf(char *) +{ + return 0; +} + +int giveme5(int input); + +static int giveme5_calltf(char *) +{ + vpiHandle systfref, args_iter, arg0, arg1; + struct t_vpi_value argval; + // vpi_printf("hello, world\n"); + systfref = vpi_handle(vpiSysTfCall, NULL); + args_iter = vpi_iterate(vpiArgument, systfref); + arg0 = vpi_scan(args_iter); + arg1 = vpi_scan(args_iter); + vpi_free_object(args_iter); + + argval.format = vpiIntVal; + vpi_get_value(arg0, &argval); + + int output = giveme5(argval.value.integer); + + // std::cout << argval.value.integer << std::endl; + + argval.value.integer = output; + vpi_put_value(arg1, &argval, NULL, vpiNoDelay); + + return 0; +} + +void giveme5_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + // tf_data.type = vpiSysFunc; + // tf_data.sysfunctype = vpiSysFuncSized 32 unsigned; + tf_data.tfname = "$giveme5"; + tf_data.calltf = giveme5_calltf; + tf_data.compiletf = giveme5_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = 0; + vpi_register_systf(&tf_data); +} + +void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data); + +static int cpp_memread_calltf(char *) +{ + vpiHandle systfref, args_iter, arg0, arg1, arg2, arg3; + struct t_vpi_value argval; + // vpi_printf("hello, world\n"); + systfref = vpi_handle(vpiSysTfCall, NULL); + args_iter = vpi_iterate(vpiArgument, systfref); + arg0 = vpi_scan(args_iter); + arg1 = vpi_scan(args_iter); + arg2 = vpi_scan(args_iter); + arg3 = vpi_scan(args_iter); + vpi_free_object(args_iter); + + argval.format = vpiIntVal; + vpi_get_value(arg0, &argval); + + int i = argval.value.integer; + int req, addr, out; + cpp_memread(i, &req, &addr, &out); + + // std::cout << argval.value.integer << std::endl; + + argval.value.integer = req; + vpi_put_value(arg1, &argval, NULL, vpiNoDelay); + argval.value.integer = addr; + vpi_put_value(arg2, &argval, NULL, vpiNoDelay); + argval.value.integer = out; + vpi_put_value(arg3, &argval, NULL, vpiNoDelay); + + return 0; +} + +static int cpp_memread_compiletf(char *) +{ + return 0; +} + +void cpp_memread_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + // tf_data.type = vpiSysFunc; + // tf_data.sysfunctype = vpiSysFuncSized 32 unsigned; + tf_data.tfname = "$cpp_memread"; + tf_data.calltf = cpp_memread_calltf; + tf_data.compiletf = cpp_memread_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = 0; + vpi_register_systf(&tf_data); +} + +void hello() { + vpi_printf("hello, world\n"); +} + +int giveme5(int input) { + std::cout << input << std::endl; + unsigned int output; + output = 5; + output = 4294967295; + output = -123; + return output; +} + +void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data) +{ + *p_mem_req = 0; + *p_mem_addr = 0; + *p_mem_data = 0; + switch(i) { + case 0: + *p_mem_req = 1; + *p_mem_addr = 1; + *p_mem_data = 222; + break; + case 1: + *p_mem_req = 1; + *p_mem_addr = 2; + *p_mem_data = 333; + break; + case 2: + *p_mem_req = 1; + *p_mem_addr = 3; + *p_mem_data = 444; + break; + case 3: + *p_mem_req = 1; + *p_mem_addr = 5; + *p_mem_data = 555; + break; + } +} + +int main(int argc, char *argv[]) { + hello_register(); + giveme5_register(); + cpp_memread_register(); + compile(); + return 0; +} From 632244fe2947f398956fe1d60d26f6b06ceadb21 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 19:59:12 -0400 Subject: [PATCH 02/10] write from main --- vvp/test_client.cpp | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/vvp/test_client.cpp b/vvp/test_client.cpp index d008c6b7e6..89bf4dfde8 100644 --- a/vvp/test_client.cpp +++ b/vvp/test_client.cpp @@ -145,32 +145,19 @@ int giveme5(int input) { return output; } +const int MAX_KERNEL_SIZE = 8; +int kernel_size = 8; +int kernel[MAX_KERNEL_SIZE + 1]; + void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data) { *p_mem_req = 0; *p_mem_addr = 0; *p_mem_data = 0; - switch(i) { - case 0: - *p_mem_req = 1; - *p_mem_addr = 1; - *p_mem_data = 222; - break; - case 1: - *p_mem_req = 1; - *p_mem_addr = 2; - *p_mem_data = 333; - break; - case 2: - *p_mem_req = 1; - *p_mem_addr = 3; - *p_mem_data = 444; - break; - case 3: - *p_mem_req = 1; - *p_mem_addr = 5; - *p_mem_data = 555; - break; + if(i < kernel_size) { + *p_mem_req = 1; + *p_mem_addr = i; + *p_mem_data = kernel[i]; } } @@ -178,6 +165,12 @@ int main(int argc, char *argv[]) { hello_register(); giveme5_register(); cpp_memread_register(); + + kernel[0] = 111; + kernel[1] = 321; + kernel[2] = 444; + kernel_size = 3; + compile(); return 0; } From da1a77acdf21befaa29d8118f78440683fa1d977 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 20:00:54 -0400 Subject: [PATCH 03/10] remove extraneous code --- vvp/hello.sv | 7 +--- vvp/test_client.cpp | 84 --------------------------------------------- 2 files changed, 1 insertion(+), 90 deletions(-) diff --git a/vvp/hello.sv b/vvp/hello.sv index 570217cbb2..f287f5f275 100644 --- a/vvp/hello.sv +++ b/vvp/hello.sv @@ -11,7 +11,7 @@ module main(); reg [31:0] n_cpp_in; - reg [31:0] mem [1024]; + reg [31:0] mem [16]; task tick(); #5 clk = 0; @@ -40,11 +40,6 @@ module main(); rst <= 0; tick(); - $hello; - cpp_in = 23; - $giveme5(cpp_in, cpp_out); - $display("cpp_out %0d", cpp_out); - tick(); for(int i = 0; i < 4; i++) begin $cpp_memread(i, cpp_mem_wr_req, cpp_mem_wr_addr, cpp_mem_wr_data); diff --git a/vvp/test_client.cpp b/vvp/test_client.cpp index 89bf4dfde8..bf592f85ae 100644 --- a/vvp/test_client.cpp +++ b/vvp/test_client.cpp @@ -3,81 +3,12 @@ void compile(); -void hello_register(); -void giveme5_register(); void cpp_memread_register(); static int hello_compiletf(char *) { return 0; } - -void hello(); - -static int hello_calltf(char *) -{ - hello(); - return 0; -} - -void hello_register() { - s_vpi_systf_data tf_data; - - tf_data.type = vpiSysTask; - tf_data.tfname = "$hello"; - tf_data.calltf = hello_calltf; - tf_data.compiletf= hello_compiletf; - tf_data.sizetf = 0; - tf_data.user_data = 0; - vpi_register_systf(&tf_data); -} - -static int giveme5_compiletf(char *) -{ - return 0; -} - -int giveme5(int input); - -static int giveme5_calltf(char *) -{ - vpiHandle systfref, args_iter, arg0, arg1; - struct t_vpi_value argval; - // vpi_printf("hello, world\n"); - systfref = vpi_handle(vpiSysTfCall, NULL); - args_iter = vpi_iterate(vpiArgument, systfref); - arg0 = vpi_scan(args_iter); - arg1 = vpi_scan(args_iter); - vpi_free_object(args_iter); - - argval.format = vpiIntVal; - vpi_get_value(arg0, &argval); - - int output = giveme5(argval.value.integer); - - // std::cout << argval.value.integer << std::endl; - - argval.value.integer = output; - vpi_put_value(arg1, &argval, NULL, vpiNoDelay); - - return 0; -} - -void giveme5_register() -{ - s_vpi_systf_data tf_data; - - tf_data.type = vpiSysTask; - // tf_data.type = vpiSysFunc; - // tf_data.sysfunctype = vpiSysFuncSized 32 unsigned; - tf_data.tfname = "$giveme5"; - tf_data.calltf = giveme5_calltf; - tf_data.compiletf = giveme5_compiletf; - tf_data.sizetf = 0; - tf_data.user_data = 0; - vpi_register_systf(&tf_data); -} - void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data); static int cpp_memread_calltf(char *) @@ -132,19 +63,6 @@ void cpp_memread_register() vpi_register_systf(&tf_data); } -void hello() { - vpi_printf("hello, world\n"); -} - -int giveme5(int input) { - std::cout << input << std::endl; - unsigned int output; - output = 5; - output = 4294967295; - output = -123; - return output; -} - const int MAX_KERNEL_SIZE = 8; int kernel_size = 8; int kernel[MAX_KERNEL_SIZE + 1]; @@ -162,8 +80,6 @@ void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data) } int main(int argc, char *argv[]) { - hello_register(); - giveme5_register(); cpp_memread_register(); kernel[0] = 111; From bef0e0c37d3916b3bf38cc9405572c0781cfecd2 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 21:36:10 -0400 Subject: [PATCH 04/10] remove superfluous files --- vvp/hello.sv | 59 ---------------------------------------------------- vvp/run.sh | 9 -------- 2 files changed, 68 deletions(-) delete mode 100644 vvp/hello.sv delete mode 100755 vvp/run.sh diff --git a/vvp/hello.sv b/vvp/hello.sv deleted file mode 100644 index f287f5f275..0000000000 --- a/vvp/hello.sv +++ /dev/null @@ -1,59 +0,0 @@ -module main(); - // reg int foo; - reg clk; - reg rst; - - reg [31:0] cpp_in; - reg [31:0] cpp_out; - reg [31:0] cpp_mem_wr_req; - reg [31:0] cpp_mem_wr_addr; - reg [31:0] cpp_mem_wr_data; - - reg [31:0] n_cpp_in; - - reg [31:0] mem [16]; - - task tick(); - #5 clk = 0; - #5 clk = 1; - endtask - - always @(*) begin - n_cpp_in = 0; - end - - always @(posedge clk, posedge rst) begin - if(rst) begin - cpp_in <= 0; - end else begin - cpp_in <= n_cpp_in; - end - if(cpp_mem_wr_req) begin - mem[cpp_mem_wr_addr] = cpp_mem_wr_data; - end - end - - initial begin - rst = 1; - tick(); - - rst <= 0; - tick(); - - tick(); - for(int i = 0; i < 4; i++) begin - $cpp_memread(i, cpp_mem_wr_req, cpp_mem_wr_addr, cpp_mem_wr_data); - tick(); - end - tick(); - tick(); - tick(); - tick(); - tick(); - tick(); - - for(int i = 0; i < 16; i++) begin - $display("i %0d %0d", i, mem[i]); - end - end -endmodule diff --git a/vvp/run.sh b/vvp/run.sh deleted file mode 100755 index 749f480242..0000000000 --- a/vvp/run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -ex - -make -iverilog -g2012 -ohello.vvp hello.sv -g++ -I../install.d/include/iverilog -c test_client.cpp -g++ -o test_client test_client.o -L../vvp -lvvp -./test_client From a8ba05017ab400a54760957981bcff8ba0cf2db0 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 21:36:43 -0400 Subject: [PATCH 05/10] remove more superfluous files --- vvp/test_client.cpp | 92 --------------------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 vvp/test_client.cpp diff --git a/vvp/test_client.cpp b/vvp/test_client.cpp deleted file mode 100644 index bf592f85ae..0000000000 --- a/vvp/test_client.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include - -void compile(); - -void cpp_memread_register(); - -static int hello_compiletf(char *) { - return 0; -} - -void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data); - -static int cpp_memread_calltf(char *) -{ - vpiHandle systfref, args_iter, arg0, arg1, arg2, arg3; - struct t_vpi_value argval; - // vpi_printf("hello, world\n"); - systfref = vpi_handle(vpiSysTfCall, NULL); - args_iter = vpi_iterate(vpiArgument, systfref); - arg0 = vpi_scan(args_iter); - arg1 = vpi_scan(args_iter); - arg2 = vpi_scan(args_iter); - arg3 = vpi_scan(args_iter); - vpi_free_object(args_iter); - - argval.format = vpiIntVal; - vpi_get_value(arg0, &argval); - - int i = argval.value.integer; - int req, addr, out; - cpp_memread(i, &req, &addr, &out); - - // std::cout << argval.value.integer << std::endl; - - argval.value.integer = req; - vpi_put_value(arg1, &argval, NULL, vpiNoDelay); - argval.value.integer = addr; - vpi_put_value(arg2, &argval, NULL, vpiNoDelay); - argval.value.integer = out; - vpi_put_value(arg3, &argval, NULL, vpiNoDelay); - - return 0; -} - -static int cpp_memread_compiletf(char *) -{ - return 0; -} - -void cpp_memread_register() -{ - s_vpi_systf_data tf_data; - - tf_data.type = vpiSysTask; - // tf_data.type = vpiSysFunc; - // tf_data.sysfunctype = vpiSysFuncSized 32 unsigned; - tf_data.tfname = "$cpp_memread"; - tf_data.calltf = cpp_memread_calltf; - tf_data.compiletf = cpp_memread_compiletf; - tf_data.sizetf = 0; - tf_data.user_data = 0; - vpi_register_systf(&tf_data); -} - -const int MAX_KERNEL_SIZE = 8; -int kernel_size = 8; -int kernel[MAX_KERNEL_SIZE + 1]; - -void cpp_memread(int i, int *p_mem_req, int *p_mem_addr, int *p_mem_data) -{ - *p_mem_req = 0; - *p_mem_addr = 0; - *p_mem_data = 0; - if(i < kernel_size) { - *p_mem_req = 1; - *p_mem_addr = i; - *p_mem_data = kernel[i]; - } -} - -int main(int argc, char *argv[]) { - cpp_memread_register(); - - kernel[0] = 111; - kernel[1] = 321; - kernel[2] = 444; - kernel_size = 3; - - compile(); - return 0; -} From f2cf6f15f3c53e89438c2213348b8e4486d7d6da Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 21:44:00 -0400 Subject: [PATCH 06/10] tidy up maekfile and lib_entry.cc a bit --- vvp/Makefile.in | 10 +++----- vvp/lib_entry.cc | 66 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/vvp/Makefile.in b/vvp/Makefile.in index a3d1ebe13a..bc8576a416 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -37,6 +37,7 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ BUILDCC = @CC_FOR_BUILD@ BUILDEXT = @BUILD_EXEEXT@ +SOEXT = .so CXX = @CXX@ DLLTOOL = @DLLTOOL@ INSTALL = @INSTALL@ @@ -99,7 +100,7 @@ endif clean: rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc - rm -rf dep vvp@EXEEXT@ parse.output vvp.man vvp.ps vvp.pdf vvp.exp + rm -rf dep vvp@EXEEXT@ vvp@SOEXT@ parse.output vvp.man vvp.ps vvp.pdf vvp.exp distclean: clean rm -f Makefile config.log @@ -131,16 +132,13 @@ vvp@EXEEXT@: $O $(srcdir)/vvp.def $(DLLTOOL) --dllname vvp$(suffix)@EXEEXT@ --def $(srcdir)/vvp.def \ --output-exp vvp.exp rm -f vvp$(suffix)@EXEEXT@ - echo vvp exe ext vvp$(suffix)@EXEEXT@ $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ vvp.exp $(LDFLAGS) $O $(dllib) $(LIBS) else vvp@EXEEXT@: $O - echo vvp exe ext vvp@EXEEXT@ CXX $(CXX) $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ $O $(LIBS) $(dllib) -vvp.so: $O - echo vvp exe ext vvp@EXEEXT@ - $(CXX) -shared $(LDFLAGS) -o libvvp.so $O $(LIBS) $(dllib) +vvp@SOEXT@: $O + $(CXX) -shared $(LDFLAGS) -o libvvp@SOEXT@ $O $(LIBS) $(dllib) endif %.o: %.cc config.h diff --git a/vvp/lib_entry.cc b/vvp/lib_entry.cc index 02c804b0f6..2b56fe26f4 100644 --- a/vvp/lib_entry.cc +++ b/vvp/lib_entry.cc @@ -18,9 +18,61 @@ #endif #if defined(HAVE_SYS_RESOURCE_H) -# include -# include -#endif // defined(HAVE_SYS_RESOURCE_H) +static void my_getrusage(struct rusage *a) +{ + getrusage(RUSAGE_SELF, a); + +#if defined(LINUX) + { + FILE *statm; + unsigned siz, rss, shd; + long page_size = sysconf(_SC_PAGESIZE); + if (page_size == -1) + page_size = 0; + statm = fopen("/proc/self/statm", "r"); + if (!statm) + { + perror("/proc/self/statm"); + return; + } + /* Given that these are in pages we'll limit the value to + * what will fit in a 32 bit integer to prevent undefined + * behavior in fscanf(). */ + if (3 == fscanf(statm, "%9u %9u %9u", &siz, &rss, &shd)) + { + a->ru_maxrss = page_size * siz; + a->ru_idrss = page_size * rss; + a->ru_ixrss = page_size * shd; + } + fclose(statm); + } +#endif +} + +static void print_rusage(struct rusage *a, struct rusage *b) +{ + double delta = a->ru_utime.tv_sec + a->ru_utime.tv_usec / 1E6 + a->ru_stime.tv_sec + a->ru_stime.tv_usec / 1E6 - b->ru_utime.tv_sec - b->ru_utime.tv_usec / 1E6 - b->ru_stime.tv_sec - b->ru_stime.tv_usec / 1E6; + + vpi_mcd_printf(1, + " ... %G seconds," + " %.1f/%.1f/%.1f KBytes size/rss/shared\n", + delta, + a->ru_maxrss / 1024.0, + (a->ru_idrss + a->ru_isrss) / 1024.0, + a->ru_ixrss / 1024.0); +} + +#else // ! defined(HAVE_SYS_RESOURCE_H) + +// Provide dummies +struct rusage +{ + int x; +}; +inline static void my_getrusage(struct rusage *) {} +inline static void print_rusage(struct rusage *, struct rusage *){}; + +#endif // ! defined(HAVE_SYS_RESOURCE_H) #if defined(HAVE_GETOPT_H) # include @@ -143,19 +195,13 @@ extern const char*module_tab[64]; extern void vpip_mcd_init(FILE *log); extern void vvp_vpi_init(void); -void compile() { - // int opt; - // unsigned flag_errors = 0; - const char*design_path = 0; +void simulate(const char *const design_path) { struct rusage cycles[3]; - // const char *logfile_name = 0x0; FILE *logfile = 0x0; extern void vpi_set_vlog_info(int, char**); extern bool stop_is_finish; extern int stop_is_finish_exit_code; - design_path = "hello.vvp"; - vpip_add_env_and_default_module_paths(); vpip_mcd_init(logfile); From 18c82b43edf5d18069c5a6657f0631106b3ebfae Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 21:48:02 -0400 Subject: [PATCH 07/10] mamke sure stuff builds --- vvp/Makefile.in | 11 +++++++---- vvp/lib_entry.cc | 49 ------------------------------------------------ 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/vvp/Makefile.in b/vvp/Makefile.in index bc8576a416..913dcebd35 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -37,7 +37,6 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ BUILDCC = @CC_FOR_BUILD@ BUILDEXT = @BUILD_EXEEXT@ -SOEXT = .so CXX = @CXX@ DLLTOOL = @DLLTOOL@ INSTALL = @INSTALL@ @@ -81,7 +80,11 @@ O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o c vvp_object.o vvp_cobject.o vvp_darray.o event.o logic.o delay.o \ words.o island_tran.o $(VPI) -all: dep vvp@EXEEXT@ vvp.man vvp.so +ifeq (@WIN32@,yes) +all: dep vvp@EXEEXT@ vvp.man +else +all: dep vvp@EXEEXT@ vvp.man libvvp.so +endif check: all ifeq (@WIN32@,yes) @@ -137,8 +140,8 @@ else vvp@EXEEXT@: $O $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ $O $(LIBS) $(dllib) -vvp@SOEXT@: $O - $(CXX) -shared $(LDFLAGS) -o libvvp@SOEXT@ $O $(LIBS) $(dllib) +libvvp.so: $O + $(CXX) -shared $(LDFLAGS) -o libvvp.so $O $(LIBS) $(dllib) endif %.o: %.cc config.h diff --git a/vvp/lib_entry.cc b/vvp/lib_entry.cc index 2b56fe26f4..43e0d2faec 100644 --- a/vvp/lib_entry.cc +++ b/vvp/lib_entry.cc @@ -92,34 +92,6 @@ extern "C" int optind; extern "C" const char*optarg; #endif -static void my_getrusage(struct rusage *a) -{ - getrusage(RUSAGE_SELF, a); - -# if defined(LINUX) - { - FILE *statm; - unsigned siz, rss, shd; - long page_size = sysconf(_SC_PAGESIZE); - if (page_size==-1) page_size=0; - statm = fopen("/proc/self/statm", "r"); - if (!statm) { - perror("/proc/self/statm"); - return; - } - /* Given that these are in pages we'll limit the value to - * what will fit in a 32 bit integer to prevent undefined - * behavior in fscanf(). */ - if (3 == fscanf(statm, "%9u %9u %9u", &siz, &rss, &shd)) { - a->ru_maxrss = page_size * siz; - a->ru_idrss = page_size * rss; - a->ru_ixrss = page_size * shd; - } - fclose(statm); - } -# endif -} - static void final_cleanup() { vvp_object::cleanup(); @@ -166,27 +138,6 @@ static void final_cleanup() #endif } -static void print_rusage(struct rusage *a, struct rusage *b) -{ - double delta = a->ru_utime.tv_sec - + a->ru_utime.tv_usec/1E6 - + a->ru_stime.tv_sec - + a->ru_stime.tv_usec/1E6 - - b->ru_utime.tv_sec - - b->ru_utime.tv_usec/1E6 - - b->ru_stime.tv_sec - - b->ru_stime.tv_usec/1E6 - ; - - vpi_mcd_printf(1, - " ... %G seconds," - " %.1f/%.1f/%.1f KBytes size/rss/shared\n", - delta, - a->ru_maxrss/1024.0, - (a->ru_idrss+a->ru_isrss)/1024.0, - a->ru_ixrss/1024.0 ); -} - static bool have_ivl_version = false; extern unsigned module_cnt; From 75154422a74eb02dbff4795b5ca64ddfd1ef318f Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Fri, 1 Apr 2022 22:09:18 -0400 Subject: [PATCH 08/10] install libvvp.so --- vvp/Makefile.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vvp/Makefile.in b/vvp/Makefile.in index 913dcebd35..bfcef1c787 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -212,8 +212,14 @@ installman: vvp.man installdirs installpdf: vvp.pdf installdirs $(INSTALL_DATA) vvp.pdf "$(DESTDIR)$(prefix)/vvp$(suffix).pdf" +ifeq (@WIN32@,yes) installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vvp@EXEEXT@ "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@" +else +installfiles: $(F) | installdirs + $(INSTALL_PROGRAM) ./vvp@EXEEXT@ "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@" + $(INSTALL_PROGRAM) ./libvvp.so "$(DESTDIR)$(libdir)/libvvp.so" +endif installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(INSTALL_DOCDIR)" From c21f7f67a734e6febcd7fdbfca54630bf0b2196d Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Sat, 2 Apr 2022 06:14:44 -0400 Subject: [PATCH 09/10] fix linux build --- vvp/lib_entry.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/vvp/lib_entry.cc b/vvp/lib_entry.cc index 43e0d2faec..af6fd30ba5 100644 --- a/vvp/lib_entry.cc +++ b/vvp/lib_entry.cc @@ -17,6 +17,21 @@ # include #endif +#if defined(HAVE_SYS_RESOURCE_H) +#include +#include +#endif // defined(HAVE_SYS_RESOURCE_H) + +#if defined(HAVE_GETOPT_H) +#include +#endif + +#if defined(__MINGW32__) +#include +#endif + +using namespace std; + #if defined(HAVE_SYS_RESOURCE_H) static void my_getrusage(struct rusage *a) { @@ -74,16 +89,6 @@ inline static void print_rusage(struct rusage *, struct rusage *){}; #endif // ! defined(HAVE_SYS_RESOURCE_H) -#if defined(HAVE_GETOPT_H) -# include -#endif - -#if defined(__MINGW32__) -# include -#endif - -using namespace std; - // ofstream debug_file; #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H) From 51dc732dbbc43bc67df0c3b996d370a06df4cf55 Mon Sep 17 00:00:00 2001 From: Hugh Perkins Date: Sat, 2 Apr 2022 06:35:01 -0400 Subject: [PATCH 10/10] Hackily add -fPIC to flags directly --- vvp/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vvp/Makefile.in b/vvp/Makefile.in index bfcef1c787..8d46c97a1a 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -54,8 +54,8 @@ else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif -CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const -CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ +CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const -fPIC +CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ -fPIC CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @rdynamic@ @LDFLAGS@ LIBS = @LIBS@ @EXTRALIBS@