Fix the debugger to finish correctly.
[iverilog.git] / vvp / main.cc
blob5bf72a5932b5fcba01e40623cfec4a913151ea3f
1 /*
2 * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: main.cc,v 1.44 2007/02/16 23:30:14 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "parse_misc.h"
25 # include "compile.h"
26 # include "schedule.h"
27 # include "vpi_priv.h"
28 # include "statistics.h"
29 # include <stdio.h>
30 # include <stdlib.h>
31 # include <string.h>
32 # include <unistd.h>
34 #if defined(HAVE_SYS_RESOURCE_H)
35 # include <sys/time.h>
36 # include <sys/resource.h>
37 # if defined(LINUX)
38 # include <asm/page.h>
39 # endif
40 #endif // defined(HAVE_SYS_RESOURCE_H)
42 #if defined(HAVE_GETOPT_H)
43 # include <getopt.h>
44 #endif
46 #if defined(__MINGW32__)
47 # include <windows.h>
48 #endif
50 ofstream debug_file;
52 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
53 extern "C" int getopt(int argc, char*argv[], const char*fmt);
54 extern "C" int optind;
55 extern "C" const char*optarg;
56 #endif
58 #if !defined(HAVE_LROUND)
60 * If the system doesn't provide the lround function, then we provide
61 * it ourselves here. It is simply the nearest integer, rounded away
62 * from zero.
64 # include <math.h>
65 extern "C" long int lround(double x)
67 if (x >= 0.0)
68 return (long)floor(x+0.5);
69 else
70 return (long)ceil(x-0.5);
72 #endif
74 bool verbose_flag = false;
76 static char log_buffer[4096];
78 #if defined(HAVE_SYS_RESOURCE_H)
79 static void my_getrusage(struct rusage *a)
81 getrusage(RUSAGE_SELF, a);
83 # if defined(LINUX)
85 FILE *statm;
86 unsigned siz, rss, shd;
87 long page_size = sysconf(_SC_PAGESIZE);
88 if (page_size==-1) page_size=0;
89 statm = fopen("/proc/self/statm", "r");
90 if (!statm) {
91 perror("/proc/self/statm");
92 return;
94 if (3<=fscanf(statm, "%u%u%u", &siz, &rss, &shd)) {
95 a->ru_maxrss = page_size * siz;
96 a->ru_idrss = page_size * rss;
97 a->ru_ixrss = page_size * shd;
99 fclose(statm);
101 # endif
104 static void print_rusage(struct rusage *a, struct rusage *b)
106 double delta = a->ru_utime.tv_sec
107 + a->ru_utime.tv_usec/1E6
108 + a->ru_stime.tv_sec
109 + a->ru_stime.tv_usec/1E6
110 - b->ru_utime.tv_sec
111 - b->ru_utime.tv_usec/1E6
112 - b->ru_stime.tv_sec
113 - b->ru_stime.tv_usec/1E6
116 vpi_mcd_printf(1,
117 " ... %G seconds,"
118 " %.1f/%.1f/%.1f KBytes size/rss/shared\n",
119 delta,
120 a->ru_maxrss/1024.0,
121 (a->ru_idrss+a->ru_isrss)/1024.0,
122 a->ru_ixrss/1024.0 );
125 #else // ! defined(HAVE_SYS_RESOURCE_H)
127 // Provide dummies
128 struct rusage { int x; };
129 inline static void my_getrusage(struct rusage *) { }
130 inline static void print_rusage(struct rusage *, struct rusage *){};
132 #endif // ! defined(HAVE_SYS_RESOURCE_H)
135 unsigned module_cnt = 0;
136 const char*module_tab[64];
138 extern void vpi_mcd_init(FILE *log);
139 extern void vvp_vpi_init(void);
141 int main(int argc, char*argv[])
143 int opt;
144 unsigned flag_errors = 0;
145 const char*design_path = 0;
146 struct rusage cycles[3];
147 const char *logfile_name = 0x0;
148 FILE *logfile = 0x0;
149 extern void vpi_set_vlog_info(int, char**);
151 #ifdef __MINGW32__
152 /* In the Windows world, we get the first module path
153 component relative the location where the binary lives. */
154 { char path[4096], *s;
155 GetModuleFileName(NULL,path,1024);
156 /* Get to the end. Search back twice for backslashes */
157 s = path + strlen(path);
158 while (*s != '\\') s--; s--;
159 while (*s != '\\') s--;
160 strcpy(s,"\\lib\\ivl");
161 vpip_module_path[0] = strdup(path);
163 #endif
165 while ((opt = getopt(argc, argv, "+hl:M:m:sv")) != EOF) switch (opt) {
166 case 'h':
167 fprintf(stderr,
168 "Usage: vvp [options] input-file [+plusargs...]\n"
169 "Options:\n"
170 " -h Print this help message.\n"
171 " -l file Logfile, '-' for <stderr>\n"
172 " -M path VPI module directory\n"
173 " -M - Clear VPI module path\n"
174 " -m module Load vpi module.\n"
175 " -s $stop right away.\n"
176 " -v Verbose progress messages.\n" );
177 exit(0);
178 case 'l':
179 logfile_name = optarg;
180 break;
181 case 'M':
182 if (strcmp(optarg,"-") == 0) {
183 vpip_module_path_cnt = 0;
184 vpip_module_path[0] = 0;
185 } else {
186 vpip_module_path[vpip_module_path_cnt++] = optarg;
188 break;
189 case 'm':
190 module_tab[module_cnt++] = optarg;
191 break;
192 case 's':
193 schedule_stop(0);
194 break;
195 case 'v':
196 verbose_flag = true;
197 break;
198 default:
199 flag_errors += 1;
202 if (flag_errors)
203 return flag_errors;
205 if (optind == argc) {
206 fprintf(stderr, "%s: no input file.\n", argv[0]);
207 return -1;
210 /* If the VVP_DEBUG variable is set, then it contains the path
211 to the vvp debug file. Open it for output. */
213 if (char*path = getenv("VVP_DEBUG")) {
214 debug_file.open(path, ios_base::out);
217 design_path = argv[optind];
219 /* This is needed to get the MCD I/O routines ready for
220 anything. It is done early because it is plausible that the
221 compile might affect it, and it is cheap to do. */
223 if (logfile_name) {
224 if (!strcmp(logfile_name, "-"))
225 logfile = stderr;
226 else {
227 logfile = fopen(logfile_name, "w");
228 if (!logfile) {
229 perror(logfile_name);
230 exit(1);
232 setvbuf(logfile, log_buffer, _IOLBF, sizeof(log_buffer));
236 vpi_mcd_init(logfile);
238 if (verbose_flag) {
239 my_getrusage(cycles+0);
240 vpi_mcd_printf(1, "Compiling VVP ...\n");
243 vvp_vpi_init();
245 /* Make the extended arguments available to the simulation. */
246 vpi_set_vlog_info(argc-optind, argv+optind);
248 compile_init();
250 for (unsigned idx = 0 ; idx < module_cnt ; idx += 1)
251 vpip_load_module(module_tab[idx]);
253 if (int rc = compile_design(design_path))
254 return rc;
256 if (verbose_flag) {
257 vpi_mcd_printf(1, "Compile cleanup...\n");
260 compile_cleanup();
262 if (compile_errors > 0) {
263 vpi_mcd_printf(1, "%s: Program not runnable, %u errors.\n",
264 design_path, compile_errors);
265 return compile_errors;
268 if (verbose_flag) {
269 vpi_mcd_printf(1, " ... %8lu functors\n", count_functors);
270 vpi_mcd_printf(1, " %8lu table\n", count_functors_table);
271 vpi_mcd_printf(1, " %8lu bufif\n", count_functors_bufif);
272 vpi_mcd_printf(1, " %8lu resolv\n",count_functors_resolv);
273 vpi_mcd_printf(1, " %8lu variable\n", count_functors_var);
274 vpi_mcd_printf(1, " ... %8lu opcodes (%lu bytes)\n",
275 count_opcodes, (unsigned long)size_opcodes);
276 vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets);
277 vpi_mcd_printf(1, " ... %8lu memories\n", count_vpi_memories);
278 vpi_mcd_printf(1, " ... %8lu scopes\n", count_vpi_scopes);
281 if (verbose_flag) {
282 my_getrusage(cycles+1);
283 print_rusage(cycles+1, cycles+0);
284 vpi_mcd_printf(1, "Running ...\n");
288 schedule_simulate();
290 if (verbose_flag) {
291 my_getrusage(cycles+2);
292 print_rusage(cycles+2, cycles+1);
294 vpi_mcd_printf(1, "Event counts: (event pool = %lu)\n",
295 count_event_pool);
296 vpi_mcd_printf(1, " %8lu thread schedule events\n",
297 count_thread_events);
298 vpi_mcd_printf(1, " %8lu propagation events\n",
299 count_prop_events);
300 vpi_mcd_printf(1, " %8lu assign events\n",
301 count_assign_events);
302 vpi_mcd_printf(1, " %8lu other events\n",
303 count_gen_events);
306 return 0;
310 * $Log: main.cc,v $
311 * Revision 1.44 2007/02/16 23:30:14 steve
312 * Get page size from sysconf.
314 * Revision 1.43 2006/04/28 15:44:37 steve
315 * Include math.h with lround implementation.
317 * Revision 1.42 2006/04/28 15:40:30 steve
318 * lround takes double, not float.
320 * Revision 1.41 2006/04/27 05:04:59 steve
321 * Detect missing lround function.
323 * Revision 1.40 2005/01/29 06:28:19 steve
324 * Add the -s flag to start up interactive.
326 * Revision 1.39 2004/10/04 01:10:59 steve
327 * Clean up spurious trailing white space.
329 * Revision 1.38 2003/06/25 04:04:19 steve
330 * Fix mingw portability problems.
332 * Revision 1.37 2003/06/13 19:51:08 steve
333 * Include verbose messages in log output.
335 * Revision 1.36 2003/05/15 16:51:09 steve
336 * Arrange for mcd id=00_00_00_01 to go to stdout
337 * as well as a user specified log file, set log
338 * file to buffer lines.
340 * Add vpi_flush function, and clear up some cunfused
341 * return codes from other vpi functions.
343 * Adjust $display and vcd/lxt messages to use the
344 * standard output/log file.
346 * Revision 1.35 2003/03/13 04:36:57 steve
347 * Remove the obsolete functor delete functions.
349 * Revision 1.34 2003/02/07 02:45:05 steve
350 * Mke getopt ignore options after the file name.
352 * Revision 1.33 2003/01/18 23:55:35 steve
353 * Add a means to clear the module search path.
355 * Revision 1.32 2003/01/06 23:57:26 steve
356 * Schedule wait lists of threads as a single event,
357 * to save on events. Also, improve efficiency of
358 * event_s allocation. Add some event statistics to
359 * get an idea where performance is really going.
361 * Revision 1.31 2002/09/18 03:34:07 steve
362 * printf size warning.
364 * Revision 1.30 2002/08/12 01:35:08 steve
365 * conditional ident string using autoconfig.
367 * Revision 1.29 2002/07/15 00:21:42 steve
368 * Fix initialization of symbol table string heap.
370 * Revision 1.28 2002/07/05 20:08:44 steve
371 * Count different types of functors.
373 * Revision 1.27 2002/07/05 17:14:15 steve
374 * Names of vpi objects allocated as vpip_strings.
376 * Revision 1.26 2002/07/05 03:47:06 steve
377 * Track opcode memory space.
379 * Revision 1.25 2002/07/05 02:50:58 steve
380 * Remove the vpi object symbol table after compile.
382 * Revision 1.24 2002/04/12 02:44:02 steve
383 * Formally define extended arguments to vvp.
385 * Revision 1.23 2002/03/01 05:43:14 steve
386 * Add cleanup to verbose messages.
388 * Revision 1.22 2002/01/09 03:15:23 steve
389 * Add vpi_get_vlog_info support.
391 * Revision 1.21 2001/10/20 01:03:42 steve
392 * Print memory usage information if requested (Stephan Boettcher)