Merge branch 'pr1864110'
This commit is contained in:
commit
3b89c1767c
26
PExpr.h
26
PExpr.h
|
|
@ -486,6 +486,32 @@ class PEUnary : public PExpr {
|
||||||
|
|
||||||
virtual bool is_constant(Module*) const;
|
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;
|
||||||
|
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:
|
private:
|
||||||
char op_;
|
char op_;
|
||||||
PExpr*expr_;
|
PExpr*expr_;
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,8 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
|
||||||
|
|
||||||
void NetSysFunc::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_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
205
elab_net.cc
205
elab_net.cc
|
|
@ -1367,6 +1367,11 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||||
return 0;
|
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(),
|
NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(),
|
||||||
def, 1+parms_.count());
|
def, 1+parms_.count());
|
||||||
des->add_node(net);
|
des->add_node(net);
|
||||||
|
|
@ -1375,6 +1380,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE, def->wid);
|
NetNet::WIRE, def->wid);
|
||||||
osig->local_flag(true);
|
osig->local_flag(true);
|
||||||
|
osig->set_signed(def->type==IVL_VT_REAL? true : false);
|
||||||
osig->data_type(def->type);
|
osig->data_type(def->type);
|
||||||
osig->set_line(*this);
|
osig->set_line(*this);
|
||||||
|
|
||||||
|
|
@ -2172,7 +2178,9 @@ NetNet* PEFNumber::elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1);
|
NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1);
|
||||||
net->data_type(IVL_VT_REAL);
|
net->data_type(IVL_VT_REAL);
|
||||||
|
net->set_signed(true);
|
||||||
net->local_flag(true);
|
net->local_flag(true);
|
||||||
|
net->set_line(*this);
|
||||||
|
|
||||||
connect(net->pin(0), obj->pin(0));
|
connect(net->pin(0), obj->pin(0));
|
||||||
return net;
|
return net;
|
||||||
|
|
@ -2932,6 +2940,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const
|
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
|
// Some unary operands allow the operand to be
|
||||||
// self-determined, and some do not.
|
// self-determined, and some do not.
|
||||||
|
|
@ -2950,51 +2961,37 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
// Handle the special case of a 2's complement of a constant
|
// Handle the special case of a 2's complement of a constant
|
||||||
// value. This can be reduced to a no-op on a precalculated
|
// value. This can be reduced to a no-op on a precalculated
|
||||||
// result.
|
// result.
|
||||||
if (op_ == '-') do {
|
if (op_ == '-') {
|
||||||
// TODO: Should replace this with a call to
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
|
||||||
// elab_and_eval. Possibly blend this with the rest of
|
return elab_net_uminus_const_logic_(des, scope, tmp,
|
||||||
// the elaboration as well.
|
width, rise, fall, decay,
|
||||||
verinum*val = expr_->eval_const(des, scope);
|
drive0, drive1);
|
||||||
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 << "."<<endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete val;
|
if (NetECReal*tmp = dynamic_cast<NetECReal*>(expr)) {
|
||||||
des->add_node(con);
|
return elab_net_uminus_const_real_(des, scope, tmp,
|
||||||
return sig;
|
width, rise, fall, decay,
|
||||||
|
drive0, drive1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} while (0);
|
// 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_->elaborate_net(des, scope, owidth, 0, 0, 0);
|
NetNet* sub_sig = expr->synthesize(des);
|
||||||
if (sub_sig == 0) {
|
if (sub_sig == 0) {
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert(sub_sig);
|
assert(sub_sig);
|
||||||
|
|
||||||
|
delete expr;
|
||||||
|
expr = 0;
|
||||||
|
|
||||||
bool reduction=false;
|
bool reduction=false;
|
||||||
NetUReduce::TYPE rtype = NetUReduce::NONE;
|
NetUReduce::TYPE rtype = NetUReduce::NONE;
|
||||||
|
|
||||||
|
|
@ -3117,3 +3114,141 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
return sig;
|
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 << "."<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete expr;
|
||||||
|
des->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->set_signed(true);
|
||||||
|
sig->local_flag(true);
|
||||||
|
sig->set_line(*this);
|
||||||
|
|
||||||
|
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() << "."<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete expr;
|
||||||
|
|
||||||
|
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 << "."<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet* sub_sig = expr->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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,11 @@ const char*NetSysFunc::func_name() const
|
||||||
return def_->name;
|
return def_->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_variable_type_t NetSysFunc::data_type() const
|
||||||
|
{
|
||||||
|
return def_->type;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned NetSysFunc::vector_width() const
|
unsigned NetSysFunc::vector_width() const
|
||||||
{
|
{
|
||||||
return def_->wid;
|
return def_->wid;
|
||||||
|
|
|
||||||
|
|
@ -1047,6 +1047,7 @@ class NetSysFunc : public NetNode {
|
||||||
unsigned ports);
|
unsigned ports);
|
||||||
~NetSysFunc();
|
~NetSysFunc();
|
||||||
|
|
||||||
|
ivl_variable_type_t data_type() const;
|
||||||
unsigned vector_width() const;
|
unsigned vector_width() const;
|
||||||
const char* func_name() const;
|
const char* func_name() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const struct sfunc_return_type sfunc_table[] = {
|
static const struct sfunc_return_type sfunc_table[] = {
|
||||||
{ "$realtime", IVL_VT_REAL, 0, 0 },
|
{ "$realtime", IVL_VT_REAL, 1, 0 },
|
||||||
{ "$bitstoreal", IVL_VT_REAL, 0, 0 },
|
{ "$bitstoreal", IVL_VT_REAL, 1, 0 },
|
||||||
{ "$itor", IVL_VT_REAL, 0, 0 },
|
{ "$itor", IVL_VT_REAL, 1, 0 },
|
||||||
{ "$realtobits", IVL_VT_LOGIC, 64, 0 },
|
{ "$realtobits", IVL_VT_LOGIC, 64, 0 },
|
||||||
{ "$time", IVL_VT_LOGIC, 64, 0 },
|
{ "$time", IVL_VT_LOGIC, 64, 0 },
|
||||||
{ "$stime", IVL_VT_LOGIC, 32, 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 = new struct sfunc_return_type_cell;
|
||||||
cell->name = lex_strings.add(name);
|
cell->name = lex_strings.add(name);
|
||||||
cell->type = IVL_VT_REAL;
|
cell->type = IVL_VT_REAL;
|
||||||
cell->wid = 0;
|
cell->wid = 1;
|
||||||
cell->signed_flag = true;
|
cell->signed_flag = true;
|
||||||
cell->next = sfunc_stack;
|
cell->next = sfunc_stack;
|
||||||
sfunc_stack = cell;
|
sfunc_stack = cell;
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,11 @@
|
||||||
assert(yylval.text);
|
assert(yylval.text);
|
||||||
return T_SYMBOL; }
|
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
|
/* Accept the common assembler style comments, treat them as white
|
||||||
space. Of course, also skip white space. The semi-colon is
|
space. Of course, also skip white space. The semi-colon is
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue