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:
parent
3cdf655c79
commit
9c8c541f5d
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# 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);
|
assert(ivl_lpm_selects(net) == 1);
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%p .functor %s %u", net, muxz, width);
|
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_input_from_net(ivl_lpm_data(net,0)));
|
||||||
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,1)));
|
fprintf(vvp_out, ", %s", draw_input_from_net(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_select(net)));
|
||||||
fprintf(vvp_out, ", C4<>;\n");
|
fprintf(vvp_out, ", C4<>;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +127,11 @@ void draw_lpm_mux(ivl_lpm_t net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: draw_mux.c,v $
|
* $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
|
* Revision 1.12 2005/09/01 04:11:37 steve
|
||||||
* Generate code to handle real valued muxes.
|
* Generate code to handle real valued muxes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_config.h"
|
# 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
|
* This generates a string from a signal that uniquely identifies
|
||||||
* that signal with letters that can be used in a label.
|
* 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);
|
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);
|
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
|
* The draw_eval_expr function writes out the code to evaluate a
|
||||||
* behavioral expression.
|
* behavioral expression.
|
||||||
|
|
@ -228,6 +245,11 @@ extern unsigned thread_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_priv.h,v $
|
* $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
|
* Revision 1.38 2005/10/11 18:30:50 steve
|
||||||
* Remove obsolete vvp_memory_label function.
|
* Remove obsolete vvp_memory_label function.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -28,6 +28,19 @@
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <string.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.
|
* 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;
|
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)
|
ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
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)
|
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
|
/* If this nexus already has a label, then its input is
|
||||||
already figured out. Just return the existing label. */
|
already figured out. Just return the existing label. */
|
||||||
char*nex_private = (char*)ivl_nexus_get_private(nex);
|
if (nex_data && nex_data->net_input)
|
||||||
if (nex_private)
|
return nex_data->net_input;
|
||||||
return nex_private;
|
|
||||||
|
|
||||||
nex_private = draw_net_input_x(nex, 0);
|
if (nex_data == 0) {
|
||||||
ivl_nexus_set_private(nex, nex_private);
|
nex_data = new_nexus_data();
|
||||||
return nex_private;
|
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" : "";
|
const char*datatype_flag = ivl_signal_signed(sig)? "/s" : "";
|
||||||
|
|
||||||
|
struct vvp_nexus_data*nex_data;
|
||||||
|
|
||||||
/* Skip the local signal. */
|
/* Skip the local signal. */
|
||||||
if (ivl_signal_local(sig))
|
if (ivl_signal_local(sig))
|
||||||
return;
|
return;
|
||||||
|
|
@ -827,6 +880,9 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
||||||
{
|
{
|
||||||
ivl_nexus_t nex = ivl_signal_nex(sig);
|
ivl_nexus_t nex = ivl_signal_nex(sig);
|
||||||
arg = draw_net_input(nex);
|
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)) {
|
switch (ivl_signal_data_type(sig)) {
|
||||||
|
|
@ -837,10 +893,21 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(vvp_out, "V_%s .net%s \"%s\", %d, %d, %s;\n",
|
if (nex_data->net == 0) {
|
||||||
vvp_signal_label(sig), datatype_flag,
|
fprintf(vvp_out, "V_%p .net%s \"%s\", %d, %d, %s;\n",
|
||||||
vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, arg);
|
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)
|
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 $
|
* $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
|
* Revision 1.136 2005/10/11 18:54:10 steve
|
||||||
* Remove the $ from signal labels. They do not help.
|
* Remove the $ from signal labels. They do not help.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue