Add support for variable part select.
This commit is contained in:
parent
48aa0f0075
commit
7dd0d255a6
74
elab_net.cc
74
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_net.cc,v 1.161 2005/05/06 00:25:13 steve Exp $"
|
||||
#ident "$Id: elab_net.cc,v 1.162 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1434,54 +1434,51 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
|||
Link::strength_t drive1) const
|
||||
{
|
||||
/* Elaborate the selector. */
|
||||
NetNet*sel = msb_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
NetNet*sel;
|
||||
|
||||
unsigned sig_width = sig->pin_count();
|
||||
unsigned sig_width = sig->vector_width();
|
||||
|
||||
/* Detect the case of some bits not accessible by the given
|
||||
select. Figure out how many bits can be selected by the
|
||||
full range of the select, and limit the input of the mux to
|
||||
that width. */
|
||||
{ unsigned max_width_by_sel = 1 << sel->pin_count();
|
||||
if (sig_width > max_width_by_sel)
|
||||
sig_width = max_width_by_sel;
|
||||
}
|
||||
#if 0
|
||||
NetMux*mux = new NetMux(scope, scope->local_symbol(), 1,
|
||||
sig_width, sel->pin_count());
|
||||
if (sig->msb() < sig->lsb()) {
|
||||
NetExpr*sel_expr = msb_->elaborate_expr(des, scope);
|
||||
sel_expr = make_sub_expr(sig->lsb(), sel_expr);
|
||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||
delete sel_expr;
|
||||
sel_expr = tmp;
|
||||
}
|
||||
|
||||
/* Connect the signal bits to the mux. Account for the
|
||||
direction of the numbering (lsb to msb vs. msb to lsb) by
|
||||
swapping the connection order. */
|
||||
sel = sel_expr->synthesize(des);
|
||||
|
||||
if (sig->msb() > sig->lsb()) {
|
||||
} else if (sig->lsb() != 0) {
|
||||
NetExpr*sel_expr = msb_->elaborate_expr(des, scope);
|
||||
sel_expr = make_add_expr(sel_expr, - sig->lsb());
|
||||
if (NetExpr*tmp = sel_expr->eval_tree()) {
|
||||
delete sel_expr;
|
||||
sel_expr = tmp;
|
||||
}
|
||||
|
||||
sel = sel_expr->synthesize(des);
|
||||
|
||||
sel = add_to_net(des, sel, -sig->lsb());
|
||||
for (unsigned idx = 0 ; idx < sig_width ; idx += 1)
|
||||
connect(mux->pin_Data(0, idx), sig->pin(idx));
|
||||
} else {
|
||||
|
||||
sel = add_to_net(des, sel, -sig->msb());
|
||||
for (unsigned idx = 0 ; idx < sig_width ; idx += 1)
|
||||
connect(mux->pin_Data(0, idx), sig->pin(sig_width-idx-1));
|
||||
sel = msb_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < sel->pin_count() ; idx += 1)
|
||||
connect(mux->pin_Sel(idx), sel->pin(idx));
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: Create NetPartSelect "
|
||||
<< "using signal " << sel->name() << " as selector"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
/* Create a part select that takes a non-constant offset and a
|
||||
width of 1. */
|
||||
NetPartSelect*mux = new NetPartSelect(sig, sel, 1);
|
||||
des->add_node(mux);
|
||||
mux->set_line(*this);
|
||||
|
||||
NetNet*out = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
connect(mux->pin_Result(0), out->pin(0));
|
||||
NetNet::WIRE, 1);
|
||||
|
||||
des->add_node(mux);
|
||||
out->local_flag(true);
|
||||
connect(out->pin(0), mux->pin(0));
|
||||
return out;
|
||||
#else
|
||||
cerr << get_line() << ": sorry: Forgot how to implement"
|
||||
<< " NetMux in elaborate_net_bitmux_." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||
|
|
@ -2508,6 +2505,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $Log: elab_net.cc,v $
|
||||
* Revision 1.162 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.161 2005/05/06 00:25:13 steve
|
||||
* Handle synthesis of concatenation expressions.
|
||||
*
|
||||
|
|
|
|||
12
ivl_target.h
12
ivl_target.h
|
|
@ -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.153 2005/05/07 03:14:00 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.154 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -856,11 +856,16 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
|||
* model part/bin selects in r-value expressions, where the _PV from
|
||||
* is meant to model part selects in l-value nets.
|
||||
*
|
||||
* In both cases, ivl_lpm_data is the input pin, and ivl_lpm_q is the
|
||||
* In both cases, ivl_lpm_data(0) is the input pin, and ivl_lpm_q is the
|
||||
* output. In the case of the _VP device, the vector is input and the
|
||||
* part is the output. In the case of the _PV device, the part is the
|
||||
* input and the vector is the output.
|
||||
*
|
||||
* If the base of the part select is non-constant, then
|
||||
* ivl_lpm_data(1) is non-nil and is the select, or base, address of
|
||||
* the part. If this pin is nil, then the constant base is used
|
||||
* instead.
|
||||
*
|
||||
* Also in both cases, the width of the device is the width of the
|
||||
* part. In the _VP case, this is obvious as the output nexus has the
|
||||
* part width. In the _PV case, this is a little less obvious, but
|
||||
|
|
@ -1653,6 +1658,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.154 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.153 2005/05/07 03:14:00 steve
|
||||
* Clarify internal delays for assignments.
|
||||
*
|
||||
|
|
|
|||
34
netlist.cc
34
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: netlist.cc,v 1.242 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.243 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -490,6 +490,35 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
|
|||
pin(1).set_name(perm_string::literal("Vect"), 0);
|
||||
}
|
||||
|
||||
NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid)
|
||||
: NetNode(sig->scope(), sig->scope()->local_symbol(), 3),
|
||||
off_(0), wid_(wid), dir_(VP)
|
||||
{
|
||||
connect(pin(1), sig->pin(0));
|
||||
connect(pin(2), sel->pin(0));
|
||||
|
||||
switch (dir_) {
|
||||
case NetPartSelect::VP:
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(1).set_dir(Link::INPUT);
|
||||
break;
|
||||
case NetPartSelect::PV:
|
||||
pin(0).set_dir(Link::INPUT);
|
||||
pin(1).set_dir(Link::OUTPUT);
|
||||
break;
|
||||
case NetPartSelect::BI:
|
||||
pin(0).set_dir(Link::PASSIVE);
|
||||
pin(1).set_dir(Link::PASSIVE);
|
||||
break;
|
||||
}
|
||||
pin(2).set_dir(Link::INPUT);
|
||||
|
||||
pin(0).set_name(perm_string::literal("Part"), 0);
|
||||
pin(1).set_name(perm_string::literal("Vect"), 0);
|
||||
pin(2).set_name(perm_string::literal("Select"), 0);
|
||||
}
|
||||
|
||||
NetPartSelect::~NetPartSelect()
|
||||
{
|
||||
}
|
||||
|
|
@ -2156,6 +2185,9 @@ const NetProc*NetTaskDef::proc() const
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.243 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.242 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
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.341 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.342 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1193,6 +1193,10 @@ class NetECRealParam : public NetECReal {
|
|||
* The part to be selected is the canonical (0-based) offset and the
|
||||
* specified number of bits (wid).
|
||||
*
|
||||
* If the offset is non-constant, then pin(2) is the input vector for
|
||||
* the selector. If this pin is present, then use the non-constant
|
||||
* selector as the input.
|
||||
*
|
||||
* The NetPartSelect can be output from the signal (i.e. reading a
|
||||
* part), input into the signal, or bi-directional. The DIR method
|
||||
* gives the type of the node.
|
||||
|
|
@ -1220,6 +1224,8 @@ class NetPartSelect : public NetNode {
|
|||
|
||||
explicit NetPartSelect(NetNet*sig,
|
||||
unsigned off, unsigned wid, dir_t dir);
|
||||
explicit NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid);
|
||||
~NetPartSelect();
|
||||
|
||||
unsigned base() const;
|
||||
|
|
@ -3437,6 +3443,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.342 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.341 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
12
t-dll-api.cc
12
t-dll-api.cc
|
|
@ -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.125 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: t-dll-api.cc,v 1.126 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -828,8 +828,11 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
|||
|
||||
case IVL_LPM_PART_VP:
|
||||
case IVL_LPM_PART_PV:
|
||||
assert(idx == 0);
|
||||
return net->u_.part.a;
|
||||
assert(idx <= 1);
|
||||
if (idx == 0)
|
||||
return net->u_.part.a;
|
||||
else
|
||||
return net->u_.part.s;
|
||||
|
||||
case IVL_LPM_REPEAT:
|
||||
assert(idx == 0);
|
||||
|
|
@ -2032,6 +2035,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-api.cc,v $
|
||||
* Revision 1.126 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.125 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
14
t-dll.cc
14
t-dll.cc
|
|
@ -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.148 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: t-dll.cc,v 1.149 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1720,6 +1720,7 @@ bool dll_target::part_select(const NetPartSelect*net)
|
|||
obj->u_.part.width = net->width();
|
||||
obj->u_.part.base = net->base();
|
||||
obj->u_.part.signed_flag = 0;
|
||||
obj->u_.part.s = 0;
|
||||
const Nexus*nex;
|
||||
|
||||
switch (obj->type) {
|
||||
|
|
@ -1735,6 +1736,14 @@ bool dll_target::part_select(const NetPartSelect*net)
|
|||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.part.a = (ivl_nexus_t) nex->t_cookie();
|
||||
|
||||
/* If the part select has an additional pin, that pin is
|
||||
a variable select base. */
|
||||
if (net->pin_count() >= 3) {
|
||||
nex = net->pin(2).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->u_.part.s = (ivl_nexus_t) nex->t_cookie();
|
||||
}
|
||||
break;
|
||||
|
||||
case IVL_LPM_PART_PV:
|
||||
|
|
@ -2071,6 +2080,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|||
|
||||
/*
|
||||
* $Log: t-dll.cc,v $
|
||||
* Revision 1.149 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.148 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
7
t-dll.h
7
t-dll.h
|
|
@ -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.124 2005/04/01 06:04:30 steve Exp $"
|
||||
#ident "$Id: t-dll.h,v 1.125 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -344,7 +344,7 @@ struct ivl_lpm_s {
|
|||
unsigned width;
|
||||
unsigned base;
|
||||
unsigned signed_flag :1;
|
||||
ivl_nexus_t q, a;
|
||||
ivl_nexus_t q, a, s;
|
||||
} part;
|
||||
|
||||
// IVL_LPM_RE_* and IVL_LPM_REPEAT use this.
|
||||
|
|
@ -685,6 +685,9 @@ struct ivl_variable_s {
|
|||
|
||||
/*
|
||||
* $Log: t-dll.h,v $
|
||||
* Revision 1.125 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.124 2005/04/01 06:04:30 steve
|
||||
* Clean up handle of UDPs.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: statement.c,v 1.5 2005/03/05 05:47:42 steve Exp $"
|
||||
#ident "$Id: statement.c,v 1.6 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -190,6 +190,9 @@ void show_statement(ivl_statement_t net, unsigned ind)
|
|||
for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1)
|
||||
show_assign_lval(ivl_stmt_lval(net, idx), ind+4);
|
||||
|
||||
if (ivl_stmt_delay_expr(net))
|
||||
show_expression(ivl_stmt_delay_expr(net), idx+4);
|
||||
|
||||
if (ivl_stmt_rval(net))
|
||||
show_expression(ivl_stmt_rval(net), ind+4);
|
||||
break;
|
||||
|
|
@ -201,6 +204,11 @@ void show_statement(ivl_statement_t net, unsigned ind)
|
|||
for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1)
|
||||
show_assign_lval(ivl_stmt_lval(net, idx), ind+4);
|
||||
|
||||
if (ivl_stmt_delay_expr(net)) {
|
||||
fprintf(out, "%*s<internal delay>\n", ind+4, "");
|
||||
show_expression(ivl_stmt_delay_expr(net), ind+6);
|
||||
}
|
||||
|
||||
if (ivl_stmt_rval(net))
|
||||
show_expression(ivl_stmt_rval(net), ind+4);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: stub.c,v 1.123 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: stub.c,v 1.124 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -544,6 +544,7 @@ static void show_lpm_part(ivl_lpm_t net)
|
|||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
unsigned base = ivl_lpm_base(net);
|
||||
ivl_nexus_t sel = ivl_lpm_data(net,1);
|
||||
const char*part_type_string = "";
|
||||
|
||||
switch (ivl_lpm_type(net)) {
|
||||
|
|
@ -563,6 +564,14 @@ static void show_lpm_part(ivl_lpm_t net)
|
|||
fprintf(out, " O: %s\n", ivl_nexus_name(ivl_lpm_q(net,0)));
|
||||
fprintf(out, " I: %s\n", ivl_nexus_name(ivl_lpm_data(net,0)));
|
||||
|
||||
if (sel != 0) {
|
||||
fprintf(out, " S: %s\n", ivl_nexus_name(sel));
|
||||
if (base != 0) {
|
||||
fprintf(out, " ERROR: Part select has base AND selector\n");
|
||||
stub_errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* The compiler must assure that the base plus the part select
|
||||
width fits within the input to the part select. */
|
||||
if (width_of_nexus(ivl_lpm_data(net,0)) < (width+base)) {
|
||||
|
|
@ -1353,6 +1362,9 @@ int target_design(ivl_design_t des)
|
|||
|
||||
/*
|
||||
* $Log: stub.c,v $
|
||||
* Revision 1.124 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.123 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.126 2005/04/24 23:44:02 steve Exp $"
|
||||
#ident "$Id: vvp_scope.c,v 1.127 2005/05/08 23:44:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -1683,19 +1683,29 @@ static void draw_lpm_ufunc(ivl_lpm_t net)
|
|||
}
|
||||
|
||||
/*
|
||||
* Handle a PART SELECT device. This has a single input and output.
|
||||
* Handle a PART SELECT device. This has a single input and output,
|
||||
* plus an optional extra input that is a non-constant base.
|
||||
*/
|
||||
static void draw_lpm_part(ivl_lpm_t net)
|
||||
{
|
||||
unsigned width, base;
|
||||
ivl_nexus_t sel;
|
||||
|
||||
width = ivl_lpm_width(net);
|
||||
base = ivl_lpm_base(net);
|
||||
sel = ivl_lpm_data(net,1);
|
||||
|
||||
fprintf(vvp_out, "L_%p .part ", net);
|
||||
draw_input_from_net(ivl_lpm_data(net, 0));
|
||||
|
||||
fprintf(vvp_out, ", %u, %u;\n", base, width);
|
||||
if (sel == 0) {
|
||||
fprintf(vvp_out, "L_%p .part ", net);
|
||||
draw_input_from_net(ivl_lpm_data(net, 0));
|
||||
fprintf(vvp_out, ", %u, %u;\n", base, width);
|
||||
} else {
|
||||
fprintf(vvp_out, "L_%p .part/v ", net);
|
||||
draw_input_from_net(ivl_lpm_data(net,0));
|
||||
fprintf(vvp_out, ", ");
|
||||
draw_input_from_net(sel);
|
||||
fprintf(vvp_out, ", %u;\n", width);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1932,6 +1942,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
|
||||
/*
|
||||
* $Log: vvp_scope.c,v $
|
||||
* Revision 1.127 2005/05/08 23:44:08 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.126 2005/04/24 23:44:02 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.65 2005/05/01 22:05:21 steve Exp $
|
||||
* $Id: README.txt,v 1.66 2005/05/08 23:40:14 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -459,6 +459,7 @@ bit number, and a width. Normally, those bits are constant values.
|
|||
|
||||
<label> .part <symbol>, <base>, <wid>;
|
||||
<label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
|
||||
<label> .part/v <symbol>, <symbol>, <wid>;
|
||||
|
||||
The input is typically a .reg or .net, but can be any vector node in
|
||||
the netlist.
|
||||
|
|
@ -470,6 +471,8 @@ network. The <vector_wid> is the total width of the destination net
|
|||
that part is written to. Destination nodes use this value to check
|
||||
further output widths.
|
||||
|
||||
The .part/v variation takes a vector (or long) input on port-1 as the
|
||||
base of the part select. Thus, the part select can move around.
|
||||
|
||||
PART CONCATENATION STATEMENTS:
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compile.h,v 1.70 2005/04/28 04:59:53 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.71 2005/05/08 23:40:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -113,6 +113,8 @@ extern void compile_part_select(char*label, char*src,
|
|||
extern void compile_part_select_pv(char*label, char*src,
|
||||
unsigned base, unsigned wid,
|
||||
unsigned vec_wid);
|
||||
extern void compile_part_select_var(char*label, char*src,
|
||||
char*var, unsigned wid);
|
||||
|
||||
/*
|
||||
* This is called by the parser to make the various arithmetic and
|
||||
|
|
@ -309,6 +311,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.71 2005/05/08 23:40:14 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.70 2005/04/28 04:59:53 steve
|
||||
* Remove dead functor code.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: lexor.lex,v 1.52 2005/04/28 04:59:53 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.53 2005/05/08 23:40:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -107,6 +107,7 @@
|
|||
".param" { return K_PARAM; }
|
||||
".part" { return K_PART; }
|
||||
".part/pv" { return K_PART_PV; }
|
||||
".part/v" { return K_PART_V; }
|
||||
".reduce/and" { return K_REDUCE_AND; }
|
||||
".reduce/or" { return K_REDUCE_OR; }
|
||||
".reduce/xor" { return K_REDUCE_XOR; }
|
||||
|
|
@ -194,6 +195,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.53 2005/05/08 23:40:14 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.52 2005/04/28 04:59:53 steve
|
||||
* Remove dead functor code.
|
||||
*
|
||||
|
|
|
|||
10
vvp/parse.y
10
vvp/parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: parse.y,v 1.73 2005/04/28 04:59:53 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.74 2005/05/08 23:40:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -63,7 +63,7 @@ extern FILE*yyin;
|
|||
%token K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
|
||||
%token K_CONCAT K_DFF
|
||||
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_PARAM K_PART K_PART_PV
|
||||
%token K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
||||
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
||||
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
|
||||
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
|
|
@ -194,6 +194,9 @@ statement
|
|||
| T_LABEL K_PART_PV T_SYMBOL ',' T_NUMBER ',' T_NUMBER ',' T_NUMBER ';'
|
||||
{ compile_part_select_pv($1, $3, $5, $7, $9); }
|
||||
|
||||
| T_LABEL K_PART_V T_SYMBOL ',' T_SYMBOL ',' T_NUMBER ';'
|
||||
{ compile_part_select_var($1, $3, $5, $7); }
|
||||
|
||||
| T_LABEL K_CONCAT '[' T_NUMBER T_NUMBER T_NUMBER T_NUMBER ']' ','
|
||||
symbols ';'
|
||||
{ compile_concat($1, $4, $5, $6, $7, $10.cnt, $10.vect); }
|
||||
|
|
@ -678,6 +681,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.74 2005/05/08 23:40:14 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.73 2005/04/28 04:59:53 steve
|
||||
* Remove dead functor code.
|
||||
*
|
||||
|
|
|
|||
59
vvp/part.cc
59
vvp/part.cc
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: part.cc,v 1.3 2005/01/09 20:11:16 steve Exp $"
|
||||
#ident "$Id: part.cc,v 1.4 2005/05/08 23:40:14 steve Exp $"
|
||||
|
||||
# include "compile.h"
|
||||
# include "vvp_net.h"
|
||||
|
|
@ -67,6 +67,46 @@ void vvp_fun_part_pv::recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit)
|
|||
vvp_send_vec4_pv(port.ptr()->out, bit, base_, wid_, vwid_);
|
||||
}
|
||||
|
||||
vvp_fun_part_var::vvp_fun_part_var(unsigned w)
|
||||
: base_(0), wid_(w)
|
||||
{
|
||||
}
|
||||
|
||||
vvp_fun_part_var::~vvp_fun_part_var()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_fun_part_var::recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit)
|
||||
{
|
||||
unsigned long tmp;
|
||||
switch (port.port()) {
|
||||
case 0:
|
||||
source_ = bit;
|
||||
break;
|
||||
case 1:
|
||||
vector4_to_value(bit, tmp);
|
||||
if (tmp == base_) return;
|
||||
base_ = tmp;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
vvp_vector4_t res (wid_);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||
unsigned adr = base_+idx;
|
||||
if (adr >= source_.size())
|
||||
break;
|
||||
|
||||
res.set_bit(idx, source_.value(adr));
|
||||
}
|
||||
|
||||
vvp_send_vec4(port.ptr()->out, res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a node functor, create a network node and link it into the
|
||||
* netlist. This form assumes nodes with a single input.
|
||||
|
|
@ -97,8 +137,25 @@ void compile_part_select_pv(char*label, char*source,
|
|||
link_node_1(label, source, fun);
|
||||
}
|
||||
|
||||
void compile_part_select_var(char*label, char*source, char*var,
|
||||
unsigned wid)
|
||||
{
|
||||
vvp_fun_part_var*fun = new vvp_fun_part_var(wid);
|
||||
vvp_net_t*net = new vvp_net_t;
|
||||
net->fun = fun;
|
||||
|
||||
define_functor_symbol(label, net);
|
||||
free(label);
|
||||
|
||||
input_connect(net, 0, source);
|
||||
input_connect(net, 1, var);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: part.cc,v $
|
||||
* Revision 1.4 2005/05/08 23:40:14 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.3 2005/01/09 20:11:16 steve
|
||||
* Add the .part/pv node and related functionality.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: vvp_net.h,v 1.25 2005/05/07 03:14:50 steve Exp $"
|
||||
#ident "$Id: vvp_net.h,v 1.26 2005/05/08 23:40:14 steve Exp $"
|
||||
|
||||
# include "config.h"
|
||||
# include <assert.h>
|
||||
|
|
@ -530,6 +530,26 @@ class vvp_fun_part_pv : public vvp_net_fun_t {
|
|||
unsigned vwid_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This part select is more flexible in that it takes the vector to
|
||||
* part in port 0, and the base of the part in port 1. The width of
|
||||
* the part to take out is fixed.
|
||||
*/
|
||||
class vvp_fun_part_var : public vvp_net_fun_t {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_part_var(unsigned wid);
|
||||
~vvp_fun_part_var();
|
||||
|
||||
public:
|
||||
void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
|
||||
|
||||
private:
|
||||
unsigned base_;
|
||||
unsigned wid_;
|
||||
vvp_vector4_t source_;
|
||||
};
|
||||
|
||||
/* vvp_fun_signal
|
||||
* This node is the place holder in a vvp network for signals,
|
||||
* including nets of various sort. The output from a signal follows
|
||||
|
|
@ -699,6 +719,9 @@ class vvp_wide_fun_t : public vvp_net_fun_t {
|
|||
|
||||
/*
|
||||
* $Log: vvp_net.h,v $
|
||||
* Revision 1.26 2005/05/08 23:40:14 steve
|
||||
* Add support for variable part select.
|
||||
*
|
||||
* Revision 1.25 2005/05/07 03:14:50 steve
|
||||
* ostream insert for vvp_vector4_t objects.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue