MUX nodes get inputs from nets, not from net inputs,

Detect and draw alias nodes to reduce net size and
 handle force confusion.
This commit is contained in:
steve 2005-10-12 17:26:17 +00:00
parent 3cdf655c79
commit 9c8c541f5d
3 changed files with 115 additions and 16 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: draw_mux.c,v 1.12 2005/09/01 04:11:37 steve Exp $"
#ident "$Id: draw_mux.c,v 1.13 2005/10/12 17:26:17 steve Exp $"
#endif
# include "vvp_priv.h"
@ -42,9 +42,9 @@ static void draw_lpm_mux_ab(ivl_lpm_t net, const char*muxz)
assert(ivl_lpm_selects(net) == 1);
fprintf(vvp_out, "L_%p .functor %s %u", net, muxz, width);
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,0)));
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,1)));
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_select(net)));
fprintf(vvp_out, ", %s", draw_input_from_net(ivl_lpm_data(net,0)));
fprintf(vvp_out, ", %s", draw_input_from_net(ivl_lpm_data(net,1)));
fprintf(vvp_out, ", %s", draw_input_from_net(ivl_lpm_select(net)));
fprintf(vvp_out, ", C4<>;\n");
}
@ -127,6 +127,11 @@ void draw_lpm_mux(ivl_lpm_t net)
/*
* $Log: draw_mux.c,v $
* Revision 1.13 2005/10/12 17:26:17 steve
* MUX nodes get inputs from nets, not from net inputs,
* Detect and draw alias nodes to reduce net size and
* handle force confusion.
*
* Revision 1.12 2005/09/01 04:11:37 steve
* Generate code to handle real valued muxes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_priv.h,v 1.38 2005/10/11 18:30:50 steve Exp $"
#ident "$Id: vvp_priv.h,v 1.39 2005/10/12 17:26:17 steve Exp $"
#endif
# include "vvp_config.h"
@ -41,6 +41,11 @@ extern const char *vvp_mangle_name(const char *);
/*
* This generates a string from a signal that uniquely identifies
* that signal with letters that can be used in a label.
*
* NOTE: vvp_signal_label should be removed. All it does is a %p of
* the pointer, and return a pointer to a static. The code that wants
* to reference a signal needs to use the format V_%p, so the presence
* of this function is just plain inconsistent.
*/
extern const char* vvp_signal_label(ivl_signal_t sig);
@ -86,6 +91,18 @@ extern int draw_vpi_rfunc_call(ivl_expr_t exp);
*/
extern const char* draw_net_input(ivl_nexus_t nex);
/*
* This function is different from draw_net_input in that it will
* return a reference to a net as its first choice. This reference
* will follow the net value, even if the net is assigned or
* forced. The draw_net_input above will return a reference to the
* *input* to the net and so will not follow direct assignments to
* the net. This function will not return references to local signals,
* and will in those cases resort to the net input, or a non-local
* signal if one exists for the nexus.
*/
extern const char*draw_input_from_net(ivl_nexus_t nex);
/*
* The draw_eval_expr function writes out the code to evaluate a
* behavioral expression.
@ -228,6 +245,11 @@ extern unsigned thread_count;
/*
* $Log: vvp_priv.h,v $
* Revision 1.39 2005/10/12 17:26:17 steve
* MUX nodes get inputs from nets, not from net inputs,
* Detect and draw alias nodes to reduce net size and
* handle force confusion.
*
* Revision 1.38 2005/10/11 18:30:50 steve
* Remove obsolete vvp_memory_label function.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.136 2005/10/11 18:54:10 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.137 2005/10/12 17:26:17 steve Exp $"
#endif
# include "vvp_priv.h"
@ -28,6 +28,19 @@
# include <stdlib.h>
# include <string.h>
struct vvp_nexus_data {
/* draw_net_input uses this */
const char*net_input;
/* draw_net_in_scope uses this */
ivl_signal_t net;
};
static struct vvp_nexus_data*new_nexus_data()
{
struct vvp_nexus_data*data = calloc(1, sizeof(struct vvp_nexus_data));
return data;
}
/*
* Escape non-symbol chararacters in ids, and quotes in strings.
*/
@ -160,6 +173,24 @@ const char* vvp_signal_label(ivl_signal_t sig)
return buf;
}
ivl_signal_t signal_of_nexus(ivl_nexus_t nex)
{
unsigned idx;
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
if (ivl_signal_local(sig))
continue;
return sig;
}
return 0;
}
ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
{
unsigned idx;
@ -768,15 +799,35 @@ static char* draw_net_input_x(ivl_nexus_t nex, ivl_nexus_ptr_t omit)
*/
const char*draw_net_input(ivl_nexus_t nex)
{
struct vvp_nexus_data*nex_data = (struct vvp_nexus_data*)
ivl_nexus_get_private(nex);
/* If this nexus already has a label, then its input is
already figured out. Just return the existing label. */
char*nex_private = (char*)ivl_nexus_get_private(nex);
if (nex_private)
return nex_private;
if (nex_data && nex_data->net_input)
return nex_data->net_input;
nex_private = draw_net_input_x(nex, 0);
ivl_nexus_set_private(nex, nex_private);
return nex_private;
if (nex_data == 0) {
nex_data = new_nexus_data();
ivl_nexus_set_private(nex, nex_data);
}
assert(nex_data->net_input == 0);
nex_data->net_input = draw_net_input_x(nex, 0);
return nex_data->net_input;
}
const char*draw_input_from_net(ivl_nexus_t nex)
{
static char result[32];
ivl_signal_t sig = signal_of_nexus(nex);
if (sig == 0)
return draw_net_input(nex);
snprintf(result, sizeof result, "V_%p", sig);
return result;
}
@ -819,6 +870,8 @@ static void draw_net_in_scope(ivl_signal_t sig)
const char*datatype_flag = ivl_signal_signed(sig)? "/s" : "";
struct vvp_nexus_data*nex_data;
/* Skip the local signal. */
if (ivl_signal_local(sig))
return;
@ -827,6 +880,9 @@ static void draw_net_in_scope(ivl_signal_t sig)
{
ivl_nexus_t nex = ivl_signal_nex(sig);
arg = draw_net_input(nex);
nex_data = (struct vvp_nexus_data*)ivl_nexus_get_private(nex);
assert(nex_data);
}
switch (ivl_signal_data_type(sig)) {
@ -837,10 +893,21 @@ static void draw_net_in_scope(ivl_signal_t sig)
break;
}
fprintf(vvp_out, "V_%s .net%s \"%s\", %d, %d, %s;\n",
vvp_signal_label(sig), datatype_flag,
vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, arg);
if (nex_data->net == 0) {
fprintf(vvp_out, "V_%p .net%s \"%s\", %d, %d, %s;\n",
sig, datatype_flag,
vvp_mangle_name(ivl_signal_basename(sig)),
msb, lsb, arg);
nex_data->net = sig;
} else {
/* Detect that this is an alias of nex_data->net. Create
a different kind of node that refers to the alias
source data instead of holding our own data. */
fprintf(vvp_out, "V_%p .alias%s \"%s\", %d, %d, V_%p;\n",
sig, datatype_flag,
vvp_mangle_name(ivl_signal_basename(sig)),
msb, lsb, nex_data->net);
}
}
static void draw_delay(ivl_net_logic_t lptr)
@ -2010,6 +2077,11 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.137 2005/10/12 17:26:17 steve
* MUX nodes get inputs from nets, not from net inputs,
* Detect and draw alias nodes to reduce net size and
* handle force confusion.
*
* Revision 1.136 2005/10/11 18:54:10 steve
* Remove the $ from signal labels. They do not help.
*