Merge pull request #47 from orsonmmz/concat
Expression concatenation in VHDL
This commit is contained in:
commit
d139142c29
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue