Redo and simplify UDP behavior.
This commit is contained in:
parent
8b5f62a5e5
commit
62c9f39297
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.17 2001/04/25 04:35:05 steve Exp $
|
||||
* $Id: README.txt,v 1.18 2001/04/26 03:10:55 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -125,13 +125,23 @@ the output becomes 1'bx.
|
|||
The output state can be specified as "0", "1", or "x". Sequential
|
||||
UDPs may also have "-": no change.
|
||||
|
||||
An input or current output state can be "1", "0", "x", or "?" (don't
|
||||
care). For Sequential UDPs, at most one input state specification may
|
||||
be replaced by an edge specification. Valid edges are:
|
||||
An input or current output state can be
|
||||
|
||||
"1": 1
|
||||
"0": 0
|
||||
"x": x
|
||||
"b": 1, 0
|
||||
"h": 1, x
|
||||
"l": 0, x
|
||||
"?": 1, 0, x
|
||||
|
||||
For Sequential UDPs, at most one input state specification may be
|
||||
replaced by an edge specification. Valid edges are:
|
||||
|
||||
"*": (??) "_": (?0) "+": (?1) "%": (?x)
|
||||
"r": (01) "R": (x1) "f": (10) "F": (x0)
|
||||
"p": (0?) "n": (1?) "P": (0x) "N": (1x)
|
||||
"p": (0?) "r": (01) "P": (0x)
|
||||
"n": (1?) "f": (10) "N": (1x)
|
||||
"B": (x?) "F": (x0) "R": (x1)
|
||||
|
||||
A combinatorial UDP is defined like this:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.40 2001/04/24 03:48:53 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.41 2001/04/26 03:10:55 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -319,7 +319,7 @@ void compile_udp_functor(char*label, char*type,
|
|||
struct vvp_udp_s *u = udp_find(type);
|
||||
assert (argc == u->nin);
|
||||
|
||||
int nfun = argc<=4 ? 1 : (argc-2) / 3 + 1;
|
||||
int nfun = (argc+3)/4;
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(nfun);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
|
@ -330,6 +330,26 @@ void compile_udp_functor(char*label, char*type,
|
|||
sym_set_value(sym_functors, label, val);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0; idx < argc; idx += 4)
|
||||
{
|
||||
vvp_ipoint_t ifdx = ipoint_input_index(fdx, idx);
|
||||
functor_t iobj = functor_index(ifdx);
|
||||
|
||||
iobj->ival = 0xaa;
|
||||
iobj->old_ival = obj->ival;
|
||||
iobj->oval = u->init;
|
||||
iobj->mode = 3;
|
||||
if (idx)
|
||||
{
|
||||
iobj->out = fdx;
|
||||
iobj->udp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iobj->udp = u;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run through the arguments looking for the functors that are
|
||||
connected to my input ports. For each source functor that I
|
||||
find, connect the output of that functor to the indexed
|
||||
|
|
@ -339,14 +359,10 @@ void compile_udp_functor(char*label, char*type,
|
|||
If the source functor is not declared yet, then don't do
|
||||
the link yet. Save the reference to be resolved later. */
|
||||
|
||||
udp_init_links(fdx, u);
|
||||
|
||||
udp_idx_t ux(fdx, u);
|
||||
for (unsigned idx = 0; idx < argc; idx += 1)
|
||||
{
|
||||
vvp_ipoint_t ifdx = ux.ipoint();
|
||||
functor_t iobj = ux.functor();
|
||||
ux.next();
|
||||
vvp_ipoint_t ifdx = ipoint_input_index(fdx, idx);
|
||||
functor_t iobj = functor_index(ifdx);
|
||||
|
||||
symbol_value_t val = sym_get_value(sym_functors, argv[idx].text);
|
||||
vvp_ipoint_t tmp = val.num;
|
||||
|
|
@ -366,12 +382,6 @@ void compile_udp_functor(char*label, char*type,
|
|||
}
|
||||
}
|
||||
|
||||
obj->ival = 0xaa;
|
||||
obj->old_ival = obj->ival;
|
||||
obj->oval = u->init;
|
||||
obj->mode = 3;
|
||||
obj->udp = u;
|
||||
|
||||
free(argv);
|
||||
free(label);
|
||||
}
|
||||
|
|
@ -944,6 +954,9 @@ void compile_dump(FILE*fd)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.41 2001/04/26 03:10:55 steve
|
||||
* Redo and simplify UDP behavior.
|
||||
*
|
||||
* Revision 1.40 2001/04/24 03:48:53 steve
|
||||
* Fix underflow when UDP has 1 input.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: pointers.h,v 1.3 2001/03/26 04:00:39 steve Exp $"
|
||||
#ident "$Id: pointers.h,v 1.4 2001/04/26 03:10:55 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -66,6 +66,14 @@ inline vvp_ipoint_t ipoint_index(vvp_ipoint_t base, unsigned idx)
|
|||
return base + (idx<<2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the ipoint of an input into a multi-functor input vector.
|
||||
*/
|
||||
inline vvp_ipoint_t ipoint_input_index(vvp_ipoint_t base, unsigned idx)
|
||||
{
|
||||
return (base & ~3) + idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the port index of a functor given a complete
|
||||
* vvp_ipoint_t pointer.
|
||||
|
|
@ -94,6 +102,9 @@ typedef struct vthread_s*vthread_t;
|
|||
|
||||
/*
|
||||
* $Log: pointers.h,v $
|
||||
* Revision 1.4 2001/04/26 03:10:55 steve
|
||||
* Redo and simplify UDP behavior.
|
||||
*
|
||||
* Revision 1.3 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
|
|
|
|||
65
vvp/udp.cc
65
vvp/udp.cc
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: udp.cc,v 1.1 2001/04/24 02:23:59 steve Exp $"
|
||||
#ident "$Id: udp.cc,v 1.2 2001/04/26 03:10:55 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "udp.h"
|
||||
|
|
@ -56,27 +56,6 @@ struct vvp_udp_s *udp_find(char *label)
|
|||
return (struct vvp_udp_s *)v.ptr;
|
||||
}
|
||||
|
||||
void udp_init_links(vvp_ipoint_t fdx, struct vvp_udp_s *u)
|
||||
{
|
||||
udp_idx_t ux(fdx, u);
|
||||
do
|
||||
{
|
||||
vvp_ipoint_t pa = ux.parent();
|
||||
if (pa)
|
||||
{
|
||||
functor_t fu = ux.functor();
|
||||
functor_t fp = functor_index(pa);
|
||||
fp->port[ipoint_port(pa)] = 0x0;
|
||||
fu->out = pa;
|
||||
fu->udp = 0x0;
|
||||
fu->mode = 3;
|
||||
|
||||
fu->ival = 0xaa;
|
||||
fu->old_ival = fu->ival;
|
||||
}
|
||||
} while (ux.next_node());
|
||||
}
|
||||
|
||||
unsigned char udp_propagate(vvp_ipoint_t uix)
|
||||
{
|
||||
functor_t fu = functor_index(uix);
|
||||
|
|
@ -84,8 +63,6 @@ unsigned char udp_propagate(vvp_ipoint_t uix)
|
|||
assert(u);
|
||||
assert(u->table);
|
||||
|
||||
udp_idx_t ux(uix, u);
|
||||
|
||||
unsigned char ret = 2;
|
||||
|
||||
for (char **rptr = u->table; *rptr ; rptr++)
|
||||
|
|
@ -94,24 +71,34 @@ unsigned char udp_propagate(vvp_ipoint_t uix)
|
|||
|
||||
if (u->sequ)
|
||||
{
|
||||
if (row[0]=='?' || row[0]==(fu->oval&3)["01xx"])
|
||||
char old_out = (fu->oval&3)["01xx"];
|
||||
if ( row[0]=='?'
|
||||
|| row[0]==old_out
|
||||
|| (row[0]=='b' && old_out!='x')
|
||||
|| (row[0]=='l' && old_out!='1')
|
||||
|| (row[0]=='h' && old_out!='0') )
|
||||
row++;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
ux.reset();
|
||||
int i;
|
||||
|
||||
do
|
||||
for (i=0; i < u->nin; i++, row++)
|
||||
{
|
||||
assert (*row);
|
||||
|
||||
int port = ipoint_port(ux.ipoint());
|
||||
functor_t pfun = ux.functor();
|
||||
int idx = ipoint_input_index(uix, i);
|
||||
int port = ipoint_port(idx);
|
||||
functor_t pfun = functor_index(idx);
|
||||
|
||||
char new_bit = ((pfun->ival >> (2*port))&3)["01xx"];
|
||||
|
||||
if (*row != new_bit && *row != '?')
|
||||
if ( *row != new_bit
|
||||
&& *row != '?'
|
||||
&& (*row != 'b' || new_bit == 'x')
|
||||
&& (*row != 'l' || new_bit == '1')
|
||||
&& (*row != 'h' || new_bit == '0') )
|
||||
{
|
||||
char old_bit = ((pfun->old_ival >> (2*port))&3)["01xx"];
|
||||
if (new_bit == old_bit)
|
||||
|
|
@ -133,6 +120,10 @@ unsigned char udp_propagate(vvp_ipoint_t uix)
|
|||
if (new_bit == 'x')
|
||||
continue;
|
||||
break;
|
||||
case 'B':
|
||||
if (old_bit == 'x')
|
||||
continue;
|
||||
break;
|
||||
case 'r':
|
||||
if (old_bit=='0' && new_bit=='1')
|
||||
continue;
|
||||
|
|
@ -168,9 +159,9 @@ unsigned char udp_propagate(vvp_ipoint_t uix)
|
|||
}
|
||||
break;
|
||||
}
|
||||
} while (row++, ux.next());
|
||||
}
|
||||
|
||||
if (ux.done())
|
||||
if (i == u->nin)
|
||||
{
|
||||
assert(*row);
|
||||
if (*row == '-')
|
||||
|
|
@ -192,18 +183,20 @@ unsigned char udp_propagate(vvp_ipoint_t uix)
|
|||
}
|
||||
}
|
||||
|
||||
ux.reset();
|
||||
do
|
||||
for (int i=0; i < u->nin; i+=4)
|
||||
{
|
||||
functor_t fu = ux.functor();
|
||||
functor_t fu = functor_index(ipoint_input_index(uix, i));
|
||||
fu->old_ival = fu->ival;
|
||||
} while (ux.next_node());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: udp.cc,v $
|
||||
* Revision 1.2 2001/04/26 03:10:55 steve
|
||||
* Redo and simplify UDP behavior.
|
||||
*
|
||||
* Revision 1.1 2001/04/24 02:23:59 steve
|
||||
* Support for UDP devices in VVP (Stephen Boettcher)
|
||||
*
|
||||
|
|
|
|||
83
vvp/udp.h
83
vvp/udp.h
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: udp.h,v 1.2 2001/04/24 03:48:53 steve Exp $"
|
||||
#ident "$Id: udp.h,v 1.3 2001/04/26 03:10:55 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "pointers.h"
|
||||
|
|
@ -36,90 +36,15 @@ struct vvp_udp_s
|
|||
char **table;
|
||||
};
|
||||
|
||||
void udp_init_links(vvp_ipoint_t fdx, struct vvp_udp_s *u);
|
||||
struct vvp_udp_s *udp_create(char *label);
|
||||
struct vvp_udp_s *udp_find(char *label);
|
||||
unsigned char udp_propagate(vvp_ipoint_t);
|
||||
|
||||
// The iterator through the input port list/tree/whatever
|
||||
|
||||
class udp_idx_t
|
||||
{
|
||||
public:
|
||||
udp_idx_t(vvp_ipoint_t, struct vvp_udp_s *);
|
||||
vvp_ipoint_t ipoint();
|
||||
functor_t functor();
|
||||
bool next();
|
||||
vvp_ipoint_t next_node();
|
||||
bool done();
|
||||
vvp_ipoint_t parent();
|
||||
void reset();
|
||||
private:
|
||||
vvp_ipoint_t root;
|
||||
unsigned nin;
|
||||
unsigned cur_i;
|
||||
};
|
||||
|
||||
inline void udp_idx_t::reset()
|
||||
{
|
||||
cur_i = 0;
|
||||
}
|
||||
|
||||
inline udp_idx_t::udp_idx_t(vvp_ipoint_t idx, struct vvp_udp_s *u)
|
||||
: root(idx), nin(u->nin)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
inline bool udp_idx_t::done()
|
||||
{
|
||||
return cur_i >= nin;
|
||||
}
|
||||
|
||||
inline bool udp_idx_t::next()
|
||||
{
|
||||
cur_i++;
|
||||
return !done();
|
||||
}
|
||||
|
||||
inline vvp_ipoint_t udp_idx_t::ipoint()
|
||||
{
|
||||
// The last node in the chain can hold 4 inputs.
|
||||
int idx = (cur_i==nin-1 && cur_i ? cur_i-1 : cur_i) / 3;
|
||||
int port = cur_i - 3*idx;
|
||||
return ipoint_make(ipoint_index(root, idx), port);
|
||||
}
|
||||
|
||||
inline functor_t udp_idx_t::functor()
|
||||
{
|
||||
return functor_index(ipoint());
|
||||
}
|
||||
|
||||
// junp to the next node, and return the ipoint.
|
||||
|
||||
inline vvp_ipoint_t udp_idx_t::next_node()
|
||||
{
|
||||
// We omit the last-node case, since is is a don't care here.
|
||||
int idx = cur_i / 3 + 1;
|
||||
cur_i = idx*3+1;
|
||||
return cur_i < nin
|
||||
? ipoint_make(ipoint_index(root, idx),0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
inline vvp_ipoint_t udp_idx_t::parent()
|
||||
{
|
||||
if (nin<=4)
|
||||
return 0x0;
|
||||
|
||||
int idx = (cur_i==nin-1 ? cur_i-1 : cur_i) / 3;
|
||||
if (!idx)
|
||||
return 0x0;
|
||||
return ipoint_make(ipoint_index(root, idx-1), 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: udp.h,v $
|
||||
* Revision 1.3 2001/04/26 03:10:55 steve
|
||||
* Redo and simplify UDP behavior.
|
||||
*
|
||||
* Revision 1.2 2001/04/24 03:48:53 steve
|
||||
* Fix underflow when UDP has 1 input.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue