Merge pull request #47 from orsonmmz/concat

Expression concatenation in VHDL
This commit is contained in:
Stephen Williams 2014-10-18 15:13:50 -07:00
commit d139142c29
6 changed files with 57 additions and 21 deletions

View File

@ -70,14 +70,17 @@ int Architecture::emit(ostream&out, Entity*entity)
// of the full definition.
typedef_context_t typedef_ctx;
for (map<perm_string,const VType*>::iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(out, typedef_ctx);
}
for (map<perm_string,const VType*>::iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {
const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second);
if (def == 0)
continue;
errors += def->emit_typedef(out, typedef_ctx);
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(out, typedef_ctx);
}
for (map<perm_string,struct const_t*>::iterator cur = use_constants_.begin()

View File

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

View File

@ -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<const VTypeArray*>(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<prange_t*> 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;
}

View File

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

View File

@ -122,8 +122,8 @@ bool ExpAttribute::evaluate(Entity*ent, Architecture*arc, int64_t&val) const
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(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;
}

View File

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