Handle signed magnitude compare all the

way through to the vvp code generator.
This commit is contained in:
steve 2003-04-11 05:18:08 +00:00
parent 2c1e36ae9a
commit 5d1d99a89f
10 changed files with 173 additions and 35 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.111 2003/03/29 05:51:25 steve Exp $"
#ident "$Id: elab_net.cc,v 1.112 2003/04/11 05:18:08 steve Exp $"
#endif
# include "config.h"
@ -421,14 +421,31 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned dwidth = lsig->pin_count();
if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count();
NetNet*zero = 0;
/* Operands of binary compare need to be padded to equal
size. Figure the pad bit needed to extend the narrowest
vector. */
NetNet*padbit = 0;
if (lsig->pin_count() != rsig->pin_count()) {
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(tmp);
zero = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
zero->local_flag(true);
connect(tmp->pin(0), zero->pin(0));
unsigned lwid = lsig->pin_count();
unsigned rwid = rsig->pin_count();
padbit = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
padbit->local_flag(true);
if (lsig->get_signed() && (lwid < rwid)) {
connect(padbit->pin(0), lsig->pin(lwid-1));
} else if (rsig->get_signed() && (rwid < lwid)) {
connect(padbit->pin(0), rsig->pin(rwid-1));
} else {
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(tmp);
connect(tmp->pin(0), padbit->pin(0));
}
}
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
@ -447,11 +464,11 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(cmp->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = lsig->pin_count(); idx < dwidth ; idx += 1)
connect(cmp->pin_DataA(idx), zero->pin(0));
connect(cmp->pin_DataA(idx), padbit->pin(0));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(cmp->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = rsig->pin_count(); idx < dwidth ; idx += 1)
connect(cmp->pin_DataB(idx), zero->pin(0));
connect(cmp->pin_DataB(idx), padbit->pin(0));
switch (op_) {
case '<':
@ -467,6 +484,11 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
connect(cmp->pin_AGEB(), osig->pin(0));
break;
}
/* If both operands are signed, then do a signed
compare. */
if (lsig->get_signed() && rsig->get_signed())
cmp->set_signed(true);
gate = cmp;
break;
}
@ -487,12 +509,12 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
if (idx < lsig->pin_count())
connect(cmp->pin(1), lsig->pin(idx));
else
connect(cmp->pin(1), zero->pin(0));
connect(cmp->pin(1), padbit->pin(0));
if (idx < rsig->pin_count())
connect(cmp->pin(2), rsig->pin(idx));
else
connect(cmp->pin(2), zero->pin(0));
connect(cmp->pin(2), padbit->pin(0));
connect(cmp->pin(0), gate->pin(idx+1));
des->add_node(cmp);
@ -527,12 +549,12 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
if (idx < lsig->pin_count())
connect(cmp->pin_DataA(idx), lsig->pin(idx));
else
connect(cmp->pin_DataA(idx), zero->pin(0));
connect(cmp->pin_DataA(idx), padbit->pin(0));
if (idx < rsig->pin_count())
connect(cmp->pin_DataB(idx), rsig->pin(idx));
else
connect(cmp->pin_DataB(idx), zero->pin(0));
connect(cmp->pin_DataB(idx), padbit->pin(0));
}
connect(cmp->pin_AEB(), osig->pin(0));
@ -561,12 +583,12 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
if (idx < lsig->pin_count())
connect(cmp->pin_DataA(idx), lsig->pin(idx));
else
connect(cmp->pin_DataA(idx), zero->pin(0));
connect(cmp->pin_DataA(idx), padbit->pin(0));
if (idx < rsig->pin_count())
connect(cmp->pin_DataB(idx), rsig->pin(idx));
else
connect(cmp->pin_DataB(idx), zero->pin(0));
connect(cmp->pin_DataB(idx), padbit->pin(0));
}
connect(cmp->pin_ANEB(), osig->pin(0));
@ -1014,16 +1036,36 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
* This method elaborates a call to a function in the context of a
* continuous assignment.
*/
NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, unsigned,
unsigned long,
unsigned long,
unsigned long,
Link::strength_t,
Link::strength_t) const
NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const
{
unsigned errors = 0;
unsigned func_pins = 0;
/* Handle the special case that the function call is to
$signed. This takes a single expression argument, and
forces it to be a signed result. Otherwise, it is as if the
$signed did not exist. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(true);
return sub;
}
/* Look up the function definition. */
NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) {
@ -1276,6 +1318,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
const NetEConst*pc = dynamic_cast<const NetEConst*>(pe);
assert(pc);
verinum pvalue = pc->value();
sig = new NetNet(scope, path_.peek_name(0),
NetNet::IMPLICIT, pc->expr_width());
NetConst*cp = new NetConst(scope, scope->local_symbol(),
@ -2281,6 +2324,10 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* Revision 1.112 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.111 2003/03/29 05:51:25 steve
* Sign extend NetMult inputs if result is signed.
*

View File

@ -75,6 +75,7 @@ ivl_lpm_q
ivl_lpm_scope
ivl_lpm_select
ivl_lpm_selects
ivl_lpm_signed
ivl_lpm_size
ivl_lpm_type
ivl_lpm_width

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.115 2003/03/10 23:40:53 steve Exp $"
#ident "$Id: ivl_target.h,v 1.116 2003/04/11 05:18:08 steve Exp $"
#endif
#ifdef __cplusplus
@ -643,6 +643,10 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* This is the size of the select input for a LPM_MUX device, or the
* address bus width of an LPM_RAM.
*
* ivl_lpm_signed
* Arithmetic LPM devices may be signed or unsigned if there is a
* distinction.
*
* ivl_lpm_size
* In addition to a width, some devices have a size. The size is
* often the number of inputs per out, i.e., the number of inputs
@ -652,6 +656,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
extern const char* ivl_lpm_basename(ivl_lpm_t net);
extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
extern int ivl_lpm_signed(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
@ -1204,6 +1209,10 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.116 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.115 2003/03/10 23:40:53 steve
* Keep parameter constants for the ivl_target API.
*

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.210 2003/03/29 05:51:25 steve Exp $"
#ident "$Id: netlist.cc,v 1.211 2003/04/11 05:18:08 steve Exp $"
#endif
# include "config.h"
@ -849,6 +849,7 @@ const Link& NetCLShift::pin_Distance(unsigned idx) const
NetCompare::NetCompare(NetScope*s, const string&n, unsigned wi)
: NetNode(s, lex_strings.add(n.c_str()), 8+2*wi), width_(wi)
{
signed_flag_ = false;
pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr");
pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock");
pin(2).set_dir(Link::OUTPUT); pin(2).set_name("AGB");
@ -874,6 +875,16 @@ unsigned NetCompare::width() const
return width_;
}
bool NetCompare::get_signed() const
{
return signed_flag_;
}
void NetCompare::set_signed(bool flag)
{
signed_flag_ = flag;
}
Link& NetCompare::pin_Aclr()
{
return pin(0);
@ -2151,6 +2162,10 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.211 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.210 2003/03/29 05:51:25 steve
* Sign extend NetMult inputs if result is signed.
*

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.284 2003/04/08 04:33:55 steve Exp $"
#ident "$Id: netlist.h,v 1.285 2003/04/11 05:18:08 steve Exp $"
#endif
/*
@ -533,6 +533,9 @@ class NetCompare : public NetNode {
unsigned width() const;
bool get_signed() const;
void set_signed(bool);
Link& pin_Aclr();
Link& pin_Clock();
Link& pin_AGB();
@ -563,6 +566,7 @@ class NetCompare : public NetNode {
private:
unsigned width_;
bool signed_flag_;
};
/*
@ -3246,6 +3250,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.285 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.284 2003/04/08 04:33:55 steve
* Synthesize shift expressions.
*

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.96 2003/03/10 23:40:53 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.97 2003/04/11 05:18:08 steve Exp $"
#endif
# include "config.h"
@ -902,6 +902,35 @@ extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
}
}
extern "C" int ivl_lpm_signed(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
case IVL_LPM_RAM:
case IVL_LPM_MUX:
return 0;
case IVL_LPM_ADD:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
return net->u_.arith.signed_flag;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
return 0;
case IVL_LPM_UFUNC:
return 0;
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
{
switch (net->type) {
@ -1797,6 +1826,10 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.97 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.96 2003/03/10 23:40:53 steve
* Keep parameter constants for the ivl_target API.
*

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.109 2003/03/29 05:51:25 steve Exp $"
#ident "$Id: t-dll.cc,v 1.110 2003/04/11 05:18:08 steve Exp $"
#endif
# include "config.h"
@ -1071,6 +1071,8 @@ void dll_target::lpm_add_sub(const NetAddSub*net)
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
obj->u_.arith.signed_flag = 0;
/* Choose the width of the adder. If the carry bit is
connected, then widen the adder by one and plan on leaving
the fake inputs unconnected. */
@ -1219,6 +1221,7 @@ void dll_target::lpm_compare(const NetCompare*net)
bool swap_operands = false;
obj->u_.arith.width = net->width();
obj->u_.arith.signed_flag = net->get_signed()? 1 : 0;
obj->u_.arith.q = new ivl_nexus_t[1 + 2 * obj->u_.arith.width];
obj->u_.arith.a = obj->u_.arith.q + 1;
@ -2117,6 +2120,10 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.110 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.109 2003/03/29 05:51:25 steve
* Sign extend NetMult inputs if result is signed.
*

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.100 2003/03/10 23:40:54 steve Exp $"
#ident "$Id: t-dll.h,v 1.101 2003/04/11 05:18:08 steve Exp $"
#endif
# include "target.h"
@ -334,7 +334,8 @@ struct ivl_lpm_s {
} shift;
struct ivl_lpm_arith_s {
unsigned short width;
unsigned width :16;
unsigned signed_flag :1;
ivl_nexus_t*q, *a, *b;
} arith;
@ -672,6 +673,10 @@ struct ivl_variable_s {
/*
* $Log: t-dll.h,v $
* Revision 1.101 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.100 2003/03/10 23:40:54 steve
* Keep parameter constants for the ivl_target API.
*

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.76 2003/03/29 05:51:26 steve Exp $"
#ident "$Id: stub.c,v 1.77 2003/04/11 05:18:08 steve Exp $"
#endif
# include "config.h"
@ -304,8 +304,11 @@ static void show_lpm(ivl_lpm_t net)
}
default:
fprintf(out, " %s: <width=%u>\n", ivl_lpm_basename(net),
ivl_lpm_width(net));
fprintf(out, " LPM(%d) %s: <width=%u, signed=%d>\n",
ivl_lpm_type(net),
ivl_lpm_basename(net),
ivl_lpm_width(net),
ivl_lpm_signed(net));
}
}
@ -837,6 +840,10 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.77 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.76 2003/03/29 05:51:26 steve
* Sign extend NetMult inputs if result is signed.
*

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.91 2003/03/25 02:15:48 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.92 2003/04/11 05:18:08 steve Exp $"
#endif
# include "vvp_priv.h"
@ -1133,6 +1133,7 @@ static void draw_lpm_cmp(ivl_lpm_t net)
{
unsigned width;
const char*type = "";
const char*signed_string = ivl_lpm_signed(net)? ".s" : "";
width = ivl_lpm_width(net);
@ -1147,9 +1148,10 @@ static void draw_lpm_cmp(ivl_lpm_t net)
assert(0);
}
fprintf(vvp_out, "L_%s.%s .cmp/%s %u",
fprintf(vvp_out, "L_%s.%s .cmp/%s%s %u",
vvp_mangle_id(ivl_scope_name(ivl_lpm_scope(net))),
vvp_mangle_id(ivl_lpm_basename(net)), type, width);
vvp_mangle_id(ivl_lpm_basename(net)), type,
signed_string, width);
draw_lpm_arith_a_b_inputs(net);
@ -1627,6 +1629,10 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.92 2003/04/11 05:18:08 steve
* Handle signed magnitude compare all the
* way through to the vvp code generator.
*
* Revision 1.91 2003/03/25 02:15:48 steve
* Use hash code for scope labels.
*