diff --git a/autoconf.sh b/autoconf.sh index 72e0c90f7..4d9622599 100644 --- a/autoconf.sh +++ b/autoconf.sh @@ -10,7 +10,7 @@ echo "Autoconf in root..." autoconf for dir -in vpip vvp +in vpip vvp tgt-vvp do echo "Autoconf in $dir..." ( cd $dir ; autoconf ) diff --git a/configure.in b/configure.in index a9306a7e7..2b034bdda 100644 --- a/configure.in +++ b/configure.in @@ -148,6 +148,6 @@ AC_SUBST(shared) AC_MSG_RESULT($shared) -AC_CONFIG_SUBDIRS(vpip vvp) +AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp) AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile) diff --git a/iverilog.conf b/iverilog.conf index 6e3fc4a8f..4c531bec9 100644 --- a/iverilog.conf +++ b/iverilog.conf @@ -61,6 +61,16 @@ [-tnull] %B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- - +# -- +# The vvp target generates code that the vvp simulation engine can execute. +# These rules support synthesized and non-synthesized variants. + +[-tvvp -S] +%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -- - + +[-tvvp] +%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -Fcprop -Fnodangle %f %m -- - + # -- # The vvm target uses the string to take the preprocessed code from # standard input, compile it with the vvm code generator and write the diff --git a/tgt-vvp/.cvsignore b/tgt-vvp/.cvsignore new file mode 100644 index 000000000..c8e9f5cfb --- /dev/null +++ b/tgt-vvp/.cvsignore @@ -0,0 +1,6 @@ +Makefile +configure +config.status +config.log +dep +vvp.tgt diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in new file mode 100644 index 000000000..17f187d8d --- /dev/null +++ b/tgt-vvp/Makefile.in @@ -0,0 +1,82 @@ +# +# This source code is free software; you can redistribute it +# and/or modify it in source code form under the terms of the GNU +# Library 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 Library General Public License for more details. +# +# You should have received a copy of the GNU Library 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 +# +#ident "$Id: Makefile.in,v 1.1 2001/03/19 01:20:46 steve Exp $" +# +# +SHELL = /bin/sh + +VERSION = 0.0 + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +srcdir = @srcdir@ + +VPATH = $(srcdir) + +bindir = @bindir@ +libdir = @libdir@ +includedir = $(prefix)/include + +CC = @CC@ +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@ +CXXFLAGS = @CXXFLAGS@ +LDFLAGS = @LDFLAGS@ + +all: vvp.tgt + +%.o: %.c + @[ -d dep ] || mkdir dep + $(CC) -Wall $(CPPFLAGS) -I$(srcdir)/.. -MD -c $< -o $*.o + mv $*.d dep + +O = vvp.o vvp_process.o + +ifeq (@CYGWIN@,yes) + TGTLDFLAGS=-L.. -livl + TGTDEPLIBS=../libivl.a +else + TGTLDFLAGS= + TGTDEPLIBS= +endif + + +vvp.tgt: $O $(TGTDEPLIBS) + $(CC) @shared@ -o $@ $O $(TGTLDFLAGS) + +clean: + rm -f *.o dep/*.d + +install: all installdirs $(libdir)/ivl/vvp.tgt + +$(libdir)/ivl/vvp.tgt: ./vvp.tgt + $(INSTALL_DATA) ./vvp.tgt $(libdir)/ivl/vvp.tgt + + +installdirs: ../mkinstalldirs + $(srcdir)/../mkinstalldirs $(libdir)/ivl + +uninstall: + rm -f $(libdir)/ivl/vvp.tgt + + +-include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-vvp/configure.in b/tgt-vvp/configure.in new file mode 100644 index 000000000..1437b51d1 --- /dev/null +++ b/tgt-vvp/configure.in @@ -0,0 +1,53 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(vvp.c) + +dnl Checks for programs. +AC_PROG_CC + +AC_PROG_INSTALL + +AC_CANONICAL_HOST +# $host + +AC_CYGWIN +AC_SUBST(CYGWIN) + +# The -fPIC flag is used to tell the compiler to make position +# independent code. It is needed when making shared objects. + +AC_MSG_CHECKING("for flag to make position independent code") +PICFLAG=-fPIC +case "${host}" in + + *-*-cygwin*) + PICFLAG= + ;; + + *-*-hpux*) + PICFLAG=+z + ;; + +esac +AC_SUBST(PICFLAG) +AC_MSG_RESULT($PICFLAG) + +AC_MSG_CHECKING("for shared library link flag") +shared=-shared +case "${host}" in + + *-*-cygwin*) + shared="-mdll -Wl,--enable-auto-image-base" + ;; + + *-*-hpux*) + shared="-b" + ;; + +esac + +AC_SUBST(shared) + +AC_MSG_RESULT($shared) + + +AC_OUTPUT(Makefile) diff --git a/tgt-vvp/vvp.c b/tgt-vvp/vvp.c new file mode 100644 index 000000000..b71f48477 --- /dev/null +++ b/tgt-vvp/vvp.c @@ -0,0 +1,61 @@ +/* + * 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 + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: vvp.c,v 1.1 2001/03/19 01:20:46 steve Exp $" +#endif + +/* + */ + +# include "vvp_priv.h" +# include + +FILE*vvp_out = 0; + +int target_design(ivl_design_t des) +{ + ivl_scope_t root; + const char*path = ivl_design_flag(des, "-o"); + assert(path); + + vvp_out = fopen(path, "w"); + if (vvp_out == 0) { + perror(path); + return -1; + } + + root = ivl_design_root(des); + fprintf(vvp_out, "S_%s .scope \"%s\";\n", ivl_scope_name(root), + ivl_scope_name(root)); + + ivl_design_process(des, draw_process, 0); + + fclose(vvp_out); + + return 0; +} + +#ifdef __CYGWIN32__ +#include +DECLARE_CYGWIN_DLL(DllMain); +#endif + +/* + */ + diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h new file mode 100644 index 000000000..601a49837 --- /dev/null +++ b/tgt-vvp/vvp_priv.h @@ -0,0 +1,46 @@ +#ifndef __vvp_priv_H +#define __vvp_priv_H +/* + * 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 + */ +#if !defined(WINNT) +#ident "$Id: vvp_priv.h,v 1.1 2001/03/19 01:20:46 steve Exp $" +#endif + +# include "ivl_target.h" +# include + +/* + * The target_design entry opens the output file that receives the + * compiled design, and sets the vvp_out to the descripter. + */ +extern FILE* vvp_out; + +/* + * This function draws a process (initial or always) into the output + * file. + */ +extern int draw_process(ivl_process_t net, void*x); + +/* + * $Log: vvp_priv.h,v $ + * Revision 1.1 2001/03/19 01:20:46 steve + * Add the tgt-vvp code generator target. + * + */ +#endif diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c new file mode 100644 index 000000000..a4baec7b3 --- /dev/null +++ b/tgt-vvp/vvp_process.c @@ -0,0 +1,139 @@ +/* + * 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 + */ +#if !defined(WINNT) +#ident "$Id: vvp_process.c,v 1.1 2001/03/19 01:20:46 steve Exp $" +#endif + +# include "vvp_priv.h" + +/* + * This file includes the code needed to generate VVP code for + * processes. Scopes are already declared, we generate here the + * executable code for the processes. + */ + + +static void show_system_task_call(ivl_statement_t net) +{ + unsigned idx; + unsigned parm_count = ivl_stmt_parm_count(net); + + if (parm_count == 0) { + fprintf(vvp_out, " %%vpi_call \"%s\";\n", ivl_stmt_name(net)); + return; + } + + fprintf(vvp_out, " %%vpi_call \"%s\"", ivl_stmt_name(net)); + for (idx = 0 ; idx < parm_count ; idx += 1) { + ivl_expr_t expr = ivl_stmt_parm(net, idx); + + switch (ivl_expr_type(expr)) { + + case IVL_EX_STRING: + fprintf(vvp_out, ", \"%s\"", ivl_expr_string(expr)); + break; + + default: + fprintf(vvp_out, ", ?"); + break; + } + } + + fprintf(vvp_out, ";\n"); +} + +/* + * This function draws a statement as vvp assembly. It basically + * switches on the statement type and draws code based on the type and + * further specifics. + */ +static void show_statement(ivl_statement_t net) +{ + const ivl_statement_type_t code = ivl_statement_type(net); + + switch (code) { + + /* Begin-end blocks simply draw their contents. */ + case IVL_ST_BLOCK: { + unsigned idx; + unsigned cnt = ivl_stmt_block_count(net); + for (idx = 0 ; idx < cnt ; idx += 1) { + show_statement(ivl_stmt_block_stmt(net, idx)); + } + break; + } + + case IVL_ST_STASK: + show_system_task_call(net); + break; + + default: + fprintf(stderr, "vvp.tgt: Unable to draw statement type %u\n", + code); + break; + } +} + +/* + * The process as a whole is surrounded by this code. We generate a + * start label that the .thread statement can use, and we generate + * code to terminate the thread. + */ + +int draw_process(ivl_process_t net, void*x) +{ + /* Generate the entry label. Just give the thread a number so + that we ar certain the label is unique. */ + static unsigned thread_count = 0; + fprintf(vvp_out, "T_%05d\n", thread_count); + + /* Draw the contents of the thread. */ + show_statement(ivl_process_stmt(net)); + + + /* Terminate the thread with either an %end instruction (initial + statements) or a %jmp back to the beginning of the thread. */ + + switch (ivl_process_type(net)) { + + case IVL_PR_INITIAL: + fprintf(vvp_out, " %%end;\n"); + break; + + case IVL_PR_ALWAYS: + fprintf(vvp_out, " %%jmp T_%05d;\n", thread_count); + break; + } + + /* Now write out the .thread directive that tells vvp where + the thread starts. */ + fprintf(vvp_out, " .thread T_%05d;\n", thread_count); + + + thread_count += 1; + return 0; +} + +/* + * $Log: vvp_process.c,v $ + * Revision 1.1 2001/03/19 01:20:46 steve + * Add the tgt-vvp code generator target. + * + */ +