From 27e717839af7657a78ab605ee91f093631485a21 Mon Sep 17 00:00:00 2001 From: steve Date: Wed, 21 Mar 2001 01:49:43 +0000 Subject: [PATCH] Scan the scopes of a design, and draw behavioral blocking assignments of constants to vectors. --- tgt-vvp/Makefile.in | 4 +- tgt-vvp/vvp.c | 5 +- tgt-vvp/vvp_priv.h | 8 ++- tgt-vvp/vvp_process.c | 115 +++++++++++++++++++++++++++++++++++++++++- tgt-vvp/vvp_scope.c | 64 +++++++++++++++++++++++ 5 files changed, 189 insertions(+), 7 deletions(-) create mode 100644 tgt-vvp/vvp_scope.c diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in index 17f187d8d..b7579a946 100644 --- a/tgt-vvp/Makefile.in +++ b/tgt-vvp/Makefile.in @@ -16,7 +16,7 @@ # 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 $" +#ident "$Id: Makefile.in,v 1.2 2001/03/21 01:49:43 steve Exp $" # # SHELL = /bin/sh @@ -49,7 +49,7 @@ all: vvp.tgt $(CC) -Wall $(CPPFLAGS) -I$(srcdir)/.. -MD -c $< -o $*.o mv $*.d dep -O = vvp.o vvp_process.o +O = vvp.o vvp_process.o vvp_scope.o ifeq (@CYGWIN@,yes) TGTLDFLAGS=-L.. -livl diff --git a/tgt-vvp/vvp.c b/tgt-vvp/vvp.c index b71f48477..2989a5368 100644 --- a/tgt-vvp/vvp.c +++ b/tgt-vvp/vvp.c @@ -17,7 +17,7 @@ * 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 $" +#ident "$Id: vvp.c,v 1.2 2001/03/21 01:49:43 steve Exp $" #endif /* @@ -41,8 +41,7 @@ int target_design(ivl_design_t des) } root = ivl_design_root(des); - fprintf(vvp_out, "S_%s .scope \"%s\";\n", ivl_scope_name(root), - ivl_scope_name(root)); + draw_scope(root, 0); ivl_design_process(des, draw_process, 0); diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 601a49837..4eaea8ea2 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -19,7 +19,7 @@ * 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 $" +#ident "$Id: vvp_priv.h,v 1.2 2001/03/21 01:49:43 steve Exp $" #endif # include "ivl_target.h" @@ -37,8 +37,14 @@ extern FILE* vvp_out; */ extern int draw_process(ivl_process_t net, void*x); +extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent); + /* * $Log: vvp_priv.h,v $ + * Revision 1.2 2001/03/21 01:49:43 steve + * Scan the scopes of a design, and draw behavioral + * blocking assignments of constants to vectors. + * * Revision 1.1 2001/03/19 01:20:46 steve * Add the tgt-vvp code generator target. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 30701bccc..500f4f64b 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,10 +17,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_process.c,v 1.2 2001/03/20 01:44:14 steve Exp $" +#ident "$Id: vvp_process.c,v 1.3 2001/03/21 01:49:43 steve Exp $" #endif # include "vvp_priv.h" +# include + +static void show_statement(ivl_statement_t net); /* * This file includes the code needed to generate VVP code for @@ -28,6 +31,100 @@ * executable code for the processes. */ +/* + * These functions handle the blocking assignment. Use the %set + * instruction to perform the actual assignment, and calculate any + * lvalues and rvalues that need calculating. + * + * The set_to_nexus function takes a particular nexus and generates + * the %set statements to assign the value. + * + * The show_stmt_assign function looks at the assign statement, scans + * the l-values, and matches bits of the r-value with the correct + * nexus. + */ + +static void set_to_nexus(ivl_nexus_t nex, char bit) +{ + unsigned idx; + + for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); + unsigned pin = ivl_nexus_ptr_pin(ptr); + ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); + + if (sig == 0) + continue; + + switch (bit) { + case '0': + case '1': + break; + case 'x': + bit = '2'; + break; + case 'z': + bit = '3'; + break; + } + fprintf(vvp_out, " %%set V_%s[%u], %c\n", + ivl_signal_name(sig), pin, bit); + } +} + +static void show_stmt_assign(ivl_statement_t net) +{ + ivl_lval_t lval; + ivl_expr_t rval = ivl_stmt_rval(net); + + + /* Handle the special case that the r-value is a constant. We + can generate the %set statement directly, without any worry + about generating code to evaluate the r-value expressions. */ + + if (ivl_expr_type(rval) == IVL_EX_NUMBER) { + unsigned idx; + const char*bits = ivl_expr_bits(rval); + + /* XXXX Only single l-value supported for now */ + assert(ivl_stmt_lvals(net) == 1); + + lval = ivl_stmt_lval(net, 0); + /* XXXX No mux support yet. */ + assert(ivl_lval_mux(lval) == 0); + + for (idx = 0 ; idx < ivl_lval_pins(lval) ; idx += 1) + set_to_nexus(ivl_lval_pin(lval, idx), bits[idx]); + + return; + } + + fprintf(stderr, "XXXX EXPRESSION TOO COMPLEX FOR ME?\n"); +} + +/* + * The delay statement is easy. Simply write a ``%delay '' + * instruction to delay the thread, then draw the included statement. + * The delay statement comes from verilog code like this: + * + * ... + * # ; + */ +static void show_stmt_delay(ivl_statement_t net) +{ + unsigned long delay = ivl_stmt_delay_val(net); + ivl_statement_t stmt = ivl_stmt_sub_stmt(net); + + fprintf(vvp_out, " %%delay %lu;\n", delay); + show_statement(stmt); +} + +/* + * noop statements are implemented by doing nothing. + */ +static void show_stmt_noop(ivl_statement_t net) +{ +} static void show_system_task_call(ivl_statement_t net) { @@ -69,6 +166,10 @@ static void show_statement(ivl_statement_t net) switch (code) { + case IVL_ST_ASSIGN: + show_stmt_assign(net); + break; + /* Begin-end blocks simply draw their contents. */ case IVL_ST_BLOCK: { unsigned idx; @@ -79,6 +180,14 @@ static void show_statement(ivl_statement_t net) break; } + case IVL_ST_DELAY: + show_stmt_delay(net); + break; + + case IVL_ST_NOOP: + show_stmt_noop(net); + break; + case IVL_ST_STASK: show_system_task_call(net); break; @@ -136,6 +245,10 @@ int draw_process(ivl_process_t net, void*x) /* * $Log: vvp_process.c,v $ + * Revision 1.3 2001/03/21 01:49:43 steve + * Scan the scopes of a design, and draw behavioral + * blocking assignments of constants to vectors. + * * Revision 1.2 2001/03/20 01:44:14 steve * Put processes in the proper scope. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c new file mode 100644 index 000000000..15444ea70 --- /dev/null +++ b/tgt-vvp/vvp_scope.c @@ -0,0 +1,64 @@ +/* + * 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_scope.c,v 1.1 2001/03/21 01:49:43 steve Exp $" +#endif + +# include "vvp_priv.h" +# include + +/* + * This function draws the major functional items within a scope. This + * includes the scopes themselves, of course. + */ +int draw_scope(ivl_scope_t net, ivl_scope_t parent) +{ + unsigned idx; + + if (parent) + fprintf(vvp_out, "S_%s .scope \"%s\", S_%s;\n", + ivl_scope_name(net), ivl_scope_name(net), + ivl_scope_name(parent)); + else + fprintf(vvp_out, "S_%s .scope \"%s\";\n", + ivl_scope_name(net), ivl_scope_name(net)); + + + for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) { + ivl_signal_t sig = ivl_scope_sig(net, idx); + int msb = ivl_signal_pins(sig) - 1; + int lsb = 0; + + fprintf(vvp_out, "V_%s .var \"%s\", %d, %d;\n", + ivl_signal_name(sig), ivl_signal_basename(sig), + msb, lsb); + } + + ivl_scope_children(net, draw_scope, net); + return 0; +} + +/* + * $Log: vvp_scope.c,v $ + * Revision 1.1 2001/03/21 01:49:43 steve + * Scan the scopes of a design, and draw behavioral + * blocking assignments of constants to vectors. + * + */ +