diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index b6f47fc91..ef17e370a 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -70,14 +70,17 @@ int Architecture::emit(ostream&out, Entity*entity) // of the full definition. typedef_context_t typedef_ctx; + for (map::iterator cur = use_types_.begin() + ; cur != use_types_.end() ; ++cur) { + + if(const VTypeDef*def = dynamic_cast(cur->second)) + errors += def->emit_typedef(out, typedef_ctx); + } for (map::iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { - const VTypeDef*def = dynamic_cast(cur->second); - if (def == 0) - continue; - - errors += def->emit_typedef(out, typedef_ctx); + if(const VTypeDef*def = dynamic_cast(cur->second)) + errors += def->emit_typedef(out, typedef_ctx); } for (map::iterator cur = use_constants_.begin() diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index df1b9bf81..b791f9a21 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -388,6 +388,7 @@ class ExpConcat : public Expression { ~ExpConcat(); const VType*probe_type(Entity*ent, Architecture*arc) const; + const VType*fit_type(Entity*ent, Architecture*arc, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); void write_to_stream(std::ostream&fd); int emit(ostream&out, Entity*ent, Architecture*arc); diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index dcea7f470..b07ff6994 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -609,6 +609,39 @@ int ExpCharacter::elaborate_expr(Entity*, Architecture*, const VType*ltype) return 0; } +const VType*ExpConcat::fit_type(Entity*ent, Architecture*arc, const VTypeArray*atype) const +{ + Expression*operands[2] = {operand1_, operand2_}; + const VType*types[2] = {NULL, NULL}; + Expression*sizes[2] = {NULL, NULL}; + + // determine the type and size of concatenated expressions + for(int i = 0; i < 2; ++i) { + types[i] = operands[i]->fit_type(ent, arc, atype); + + if(const VTypeArray*arr = dynamic_cast(types[i])) { + types[i] = arr->element_type(); + ivl_assert(*this, arr->dimensions() == 1); + const VTypeArray::range_t&dim = arr->dimension(0); + sizes[i] = new ExpArithmetic(ExpArithmetic::MINUS, dim.msb(), dim.lsb()); + } else { + sizes[i] = new ExpInteger(0); + } + } + + // the range of the concatenated expression is (size1 + size2 + 1):0 + // note that each of the sizes are already decreased by one, + // e.g. 3:0 <=> size == 3 even though there are 4 bits + Expression*size = new ExpArithmetic(ExpArithmetic::PLUS, + new ExpArithmetic(ExpArithmetic::PLUS, sizes[0], sizes[1]), + new ExpInteger(1)); + + std::list ranges; + ranges.push_front(new prange_t(size, new ExpInteger(0), true)); + const VType*array = new VTypeArray(types[1], &ranges); + + return array; +} /* * I don't know how to probe the type of a concatenation, quite yet. */ @@ -879,11 +912,8 @@ const VType* ExpNameALL::probe_type(Entity*, Architecture*) const return 0; } -const VType* ExpRelation::probe_type(Entity*ent, Architecture*arc) const +const VType* ExpRelation::probe_type(Entity*, Architecture*) const { - /* const VType*type1 = */ peek_operand1()->probe_type(ent, arc); - /* const VType*type2 = */ peek_operand2()->probe_type(ent, arc); - return &primitive_BOOLEAN; } diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index a84122c02..2c1e510e5 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -391,16 +391,6 @@ int ExpCharacter::emit_primitive_bit_(ostream&out, Entity*, Architecture*, switch (etype->type()) { case VTypePrimitive::BOOLEAN: case VTypePrimitive::BIT: - switch (value_) { - case '0': - case '1': - out << "1'b" << value_; - return 0; - default: - break; - } - break; - case VTypePrimitive::STDLOGIC: switch (value_) { case '0': @@ -571,6 +561,11 @@ int ExpFunc::emit(ostream&out, Entity*ent, Architecture*arc) errors += argv_[0]->emit(out, ent, arc); out << ")"; + } else if (name_ == "integer" && argv_.size() == 1) { + // Simply skip the function name, SystemVerilog takes care of + // rounding real numbers + errors += argv_[0]->emit(out, ent, arc); + } else if (name_ == "std_logic_vector" && argv_.size() == 1) { // Special case: The std_logic_vector function casts its // argument to std_logic_vector. Internally, we don't @@ -831,6 +826,10 @@ int ExpString::emit_as_array_(ostream& out, Entity*, Architecture*, const VTypeA assert(etype->type() == VTypePrimitive::STDLOGIC); out << "z"; break; + case '-': + assert(etype->type() == VTypePrimitive::STDLOGIC); + out << "x"; + break; default: cerr << get_fileline() << ": internal error: " << "Don't know how to handle bit " << value_[idx] diff --git a/vhdlpp/expression_evaluate.cc b/vhdlpp/expression_evaluate.cc index 0bdb8bded..2f506eb28 100644 --- a/vhdlpp/expression_evaluate.cc +++ b/vhdlpp/expression_evaluate.cc @@ -122,8 +122,8 @@ bool ExpAttribute::evaluate(Entity*ent, Architecture*arc, int64_t&val) const const VTypeArray*arr = dynamic_cast(base_type); if (arr == 0) { cerr << get_fileline() << ": error: " - << "Cannot apply the 'left attribute to non-array objects" - << endl; + << "Cannot apply the '" << name_ + << " attribute to non-array objects" << endl; return false; } diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index b66428626..3e4572049 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -146,6 +146,9 @@ void VTypePrimitive::write_to_stream(ostream&fd) const case STDLOGIC: fd << "std_logic"; break; + case CHARACTER: + fd << "character"; + break; case BOOLEAN: fd << "boolean"; break;