Merge branch 'master' into verilog-ams
This commit is contained in:
commit
17b937740a
|
|
@ -60,7 +60,7 @@ bindir = @bindir@
|
|||
libdir = @libdir@
|
||||
# This is actually the directory where we install our own header files.
|
||||
# It is a little different from the generic includedir.
|
||||
includedir = @includedir@/verilog$(suffix)
|
||||
includedir = @includedir@/iverilog$(suffix)
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
|
@ -166,7 +166,7 @@ SUBDIRS += driver-vpi
|
|||
else
|
||||
all: dep iverilog-vpi
|
||||
|
||||
iverilog-vpi: iverilog-vpi.sh
|
||||
iverilog-vpi: iverilog-vpi.sh Makefile
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
|
|
|
|||
20
PExpr.cc
20
PExpr.cc
|
|
@ -95,11 +95,29 @@ PEBLogic::~PEBLogic()
|
|||
{
|
||||
}
|
||||
|
||||
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||
PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBLeftWidth::~PEBLeftWidth()
|
||||
{
|
||||
}
|
||||
|
||||
PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
|
||||
: PEBLeftWidth(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBPower::~PEBPower()
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||
: PEBLeftWidth(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::~PEBShift()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
47
PExpr.h
47
PExpr.h
|
|
@ -535,18 +535,51 @@ class PEBLogic : public PEBinary {
|
|||
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
};
|
||||
|
||||
class PEBShift : public PEBinary {
|
||||
/*
|
||||
* A couple of the binary operands have a special sub-expression rule
|
||||
* where the expression width is carried entirely by the left
|
||||
* expression, and the right operand is self-determined.
|
||||
*/
|
||||
class PEBLeftWidth : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
|
||||
~PEBLeftWidth() =0;
|
||||
|
||||
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const =0;
|
||||
|
||||
protected:
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
bool&flag);
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*scope) const;
|
||||
|
||||
};
|
||||
|
||||
class PEBPower : public PEBLeftWidth {
|
||||
|
||||
public:
|
||||
explicit PEBPower(char op, PExpr*l, PExpr*r);
|
||||
~PEBPower();
|
||||
|
||||
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const;
|
||||
};
|
||||
|
||||
class PEBShift : public PEBLeftWidth {
|
||||
|
||||
public:
|
||||
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
||||
~PEBShift();
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
bool&flag);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
74
PGenerate.cc
74
PGenerate.cc
|
|
@ -22,10 +22,12 @@
|
|||
|
||||
# include "PGenerate.h"
|
||||
# include "PWire.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
PGenerate::PGenerate(unsigned id)
|
||||
: id_number(id)
|
||||
{
|
||||
direct_nested_ = false;
|
||||
parent = 0;
|
||||
lexical_scope = 0;
|
||||
}
|
||||
|
|
@ -38,3 +40,75 @@ void PGenerate::add_gate(PGate*gate)
|
|||
{
|
||||
gates.push_back(gate);
|
||||
}
|
||||
|
||||
void PGenerate::probe_for_direct_nesting_(void)
|
||||
{
|
||||
direct_nested_ = false;
|
||||
|
||||
ivl_assert(*this, scheme_type==GS_CASE_ITEM || scheme_type==GS_CONDIT || scheme_type==GS_ELSE);
|
||||
|
||||
// If this scheme has received an explicit name, then it
|
||||
// cannot be direct nested.
|
||||
if (scope_name[0] != '$') return;
|
||||
|
||||
if (tasks.size() > 0) return;
|
||||
if (funcs.size() > 0) return;
|
||||
if (gates.size() > 0) return;
|
||||
if (parameters.size() > 0) return;
|
||||
if (localparams.size() > 0) return;
|
||||
if (events.size() > 0) return;
|
||||
if (wires.size() > 0) return;
|
||||
if (behaviors.size() > 0) return;
|
||||
if (analog_behaviors.size() > 0) return;
|
||||
|
||||
if (generate_schemes.size() == 0) return;
|
||||
|
||||
switch (generate_schemes.size()) {
|
||||
case 1: {
|
||||
PGenerate*child = generate_schemes.front();
|
||||
if (child->scheme_type == GS_CONDIT)
|
||||
direct_nested_ = true;
|
||||
if (child->scheme_type == GS_CASE)
|
||||
direct_nested_ = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
PGenerate*child1 = generate_schemes.front();
|
||||
PGenerate*child2 = generate_schemes.back();
|
||||
if (child1->scheme_type==GS_CONDIT && child2->scheme_type==GS_ELSE)
|
||||
direct_nested_ = true;
|
||||
if (child2->scheme_type==GS_CONDIT && child1->scheme_type==GS_ELSE)
|
||||
direct_nested_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&out, PGenerate::scheme_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case PGenerate::GS_NONE:
|
||||
out << "GS_NONE";
|
||||
break;
|
||||
case PGenerate::GS_LOOP:
|
||||
out << "GS_LOOP";
|
||||
break;
|
||||
case PGenerate::GS_CONDIT:
|
||||
out << "GS_CONDIT";
|
||||
break;
|
||||
case PGenerate::GS_ELSE:
|
||||
out << "GS_ELSE";
|
||||
break;
|
||||
case PGenerate::GS_CASE:
|
||||
out << "GS_CASE";
|
||||
break;
|
||||
case PGenerate::GS_CASE_ITEM:
|
||||
out << "GS_CASE_ITEM";
|
||||
break;
|
||||
case PGenerate::GS_NBLOCK:
|
||||
out << "GS_NBLOCK";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
17
PGenerate.h
17
PGenerate.h
|
|
@ -25,6 +25,7 @@
|
|||
# include "PScope.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <valarray>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
|
|
@ -74,6 +75,10 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
PExpr*loop_init;
|
||||
PExpr*loop_test;
|
||||
PExpr*loop_step;
|
||||
// Case items may have multiple guard expression values. It is
|
||||
// enough for any on of the guards to match the case statement
|
||||
// test value.
|
||||
std::valarray<PExpr*> item_test;
|
||||
|
||||
list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
|
@ -104,18 +109,30 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
bool generate_scope_case_(Design*des, NetScope*container);
|
||||
bool generate_scope_nblock_(Design*des, NetScope*container);
|
||||
|
||||
// Call probe during elaborate_scope to calulate the
|
||||
// directed_nested_ flag. It is OK to store the direct_nested_
|
||||
// information here because "direct nested" is a property of
|
||||
// the lexical generate code.
|
||||
void probe_for_direct_nesting_(void);
|
||||
bool direct_nested_;
|
||||
|
||||
// Elaborate_scope within a generated scope.
|
||||
void elaborate_subscope_(Design*des, NetScope*scope);
|
||||
void elaborate_subscope_direct_(Design*des, NetScope*scope);
|
||||
|
||||
// These are the scopes created by generate_scope.
|
||||
list<NetScope*>scope_list_;
|
||||
// internal function called on each scope generated by this scheme.
|
||||
bool elaborate_sig_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_direct_(Design*des, NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
PGenerate(const PGenerate&);
|
||||
PGenerate& operator= (const PGenerate&);
|
||||
};
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ static void setup_ivl_environment()
|
|||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\verilog" IVERILOG_SUFFIX);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the LDFLAGS option string */
|
||||
assign(&gstr.pLDLIBS,"-L");
|
||||
|
|
|
|||
99
elab_expr.cc
99
elab_expr.cc
|
|
@ -214,6 +214,7 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope,
|
|||
case 'G': // >= Should be handled by PEBComp
|
||||
case 'n': // != Should be handled by PEBComp
|
||||
case 'N': // !== Should be handled by PEBComp
|
||||
case 'p': // ** should be handled by PEBPower
|
||||
ivl_assert(*this, 0);
|
||||
default:
|
||||
if (wid_left > min)
|
||||
|
|
@ -352,14 +353,15 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des,
|
|||
tmp = elaborate_expr_base_div_(des, lp, rp, expr_wid);
|
||||
break;
|
||||
|
||||
case 'l': // <<
|
||||
tmp = elaborate_expr_base_lshift_(des, lp, rp, expr_wid);
|
||||
break;
|
||||
|
||||
case 'r': // >>
|
||||
case 'R': // >>>
|
||||
tmp = elaborate_expr_base_rshift_(des, lp, rp, expr_wid);
|
||||
break;
|
||||
case 'l':
|
||||
case 'r':
|
||||
case 'R':
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Elaboration of " << human_readable_op(op_)
|
||||
<< " Should have been handled in NetEBShift::elaborate."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
||||
case '^':
|
||||
case '&':
|
||||
|
|
@ -898,12 +900,12 @@ NetExpr*PEBLogic::elaborate_expr(Design*des, NetScope*scope,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
||||
unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
unsigned wid_left = left_->test_width(des,scope,min, 0, expr_type__, unsized_flag);
|
||||
unsigned wid_left = left_->test_width(des,scope,min, lval, expr_type__, unsized_flag);
|
||||
|
||||
// The right expression is self-determined and has no impact
|
||||
// on the expression size that is generated.
|
||||
|
|
@ -913,12 +915,15 @@ unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
|||
if (wid_left < lval)
|
||||
wid_left = lval;
|
||||
|
||||
if (unsized_flag && wid_left < integer_width) {
|
||||
if (unsized_flag
|
||||
&& type_is_vectorable(expr_type__)
|
||||
&& wid_left > 0
|
||||
&& wid_left < integer_width) {
|
||||
wid_left = integer_width;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Test width of unsized left shift"
|
||||
<< "Test width of unsized " << human_readable_op(op_)
|
||||
<< " is padded to compiler integer width=" << wid_left
|
||||
<< endl;
|
||||
}
|
||||
|
|
@ -934,20 +939,28 @@ unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
|||
unsigned wid_right = right_->test_width(des, scope, 0, 0, rtype, rflag);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Test width of shift amount of shift expression "
|
||||
<< "Test width of exponent of " << op_ << " expression "
|
||||
<< "returns wid=" << wid_right << ", type=" << rtype
|
||||
<< ", flag=" << rflag << endl;
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
NetExpr*PEBShift::elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_wid, bool sys_task_arg) const
|
||||
NetExpr*PEBLeftWidth::elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_wid, bool sys_task_arg) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, false);
|
||||
if (expr_wid > 0 && lp->expr_width() < (unsigned)expr_wid) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Pad left operand of " << human_readable_op(op_)
|
||||
<< " to " << expr_wid << "." << endl;
|
||||
lp = pad_to_width(lp, expr_wid, *this);
|
||||
}
|
||||
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope, -1, false);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
|
|
@ -955,7 +968,48 @@ NetExpr*PEBShift::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*tmp = elaborate_eval_expr_base_(des, lp, rp, expr_wid);
|
||||
eval_expr(lp);
|
||||
eval_expr(rp);
|
||||
|
||||
return elaborate_expr_leaf(des, lp, rp, expr_wid);
|
||||
}
|
||||
|
||||
NetExpr*PEBPower::elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const
|
||||
{
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: elaborate expression "
|
||||
<< *this << " expr_wid=" << expr_wid << endl;
|
||||
}
|
||||
|
||||
NetExpr*tmp = new NetEBPow(op_, lp, rp);
|
||||
tmp->set_line(*this);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr*PEBShift::elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const
|
||||
{
|
||||
NetExpr*tmp = 0;
|
||||
|
||||
switch (op_) {
|
||||
case 'l':
|
||||
tmp = elaborate_expr_base_lshift_(des, lp, rp, expr_wid);
|
||||
break;
|
||||
|
||||
case 'r': // >>
|
||||
case 'R': // >>>
|
||||
tmp = elaborate_expr_base_rshift_(des, lp, rp, expr_wid);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected opcode " << human_readable_op(op_)
|
||||
<< " in PEBShift::elaborate_expr_leaf." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
@ -1682,6 +1736,7 @@ NetExpr* PEIdent::calculate_up_do_base_(Design*des, NetScope*scope) const
|
|||
ivl_assert(*this, index_tail.lsb != 0);
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
|
||||
probe_expr_width(des, scope, index_tail.msb);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -1756,8 +1811,13 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
break;
|
||||
}
|
||||
case index_component_t::SEL_BIT:
|
||||
use_width = 1;
|
||||
break;
|
||||
{ ivl_assert(*this, !name_tail.index.empty());
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb);
|
||||
probe_expr_width(des, scope, index_tail.msb);
|
||||
}
|
||||
use_width = 1;
|
||||
break;
|
||||
default:
|
||||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
|
@ -2928,7 +2988,6 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
|
|||
bool flag = false;
|
||||
expr_->test_width(des, scope, 0, 0, sub_type, flag);
|
||||
expr_type_ = sub_type;
|
||||
ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE);
|
||||
}
|
||||
expr_width_ = 1;
|
||||
|
||||
|
|
@ -2976,6 +3035,8 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
NetExpr*ip = expr_->elaborate_expr(des, scope, expr_wid, false);
|
||||
if (ip == 0) return 0;
|
||||
|
||||
ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE);
|
||||
|
||||
NetExpr*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -81,6 +81,20 @@ NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr*PEBLeftWidth::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*lp = left_->elaborate_pexpr(des, scope);
|
||||
NetExpr*rp = right_->elaborate_pexpr(des, scope);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
delete rp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*tmp = elaborate_expr_leaf(des, lp, rp, -2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr*PEBLogic::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*lp = left_->elaborate_pexpr(des, scope);
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ static void elaborate_parm_item_(perm_string name,
|
|||
tmp->high_open_flag = range->high_open_flag;
|
||||
|
||||
if (range->low_expr) {
|
||||
probe_expr_width(des, scope, range->low_expr);
|
||||
tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1);
|
||||
ivl_assert(*range->low_expr, tmp->low_expr);
|
||||
} else {
|
||||
|
|
@ -130,6 +131,7 @@ static void elaborate_parm_item_(perm_string name,
|
|||
tmp->high_expr = tmp->low_expr;
|
||||
|
||||
} else if (range->high_expr) {
|
||||
probe_expr_width(des, scope, range->high_expr);
|
||||
tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1);
|
||||
ivl_assert(*range->high_expr, tmp->high_expr);
|
||||
} else {
|
||||
|
|
@ -493,6 +495,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
// The initial value for the genvar does not need (nor can it
|
||||
// use) the genvar itself, so we can evaluate this expression
|
||||
// the same way any other parameter value is evaluated.
|
||||
probe_expr_width(des, container, loop_init);
|
||||
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
|
||||
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
if (init == 0) {
|
||||
|
|
@ -522,6 +525,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
|
||||
container->genvar_tmp = loop_index;
|
||||
container->genvar_tmp_val = genvar;
|
||||
probe_expr_width(des, container, loop_test);
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||
if (test == 0) {
|
||||
|
|
@ -574,6 +578,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
elaborate_subscope_(des, scope);
|
||||
|
||||
// Calculate the step for the loop variable.
|
||||
probe_expr_width(des, container, loop_step);
|
||||
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
|
||||
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
||||
if (step == 0) {
|
||||
|
|
@ -590,6 +595,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
delete test_ex;
|
||||
probe_expr_width(des, container, loop_test);
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
test = dynamic_cast<NetEConst*>(test_ex);
|
||||
assert(test);
|
||||
|
|
@ -604,6 +610,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
|
||||
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
|
||||
{
|
||||
probe_expr_width(des, container, loop_test);
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
||||
if (test == 0) {
|
||||
|
|
@ -634,14 +641,26 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
|||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate condition "
|
||||
<< (else_flag? "(else)" : "(if)")
|
||||
<< " value=" << test->value() << ": Generate scope="
|
||||
<< use_name << endl;
|
||||
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
probe_for_direct_nesting_();
|
||||
if (direct_nested_) {
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate condition "
|
||||
<< (else_flag? "(else)" : "(if)")
|
||||
<< " detected direct nesting." << endl;
|
||||
elaborate_subscope_direct_(des, container);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this is not directly nested, then generate a scope
|
||||
// for myself. That is what I will pass to the subscope.
|
||||
NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
|
||||
elaborate_subscope_(des, scope);
|
||||
|
|
@ -651,6 +670,7 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
|||
|
||||
bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||
{
|
||||
probe_expr_width(des, container, loop_test);
|
||||
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
|
||||
if (case_value_co == 0) {
|
||||
|
|
@ -673,24 +693,32 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
assert( item->scheme_type == PGenerate::GS_CASE_ITEM );
|
||||
|
||||
// Detect that the item is a default.
|
||||
if (item->loop_test == 0) {
|
||||
if (item->item_test.size() == 0) {
|
||||
default_item = item;
|
||||
cur ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
NetExpr*item_value_ex = elab_and_eval(des, container, item->loop_test, -1);
|
||||
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
|
||||
assert(item_value_co);
|
||||
bool match_flag = false;
|
||||
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
|
||||
probe_expr_width(des, container, item->item_test[idx]);
|
||||
NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1);
|
||||
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
|
||||
assert(item_value_co);
|
||||
|
||||
// If we stumble on the item that matches, then break
|
||||
// out now.
|
||||
if (case_value_co->value() == item_value_co->value()) {
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate case "
|
||||
<< "item value=" << item_value_co->value() << endl;
|
||||
|
||||
if (case_value_co->value() == item_value_co->value())
|
||||
match_flag = true;
|
||||
delete item_value_co;
|
||||
break;
|
||||
}
|
||||
|
||||
delete item_value_co;
|
||||
// If we stumble on the item that matches, then break out now.
|
||||
if (match_flag)
|
||||
break;
|
||||
|
||||
cur ++;
|
||||
}
|
||||
|
||||
|
|
@ -712,6 +740,15 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
// The name of the scope to generate, whatever that item is.
|
||||
hname_t use_name (item->scope_name);
|
||||
|
||||
item->probe_for_direct_nesting_();
|
||||
if (item->direct_nested_) {
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate case item " << scope_name
|
||||
<< " detected direct nesting." << endl;
|
||||
item->elaborate_subscope_direct_(des, container);
|
||||
return true;
|
||||
}
|
||||
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
scope->set_line(get_file(), get_lineno());
|
||||
|
|
@ -743,6 +780,15 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
|||
return true;
|
||||
}
|
||||
|
||||
void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
|
||||
{
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur) -> generate_scope(des, scope);
|
||||
}
|
||||
}
|
||||
|
||||
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
||||
{
|
||||
// Scan the generated scope for nested generate schemes,
|
||||
|
|
@ -785,6 +831,10 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
|||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generated scope " << scope_path(scope)
|
||||
<< " by generate block " << scope_name << endl;
|
||||
|
||||
// Save the scope that we created, for future use.
|
||||
scope_list_.push_back(scope);
|
||||
}
|
||||
|
|
@ -900,6 +950,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
*/
|
||||
void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
if (msb_) probe_expr_width(des, sc, msb_);
|
||||
if (lsb_) probe_expr_width(des, sc, lsb_);
|
||||
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
|
||||
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
|
||||
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
|
||||
|
|
|
|||
41
elab_sig.cc
41
elab_sig.cc
|
|
@ -412,6 +412,9 @@ bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const
|
|||
|
||||
bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
|
||||
{
|
||||
if (direct_nested_)
|
||||
return elaborate_sig_direct_(des, container);
|
||||
|
||||
bool flag = true;
|
||||
|
||||
// Handle the special case that this is a CASE scheme. In this
|
||||
|
|
@ -428,7 +431,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
|
|||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++) {
|
||||
PGenerate*item = *cur;
|
||||
if (! item->scope_list_.empty()) {
|
||||
if (item->direct_nested_ || !item->scope_list_.empty()) {
|
||||
flag &= item->elaborate_sig(des, container);
|
||||
}
|
||||
}
|
||||
|
|
@ -454,6 +457,32 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
|
|||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
|
||||
{
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Direct nesting " << scope_name
|
||||
<< " (scheme_type=" << scheme_type << ")"
|
||||
<< " elaborate_sig in scope "
|
||||
<< scope_path(container) << "." << endl;
|
||||
|
||||
// Elaborate_sig for a direct nested generated scheme knows
|
||||
// that there are only sub_schemes to be elaborated. There
|
||||
// should be exactly 1 active generate scheme, search for it
|
||||
// using this loop.
|
||||
bool flag = true;
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++) {
|
||||
PGenerate*item = *cur;
|
||||
if (item->direct_nested_ || !item->scope_list_.empty()) {
|
||||
// Found the item, and it is direct nested.
|
||||
flag &= item->elaborate_sig(des, container);
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Scan the declared PWires to elaborate the obvious signals
|
||||
|
|
@ -530,6 +559,9 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
case PTF_REG:
|
||||
case PTF_REG_S:
|
||||
if (return_type_.range) {
|
||||
probe_expr_width(des, scope, (*return_type_.range)[0]);
|
||||
probe_expr_width(des, scope, (*return_type_.range)[1]);
|
||||
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[0], -1);
|
||||
assert(me);
|
||||
|
|
@ -823,6 +855,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
bool bad_lsb = false, bad_msb = false;
|
||||
/* If they exist get the port definition MSB and LSB */
|
||||
if (port_set_ && port_msb_ != 0) {
|
||||
probe_expr_width(des, scope, port_msb_);
|
||||
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
|
||||
|
||||
if (! eval_as_long(pmsb, texpr)) {
|
||||
|
|
@ -837,6 +870,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
delete texpr;
|
||||
|
||||
probe_expr_width(des, scope, port_lsb_);
|
||||
texpr = elab_and_eval(des, scope, port_lsb_, -1);
|
||||
|
||||
if (! eval_as_long(plsb, texpr)) {
|
||||
|
|
@ -859,6 +893,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
/* If they exist get the net/etc. definition MSB and LSB */
|
||||
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
|
||||
probe_expr_width(des, scope, net_msb_);
|
||||
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
|
||||
|
||||
if (! eval_as_long(nmsb, texpr)) {
|
||||
|
|
@ -873,6 +908,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
delete texpr;
|
||||
|
||||
probe_expr_width(des, scope, net_lsb_);
|
||||
texpr = elab_and_eval(des, scope, net_lsb_, -1);
|
||||
|
||||
if (! eval_as_long(nlsb, texpr)) {
|
||||
|
|
@ -964,6 +1000,9 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
|
||||
probe_expr_width(des, scope, lidx_);
|
||||
probe_expr_width(des, scope, ridx_);
|
||||
|
||||
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
|
||||
|
||||
|
|
|
|||
75
elaborate.cc
75
elaborate.cc
|
|
@ -700,7 +700,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
|
||||
const PExpr*ex = pin(idx);
|
||||
PExpr*ex = pin(idx);
|
||||
if (ex == 0) {
|
||||
cerr << get_fileline() << ": error: Logic gate port "
|
||||
"expressions are not optional." << endl;
|
||||
|
|
@ -713,6 +713,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
} else {
|
||||
unsigned use_width = array_count * instance_width;
|
||||
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
ex->test_width(des, scope, 0, use_width, tmp_type, flag);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, ex,
|
||||
use_width, use_width);
|
||||
sig = tmp->synthesize(des, scope);
|
||||
|
|
@ -1171,10 +1174,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
width. We use that, then, to decide how to hook
|
||||
it up.
|
||||
|
||||
v NOTE that this also handles the case that the
|
||||
NOTE that this also handles the case that the
|
||||
port is actually empty on the inside. We assume
|
||||
in that case that the port is input. */
|
||||
|
||||
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
pins[idx]->test_width(des, scope, 0, desired_vector_width,
|
||||
tmp_type, flag);
|
||||
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx],
|
||||
desired_vector_width,
|
||||
desired_vector_width);
|
||||
|
|
@ -1790,6 +1797,7 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
|||
*/
|
||||
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
|
||||
{
|
||||
probe_expr_width(des, scope, expr);
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
|
|
@ -2280,17 +2288,8 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
|||
cerr << get_fileline() << ": debug: Elaborate condition statement"
|
||||
<< " with conditional: " << *expr_ << endl;
|
||||
|
||||
// Run a test-width on the condition so that its types are
|
||||
// worked out for elaboration later on.
|
||||
ivl_variable_type_t rtype = IVL_VT_NO_TYPE;
|
||||
bool rflag = false;
|
||||
unsigned expr_wid = expr_->test_width(des, scope, 0, 0, rtype, rflag);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Test width of condition expression"
|
||||
<< " returns wid=" << expr_wid << ", type=" << rtype
|
||||
<< ", flag=" << rflag << endl;
|
||||
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
probe_expr_width(des, scope, expr_);
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
|
||||
if (expr == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to elaborate"
|
||||
|
|
@ -2545,6 +2544,10 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
NetAssign_*lv = new NetAssign_(port);
|
||||
unsigned wid = count_lval_width(lv);
|
||||
|
||||
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
parms_[idx]->test_width(des, scope, 0, wid, tmp_type, flag);
|
||||
|
||||
NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid);
|
||||
rv->set_width(wid);
|
||||
rv = pad_to_width(rv, wid, *this);
|
||||
|
|
@ -2650,8 +2653,9 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
|
|||
return 0;
|
||||
|
||||
unsigned lwid = count_lval_width(lval);
|
||||
ivl_variable_type_t ltype = lval->expr_type();
|
||||
|
||||
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
|
||||
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
|
||||
if (rexp == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -2954,6 +2958,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
|
||||
bool save_flag = error_implicit;
|
||||
error_implicit = true;
|
||||
probe_expr_width(des, scope, expr_[idx]->expr());
|
||||
NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), 0);
|
||||
if (tmp == 0) {
|
||||
expr_[idx]->dump(cerr);
|
||||
|
|
@ -3054,10 +3059,12 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
const PExpr *pe = expr_[0]->expr();
|
||||
PExpr *pe = expr_[0]->expr();
|
||||
|
||||
/* Elaborate wait expression. Don't eval yet, we will do that
|
||||
shortly, after we apply a reduction or. */
|
||||
|
||||
probe_expr_width(des, scope, pe);
|
||||
NetExpr*expr = pe->elaborate_expr(des, scope, -1, false);
|
||||
if (expr == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to elaborate"
|
||||
|
|
@ -3248,8 +3255,9 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
|
|||
return 0;
|
||||
|
||||
unsigned lwid = count_lval_width(lval);
|
||||
ivl_variable_type_t ltype = lval->expr_type();
|
||||
|
||||
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
|
||||
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
|
||||
if (rexp == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -3379,6 +3387,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
/* Elaborate the condition expression. Try to evaluate it too,
|
||||
in case it is a constant. This is an interesting case
|
||||
worthy of a warning. */
|
||||
probe_expr_width(des, scope, cond_);
|
||||
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
||||
if (ce == 0) {
|
||||
delete top;
|
||||
|
|
@ -3591,8 +3600,9 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
|
|||
*/
|
||||
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_, -1),
|
||||
statement_->elaborate(des, scope));
|
||||
probe_expr_width(des, scope, cond_);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
|
||||
NetWhile*loop = new NetWhile(tmp, statement_->elaborate(des, scope));
|
||||
return loop;
|
||||
}
|
||||
|
||||
|
|
@ -3683,6 +3693,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
|
|||
them for the timescale/precision of the scope. */
|
||||
for (unsigned idx = 0 ; idx < ndelays ; idx += 1) {
|
||||
PExpr*exp = delays[idx];
|
||||
probe_expr_width(des, scope, exp);
|
||||
NetExpr*cur = elab_and_eval(des, scope, exp, 0);
|
||||
|
||||
if (NetEConst*cur_con = dynamic_cast<NetEConst*> (cur)) {
|
||||
|
|
@ -3720,6 +3731,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
|
|||
NetNet*condit_sig = 0;
|
||||
if (conditional && condition) {
|
||||
|
||||
probe_expr_width(des, scope, condition);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, condition, -1);
|
||||
ivl_assert(*condition, tmp);
|
||||
|
||||
|
|
@ -3962,6 +3974,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
bool PGenerate::elaborate(Design*des, NetScope*container) const
|
||||
{
|
||||
if (direct_nested_)
|
||||
return elaborate_direct_(des, container);
|
||||
|
||||
bool flag = true;
|
||||
|
||||
// Handle the special case that this is a CASE scheme. In this
|
||||
|
|
@ -3978,7 +3993,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
|
|||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++) {
|
||||
PGenerate*item = *cur;
|
||||
if (! item->scope_list_.empty()) {
|
||||
if (item->direct_nested_ || !item->scope_list_.empty()) {
|
||||
flag &= item->elaborate(des, container);
|
||||
}
|
||||
}
|
||||
|
|
@ -4016,6 +4031,30 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
|
|||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
|
||||
{
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Direct nesting elaborate in scope "
|
||||
<< scope_path(container) << "." << endl;
|
||||
|
||||
// Elaborate for a direct nested generated scheme knows
|
||||
// that there are only sub_schemes to be elaborated. There
|
||||
// should be exactly 1 active generate scheme, search for it
|
||||
// using this loop.
|
||||
bool flag = true;
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++) {
|
||||
PGenerate*item = *cur;
|
||||
if (item->direct_nested_ || !item->scope_list_.empty()) {
|
||||
// Found the item, and it is direct nested.
|
||||
flag &= item->elaborate(des, container);
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_(Design*des, NetScope*scope) const
|
||||
{
|
||||
elaborate_functions(des, scope, funcs);
|
||||
|
|
|
|||
|
|
@ -18,12 +18,9 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.18 2006/10/30 22:45:37 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.36 2007/02/06 05:07:32 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
|
|
|||
|
|
@ -250,6 +250,13 @@ NetExpr* condition_reduce(NetExpr*expr)
|
|||
return cmp;
|
||||
}
|
||||
|
||||
void probe_expr_width(Design*des, NetScope*scope, PExpr*pe)
|
||||
{
|
||||
ivl_variable_type_t expr_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
pe->test_width(des, scope, 0, 0, expr_type, flag);
|
||||
}
|
||||
|
||||
NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||
const PExpr*pe, int expr_wid, int prune_width)
|
||||
{
|
||||
|
|
@ -398,6 +405,7 @@ const char *human_readable_op(const char op)
|
|||
case 'r': type = ">>"; break; // Logical right shift
|
||||
case 'R': type = ">>>"; break; // Arithmetic right shift
|
||||
|
||||
case 'p': type = "**"; break; // Power
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
|||
const PExpr*pe, int expr_wid,
|
||||
int prune_width =-1);
|
||||
|
||||
void probe_expr_width(Design*des, NetScope*scope, PExpr*pe);
|
||||
|
||||
/*
|
||||
* This function elaborates an expression as if it is for the r-value
|
||||
* of an assignment, The data_type_lv and expr_wid_lv are the type and
|
||||
|
|
|
|||
4
parse.y
4
parse.y
|
|
@ -929,7 +929,7 @@ expression
|
|||
$$ = tmp;
|
||||
}
|
||||
| expression K_POW expression
|
||||
{ PEBinary*tmp = new PEBinary('p', $1, $3);
|
||||
{ PEBinary*tmp = new PEBPower('p', $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
@ -2321,7 +2321,7 @@ generate_case_items
|
|||
;
|
||||
|
||||
generate_case_item
|
||||
: expression ':' { pform_generate_case_item(@1, $1); } generate_block_opt
|
||||
: expression_list_proper ':' { pform_generate_case_item(@1, $1); } generate_block_opt
|
||||
{ pform_endgenerate(); }
|
||||
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block_opt
|
||||
{ pform_endgenerate(); }
|
||||
|
|
|
|||
10
pform.cc
10
pform.cc
|
|
@ -558,7 +558,7 @@ void pform_start_generate_nblock(const struct vlltype&li, char*name)
|
|||
* case schema can only instantiate exactly one item, so the items
|
||||
* need not have a unique number.
|
||||
*/
|
||||
void pform_generate_case_item(const struct vlltype&li, PExpr*expr)
|
||||
void pform_generate_case_item(const struct vlltype&li, svector<PExpr*>*expr_list)
|
||||
{
|
||||
assert(pform_cur_generate);
|
||||
assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE);
|
||||
|
|
@ -573,8 +573,14 @@ void pform_generate_case_item(const struct vlltype&li, PExpr*expr)
|
|||
pform_cur_generate->scheme_type = PGenerate::GS_CASE_ITEM;
|
||||
|
||||
pform_cur_generate->loop_init = 0;
|
||||
pform_cur_generate->loop_test = expr;
|
||||
pform_cur_generate->loop_test = 0;
|
||||
pform_cur_generate->loop_step = 0;
|
||||
|
||||
if (expr_list != 0) {
|
||||
pform_cur_generate->item_test.resize(expr_list->count());
|
||||
for (unsigned idx = 0 ; idx < expr_list->count() ; idx += 1)
|
||||
pform_cur_generate->item_test[idx] = expr_list[0][idx];
|
||||
}
|
||||
}
|
||||
|
||||
void pform_generate_block_name(char*name)
|
||||
|
|
|
|||
2
pform.h
2
pform.h
|
|
@ -205,7 +205,7 @@ extern void pform_start_generate_if(const struct vlltype&li, PExpr*test);
|
|||
extern void pform_start_generate_else(const struct vlltype&li);
|
||||
extern void pform_start_generate_case(const struct vlltype&lp, PExpr*test);
|
||||
extern void pform_start_generate_nblock(const struct vlltype&lp, char*name);
|
||||
extern void pform_generate_case_item(const struct vlltype&lp, PExpr*test);
|
||||
extern void pform_generate_case_item(const struct vlltype&lp, svector<PExpr*>*test);
|
||||
extern void pform_generate_block_name(char*name);
|
||||
extern void pform_endgenerate();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,9 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.16 2004/02/10 19:25:01 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,9 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.11 2004/02/10 19:25:01 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
|
|
|||
|
|
@ -16,12 +16,9 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.12 2004/02/10 19:25:01 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ INSTALL = @INSTALL@
|
|||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CXXFLAGS = -Wall @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ static vhdl_expr *part_select_vp_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
|
|||
if (NULL == off)
|
||||
return NULL;
|
||||
|
||||
selfrom->set_slice(off, ivl_lpm_width(lpm) - 1);
|
||||
if (selfrom->get_type()->get_width() > 1)
|
||||
selfrom->set_slice(off, ivl_lpm_width(lpm) - 1);
|
||||
|
||||
return selfrom;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ static vhdl_var_ref *make_assign_lhs(ivl_lval_t lval, vhdl_scope *scope)
|
|||
if (base) {
|
||||
if (decl->get_type()->get_name() == VHDL_TYPE_ARRAY)
|
||||
lval_ref->set_slice(base, 0);
|
||||
else
|
||||
else if (ivl_signal_width(sig) > 1)
|
||||
lval_ref->set_slice(base, lval_width - 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ INSTALL = @INSTALL@
|
|||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
|
|
|
|||
|
|
@ -1469,8 +1469,13 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid)
|
|||
break;
|
||||
|
||||
case 'p':
|
||||
fprintf(vvp_out, " %%pow%s %u, %u, %u;\n", sign_string,
|
||||
lv.base, rv.base, wid);
|
||||
if (ivl_expr_signed(le) || ivl_expr_signed(re)) {
|
||||
fprintf(vvp_out, " %%pow/s %u, %u, %u;\n",
|
||||
lv.base, rv.base, wid);
|
||||
} else {
|
||||
fprintf(vvp_out, " %%pow %u, %u, %u;\n",
|
||||
lv.base, rv.base, wid);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -53,7 +53,15 @@ __inline__ static void draw_execute_header(ivl_design_t des)
|
|||
fprintf(vvp_out, "#! %s\n", cp);
|
||||
fchmod(fileno(vvp_out), 0755);
|
||||
}
|
||||
#else
|
||||
fprintf(vvp_out, "# MinGW does not support an executable header.\n");
|
||||
#endif
|
||||
fprintf(vvp_out, ":ivl_version \"" VERSION "\"");
|
||||
/* I am assuming that a base release will have a blank tag. */
|
||||
if (strcmp(VERSION_TAG, "") != 0) {
|
||||
fprintf(vvp_out, " \"(" VERSION_TAG ")\"");
|
||||
}
|
||||
fprintf(vvp_out, ";\n");
|
||||
}
|
||||
|
||||
__inline__ static void draw_module_declarations(ivl_design_t des)
|
||||
|
|
|
|||
13
verilog.spec
13
verilog.spec
|
|
@ -76,13 +76,16 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%attr(-,root,root) %{_libdir}/libveriuser.a
|
||||
%attr(-,root,root) %{_libdir}/ivl/include/constants.vams
|
||||
%attr(-,root,root) %{_libdir}/ivl/include/disciplines.vams
|
||||
%attr(-,root,root) /usr/include/verilog/ivl_target.h
|
||||
%attr(-,root,root) /usr/include/verilog/vpi_user.h
|
||||
%attr(-,root,root) /usr/include/verilog/acc_user.h
|
||||
%attr(-,root,root) /usr/include/verilog/veriuser.h
|
||||
%attr(-,root,root) /usr/include/verilog/_pli_types.h
|
||||
%attr(-,root,root) /usr/include/iverilog/ivl_target.h
|
||||
%attr(-,root,root) /usr/include/iverilog/vpi_user.h
|
||||
%attr(-,root,root) /usr/include/iverilog/acc_user.h
|
||||
%attr(-,root,root) /usr/include/iverilog/veriuser.h
|
||||
%attr(-,root,root) /usr/include/iverilog/_pli_types.h
|
||||
|
||||
%changelog -n verilog
|
||||
* Tue Nov 25 2008 - steve@icarus.com
|
||||
- Move header files frim /verilog/ to /iverilog/
|
||||
|
||||
* Tue Nov 18 2008 - steve@icarus.com
|
||||
- New snapshot 20080905
|
||||
|
||||
|
|
|
|||
24
verinum.cc
24
verinum.cc
|
|
@ -727,12 +727,28 @@ ostream& operator<< (ostream&o, const verinum&v)
|
|||
|
||||
verinum::V operator == (const verinum&left, const verinum&right)
|
||||
{
|
||||
if (left.len() != right.len())
|
||||
return verinum::V0;
|
||||
verinum::V left_pad = verinum::V0;
|
||||
verinum::V right_pad = verinum::V0;
|
||||
if (left.has_sign() && right.has_sign()) {
|
||||
left_pad = left.get(left.len()-1);
|
||||
right_pad = right.get(right.len()-1);
|
||||
|
||||
for (unsigned idx = 0 ; idx < left.len() ; idx += 1)
|
||||
if (left[idx] != right[idx])
|
||||
if (left_pad == verinum::V1 && right_pad == verinum::V0)
|
||||
return verinum::V1;
|
||||
if (left_pad == verinum::V0 && right_pad == verinum::V1)
|
||||
return verinum::V0;
|
||||
}
|
||||
|
||||
unsigned max_len = left.len();
|
||||
if (right.len() > max_len)
|
||||
max_len = right.len();
|
||||
|
||||
for (unsigned idx = 0 ; idx < max_len ; idx += 1) {
|
||||
verinum::V left_bit = idx < left.len() ? left[idx] : left_pad;
|
||||
verinum::V right_bit = idx < right.len()? right[idx] : right_pad;
|
||||
if (left_bit != right_bit)
|
||||
return verinum::V0;
|
||||
}
|
||||
|
||||
return verinum::V1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,9 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.73 2007/02/06 05:07:32 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.9.devel
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ extern bool of_NORR(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_OR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ORR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_POW(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_POW_S(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%or/r", of_ORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%pow/wr", of_POW_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
%%
|
||||
|
||||
/* These are some special header/footer keywords. */
|
||||
^":ivl_version" { return K_ivl_version; }
|
||||
^":vpi_module" { return K_vpi_module; }
|
||||
^":vpi_time_precision" { return K_vpi_time_precision; }
|
||||
^":file_names" { return K_file_names; }
|
||||
|
|
|
|||
62
vvp/main.cc
62
vvp/main.cc
|
|
@ -133,6 +133,62 @@ inline static void print_rusage(struct rusage *, struct rusage *){};
|
|||
|
||||
#endif // ! defined(HAVE_SYS_RESOURCE_H)
|
||||
|
||||
static bool have_ivl_version = false;
|
||||
/*
|
||||
* Verify that the input file has a compatible version.
|
||||
*/
|
||||
void verify_version(char*ivl_ver, char*commit)
|
||||
{
|
||||
have_ivl_version = true;
|
||||
|
||||
if (verbose_flag) {
|
||||
vpi_mcd_printf(1, " ... VVP file version %s", ivl_ver);
|
||||
if (commit) vpi_mcd_printf(1, " %s", commit);
|
||||
vpi_mcd_printf(1, "\n");
|
||||
}
|
||||
free(commit);
|
||||
|
||||
char*vvp_ver = strdup(VERSION);
|
||||
char *vp, *ip;
|
||||
|
||||
/* Check the major/minor version. */
|
||||
ip = strrchr(ivl_ver, '.');
|
||||
*ip = '\0';
|
||||
vp = strrchr(vvp_ver, '.');
|
||||
*vp = '\0';
|
||||
if (strcmp(ivl_ver, vvp_ver) != 0) {
|
||||
vpi_mcd_printf(1, "Error: VVP input file version %s can not "
|
||||
"be run with run time version %s!\n",
|
||||
ivl_ver, vvp_ver);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check that the sub-version is compatible. */
|
||||
ip += 1;
|
||||
vp += 1;
|
||||
int ivl_sv, vvp_sv;
|
||||
if (strcmp(ip, "devel") == 0) {
|
||||
ivl_sv = -1;
|
||||
} else {
|
||||
int res = sscanf(ip, "%d", &ivl_sv);
|
||||
assert(res == 1);
|
||||
}
|
||||
if (strcmp(vp, "devel") == 0) {
|
||||
vvp_sv = -1;
|
||||
} else {
|
||||
int res = sscanf(vp, "%d", &vvp_sv);
|
||||
assert(res == 1);
|
||||
}
|
||||
if (ivl_sv > vvp_sv) {
|
||||
if (verbose_flag) vpi_mcd_printf(1, " ... ");
|
||||
vpi_mcd_printf(1, "Warning: VVP input file sub-version %s is "
|
||||
"greater than the run time sub-version %s!\n",
|
||||
ip, vp);
|
||||
}
|
||||
|
||||
free(ivl_ver);
|
||||
free(vvp_ver);
|
||||
}
|
||||
|
||||
unsigned module_cnt = 0;
|
||||
const char*module_tab[64];
|
||||
|
|
@ -289,6 +345,12 @@ int main(int argc, char*argv[])
|
|||
if (int rc = compile_design(design_path))
|
||||
return rc;
|
||||
|
||||
if (!have_ivl_version) {
|
||||
if (verbose_flag) vpi_mcd_printf(1, "... ");
|
||||
vpi_mcd_printf(1, "Warning: vvp input file may not be correct "
|
||||
"version!\n");
|
||||
}
|
||||
|
||||
if (verbose_flag) {
|
||||
vpi_mcd_printf(1, "Compile cleanup...\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -653,10 +653,14 @@ and the <dst> is a writable scalar. The <dst> gets the value of the
|
|||
or of all the bits of the src vector.
|
||||
|
||||
|
||||
* %pow <bit-l>, <bit-r>
|
||||
* %pow <bit-l>, <bit-r>, <wid>
|
||||
* %pow/s <bit-l>, <bit-r>, <wid>
|
||||
|
||||
This opcode raises <bit-l> (unsigned) to the power of <bit-r> (unsigned).
|
||||
The result replaces the left operand.
|
||||
The %pow opcode raises <bit-l> (unsigned) to the power of <bit-r>
|
||||
(unsigned) giving an exact integer result. The %pow/s opcode does
|
||||
the same for signed values, except it uses the double pow() function
|
||||
to calculate the result so may not produce exact results. The result
|
||||
replaces the left operand.
|
||||
|
||||
|
||||
* %pow/wr <bit-l>, <bit-r>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
%token K_UDP K_UDP_C K_UDP_S
|
||||
%token K_VAR K_VAR_S K_VAR_I K_VAR_R K_vpi_call K_vpi_func K_vpi_func_r
|
||||
%token K_disable K_fork
|
||||
%token K_vpi_module K_vpi_time_precision K_file_names
|
||||
%token K_ivl_version K_vpi_module K_vpi_time_precision K_file_names
|
||||
|
||||
%token <text> T_INSTR
|
||||
%token <text> T_LABEL
|
||||
|
|
@ -121,7 +121,11 @@ header_lines
|
|||
;
|
||||
|
||||
header_line
|
||||
: K_vpi_module T_STRING ';'
|
||||
: K_ivl_version T_STRING ';'
|
||||
{ verify_version($2, NULL); }
|
||||
| K_ivl_version T_STRING T_STRING ';'
|
||||
{ verify_version($2, $3); }
|
||||
| K_vpi_module T_STRING ';'
|
||||
{ compile_load_vpi_module($2); }
|
||||
| K_vpi_time_precision '+' T_NUMBER ';'
|
||||
{ compile_vpi_time_precision($3); }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __parse_misc_H
|
||||
#define __parse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-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
|
||||
|
|
@ -18,10 +18,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: parse_misc.h,v 1.8 2006/09/23 04:57:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "vpi_priv.h"
|
||||
|
||||
|
|
@ -31,6 +27,12 @@
|
|||
*/
|
||||
extern int compile_design(const char*path);
|
||||
|
||||
/*
|
||||
* This routine is called to check that the input file has a compatible
|
||||
* version.
|
||||
*/
|
||||
extern void verify_version(char *ivl_ver, char* commit);
|
||||
|
||||
/*
|
||||
* various functions shared by the lexor and the parser.
|
||||
*/
|
||||
|
|
@ -76,35 +78,4 @@ extern void argv_add(struct argv_s*obj, vpiHandle);
|
|||
extern void argv_sym_add(struct argv_s*obj, char *);
|
||||
extern void argv_sym_lookup(struct argv_s*obj);
|
||||
|
||||
/*
|
||||
* $Log: parse_misc.h,v $
|
||||
* Revision 1.8 2006/09/23 04:57:20 steve
|
||||
* Basic support for specify timing.
|
||||
*
|
||||
* Revision 1.7 2002/08/12 01:35:08 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2001/07/11 04:43:57 steve
|
||||
* support postpone of $systask parameters. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/05/02 23:16:50 steve
|
||||
* Document memory related opcodes,
|
||||
* parser uses numbv_s structures instead of the
|
||||
* symbv_s and a mess of unions,
|
||||
* Add the %is/sub instruction.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/05/01 01:09:39 steve
|
||||
* Add support for memory objects. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.3 2001/03/20 06:16:24 steve
|
||||
* Add support for variable vectors.
|
||||
*
|
||||
* Revision 1.2 2001/03/18 04:35:18 steve
|
||||
* Add support for string constants to VPI.
|
||||
*
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3838,6 +3838,36 @@ bool of_POW(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool of_POW_S(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned idx = cp->bit_idx[0];
|
||||
unsigned idy = cp->bit_idx[1];
|
||||
unsigned wid = cp->number;
|
||||
vvp_vector4_t xv = vthread_bits_to_vector(thr, idx, wid);
|
||||
vvp_vector4_t yv = vthread_bits_to_vector(thr, idy, wid);
|
||||
|
||||
/* If we have an X or Z in the arguments return X. */
|
||||
if (xv.has_xz() || yv.has_xz()) {
|
||||
for (unsigned jdx = 0 ; jdx < wid ; jdx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx[0]+jdx, BIT4_X);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Calculate the result using the double pow() function. */
|
||||
double xd, yd;
|
||||
vector4_to_value(xv, xd, true);
|
||||
vector4_to_value(yv, yd, true);
|
||||
vvp_vector4_t res = vvp_vector4_t(wid, pow(xd, yd));
|
||||
|
||||
/* Copy the result. */
|
||||
for (unsigned jdx = 0; jdx < wid; jdx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx[0]+jdx, res.value(jdx));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_POW_WR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
double l = thr->words[cp->bit_idx[0]].w_real;
|
||||
|
|
|
|||
Loading…
Reference in New Issue