Functor values and propagation.

This commit is contained in:
steve 2001-03-11 22:42:11 +00:00
parent cb65ee5e00
commit cbc3be0304
13 changed files with 448 additions and 32 deletions

View File

@ -8,4 +8,5 @@ lexor.cc
parse.cc parse.cc
parse.cc.output parse.cc.output
parse.h parse.h
tables.cc
vvp vvp

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.1 2001/03/11 00:29:38 steve Exp $" #ident "$Id: Makefile.in,v 1.2 2001/03/11 22:42:11 steve Exp $"
# #
# #
SHELL = /bin/sh SHELL = /bin/sh
@ -52,7 +52,7 @@ distclean: clean
rm -f config.h Makefile config.cache config.log config.status rm -f config.h Makefile config.cache config.log config.status
O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \ O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \
codes.o vthread.o schedule.o codes.o vthread.o schedule.o tables.o
vvp: $O vvp: $O
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(CXX) $(CXXFLAGS) $(LDFLAGS) -o vvp $O
@ -63,6 +63,10 @@ vvp: $O
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d mv $*.d dep/$*.d
tables.cc: draw_tt.c
$(CC) -o draw_tt draw_tt.c
./draw_tt > tables.cc
rm draw_tt
lexor.o: lexor.cc parse.h lexor.o: lexor.cc parse.h

View File

@ -19,7 +19,7 @@ Every statement is terminated by a semicolon. The semicolon is also
the start of a comment line, so you can put comment text after the the start of a comment line, so you can put comment text after the
semicolon that terminates a statement. Like so: semicolon that terminates a statement. Like so:
Label .functor and, x, y ; This is a comment. Label .functor and, 0x5a, x, y ; This is a comment.
The semicolon is required, whether the comment is there or not. The semicolon is required, whether the comment is there or not.
@ -59,15 +59,20 @@ label is required for functors.
The general syntax of a functor is: The general syntax of a functor is:
<label> .functor <type> [, symbol_list] <label> .functor <type>, <init> [, symbol_list]
The symbol list is 0-4 names of labels of other functors. These The symbol list is 0-4 names of labels of other functors. These
connect inputs of the functor of the statement to the output of other connect inputs of the functor of the statement to the output of other
functors. The type is the label of a .ftype statement elsewhere in the functors. The type is the label of a .ftype statement elsewhere in the
program. The references .ftype describes the behavoir of the functor. program. The references .ftype describes the behavoir of the
functor.
The <init> value is the 8-bit initial value of the 4 input ports. The
LSB is port 0, and the MSB port 3.
Almost all of the structural aspects of a simulation can be Almost all of the structural aspects of a simulation can be
represented by functors. represented by functors, which perform the very basic task of
combining up to four inputs down to one output.
VARIABLE STATEMENTS: VARIABLE STATEMENTS:
@ -111,6 +116,43 @@ This statement creates a thread with a starting address at the
instruction given by <symbol>. instruction given by <symbol>.
TRUTH TABLES
The logic that a functor represents is expressed as a truth table. The
functor has four inputs and one output. Each input and output has one
of four possible values (0, 1, x and z) so two bits are needed to
represent them. So the input of the functor is 8 bits, and the output
2 bits. A complete lookup table for generating the 2-bit output from
an 8-bit input is 512 bits. That can be packed into 64 bytes. This is
small enough that the table should take less space then the code to
implement the logic.
To implement the truth table, we need to assign 2-bit encodings for
the 4-value signals. I choose, pseudo-randomly, the following
encoding:
1'b0 : 00
1'b1 : 01
1'bx : 10
1'bz : 11
The table is an array of 64 bytes, each byte holding 4 2-bit
outputs. Construct a 6-bit byte address with inputs 1, 2 and 3 like
so:
332211
The input 0 2-bits can then be used to select which of the 4 2-bit
pairs in the 8-bit byte are the output:
MSB -> zzxx1100 <- LSB
A complete truth table, then is described as 64 8-bit bytes.
The vvp engine includes truth tables for the primitive gate types, so
none needs to be given by the programmer. It is sufficient to name the
type to get that truth table.
EXECUTABLE INSTRUCTIONS EXECUTABLE INSTRUCTIONS
Threads run executable code, much like a processor executes machine Threads run executable code, much like a processor executes machine

View File

@ -17,7 +17,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.cc,v 1.1 2001/03/11 00:29:38 steve Exp $" #ident "$Id: compile.cc,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "compile.h" # include "compile.h"
@ -125,7 +125,8 @@ void compile_init(void)
* functor, and map the name to the vvp_ipoint_t address for the * functor, and map the name to the vvp_ipoint_t address for the
* functor. Also resolve the inputs to the functor. * functor. Also resolve the inputs to the functor.
*/ */
void compile_functor(char*label, char*type, unsigned argc, char**argv) void compile_functor(char*label, char*type, unsigned init,
unsigned argc, char**argv)
{ {
vvp_ipoint_t fdx = functor_allocate(); vvp_ipoint_t fdx = functor_allocate();
functor_t obj = functor_index(fdx); functor_t obj = functor_index(fdx);
@ -163,6 +164,19 @@ void compile_functor(char*label, char*type, unsigned argc, char**argv)
} }
} }
obj->ival = init;
obj->oval = 2;
if (strcmp(type, "OR") == 0) {
obj->table = ft_OR;
} else if (strcmp(type, "AND") == 0) {
obj->table = ft_AND;
} else {
yyerror("invalid functor type.");
}
free(argv); free(argv);
free(label); free(label);
free(type); free(type);
@ -298,12 +312,20 @@ void compile_thread(char*start_sym)
void compile_variable(char*label) void compile_variable(char*label)
{ {
vvp_ipoint_t fdx = functor_allocate(); vvp_ipoint_t fdx = functor_allocate();
functor_t obj = functor_index(fdx);
sym_set_value(sym_functors, label, fdx); sym_set_value(sym_functors, label, fdx);
functor_t obj = functor_index(fdx);
obj->table = ft_var;
obj->ival = 0x22;
obj->oval = 0x02;
free(label); free(label);
} }
/*
* When parsing is otherwise complete, this function is called to do
* the final stuff. Clean up deferred linking here.
*/
void compile_cleanup(void) void compile_cleanup(void)
{ {
struct resolv_list_s*tmp_list = resolv_list; struct resolv_list_s*tmp_list = resolv_list;
@ -313,12 +335,18 @@ void compile_cleanup(void)
struct resolv_list_s*res = tmp_list; struct resolv_list_s*res = tmp_list;
tmp_list = res->next; tmp_list = res->next;
/* Get the addressed functor object and select the input
port that needs resolution. */
functor_t obj = functor_index(res->port); functor_t obj = functor_index(res->port);
unsigned idx = ipoint_port(res->port); unsigned idx = ipoint_port(res->port);
/* Try again to look up the symbol that was not defined
the first time around. */
vvp_ipoint_t tmp = sym_get_value(sym_functors, res->source); vvp_ipoint_t tmp = sym_get_value(sym_functors, res->source);
if (tmp != 0) { if (tmp != 0) {
/* The symbol is defined, link the functor input
to the resolved output. */
functor_t fport = functor_index(tmp); functor_t fport = functor_index(tmp);
obj->port[idx] = fport->out; obj->port[idx] = fport->out;
fport->out = res->port; fport->out = res->port;
@ -353,6 +381,9 @@ void compile_dump(FILE*fd)
/* /*
* $Log: compile.cc,v $ * $Log: compile.cc,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:38 steve * Revision 1.1 2001/03/11 00:29:38 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

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.1 2001/03/11 00:29:38 steve Exp $" #ident "$Id: compile.h,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include <stdio.h> # include <stdio.h>
@ -47,7 +47,7 @@ extern void compile_cleanup(void);
* of the functor. The compile should match those port parameters up * of the functor. The compile should match those port parameters up
* to existing functors to manage the linking. * to existing functors to manage the linking.
*/ */
extern void compile_functor(char*label, char*type, extern void compile_functor(char*label, char*type, unsigned init,
unsigned argc, char**argv); unsigned argc, char**argv);
@ -97,6 +97,9 @@ extern void compile_dump(FILE*fd);
/* /*
* $Log: compile.h,v $ * $Log: compile.h,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:38 steve * Revision 1.1 2001/03/11 00:29:38 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

107
vvp/draw_tt.c Normal file
View File

@ -0,0 +1,107 @@
/*
* 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: draw_tt.c,v 1.1 2001/03/11 22:42:11 steve Exp $"
#endif
# include <stdio.h>
static void draw_AND(void)
{
unsigned i0, i1, i2, i3;
printf("const unsigned char ft_AND[64] = {");
for (i3 = 0 ; i3 < 4 ; i3 += 1)
for (i2 = 0 ; i2 < 4 ; i2 += 1) {
printf("\n ");
for (i1 = 0 ; i1 < 4 ; i1 += 1) {
unsigned idx = (i3 << 4) | (i2 << 2) | i1;
unsigned char byte = 0;
for (i0 = 0 ; i0 < 4 ; i0 += 1) {
unsigned val;
if ((i0 == 0) || (i1 == 0) ||
(i2 == 0) || (i3 == 0))
val = 0;
else if ((i0 == 1) && (i1 == 1) &&
(i2 == 1) && (i3 == 1))
val = 1;
else
val = 2;
byte |= val << (i0*2);
}
printf("0x%02x, ", byte);
}
}
printf("};\n");
}
static void draw_OR(void)
{
unsigned i0, i1, i2, i3;
printf("const unsigned char ft_OR[64] = {");
for (i3 = 0 ; i3 < 4 ; i3 += 1)
for (i2 = 0 ; i2 < 4 ; i2 += 1) {
printf("\n ");
for (i1 = 0 ; i1 < 4 ; i1 += 1) {
unsigned idx = (i3 << 4) | (i2 << 2) | i1;
unsigned char byte = 0;
for (i0 = 0 ; i0 < 4 ; i0 += 1) {
unsigned val;
if ((i0 == 1) || (i1 == 1) ||
(i2 == 1) || (i3 == 1))
val = 1;
else if ((i0 == 0) && (i1 == 0) &&
(i2 == 0) && (i3 == 0))
val = 0;
else
val = 2;
byte |= val << (i0*2);
}
printf("0x%02x, ", byte);
}
}
printf("};\n");
}
main()
{
printf("# include \"functor.h\"\n");
draw_AND();
draw_OR();
return 0;
}
/*
* $Log: draw_tt.c,v $
* Revision 1.1 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
*/

View File

@ -17,10 +17,11 @@
* 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: functor.cc,v 1.1 2001/03/11 00:29:38 steve Exp $" #ident "$Id: functor.cc,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "functor.h" # include "functor.h"
# include "schedule.h"
# include <assert.h> # include <assert.h>
/* /*
@ -68,7 +69,7 @@ void functor_init(void)
} }
/* /*
* Allocate normall is just a matter of incrementing the functor_count * Allocate normally is just a matter of incrementing the functor_count
* and returning a pointer to the next unallocated functor. However, * and returning a pointer to the next unallocated functor. However,
* if we overrun a chunk or an index, we need to allocate the needed * if we overrun a chunk or an index, we need to allocate the needed
* bits first. * bits first.
@ -95,7 +96,11 @@ vvp_ipoint_t functor_allocate(void)
return res * 4; return res * 4;
} }
/*
* Given a vvp_ipoint_t pointer, return a pointer to the detailed
* functor structure. This does not use the low 2 bits, which address
* a specific port of the functor.
*/
functor_t functor_index(vvp_ipoint_t point) functor_t functor_index(vvp_ipoint_t point)
{ {
point /= 4; point /= 4;
@ -112,6 +117,57 @@ functor_t functor_index(vvp_ipoint_t point)
return functor_table[point]->table[index1]->table + index0; return functor_table[point]->table[index1]->table + index0;
} }
/*
* Set the addressed bit of the functor, and recalculate the
* output. If the output changes any, then generate the necessary
* propagation events to pass the output on.
*/
void functor_set(vvp_ipoint_t ptr, unsigned bit)
{
functor_t fp = functor_index(ptr);
unsigned pp = ipoint_port(ptr);
assert(fp);
assert(fp->table);
/* Change the bits of the input. */
static const unsigned char mask_table[4] = { 0xfc, 0xf3, 0xcf, 0x3f };
unsigned char mask = mask_table[pp];
fp->ival = (fp->ival & mask) | (bit << (2*pp));
/* Locate the new output value in the table. */
unsigned char out = fp->table[fp->ival >> 2];
out >>= 2 * (fp->ival&0x03);
out &= 0x03;
/* If the output changes, then create a propagation event. */
if (out != fp->oval) {
fp->oval = out;
schedule_functor(ptr, 0);
}
}
/*
* This function is used by the scheduler to implement the propagation
* event. The input is the pointer to the functor who's output is to
* be propagated. Pass the output to the inputs of all the connected
* functors.
*/
void functor_propagate(vvp_ipoint_t ptr)
{
functor_t fp = functor_index(ptr);
unsigned char oval = fp->oval;
printf("functor %lx becomes %u\n", ptr, oval);
vvp_ipoint_t idx = fp->out;
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);
functor_set(idx, oval);
idx = next;
}
}
void functor_dump(FILE*fd) void functor_dump(FILE*fd)
{ {
@ -123,8 +179,35 @@ void functor_dump(FILE*fd)
} }
} }
/*
* The variable functor is special. This is the truth table for it.
*/
const unsigned char ft_var[16] = {
0xe4, /* 0 0: 11, 10, 01, 00 */
0xe4, /* 0 1: 11, 10, 01, 00 */
0xe4, /* 0 x: 11, 10, 01, 00 */
0xe4, /* 0 z: 11, 10, 01, 00 */
0x00, /* 1 0: 00, 00, 00, 00 */
0x55, /* 1 1: 01, 01, 01, 01 */
0xaa, /* 1 x: 10, 10, 10, 10 */
0xff, /* 1 z: 11, 11, 11, 11 */
0xe4,
0xe4,
0xe4,
0xe4,
0xe4,
0xe4,
0xe4,
0xe4
};
/* /*
* $Log: functor.cc,v $ * $Log: functor.cc,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:38 steve * Revision 1.1 2001/03/11 00:29:38 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

View File

@ -19,13 +19,13 @@
* 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: functor.h,v 1.1 2001/03/11 00:29:38 steve Exp $" #ident "$Id: functor.h,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "pointers.h" # include "pointers.h"
# include <stdio.h> # include <stdio.h>
typedef struct vvp_truth_s*vvp_truth_t; typedef const unsigned char*vvp_truth_t;
/* /*
* The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits * The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits
@ -39,6 +39,12 @@ typedef struct vvp_truth_s*vvp_truth_t;
* port, and so on. The last .port[x] contains the null vvp_ipoint_t * port, and so on. The last .port[x] contains the null vvp_ipoint_t
* value zero (0). In this way, an output can fan out as wide as the * value zero (0). In this way, an output can fan out as wide as the
* original design requires. * original design requires.
*
* Value Encoding
* 1'b0 : 00
* 1'b1 : 01
* 1'bx : 10
* 1'bz : 11
*/ */
struct functor_s { struct functor_s {
@ -48,6 +54,9 @@ struct functor_s {
vvp_ipoint_t out; vvp_ipoint_t out;
/* These are the input ports. */ /* These are the input ports. */
vvp_ipoint_t port[4]; vvp_ipoint_t port[4];
/* These are the input values. */
unsigned char ival;
unsigned char oval;
}; };
typedef struct functor_s *functor_t; typedef struct functor_s *functor_t;
@ -66,6 +75,20 @@ extern void functor_init(void);
*/ */
extern vvp_ipoint_t functor_allocate(void); extern vvp_ipoint_t functor_allocate(void);
/*
* functor_set sets the addressed input to the specified value, and
* calculates a new output value. If there is any propagation to do,
* propagation events are created.
*/
extern void functor_set(vvp_ipoint_t point, unsigned val);
/*
* When a propagation event happens, this function is called with the
* address of the affected functor. It propagates the output to all
* the inputs it is connected to, creating new propagation event on
* the way.
*/
extern void functor_propagate(vvp_ipoint_t ptr);
/* /*
* Given an ipoint_t pointer, return a C pointer to the functor. This * Given an ipoint_t pointer, return a C pointer to the functor. This
* is like a pointer dereference. The point parameter must have been * is like a pointer dereference. The point parameter must have been
@ -78,8 +101,16 @@ extern functor_t functor_index(vvp_ipoint_t point);
*/ */
extern void functor_dump(FILE*fd); extern void functor_dump(FILE*fd);
extern const unsigned char ft_AND[];
extern const unsigned char ft_OR[];
extern const unsigned char ft_var[];
/* /*
* $Log: functor.h,v $ * $Log: functor.h,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:38 steve * Revision 1.1 2001/03/11 00:29:38 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

30
vvp/functor.txt Normal file
View File

@ -0,0 +1,30 @@
FUNCTOR DETAILS
The README.txt describes the .functor statement and how that creates a
functor. It also makes passing mention of how the functor is connected
up to the netlist. This document describes in detail how a functor is
supposed to act. See also the functor.h header file and the functor.cc
source file.
The current values of the inputs are stored in a single 8-bit byte,
2-bits per value. This is the ``ival'' member. The input of a functor
gets set by propagation events, assign events or %set
instructions.
The output value is stored in two bits of the functor. The current
output is used to detect edges when the input changes. Whenever an
input is set, a new output is calculated and compared with the current
output. If the current output is the same as the new output, then the
operation is complete and propagation stops.
If after a set the output changes, the current output is changed to
the new output, and a propagation event is created. This propagation
event is given a pointer to the functor that changed, and *not* simply
the contents of the out port. The event is scheduled for a delay that
is the propagation delay for the functor.
A propagation event is the only way that the output of a functor is
moved to the input of another functor. The propagation event, which is
given a pointer to the functor to propagate, looks at the output list
and sets the listed inputs to the current value of the output.

View File

@ -50,12 +50,12 @@ statement
/* Functor statements define functors. The functor must have a /* Functor statements define functors. The functor must have a
label and a type name, and may have operands. */ label and a type name, and may have operands. */
: T_LABEL K_FUNCTOR T_SYMBOL ',' symbols ';' : T_LABEL K_FUNCTOR T_SYMBOL ',' T_NUMBER ',' symbols ';'
{ struct textv_s obj = $5; { struct textv_s obj = $7;
compile_functor($1, $3, obj.cnt, obj.text); compile_functor($1, $3, $5, obj.cnt, obj.text);
} }
| T_LABEL K_FUNCTOR T_SYMBOL ';' | T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';'
{ compile_functor($1, $3, 0, 0); } { compile_functor($1, $3, $5, 0, 0); }
/* Instructions may have a label, and have zero or more /* Instructions may have a label, and have zero or more
operands. The meaning of and restrictions on the operands depends operands. The meaning of and restrictions on the operands depends

View File

@ -17,10 +17,11 @@
* 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: schedule.cc,v 1.1 2001/03/11 00:29:39 steve Exp $" #ident "$Id: schedule.cc,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "schedule.h" # include "schedule.h"
# include "functor.h"
# include "vthread.h" # include "vthread.h"
# include <malloc.h> # include <malloc.h>
# include <assert.h> # include <assert.h>
@ -28,12 +29,19 @@
struct event_s { struct event_s {
unsigned delay; unsigned delay;
vthread_t thr; union {
vvp_ipoint_t fun; vthread_t thr;
vvp_ipoint_t fun;
};
unsigned val :2;
unsigned type :2;
struct event_s*next; struct event_s*next;
struct event_s*last; struct event_s*last;
}; };
const unsigned TYPE_THREAD = 0;
const unsigned TYPE_PROP = 1;
const unsigned TYPE_ASSIGN = 2;
static struct event_s* list = 0; static struct event_s* list = 0;
@ -91,6 +99,7 @@ void schedule_vthread(vthread_t thr, unsigned delay)
cur->delay = delay; cur->delay = delay;
cur->thr = thr; cur->thr = thr;
cur->type = TYPE_THREAD;
schedule_event_(cur); schedule_event_(cur);
} }
@ -102,10 +111,25 @@ void schedule_functor(vvp_ipoint_t fun, unsigned delay)
cur->delay = delay; cur->delay = delay;
cur->fun = fun; cur->fun = fun;
cur->type = TYPE_PROP;
schedule_event_(cur); schedule_event_(cur);
} }
void schedule_assign(vvp_ipoint_t fun, unsigned char val, unsigned delay)
{
struct event_s*cur = (struct event_s*)
calloc(1, sizeof(struct event_s));
cur->delay = delay;
cur->fun = fun;
cur->val = val;
cur->type= TYPE_ASSIGN;
schedule_event_(cur);
}
static unsigned long schedule_time; static unsigned long schedule_time;
void schedule_simulate(void) void schedule_simulate(void)
@ -127,11 +151,19 @@ void schedule_simulate(void)
printf("TIME: %u\n", schedule_time); printf("TIME: %u\n", schedule_time);
} }
if (cur->thr) { switch (cur->type) {
case TYPE_THREAD:
vthread_run(cur->thr); vthread_run(cur->thr);
break;
} else if (cur->fun) { case TYPE_PROP:
/* XXXX not implemented yet */ printf("Propagate %p\n", cur->fun);
functor_propagate(cur->fun);
break;
case TYPE_ASSIGN:
functor_set(cur->fun, cur->val);
break;
} }
@ -141,6 +173,9 @@ void schedule_simulate(void)
/* /*
* $Log: schedule.cc,v $ * $Log: schedule.cc,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:39 steve * Revision 1.1 2001/03/11 00:29:39 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

View File

@ -19,20 +19,43 @@
* 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: schedule.h,v 1.1 2001/03/11 00:29:39 steve Exp $" #ident "$Id: schedule.h,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "vthread.h" # include "vthread.h"
# include "pointers.h" # include "pointers.h"
/*
* This causes a thread to be scheduled for execution. The schedule
* puts the event into the event queue after any existing events for a
* given time step. The delay is a relative time.
*/
extern void schedule_vthread(vthread_t thr, unsigned delay); extern void schedule_vthread(vthread_t thr, unsigned delay);
/*
* Create a propagation event. The fun parameter points to the functor
* to have its output propagated, and the delay is the delay to
* schedule the propagation.
*/
extern void schedule_functor(vvp_ipoint_t fun, unsigned delay); extern void schedule_functor(vvp_ipoint_t fun, unsigned delay);
/*
* Create an assignment event. The val passed here will be assigned to
* the specified input when the delay times out.
*/
extern void schedule_assign(vvp_ipoint_t fun, unsigned char val,
unsigned delay);
/*
* This runs the simulator. It runs until all the functors run out.
*/
extern void schedule_simulate(void); extern void schedule_simulate(void);
/* /*
* $Log: schedule.h,v $ * $Log: schedule.h,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:39 steve * Revision 1.1 2001/03/11 00:29:39 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *

View File

@ -17,12 +17,14 @@
* 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: vthread.cc,v 1.1 2001/03/11 00:29:39 steve Exp $" #ident "$Id: vthread.cc,v 1.2 2001/03/11 22:42:11 steve Exp $"
#endif #endif
# include "vthread.h" # include "vthread.h"
# include "codes.h" # include "codes.h"
# include "schedule.h" # include "schedule.h"
# include "functor.h"
# include <assert.h>
struct vthread_s { struct vthread_s {
/* This is the program counter. */ /* This is the program counter. */
@ -59,13 +61,23 @@ void vthread_run(vthread_t thr)
bool of_ASSIGN(vthread_t thr, vvp_code_t cp) bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
{ {
printf("thread %p: %%assign\n"); printf("thread %p: %%assign\n", thr);
unsigned char bit_val = 3;
if ((cp->bit_idx & ~0x3) == 0x0) {
bit_val = cp->bit_idx&3;
} else {
printf("XXXX bit_idx out of range?\n");
}
schedule_assign(cp->iptr, bit_val, cp->number);
return true; return true;
} }
bool of_DELAY(vthread_t thr, vvp_code_t cp) bool of_DELAY(vthread_t thr, vvp_code_t cp)
{ {
printf("thread %p: %%delay %u\n", thr, cp->number); printf("thread %p: %%delay %lu\n", thr, cp->number);
schedule_vthread(thr, cp->number); schedule_vthread(thr, cp->number);
return false; return false;
} }
@ -83,12 +95,26 @@ bool of_NOOP(vthread_t thr, vvp_code_t cp)
bool of_SET(vthread_t thr, vvp_code_t cp) bool of_SET(vthread_t thr, vvp_code_t cp)
{ {
printf("thread %p: %%set\n"); printf("thread %p: %%set %lu, %u\n", thr, cp->iptr, cp->bit_idx);
unsigned char bit_val = 3;
if ((cp->bit_idx & ~0x3) == 0x0) {
bit_val = cp->bit_idx&3;
} else {
printf("XXXX bit_idx out of range?\n");
}
functor_set(cp->iptr, bit_val);
return true; return true;
} }
/* /*
* $Log: vthread.cc,v $ * $Log: vthread.cc,v $
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*
* Revision 1.1 2001/03/11 00:29:39 steve * Revision 1.1 2001/03/11 00:29:39 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *