It is an error to select part of a scalar value.
In 1364-2005 it is an explicit error to take the select of a scalar or real value. We added the checks for real a while ago. This patch adds the functionality for scalar values. In the future we may want to push the scalar property to the run time.
This commit is contained in:
parent
5d5c7e88f9
commit
b1dd0b1f6d
16
PWire.cc
16
PWire.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 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
|
||||
|
|
@ -29,8 +29,8 @@ PWire::PWire(perm_string n,
|
|||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_msb_(0), port_lsb_(0), port_set_(false),
|
||||
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
|
||||
lidx_(0), ridx_(0), discipline_(0)
|
||||
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
|
|
@ -135,7 +135,12 @@ bool PWire::get_isint() const
|
|||
return isint_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||
bool PWire::get_scalar() const
|
||||
{
|
||||
return is_scalar_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
||||
{
|
||||
switch (type) {
|
||||
case SR_PORT:
|
||||
|
|
@ -147,6 +152,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
port_msb_ = m;
|
||||
port_lsb_ = l;
|
||||
port_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -159,6 +165,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -181,6 +188,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
6
PWire.h
6
PWire.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 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
|
||||
|
|
@ -70,11 +70,12 @@ class PWire : public LineInfo {
|
|||
void set_signed(bool flag);
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
bool get_scalar() const;
|
||||
|
||||
bool set_data_type(ivl_variable_type_t dt);
|
||||
ivl_variable_type_t get_data_type() const;
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
|
||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type, bool is_scalar);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
|
|
@ -104,6 +105,7 @@ class PWire : public LineInfo {
|
|||
PExpr*net_msb_;
|
||||
PExpr*net_lsb_;
|
||||
bool net_set_;
|
||||
bool is_scalar_;
|
||||
unsigned error_cnt_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
|
|
|
|||
18
elab_expr.cc
18
elab_expr.cc
|
|
@ -2642,11 +2642,13 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
if (name_tail.index.size() > 1)
|
||||
word_sel = name_tail.index.back().sel;
|
||||
|
||||
if (res->expr_type() == IVL_VT_REAL &&
|
||||
if (net->get_scalar() &&
|
||||
word_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real array word: "
|
||||
<< net->name() <<"[" << *word_index << "]" << endl;
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (res->expr_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << net->name()
|
||||
<<"[" << *word_index << "]" << endl;
|
||||
des->errors += 1;
|
||||
delete res;
|
||||
return 0;
|
||||
|
|
@ -2946,10 +2948,12 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
if (! path_.back().index.empty())
|
||||
use_sel = path_.back().index.back().sel;
|
||||
|
||||
if (node->expr_type() == IVL_VT_REAL &&
|
||||
if (net->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real: " << net->name() << endl;
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (node->expr_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << net->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
19
elab_lval.cc
19
elab_lval.cc
|
|
@ -199,10 +199,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
return elaborate_lval_net_word_(des, scope, reg);
|
||||
|
||||
// This must be after the array word elaboration above!
|
||||
if (reg->data_type() == IVL_VT_REAL &&
|
||||
if (reg->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real: " << reg->name() << endl;
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (reg->data_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << reg->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -301,12 +303,13 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
if (name_tail.index.size() > 1)
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
if (reg->data_type() == IVL_VT_REAL &&
|
||||
if (reg->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real array word: "
|
||||
<< reg->name() << "[" << *word << "]" << endl;
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << reg->name()
|
||||
<< "[" << *word << "]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
17
elab_net.cc
17
elab_net.cc
|
|
@ -466,10 +466,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
|
||||
/* The array has a part/bit select at the end. */
|
||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||
if (sig->data_type() == IVL_VT_REAL) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real array word: "
|
||||
<< sig->name() << "[" << widx_val << "]" << endl;
|
||||
<< "can not select part of ";
|
||||
if (sig->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << sig->name()
|
||||
<< "[" << widx_val << "]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -489,10 +492,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
lidx = lidx_tmp;
|
||||
}
|
||||
} else if (!name_tail.index.empty()) {
|
||||
if (sig->data_type() == IVL_VT_REAL) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real: "
|
||||
<< sig->name() << endl;
|
||||
<< "can not select part of ";
|
||||
if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << sig->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
25
elab_sig.cc
25
elab_sig.cc
|
|
@ -599,9 +599,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
|
||||
ret_sig->set_scalar(false);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
ret_sig->set_scalar(true);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_REG_S);
|
||||
|
|
@ -614,6 +616,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
|
@ -623,6 +626,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
|
@ -633,6 +637,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_REAL);
|
||||
break;
|
||||
|
|
@ -850,10 +855,15 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
|||
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
bool is_implicit_scalar = false;
|
||||
if (wtype == NetNet::IMPLICIT) {
|
||||
wtype = NetNet::WIRE;
|
||||
if (wtype == NetNet::IMPLICIT_REG)
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
if (wtype == NetNet::IMPLICIT_REG) {
|
||||
wtype = NetNet::REG;
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
|
||||
unsigned wid = 1;
|
||||
long lsb = 0, msb = 0;
|
||||
|
|
@ -902,6 +912,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
delete texpr;
|
||||
nmsb = pmsb;
|
||||
nlsb = plsb;
|
||||
/* An implicit port can have a range so note that here. */
|
||||
is_implicit_scalar = false;
|
||||
}
|
||||
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
|
||||
if (port_msb_ == 0) assert(port_lsb_ == 0);
|
||||
|
|
@ -1095,8 +1107,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal "
|
||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_;
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
if (!get_scalar()) {
|
||||
cerr << " ["<<msb<<":"<<lsb<<"]";
|
||||
}
|
||||
cerr << " " << name_;
|
||||
if (array_dimensions > 0) {
|
||||
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
|
||||
}
|
||||
|
|
@ -1126,6 +1141,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
if (is_implicit_scalar) sig->set_scalar(true);
|
||||
else sig->set_scalar(get_scalar());
|
||||
|
||||
if (ivl_discipline_t dis = get_discipline()) {
|
||||
sig->set_discipline(dis);
|
||||
|
|
|
|||
20
netlist.cc
20
netlist.cc
|
|
@ -491,8 +491,8 @@ const Link& NetDelaySrc::condit_pin() const
|
|||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
|
||||
signed_(false), isint_(false), discipline_(0), msb_(npins-1), lsb_(0),
|
||||
dimensions_(0),
|
||||
signed_(false), isint_(false), is_scalar_(false),
|
||||
discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0),
|
||||
s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
|
|
@ -544,7 +544,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
long ms, long ls)
|
||||
: NetObj(s, n, 1), type_(t),
|
||||
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
|
||||
isint_(false), discipline_(0), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0),
|
||||
isint_(false), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
dimensions_(0), s0_(0), e0_(0),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
|
|
@ -594,7 +595,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
: NetObj(s, n, calculate_count(array_s, array_e)),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e),
|
||||
is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
dimensions_(1), s0_(array_s), e0_(array_e),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
ivl_assert(*this, s);
|
||||
|
|
@ -727,6 +729,16 @@ void NetNet::set_isint(bool flag)
|
|||
isint_ = flag;
|
||||
}
|
||||
|
||||
bool NetNet::get_scalar() const
|
||||
{
|
||||
return is_scalar_;
|
||||
}
|
||||
|
||||
void NetNet::set_scalar(bool flag)
|
||||
{
|
||||
is_scalar_ = flag;
|
||||
}
|
||||
|
||||
ivl_discipline_t NetNet::get_discipline() const
|
||||
{
|
||||
return discipline_;
|
||||
|
|
|
|||
|
|
@ -581,6 +581,9 @@ class NetNet : public NetObj {
|
|||
bool get_isint() const;
|
||||
void set_isint(bool);
|
||||
|
||||
bool get_scalar() const;
|
||||
void set_scalar(bool);
|
||||
|
||||
/* Attach a discipline to the net. */
|
||||
ivl_discipline_t get_discipline() const;
|
||||
void set_discipline(ivl_discipline_t dis);
|
||||
|
|
@ -650,6 +653,7 @@ class NetNet : public NetObj {
|
|||
ivl_variable_type_t data_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
bool is_scalar_;
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
long msb_, lsb_;
|
||||
|
|
|
|||
18
pform.cc
18
pform.cc
|
|
@ -1031,13 +1031,13 @@ static void pform_set_net_range(perm_string name,
|
|||
if (range == 0) {
|
||||
/* This is the special case that we really mean a
|
||||
scalar. Set a fake range. */
|
||||
cur->set_range(0, 0, rt);
|
||||
cur->set_range(0, 0, rt, true);
|
||||
|
||||
} else {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1], rt);
|
||||
cur->set_range((*range)[0], (*range)[1], rt, false);
|
||||
}
|
||||
cur->set_signed(signed_flag);
|
||||
|
||||
|
|
@ -1399,14 +1399,16 @@ void pform_module_define_port(const struct vlltype&li,
|
|||
|
||||
if (range == 0) {
|
||||
cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT :
|
||||
SR_BOTH);
|
||||
SR_BOTH,
|
||||
true);
|
||||
|
||||
} else {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1],
|
||||
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
|
||||
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH,
|
||||
false);
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
|
|
@ -1486,7 +1488,7 @@ void pform_makewire(const vlltype&li, perm_string name,
|
|||
<< " to " << dt << "." << endl;
|
||||
}
|
||||
ivl_assert(*cur, flag);
|
||||
cur->set_range(0, 0, SR_NET);
|
||||
cur->set_range(0, 0, SR_NET, true);
|
||||
cur->set_signed(true);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1676,7 +1678,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
|||
|
||||
/* If there is a range involved, it needs to be set. */
|
||||
if (range)
|
||||
curw->set_range((*range)[0], (*range)[1], SR_PORT);
|
||||
curw->set_range((*range)[0], (*range)[1], SR_PORT, false);
|
||||
|
||||
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
|
||||
|
||||
|
|
@ -1936,7 +1938,7 @@ static void pform_set_reg_integer(perm_string name)
|
|||
|
||||
cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)),
|
||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
||||
SR_NET);
|
||||
SR_NET, false);
|
||||
cur->set_signed(true);
|
||||
}
|
||||
|
||||
|
|
@ -1967,7 +1969,7 @@ static void pform_set_reg_time(perm_string name)
|
|||
|
||||
cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)),
|
||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
||||
SR_NET);
|
||||
SR_NET, false);
|
||||
}
|
||||
|
||||
void pform_set_reg_time(list<perm_string>*names)
|
||||
|
|
|
|||
Loading…
Reference in New Issue