Merge pull request #42 from orsonmmz/const_package
Enable constant initializers that require elaboration in packages.
This commit is contained in:
commit
d13e488f4c
|
|
@ -767,7 +767,7 @@ int ExpString::emit_as_array_(ostream& out, Entity*, Architecture*, const VTypeA
|
|||
int errors = 0;
|
||||
assert(arr->dimensions() == 1);
|
||||
|
||||
const VTypePrimitive*etype = dynamic_cast<const VTypePrimitive*> (arr->element_type());
|
||||
const VTypePrimitive*etype = dynamic_cast<const VTypePrimitive*> (arr->basic_type());
|
||||
assert(etype);
|
||||
|
||||
// Detect the special case that this is an array of
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ void ExpAggregate::write_to_stream(ostream&fd)
|
|||
fd << "(";
|
||||
for (vector<element_t*>::const_iterator cur = elements_.begin()
|
||||
; cur != elements_.end() ; ++cur) {
|
||||
if(cur != elements_.begin())
|
||||
fd << ", ";
|
||||
|
||||
(*cur)->write_to_stream(fd);
|
||||
}
|
||||
fd << ")";
|
||||
|
|
@ -41,7 +44,8 @@ void ExpAggregate::element_t::write_to_stream(ostream&fd) const
|
|||
(*cur)->write_to_stream(fd);
|
||||
}
|
||||
|
||||
fd << "=>";
|
||||
if(!fields_.empty())
|
||||
fd << "=>";
|
||||
val_->write_to_stream(fd);
|
||||
}
|
||||
|
||||
|
|
@ -112,9 +116,14 @@ void ExpAttribute::write_to_stream(ostream&)
|
|||
ivl_assert(*this, !"Not supported");
|
||||
}
|
||||
|
||||
void ExpBitstring::write_to_stream(ostream&)
|
||||
void ExpBitstring::write_to_stream(ostream&fd)
|
||||
{
|
||||
ivl_assert(*this, !"Not supported");
|
||||
fd << "\"";
|
||||
for(vector<char>::const_iterator it = value_.begin();
|
||||
it != value_.end(); ++it) {
|
||||
fd << *it;
|
||||
}
|
||||
fd << "\"";
|
||||
}
|
||||
|
||||
void ExpCharacter::write_to_stream(ostream&fd)
|
||||
|
|
@ -198,9 +207,14 @@ void ExpRelation::write_to_stream(ostream&)
|
|||
ivl_assert(*this, !"Not supported");
|
||||
}
|
||||
|
||||
void ExpString::write_to_stream(ostream&)
|
||||
void ExpString::write_to_stream(ostream&fd)
|
||||
{
|
||||
ivl_assert(*this, !"Not supported");
|
||||
fd << "\"";
|
||||
for(vector<char>::const_iterator it = value_.begin();
|
||||
it != value_.end(); ++it) {
|
||||
fd << *it;
|
||||
}
|
||||
fd << "\"";
|
||||
}
|
||||
|
||||
void ExpUAbs::write_to_stream(ostream&fd)
|
||||
|
|
|
|||
|
|
@ -66,21 +66,6 @@ void Package::write_to_stream(ostream&fd) const
|
|||
fd << "type " << cur->first << ";" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.begin()
|
||||
; cur != cur_constants_.end() ; ++ cur) {
|
||||
if (cur->second==0 || cur->second->typ==0) {
|
||||
fd << "-- const " << cur->first
|
||||
<< " has errors." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
fd << "constant " << cur->first << ": ";
|
||||
cur->second->typ->write_to_stream(fd);
|
||||
fd << " := ";
|
||||
cur->second->val->write_to_stream(fd);
|
||||
fd << ";" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,const VType*>::const_iterator cur = use_types_.begin()
|
||||
; cur != use_types_.end() ; ++cur) {
|
||||
|
||||
|
|
@ -108,6 +93,21 @@ void Package::write_to_stream(ostream&fd) const
|
|||
fd << ";" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.begin()
|
||||
; cur != cur_constants_.end() ; ++ cur) {
|
||||
if (cur->second==0 || cur->second->typ==0) {
|
||||
fd << "-- const " << cur->first
|
||||
<< " has errors." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
fd << "constant " << cur->first << ": ";
|
||||
cur->second->typ->write_to_stream(fd);
|
||||
fd << " := ";
|
||||
cur->second->val->write_to_stream(fd);
|
||||
fd << ";" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,Subprogram*>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
cur->second->write_to_stream(fd);
|
||||
|
|
|
|||
|
|
@ -52,18 +52,18 @@ int Package::emit_package(ostream&fd) const
|
|||
fd << " ;" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,struct const_t*>::const_iterator cur = use_constants_.begin()
|
||||
; cur != use_constants_.end() ; ++cur) {
|
||||
fd << "localparam \\" << cur->first << " = ";
|
||||
errors += cur->second->val->emit_package(fd);
|
||||
fd << ";" << endl;
|
||||
}
|
||||
for (map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.begin()
|
||||
; cur != cur_constants_.end() ; ++cur) {
|
||||
fd << "localparam " << cur->first << " = ";
|
||||
errors += cur->second->val->emit_package(fd);
|
||||
fd << ";" << endl;
|
||||
}
|
||||
//for (map<perm_string,struct const_t*>::const_iterator cur = use_constants_.begin()
|
||||
//; cur != use_constants_.end() ; ++cur) {
|
||||
//fd << "localparam \\" << cur->first << " = ";
|
||||
//errors += cur->second->val->emit_package(fd);
|
||||
//fd << ";" << endl;
|
||||
//}
|
||||
//for (map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.begin()
|
||||
//; cur != cur_constants_.end() ; ++cur) {
|
||||
//fd << "localparam " << cur->first << " = ";
|
||||
//errors += cur->second->val->emit_package(fd);
|
||||
//fd << ";" << endl;
|
||||
//}
|
||||
|
||||
for (map<perm_string,Subprogram*>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++ cur) {
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ composite_type_definition
|
|||
/* unbounded_array_definition IEEE 1076-2008 P5.3.2.1 */
|
||||
| K_array '(' index_subtype_definition_list ')' K_of subtype_indication
|
||||
{ std::list<prange_t*> r;
|
||||
r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type
|
||||
r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type
|
||||
VTypeArray*tmp = new VTypeArray($6, &r);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ void bind_architecture_to_entity(const char*ename, Architecture*arch)
|
|||
static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase* /* scope */,
|
||||
Expression*array_left,
|
||||
bool /* downto*/ ,
|
||||
bool downto,
|
||||
Expression*array_right)
|
||||
{
|
||||
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
||||
|
|
@ -82,7 +82,8 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n
|
|||
|
||||
assert(array_left==0 || array_right!=0);
|
||||
|
||||
// unfold typedef, if it is the case
|
||||
// unfold typedef, there might be VTypeArray inside
|
||||
const VType*origin_type = base_type;
|
||||
const VTypeDef*type_def = dynamic_cast<const VTypeDef*> (base_type);
|
||||
if (type_def) {
|
||||
base_type = type_def->peek_definition();
|
||||
|
|
@ -97,9 +98,13 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n
|
|||
// For now, I only know how to handle 1 dimension
|
||||
assert(base_array->dimensions() == 1);
|
||||
|
||||
range[0] = VTypeArray::range_t(array_left, array_right);
|
||||
range[0] = VTypeArray::range_t(array_left, array_right, downto);
|
||||
|
||||
VTypeArray*subtype = new VTypeArray(base_array->element_type(), range, base_array->signed_vector());
|
||||
// use typedef as the element type if possible
|
||||
const VType*element = type_def ? origin_type : base_array->element_type();
|
||||
|
||||
VTypeArray*subtype = new VTypeArray(element, range,
|
||||
base_array->signed_vector());
|
||||
return subtype;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,10 +50,7 @@ void SigVarBase::elaborate_init_expr(Entity*ent, Architecture*arc)
|
|||
init_expr_ = bitstring;
|
||||
}
|
||||
else {
|
||||
ExpAggregate*aggr = dynamic_cast<ExpAggregate*>(init_expr_);
|
||||
if(aggr) {
|
||||
aggr->elaborate_expr(ent, arc, peek_type());
|
||||
}
|
||||
init_expr_->elaborate_expr(ent, arc, peek_type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ VTypeArray::VTypeArray(const VType*element, std::list<prange_t*>*r, bool sv)
|
|||
r->pop_front();
|
||||
Expression*msb = curp->msb();
|
||||
Expression*lsb = curp->lsb();
|
||||
ranges_[idx] = range_t(msb, lsb);
|
||||
bool dir = curp->is_downto();
|
||||
ranges_[idx] = range_t(msb, lsb, dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,14 +98,28 @@ VTypeArray::~VTypeArray()
|
|||
{
|
||||
}
|
||||
|
||||
size_t VTypeArray::dimensions() const
|
||||
const VType* VTypeArray::basic_type(bool typedef_allowed) const
|
||||
{
|
||||
return ranges_.size();
|
||||
}
|
||||
const VType*t = etype_;
|
||||
const VTypeDef*tdef = NULL;
|
||||
bool progress = false;
|
||||
|
||||
const VType* VTypeArray::element_type() const
|
||||
{
|
||||
return etype_;
|
||||
do {
|
||||
progress = false;
|
||||
|
||||
if((tdef = dynamic_cast<const VTypeDef*>(t))) {
|
||||
t = tdef->peek_definition();
|
||||
}
|
||||
|
||||
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(t)) {
|
||||
t = arr->element_type();
|
||||
progress = true;
|
||||
} else if(tdef) { // return the typedef if it does not define an array
|
||||
t = typedef_allowed ? tdef : tdef->peek_definition();
|
||||
}
|
||||
} while(progress);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void VTypeArray::show(ostream&out) const
|
||||
|
|
|
|||
|
|
@ -173,17 +173,19 @@ class VTypeArray : public VType {
|
|||
public:
|
||||
class range_t {
|
||||
public:
|
||||
range_t() : msb_(0), lsb_(0) { }
|
||||
range_t(Expression*m, Expression*l) : msb_(m), lsb_(l) { }
|
||||
range_t(Expression*m = NULL, Expression*l = NULL, bool dir = true) :
|
||||
msb_(m), lsb_(l), direction_(dir) { }
|
||||
|
||||
bool is_box() const { return msb_==0 && lsb_==0; }
|
||||
inline bool is_box() const { return msb_==0 && lsb_==0; }
|
||||
inline bool is_downto() const { return direction_; }
|
||||
|
||||
Expression* msb() const { return msb_; }
|
||||
Expression* lsb() const { return lsb_; }
|
||||
inline Expression* msb() const { return msb_; }
|
||||
inline Expression* lsb() const { return lsb_; }
|
||||
|
||||
private:
|
||||
Expression* msb_;
|
||||
Expression* lsb_;
|
||||
bool direction_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -195,13 +197,20 @@ class VTypeArray : public VType {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
void show(std::ostream&) const;
|
||||
|
||||
size_t dimensions() const;
|
||||
inline size_t dimensions() const { return ranges_.size(); };
|
||||
const range_t&dimension(size_t idx) const
|
||||
{ return ranges_[idx]; }
|
||||
|
||||
bool signed_vector() const { return signed_flag_; }
|
||||
inline bool signed_vector() const { return signed_flag_; }
|
||||
|
||||
const VType* element_type() const;
|
||||
// returns the type of element held in the array
|
||||
inline const VType* element_type() const { return etype_; }
|
||||
|
||||
// returns the basic type of element held in the array
|
||||
// (unfolds typedefs and multidimensional arrays)
|
||||
// typedef_allowed decides if VTypeDef can be returned or should
|
||||
// it be unfolded
|
||||
const VType* basic_type(bool typedef_allowed = true) const;
|
||||
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
||||
|
|
@ -210,6 +219,7 @@ class VTypeArray : public VType {
|
|||
bool can_be_packed() const { return etype_->can_be_packed(); }
|
||||
|
||||
private:
|
||||
void write_range_to_stream_(std::ostream&fd) const;
|
||||
const VType*etype_;
|
||||
|
||||
std::vector<range_t> ranges_;
|
||||
|
|
@ -240,6 +250,7 @@ class VTypeEnum : public VType {
|
|||
VTypeEnum(const std::list<perm_string>*names);
|
||||
~VTypeEnum();
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
void show(std::ostream&) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,12 +60,8 @@ int VTypeArray::emit_def(ostream&out, perm_string name) const
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
const VTypeArray*cur = this;
|
||||
while (const VTypeArray*sub = dynamic_cast<const VTypeArray*> (cur->etype_)) {
|
||||
cur = sub;
|
||||
}
|
||||
const VType*raw_base = basic_type();
|
||||
|
||||
const VType*raw_base = cur->etype_;
|
||||
const VTypePrimitive*base = dynamic_cast<const VTypePrimitive*> (raw_base);
|
||||
|
||||
if (base) {
|
||||
|
|
|
|||
|
|
@ -42,45 +42,52 @@ void VTypeArray::write_to_stream(ostream&fd) const
|
|||
if (etype_ == &primitive_STDLOGIC) {
|
||||
fd << "std_logic_vector";
|
||||
if (! ranges_.empty() && ! ranges_[0].is_box()) {
|
||||
assert(ranges_.size() < 2);
|
||||
fd << " (";
|
||||
if (ranges_[0].msb())
|
||||
ranges_[0].msb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
fd << " downto ";
|
||||
if (ranges_[0].lsb())
|
||||
ranges_[0].lsb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
fd << ") ";
|
||||
write_range_to_stream_(fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fd << "array ";
|
||||
bool typedefed = false;
|
||||
if(const VTypeDef*tdef = dynamic_cast<const VTypeDef*>(etype_)) {
|
||||
tdef->write_to_stream(fd);
|
||||
typedefed = true;
|
||||
} else {
|
||||
fd << "array ";
|
||||
}
|
||||
|
||||
if (! ranges_.empty()) {
|
||||
assert(ranges_.size() < 2);
|
||||
if (ranges_[0].is_box()) {
|
||||
fd << "(INTEGER range <>) ";
|
||||
} else {
|
||||
assert(ranges_[0].msb() && ranges_[0].lsb());
|
||||
fd << "(";
|
||||
if (ranges_[0].msb())
|
||||
ranges_[0].msb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
fd << " downto ";
|
||||
if (ranges_[0].lsb())
|
||||
ranges_[0].lsb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
fd << ") ";
|
||||
write_range_to_stream_(fd);
|
||||
}
|
||||
}
|
||||
|
||||
fd << "of ";
|
||||
etype_->write_to_stream(fd);
|
||||
if(!typedefed) {
|
||||
fd << "of ";
|
||||
etype_->write_to_stream(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void VTypeArray::write_range_to_stream_(std::ostream&fd) const
|
||||
{
|
||||
assert(ranges_.size() < 2);
|
||||
assert(ranges_[0].msb() && ranges_[0].lsb());
|
||||
|
||||
fd << "(";
|
||||
if (ranges_[0].msb())
|
||||
ranges_[0].msb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
|
||||
fd << (ranges_[0].is_downto() ? " downto " : " to ");
|
||||
|
||||
if (ranges_[0].lsb())
|
||||
ranges_[0].lsb()->write_to_stream(fd);
|
||||
else
|
||||
fd << "<>";
|
||||
fd << ") ";
|
||||
}
|
||||
|
||||
void VTypeDef::write_type_to_stream(ostream&fd) const
|
||||
|
|
@ -148,3 +155,18 @@ void VTypeRecord::element_t::write_to_stream(ostream&fd) const
|
|||
fd << name_ << ": ";
|
||||
type_->write_to_stream(fd);
|
||||
}
|
||||
|
||||
void VTypeEnum::write_to_stream(std::ostream&fd) const
|
||||
{
|
||||
fd << "(";
|
||||
for (vector<perm_string>::const_iterator it = names_.begin();
|
||||
it != names_.end(); ++it) {
|
||||
if(it != names_.begin())
|
||||
fd << ",";
|
||||
|
||||
fd << *it;
|
||||
|
||||
}
|
||||
fd << ")";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue