From 4f35865a6c77a898c3c006ca6b8aa364bc942a22 Mon Sep 17 00:00:00 2001 From: markhummel Date: Tue, 10 Jun 2008 17:42:41 +0000 Subject: [PATCH] initial import --- src/file.cc | 151 ++++++++++++++++ src/file.h | 59 +++++++ src/veriwellinterface.cc | 230 +++++++++++++++++++++++++ src/veriwellinterface.h | 361 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 801 insertions(+) create mode 100644 src/file.cc create mode 100644 src/file.h create mode 100644 src/veriwellinterface.cc create mode 100644 src/veriwellinterface.h diff --git a/src/file.cc b/src/file.cc new file mode 100644 index 0000000..4ba2786 --- /dev/null +++ b/src/file.cc @@ -0,0 +1,151 @@ +/***************************************************************************** + * Copyright 1994-2008, Elliot Mednick and Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it 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. + * + * Veriwell 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 Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ + +/* file.cc - file abstraction */ + +#include +#include +#include +#include +#include "file.h" +#include "vtypes.h" + + +namespace veriwell { +File* File::stdin_ = new File(stdin); + +File::File(FILE* f) : + f(f), + isBuffer(0), + buffer(0), + len(0), + offset(0), + own(0) +{ +} + +File::File(char *buffer, int len, int own) : + f(0), + isBuffer(1), + buffer(buffer), + len(len), + offset(0), + own(own) +{ +} + +File *File::fopen(const char *name, char *mode) +{ + FILE* fin = ::fopen(name, mode); + if( !fin ) { + return NULL; + } + return new File(fin); +} + +File* File::Stdin() +{ + return stdin_; +} + +void File::fclose() +{ + if (!isBuffer) { + ::fclose(f); + } else if (own) { + free(buffer); + } + delete this; +} + +int File::isatty() +{ + return !isBuffer && ::isatty(fileno(f)); +} + +File* File::fopenbuf(char *buffer, int len) +{ + return new File(buffer, len); +} + +int File::fgetc() +{ + int result = EOF; + if (isBuffer) { + if (offset < len) { + result = buffer[offset++]; + } + } else { + result = getc(f); + } + return result; +} + +int File::fscanf(char *format, ...) +{ + int result; + va_list args; + va_start(args, format); + if (isBuffer) { + /* fscanf not support on in memory buffers */ + ASSERT(FALSE);; + result = 0; + } else { + result = vfscanf(f, format, args); + } + va_end(args); + return result; +} +int File::fungetc(int c) { + if (isBuffer) { + if (offset != 0 && c != EOF) { + buffer[--offset] = c; + return c; + } else { + return EOF; + } + } else { + return ungetc(c, f); + } +} +char *File::fgets(char *s, int size) { + if (isBuffer) { + int i; + for (i = 0; i < size - 1; ++i) { + s[i] = fgetc(); + if (s[i] == EOF) { + if (i == 0) { + return NULL; + } else { + break; + } + } else if (s[i] == '\n') { + i++; + break; + } + } + s[i] = 0; + return s; + } else { + return::fgets(s, size, f); + } +} + +} + diff --git a/src/file.h b/src/file.h new file mode 100644 index 0000000..a4038b2 --- /dev/null +++ b/src/file.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * Copyright 1994-2008, Elliot Mednick and Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it 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. + * + * Veriwell 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 Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ + +/* file.h - file abstraction */ + +#ifndef FILE_H +#define FILE_H + +#include +#include + + +namespace veriwell { +/* + * file class + */ +class File { + FILE *f; + int isBuffer; + int len; + char *buffer; + int offset; + int own; + public: + static File *stdin_; + static File *fopen(const char *name, char *mode); + static File* Stdin(); + static File* fopenbuf(char *buffer, int len); + File(FILE * f); + File(char *buffer, int len, int own = 0); + void fclose(); + int isatty(); + int fgetc(); + int fscanf(char *format, ...); + int fungetc(int c); + char* fgets(char *s, int size); +}; + +} // namespace veriwell + +#endif //FILE_H + + diff --git a/src/veriwellinterface.cc b/src/veriwellinterface.cc new file mode 100644 index 0000000..c1536ab --- /dev/null +++ b/src/veriwellinterface.cc @@ -0,0 +1,230 @@ +/***************************************************************************** + * Copyright 2008, Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it 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. + * + * Veriwell 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 Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ + +/* veriwellinterface.cc - external interface to core simulator */ + +#include +#include +#include +#include +#include +#include "veriwellinterface.h" + +extern char *veriuser_version_str; +#define CPS sysconf(_SC_CLK_TCK) + +namespace veriwell { + + +Simulator simulator; +char *versionString = VERSION; +char copyright[] = "Copyright (C) 1993-2008 Elliot Mednick and Mark Hummel\n\n" + "Veriwell comes with ABSOLUTELY NO WARRANTY; This is free\n" + "software, and you are welcome to redistribute it under the\n" + "terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 2 of the License,\n" + "or (at your option) any later version. " + "\n\n"; + +static clock_t mclock() +{ + struct tms tms; + times(&tms); + return tms.tms_utime + tms.tms_stime; +} + + +/* + * Initialize simulator + */ +void Simulator::Init( int argc, char** argv ) +{ + veriwell::globalArgc = argc; + veriwell::globalArgv = argv; + veriwell::init_check(); + veriwell::init_copy(); + veriwell::init_decl(); + veriwell::init_flags(); + veriwell::init_io(); + veriwell::init_print(); + veriwell::init_sched(); + veriwell::init_tree_1(); + veriwell::init_eval(); + veriwell::init_pass3(); + veriwell::init_exec(); + veriwell::init_store(); + veriwell::init_pass2(); + veriwell::Usertask_Init(argc, argv); + veriwell::init_systask_1(); + veriwell::init_trace(); + veriwell::init_multdiv(); + veriwell::init_dumpvar(); + veriwell::init_strobe(); + veriwell::init_scope(); + veriwell::init_udp(); + veriwell::init_timescale(); + veriwell::InitNSched(); + veriwell::init_verisys(); + init_pli(); + init_tree(); +} + +/* + * Precomilation initialization + */ +void Simulator::Precompile() +{ + time_t t = time(NULL); + + /* Print out our header */ + printf_V("\n\n%s version %s, \n", VERIWELL, VERSION ); + printf_V( copyright ); + printf_V(veriuser_version_str); + + init_interactive(); + + clock_start = mclock(); + clock_compile = 0; + clock_load = 0; + clock_simulate = 0; +} + +/* + * Compilation stage + */ +void Simulator::CompileI() +{ + clock_compile = mclock() - clock_start; + if (!errorcount) { + printf_V("\nEntering Phase II...\n"); + build_hierarchy(); + } + if (!errorcount) { + printf_V("Entering Phase III...\n"); + pass3_tree(top_level); + /* + * allocate extra size for sysfunctions + * - mdh ??? doesn't appear as easy as this + * as this seem to create memory corruption issues + */ + // max_label += 64; + // stack_size += 1024; + stack_allocate(); + } +#if VDEBUG != 0 + if (vdebug) + print_stats(); +#endif + + if (warningcount) { + if (warningcount == 1) { + printf_V("1 warning in compilation\n"); + } else { + printf_V("%d warnings in compilation\n", warningcount); + } + } + if (errorcount) { + if (errorcount == 1) { + printf_V("1 error in compilation\n"); + } else { + printf_V("%d errors in compilation\n", errorcount); + } + goto DONE; + } + printf_V("No errors in compilation\n"); +DONE: + clock_load = mclock() - clock_start - clock_compile; + +} + +static void Breaker(int sig_number) +{ + if (!in_simulation) { + fputs("Compilation terminated by user\n", stdout); + fflush(stdout); + exit(1); + } else { + normal_flag = 0; + break_flag = 1; + signal(SIGINT, Breaker); + } +} + + +/* + * Simulate code + */ +void Simulator::Simulate() +{ + if( errorcount ) { + return; + } + signal(SIGINT,Breaker); + initialize_scope(top_level); + initialize_gates(); + initialize_cont_assignments(); + tree save_pc = dispatch_pc((enum which_list) NULL); + init_interactive(); + print_top_modules(); + in_simulation = 1; + broadcast_tf(reason_endofcompile); + fin = File::Stdin(); + exec_(save_pc); + signal(SIGINT,SIG_DFL); +} + +/* + * Print simulation statistics + */ + +void Simulator::PrintInfo(void) +{ + clock_t clock_current = mclock(); + + clock_simulate = clock_current - clock_start - clock_compile - + clock_load - clock_pause; + + printf_V("%d Error", errorcount); + if (errorcount != 1) { + printf_V("%c", (int) 's'); + } + printf_V(", %d Warning", warningcount); + if (warningcount != 1) { + printf_V("%c", (int) 's'); + } + printf_V(", Compile time = %.1f, Load time = %.1f," + " Simulation time = %.1f\n", + (double) clock_compile / CPS, (double) clock_load / CPS, + (double) clock_simulate / CPS); +} + +/* + * increment error count + */ +int Simulator::CountError( int warning ) +{ + if (warning) { + warningcount++; + } else { + errorcount++; + } + return 1; +} + +} diff --git a/src/veriwellinterface.h b/src/veriwellinterface.h new file mode 100644 index 0000000..e23d870 --- /dev/null +++ b/src/veriwellinterface.h @@ -0,0 +1,361 @@ +/***************************************************************************** + * Copyright 2008, Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it 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. + * + * Veriwell 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 Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ + +/* veriwellinterface.h - external interface to core simulator */ + +#ifndef VERIWELL_INTERFACE +#define VERIWELL_INTERFACE + +#include "vtypes.h" +#include "flags.h" +#include "schedule.h" +#include "pass3.h" +#include "gates.h" +#include "acc_user.h" +#include "pli.h" +#include "systask.h" +#include "pass2.h" +#include "runtime.h" +#include "tree.h" +#include "eval.h" +#include "timescal.h" +#include "obstack.h" +#include "exec.h" +#include "scope.h" +#include "check.h" +#include "tree.h" +#include "specify.h" +#include "decl.h" +#include "copy.h" +#include "udp.h" +#include "store.h" +#include "usertask.h" +#include "trace.h" +#include "multdiv.h" +#include "strobe.h" +#include "nsched.h" +#include "verisys.h" +#include "file.h" +#include "dumpvar.h" +#include "print.h" +#include "io.h" +#include "file.h" + +/*************************************************************** + * simulator exports used to create simulator structures + * ************************************************************/ + +/* + * objects + */ +using veriwell::integer_zero_node; +using veriwell::debug; +// current scope should be cleaned up +using veriwell::current_scope; +// the in_* variables are unsafe usages of globals +using veriwell::in_tf; +using veriwell::in_event; +using veriwell::in_systask; +using veriwell::in_instantiation; +using veriwell::module_list; +using veriwell::is_interactive; +// lineno unsafe usage of global +using veriwell::lineno; +using veriwell::new_cmd_level; +using veriwell::cmd_level; +using veriwell::plusargs; +using veriwell::in_simulation; +using veriwell::var_debug_flag; +using veriwell::error_mark_node; +using veriwell::default_net_type; +using veriwell::normal_flag; +using veriwell::trace_flag; +using veriwell::alledgeMask; +using veriwell::posedgeMask; +using veriwell::negedgeMask; +using veriwell::edge_mask; +// fin is bad use of global variable +using veriwell::fin; +using veriwell::ylibext; +using veriwell::ypathList; +using veriwell::key_enable; +using veriwell::key_file; +using veriwell::key_file_name; +using veriwell::log_file; +using veriwell::log_enable; +using veriwell::log_file_name; +using veriwell::key_available; +using veriwell::log_available; +using veriwell::stmt_lineno; +// input_filename needs to be untangled, but needs a major cleanup +using veriwell::input_filename; + +/* + * types + */ +using veriwell::nbits_t; +using veriwell::Bit; +using veriwell::radii; +using veriwell::tree; +using veriwell::lineno_t; +using veriwell::tree_type; +using veriwell::tree_code; +using veriwell::lval_type; +using veriwell::File; +using veriwell::obstack_t; +using veriwell::ngroups_t; +using veriwell::LibPath_t; + +/* + * procedures + */ +using veriwell::build_stmt; +using veriwell::build_int_cst; +using veriwell::build_real_cst; +using veriwell::nreverse; +using veriwell::make_node; +using veriwell::pop_scope; +using veriwell::push_scope; +using veriwell::make_event_spec; +using veriwell::build_string; +using veriwell::get_identifier; +using veriwell::process_timescale; +using veriwell::printf_error_V; +using veriwell::printf_V; +using veriwell::parse_base_const1g; +using veriwell::obstack_alloc; +using veriwell::obstack_init; +using veriwell::obstack_free; +using veriwell::warning; +using veriwell::error; +using veriwell::sorry; + +/* + * constants used by ASTs + */ +using veriwell::RANGE_HANDLE; +using veriwell::NET_WIRE_TYPE; +using veriwell::MIN_DELAY; +using veriwell::TYP_DELAY; +using veriwell::MAX_DELAY; +using veriwell::NO_TYPE; +using veriwell::GATE_RTRAN_TYPE; +using veriwell::NET_TRIOR_TYPE; +using veriwell::NET_TRIAND_TYPE; +using veriwell::NET_TRI_TYPE; +using veriwell::GATE_NOR_TYPE; +using veriwell::GATE_NOT_TYPE; +using veriwell::GATE_RNMOS_TYPE; +using veriwell::GATE_XOR_TYPE; +using veriwell::GATE_XNOR_TYPE; +using veriwell::GATE_NMOS_TYPE; +using veriwell::GATE_AND_TYPE; +using veriwell::GATE_NAND_TYPE; +using veriwell::GATE_TRAN_TYPE; +using veriwell::GATE_RPMOS_TYPE; +using veriwell::GATE_PMOS_TYPE; +using veriwell::NET_WOR_TYPE; +using veriwell::GATE_RTRANIF1_TYPE; +using veriwell::GATE_RCMOS_TYPE; +using veriwell::NET_TRI1_TYPE; +using veriwell::GATE_RTRANIF0_TYPE; +using veriwell::STRENGTH_STRONG1_TYPE; +using veriwell::NET_TRI0_TYPE; +using veriwell::GATE_PULLDN_TYPE; +using veriwell::GATE_NOTIF1_TYPE; +using veriwell::GATE_CMOS_TYPE; +using veriwell::STRENGTH_STRONG0_TYPE; +using veriwell::NET_WAND_TYPE; +using veriwell::GATE_BUF_TYPE; +using veriwell::GATE_NOTIF0_TYPE; +using veriwell::NET_TRIREG_TYPE; +using veriwell::GATE_PULLUP_TYPE; +using veriwell::NET_SUPPLY1_TYPE; +using veriwell::GATE_TRANIF1_TYPE; +using veriwell::NET_SUPPLY0_TYPE; +using veriwell::GATE_TRANIF0_TYPE; +using veriwell::GATE_BUFIF1_TYPE; +using veriwell::GATE_BUFIF0_TYPE; +using veriwell::STRENGTH_PULL1_TYPE; +using veriwell::STRENGTH_PULL0_TYPE; +using veriwell::STRENGTH_WEAK1_TYPE; +using veriwell::STRENGTH_WEAK0_TYPE; +using veriwell::STRENGTH_HIGHZ1_TYPE; +using veriwell::STRENGTH_HIGHZ0_TYPE; +using veriwell::STRING_; +using veriwell::HEX; +using veriwell::BIN; +using veriwell::OCT; +using veriwell::DEC; +using veriwell::X; +using veriwell::ZERO; +using veriwell::ONE; +using veriwell::ALWAYS_CODE; +using veriwell::ALWAYS_BLOCK; +using veriwell::INITIAL_CODE; +using veriwell::INITIAL_BLOCK; +using veriwell::LVAL_NEW_NET; +using veriwell::LVAL_REG; +using veriwell::LVAL_NET; +using veriwell::LVAL_REG_NET; +using veriwell::ASSIGN_STMT; +using veriwell::ASSIGN_DELAY_STMT; +using veriwell::ASSIGN_NONBLK_DELAY_STMT; +using veriwell::ASSIGN_EVENT_STMT; +using veriwell::ASSIGN_NONBLK_DELAY_STMT; +using veriwell::ASSIGN_NONBLK_EVENT_STMT; +using veriwell::ASSIGN_PROC_STMT; +using veriwell::DEASSIGN_STMT; +using veriwell::ASSIGN_STMT; +using veriwell::GATE_OR_TYPE; +using veriwell::INSTANCE_NODE; +using veriwell::NULL_STMT; +using veriwell::IF_STMT; +using veriwell::FOREVER_STMT; +using veriwell::FOR_STMT; +using veriwell::FORCE_STMT; +using veriwell::FORK_STMT; +using veriwell::FORK_NAMED_STMT; +using veriwell::REPEAT_INIT_STMT; +using veriwell::REPEAT_STMT; +using veriwell::WHILE_STMT; +using veriwell::DELAY_STMT; +using veriwell::WAIT_STMT; +using veriwell::ARROW_STMT; +using veriwell::DISABLE_STMT; +using veriwell::RELEASE_STMT; +using veriwell::CASE_STMT; +using veriwell::CASEZ_STMT; +using veriwell::CASEX_STMT; +using veriwell::BEGIN_STMT; +using veriwell::END_STMT; +using veriwell::NAMED_BLOCK; +using veriwell::BEGIN_NAMED_STMT; +using veriwell::END_NAMED_STMT; +using veriwell::JOIN_STMT; +using veriwell::JOIN_NAMED_STMT; +using veriwell::TASK_STMT; +using veriwell::SYSTASK_STMT; +using veriwell::BIT_NOT_EXPR; +using veriwell::EQ_EXPR; +using veriwell::EQ_CASE_EXPR; +using veriwell::NE_CASE_EXPR; +using veriwell::NE_EXPR; +using veriwell::CONCAT_REF; +using veriwell::NEGATE_EXPR; +using veriwell::TRUTH_NOT_EXPR; +using veriwell::BIT_NOT_EXPR; +using veriwell::AND_REDUCE_EXPR; +using veriwell::NAND_REDUCE_EXPR; +using veriwell::OR_REDUCE_EXPR; +using veriwell::NOR_REDUCE_EXPR; +using veriwell::XOR_REDUCE_EXPR; +using veriwell::XNOR_REDUCE_EXPR; +using veriwell::PLUS_EXPR; +using veriwell::MINUS_EXPR; +using veriwell::MULT_EXPR; +using veriwell::DIV_EXPR; +using veriwell::MOD_EXPR; +using veriwell::TRUTH_ANDIF_EXPR; +using veriwell::TRUTH_ORIF_EXPR; +using veriwell::LT_EXPR; +using veriwell::LE_EXPR; +using veriwell::GT_EXPR; +using veriwell::GE_EXPR; +using veriwell::BIT_AND_EXPR; +using veriwell::BIT_OR_EXPR; +using veriwell::BIT_XOR_EXPR; +using veriwell::BIT_XNOR_EXPR; +using veriwell::LSHIFT_EXPR; +using veriwell::RSHIFT_EXPR; +using veriwell::CONCAT_REP_REF; +using veriwell::SYSFUNCTION_REF; +using veriwell::DELAY_EXPR; +using veriwell::EVENT_DECL; +using veriwell::EVENT_STMT; +using veriwell::ANYEDGE_EXPR; +using veriwell::POSEDGE_EXPR; +using veriwell::NEGEDGE_EXPR; + + +namespace veriwell { + class Simulator { + private: + /* + * lex/parse callbacks for + * interactive mode and library + * parsing + */ + void (*reinit_lex_fptr)(); + int (*prog_parse_fptr)(tree&); + void (*push_stream_fptr)(File*,int); + File* (*pop_stream_fptr)(); + /* + * these callback's need to be untangled and removed + */ + void (*finish_fptr)(); + /* + * global simulator state + */ + clock_t clock_start; + clock_t clock_compile; + clock_t clock_load; + clock_t clock_simulate; + public: + Simulator() : + reinit_lex_fptr(0), + prog_parse_fptr(0), + push_stream_fptr(0), + pop_stream_fptr(0), + finish_fptr(0) + {} + void reinit_lex() { (*reinit_lex_fptr)(); } + void reinit_lex( void (*fptr)() ) { reinit_lex_fptr = fptr; } + int prog_parse(tree& t) { return (*prog_parse_fptr)(t); } + void prog_parse( int (*fptr)(tree&) ) { prog_parse_fptr = fptr; } + void push_stream(File* f,int i) { (*push_stream_fptr)(f,i); } + void push_stream( void (*fptr)(File*,int) ) + { push_stream_fptr = fptr; } + File* pop_stream() { return (*pop_stream_fptr)(); } + void pop_stream( File* (*fptr)() ) { pop_stream_fptr = fptr; } + void finish() { (*finish_fptr)(); } + void finish( void (*fptr)() ) { finish_fptr = fptr; } + /* + * simulator control + */ + void DelayType( delay_type dt ) { delayType = dt; } + delay_type DelayType() { return delayType; } + void Init(int,char**); + void Precompile(); + void CompileI(); + void Simulate(); + void PrintInfo(); + int CountError( int warning ); + }; + extern Simulator simulator; + inline void finish() { + broadcast_tf(reason_finish); + simulator.finish(); + } +} + + + + +#endif // VERIWELL_INTERFACE