Clean up handle of UDPs.

This commit is contained in:
steve 2005-04-01 06:04:30 +00:00
parent b7ef2fcb0a
commit 236ff2b278
5 changed files with 182 additions and 13 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.147 2005/03/18 02:56:03 steve Exp $"
#ident "$Id: ivl_target.h,v 1.148 2005/04/01 06:04:30 steve Exp $"
#endif
#ifdef __cplusplus
@ -378,11 +378,17 @@ typedef const struct ivl_attribute_s*ivl_attribute_t;
* scanned. This function will return 0, or the non-zero value that
* was returned from the last scanned process.
*
* ivl_design_root
* ivl_design_root (ANACHRONISM)
* A design has a root named scope that is an instance of the top
* level module in the design. This is a hook for naming the
* design, or for starting the scope scan.
*
* ivl_design_roots
* A design has some number of root scopes. These are the starting
* points for structural elaboration. This function returns to the
* caller a pointer to an ivl_scope_t array, and the size of the
* array.
*
* ivl_design_time_precision
* A design as a time precision. This is the size in seconds (a
* signed power of 10) of a simulation tick.
@ -675,6 +681,15 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
* the outputs have the same characteristics as other logic
* devices. They are special only in that they have zero inputs, and
* their drivers typically have strength other then strong.
*
* - IVL_LO_UDP
* User defined primitives (UDPs) are like any other logic devices, in
* that they are bit-slice devices. If they have a width, then they
* are repeated to accommodate that width, and that implies that the
* output and all the inputs must have the same width.
*
* The IVL_LO_UDP represents instantiations of UDP devices. The
* ivl_udp_t describes the implementation.
*/
extern const char* ivl_logic_name(ivl_net_logic_t net);
@ -694,10 +709,43 @@ extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net);
extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx);
/* UDP
* These methods allow access to the ivl_udp_t definition of a UDP.
* The UDP definition is accessed through the ivl_logic_udp method of
* an ivl_net_logic_t object.
*
* ivl_udp_name
* This returns the name of the definition of the primitive.
*
* ivl_udp_nin
* This is the number of inputs for the UDP definition.
*
* ivl_udp_rows
* ivl_udp_row
* These methods give access to the rows that define the table of
* the primitive.
*
* SEMANTIC NOTES
*
* - Combinational primitives
* These devices have no edge dependencies, and have no table entry
* for the current input value. These have ivl_udp_sequ return 0
* (false) and the length of each row is the number of inputs plus 1.
* The first N characters correspond to the N inputs of the
* device. The next character, the last character, is the output for
* that row.
*
* - Sequential primitives
* These devices allow edge transitions, and the rows are 1+N+1
* characters long. The first character is the current output, the
* next N characters the current input and the last character is the
* new output.
*
* The ivl_udp_init value is only valid if the device is
* sequential. It is the initial value for the output of the storage
* element.
*/
extern unsigned ivl_udp_sequ(ivl_udp_t net);
extern int ivl_udp_sequ(ivl_udp_t net);
extern unsigned ivl_udp_nin(ivl_udp_t net);
extern unsigned ivl_udp_init(ivl_udp_t net);
extern const char* ivl_udp_row(ivl_udp_t net, unsigned idx);
@ -1580,6 +1628,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.148 2005/04/01 06:04:30 steve
* Clean up handle of UDPs.
*
* Revision 1.147 2005/03/18 02:56:03 steve
* Add support for LPM_UFUNC user defined functions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.121 2005/03/18 02:56:04 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.122 2005/04/01 06:04:30 steve Exp $"
#endif
# include "config.h"
@ -50,6 +50,9 @@ extern "C" int ivl_design_process(ivl_design_t des,
extern "C" ivl_scope_t ivl_design_root(ivl_design_t des)
{
cerr << "ANACHRONISM: ivl_design_root called. "
"Use ivl_design_roots instead." << endl;
assert (des->nroots_);
return des->roots_[0];
}
@ -572,7 +575,7 @@ extern "C" unsigned ivl_logic_width(ivl_net_logic_t net)
return net->width_;
}
extern "C" unsigned ivl_udp_sequ(ivl_udp_t net)
extern "C" int ivl_udp_sequ(ivl_udp_t net)
{
return net->sequ;
}
@ -2000,6 +2003,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.122 2005/04/01 06:04:30 steve
* Clean up handle of UDPs.
*
* Revision 1.121 2005/03/18 02:56:04 steve
* Add support for LPM_UFUNC user defined functions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.145 2005/03/18 02:56:04 steve Exp $"
#ident "$Id: t-dll.cc,v 1.146 2005/04/01 06:04:30 steve Exp $"
#endif
# include "config.h"
@ -1046,6 +1046,10 @@ void dll_target::udp(const NetUDP*net)
obj->type_ = IVL_LO_UDP;
/* The NetUDP class hasn't learned about width yet, so we
assume a width of 1. */
obj->width_ = 1;
static map<perm_string,ivl_udp_t> udps;
ivl_udp_t u;
@ -2133,6 +2137,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.146 2005/04/01 06:04:30 steve
* Clean up handle of UDPs.
*
* Revision 1.145 2005/03/18 02:56:04 steve
* Add support for LPM_UFUNC user defined functions.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.123 2005/03/18 02:56:04 steve Exp $"
#ident "$Id: t-dll.h,v 1.124 2005/04/01 06:04:30 steve Exp $"
#endif
# include "target.h"
@ -438,7 +438,7 @@ struct ivl_net_logic_s {
struct ivl_udp_s {
perm_string name;
unsigned nin;
unsigned sequ;
int sequ; /* boolen */
char init;
unsigned nrows;
typedef const char*ccharp_t;
@ -685,6 +685,9 @@ struct ivl_variable_s {
/*
* $Log: t-dll.h,v $
* Revision 1.124 2005/04/01 06:04:30 steve
* Clean up handle of UDPs.
*
* Revision 1.123 2005/03/18 02:56:04 steve
* Add support for LPM_UFUNC user defined functions.
*

View File

@ -17,16 +17,49 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.119 2005/03/19 06:59:53 steve Exp $"
#ident "$Id: stub.c,v 1.120 2005/04/01 06:04:30 steve Exp $"
#endif
# include "config.h"
# include "priv.h"
# include <stdlib.h>
# include <assert.h>
FILE*out;
int stub_errors = 0;
static struct udp_define_cell {
ivl_udp_t udp;
unsigned ref;
struct udp_define_cell*next;
}*udp_define_list = 0;
static void reference_udp_definition(ivl_udp_t udp)
{
struct udp_define_cell*cur;
if (udp_define_list == 0) {
udp_define_list = calloc(1, sizeof(struct udp_define_cell));
udp_define_list->udp = udp;
udp_define_list->ref = 1;
return;
}
cur = udp_define_list;
while (cur->udp != udp) {
if (cur->next == 0) {
cur->next = calloc(1, sizeof(struct udp_define_cell));
cur->next->udp = udp;
cur->next->ref = 1;
return;
}
cur = cur->next;
}
cur->ref += 1;
}
/*
* This function finds the vector width of a signal. It relies on the
* assumption that all the signal inputs to the nexus have the same
@ -1074,7 +1107,8 @@ static void show_logic(ivl_net_logic_t net)
break;
case IVL_LO_UDP:
fprintf(out, " primitive %s", name);
fprintf(out, " primitive<%s> %s",
ivl_udp_name(ivl_logic_udp(net)), name);
break;
default:
@ -1112,6 +1146,19 @@ static void show_logic(ivl_net_logic_t net)
}
}
/* If this is an instance of a UDP, then check that the
instantiation is consistent with the definition. */
if (ivl_logic_type(net) == IVL_LO_UDP) {
ivl_udp_t udp = ivl_logic_udp(net);
if (npins != 1+ivl_udp_nin(udp)) {
fprintf(out, " ERROR: UDP %s expects %u inputs\n",
ivl_udp_name(udp), ivl_udp_nin(udp));
stub_errors += 1;
}
/* Add a reference to this udp definition. */
reference_udp_definition(udp);
}
npins = ivl_logic_attr_cnt(net);
for (idx = 0 ; idx < npins ; idx += 1) {
@ -1204,8 +1251,49 @@ static int show_scope(ivl_scope_t net, void*x)
return ivl_scope_children(net, show_scope, 0);
}
static void show_primitive(ivl_udp_t net, unsigned ref_count)
{
unsigned rdx;
fprintf(out, "primtive %s (referenced %u times)\n",
ivl_udp_name(net), ref_count);
if (ivl_udp_sequ(net))
fprintf(out, " reg out = %u;\n", ivl_udp_init(net));
else
fprintf(out, " wire out;\n");
fprintf(out, " table\n");
for (rdx = 0 ; rdx < ivl_udp_rows(net) ; rdx += 1) {
/* Each row has the format:
Combinational: iii...io
Sequential: oiii...io
In the sequential case, the o value in the front is
the current output value. */
unsigned idx;
const char*row = ivl_udp_row(net,rdx);
fprintf(out, " ");
if (ivl_udp_sequ(net))
fprintf(out, " cur=%c :", *row++);
for (idx = 0 ; idx < ivl_udp_nin(net) ; idx += 1)
fprintf(out, " %c", *row++);
fprintf(out, " : out=%c\n", *row++);
}
fprintf(out, " endtable\n");
fprintf(out, "endprimitive\n");
}
int target_design(ivl_design_t des)
{
ivl_scope_t*root_scopes;
unsigned nroot = 0;
unsigned idx;
const char*path = ivl_design_flag(des, "-o");
if (path == 0) {
return -1;
@ -1217,10 +1305,21 @@ int target_design(ivl_design_t des)
return -2;
}
fprintf(out, "root module = %s;\n",
ivl_scope_name(ivl_design_root(des)));
ivl_design_roots(des, &root_scopes, &nroot);
for (idx = 0 ; idx < nroot ; idx += 1) {
fprintf(out, "root module = %s;\n",
ivl_scope_name(root_scopes[idx]));
show_scope(root_scopes[idx], 0);
}
while (udp_define_list) {
struct udp_define_cell*cur = udp_define_list;
udp_define_list = cur->next;
show_primitive(cur->udp, cur->ref);
free(cur);
}
show_scope(ivl_design_root(des), 0);
ivl_design_process(des, show_process, 0);
fclose(out);
@ -1230,6 +1329,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.120 2005/04/01 06:04:30 steve
* Clean up handle of UDPs.
*
* Revision 1.119 2005/03/19 06:59:53 steve
* Handle wide operands to logical AND.
*