Merge pull request #42 from orsonmmz/const_package

Enable constant initializers that require elaboration in packages.
This commit is contained in:
Stephen Williams 2014-09-18 12:58:19 -07:00
commit d13e488f4c
11 changed files with 149 additions and 89 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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());
}
}
}

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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 << ")";
}