Generate code for wide muxes.
This commit is contained in:
parent
8114523be2
commit
472f98affe
|
|
@ -16,7 +16,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.8 2001/10/09 16:50:17 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.9 2002/07/08 04:04:07 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -50,7 +50,7 @@ all: vvp.tgt
|
||||||
$(CC) -Wall -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
$(CC) -Wall -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||||
mv $*.d dep
|
mv $*.d dep
|
||||||
|
|
||||||
O = vvp.o eval_expr.o vvp_process.o vvp_scope.o
|
O = vvp.o draw_mux.o eval_expr.o vvp_process.o vvp_scope.o
|
||||||
|
|
||||||
ifeq (@WIN32@,yes)
|
ifeq (@WIN32@,yes)
|
||||||
TGTLDFLAGS=-L.. -livl
|
TGTLDFLAGS=-L.. -livl
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: draw_mux.c,v 1.1 2002/07/08 04:04:07 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# include "vvp_priv.h"
|
||||||
|
# include <assert.h>
|
||||||
|
#ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
#endif
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <string.h>
|
||||||
|
|
||||||
|
static void draw_lpm_mux_bitslice(ivl_lpm_t net, unsigned slice)
|
||||||
|
{
|
||||||
|
unsigned sel = ivl_lpm_selects(net);
|
||||||
|
unsigned size = ivl_lpm_size(net);
|
||||||
|
unsigned seldx, idx;
|
||||||
|
ivl_nexus_t s;
|
||||||
|
|
||||||
|
assert(size <= (1 << sel));
|
||||||
|
|
||||||
|
s = ivl_lpm_select(net, 0);
|
||||||
|
|
||||||
|
/* Draw the leaf mux devices that take inputs from the
|
||||||
|
net. These also use up the least significant bit of the
|
||||||
|
select vector. */
|
||||||
|
for (idx = 0 ; idx < size ; idx += 2) {
|
||||||
|
|
||||||
|
fprintf(vvp_out, "L_%s/%u/%u/%u .functor MUXZ, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)), slice, sel, idx);
|
||||||
|
|
||||||
|
{
|
||||||
|
ivl_nexus_t a = ivl_lpm_data2(net, idx+0, slice);
|
||||||
|
draw_input_from_net(a);
|
||||||
|
fprintf(vvp_out, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((idx+1) < size) {
|
||||||
|
ivl_nexus_t b = ivl_lpm_data2(net, idx+1, slice);
|
||||||
|
draw_input_from_net(b);
|
||||||
|
fprintf(vvp_out, ", ");
|
||||||
|
} else {
|
||||||
|
fprintf(vvp_out, "C<x>, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_input_from_net(s);
|
||||||
|
fprintf(vvp_out, ", C<1>;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw the tree of MUXZ devices to connect the inner tree
|
||||||
|
nodes. */
|
||||||
|
for (seldx = 1 ; seldx < (sel-1) ; seldx += 1) {
|
||||||
|
unsigned level = sel - seldx;
|
||||||
|
unsigned span = 2 << seldx;
|
||||||
|
s = ivl_lpm_select(net, seldx);
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < size ; idx += span) {
|
||||||
|
fprintf(vvp_out, "L_%s/%u/%u/%u .functor MUXZ, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)), slice, level, idx);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "L_%s/%u/%u/%u, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)),
|
||||||
|
slice, level+1, idx);
|
||||||
|
|
||||||
|
if ((idx + span/2) < size) {
|
||||||
|
fprintf(vvp_out, "L_%s/%u/%u/%u, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)),
|
||||||
|
slice, level+1, idx+span/2);
|
||||||
|
} else {
|
||||||
|
fprintf(vvp_out, "C<x>, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_input_from_net(s);
|
||||||
|
fprintf(vvp_out, ", C<1>;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = ivl_lpm_select(net, sel-1);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "L_%s/%u .functor MUXZ, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)), slice);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "L_%s/%u/2/0, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)), slice);
|
||||||
|
|
||||||
|
|
||||||
|
if ((2 << (sel-1))/2 < size) {
|
||||||
|
fprintf(vvp_out, "L_%s/%u/2/%u, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)),
|
||||||
|
slice, (2 << (sel-1))/2);
|
||||||
|
} else {
|
||||||
|
fprintf(vvp_out, "C<x>, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_input_from_net(s);
|
||||||
|
fprintf(vvp_out, ", C<1>;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
ivl_nexus_t s;
|
||||||
|
unsigned idx, width;
|
||||||
|
|
||||||
|
/* Only support A-B muxes at this oint. */
|
||||||
|
assert(ivl_lpm_size(net) == 2);
|
||||||
|
assert(ivl_lpm_selects(net) == 1);
|
||||||
|
|
||||||
|
width = ivl_lpm_width(net);
|
||||||
|
s = ivl_lpm_select(net, 0);
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
ivl_nexus_t a = ivl_lpm_data2(net, 0, idx);
|
||||||
|
ivl_nexus_t b = ivl_lpm_data2(net, 1, idx);
|
||||||
|
fprintf(vvp_out, "L_%s/%u .functor MUXZ, ",
|
||||||
|
vvp_mangle_id(ivl_lpm_name(net)), idx);
|
||||||
|
draw_input_from_net(a);
|
||||||
|
fprintf(vvp_out, ", ");
|
||||||
|
draw_input_from_net(b);
|
||||||
|
fprintf(vvp_out, ", ");
|
||||||
|
draw_input_from_net(s);
|
||||||
|
fprintf(vvp_out, ", C<1>;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_lpm_mux(ivl_lpm_t net)
|
||||||
|
{
|
||||||
|
unsigned idx;
|
||||||
|
|
||||||
|
if ((ivl_lpm_size(net) == 2) && (ivl_lpm_selects(net) == 1)) {
|
||||||
|
draw_lpm_mux_ab(net);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1)
|
||||||
|
draw_lpm_mux_bitslice(net, idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvp_priv.h,v 1.14 2002/06/02 18:57:17 steve Exp $"
|
#ident "$Id: vvp_priv.h,v 1.15 2002/07/08 04:04:07 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
|
|
@ -49,6 +49,8 @@ extern int draw_func_definition(ivl_scope_t scope);
|
||||||
|
|
||||||
extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
||||||
|
|
||||||
|
extern void draw_lpm_mux(ivl_lpm_t net);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a nexus, draw a string that represents the functor output
|
* Given a nexus, draw a string that represents the functor output
|
||||||
* that feeds the nexus. This function can be used to get the input to
|
* that feeds the nexus. This function can be used to get the input to
|
||||||
|
|
@ -59,6 +61,8 @@ extern void draw_nexus_input(ivl_nexus_t nex);
|
||||||
|
|
||||||
extern const char* draw_net_input(ivl_nexus_t nex);
|
extern const char* draw_net_input(ivl_nexus_t nex);
|
||||||
|
|
||||||
|
extern void 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.
|
||||||
|
|
@ -93,6 +97,9 @@ extern unsigned thread_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_priv.h,v $
|
* $Log: vvp_priv.h,v $
|
||||||
|
* Revision 1.15 2002/07/08 04:04:07 steve
|
||||||
|
* Generate code for wide muxes.
|
||||||
|
*
|
||||||
* Revision 1.14 2002/06/02 18:57:17 steve
|
* Revision 1.14 2002/06/02 18:57:17 steve
|
||||||
* Generate %cmpi/u where appropriate.
|
* Generate %cmpi/u where appropriate.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvp_scope.c,v 1.72 2002/07/05 21:26:17 steve Exp $"
|
#ident "$Id: vvp_scope.c,v 1.73 2002/07/08 04:04:07 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -508,7 +508,7 @@ const char* draw_net_input(ivl_nexus_t nex)
|
||||||
* functor inputs to. Sort the signals in the nexus by name, and
|
* functor inputs to. Sort the signals in the nexus by name, and
|
||||||
* choose the lexically earliest one.
|
* choose the lexically earliest one.
|
||||||
*/
|
*/
|
||||||
static void draw_input_from_net(ivl_nexus_t nex)
|
void draw_input_from_net(ivl_nexus_t nex)
|
||||||
{
|
{
|
||||||
const char*nex_private = (const char*)ivl_nexus_get_private(nex);
|
const char*nex_private = (const char*)ivl_nexus_get_private(nex);
|
||||||
if (nex_private == 0)
|
if (nex_private == 0)
|
||||||
|
|
@ -1236,123 +1236,6 @@ static void draw_lpm_eq(ivl_lpm_t net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_lpm_mux_bitwide(ivl_lpm_t net)
|
|
||||||
{
|
|
||||||
unsigned sel = ivl_lpm_selects(net);
|
|
||||||
unsigned size = ivl_lpm_size(net);
|
|
||||||
unsigned seldx, idx;
|
|
||||||
ivl_nexus_t s;
|
|
||||||
|
|
||||||
assert(size <= (1 << sel));
|
|
||||||
|
|
||||||
s = ivl_lpm_select(net, 0);
|
|
||||||
|
|
||||||
/* Draw the leaf mux devices that take inputs from the
|
|
||||||
net. These also use up the least significant bit of the
|
|
||||||
select vector. */
|
|
||||||
for (idx = 0 ; idx < size ; idx += 2) {
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s/0/%u/%u .functor MUXZ, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)), sel, idx);
|
|
||||||
|
|
||||||
{
|
|
||||||
ivl_nexus_t a = ivl_lpm_data2(net, idx+0, 0);
|
|
||||||
draw_input_from_net(a);
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((idx+1) < size) {
|
|
||||||
ivl_nexus_t b = ivl_lpm_data2(net, idx+1, 0);
|
|
||||||
draw_input_from_net(b);
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, "C<x>, ");
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_input_from_net(s);
|
|
||||||
fprintf(vvp_out, ", C<1>;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw the tree of MUXZ devices to connect the inner tree
|
|
||||||
nodes. */
|
|
||||||
for (seldx = 1 ; seldx < (sel-1) ; seldx += 1) {
|
|
||||||
unsigned level = sel - seldx;
|
|
||||||
unsigned span = 2 << seldx;
|
|
||||||
s = ivl_lpm_select(net, seldx);
|
|
||||||
|
|
||||||
for (idx = 0 ; idx < size ; idx += span) {
|
|
||||||
fprintf(vvp_out, "L_%s/0/%u/%u .functor MUXZ, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)), level, idx);
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s/0/%u/%u, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)),
|
|
||||||
level+1, idx);
|
|
||||||
|
|
||||||
if ((idx + span/2) < size) {
|
|
||||||
fprintf(vvp_out, "L_%s/0/%u/%u, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)),
|
|
||||||
level+1, idx+span/2);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, "C<x>, ");
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_input_from_net(s);
|
|
||||||
fprintf(vvp_out, ", C<1>;\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s = ivl_lpm_select(net, sel-1);
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s/0 .functor MUXZ, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)));
|
|
||||||
|
|
||||||
fprintf(vvp_out, "L_%s/0/2/0, ", vvp_mangle_id(ivl_lpm_name(net)));
|
|
||||||
|
|
||||||
|
|
||||||
if ((2 << (sel-1))/2 < size) {
|
|
||||||
fprintf(vvp_out, "L_%s/0/2/%u, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)),
|
|
||||||
(2 << (sel-1))/2);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, "C<x>, ");
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_input_from_net(s);
|
|
||||||
fprintf(vvp_out, ", C<1>;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_lpm_mux(ivl_lpm_t net)
|
|
||||||
{
|
|
||||||
ivl_nexus_t s;
|
|
||||||
unsigned idx, width;
|
|
||||||
|
|
||||||
if ((ivl_lpm_width(net) == 1) && (ivl_lpm_size(net) > 2)) {
|
|
||||||
draw_lpm_mux_bitwide(net);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only support A-B muxes at this oint. */
|
|
||||||
assert(ivl_lpm_size(net) == 2);
|
|
||||||
assert(ivl_lpm_selects(net) == 1);
|
|
||||||
|
|
||||||
width = ivl_lpm_width(net);
|
|
||||||
s = ivl_lpm_select(net, 0);
|
|
||||||
|
|
||||||
for (idx = 0 ; idx < width ; idx += 1) {
|
|
||||||
ivl_nexus_t a = ivl_lpm_data2(net, 0, idx);
|
|
||||||
ivl_nexus_t b = ivl_lpm_data2(net, 1, idx);
|
|
||||||
fprintf(vvp_out, "L_%s/%u .functor MUXZ, ",
|
|
||||||
vvp_mangle_id(ivl_lpm_name(net)), idx);
|
|
||||||
draw_input_from_net(a);
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
draw_input_from_net(b);
|
|
||||||
fprintf(vvp_out, ", ");
|
|
||||||
draw_input_from_net(s);
|
|
||||||
fprintf(vvp_out, ", C<1>;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_lpm_shiftl(ivl_lpm_t net)
|
static void draw_lpm_shiftl(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
unsigned idx, width, selects;
|
unsigned idx, width, selects;
|
||||||
|
|
@ -1577,6 +1460,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_scope.c,v $
|
* $Log: vvp_scope.c,v $
|
||||||
|
* Revision 1.73 2002/07/08 04:04:07 steve
|
||||||
|
* Generate code for wide muxes.
|
||||||
|
*
|
||||||
* Revision 1.72 2002/07/05 21:26:17 steve
|
* Revision 1.72 2002/07/05 21:26:17 steve
|
||||||
* Avoid emitting to vvp local net symbols.
|
* Avoid emitting to vvp local net symbols.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue