Add the NetRepeat node, and code generator support.

This commit is contained in:
steve 2005-02-08 00:12:36 +00:00
parent ca1bbc79a3
commit ee5bb5fcaf
13 changed files with 274 additions and 17 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: design_dump.cc,v 1.155 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: design_dump.cc,v 1.156 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -366,6 +366,7 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetRamDq::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_RAM_DQ (" << mem_->name() << "): "
@ -374,6 +375,15 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetReplicate::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetReplicate: "
<< name() << " wid=" << width_ << ", repeat_=" << repeat_
<< ", input wid=" << width_/repeat_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUReduce::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "reduction logic: ";
@ -1129,6 +1139,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.156 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.155 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.316 2005/01/30 01:42:05 steve Exp $"
#ident "$Id: elaborate.cc,v 1.317 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -471,6 +471,26 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
if (count == 1) {
/* Handle the case where there is one gate that
carries the whole vector width. */
if (instance_width != sig->vector_width()) {
assert(sig->vector_width() == 1);
NetReplicate*rep
= new NetReplicate(scope,
scope->local_symbol(),
instance_width,
instance_width);
rep->set_line(*this);
des->add_node(rep);
connect(rep->pin(1), sig->pin(0));
sig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, instance_width);
sig->local_flag(true);
sig->set_line(*this);
connect(rep->pin(0), sig->pin(0));
}
connect(cur[0]->pin(idx), sig->pin(0));
} else if (sig->vector_width() == 1) {
@ -2885,6 +2905,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.317 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.316 2005/01/30 01:42:05 steve
* Debug messages for PGAssign elaboration.
*

10
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.82 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: emit.cc,v 1.83 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -126,6 +126,11 @@ bool NetRamDq::emit_node(struct target_t*tgt) const
return true;
}
bool NetReplicate::emit_node(struct target_t*tgt) const
{
return tgt->replicate(this);
}
bool NetUReduce::emit_node(struct target_t*tgt) const
{
return tgt->ureduce(this);
@ -518,6 +523,9 @@ int emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.83 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.82 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.138 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: ivl_target.h,v 1.139 2005/02/08 00:12:36 steve Exp $"
#endif
#ifdef __cplusplus
@ -244,6 +244,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_RE_OR = 23,
IVL_LPM_RE_XNOR= 24,
IVL_LPM_RE_XOR = 25,
IVL_LPM_REPEAT = 26,
IVL_LPM_SHIFTL = 6,
IVL_LPM_SHIFTR = 7,
IVL_LPM_SUB = 8,
@ -810,6 +811,13 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* These devices have one input, a vector, and generate a single bit
* result. The width from the ivl_lpm_width is the width of the input
* vector.
*
* - Repeat Node (IVL_LPM_REPEAT)
* This node takes as input a single vector, and outputs a single
* vector. The ivl_lpm_width if this node is the width of the *output*
* vector. The ivl_lpm_size() returns the number of times the input is
* repeated to get the desired width. The ivl core assures that the
* input vector is exactly ivl_lpm_width() / ivl_lpm_size() bits.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
@ -850,7 +858,7 @@ extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
/* IVL_LPM_MUX IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_CONCAT IVL_LPM_MUX */
/* IVL_LPM_CONCAT IVL_LPM_MUX IVL_LPM_REPEAT */
extern unsigned ivl_lpm_size(ivl_lpm_t net);
/* IVL_LPM_RAM */
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
@ -1481,6 +1489,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.139 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.138 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.235 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: netlist.cc,v 1.236 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -559,6 +559,30 @@ unsigned NetConcat::width() const
return width_;
}
NetReplicate::NetReplicate(NetScope*scope, perm_string n,
unsigned wid, unsigned rpt)
: NetNode(scope, n, 2), width_(wid), repeat_(rpt)
{
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(perm_string::literal("O"), 0);
pin(1).set_dir(Link::INPUT);
pin(1).set_name(perm_string::literal("I"), 0);
}
NetReplicate::~NetReplicate()
{
}
unsigned NetReplicate::width() const
{
return width_;
}
unsigned NetReplicate::repeat() const
{
return repeat_;
}
/*
* The NetFF class represents an LPM_FF device. The pinout is assigned
* like so:
@ -2269,6 +2293,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.236 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.235 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.332 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: netlist.h,v 1.333 2005/02/08 00:12:36 steve Exp $"
#endif
/*
@ -940,6 +940,36 @@ class NetRamDq : public NetNode {
};
/*
* The NetReplicate node takes a vector input and makes it into a larger
* vector by repeating the input vector some number of times. The
* repeat count is a fixed value. This is just like the repeat
* concatenation of Verilog: {<repeat>{<vector>}}.
*
* When construction this node, the wid is the vector width of the
* output, and the rpt is the repeat count. The wid must be an even
* multiple of the cnt, and wid/cnt is the expected input width.
*
* The device has exacly 2 pins: pin(0) is the output and pin(1) the
* input.
*/
class NetReplicate : public NetNode {
public:
NetReplicate(NetScope*scope, perm_string n, unsigned wid, unsigned rpt);
~NetReplicate();
unsigned width() const;
unsigned repeat() const;
void dump_node(ostream&, unsigned ind) const;
bool emit_node(struct target_t*) const;
private:
unsigned width_;
unsigned repeat_;
};
/*
* This node represents the call of a user defined function in a
* structural context.
@ -3396,6 +3426,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.333 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.332 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.116 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.117 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -786,6 +786,10 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
assert(idx == 0);
return net->u_.part.a;
case IVL_LPM_REPEAT:
assert(idx == 0);
return net->u_.repeat.a;
default:
assert(0);
return 0;
@ -947,6 +951,10 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
assert(idx == 0);
return net->u_.part.q;
case IVL_LPM_REPEAT:
assert(idx == 0);
return net->u_.repeat.q;
default:
assert(0);
return 0;
@ -1041,6 +1049,8 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
return net->u_.part.signed_flag;
case IVL_LPM_REPEAT:
return 0;
default:
assert(0);
return 0;
@ -1054,6 +1064,8 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
return net->u_.mux.size;
case IVL_LPM_UFUNC:
return net->u_.ufunc.ports - 1;
case IVL_LPM_REPEAT:
return net->u_.repeat.count;
default:
assert(0);
return 0;
@ -1102,6 +1114,8 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
return net->u_.part.width;
case IVL_LPM_REPEAT:
return net->u_.repeat.width;
default:
assert(0);
return 0;
@ -1984,6 +1998,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.117 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.116 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.138 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: t-dll.cc,v 1.139 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -1950,6 +1950,37 @@ bool dll_target::part_select(const NetPartSelect*net)
return true;
}
bool dll_target::replicate(const NetReplicate*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_REPEAT;
obj->name = net->name();
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
obj->u_.repeat.width = net->width();
obj->u_.repeat.count = net->repeat();
ivl_drive_t dr = IVL_DR_STRONG;
const Nexus*nex = net->pin(0).nexus();
assert(nex->t_cookie());
obj->u_.repeat.q = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.repeat.q, obj, 0, dr, dr);
dr = IVL_DR_HiZ;
nex = net->pin(1).nexus();
assert(nex->t_cookie());
obj->u_.repeat.a = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.repeat.a, obj, 0, dr, dr);
scope_add_lpm(obj->scope, obj);
return true;
}
/*
* The assignment l-values are captured by the assignment statements
* themselves in the process handling.
@ -2226,6 +2257,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.139 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.138 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

13
t-dll.h
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.119 2005/02/03 04:56:20 steve Exp $"
#ident "$Id: t-dll.h,v 1.120 2005/02/08 00:12:36 steve Exp $"
#endif
# include "target.h"
@ -85,6 +85,7 @@ struct dll_target : public target_t, public expr_scan_t {
void lpm_ram_dq(const NetRamDq*);
bool concat(const NetConcat*);
bool part_select(const NetPartSelect*);
bool replicate(const NetReplicate*);
void net_assign(const NetAssign_*);
bool net_function(const NetUserFunc*);
bool net_const(const NetConst*);
@ -355,11 +356,18 @@ struct ivl_lpm_s {
ivl_nexus_t q, a;
} part;
// IVL_LPM_RE_* and IVL_LPM_REPEAT use this.
struct ivl_lpm_reduce_s {
unsigned width;
ivl_nexus_t q, a;
} reduce;
struct ivl_lpm_repeat_s {
unsigned width;
unsigned count;
ivl_nexus_t q, a;
} repeat;
struct ivl_lpm_ufunc_s {
ivl_scope_t def;
unsigned ports;
@ -686,6 +694,9 @@ struct ivl_variable_s {
/*
* $Log: t-dll.h,v $
* Revision 1.120 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.119 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: target.cc,v 1.73 2005/02/03 04:56:21 steve Exp $"
#ident "$Id: target.cc,v 1.74 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -160,6 +160,13 @@ bool target_t::part_select(const NetPartSelect*)
return false;
}
bool target_t::replicate(const NetReplicate*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled NetReplicate." << endl;
return false;
}
void target_t::net_case_cmp(const NetCaseCmp*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -422,6 +429,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.74 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.73 2005/02/03 04:56:21 steve
* laborate reduction gates into LPM_RED_ nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: target.h,v 1.70 2005/02/03 04:56:21 steve Exp $"
#ident "$Id: target.h,v 1.71 2005/02/08 00:12:36 steve Exp $"
#endif
# include "netlist.h"
@ -88,6 +88,7 @@ struct target_t {
virtual bool concat(const NetConcat*);
virtual bool part_select(const NetPartSelect*);
virtual bool replicate(const NetReplicate*);
/* Output a gate (called for each gate) */
virtual void logic(const NetLogic*);
@ -171,6 +172,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.71 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.70 2005/02/03 04:56:21 steve
* laborate reduction gates into LPM_RED_ nodes.
*

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.106 2005/02/03 04:56:21 steve Exp $"
#ident "$Id: stub.c,v 1.107 2005/02/08 00:12:36 steve Exp $"
#endif
# include "config.h"
@ -422,6 +422,36 @@ static void show_lpm_re(ivl_lpm_t net)
}
}
static void show_lpm_repeat(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
unsigned count = ivl_lpm_size(net);
ivl_nexus_t nex_q = ivl_lpm_q(net,0);
ivl_nexus_t nex_a = ivl_lpm_data(net,0);
fprintf(out, " LPM_REPEAT %s: <width=%u, count=%u>\n",
ivl_lpm_basename(net), width, count);
fprintf(out, " Q: %s\n", ivl_nexus_name(nex_q));
fprintf(out, " D: %s\n", ivl_nexus_name(nex_a));
if (width != width_of_nexus(nex_q)) {
fprintf(out, " ERROR: Width of Q is %u, expecting %u\n",
width_of_nexus(nex_q), width);
stub_errors += 1;
}
if (count == 0 || count > width || (width%count != 0)) {
fprintf(out, " ERROR: Repeat count not reasonable\n");
stub_errors += 1;
} else if (width/count != width_of_nexus(nex_a)) {
fprintf(out, " ERROR: Windth of D is %u, expecting %u\n",
width_of_nexus(nex_a), width/count);
stub_errors += 1;
}
}
static void show_lpm_sub(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
@ -598,6 +628,10 @@ static void show_lpm(ivl_lpm_t net)
break;
}
case IVL_LPM_REPEAT:
show_lpm_repeat(net);
break;
default:
fprintf(out, " LPM(%d) %s: <width=%u, signed=%d>\n",
ivl_lpm_type(net),
@ -1058,6 +1092,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.107 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.106 2005/02/03 04:56:21 steve
* laborate reduction gates into LPM_RED_ nodes.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2005 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
@ -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.114 2005/02/04 05:13:57 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.115 2005/02/08 00:12:36 steve Exp $"
#endif
# include "vvp_priv.h"
@ -126,6 +126,17 @@ const char *vvp_mangle_name(const char *id)
return out;
}
static void draw_C4_repeated_constant(char bit_char, unsigned width)
{
unsigned idx;
fprintf(vvp_out, "C4<");
for (idx = 0 ; idx < width ; idx += 1)
fprintf(vvp_out, "%c", bit_char);
fprintf(vvp_out, ">");
}
/*
* Given a signal, generate a string name that is suitable for use as
* a label. The only rule is that the same signal will always have the
@ -453,6 +464,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
case IVL_LPM_UFUNC:
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV: /* NOTE: This is only a partial driver. */
case IVL_LPM_REPEAT:
if (ivl_lpm_q(lpm, 0) == nex) {
sprintf(result, "L_%p", lpm);
return result;
@ -601,8 +613,10 @@ const char* draw_net_input(ivl_nexus_t nex)
draw_net_input_drive(nex, drivers[idx]));
}
}
for ( ; idx < inst+4 ; idx += 1)
fprintf(vvp_out, ", C4<z>");
for ( ; idx < inst+4 ; idx += 1) {
fprintf(vvp_out, ", ");
draw_C4_repeated_constant('z',width_of_nexus(nex));
}
fprintf(vvp_out, ";\n");
}
@ -1689,6 +1703,14 @@ static void draw_lpm_re(ivl_lpm_t net, const char*type)
fprintf(vvp_out, ";\n");
}
static void draw_lpm_repeat(ivl_lpm_t net)
{
fprintf(vvp_out, "L_%p .repeat %u, %u, ", net,
ivl_lpm_width(net), ivl_lpm_size(net));
draw_input_from_net(ivl_lpm_data(net,0));
fprintf(vvp_out, ";\n");
}
static void draw_lpm_in_scope(ivl_lpm_t net)
{
switch (ivl_lpm_type(net)) {
@ -1752,6 +1774,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
draw_lpm_re(net, "xnor");
return;
case IVL_LPM_REPEAT:
draw_lpm_repeat(net);
return;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
draw_lpm_shiftl(net);
@ -1884,6 +1910,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.115 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.114 2005/02/04 05:13:57 steve
* Support .concat with arbitrary input counts.
*