From bafd7054787de5983145c687f5d0474243598a63 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 6 Jan 2008 18:57:16 -0800 Subject: [PATCH 1/5] Allow negative values for realtime net constants. The lexor didn't allow for negative values for realtime net constants. The minus sign was not accepted as a character in the identifier string. --- vvp/lexor.lex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vvp/lexor.lex b/vvp/lexor.lex index 8a6769f5e..95a437017 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -195,6 +195,11 @@ assert(yylval.text); return T_SYMBOL; } +"Cr<"[.$_a-zA-Z0-9/,\-]*">" { + yylval.text = strdup(yytext); + assert(yylval.text); + return T_SYMBOL; } + /* Accept the common assembler style comments, treat them as white space. Of course, also skip white space. The semi-colon is From 9d55597b26789fca2ea9b6bfaffe1a2b3a3ebde0 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 6 Jan 2008 19:59:31 -0800 Subject: [PATCH 2/5] Elaborate net of real-value constant Handle the special case of a unary minus net with the operand that is a real-valued constant. --- PExpr.h | 18 ++++++++ elab_net.cc | 119 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 101 insertions(+), 36 deletions(-) diff --git a/PExpr.h b/PExpr.h index 37c215fb7..e1d5f2056 100644 --- a/PExpr.h +++ b/PExpr.h @@ -486,6 +486,24 @@ class PEUnary : public PExpr { virtual bool is_constant(Module*) const; + private: + NetNet* elab_net_uminus_const_logic_(Design*des, NetScope*scope, + NetEConst*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const; + NetNet* elab_net_uminus_const_real_(Design*des, NetScope*scope, + NetECReal*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const; + private: char op_; PExpr*expr_; diff --git a/elab_net.cc b/elab_net.cc index 04db2a8e0..9ea0b673b 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -2930,6 +2930,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, Link::strength_t drive0, Link::strength_t drive1) const { + NetExpr*expr = elab_and_eval(des, scope, expr_, width); // Some unary operands allow the operand to be // self-determined, and some do not. @@ -2948,45 +2949,21 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, // Handle the special case of a 2's complement of a constant // value. This can be reduced to a no-op on a precalculated // result. - if (op_ == '-') do { - // TODO: Should replace this with a call to - // elab_and_eval. Possibly blend this with the rest of - // the elaboration as well. - verinum*val = expr_->eval_const(des, scope); - if (val == 0) - break; - - if (width == 0) - width = val->len(); - - assert(width > 0); - sig = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, width); - sig->data_type(IVL_VT_LOGIC); - sig->local_flag(true); - - /* Take the 2s complement by taking the 1s complement - and adding 1. */ - verinum tmp (v_not(*val), width); - verinum one (1UL, width); - tmp = verinum(tmp + one, width); - tmp.has_sign(val->has_sign()); - - NetConst*con = new NetConst(scope, scope->local_symbol(), tmp); - connect(sig->pin(0), con->pin(0)); - - if (debug_elaborate) { - cerr << get_fileline() << ": debug: Replace expression " - << *this << " with constant " << tmp << "."<(expr)) { + return elab_net_uminus_const_logic_(des, scope, tmp, + width, rise, fall, decay, + drive0, drive1); } - delete val; - des->add_node(con); - return sig; + if (NetECReal*tmp = dynamic_cast(expr)) { + return elab_net_uminus_const_real_(des, scope, tmp, + width, rise, fall, decay, + drive0, drive1); + } + } - } while (0); - - NetNet* sub_sig = expr_->elaborate_net(des, scope, owidth, 0, 0, 0); + NetNet* sub_sig = expr->synthesize(des); if (sub_sig == 0) { des->errors += 1; return 0; @@ -3115,3 +3092,73 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, return sig; } +NetNet* PEUnary::elab_net_uminus_const_logic_(Design*des, NetScope*scope, + NetEConst*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const +{ + verinum val = expr->value(); + + if (width == 0) + width = val.len(); + + assert(width > 0); + NetNet*sig = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, width); + sig->data_type(IVL_VT_LOGIC); + sig->local_flag(true); + + /* Take the 2s complement by taking the 1s complement + and adding 1. */ + verinum tmp (v_not(val), width); + verinum one (1UL, width); + tmp = verinum(tmp + one, width); + tmp.has_sign(val.has_sign()); + + NetConst*con = new NetConst(scope, scope->local_symbol(), tmp); + connect(sig->pin(0), con->pin(0)); + + if (debug_elaborate) { + cerr << get_fileline() << ": debug: Replace expression " + << *this << " with constant " << tmp << "."<add_node(con); + return sig; +} + +NetNet* PEUnary::elab_net_uminus_const_real_(Design*des, NetScope*scope, + NetECReal*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const +{ + verireal val = expr->value(); + + NetNet*sig = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, width); + sig->data_type(IVL_VT_REAL); + sig->local_flag(true); + + NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), -val); + + connect(con->pin(0), sig->pin(0)); + des->add_node(con); + + if (debug_elaborate) { + cerr << get_fileline() << ": debug: Replace expression " + << *this << " with constant " << con->value_real() << "."< Date: Sun, 6 Jan 2008 20:54:33 -0800 Subject: [PATCH 3/5] Handle real-valued unary in general Handle the unary minus with general sub-expressions. --- PExpr.h | 8 ++++++ elab_net.cc | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/PExpr.h b/PExpr.h index e1d5f2056..73e7be2fc 100644 --- a/PExpr.h +++ b/PExpr.h @@ -503,6 +503,14 @@ class PEUnary : public PExpr { const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; + NetNet* elab_net_unary_real_(Design*des, NetScope*scope, + NetExpr*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const; private: char op_; diff --git a/elab_net.cc b/elab_net.cc index 9ea0b673b..ffcbd27e7 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -2931,6 +2931,8 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, Link::strength_t drive1) const { NetExpr*expr = elab_and_eval(des, scope, expr_, width); + if (expr == 0) + return 0; // Some unary operands allow the operand to be // self-determined, and some do not. @@ -2963,6 +2965,13 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, } } + // Handle the case that the expression is real-valued. + if (expr->expr_type() == IVL_VT_REAL) { + return elab_net_unary_real_(des, scope, expr, + width, rise, fall, decay, + drive0, drive1); + } + NetNet* sub_sig = expr->synthesize(des); if (sub_sig == 0) { des->errors += 1; @@ -2970,6 +2979,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, } assert(sub_sig); + delete expr; + expr = 0; + bool reduction=false; NetUReduce::TYPE rtype = NetUReduce::NONE; @@ -3162,3 +3174,69 @@ NetNet* PEUnary::elab_net_uminus_const_real_(Design*des, NetScope*scope, return sig; } + +NetNet* PEUnary::elab_net_unary_real_(Design*des, NetScope*scope, + NetExpr*expr, + unsigned width, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) const +{ + if (debug_elaborate) { + cerr << get_fileline() << ": debug: Elaborate real expression " + << *this << "."<synthesize(des); + delete expr; + if (sub_sig == 0) { + des->errors += 1; + return 0; + } + ivl_assert(*this, sub_sig); + + NetNet*sig = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, 1); + sig->data_type(IVL_VT_REAL); + sig->set_signed(true); + sig->local_flag(true); + sig->set_line(*this); + + switch (op_) { + + default: + cerr << get_fileline() << ": internal error: Unhandled UNARY " + << op_ << " expression with real values." << endl; + des->errors += 1; + break; + + case '-': + NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(), 1); + sub->attribute(perm_string::literal("LPM_Direction"), + verinum("SUB")); + sub->set_line(*this); + des->add_node(sub); + connect(sig->pin(0), sub->pin_Result()); + connect(sub_sig->pin(0), sub->pin_DataB()); + + NetLiteral*tmp_con = new NetLiteral(scope, scope->local_symbol(), + verireal(0.0)); + tmp_con->set_line(*this); + des->add_node(tmp_con); + + NetNet*tmp_sig = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, 1); + tmp_sig->data_type(IVL_VT_REAL); + tmp_sig->set_signed(true); + tmp_sig->local_flag(true); + tmp_sig->set_line(*this); + + connect(tmp_sig->pin(0), sub->pin_DataA()); + connect(tmp_sig->pin(0), tmp_con->pin(0)); + break; + } + + return sig; +} From eb5e7b792b8aa7a07945d62ba96c2ccd4abe966f Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 4 Jan 2008 12:35:27 -0800 Subject: [PATCH 4/5] Spelling fixes Sorry, I can't help myself. :-p --- ivl_target.h | 2 +- vpip/vpi_bit.c | 2 +- vvp/delay.cc | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ivl_target.h b/ivl_target.h index 50903fffc..09c51a1e5 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -1081,7 +1081,7 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net); * for the signal function return value. The width of this nexus must * exactly match the width of the device from ivl_lpm_width. * - * The ivl_lpm_data function retrives the nexa for all the input + * The ivl_lpm_data function retrieves the nexa for all the input * ports. The ivl_lpm_size function returns the number of inputs for * the device, and the ivl_lpm_data() function index argument selects * the port to retrieve. Each port is sized independently. diff --git a/vpip/vpi_bit.c b/vpip/vpi_bit.c index 3829ad328..a97ac6803 100644 --- a/vpip/vpi_bit.c +++ b/vpip/vpi_bit.c @@ -107,7 +107,7 @@ vpip_bit_t vpip_pair_resolve(vpip_bit_t a, vpip_bit_t b) res = tmp; } - /* Cannonicalize the HiZ value. */ + /* Canonicalize the HiZ value. */ if ((res&0x77) == 0) res = HiZ; diff --git a/vvp/delay.cc b/vvp/delay.cc index 672d54918..9bcc2ed5e 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -563,8 +563,8 @@ static int modpath_src_free_object( vpiHandle ref ) } /* - * This Routine will put specific demension of delay[] values - * into a vpiHandle. In this case, he will put an + * This routine will put specific dimension of delay[] values + * into a vpiHandle. In this case, he will put * specific delays values in a vpiModPathIn object * */ @@ -628,9 +628,9 @@ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) } /* - * This Routine will retrive the delay[12] values - * of an vpiHandle. In this case, he will get an - * specific delays values from an vpiModPathIn + * This routine will retrieve the delay[12] values + * of a vpiHandle. In this case, he will get an + * specific delays values from a vpiModPathIn * object * */ @@ -734,7 +734,7 @@ static void initialize_path_term(struct __vpiModPathTerm&obj) } /* - * This function will Construct a vpiModPath Object. + * This function will construct a vpiModPath Object. * give a respective "net", and will point to his * respective functor */ @@ -752,7 +752,7 @@ struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) /* - * This function will Constructs a vpiModPathIn + * This function will construct a vpiModPathIn * ( struct __vpiModPathSrc ) Object. will give * a delays[12] values, and point to the specified functor * @@ -772,7 +772,7 @@ struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path, vvp_tim /* - this Routine will safetly convert a modpath vpiHandle + this routine will safely convert a modpath vpiHandle to a struct __vpiModPath { } */ @@ -785,8 +785,8 @@ struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) } /* - this Routine will safetly convert a modpathsrc vpiHandle - to a struct __vpiModPathSrc { }, This is equivalent ao + this routine will safely convert a modpathsrc vpiHandle + to a struct __vpiModPathSrc { }, This is equivalent to a vpiModPathIn handle */ From 1f7957c612d6f0e4a1d37c631b1cc5b17a731679 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 8 Jan 2008 18:54:55 -0800 Subject: [PATCH 5/5] Fix type handling of real-value system functions in nets In nets, if system functions return a real value the function lookup was getting the correct width, but was also setting the width to 0, which confused down-stream net handling. Real-value system fuctions have a width of 1. (1 real-valued scalar.) --- design_dump.cc | 3 ++- elab_net.cc | 10 ++++++++++ net_func.cc | 5 +++++ netlist.h | 1 + sys_funcs.cc | 8 ++++---- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 950925d53..b9ce6ad04 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -512,7 +512,8 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const void NetSysFunc::dump_node(ostream&o, unsigned ind) const { - o << setw(ind) << "" << def_->name << "(...)" << endl; + o << setw(ind) << "" << def_->name << "(...) -->" + << data_type() << " width=" << vector_width() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } diff --git a/elab_net.cc b/elab_net.cc index ffcbd27e7..dcbed7a70 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -1365,6 +1365,11 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope, return 0; } + if (debug_elaborate) { + cerr << get_fileline() << ": debug: Net system function " + << name << " returns " << def->type << endl; + } + NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(), def, 1+parms_.count()); des->add_node(net); @@ -1373,6 +1378,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, def->wid); osig->local_flag(true); + osig->set_signed(def->type==IVL_VT_REAL? true : false); osig->data_type(def->type); osig->set_line(*this); @@ -2170,7 +2176,9 @@ NetNet* PEFNumber::elaborate_net(Design*des, NetScope*scope, NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1); net->data_type(IVL_VT_REAL); + net->set_signed(true); net->local_flag(true); + net->set_line(*this); connect(net->pin(0), obj->pin(0)); return net; @@ -3158,7 +3166,9 @@ NetNet* PEUnary::elab_net_uminus_const_real_(Design*des, NetScope*scope, NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, width); sig->data_type(IVL_VT_REAL); + sig->set_signed(true); sig->local_flag(true); + sig->set_line(*this); NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), -val); diff --git a/net_func.cc b/net_func.cc index 137e75dbd..5d270475e 100644 --- a/net_func.cc +++ b/net_func.cc @@ -138,6 +138,11 @@ const char*NetSysFunc::func_name() const return def_->name; } +ivl_variable_type_t NetSysFunc::data_type() const +{ + return def_->type; +} + unsigned NetSysFunc::vector_width() const { return def_->wid; diff --git a/netlist.h b/netlist.h index 022187df3..a4d47e58d 100644 --- a/netlist.h +++ b/netlist.h @@ -1047,6 +1047,7 @@ class NetSysFunc : public NetNode { unsigned ports); ~NetSysFunc(); + ivl_variable_type_t data_type() const; unsigned vector_width() const; const char* func_name() const; diff --git a/sys_funcs.cc b/sys_funcs.cc index 498d31a54..633540b00 100644 --- a/sys_funcs.cc +++ b/sys_funcs.cc @@ -33,9 +33,9 @@ */ static const struct sfunc_return_type sfunc_table[] = { - { "$realtime", IVL_VT_REAL, 0, 0 }, - { "$bitstoreal", IVL_VT_REAL, 0, 0 }, - { "$itor", IVL_VT_REAL, 0, 0 }, + { "$realtime", IVL_VT_REAL, 1, 0 }, + { "$bitstoreal", IVL_VT_REAL, 1, 0 }, + { "$itor", IVL_VT_REAL, 1, 0 }, { "$realtobits", IVL_VT_LOGIC, 64, 0 }, { "$time", IVL_VT_LOGIC, 64, 0 }, { "$stime", IVL_VT_LOGIC, 32, 0 }, @@ -127,7 +127,7 @@ int load_sys_func_table(const char*path) cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_REAL; - cell->wid = 0; + cell->wid = 1; cell->signed_flag = true; cell->next = sfunc_stack; sfunc_stack = cell;