Add structural addition.

This commit is contained in:
steve 2001-06-05 03:05:41 +00:00
parent 33ee5c26b0
commit f3019ff5a0
9 changed files with 335 additions and 12 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330 # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA # Boston, MA 02111-1307, USA
# #
#ident "$Id: Makefile.in,v 1.21 2001/05/31 04:12:43 steve Exp $" #ident "$Id: Makefile.in,v 1.22 2001/06/05 03:05:41 steve Exp $"
# #
# #
SHELL = /bin/sh SHELL = /bin/sh
@ -62,8 +62,9 @@ V = vpi_modules.o vpi_const.o vpi_iter.o vpi_mcd.o vpi_priv.o \
vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \ vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
vpi_vthr_vector.o vpi_vthr_vector.o
O = main.o parse.o parse_misc.o lexor.o bufif.o compile.o debug.o functor.o \ O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
resolv.o symbols.o codes.o vthread.o schedule.o tables.o udp.o memory.o $V functor.o resolv.o symbols.o codes.o vthread.o schedule.o \
tables.o udp.o memory.o $V
vvp: $O vvp: $O
$(CXX) $(rdynamic) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(LIBS) $(dllib) $(CXX) $(rdynamic) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(LIBS) $(dllib)

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* *
* $Id: README.txt,v 1.25 2001/05/09 02:53:25 steve Exp $ * $Id: README.txt,v 1.26 2001/06/05 03:05:41 steve Exp $
*/ */
VVP SIMULATION ENGINE VVP SIMULATION ENGINE
@ -375,7 +375,7 @@ single symbol for the addressed bit. However, if there are several
events of the same edge in an event OR expression, the compiler may events of the same edge in an event OR expression, the compiler may
combine up to 4 into a single event. combine up to 4 into a single event.
If many more events need to be conbined together (for example due to If many more events need to be combined together (for example due to
an event or expression in the Verilog) then this form can be used: an event or expression in the Verilog) then this form can be used:
<label> .event/or <symbols_list>; <label> .event/or <symbols_list>;
@ -397,6 +397,26 @@ resolution function.
<label> .resolv tri1, <symbols_list>; <label> .resolv tri1, <symbols_list>;
STRUCTURAL ARITHMETIC STATEMENTS:
The various Verilog arithmetic opeators (+-*/%) are available to
structural contexts even though they do not fit into nice neat
functors. These operators are not in general bitwise, so special
measures are needed to make them work in a functor environment. We
create special statement types for the various arithmetic operators.
<label> .arith/sum <wid>, <symbols_list>;
Addition is represented by the .arith/sum statement. This creates an
array of functors based at the label. The width of the array is given
by <wid>, and the <symbols_list> connects the inputs.
The sum can add together up to 4 operands, specified in the
<symbols_list> one bit at a time. All the bits of the first operand
(lsb first) are listed, then the bits of the second, and so on. The
number of symbols must be an even multiple of the width of the operator.
THREAD STATEMENTS: THREAD STATEMENTS:
Thread statements create the initial threads for a simulation. These Thread statements create the initial threads for a simulation. These

105
vvp/arith.cc Normal file
View File

@ -0,0 +1,105 @@
/*
* 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: arith.cc,v 1.1 2001/06/05 03:05:41 steve Exp $"
#endif
# include "arith.h"
# include "schedule.h"
# include <assert.h>
# include <stdio.h>
vvp_arith_sum::vvp_arith_sum(vvp_ipoint_t b, unsigned w)
: base_(b), wid_(w)
{
}
void vvp_arith_sum::output_x_(bool push)
{
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base_,idx);
functor_t obj = functor_index(ptr);
if (obj->oval == 2)
continue;
obj->oval = 2;
if (push)
functor_propagate(ptr);
else
schedule_functor(ptr, 0);
}
}
void vvp_arith_sum::set(vvp_ipoint_t i, functor_t f, bool push)
{
assert(wid_ <= sizeof(unsigned long));
unsigned long sum = 0;
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base_,idx);
functor_t obj = functor_index(ptr);
unsigned ival = obj->ival;
if (ival & 0xaa) {
output_x_(push);
return;
}
unsigned tmp = 0;
if (ival & 0x01)
tmp += 1;
if (ival & 0x04)
tmp += 1;
if (ival & 0x10)
tmp += 1;
if (ival & 0x40)
tmp += 1;
sum += (tmp << idx);
}
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base_,idx);
functor_t obj = functor_index(ptr);
unsigned oval = sum & 1;
sum >>= 1;
if (obj->oval == oval)
continue;
obj->oval = oval;
if (push)
functor_propagate(ptr);
else
schedule_functor(ptr, 0);
}
}
/*
* $Log: arith.cc,v $
* Revision 1.1 2001/06/05 03:05:41 steve
* Add structural addition.
*
*/

56
vvp/arith.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef __arith_H
#define __arith_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: arith.h,v 1.1 2001/06/05 03:05:41 steve Exp $"
#endif
# include "functor.h"
/*
* This class is a mode-42 object for arithmetic sum. Inputs that come
* in cause the 4-input summation to be calculated, and output
* functors that are affected cause propagations.
*/
class vvp_arith_sum : public vvp_fobj_s {
public:
explicit vvp_arith_sum(vvp_ipoint_t b, unsigned wid);
void set(vvp_ipoint_t i, functor_t f, bool push);
private:
vvp_ipoint_t base_;
unsigned wid_;
void output_x_(bool push);
private: // not implemented
vvp_arith_sum(const vvp_arith_sum&);
vvp_arith_sum& operator= (const vvp_arith_sum&);
};
/*
* $Log: arith.h,v $
* Revision 1.1 2001/06/05 03:05:41 steve
* Add structural addition.
*
*/
#endif

View File

@ -17,9 +17,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #if !defined(WINNT)
#ident "$Id: compile.cc,v 1.70 2001/05/31 04:12:43 steve Exp $" #ident "$Id: compile.cc,v 1.71 2001/06/05 03:05:41 steve Exp $"
#endif #endif
# include "arith.h"
# include "bufif.h" # include "bufif.h"
# include "compile.h" # include "compile.h"
# include "functor.h" # include "functor.h"
@ -319,8 +320,6 @@ static void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
postpone_functor_input(ifdx, argv[idx].text, argv[idx].idx); postpone_functor_input(ifdx, argv[idx].text, argv[idx].idx);
} }
} }
free(argv);
} }
/* /*
@ -388,6 +387,7 @@ void compile_functor(char*label, char*type, unsigned argc, struct symb_s*argv)
/* Connect the inputs of this functor to the given symbols. If /* Connect the inputs of this functor to the given symbols. If
there are C<X> inputs, set the ival appropriately. */ there are C<X> inputs, set the ival appropriately. */
inputs_connect(fdx, argc, argv); inputs_connect(fdx, argc, argv);
free(argv);
/* Recalculate the output based on the given ival. if the oval /* Recalculate the output based on the given ival. if the oval
turns out to *not* be x, then schedule the functor so that turns out to *not* be x, then schedule the functor so that
@ -401,6 +401,54 @@ void compile_functor(char*label, char*type, unsigned argc, struct symb_s*argv)
free(type); free(type);
} }
void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
{
assert( wid > 0 );
if ((argc % wid) != 0) {
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
compile_errors += 1;
free(label);
return;
}
unsigned opcount = argc / wid;
if (opcount > 4) {
fprintf(stderr, "%s; .arith has too many operands.\n", label);
compile_errors += 1;
free(label);
return;
}
vvp_ipoint_t fdx = functor_allocate(wid);
define_functor_symbol(label, fdx);
vvp_arith_sum*arith = new vvp_arith_sum(fdx, wid);
struct symb_s tmp_argv[4];
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(fdx,idx);
functor_t obj = functor_index(ptr);
obj->ival = 0xaa >> 2*(4 - opcount);
obj->oval = 2;
obj->odrive0 = 6;
obj->odrive1 = 6;
obj->mode = M42;
obj->obj = arith;
#if defined(WITH_DEBUG)
obj->breakpoint = 0;
#endif
for (unsigned cdx = 0 ; cdx < opcount ; cdx += 1)
tmp_argv[cdx] = argv[idx + wid*cdx];
inputs_connect(ptr, opcount, tmp_argv);
}
free(argv);
}
void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv) void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
{ {
vvp_ipoint_t fdx = functor_allocate(1); vvp_ipoint_t fdx = functor_allocate(1);
@ -430,6 +478,7 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
/* Connect the inputs of this functor to the given symbols. If /* Connect the inputs of this functor to the given symbols. If
there are C<X> inputs, set the ival appropriately. */ there are C<X> inputs, set the ival appropriately. */
inputs_connect(fdx, argc, argv); inputs_connect(fdx, argc, argv);
free(argv);
/* This causes the output value to be set from the existing /* This causes the output value to be set from the existing
inputs, and if the output is not x, a propagation event is inputs, and if the output is not x, a propagation event is
@ -506,6 +555,7 @@ void compile_udp_functor(char*label, char*type,
} }
inputs_connect(fdx, argc, argv); inputs_connect(fdx, argc, argv);
free(argv);
} }
@ -547,6 +597,7 @@ void compile_memory_port(char *label, char *memid,
free(label); free(label);
inputs_connect(ix, argc, argv); inputs_connect(ix, argc, argv);
free(argv);
memory_port_new(mem, ix, nbits, lsb); memory_port_new(mem, ix, nbits, lsb);
} }
@ -587,6 +638,7 @@ void compile_event(char*label, char*type,
the link yet. Save the reference to be resolved later. */ the link yet. Save the reference to be resolved later. */
inputs_connect(fdx, argc, argv); inputs_connect(fdx, argc, argv);
free(argv);
obj->ival = 0xaa; obj->ival = 0xaa;
obj->oval = 2; obj->oval = 2;
@ -1210,6 +1262,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
/* /*
* $Log: compile.cc,v $ * $Log: compile.cc,v $
* Revision 1.71 2001/06/05 03:05:41 steve
* Add structural addition.
*
* Revision 1.70 2001/05/31 04:12:43 steve * Revision 1.70 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware, * Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs. * and accurately propagate strengths of outputs.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #if !defined(WINNT)
#ident "$Id: compile.h,v 1.23 2001/05/20 00:46:12 steve Exp $" #ident "$Id: compile.h,v 1.24 2001/06/05 03:05:41 steve Exp $"
#endif #endif
# include <stdio.h> # include <stdio.h>
@ -69,6 +69,12 @@ extern void compile_functor(char*label, char*type,
extern void compile_resolver(char*label, char*type, extern void compile_resolver(char*label, char*type,
unsigned argc, struct symb_s*argv); unsigned argc, struct symb_s*argv);
/*
* This is called by the parser to make an adder.
*/
extern void compile_arith_sum(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_vpi_symbol(const char*label, vpiHandle obj); extern void compile_vpi_symbol(const char*label, vpiHandle obj);
extern vpiHandle compile_vpi_lookup(const char*label); extern vpiHandle compile_vpi_lookup(const char*label);
@ -182,6 +188,9 @@ extern void compile_net(char*label, char*name,
/* /*
* $Log: compile.h,v $ * $Log: compile.h,v $
* Revision 1.24 2001/06/05 03:05:41 steve
* Add structural addition.
*
* Revision 1.23 2001/05/20 00:46:12 steve * Revision 1.23 2001/05/20 00:46:12 steve
* Add support for system function calls. * Add support for system function calls.
* *

61
vvp/examples/sum.vvp Normal file
View File

@ -0,0 +1,61 @@
: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 shows how to wire up a simple adder. The code below is
; like what might be generated from the Verilog:
;
; module main;
; reg [3:0] A, B;
; wire [3:0] Q = A + B;
:
: initial begin
; A = 2;
; B = 3;
; #1 $display("%b %b = %b", A, B, Q);
; end
; endmodule
;
; Notice the use of the .arith/sum statment, including the specification
; of the width (4 bits) and the order that the bits of the operands are
; passed to the statement.
S_main .scope "main";
A .var "A", 3, 0;
B .var "B", 3, 0;
add .arith/sum 4, A[0], A[1], A[2], A[3], B[0], B[1], B[2], B[3];
Q .net "Q", 3, 0, add[0], add[1], add[2], add[3];
start %set A[0], 0;
%set A[1], 1;
%set A[2], 0;
%set A[3], 0;
%set B[0], 1;
%set B[1], 1;
%set B[2], 0;
%set B[3], 0;
%delay 1;
%vpi_call "$display", "%b + %b == %b", A, B, Q;
%end;
.thread start;

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.18 2001/05/20 00:46:12 steve Exp $" #ident "$Id: lexor.lex,v 1.19 2001/06/05 03:05:41 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -65,6 +65,7 @@
/* These are some keywords that are recognized. */ /* These are some keywords that are recognized. */
".arith/sum" { return K_ARITH_SUM; }
".event" { return K_EVENT; } ".event" { return K_EVENT; }
".event/or" { return K_EVENT_OR; } ".event/or" { return K_EVENT_OR; }
".functor" { return K_FUNCTOR; } ".functor" { return K_FUNCTOR; }
@ -140,6 +141,9 @@ int yywrap()
/* /*
* $Log: lexor.lex,v $ * $Log: lexor.lex,v $
* Revision 1.19 2001/06/05 03:05:41 steve
* Add structural addition.
*
* Revision 1.18 2001/05/20 00:46:12 steve * Revision 1.18 2001/05/20 00:46:12 steve
* Add support for system function calls. * Add support for system function calls.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #if !defined(WINNT)
#ident "$Id: parse.y,v 1.27 2001/05/20 00:46:12 steve Exp $" #ident "$Id: parse.y,v 1.28 2001/06/05 03:05:41 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -54,7 +54,8 @@ extern FILE*yyin;
}; };
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_RESOLV K_SCOPE K_THREAD %token K_ARITH_SUM K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S
%token K_RESOLV K_SCOPE K_THREAD
%token K_UDP K_UDP_C K_UDP_S %token K_UDP K_UDP_C K_UDP_S
%token K_MEM K_MEM_P K_MEM_I %token K_MEM K_MEM_P K_MEM_I
%token K_VAR K_VAR_S K_vpi_call K_vpi_func K_disable K_fork %token K_VAR K_VAR_S K_vpi_call K_vpi_func K_disable K_fork
@ -152,6 +153,14 @@ statement
compile_resolver($1, $3, obj.cnt, obj.vect); compile_resolver($1, $3, obj.cnt, obj.vect);
} }
/* Arithmetic statements generate functor arrays of a given width
that take like size input vectors. */
| T_LABEL K_ARITH_SUM T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_sum($1, $3, obj.cnt, obj.vect);
}
/* Event statements take a label, a type (the first T_SYMBOL) and a /* Event statements take a label, a type (the first T_SYMBOL) and a
list of inputs. If the type is instead a string, then we have a list of inputs. If the type is instead a string, then we have a
@ -444,6 +453,9 @@ int compile_design(const char*path)
/* /*
* $Log: parse.y,v $ * $Log: parse.y,v $
* Revision 1.28 2001/06/05 03:05:41 steve
* Add structural addition.
*
* Revision 1.27 2001/05/20 00:46:12 steve * Revision 1.27 2001/05/20 00:46:12 steve
* Add support for system function calls. * Add support for system function calls.
* *