Add support for variable part select.

This commit is contained in:
steve 2005-05-08 23:40:14 +00:00
parent 48aa0f0075
commit 7dd0d255a6
16 changed files with 263 additions and 62 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: 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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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;

View File

@ -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.
*

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.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.
*

View File

@ -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:

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*