Functor values and propagation.
This commit is contained in:
parent
cb65ee5e00
commit
cbc3be0304
|
|
@ -8,4 +8,5 @@ lexor.cc
|
|||
parse.cc
|
||||
parse.cc.output
|
||||
parse.h
|
||||
tables.cc
|
||||
vvp
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# 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
|
||||
|
|
@ -52,7 +52,7 @@ distclean: clean
|
|||
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 \
|
||||
codes.o vthread.o schedule.o
|
||||
codes.o vthread.o schedule.o tables.o
|
||||
|
||||
vvp: $O
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o vvp $O
|
||||
|
|
@ -63,6 +63,10 @@ vvp: $O
|
|||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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.
|
||||
|
||||
|
|
@ -59,15 +59,20 @@ label is required for functors.
|
|||
|
||||
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
|
||||
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
|
||||
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
|
||||
represented by functors.
|
||||
represented by functors, which perform the very basic task of
|
||||
combining up to four inputs down to one output.
|
||||
|
||||
VARIABLE STATEMENTS:
|
||||
|
||||
|
|
@ -111,6 +116,43 @@ This statement creates a thread with a starting address at the
|
|||
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
|
||||
|
||||
Threads run executable code, much like a processor executes machine
|
||||
|
|
|
|||
|
|
@ -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.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
|
||||
|
||||
# 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. 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();
|
||||
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(label);
|
||||
free(type);
|
||||
|
|
@ -298,12 +312,20 @@ void compile_thread(char*start_sym)
|
|||
void compile_variable(char*label)
|
||||
{
|
||||
vvp_ipoint_t fdx = functor_allocate();
|
||||
functor_t obj = functor_index(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* When parsing is otherwise complete, this function is called to do
|
||||
* the final stuff. Clean up deferred linking here.
|
||||
*/
|
||||
void compile_cleanup(void)
|
||||
{
|
||||
struct resolv_list_s*tmp_list = resolv_list;
|
||||
|
|
@ -313,12 +335,18 @@ void compile_cleanup(void)
|
|||
struct resolv_list_s*res = tmp_list;
|
||||
tmp_list = res->next;
|
||||
|
||||
/* Get the addressed functor object and select the input
|
||||
port that needs resolution. */
|
||||
functor_t obj = functor_index(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);
|
||||
|
||||
if (tmp != 0) {
|
||||
/* The symbol is defined, link the functor input
|
||||
to the resolved output. */
|
||||
functor_t fport = functor_index(tmp);
|
||||
obj->port[idx] = fport->out;
|
||||
fport->out = res->port;
|
||||
|
|
@ -353,6 +381,9 @@ void compile_dump(FILE*fd)
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.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
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -47,7 +47,7 @@ extern void compile_cleanup(void);
|
|||
* of the functor. The compile should match those port parameters up
|
||||
* 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);
|
||||
|
||||
|
||||
|
|
@ -97,6 +97,9 @@ extern void compile_dump(FILE*fd);
|
|||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -17,10 +17,11 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "functor.h"
|
||||
# include "schedule.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,
|
||||
* if we overrun a chunk or an index, we need to allocate the needed
|
||||
* bits first.
|
||||
|
|
@ -95,7 +96,11 @@ vvp_ipoint_t functor_allocate(void)
|
|||
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)
|
||||
{
|
||||
point /= 4;
|
||||
|
|
@ -112,6 +117,57 @@ functor_t functor_index(vvp_ipoint_t point)
|
|||
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)
|
||||
{
|
||||
|
|
@ -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 $
|
||||
* Revision 1.2 2001/03/11 22:42:11 steve
|
||||
* Functor values and propagation.
|
||||
*
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "pointers.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
|
||||
|
|
@ -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
|
||||
* value zero (0). In this way, an output can fan out as wide as the
|
||||
* original design requires.
|
||||
*
|
||||
* Value Encoding
|
||||
* 1'b0 : 00
|
||||
* 1'b1 : 01
|
||||
* 1'bx : 10
|
||||
* 1'bz : 11
|
||||
*/
|
||||
|
||||
struct functor_s {
|
||||
|
|
@ -48,6 +54,9 @@ struct functor_s {
|
|||
vvp_ipoint_t out;
|
||||
/* These are the input ports. */
|
||||
vvp_ipoint_t port[4];
|
||||
/* These are the input values. */
|
||||
unsigned char ival;
|
||||
unsigned char oval;
|
||||
};
|
||||
|
||||
typedef struct functor_s *functor_t;
|
||||
|
|
@ -66,6 +75,20 @@ extern void functor_init(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
|
||||
* 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 const unsigned char ft_AND[];
|
||||
extern const unsigned char ft_OR[];
|
||||
extern const unsigned char ft_var[];
|
||||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
10
vvp/parse.y
10
vvp/parse.y
|
|
@ -50,12 +50,12 @@ statement
|
|||
/* Functor statements define functors. The functor must have a
|
||||
label and a type name, and may have operands. */
|
||||
|
||||
: T_LABEL K_FUNCTOR T_SYMBOL ',' symbols ';'
|
||||
{ struct textv_s obj = $5;
|
||||
compile_functor($1, $3, obj.cnt, obj.text);
|
||||
: T_LABEL K_FUNCTOR T_SYMBOL ',' T_NUMBER ',' symbols ';'
|
||||
{ struct textv_s obj = $7;
|
||||
compile_functor($1, $3, $5, obj.cnt, obj.text);
|
||||
}
|
||||
| T_LABEL K_FUNCTOR T_SYMBOL ';'
|
||||
{ compile_functor($1, $3, 0, 0); }
|
||||
| T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';'
|
||||
{ compile_functor($1, $3, $5, 0, 0); }
|
||||
|
||||
/* Instructions may have a label, and have zero or more
|
||||
operands. The meaning of and restrictions on the operands depends
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "schedule.h"
|
||||
# include "functor.h"
|
||||
# include "vthread.h"
|
||||
# include <malloc.h>
|
||||
# include <assert.h>
|
||||
|
|
@ -28,12 +29,19 @@
|
|||
struct event_s {
|
||||
unsigned delay;
|
||||
|
||||
union {
|
||||
vthread_t thr;
|
||||
vvp_ipoint_t fun;
|
||||
};
|
||||
unsigned val :2;
|
||||
unsigned type :2;
|
||||
|
||||
struct event_s*next;
|
||||
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;
|
||||
|
||||
|
|
@ -91,6 +99,7 @@ void schedule_vthread(vthread_t thr, unsigned delay)
|
|||
|
||||
cur->delay = delay;
|
||||
cur->thr = thr;
|
||||
cur->type = TYPE_THREAD;
|
||||
|
||||
schedule_event_(cur);
|
||||
}
|
||||
|
|
@ -102,10 +111,25 @@ void schedule_functor(vvp_ipoint_t fun, unsigned delay)
|
|||
|
||||
cur->delay = delay;
|
||||
cur->fun = fun;
|
||||
cur->type = TYPE_PROP;
|
||||
|
||||
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;
|
||||
|
||||
void schedule_simulate(void)
|
||||
|
|
@ -127,11 +151,19 @@ void schedule_simulate(void)
|
|||
printf("TIME: %u\n", schedule_time);
|
||||
}
|
||||
|
||||
if (cur->thr) {
|
||||
switch (cur->type) {
|
||||
case TYPE_THREAD:
|
||||
vthread_run(cur->thr);
|
||||
break;
|
||||
|
||||
} else if (cur->fun) {
|
||||
/* XXXX not implemented yet */
|
||||
case TYPE_PROP:
|
||||
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 $
|
||||
* Revision 1.2 2001/03/11 22:42:11 steve
|
||||
* Functor values and propagation.
|
||||
*
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,20 +19,43 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "vthread.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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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
|
||||
|
||||
# include "vthread.h"
|
||||
# include "codes.h"
|
||||
# include "schedule.h"
|
||||
# include "functor.h"
|
||||
# include <assert.h>
|
||||
|
||||
struct vthread_s {
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* $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
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue