Merge pull request #38 from orsonmmz/unbounded_array
Support for VHDL unbounded arrays.
This commit is contained in:
commit
3852545f21
|
|
@ -210,3 +210,5 @@ ostream& operator << (ostream&out, perm_string that)
|
|||
out << that.str();
|
||||
return out;
|
||||
}
|
||||
|
||||
const perm_string empty_perm_string = perm_string::literal("");
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class perm_string {
|
|||
const char*text_;
|
||||
};
|
||||
|
||||
extern const perm_string empty_perm_string;
|
||||
extern bool operator == (perm_string a, perm_string b);
|
||||
extern bool operator == (perm_string a, const char* b);
|
||||
extern bool operator != (perm_string a, perm_string b);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,24 @@ int Architecture::elaborate(Entity*entity)
|
|||
cur->second->val->elaborate_expr(entity, this, cur->second->typ);
|
||||
}
|
||||
|
||||
// Elaborate initializer expressions for signals & variables
|
||||
for (map<perm_string,Signal*>::iterator cur = old_signals_.begin()
|
||||
; cur != old_signals_.end() ; ++cur) {
|
||||
cur->second->elaborate_init_expr(entity, this);
|
||||
}
|
||||
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
||||
; cur != new_signals_.end() ; ++cur) {
|
||||
cur->second->elaborate_init_expr(entity, this);
|
||||
}
|
||||
for (map<perm_string,Variable*>::iterator cur = old_variables_.begin()
|
||||
; cur != old_variables_.end() ; ++cur) {
|
||||
cur->second->elaborate_init_expr(entity, this);
|
||||
}
|
||||
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
||||
; cur != new_variables_.end() ; ++cur) {
|
||||
cur->second->elaborate_init_expr(entity, this);
|
||||
}
|
||||
|
||||
for (list<Architecture::Statement*>::iterator cur = statements_.begin()
|
||||
; cur != statements_.end() ; ++cur) {
|
||||
|
||||
|
|
|
|||
|
|
@ -638,6 +638,7 @@ class ExpString : public Expression {
|
|||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
bool is_primary(void) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
const std::vector<char>& get_value() const { return value_; }
|
||||
|
||||
private:
|
||||
int emit_as_array_(ostream&out, Entity*ent, Architecture*arc, const VTypeArray*arr);
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
ivl_assert(*this, rc);
|
||||
rc = rang.lsb()->evaluate(ent, arc, use_lsb);
|
||||
ivl_assert(*this, rc);
|
||||
ivl_assert(*this, use_msb >= use_lsb);
|
||||
if(use_msb < use_lsb)
|
||||
swap(use_msb, use_lsb);
|
||||
|
||||
map<int64_t,choice_element*> element_map;
|
||||
choice_element*element_other = 0;
|
||||
|
|
@ -244,6 +245,10 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
// Emit the elements as a concatenation. This works great for
|
||||
// vectors of bits. We implement VHDL arrays as packed arrays,
|
||||
// so this should be generally correct.
|
||||
// TODO uncomment this once ivl supports assignments of '{}
|
||||
/*if(!peek_type()->can_be_packed())
|
||||
out << "'";*/
|
||||
|
||||
out << "{";
|
||||
for (int64_t idx = use_msb ; idx >= use_lsb ; idx -= 1) {
|
||||
choice_element*cur = element_map[idx];
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ static char*make_bitstring_bin(int width_prefix, bool sflag, bool,
|
|||
while (*src) {
|
||||
*rp++ = *src++;
|
||||
}
|
||||
*rp = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,11 +343,11 @@ static void import_ieee_use(ActiveScope*res, perm_string package, perm_string na
|
|||
}
|
||||
}
|
||||
|
||||
const VTypePrimitive primitive_BOOLEAN(VTypePrimitive::BOOLEAN);
|
||||
const VTypePrimitive primitive_BIT(VTypePrimitive::BIT);
|
||||
const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER);
|
||||
const VTypePrimitive primitive_BOOLEAN(VTypePrimitive::BOOLEAN, true);
|
||||
const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true);
|
||||
const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER, true);
|
||||
const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC);
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
|
||||
const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER);
|
||||
|
||||
const VTypeRange primitive_NATURAL(&primitive_INTEGER, INT64_MAX, 0);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ int Package::emit_package(ostream&fd) const
|
|||
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
|
||||
; cur != cur_types_.end() ; ++ cur) {
|
||||
fd << "typedef ";
|
||||
errors += cur->second->emit_def(fd);
|
||||
fd << " \\" << cur->first << " ;" << endl;
|
||||
errors += cur->second->emit_def(fd, cur->first);
|
||||
fd << " ;" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,struct const_t*>::const_iterator cur = use_constants_.begin()
|
||||
|
|
|
|||
|
|
@ -684,8 +684,8 @@ composite_type_definition
|
|||
|
||||
/* unbounded_array_definition IEEE 1076-2008 P5.3.2.1 */
|
||||
| K_array '(' index_subtype_definition_list ')' K_of subtype_indication
|
||||
{ sorrymsg(@1, "unbounded_array_definition not supported.\n");
|
||||
std::list<prange_t*> r;
|
||||
{ std::list<prange_t*> r;
|
||||
r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type
|
||||
VTypeArray*tmp = new VTypeArray($6, &r);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,12 @@ 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
|
||||
const VTypeDef*type_def = dynamic_cast<const VTypeDef*> (base_type);
|
||||
if (type_def) {
|
||||
base_type = type_def->peek_definition();
|
||||
}
|
||||
|
||||
const VTypeArray*base_array = dynamic_cast<const VTypeArray*> (base_type);
|
||||
if (base_array) {
|
||||
assert(array_left && array_right);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int Subprogram::emit_package(ostream&fd) const
|
|||
|
||||
if (return_type_) {
|
||||
fd << "function ";
|
||||
return_type_->emit_def(fd);
|
||||
return_type_->emit_def(fd, empty_perm_string);
|
||||
fd << " " << name_;
|
||||
fd << "(";
|
||||
} else {
|
||||
|
|
@ -55,8 +55,7 @@ int Subprogram::emit_package(ostream&fd) const
|
|||
break;
|
||||
}
|
||||
|
||||
errors += curp->type->emit_def(fd);
|
||||
fd << " \\" << curp->name << " ";
|
||||
errors += curp->type->emit_def(fd, curp->name);
|
||||
}
|
||||
|
||||
fd << ");" << endl;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2014 / Maciej Suminski (maciej.suminski@cern.ch)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -33,6 +34,30 @@ SigVarBase::~SigVarBase()
|
|||
{
|
||||
}
|
||||
|
||||
void SigVarBase::elaborate_init_expr(Entity*ent, Architecture*arc)
|
||||
{
|
||||
if(init_expr_) {
|
||||
// convert the initializing string to bitstring if applicable
|
||||
const ExpString*string = dynamic_cast<const ExpString*>(init_expr_);
|
||||
if(string) {
|
||||
const std::vector<char>& val = string->get_value();
|
||||
char buf[val.size() + 1];
|
||||
std::copy(val.begin(), val.end(), buf);
|
||||
buf[val.size()] = 0;
|
||||
|
||||
ExpBitstring*bitstring = new ExpBitstring(buf);
|
||||
delete init_expr_;
|
||||
init_expr_ = bitstring;
|
||||
}
|
||||
else {
|
||||
ExpAggregate*aggr = dynamic_cast<ExpAggregate*>(init_expr_);
|
||||
if(aggr) {
|
||||
aggr->elaborate_expr(ent, arc, peek_type());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SigVarBase::type_elaborate_(VType::decl_t&decl)
|
||||
{
|
||||
decl.type = type_;
|
||||
|
|
@ -44,7 +69,7 @@ int Signal::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
VType::decl_t decl;
|
||||
type_elaborate_(decl);
|
||||
if (peek_refcnt_sequ_() > 0)
|
||||
if (peek_refcnt_sequ_() > 0 || !peek_type()->can_be_packed())
|
||||
decl.reg_flag = true;
|
||||
errors += decl.emit(out, peek_name_());
|
||||
|
||||
|
|
@ -63,7 +88,7 @@ int Variable::emit(ostream&out, Entity*, Architecture*)
|
|||
|
||||
VType::decl_t decl;
|
||||
type_elaborate_(decl);
|
||||
if (peek_refcnt_sequ_() > 0)
|
||||
if (peek_refcnt_sequ_() > 0 || !peek_type()->can_be_packed())
|
||||
decl.reg_flag = true;
|
||||
errors += decl.emit(out, peek_name_());
|
||||
out << ";" << endl;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ class SigVarBase : public LineInfo {
|
|||
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
// Elaborates initializer expressions if needed.
|
||||
void elaborate_init_expr(Entity*ent, Architecture*arc);
|
||||
|
||||
protected:
|
||||
perm_string peek_name_() const { return name_; }
|
||||
unsigned peek_refcnt_sequ_() const { return refcnt_sequ_; }
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ void VType::show(ostream&out) const
|
|||
write_to_stream(out);
|
||||
}
|
||||
|
||||
VTypePrimitive::VTypePrimitive(VTypePrimitive::type_t tt)
|
||||
: type_(tt)
|
||||
VTypePrimitive::VTypePrimitive(VTypePrimitive::type_t tt, bool packed)
|
||||
: type_(tt), packed_(packed)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -60,8 +60,8 @@ void VTypePrimitive::show(ostream&out) const
|
|||
out << "INTEGER";
|
||||
break;
|
||||
case REAL:
|
||||
out << "REAL";
|
||||
break;
|
||||
out << "REAL";
|
||||
break;
|
||||
case STDLOGIC:
|
||||
out << "std_logic";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define IVL_vtype_H
|
||||
/*
|
||||
* Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com),
|
||||
* Copyright CERN 2014 / Stephen Williams (steve@icarus.com),
|
||||
* Maciej Suminski (maciej.suminski@cern.ch)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -74,7 +74,7 @@ class VType {
|
|||
|
||||
// This virtual method emits a definition for the specific
|
||||
// type. It is used to emit typedef's.
|
||||
virtual int emit_def(std::ostream&out) const =0;
|
||||
virtual int emit_def(std::ostream&out, perm_string name) const =0;
|
||||
|
||||
// This virtual method causes VTypeDef types to emit typedefs
|
||||
// of themselves. The VTypeDef implementation of this method
|
||||
|
|
@ -82,6 +82,9 @@ class VType {
|
|||
// all the types that it emits.
|
||||
virtual int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
||||
|
||||
// Determines if a type can be used in Verilog packed array.
|
||||
virtual bool can_be_packed() const { return false; }
|
||||
|
||||
private:
|
||||
friend class decl_t;
|
||||
// This virtual method is called to emit the declaration. This
|
||||
|
|
@ -100,6 +103,12 @@ class VType {
|
|||
bool reg_flag;
|
||||
};
|
||||
|
||||
protected:
|
||||
inline void emit_name(std::ostream&out, perm_string name) const
|
||||
{
|
||||
if(name != empty_perm_string)
|
||||
out << " \\" << name << " ";
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream&operator << (std::ostream&out, const VType&item)
|
||||
|
|
@ -115,7 +124,7 @@ extern void preload_global_types(void);
|
|||
*/
|
||||
class VTypeERROR : public VType {
|
||||
public:
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -128,7 +137,7 @@ class VTypePrimitive : public VType {
|
|||
enum type_t { BOOLEAN, BIT, INTEGER, REAL, STDLOGIC, CHARACTER };
|
||||
|
||||
public:
|
||||
VTypePrimitive(type_t);
|
||||
VTypePrimitive(type_t tt, bool packed = false);
|
||||
~VTypePrimitive();
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
|
|
@ -137,10 +146,13 @@ class VTypePrimitive : public VType {
|
|||
type_t type() const { return type_; }
|
||||
|
||||
int emit_primitive_type(std::ostream&fd) const;
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
bool can_be_packed() const { return packed_; }
|
||||
|
||||
private:
|
||||
type_t type_;
|
||||
bool packed_;
|
||||
};
|
||||
|
||||
extern const VTypePrimitive primitive_BOOLEAN;
|
||||
|
|
@ -191,8 +203,11 @@ class VTypeArray : public VType {
|
|||
|
||||
const VType* element_type() const;
|
||||
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
||||
int emit_dimensions(std::ostream&out) const;
|
||||
|
||||
bool can_be_packed() const { return etype_->can_be_packed(); }
|
||||
|
||||
private:
|
||||
const VType*etype_;
|
||||
|
|
@ -212,7 +227,7 @@ class VTypeRange : public VType {
|
|||
|
||||
public: // Virtual methods
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
private:
|
||||
const VType*base_;
|
||||
|
|
@ -226,7 +241,7 @@ class VTypeEnum : public VType {
|
|||
~VTypeEnum();
|
||||
|
||||
void show(std::ostream&) const;
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
private:
|
||||
std::vector<perm_string>names_;
|
||||
|
|
@ -259,7 +274,9 @@ class VTypeRecord : public VType {
|
|||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
void show(std::ostream&) const;
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
bool can_be_packed() const { return true; }
|
||||
|
||||
const element_t* element_by_name(perm_string name) const;
|
||||
|
||||
|
|
@ -288,7 +305,9 @@ class VTypeDef : public VType {
|
|||
void write_type_to_stream(ostream&fd) const;
|
||||
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
||||
|
||||
int emit_def(std::ostream&out) const;
|
||||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
bool can_be_packed() const { return type_->can_be_packed(); }
|
||||
private:
|
||||
int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ int VType::decl_t::emit(ostream&out, perm_string name) const
|
|||
return type->emit_decl(out, name, reg_flag);
|
||||
}
|
||||
|
||||
|
||||
int VType::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
@ -41,9 +40,8 @@ int VType::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
|||
if (!reg_flag)
|
||||
out << "wire ";
|
||||
|
||||
errors += emit_def(out);
|
||||
|
||||
out << " \\" << name << " ";
|
||||
errors += emit_def(out, name);
|
||||
out << " ";
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -52,53 +50,40 @@ int VType::emit_typedef(std::ostream&, typedef_context_t&) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
int VTypeERROR::emit_def(ostream&out) const
|
||||
int VTypeERROR::emit_def(ostream&out, perm_string) const
|
||||
{
|
||||
out << "/* ERROR */";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int VTypeArray::emit_def(ostream&out) const
|
||||
int VTypeArray::emit_def(ostream&out, perm_string name) const
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
list<const VTypeArray*> dims;
|
||||
const VTypeArray*cur = this;
|
||||
while (const VTypeArray*sub = dynamic_cast<const VTypeArray*> (cur->etype_)) {
|
||||
dims.push_back(cur);
|
||||
cur = sub;
|
||||
}
|
||||
|
||||
const VType*raw_base = cur->etype_;
|
||||
|
||||
const VTypePrimitive*base = dynamic_cast<const VTypePrimitive*> (raw_base);
|
||||
|
||||
if (base) {
|
||||
assert(dimensions() == 1);
|
||||
|
||||
base->emit_def(out);
|
||||
base->emit_def(out, empty_perm_string);
|
||||
if (signed_flag_)
|
||||
out << " signed";
|
||||
} else {
|
||||
raw_base->emit_def(out);
|
||||
raw_base->emit_def(out, empty_perm_string);
|
||||
}
|
||||
|
||||
dims.push_back(cur);
|
||||
|
||||
while (! dims.empty()) {
|
||||
cur = dims.front();
|
||||
dims.pop_front();
|
||||
out << "[";
|
||||
if (cur->dimension(0).msb())
|
||||
errors += cur->dimension(0).msb()->emit(out, 0, 0);
|
||||
else
|
||||
out << "?error?";
|
||||
out << ":";
|
||||
if (cur->dimension(0).lsb())
|
||||
errors += cur->dimension(0).lsb()->emit(out, 0, 0);
|
||||
else
|
||||
out << "?error?";
|
||||
out << "]";
|
||||
if(raw_base->can_be_packed()) {
|
||||
errors += emit_dimensions(out);
|
||||
emit_name(out, name);
|
||||
} else {
|
||||
emit_name(out, name);
|
||||
errors += emit_dimensions(out);
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
|
@ -109,7 +94,36 @@ int VTypeArray::emit_typedef(std::ostream&out, typedef_context_t&ctx) const
|
|||
return etype_->emit_typedef(out, ctx);
|
||||
}
|
||||
|
||||
int VTypeEnum::emit_def(ostream&out) const
|
||||
int VTypeArray::emit_dimensions(std::ostream&out) const
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
list<const VTypeArray*> dims;
|
||||
const VTypeArray*cur = this;
|
||||
while (const VTypeArray*sub = dynamic_cast<const VTypeArray*> (cur->etype_)) {
|
||||
dims.push_back(cur);
|
||||
cur = sub;
|
||||
}
|
||||
dims.push_back(cur);
|
||||
|
||||
while (! dims.empty()) {
|
||||
cur = dims.front();
|
||||
dims.pop_front();
|
||||
|
||||
out << "[";
|
||||
if (cur->dimension(0).msb() && cur->dimension(0).lsb()) {
|
||||
// bounded array, unbounded arrays have msb() & lsb() nullified
|
||||
errors += cur->dimension(0).msb()->emit(out, 0, 0);
|
||||
out << ":";
|
||||
errors += cur->dimension(0).lsb()->emit(out, 0, 0);
|
||||
}
|
||||
out << "]";
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int VTypeEnum::emit_def(ostream&out, perm_string name) const
|
||||
{
|
||||
int errors = 0;
|
||||
out << "enum {";
|
||||
|
|
@ -119,6 +133,7 @@ int VTypeEnum::emit_def(ostream&out) const
|
|||
out << ", \\" << names_[idx] << " ";
|
||||
|
||||
out << "}";
|
||||
emit_name(out, name);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
|
@ -135,11 +150,11 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
|
|||
out << "logic";
|
||||
break;
|
||||
case INTEGER:
|
||||
out << "bool [31:0]";
|
||||
out << "bool[31:0]";
|
||||
break;
|
||||
case REAL:
|
||||
out << "real";
|
||||
break;
|
||||
case REAL:
|
||||
out << "real";
|
||||
break;
|
||||
case CHARACTER:
|
||||
out << "char";
|
||||
break;
|
||||
|
|
@ -150,22 +165,23 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
|
|||
return errors;
|
||||
}
|
||||
|
||||
int VTypePrimitive::emit_def(ostream&out) const
|
||||
int VTypePrimitive::emit_def(ostream&out, perm_string name) const
|
||||
{
|
||||
int errors = 0;
|
||||
errors += emit_primitive_type(out);
|
||||
emit_name(out, name);
|
||||
return errors;
|
||||
}
|
||||
|
||||
int VTypeRange::emit_def(ostream&out) const
|
||||
int VTypeRange::emit_def(ostream&out, perm_string name) const
|
||||
{
|
||||
int errors = 0;
|
||||
out << "/* Internal error: Don't know how to emit range */";
|
||||
errors += base_->emit_def(out);
|
||||
errors += base_->emit_def(out, name);
|
||||
return errors;
|
||||
}
|
||||
|
||||
int VTypeRecord::emit_def(ostream&out) const
|
||||
int VTypeRecord::emit_def(ostream&out, perm_string name) const
|
||||
{
|
||||
int errors = 0;
|
||||
out << "struct packed {";
|
||||
|
|
@ -174,11 +190,12 @@ int VTypeRecord::emit_def(ostream&out) const
|
|||
; cur != elements_.end() ; ++cur) {
|
||||
perm_string element_name = (*cur)->peek_name();
|
||||
const VType*element_type = (*cur)->peek_type();
|
||||
element_type->emit_def(out);
|
||||
element_type->emit_def(out, empty_perm_string);
|
||||
out << " \\" << element_name << " ; ";
|
||||
}
|
||||
|
||||
out << "}";
|
||||
emit_name(out, name);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -187,10 +204,10 @@ int VTypeRecord::emit_def(ostream&out) const
|
|||
* type. (We are defining a variable here, not the type itself.) The
|
||||
* emit_typedef() method was presumably called to define type already.
|
||||
*/
|
||||
int VTypeDef::emit_def(ostream&out) const
|
||||
int VTypeDef::emit_def(ostream&out, perm_string) const
|
||||
{
|
||||
int errors = 0;
|
||||
out << "\\" << name_ << " ";
|
||||
emit_name(out, name_);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -202,8 +219,7 @@ int VTypeDef::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
|||
else
|
||||
out << "wire ";
|
||||
|
||||
errors += type_->emit_def(out);
|
||||
out << " \\" << name << " ";
|
||||
errors += type_->emit_def(out, name);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -229,8 +245,14 @@ int VTypeDef::emit_typedef(ostream&out, typedef_context_t&ctx) const
|
|||
int errors = type_->emit_typedef(out, ctx);
|
||||
flag = MARKED;
|
||||
|
||||
// Array types are used directly anyway and typedefs for unpacked
|
||||
// arrays do not work currently
|
||||
if(dynamic_cast<const VTypeArray*>(type_))
|
||||
out << "// ";
|
||||
|
||||
out << "typedef ";
|
||||
errors += type_->emit_def(out);
|
||||
out << " \\" << name_ << " ;" << endl;
|
||||
errors += type_->emit_def(out, name_);
|
||||
out << " ;" << endl;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue