diff --git a/vvp/compile.cc b/vvp/compile.cc index c333028b7..8103e16d3 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.12 2001/03/23 02:40:22 steve Exp $" +#ident "$Id: compile.cc,v 1.13 2001/03/25 00:35:35 steve Exp $" #endif # include "compile.h" @@ -441,6 +441,48 @@ void compile_variable(char*label, char*name, int msb, int lsb) free(label); } +void compile_net(char*label, char*name, int msb, int lsb, + unsigned argc, struct symb_s*argv) +{ + unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1; + vvp_ipoint_t fdx = functor_allocate(wid); + symbol_value_t val; + val.num = fdx; + sym_set_value(sym_functors, label, val); + + /* Allocate all the functors for the net itself. */ + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + functor_t obj = functor_index(ipoint_index(fdx,idx)); + obj->table = ft_var; + obj->ival = 0x22; + obj->oval = 0x02; + } + + assert(argc == wid); + + /* Connect port[0] of each of the net functors to the output + of the addressed object. */ + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + vvp_ipoint_t ptr = ipoint_index(fdx,idx); + functor_t obj = functor_index(ptr); + + val = sym_get_value(sym_functors, argv[idx].text); + assert(val.num); + + functor_t src = functor_index(ipoint_index(val.num, + argv[idx].idx)); + obj->port[0] = src->out; + src->out = ptr; + } + + /* Make the vpiHandle for the reg. */ + vpiHandle obj = vpip_make_net(name, msb, lsb, fdx); + compile_vpi_symbol(label, obj); + + free(label); + free(argv); +} + /* * When parsing is otherwise complete, this function is called to do * the final stuff. Clean up deferred linking here. @@ -524,6 +566,9 @@ void compile_dump(FILE*fd) /* * $Log: compile.cc,v $ + * Revision 1.13 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.12 2001/03/23 02:40:22 steve * Add the :module header statement. * diff --git a/vvp/compile.h b/vvp/compile.h index 69f25668e..0fce2e9ae 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.h,v 1.9 2001/03/23 02:40:22 steve Exp $" +#ident "$Id: compile.h,v 1.10 2001/03/25 00:35:35 steve Exp $" #endif # include @@ -112,6 +112,9 @@ extern void compile_thread(char*start_sym); */ extern void compile_variable(char*label, char*name, int msb, int lsb); +extern void compile_net(char*label, char*name, int msb, int lsb, + unsigned argc, struct symb_s*argv); + /* * This is a diagnostic aid. Dump all the compiler tables to the file * descriptor in a readable form. @@ -120,6 +123,9 @@ extern void compile_dump(FILE*fd); /* * $Log: compile.h,v $ + * Revision 1.10 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.9 2001/03/23 02:40:22 steve * Add the :module header statement. * diff --git a/vvp/examples/copy.vvp b/vvp/examples/copy.vvp new file mode 100644 index 000000000..8c1ce8f4c --- /dev/null +++ b/vvp/examples/copy.vvp @@ -0,0 +1,53 @@ +:vpi_module "system"; + +; 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 + + +; This example is similar to the code that the following Verilog program +; would make: +; +; module main; +; reg a; +; wire b = a; +; initial begin +; a = 0; +; #1 $display("a=%b, b=%b", a, b); +; a = 1; +; #1 $display("a=%b, b=%b", a, b); +; end +; endmodule +; +; This tests that a simple continuous assign of a net from a var works +; properly. This is a very trivial functor propagation that is initiated +; by the %set instruction. + +main .scope "main"; + +V_main.a .var "a", 0, 0; +V_main.b .net "b", 0, 0, V_main.a; + +code + %set V_main.a, 0; + %delay 1; + %vpi_call "$display", "a=%b, b=%b", V_main.a, V_main.b; + %set V_main.a, 1; + %delay 1; + %vpi_call "$display", "a=%b, b=%b", V_main.a, V_main.b; + %end; + + .thread code; diff --git a/vvp/functor.cc b/vvp/functor.cc index b35ae3979..820520412 100644 --- a/vvp/functor.cc +++ b/vvp/functor.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: functor.cc,v 1.5 2001/03/22 05:28:16 steve Exp $" +#ident "$Id: functor.cc,v 1.6 2001/03/25 00:35:35 steve Exp $" #endif # include "functor.h" @@ -184,7 +184,7 @@ void functor_propagate(vvp_ipoint_t ptr) while (idx) { functor_t idxp = functor_index(idx); vvp_ipoint_t next = idxp->port[ipoint_port(idx)]; - printf(" set %lx to %u\n", idx, oval); + //printf(" set %lx to %u\n", idx, oval); functor_set(idx, oval); idx = next; } @@ -226,6 +226,9 @@ const unsigned char ft_var[16] = { /* * $Log: functor.cc,v $ + * Revision 1.6 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.5 2001/03/22 05:28:16 steve * no longer need out message. * diff --git a/vvp/lexor.lex b/vvp/lexor.lex index a4d1cff12..480062491 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: lexor.lex,v 1.6 2001/03/23 02:40:22 steve Exp $" +#ident "$Id: lexor.lex,v 1.7 2001/03/25 00:35:35 steve Exp $" #endif # include "parse_misc.h" @@ -49,6 +49,7 @@ /* These are some keywords that are recognized. */ ".functor" { return K_FUNCTOR; } +".net" { return K_NET; } ".scope" { return K_SCOPE; } ".thread" { return K_THREAD; } ".var" { return K_VAR; } @@ -103,6 +104,9 @@ int yywrap() /* * $Log: lexor.lex,v $ + * Revision 1.7 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.6 2001/03/23 02:40:22 steve * Add the :module header statement. * diff --git a/vvp/parse.y b/vvp/parse.y index 6c9fa06f1..36dd35f4d 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.11 2001/03/23 02:40:22 steve Exp $" +#ident "$Id: parse.y,v 1.12 2001/03/25 00:35:35 steve Exp $" #endif # include "parse_misc.h" @@ -49,7 +49,7 @@ extern FILE*yyin; }; -%token K_FUNCTOR K_SCOPE K_THREAD K_VAR K_vpi_call +%token K_FUNCTOR K_NET K_SCOPE K_THREAD K_VAR K_vpi_call %token K_vpi_module %token T_INSTR @@ -147,6 +147,12 @@ statement | T_LABEL K_VAR T_STRING ',' T_NUMBER ',' T_NUMBER ';' { compile_variable($1, $3, $5, $7); } + /* Net statements are similar to .var statements, except that they + declare nets, and they have an input list. */ + + | T_LABEL K_NET T_STRING ',' T_NUMBER ',' T_NUMBER ',' symbols ';' + { compile_net($1, $3, $5, $7, $9.cnt, $9.vect); } + /* Oh and by the way, empty statements are OK as well. */ | ';' @@ -289,6 +295,9 @@ int compile_design(const char*path) /* * $Log: parse.y,v $ + * Revision 1.12 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.11 2001/03/23 02:40:22 steve * Add the :module header statement. * diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 6b0e63ccf..886fffe30 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vpi_priv.h,v 1.6 2001/03/23 02:40:23 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.7 2001/03/25 00:35:35 steve Exp $" #endif # include "vpi_user.h" @@ -106,6 +106,8 @@ struct __vpiSignal { }; extern vpiHandle vpip_make_reg(char*name, int msb, int lsb, vvp_ipoint_t base); +extern vpiHandle vpip_make_net(char*name, int msb, int lsb, + vvp_ipoint_t base); /* * When a loaded VPI module announces a system task/function, one @@ -180,6 +182,9 @@ extern void vpip_execute_vpi_call(vpiHandle obj); /* * $Log: vpi_priv.h,v $ + * Revision 1.7 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.6 2001/03/23 02:40:23 steve * Add the :module header statement. * diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index e666f67c6..4f4d4bdfa 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vpi_signal.cc,v 1.2 2001/03/21 05:13:03 steve Exp $" +#ident "$Id: vpi_signal.cc,v 1.3 2001/03/25 00:35:35 steve Exp $" #endif /* @@ -141,6 +141,16 @@ static const struct __vpirt vpip_reg_rt = { 0 }; +static const struct __vpirt vpip_net_rt = { + vpiNet, + signal_get, + signal_get_str, + signal_get_value, + signal_put_value, + 0, + 0 +}; + /* * Construct a vpiReg object. Give the object specified dimensions, * and point to the specified functor for the lsb. @@ -161,8 +171,31 @@ vpiHandle vpip_make_reg(char*name, int msb, int lsb, vvp_ipoint_t base) } +/* + * Construct a vpiReg object. Give the object specified dimensions, + * and point to the specified functor for the lsb. + */ +vpiHandle vpip_make_net(char*name, int msb, int lsb, vvp_ipoint_t base) +{ + struct __vpiSignal*obj = (struct __vpiSignal*) + malloc(sizeof(struct __vpiSignal)); + obj->base.vpi_type = &vpip_net_rt; + obj->name = name; + obj->msb = msb; + obj->lsb = lsb; + obj->bits = base; + + obj->scope = vpip_peek_current_scope(); + + return &obj->base; +} + + /* * $Log: vpi_signal.cc,v $ + * Revision 1.3 2001/03/25 00:35:35 steve + * Add the .net statement. + * * Revision 1.2 2001/03/21 05:13:03 steve * Allow var objects as vpiHandle arguments to %vpi_call. *