Skip to content

Commit

Permalink
Add power operator (**) for real values in a continuous assignment.
Browse files Browse the repository at this point in the history
This patch adds the power operator for real values in a continuous
assignment.
  • Loading branch information
caryr authored and steveicarus committed Feb 1, 2008
1 parent fa759c1 commit 5e8a1bd
Show file tree
Hide file tree
Showing 21 changed files with 361 additions and 616 deletions.
7 changes: 6 additions & 1 deletion PExpr.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* Copyright (c) 1998-2000 Stephen Williams <steve@icarus.com>
* Copyright (c) 1998-2008 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
Expand Down Expand Up @@ -589,6 +589,11 @@ class PEBinary : public PExpr {
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_pow_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
Expand Down
13 changes: 8 additions & 5 deletions design_dump.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008 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
Expand All @@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.176 2007/06/02 03:42:12 steve Exp $"
#endif

# include "config.h"

Expand Down Expand Up @@ -303,6 +300,13 @@ void NetMult::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}

void NetPow::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_POW (NetPow): " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}

void NetMux::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
Expand Down Expand Up @@ -1232,4 +1236,3 @@ void Design::dump(ostream&o) const
idx->dump(o, 0);

}

104 changes: 83 additions & 21 deletions elab_net.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
return elaborate_net_mod_(des, scope, width, rise, fall, decay);
case '/':
return elaborate_net_div_(des, scope, width, rise, fall, decay);
case 'p': // **
return elaborate_net_pow_(des, scope, width, rise, fall, decay);
case '+':
case '-':
return elaborate_net_add_(des, scope, width, rise, fall, decay);
Expand All @@ -96,10 +98,6 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
case 'r': // >>
case 'R': // >>>
return elaborate_net_shift_(des, scope, width, rise, fall, decay);
case 'p': // **
cerr << get_fileline() << ": sorry: ** is currently unsupported"
" in continuous assignments." << endl;
des->errors += 1;

return 0;
}
Expand Down Expand Up @@ -769,8 +767,6 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
des->errors += 1;
}

ivl_variable_type_t data_type = lsig->data_type();

// Create a device with the calculated dimensions.
NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth,
lsig->vector_width(),
Expand Down Expand Up @@ -799,7 +795,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
NetNet::IMPLICIT, lwidth);
osig->local_flag(true);
osig->set_line(*this);
osig->data_type(data_type);
osig->data_type( lsig->data_type() );
osig->set_signed(div->get_signed());

connect(div->pin_Result(), osig->pin(0));
Expand Down Expand Up @@ -838,8 +834,6 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope,
des->errors += 1;
}

ivl_variable_type_t data_type = lsig->data_type();

/* rwidth is result width. */
unsigned rwidth = lwidth;
if (rwidth == 0) {
Expand All @@ -865,7 +859,7 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope,
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, rwidth);
osig->set_line(*this);
osig->data_type(data_type);
osig->data_type( lsig->data_type() );
osig->local_flag(true);

connect(mod->pin_Result(), osig->pin(0));
Expand Down Expand Up @@ -1030,9 +1024,6 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (rsig == 0) return 0;

// The mult is signed if both its operands are signed.
bool arith_is_signed = lsig->get_signed() && rsig->get_signed();

/* The arguments of a multiply must have the same type. */
if (lsig->data_type() != rsig->data_type()) {
cerr << get_fileline() << ": error: Arguments of multiply "
Expand All @@ -1043,7 +1034,8 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
des->errors += 1;
}

ivl_variable_type_t data_type = lsig->data_type();
// The mult is signed if both its operands are signed.
bool arith_is_signed = lsig->get_signed() && rsig->get_signed();

unsigned rwidth = lwidth;
if (rwidth == 0) {
Expand Down Expand Up @@ -1079,13 +1071,84 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
// Make a signal to carry the output from the multiply.
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, rwidth);
osig->data_type(data_type);
osig->data_type( lsig->data_type() );
osig->local_flag(true);
connect(mult->pin_Result(), osig->pin(0));

return osig;
}

NetNet* PEBinary::elaborate_net_pow_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const
{
NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (lsig == 0) return 0;
NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (rsig == 0) return 0;

/* The arguments of a power must have the same type. */
if (lsig->data_type() != rsig->data_type()) {
cerr << get_fileline() << ": error: Arguments of power "
<< "have different data types." << endl;
cerr << get_fileline() << ": : Left argument is "
<< lsig->data_type() << ", right argument is "
<< rsig->data_type() << "." << endl;
des->errors += 1;
}

/* For now we only support real values. */
if (lsig->data_type() != IVL_VT_REAL) {
cerr << get_fileline() << ": sorry: Bit based power (**) is "
<< "currently unsupported in continuous assignments." << endl;
return 0;
}

// The power is signed if both its operands are signed.
bool arith_is_signed = lsig->get_signed() && rsig->get_signed();

unsigned rwidth = lwidth;
if (rwidth == 0) {
/* Reals are always 1 wide and lsig/rsig types match here. */
if (lsig->data_type() == IVL_VT_REAL) {
rwidth = 1;
lwidth = 1;
} else {
/* Nothing for now. Need integer value.*/
}
}

if (arith_is_signed) {
lsig = pad_to_width_signed(des, lsig, rwidth);
rsig = pad_to_width_signed(des, rsig, rwidth);
}

NetPow*powr = new NetPow(scope, scope->local_symbol(), rwidth,
lsig->vector_width(),
rsig->vector_width());
powr->set_line(*this);
powr->rise_time(rise);
powr->fall_time(fall);
powr->decay_time(decay);
des->add_node(powr);

powr->set_signed( arith_is_signed );

connect(powr->pin_DataA(), lsig->pin(0));
connect(powr->pin_DataB(), rsig->pin(0));

// Make a signal to carry the output from the power.
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, rwidth);
osig->data_type( lsig->data_type() );
osig->local_flag(true);
connect(powr->pin_Result(), osig->pin(0));

return osig;
}

NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
Expand All @@ -1100,7 +1163,6 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,

bool right_flag = op_ == 'r' || op_ == 'R';
bool signed_flag = op_ == 'R';
ivl_variable_type_t data_type = lsig->data_type();

/* Handle the special case of a constant shift amount. There
is no reason in this case to create a gate at all, just
Expand All @@ -1121,7 +1183,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
result that I return from this function. */
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, lwidth);
osig->data_type( data_type );
osig->data_type( lsig->data_type() );
osig->local_flag(true);


Expand Down Expand Up @@ -1150,7 +1212,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,

NetNet*zero = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, pad_width);
zero->data_type( data_type );
zero->data_type( lsig->data_type() );
zero->local_flag(true);
zero->set_line(*this);

Expand All @@ -1167,7 +1229,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
des->add_node(sign_pad);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
tmp->data_type( data_type );
tmp->data_type( lsig->data_type() );
tmp->local_flag(true);
tmp->set_line(*this);
connect(sign_bit->pin(0), tmp->pin(0));
Expand Down Expand Up @@ -1238,7 +1300,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
input) */
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, part_width);
tmp->data_type( data_type );
tmp->data_type( lsig->data_type() );
tmp->local_flag(true);
tmp->set_line(*this);
connect(part->pin(0), tmp->pin(0));
Expand Down Expand Up @@ -1268,7 +1330,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,

NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, lwidth);
osig->data_type( data_type );
osig->data_type( lsig->data_type() );
osig->local_flag(true);
osig->set_signed(signed_flag);

Expand Down
8 changes: 7 additions & 1 deletion emit.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008 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
Expand Down Expand Up @@ -128,6 +128,12 @@ bool NetPartSelect::emit_node(struct target_t*tgt) const
return tgt->part_select(this);
}

bool NetPow::emit_node(struct target_t*tgt) const
{
tgt->lpm_pow(this);
return true;
}

bool NetReplicate::emit_node(struct target_t*tgt) const
{
return tgt->replicate(this);
Expand Down
68 changes: 10 additions & 58 deletions functor.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2008 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
Expand All @@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.cc,v 1.35 2005/07/07 16:22:49 steve Exp $"
#endif

# include "config.h"

Expand Down Expand Up @@ -83,6 +80,10 @@ void functor_t::lpm_mux(class Design*, class NetMux*)
{
}

void functor_t::lpm_pow(class Design*, class NetPow*)
{
}

void functor_t::sign_extend(class Design*, class NetSignExtend*)
{
}
Expand Down Expand Up @@ -223,6 +224,11 @@ void NetMux::functor_node(Design*des, functor_t*fun)
fun->lpm_mux(des, this);
}

void NetPow::functor_node(Design*des, functor_t*fun)
{
fun->lpm_pow(des, this);
}

void NetSignExtend::functor_node(Design*des, functor_t*fun)
{
fun->sign_extend(des, this);
Expand Down Expand Up @@ -291,57 +297,3 @@ int proc_match_t::event_wait(NetEvWait*)
{
return 0;
}

/*
* $Log: functor.cc,v $
* Revision 1.35 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.34 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
*
* Revision 1.33 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*
* Revision 1.32 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.31 2002/08/16 05:18:27 steve
* Fix intermix of node functors and node delete.
*
* Revision 1.30 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2002/08/10 22:07:38 steve
* Remove useless error messages.
*
* Revision 1.28 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.27 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.26 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.25 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.24 2000/11/19 20:48:30 steve
* Fix cases where signal iteration might die early.
*
* Revision 1.23 2000/11/18 04:53:04 steve
* Watch out in functor, it may delete the last signal.
*
* Revision 1.22 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.21 2000/08/01 02:48:41 steve
* Support <= in synthesis of DFF and ram devices.
*/

Loading

0 comments on commit 5e8a1bd

Please sign in to comment.