commit
301e85a8ca
|
|
@ -152,22 +152,9 @@ int CondSignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
out << "// " << get_fileline() << endl;
|
out << "// " << get_fileline() << endl;
|
||||||
out << "always @(";
|
out << "always begin" << endl;
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for(list<const ExpName*>::const_iterator it = sens_list_.begin();
|
|
||||||
it != sens_list_.end(); ++it) {
|
|
||||||
if(first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
out << ",";
|
|
||||||
|
|
||||||
errors += (*it)->emit(out, ent, arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
out << ") begin" << endl;
|
|
||||||
|
|
||||||
first = true;
|
|
||||||
for(list<ExpConditional::case_t*>::iterator it = options_.begin();
|
for(list<ExpConditional::case_t*>::iterator it = options_.begin();
|
||||||
it != options_.end(); ++it) {
|
it != options_.end(); ++it) {
|
||||||
ExpConditional::case_t*cas = *it;
|
ExpConditional::case_t*cas = *it;
|
||||||
|
|
@ -192,6 +179,21 @@ int CondSignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
out << ";" << endl;
|
out << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sensitivity list
|
||||||
|
first = true;
|
||||||
|
out << "@(";
|
||||||
|
|
||||||
|
for(list<const ExpName*>::const_iterator it = sens_list_.begin();
|
||||||
|
it != sens_list_.end(); ++it) {
|
||||||
|
if(first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
out << ",";
|
||||||
|
|
||||||
|
errors += (*it)->emit(out, ent, arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
out << ");" << endl;
|
||||||
out << "end" << endl;
|
out << "end" << endl;
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
|
|
|
||||||
|
|
@ -436,29 +436,6 @@ void ExpRelation::dump(ostream&out, int indent) const
|
||||||
dump_operands(out, indent+4);
|
dump_operands(out, indent+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpString::dump(ostream&out, int indent) const
|
|
||||||
{
|
|
||||||
out << setw(indent) << "" << "String \"" << value_;
|
|
||||||
out << "\"" << " at " << get_fileline() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpUAbs::dump(ostream&out, int indent) const
|
|
||||||
{
|
|
||||||
out << setw(indent) << "" << "abs() at " << get_fileline() << endl;
|
|
||||||
dump_operand1(out, indent+4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpUnary::dump_operand1(ostream&out, int indent) const
|
|
||||||
{
|
|
||||||
operand1_->dump(out, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpUNot::dump(ostream&out, int indent) const
|
|
||||||
{
|
|
||||||
out << setw(indent) << "" << "not() at " << get_fileline() << endl;
|
|
||||||
dump_operand1(out, indent+4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void named_expr_t::dump(ostream&out, int indent) const
|
void named_expr_t::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << name_ << "=>";
|
out << setw(indent) << "" << name_ << "=>";
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
# include "subprogram.h"
|
# include "subprogram.h"
|
||||||
# include "parse_types.h"
|
# include "parse_types.h"
|
||||||
# include "scope.h"
|
# include "scope.h"
|
||||||
|
# include "library.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
|
|
@ -569,6 +570,32 @@ const VType* ExpFunc::func_ret_type() const
|
||||||
return def_ ? def_->peek_return_type() : NULL;
|
return def_ ? def_->peek_return_type() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubprogramHeader*ExpFunc::match_signature(Entity*ent, ScopeBase*scope) const
|
||||||
|
{
|
||||||
|
SubprogramHeader*prog = NULL;
|
||||||
|
list<const VType*> arg_types;
|
||||||
|
|
||||||
|
// Create a list of argument types to find a matching subprogram
|
||||||
|
for(vector<Expression*>::const_iterator it = argv_.begin();
|
||||||
|
it != argv_.end(); ++it) {
|
||||||
|
arg_types.push_back((*it)->probe_type(ent, scope));
|
||||||
|
}
|
||||||
|
|
||||||
|
prog = scope->match_subprogram(name_, &arg_types);
|
||||||
|
|
||||||
|
if(!prog)
|
||||||
|
prog = library_match_subprogram(name_, &arg_types);
|
||||||
|
|
||||||
|
if(!prog) {
|
||||||
|
cerr << get_fileline() << ": sorry: could not find function ";
|
||||||
|
emit_subprogram_sig(cerr, name_, arg_types);
|
||||||
|
cerr << endl;
|
||||||
|
ivl_assert(*this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
ExpInteger::ExpInteger(int64_t val)
|
ExpInteger::ExpInteger(int64_t val)
|
||||||
: value_(val)
|
: value_(val)
|
||||||
{
|
{
|
||||||
|
|
@ -818,6 +845,15 @@ ExpUNot::~ExpUNot()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpUMinus::ExpUMinus(Expression*op1)
|
||||||
|
: ExpUnary(op1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpUMinus::~ExpUMinus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ExpCast::ExpCast(Expression*base, const VType*type) :
|
ExpCast::ExpCast(Expression*base, const VType*type) :
|
||||||
base_(base), type_(type)
|
base_(base), type_(type)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -620,12 +620,15 @@ class ExpFunc : public Expression {
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
|
int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
|
||||||
void dump(ostream&out, int indent = 0) const;
|
void dump(ostream&out, int indent = 0) const;
|
||||||
void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram
|
void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram body
|
||||||
|
|
||||||
|
// Returns a subprogram header that matches the function call
|
||||||
|
SubprogramHeader*match_signature(Entity*ent, ScopeBase*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
std::vector<Expression*> argv_;
|
std::vector<Expression*> argv_;
|
||||||
SubprogramHeader*def_;
|
mutable SubprogramHeader*def_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExpInteger : public Expression {
|
class ExpInteger : public Expression {
|
||||||
|
|
@ -948,6 +951,19 @@ class ExpUNot : public ExpUnary {
|
||||||
void dump(ostream&out, int indent = 0) const;
|
void dump(ostream&out, int indent = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ExpUMinus : public ExpUnary {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ExpUMinus(Expression*op1);
|
||||||
|
~ExpUMinus();
|
||||||
|
|
||||||
|
Expression*clone() const { return new ExpUMinus(peek_operand()->clone()); }
|
||||||
|
|
||||||
|
void write_to_stream(std::ostream&fd) const;
|
||||||
|
int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
|
||||||
|
void dump(ostream&out, int indent = 0) const;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class that wraps other expressions to cast them to other types.
|
* Class that wraps other expressions to cast them to other types.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,35 @@ void ExpShift::dump(ostream&out, int indent) const
|
||||||
dump_operands(out, indent+4);
|
dump_operands(out, indent+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpString::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "String \"" << value_;
|
||||||
|
out << "\"" << " at " << get_fileline() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpUAbs::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "abs() at " << get_fileline() << endl;
|
||||||
|
dump_operand1(out, indent+4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpUnary::dump_operand1(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
operand1_->dump(out, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpUNot::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "not() at " << get_fileline() << endl;
|
||||||
|
dump_operand1(out, indent+4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpUMinus::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "unary_minus() at " << get_fileline() << endl;
|
||||||
|
dump_operand1(out, indent+4);
|
||||||
|
}
|
||||||
|
|
||||||
void ExpTime::dump(ostream&out, int indent) const
|
void ExpTime::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "Time ";
|
out << setw(indent) << "" << "Time ";
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
# include "entity.h"
|
# include "entity.h"
|
||||||
# include "vsignal.h"
|
# include "vsignal.h"
|
||||||
# include "subprogram.h"
|
# include "subprogram.h"
|
||||||
# include "library.h"
|
|
||||||
# include "std_types.h"
|
# include "std_types.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
|
|
@ -74,13 +73,12 @@ const VType*ExpName::elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*sco
|
||||||
// If the name is an array, then a part select is
|
// If the name is an array, then a part select is
|
||||||
// also an array, but with different bounds.
|
// also an array, but with different bounds.
|
||||||
int64_t use_msb, use_lsb;
|
int64_t use_msb, use_lsb;
|
||||||
bool flag;
|
bool flag = true;
|
||||||
|
|
||||||
flag = range->msb()->evaluate(ent, scope, use_msb);
|
flag &= range->msb()->evaluate(ent, scope, use_msb);
|
||||||
ivl_assert(*this, flag);
|
flag &= range->lsb()->evaluate(ent, scope, use_lsb);
|
||||||
flag = range->lsb()->evaluate(ent, scope, use_lsb);
|
|
||||||
ivl_assert(*this, flag);
|
|
||||||
|
|
||||||
|
if(flag)
|
||||||
type = new VTypeArray(array->element_type(), use_msb, use_lsb);
|
type = new VTypeArray(array->element_type(), use_msb, use_lsb);
|
||||||
}
|
}
|
||||||
else if(idx) {
|
else if(idx) {
|
||||||
|
|
@ -419,7 +417,7 @@ const VType*ExpAggregate::fit_type(Entity*, ScopeBase*, const VTypeArray*host) c
|
||||||
Expression*use_msb = prange->msb();
|
Expression*use_msb = prange->msb();
|
||||||
Expression*use_lsb = prange->lsb();
|
Expression*use_lsb = prange->lsb();
|
||||||
|
|
||||||
ivl_assert(*this, host->dimensions() == 1);
|
ivl_assert(*this, host->dimensions().size() == 1);
|
||||||
vector<VTypeArray::range_t> range (1);
|
vector<VTypeArray::range_t> range (1);
|
||||||
|
|
||||||
range[0] = VTypeArray::range_t(use_msb, use_lsb);
|
range[0] = VTypeArray::range_t(use_msb, use_lsb);
|
||||||
|
|
@ -580,6 +578,7 @@ int ExpArithmetic::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype
|
||||||
|
|
||||||
const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const
|
const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const
|
||||||
{
|
{
|
||||||
|
// Ranges
|
||||||
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t1))
|
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t1))
|
||||||
t1 = tmp->base_type();
|
t1 = tmp->base_type();
|
||||||
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t2))
|
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t2))
|
||||||
|
|
@ -588,6 +587,57 @@ const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t
|
||||||
if (t1->type_match(t2))
|
if (t1->type_match(t2))
|
||||||
return t1;
|
return t1;
|
||||||
|
|
||||||
|
// Signed & unsigned (resized to the widest argument)
|
||||||
|
const VTypeArray*t1_arr = dynamic_cast<const VTypeArray*>(t1);
|
||||||
|
const VTypeArray*t2_arr = dynamic_cast<const VTypeArray*>(t2);
|
||||||
|
|
||||||
|
if(t1_arr && t2_arr) {
|
||||||
|
const VTypeArray*t1_parent = t1_arr->get_parent_type();
|
||||||
|
const VTypeArray*t2_parent = t2_arr->get_parent_type();
|
||||||
|
|
||||||
|
if(t1_parent == t2_parent
|
||||||
|
&& (t1_parent == &primitive_SIGNED || t1_parent == &primitive_UNSIGNED)) {
|
||||||
|
int t1_size = t1_arr->get_width(NULL);
|
||||||
|
int t2_size = t2_arr->get_width(NULL);
|
||||||
|
|
||||||
|
// Easy, the same sizes, so we do not need to resize
|
||||||
|
if(t1_size == t2_size && t1_size > 0)
|
||||||
|
return t1; // == t2
|
||||||
|
|
||||||
|
VTypeArray*resolved = new VTypeArray(t1_parent->element_type(),
|
||||||
|
std::max(t1_size, t2_size) - 1, 0, t1_parent->signed_vector());
|
||||||
|
resolved->set_parent_type(t1_parent);
|
||||||
|
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(t1_arr) {
|
||||||
|
if(const VTypePrimitive*prim = dynamic_cast<const VTypePrimitive*>(t2)) {
|
||||||
|
const VTypeArray*t1_parent = t1_arr->get_parent_type();
|
||||||
|
VTypePrimitive::type_t t2_type = prim->type();
|
||||||
|
|
||||||
|
if((t2_type == VTypePrimitive::NATURAL || t2_type == VTypePrimitive::INTEGER)
|
||||||
|
&& t1_parent == &primitive_SIGNED)
|
||||||
|
return t1;
|
||||||
|
|
||||||
|
if((t2_type == VTypePrimitive::NATURAL) && t1_parent == &primitive_UNSIGNED)
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(t2_arr) {
|
||||||
|
if(const VTypePrimitive*prim = dynamic_cast<const VTypePrimitive*>(t1)) {
|
||||||
|
const VTypeArray*t2_parent = t2_arr->get_parent_type();
|
||||||
|
VTypePrimitive::type_t t1_type = prim->type();
|
||||||
|
|
||||||
|
if((t1_type == VTypePrimitive::NATURAL || t1_type == VTypePrimitive::INTEGER)
|
||||||
|
&& t2_parent == &primitive_SIGNED)
|
||||||
|
return t2;
|
||||||
|
|
||||||
|
if((t1_type == VTypePrimitive::NATURAL) && t2_parent == &primitive_UNSIGNED)
|
||||||
|
return t2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,7 +728,7 @@ const VType*ExpConcat::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*at
|
||||||
|
|
||||||
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(types[i])) {
|
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(types[i])) {
|
||||||
types[i] = arr->element_type();
|
types[i] = arr->element_type();
|
||||||
ivl_assert(*this, arr->dimensions() == 1);
|
ivl_assert(*this, arr->dimensions().size() == 1);
|
||||||
const VTypeArray::range_t&dim = arr->dimension(0);
|
const VTypeArray::range_t&dim = arr->dimension(0);
|
||||||
sizes[i] = new ExpArithmetic(ExpArithmetic::MINUS, dim.msb(), dim.lsb());
|
sizes[i] = new ExpArithmetic(ExpArithmetic::MINUS, dim.msb(), dim.lsb());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -733,7 +783,7 @@ int ExpConcat::elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArr
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
// For now, only support single-dimension arrays here.
|
// For now, only support single-dimension arrays here.
|
||||||
ivl_assert(*this, atype->dimensions() == 1);
|
ivl_assert(*this, atype->dimensions().size() == 1);
|
||||||
|
|
||||||
const VType*type1 = operand1_->fit_type(ent, scope, atype);
|
const VType*type1 = operand1_->fit_type(ent, scope, atype);
|
||||||
ivl_assert(*this, type1);
|
ivl_assert(*this, type1);
|
||||||
|
|
@ -791,55 +841,23 @@ int ExpConditional::case_t::elaborate_expr(Entity*ent, ScopeBase*scope, const VT
|
||||||
|
|
||||||
const VType*ExpFunc::probe_type(Entity*ent, ScopeBase*scope) const
|
const VType*ExpFunc::probe_type(Entity*ent, ScopeBase*scope) const
|
||||||
{
|
{
|
||||||
SubprogramHeader*prog = def_;
|
if(!def_)
|
||||||
|
def_ = match_signature(ent, scope);
|
||||||
|
|
||||||
if(!prog) {
|
return def_ ? def_->exact_return_type(argv_, ent, scope) : NULL;
|
||||||
list<const VType*> arg_types;
|
|
||||||
|
|
||||||
for(vector<Expression*>::const_iterator it = argv_.begin();
|
|
||||||
it != argv_.end(); ++it) {
|
|
||||||
arg_types.push_back((*it)->probe_type(ent, scope));
|
|
||||||
}
|
|
||||||
|
|
||||||
prog = scope->match_subprogram(name_, &arg_types);
|
|
||||||
|
|
||||||
if(!prog)
|
|
||||||
prog = library_match_subprogram(name_, &arg_types);
|
|
||||||
|
|
||||||
if(!prog) {
|
|
||||||
cerr << get_fileline() << ": sorry: could not find function ";
|
|
||||||
emit_subprogram_sig(cerr, name_, arg_types);
|
|
||||||
cerr << endl;
|
|
||||||
ivl_assert(*this, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return prog->peek_return_type();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
|
int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
ivl_assert(*this, def_ == 0); // do not elaborate twice
|
if(def_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Create a list of argument types to find a matching subprogram
|
def_ = match_signature(ent, scope);
|
||||||
list<const VType*> arg_types;
|
|
||||||
for(vector<Expression*>::iterator it = argv_.begin();
|
|
||||||
it != argv_.end(); ++it)
|
|
||||||
arg_types.push_back((*it)->probe_type(ent, scope));
|
|
||||||
|
|
||||||
def_ = scope->match_subprogram(name_, &arg_types);
|
|
||||||
|
|
||||||
if(!def_)
|
if(!def_)
|
||||||
def_ = library_match_subprogram(name_, &arg_types);
|
|
||||||
|
|
||||||
if(!def_) {
|
|
||||||
cerr << get_fileline() << ": error: could not find function ";
|
|
||||||
emit_subprogram_sig(cerr, name_, arg_types);
|
|
||||||
cerr << endl;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
// Elaborate arguments
|
// Elaborate arguments
|
||||||
for (size_t idx = 0; idx < argv_.size(); ++idx) {
|
for (size_t idx = 0; idx < argv_.size(); ++idx) {
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VT
|
||||||
|
|
||||||
// Special case: The aggregate is a single "others" item.
|
// Special case: The aggregate is a single "others" item.
|
||||||
if (aggregate_.size() == 1 && aggregate_[0].choice->others()) {
|
if (aggregate_.size() == 1 && aggregate_[0].choice->others()) {
|
||||||
assert(atype->dimensions() == 1);
|
assert(atype->dimensions().size() == 1);
|
||||||
|
|
||||||
const VTypeArray::range_t&rang = atype->dimension(0);
|
const VTypeArray::range_t&rang = atype->dimension(0);
|
||||||
assert(! rang.is_box());
|
assert(! rang.is_box());
|
||||||
|
|
@ -978,7 +978,7 @@ int ExpString::emit(ostream& out, Entity*ent, ScopeBase*scope) const
|
||||||
int ExpString::emit_as_array_(ostream& out, Entity*, ScopeBase*, const VTypeArray*arr) const
|
int ExpString::emit_as_array_(ostream& out, Entity*, ScopeBase*, const VTypeArray*arr) const
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
assert(arr->dimensions() == 1);
|
assert(arr->dimensions().size() == 1);
|
||||||
|
|
||||||
const VTypePrimitive*etype = dynamic_cast<const VTypePrimitive*> (arr->basic_type());
|
const VTypePrimitive*etype = dynamic_cast<const VTypePrimitive*> (arr->basic_type());
|
||||||
assert(etype);
|
assert(etype);
|
||||||
|
|
@ -1048,6 +1048,15 @@ int ExpUNot::emit(ostream&out, Entity*ent, ScopeBase*scope) const
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ExpUMinus::emit(ostream&out, Entity*ent, ScopeBase*scope) const
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
out << "-(";
|
||||||
|
errors += emit_operand1(out, ent, scope);
|
||||||
|
out << ")";
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int ExpCast::emit(ostream&out, Entity*ent, ScopeBase*scope) const
|
int ExpCast::emit(ostream&out, Entity*ent, ScopeBase*scope) const
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ bool ExpAttribute::test_array_type(const VType*type) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arr->dimensions() > 1) {
|
if (arr->dimensions().size() > 1) {
|
||||||
cerr << endl << get_fileline() << ": error: "
|
cerr << endl << get_fileline() << ": error: "
|
||||||
<< "Cannot apply the '" << name_
|
<< "Cannot apply the '" << name_
|
||||||
<< " attribute to multidimensional arrays" << endl;
|
<< " attribute to multidimensional arrays" << endl;
|
||||||
|
|
@ -144,19 +144,6 @@ bool ExpName::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent) {
|
|
||||||
const InterfacePort*gen = ent->find_generic(name_);
|
|
||||||
if (gen) {
|
|
||||||
// Evaluate the default expression and use that.
|
|
||||||
if (gen->expr && gen->expr->evaluate(ent, scope, val))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
cerr << get_fileline() << ": sorry: I could not evaluate "
|
|
||||||
<< "generic override." << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope) {
|
if (scope) {
|
||||||
const VType*type;
|
const VType*type;
|
||||||
Expression*exp;
|
Expression*exp;
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,13 @@ void ExpUNot::write_to_stream(ostream&fd) const
|
||||||
write_to_stream_operand1(fd);
|
write_to_stream_operand1(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpUMinus::write_to_stream(ostream&fd) const
|
||||||
|
{
|
||||||
|
fd << "-(";
|
||||||
|
write_to_stream_operand1(fd);
|
||||||
|
fd << ")";
|
||||||
|
}
|
||||||
|
|
||||||
void ExpCast::write_to_stream(ostream&fd) const
|
void ExpCast::write_to_stream(ostream&fd) const
|
||||||
{
|
{
|
||||||
// Type casting is introduced only for a few specific cases in
|
// Type casting is introduced only for a few specific cases in
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include "package.h"
|
# include "package.h"
|
||||||
# include "std_types.h"
|
# include "std_types.h"
|
||||||
|
# include "std_funcs.h"
|
||||||
# include <fstream>
|
# include <fstream>
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
|
|
@ -110,7 +111,7 @@ static string make_library_package_path(perm_string lib_name, perm_string name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_ieee(void);
|
static void import_ieee(void);
|
||||||
static void import_ieee_use(ActiveScope*res, perm_string package, perm_string name);
|
static void import_ieee_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name);
|
||||||
static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name);
|
static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name);
|
||||||
|
|
||||||
static void dump_library_package(ostream&file, perm_string lname, perm_string pname, Package*pack)
|
static void dump_library_package(ostream&file, perm_string lname, perm_string pname, Package*pack)
|
||||||
|
|
@ -242,7 +243,7 @@ void library_use(const YYLTYPE&loc, ActiveScope*res,
|
||||||
|
|
||||||
// Special case handling for the IEEE library.
|
// Special case handling for the IEEE library.
|
||||||
if (use_library == "ieee") {
|
if (use_library == "ieee") {
|
||||||
import_ieee_use(res, use_package, use_name);
|
import_ieee_use(loc, res, use_package, use_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Special case handling for the STD library.
|
// Special case handling for the STD library.
|
||||||
|
|
@ -312,8 +313,30 @@ static void import_ieee_use_std_logic_1164(ActiveScope*res, perm_string name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_ieee_use_std_logic_arith(ActiveScope*, perm_string)
|
static void import_ieee_use_std_logic_misc(ActiveScope*, perm_string name)
|
||||||
{
|
{
|
||||||
|
bool all_flag = name=="all";
|
||||||
|
list<InterfacePort*>*args;
|
||||||
|
|
||||||
|
if (all_flag || name == "or_reduce") {
|
||||||
|
/* function or_reduce(arg : std_logic_vector) return std_logic;
|
||||||
|
*/
|
||||||
|
args = new list<InterfacePort*>();
|
||||||
|
args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR));
|
||||||
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("or_reduce"),
|
||||||
|
perm_string::literal("|"),
|
||||||
|
args, &primitive_STDLOGIC));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_flag || name == "and_reduce") {
|
||||||
|
/* function and_reduce(arg : std_logic_vector) return std_logic;
|
||||||
|
*/
|
||||||
|
args = new list<InterfacePort*>();
|
||||||
|
args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR));
|
||||||
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("and_reduce"),
|
||||||
|
perm_string::literal("&"),
|
||||||
|
args, &primitive_STDLOGIC));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name)
|
static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name)
|
||||||
|
|
@ -340,7 +363,7 @@ static void import_ieee_use_numeric_std(ActiveScope*res, perm_string name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_ieee_use(ActiveScope*res, perm_string package, perm_string name)
|
static void import_ieee_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name)
|
||||||
{
|
{
|
||||||
if (package == "std_logic_1164") {
|
if (package == "std_logic_1164") {
|
||||||
import_ieee_use_std_logic_1164(res, name);
|
import_ieee_use_std_logic_1164(res, name);
|
||||||
|
|
@ -348,7 +371,17 @@ static void import_ieee_use(ActiveScope*res, perm_string package, perm_string na
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package == "std_logic_arith") {
|
if (package == "std_logic_arith") {
|
||||||
import_ieee_use_std_logic_arith(res, name);
|
// arithmetic operators for std_logic_vector
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (package == "std_logic_misc") {
|
||||||
|
import_ieee_use_std_logic_misc(res, name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (package == "std_logic_unsigned") {
|
||||||
|
// arithmetic operators for std_logic_vector
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,9 +394,11 @@ static void import_ieee_use(ActiveScope*res, perm_string package, perm_string na
|
||||||
import_ieee_use_numeric_std(res, name);
|
import_ieee_use_numeric_std(res, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "Warning: Package ieee." << package.str() <<" is not yet supported" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name)
|
static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string /*name*/)
|
||||||
{
|
{
|
||||||
if (package == "standard") {
|
if (package == "standard") {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|
@ -375,7 +410,7 @@ static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string packa
|
||||||
res->use_name(type_FILE_OPEN_STATUS.peek_name(), &type_FILE_OPEN_STATUS);
|
res->use_name(type_FILE_OPEN_STATUS.peek_name(), &type_FILE_OPEN_STATUS);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
sorrymsg(loc, "package %s of library %s not yet supported", package.str(), name.str());
|
cerr << "Warning: Package std." << package.str() <<" is not yet supported" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2484,11 +2484,6 @@ shift_expression
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sign
|
|
||||||
: '+'
|
|
||||||
| '-'
|
|
||||||
;
|
|
||||||
|
|
||||||
signal_declaration_assign_opt
|
signal_declaration_assign_opt
|
||||||
: VASSIGN expression { $$ = $2; }
|
: VASSIGN expression { $$ = $2; }
|
||||||
| { $$ = 0; }
|
| { $$ = 0; }
|
||||||
|
|
@ -2514,10 +2509,10 @@ signal_declaration_assign_opt
|
||||||
* list fixes up the associations.
|
* list fixes up the associations.
|
||||||
*/
|
*/
|
||||||
simple_expression
|
simple_expression
|
||||||
: sign simple_expression_2
|
: '-' simple_expression_2
|
||||||
{ sorrymsg(@1, "Unary expression +- not supported.\n");
|
{ $$ = new ExpUMinus($2); }
|
||||||
$$ = $2;
|
| '+' simple_expression_2
|
||||||
}
|
{ $$ = $2; }
|
||||||
| simple_expression_2
|
| simple_expression_2
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n
|
||||||
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
||||||
|
|
||||||
if (base_type == 0) {
|
if (base_type == 0) {
|
||||||
errormsg(loc, "Unable to find base type %s of array.\n", base_name);
|
errormsg(loc, "Unable to find array base type '%s'.\n", base_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n
|
||||||
vector<VTypeArray::range_t> range (base_array->dimensions());
|
vector<VTypeArray::range_t> range (base_array->dimensions());
|
||||||
|
|
||||||
// For now, I only know how to handle 1 dimension
|
// For now, I only know how to handle 1 dimension
|
||||||
assert(base_array->dimensions() == 1);
|
assert(base_array->dimensions().size() == 1);
|
||||||
|
|
||||||
range[0] = VTypeArray::range_t(array_left, array_right, downto);
|
range[0] = VTypeArray::range_t(array_left, array_right, downto);
|
||||||
|
|
||||||
|
|
@ -141,7 +141,7 @@ const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name,
|
||||||
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
||||||
|
|
||||||
if (base_type == 0) {
|
if (base_type == 0) {
|
||||||
errormsg(loc, "Unable to find base type %s of range.\n", base_name);
|
errormsg(loc, "Unable to find range base type '%s'.\n", base_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
static std::map<perm_string,SubHeaderList> std_subprograms;
|
static std::map<perm_string,SubHeaderList> std_subprograms;
|
||||||
|
|
||||||
static inline void register_std_subprogram(SubprogramHeader*header)
|
void register_std_subprogram(SubprogramHeader*header)
|
||||||
{
|
{
|
||||||
std_subprograms[header->name()].push_back(header);
|
std_subprograms[header->name()].push_back(header);
|
||||||
}
|
}
|
||||||
|
|
@ -68,28 +68,51 @@ class SubprogramSizeCast : public SubprogramStdHeader {
|
||||||
: SubprogramStdHeader(nam, NULL, target) {
|
: SubprogramStdHeader(nam, NULL, target) {
|
||||||
ports_ = new list<InterfacePort*>();
|
ports_ = new list<InterfacePort*>();
|
||||||
ports_->push_back(new InterfacePort(base));
|
ports_->push_back(new InterfacePort(base));
|
||||||
ports_->push_back(new InterfacePort(&primitive_INTEGER));
|
ports_->push_back(new InterfacePort(&primitive_NATURAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
int emit_name(const std::vector<Expression*>&argv,
|
int emit_name(const std::vector<Expression*>&,
|
||||||
std::ostream&out, Entity*ent, ScopeBase*scope) const {
|
std::ostream&, Entity*, ScopeBase*) const {
|
||||||
int64_t use_size;
|
|
||||||
bool rc = argv[1]->evaluate(ent, scope, use_size);
|
|
||||||
|
|
||||||
if(!rc) {
|
|
||||||
cerr << get_fileline() << ": sorry: Could not evaluate the "
|
|
||||||
<< "expression size. Size casting impossible." << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
out << use_size << "'";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int emit_args(const std::vector<Expression*>&argv,
|
int emit_args(const std::vector<Expression*>&argv,
|
||||||
std::ostream&out, Entity*ent, ScopeBase*scope) const {
|
std::ostream&out, Entity*ent, ScopeBase*scope) const {
|
||||||
|
int64_t new_size, old_size;
|
||||||
|
|
||||||
return argv[0]->emit(out, ent, scope);
|
const VType*type = argv[0]->probe_type(ent, scope);
|
||||||
|
|
||||||
|
if(!type) {
|
||||||
|
cerr << get_fileline() << ": sorry: Could not determine "
|
||||||
|
<< "the argument type. Size casting impossible." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_size = type->get_width(scope);
|
||||||
|
|
||||||
|
if(old_size <= 0) {
|
||||||
|
cerr << get_fileline() << ": sorry: Could not determine "
|
||||||
|
<< "the argument size. Size casting impossible." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!argv[1]->evaluate(ent, scope, new_size)) {
|
||||||
|
cerr << get_fileline() << ": sorry: Could not evaluate the requested"
|
||||||
|
<< "expression size. Size casting impossible." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
out << new_size << "'(" << old_size << "'(";
|
||||||
|
|
||||||
|
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type))
|
||||||
|
out << (arr->signed_vector() ? "$signed" : "$unsigned");
|
||||||
|
|
||||||
|
out << "(";
|
||||||
|
bool res = argv[0]->emit(out, ent, scope);
|
||||||
|
out << ")))";
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -187,7 +210,13 @@ void preload_std_funcs(void)
|
||||||
have to do anything for that to work.
|
have to do anything for that to work.
|
||||||
*/
|
*/
|
||||||
args = new list<InterfacePort*>();
|
args = new list<InterfacePort*>();
|
||||||
args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR));
|
args->push_back(new InterfacePort(&primitive_SIGNED));
|
||||||
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("std_logic_vector"),
|
||||||
|
empty_perm_string,
|
||||||
|
args, &primitive_STDLOGIC_VECTOR));
|
||||||
|
|
||||||
|
args = new list<InterfacePort*>();
|
||||||
|
args->push_back(new InterfacePort(&primitive_UNSIGNED));
|
||||||
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("std_logic_vector"),
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("std_logic_vector"),
|
||||||
empty_perm_string,
|
empty_perm_string,
|
||||||
args, &primitive_STDLOGIC_VECTOR));
|
args, &primitive_STDLOGIC_VECTOR));
|
||||||
|
|
@ -215,6 +244,13 @@ void preload_std_funcs(void)
|
||||||
* function shift_right (arg: signed; count: natural) return signed;
|
* function shift_right (arg: signed; count: natural) return signed;
|
||||||
*/
|
*/
|
||||||
args = new list<InterfacePort*>();
|
args = new list<InterfacePort*>();
|
||||||
|
args->push_back(new InterfacePort(&primitive_UNSIGNED));
|
||||||
|
args->push_back(new InterfacePort(&primitive_NATURAL));
|
||||||
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_right"),
|
||||||
|
perm_string::literal("$ivlh_shift_right"),
|
||||||
|
args, &primitive_UNSIGNED));
|
||||||
|
|
||||||
|
args = new list<InterfacePort*>();
|
||||||
args->push_back(new InterfacePort(&primitive_SIGNED));
|
args->push_back(new InterfacePort(&primitive_SIGNED));
|
||||||
args->push_back(new InterfacePort(&primitive_NATURAL));
|
args->push_back(new InterfacePort(&primitive_NATURAL));
|
||||||
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_right"),
|
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_right"),
|
||||||
|
|
@ -224,12 +260,16 @@ void preload_std_funcs(void)
|
||||||
/* function resize
|
/* function resize
|
||||||
*/
|
*/
|
||||||
register_std_subprogram(new SubprogramSizeCast(perm_string::literal("resize"),
|
register_std_subprogram(new SubprogramSizeCast(perm_string::literal("resize"),
|
||||||
&primitive_STDLOGIC_VECTOR, &primitive_STDLOGIC_VECTOR));
|
&primitive_UNSIGNED, &primitive_UNSIGNED));
|
||||||
|
|
||||||
|
register_std_subprogram(new SubprogramSizeCast(perm_string::literal("resize"),
|
||||||
|
&primitive_SIGNED, &primitive_SIGNED));
|
||||||
|
|
||||||
/* std_logic_arith library
|
/* std_logic_arith library
|
||||||
* function conv_std_logic_vector(arg: integer; size: integer) return std_logic_vector;
|
* function conv_std_logic_vector(arg: integer; size: integer) return std_logic_vector;
|
||||||
*/
|
*/
|
||||||
register_std_subprogram(new SubprogramSizeCast(perm_string::literal("conv_std_logic_vector"),
|
register_std_subprogram(new SubprogramSizeCast(
|
||||||
|
perm_string::literal("conv_std_logic_vector"),
|
||||||
&primitive_INTEGER, &primitive_STDLOGIC_VECTOR));
|
&primitive_INTEGER, &primitive_STDLOGIC_VECTOR));
|
||||||
|
|
||||||
/* numeric_bit library
|
/* numeric_bit library
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ void preload_std_funcs();
|
||||||
// Destroys subprogram headers for standard VHDL library functions.
|
// Destroys subprogram headers for standard VHDL library functions.
|
||||||
void delete_std_funcs();
|
void delete_std_funcs();
|
||||||
|
|
||||||
|
// Adds a subprogram to the standard library subprogram set
|
||||||
|
void register_std_subprogram(SubprogramHeader*header);
|
||||||
|
|
||||||
// Returns subprogram header for a requested function or NULL if it does not exist.
|
// Returns subprogram header for a requested function or NULL if it does not exist.
|
||||||
SubHeaderList find_std_subprogram(perm_string name);
|
SubHeaderList find_std_subprogram(perm_string name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,24 @@ const VType*SubprogramHeader::peek_param_type(int idx) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VType*SubprogramHeader::exact_return_type(const std::vector<Expression*>&argv, Entity*ent, ScopeBase*scope)
|
||||||
|
{
|
||||||
|
const VTypeArray*orig_ret = dynamic_cast<const VTypeArray*>(return_type_);
|
||||||
|
|
||||||
|
if(!orig_ret)
|
||||||
|
return return_type_;
|
||||||
|
|
||||||
|
const VTypeArray*arg = dynamic_cast<const VTypeArray*>(argv[0]->fit_type(ent, scope, orig_ret));
|
||||||
|
|
||||||
|
if(!arg)
|
||||||
|
return return_type_;
|
||||||
|
|
||||||
|
VTypeArray*ret = new VTypeArray(orig_ret->element_type(), arg->dimensions(), orig_ret->signed_vector());
|
||||||
|
ret->set_parent_type(orig_ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool SubprogramHeader::unbounded() const {
|
bool SubprogramHeader::unbounded() const {
|
||||||
if(return_type_ && return_type_->is_unbounded())
|
if(return_type_ && return_type_->is_unbounded())
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,10 @@ class SubprogramHeader : public LineInfo {
|
||||||
const VType*peek_param_type(int idx) const;
|
const VType*peek_param_type(int idx) const;
|
||||||
const VType*peek_return_type() const { return return_type_; }
|
const VType*peek_return_type() const { return return_type_; }
|
||||||
|
|
||||||
|
// Computes the exact return type (e.g. std_logic_vector(7 downto 0)
|
||||||
|
// instead of generic std_logic_vector)
|
||||||
|
virtual const VType*exact_return_type(const std::vector<Expression*>&, Entity*, ScopeBase*);
|
||||||
|
|
||||||
inline void set_package(const Package*pkg) { assert(!package_); package_ = pkg; }
|
inline void set_package(const Package*pkg) { assert(!package_); package_ = pkg; }
|
||||||
inline const Package*get_package() const { return package_; }
|
inline const Package*get_package() const { return package_; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ class VTypeArray : public VType {
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
int get_width(ScopeBase*scope) const;
|
int get_width(ScopeBase*scope) const;
|
||||||
|
|
||||||
inline size_t dimensions() const { return ranges_.size(); };
|
const std::vector<range_t>&dimensions() const { return ranges_; };
|
||||||
const range_t&dimension(size_t idx) const
|
const range_t&dimension(size_t idx) const
|
||||||
{ return ranges_[idx]; }
|
{ return ranges_[idx]; }
|
||||||
|
|
||||||
|
|
@ -253,6 +253,8 @@ class VTypeArray : public VType {
|
||||||
// To handle subtypes
|
// To handle subtypes
|
||||||
inline void set_parent_type(const VTypeArray*parent) { parent_ = parent; }
|
inline void set_parent_type(const VTypeArray*parent) { parent_ = parent; }
|
||||||
|
|
||||||
|
const VTypeArray*get_parent_type() const { return parent_; }
|
||||||
|
|
||||||
// Wherever it is possible, replaces range lsb & msb expressions with
|
// Wherever it is possible, replaces range lsb & msb expressions with
|
||||||
// constant integers.
|
// constant integers.
|
||||||
void evaluate_ranges(ScopeBase*scope);
|
void evaluate_ranges(ScopeBase*scope);
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ int VTypeArray::emit_def(ostream&out, perm_string name) const
|
||||||
const VTypePrimitive*base = dynamic_cast<const VTypePrimitive*> (raw_base);
|
const VTypePrimitive*base = dynamic_cast<const VTypePrimitive*> (raw_base);
|
||||||
|
|
||||||
if (base) {
|
if (base) {
|
||||||
assert(dimensions() == 1);
|
assert(dimensions().size() == 1);
|
||||||
|
|
||||||
// If this is a string type without any boundaries specified, then
|
// If this is a string type without any boundaries specified, then
|
||||||
// there is a direct counterpart in SV called.. 'string'
|
// there is a direct counterpart in SV called.. 'string'
|
||||||
|
|
@ -127,7 +127,7 @@ int VTypeArray::emit_with_dims_(std::ostream&out, bool packed, perm_string name)
|
||||||
name_emitted = true;
|
name_emitted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned i = 0; i < cur->dimensions(); ++i) {
|
for(unsigned i = 0; i < cur->dimensions().size(); ++i) {
|
||||||
if(cur->dimension(i).is_box() && !name_emitted) {
|
if(cur->dimension(i).is_box() && !name_emitted) {
|
||||||
emit_name(out, name);
|
emit_name(out, name);
|
||||||
name_emitted = true;
|
name_emitted = true;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,15 @@ bool VTypeArray::type_match(const VType*that) const
|
||||||
|
|
||||||
// Check if both arrays are of the same size
|
// Check if both arrays are of the same size
|
||||||
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(that)) {
|
if(const VTypeArray*arr = dynamic_cast<const VTypeArray*>(that)) {
|
||||||
if(!element_type()->type_match(arr->element_type()))
|
const VTypeArray*this_parent = this;
|
||||||
|
while(const VTypeArray*tmp = this_parent->get_parent_type())
|
||||||
|
this_parent = tmp;
|
||||||
|
|
||||||
|
const VTypeArray*that_parent = arr;
|
||||||
|
while(const VTypeArray*tmp = that_parent->get_parent_type())
|
||||||
|
that_parent = tmp;
|
||||||
|
|
||||||
|
if(this_parent != that_parent)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int this_width = get_width(NULL);
|
int this_width = get_width(NULL);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue