From 76aab15798b85612d449e26a4388efa16baf0c55 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 9 Oct 2014 16:52:35 +0200 Subject: [PATCH 1/6] vhdlpp: Minor code cleaning. --- vhdlpp/expression_elaborate.cc | 5 +---- vhdlpp/expression_emit.cc | 10 ---------- vhdlpp/vtype_stream.cc | 3 +++ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index dcea7f470..174d97de6 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -879,11 +879,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..4b1a41a06 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': 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; From 95faed8e9d38f22952bff5e625ac4f12edb85764 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 9 Oct 2014 17:08:35 +0200 Subject: [PATCH 2/6] vhdlpp: Added basic support for concatenated expressions. --- vhdlpp/expression.h | 1 + vhdlpp/expression_elaborate.cc | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) 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 174d97de6..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. */ From 97df6183a9e75f9207914d9607fc5a3ab236549a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 10 Oct 2014 16:08:23 +0200 Subject: [PATCH 3/6] vhdlpp: Emit '-' std_logic value as 'x'. Note: It is not a direct ("don't care" vs "unknown"), but I could not find anything that suits better. --- vhdlpp/expression_emit.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 4b1a41a06..af62d8dd6 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -821,6 +821,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] From 4a779f43bdb1c665991f194922cd997058120fb9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 14 Oct 2014 10:58:01 +0200 Subject: [PATCH 4/6] vhdlpp: Fix error message for 'right attribute. --- vhdlpp/expression_evaluate.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; } From dfbca0b1862d5d9bae2267c0382568177b514257 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 15 Oct 2014 11:13:04 +0200 Subject: [PATCH 5/6] vhdlpp: Emit use_types in Architecture. --- vhdlpp/architec_emit.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) 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() From c55a0131625b0a6dc6a8c94dbfb1e2b190a51702 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 17 Oct 2014 14:53:59 +0200 Subject: [PATCH 6/6] vhdlpp: Support for integer() function. Note: I could not find any info about the integer() function, but it is used in the VHDL standard packages (e.g. math_real, see: http://www.csee.umbc.edu/portal/help/VHDL/packages/mathpack.vhd) Real numbers are rounded, this is compatible with ModelSim behavior. --- vhdlpp/expression_emit.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index af62d8dd6..2c1e510e5 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -561,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