Generate code to handle real valued muxes.
This commit is contained in:
parent
4902c222fb
commit
c39976fbf1
|
|
@ -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.159 2005/08/06 17:58:16 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.160 2005/09/01 04:11:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -920,7 +920,8 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
|||
* The ivl_lpm_data() method returns the inputs of the MUX device. The
|
||||
* ivl_lpm_size() method returns the number of data inputs there
|
||||
* are. All the data inputs have the same width, the width of the
|
||||
* ivl_lpm_q output.
|
||||
* ivl_lpm_q output. The type of the device is devined from the
|
||||
* inputs and the Q. All the types must be exactly the same.
|
||||
*
|
||||
* - D-FlipFlop (IVL_LPM_FF)
|
||||
* This data is an edge sensitive register. The ivl_lpm_q output and
|
||||
|
|
@ -1670,6 +1671,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.160 2005/09/01 04:11:37 steve
|
||||
* Generate code to handle real valued muxes.
|
||||
*
|
||||
* Revision 1.159 2005/08/06 17:58:16 steve
|
||||
* Implement bi-directional part selects.
|
||||
*
|
||||
|
|
|
|||
11
netlist.h
11
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: netlist.h,v 1.348 2005/08/31 05:07:31 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.349 2005/09/01 04:11:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -876,6 +876,12 @@ class NetMult : public NetNode {
|
|||
* width -- Width of the result and each possible Data input
|
||||
* size -- Number of Data input (each of width)
|
||||
* selw -- Width in bits of the select input
|
||||
*
|
||||
* All the data inputs must have the same type, and are the type of
|
||||
* the result. The actual type does not matter, as the mux does not
|
||||
* process data, just selects alternatives.
|
||||
*
|
||||
* The select input must be an integral type of some sort. Not real.
|
||||
*/
|
||||
class NetMux : public NetNode {
|
||||
|
||||
|
|
@ -3436,6 +3442,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.349 2005/09/01 04:11:37 steve
|
||||
* Generate code to handle real valued muxes.
|
||||
*
|
||||
* Revision 1.348 2005/08/31 05:07:31 steve
|
||||
* Handle memory references is continuous assignments.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.11 2005/08/27 04:32:08 steve Exp $"
|
||||
#ident "$Id: draw_mux.c,v 1.12 2005/09/01 04:11:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
* This draws a simple A/B mux. The mux can have any width, enough
|
||||
* MUXZ nodes are created to support the vector.
|
||||
*/
|
||||
static void draw_lpm_mux_ab(ivl_lpm_t net)
|
||||
static void draw_lpm_mux_ab(ivl_lpm_t net, const char*muxz)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
|
||||
|
|
@ -41,14 +41,14 @@ static void draw_lpm_mux_ab(ivl_lpm_t net)
|
|||
assert(ivl_lpm_size(net) == 2);
|
||||
assert(ivl_lpm_selects(net) == 1);
|
||||
|
||||
fprintf(vvp_out, "L_%p .functor MUXZ %u", net, 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_net_input(ivl_lpm_data(net,1)));
|
||||
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_select(net)));
|
||||
fprintf(vvp_out, ", C4<>;\n");
|
||||
}
|
||||
|
||||
static void draw_lpm_mux_nest(ivl_lpm_t net)
|
||||
static void draw_lpm_mux_nest(ivl_lpm_t net, const char*muxz)
|
||||
{
|
||||
int idx, level;
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
|
|
@ -63,8 +63,8 @@ static void draw_lpm_mux_nest(ivl_lpm_t net)
|
|||
net, select_input);
|
||||
|
||||
for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 2) {
|
||||
fprintf(vvp_out, "L_%p/0/%d .functor MUXZ %u",
|
||||
net, idx/2, width);
|
||||
fprintf(vvp_out, "L_%p/0/%d .functor %s %u",
|
||||
net, idx/2, muxz, width);
|
||||
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,idx+0)));
|
||||
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,idx+1)));
|
||||
fprintf(vvp_out, ", L_%p/0s, C4<>;\n", net);
|
||||
|
|
@ -75,8 +75,8 @@ static void draw_lpm_mux_nest(ivl_lpm_t net)
|
|||
net, level, select_input, level);
|
||||
|
||||
for (idx = 0 ; idx < (ivl_lpm_size(net) >> level); idx += 2) {
|
||||
fprintf(vvp_out, "L_%p/%d/%d .functor MUXZ %u",
|
||||
net, width, level,idx);
|
||||
fprintf(vvp_out, "L_%p/%d/%d .functor %s %u",
|
||||
net, width, level, muxz, idx);
|
||||
fprintf(vvp_out, ", L_%p/%d/%d", net, level-1, idx/2+0);
|
||||
fprintf(vvp_out, ", L_%p/%d/%d", net, level-1, idx/2+1);
|
||||
fprintf(vvp_out, ", L_%p/%ds", net, level);
|
||||
|
|
@ -90,28 +90,46 @@ static void draw_lpm_mux_nest(ivl_lpm_t net)
|
|||
net, swidth-1, select_input, swidth-1, swidth-1);
|
||||
|
||||
|
||||
fprintf(vvp_out, "L_%p .functor MUXZ %u", net, width);
|
||||
fprintf(vvp_out, "L_%p .functor %s %u", net, muxz, width);
|
||||
fprintf(vvp_out, ", L_%p/%d/0", net, swidth-2);
|
||||
fprintf(vvp_out, ", L_%p/%d/1", net, swidth-2);
|
||||
fprintf(vvp_out, ", L_%p/%ds", net, swidth-1);
|
||||
fprintf(vvp_out, ", C4<>;\n");
|
||||
|
||||
free(select_input);}
|
||||
free(select_input);
|
||||
}
|
||||
|
||||
void draw_lpm_mux(ivl_lpm_t net)
|
||||
{
|
||||
const char*muxz = "MUXZ";
|
||||
|
||||
/* The output of the mux defines the type of the mux. the
|
||||
ivl_target should guarantee that all the inputs are the
|
||||
same type as the output. */
|
||||
switch (data_type_of_nexus(ivl_lpm_q(net,0))) {
|
||||
case IVL_VT_REAL:
|
||||
muxz = "MUXR";
|
||||
break;
|
||||
default:
|
||||
muxz = "MUXZ";
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ivl_lpm_size(net) == 2) && (ivl_lpm_selects(net) == 1)) {
|
||||
draw_lpm_mux_ab(net);
|
||||
draw_lpm_mux_ab(net, muxz);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Here we are at the worst case, we generate a tree of MUXZ
|
||||
devices to handle the arbitrary size. */
|
||||
draw_lpm_mux_nest(net);
|
||||
draw_lpm_mux_nest(net, muxz);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: draw_mux.c,v $
|
||||
* Revision 1.12 2005/09/01 04:11:37 steve
|
||||
* Generate code to handle real valued muxes.
|
||||
*
|
||||
* Revision 1.11 2005/08/27 04:32:08 steve
|
||||
* Handle synthesis of fully packed case statements.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.32 2005/08/06 17:58:16 steve Exp $"
|
||||
#ident "$Id: vvp_priv.h,v 1.33 2005/09/01 04:11:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_config.h"
|
||||
|
|
@ -49,6 +49,9 @@ extern const char* vvp_signal_label(ivl_signal_t sig);
|
|||
*/
|
||||
extern const char* vvp_memory_label(ivl_memory_t mem);
|
||||
|
||||
extern unsigned width_of_nexus(ivl_nexus_t nex);
|
||||
extern ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex);
|
||||
|
||||
/*
|
||||
* This function draws a process (initial or always) into the output
|
||||
* file. It normally returns 0, but returns !0 of there is some sort
|
||||
|
|
@ -198,6 +201,9 @@ extern unsigned thread_count;
|
|||
|
||||
/*
|
||||
* $Log: vvp_priv.h,v $
|
||||
* Revision 1.33 2005/09/01 04:11:37 steve
|
||||
* Generate code to handle real valued muxes.
|
||||
*
|
||||
* Revision 1.32 2005/08/06 17:58:16 steve
|
||||
* Implement bi-directional part selects.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue