iverilog/vvp/main.cc

350 lines
9.8 KiB
C++
Raw Normal View History

2001-03-11 01:29:38 +01:00
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.cc,v 1.36 2003/05/15 16:51:09 steve Exp $"
2001-03-11 01:29:38 +01:00
#endif
# include "config.h"
# include "parse_misc.h"
# include "compile.h"
# include "schedule.h"
# include "vpi_priv.h"
# include "statistics.h"
2001-03-11 01:29:38 +01:00
# include <stdio.h>
2001-06-23 20:26:26 +02:00
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
#if defined(HAVE_SYS_RESOURCE_H)
# include <sys/time.h>
# include <sys/resource.h>
# if defined(LINUX)
# include <asm/page.h>
# endif
#endif // defined(HAVE_SYS_RESOURCE_H)
#if defined(HAVE_GETOPT_H)
2001-03-11 01:29:38 +01:00
# include <getopt.h>
#endif
2001-03-11 01:29:38 +01:00
#if defined(__MINGW32__)
# include <windows.h>
#endif
#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
bool verbose_flag = false;
#if 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;
statm = fopen("/proc/self/statm", "r");
if (!statm) {
perror("/proc/self/statm");
return;
}
if (3<=fscanf(statm, "%u%u%u", &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(FILE *f, 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
;
fprintf(f,
" ... %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(FILE *, struct rusage *, struct rusage *){};
#endif // ! defined(HAVE_SYS_RESOURCE_H)
2001-03-11 01:29:38 +01:00
unsigned module_cnt = 0;
const char*module_tab[64];
extern void vpi_mcd_init(FILE *log);
extern void vvp_vpi_init(void);
2001-03-11 01:29:38 +01:00
int main(int argc, char*argv[])
{
int opt;
unsigned flag_errors = 0;
const char*design_path = 0;
struct rusage cycles[3];
const char *logfile_name = 0x0;
FILE *logfile = 0x0;
2002-01-09 04:15:23 +01:00
extern void vpi_set_vlog_info(int, char**);
2001-03-11 01:29:38 +01:00
#ifdef __MINGW32__
/* In the Windows world, we get the first module path
component relative the location where the binary lives. */
{ char path[4096], *s;
GetModuleFileName(NULL,path,1024);
/* Get to the end. Search back twice for backslashes */
s = path + strlen(path);
while (*s != '\\') s--; s--;
while (*s != '\\') s--;
strcpy(s,"\\lib\\ivl");
vpip_module_path[0] = strdup(path);
}
#endif
while ((opt = getopt(argc, argv, "+dhl:M:m:v")) != EOF) switch (opt) {
case 'h':
fprintf(stderr,
"Usage: vvp [options] input-file [+plusargs...]\n"
"Options:\n"
" -h Print this help message.\n"
" -l file Logfile, '-' for <stderr>\n"
" -M path VPI module directory\n"
" -M - Clear VPI module path\n"
" -m module Load vpi module.\n"
" -v Verbose progress messages.\n" );
exit(0);
case 'l':
logfile_name = optarg;
break;
case 'M':
if (strcmp(optarg,"-") == 0) {
vpip_module_path_cnt = 0;
vpip_module_path[0] = 0;
} else {
vpip_module_path[vpip_module_path_cnt++] = optarg;
}
break;
case 'm':
module_tab[module_cnt++] = optarg;
break;
case 'v':
verbose_flag = true;
break;
2001-03-11 01:29:38 +01:00
default:
flag_errors += 1;
}
if (flag_errors)
return flag_errors;
if (optind == argc) {
fprintf(stderr, "%s: no input file.\n", argv[0]);
return -1;
}
design_path = argv[optind];
/* This is needed to get the MCD I/O routines ready for
anything. It is done early because it is plausible that the
compile might affect it, and it is cheap to do. */
if (logfile_name) {
if (!strcmp(logfile_name, "-"))
logfile = stderr;
else {
logfile = fopen(logfile_name, "w");
if (!logfile) {
perror(logfile_name);
exit(1);
}
setlinebuf(logfile);
}
}
if (verbose_flag) {
my_getrusage(cycles+0);
fprintf(stderr, "Compiling VVP ...\n");
if (logfile && logfile != stderr)
fprintf(logfile, "Compiling VVP ...\n");
}
vpi_mcd_init(logfile);
2002-01-09 04:15:23 +01:00
vvp_vpi_init();
/* Make the extended arguments available to the simulation. */
vpi_set_vlog_info(argc-optind, argv+optind);
2002-01-09 04:15:23 +01:00
2001-03-11 01:29:38 +01:00
compile_init();
2001-03-23 03:40:22 +01:00
for (unsigned idx = 0 ; idx < module_cnt ; idx += 1)
vpip_load_module(module_tab[idx]);
if (int rc = compile_design(design_path))
return rc;
2001-03-11 01:29:38 +01:00
if (verbose_flag) {
2002-03-01 06:43:14 +01:00
fprintf(stderr, "Compile cleanup...\n");
}
2002-03-01 06:43:14 +01:00
compile_cleanup();
if (compile_errors > 0) {
fprintf(stderr, "%s: Program not runnable, %u errors.\n",
design_path, compile_errors);
if (logfile && logfile != stderr)
fprintf(logfile, "%s: Program not runnable, %u errors.\n",
design_path, compile_errors);
return compile_errors;
}
if (verbose_flag) {
fprintf(stderr, " ... %8lu functors\n", count_functors);
2002-07-05 22:08:44 +02:00
fprintf(stderr, " %8lu table\n", count_functors_table);
fprintf(stderr, " %8lu bufif\n", count_functors_bufif);
fprintf(stderr, " %8lu resolv\n", count_functors_resolv);
fprintf(stderr, " %8lu variable\n", count_functors_var);
2002-07-05 05:46:43 +02:00
fprintf(stderr, " ... %8lu opcodes (%lu bytes)\n",
2002-09-18 05:34:07 +02:00
count_opcodes, (unsigned long)size_opcodes);
fprintf(stderr, " ... %8lu nets\n", count_vpi_nets);
fprintf(stderr, " ... %8lu memories\n", count_vpi_memories);
fprintf(stderr, " ... %8lu scopes\n", count_vpi_scopes);
}
2002-03-01 06:43:14 +01:00
if (verbose_flag) {
my_getrusage(cycles+1);
print_rusage(stderr, cycles+1, cycles+0);
fprintf(stderr, "Running ...\n");
if (logfile && logfile != stderr) {
print_rusage(logfile, cycles+1, cycles+0);
fprintf(logfile, "Running ...\n");
}
}
2001-03-11 01:29:38 +01:00
schedule_simulate();
if (verbose_flag) {
my_getrusage(cycles+2);
print_rusage(stderr, cycles+2, cycles+1);
if (logfile && logfile != stderr)
print_rusage(logfile, cycles+2, cycles+1);
fprintf(stderr, "Event counts: (event pool = %lu)\n",
count_event_pool);
fprintf(stderr, " %8lu thread schedule events\n",
count_thread_events);
fprintf(stderr, " %8lu propagation events\n",
count_prop_events);
fprintf(stderr, " %8lu assign events\n",
count_assign_events);
fprintf(stderr, " %8lu other events\n",
count_gen_events);
}
2001-03-11 01:29:38 +01:00
return 0;
}
/*
* $Log: main.cc,v $
* Revision 1.36 2003/05/15 16:51:09 steve
* Arrange for mcd id=00_00_00_01 to go to stdout
* as well as a user specified log file, set log
* file to buffer lines.
*
* Add vpi_flush function, and clear up some cunfused
* return codes from other vpi functions.
*
* Adjust $display and vcd/lxt messages to use the
* standard output/log file.
*
* Revision 1.35 2003/03/13 04:36:57 steve
* Remove the obsolete functor delete functions.
*
* Revision 1.34 2003/02/07 02:45:05 steve
* Mke getopt ignore options after the file name.
*
* Revision 1.33 2003/01/18 23:55:35 steve
* Add a means to clear the module search path.
*
* Revision 1.32 2003/01/06 23:57:26 steve
* Schedule wait lists of threads as a single event,
* to save on events. Also, improve efficiency of
* event_s allocation. Add some event statistics to
* get an idea where performance is really going.
*
2002-09-18 05:34:07 +02:00
* Revision 1.31 2002/09/18 03:34:07 steve
* printf size warning.
*
* Revision 1.30 2002/08/12 01:35:08 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2002/07/15 00:21:42 steve
* Fix initialization of symbol table string heap.
*
2002-07-05 22:08:44 +02:00
* Revision 1.28 2002/07/05 20:08:44 steve
* Count different types of functors.
*
* Revision 1.27 2002/07/05 17:14:15 steve
* Names of vpi objects allocated as vpip_strings.
*
2002-07-05 05:46:43 +02:00
* Revision 1.26 2002/07/05 03:47:06 steve
* Track opcode memory space.
*
* Revision 1.25 2002/07/05 02:50:58 steve
* Remove the vpi object symbol table after compile.
*
* Revision 1.24 2002/04/12 02:44:02 steve
* Formally define extended arguments to vvp.
*
2002-03-01 06:43:14 +01:00
* Revision 1.23 2002/03/01 05:43:14 steve
* Add cleanup to verbose messages.
*
2002-01-09 04:15:23 +01:00
* Revision 1.22 2002/01/09 03:15:23 steve
* Add vpi_get_vlog_info support.
*
* Revision 1.21 2001/10/20 01:03:42 steve
* Print memory usage information if requested (Stephan Boettcher)
2001-03-11 01:29:38 +01:00
*/