commit
ced9759c65
|
|
@ -27,6 +27,11 @@ LineInfo::LineInfo()
|
|||
{
|
||||
}
|
||||
|
||||
LineInfo::LineInfo(const LineInfo&that) :
|
||||
file_(that.file_), lineno_(that.lineno_)
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ using namespace std;
|
|||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
LineInfo(const LineInfo&that);
|
||||
virtual ~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
|
|
|
|||
|
|
@ -150,6 +150,22 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
arc->set_cur_component(this);
|
||||
|
||||
if(ComponentBase*comp = arc->find_component(cname_)) {
|
||||
const std::vector<InterfacePort*>& generics = comp->get_generics();
|
||||
|
||||
if(generics.size() != generic_map_.size())
|
||||
// Display an error for generics that do not have neither
|
||||
// default nor component specific value defined
|
||||
for(vector<InterfacePort*>::const_iterator it = generics.begin();
|
||||
it != generics.end(); ++it) {
|
||||
if(!(*it)->expr && generic_map_.count((*it)->name) == 0) {
|
||||
cerr << get_fileline() << ": generic " << (*it)->name <<
|
||||
"value is not defined" << endl;
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out << cname_;
|
||||
if (! generic_map_.empty()) {
|
||||
out << " #(";
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
# include "StringHeap.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t;
|
||||
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT, PORT_INOUT } port_mode_t;
|
||||
|
||||
class Architecture;
|
||||
class Expression;
|
||||
|
|
@ -63,6 +63,7 @@ class ComponentBase : public LineInfo {
|
|||
|
||||
const InterfacePort* find_port(perm_string by_name) const;
|
||||
const InterfacePort* find_generic(perm_string by_name) const;
|
||||
const std::vector<InterfacePort*>& get_generics() const { return parms_; }
|
||||
|
||||
// Declare the ports for the entity. The parser calls this
|
||||
// method with a list of interface elements that were parsed
|
||||
|
|
|
|||
|
|
@ -50,11 +50,14 @@ int Entity::emit(ostream&out)
|
|||
const InterfacePort*curp = *cur;
|
||||
if (cur != parms_.begin())
|
||||
out << ", ";
|
||||
out << "parameter \\" << curp->name << " ";
|
||||
out << "parameter \\" << curp->name << " = ";
|
||||
if(curp->expr) {
|
||||
out << "= ";
|
||||
errors += curp->expr->emit(out, this, 0);
|
||||
}
|
||||
} else {
|
||||
// Unlike VHDL, Verilog module parameter port list
|
||||
// elements are always assignments. Fill in the blank.
|
||||
out << "1'bx";
|
||||
}
|
||||
}
|
||||
out << ") ";
|
||||
}
|
||||
|
|
@ -74,17 +77,21 @@ int Entity::emit(ostream&out)
|
|||
|
||||
switch (port->mode) {
|
||||
case PORT_NONE: // Should not happen
|
||||
cerr << get_fileline() << ": error: Undefined port direction." << endl;
|
||||
out << "NO_PORT " << port->name;
|
||||
break;
|
||||
case PORT_IN:
|
||||
out << "input ";
|
||||
errors += decl.emit(out, port->name);
|
||||
break;
|
||||
case PORT_OUT:
|
||||
out << "output ";
|
||||
errors += decl.emit(out, port->name);
|
||||
break;
|
||||
case PORT_INOUT:
|
||||
out << "inout ";
|
||||
break;
|
||||
}
|
||||
|
||||
errors += decl.emit(out, port->name);
|
||||
}
|
||||
cout << ")";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ void ComponentBase::write_to_stream(ostream&fd) const
|
|||
case PORT_OUT:
|
||||
fd << "out ";
|
||||
break;
|
||||
case PORT_INOUT:
|
||||
fd << "inout ";
|
||||
break;
|
||||
}
|
||||
|
||||
item->type->write_to_stream(fd);
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ ExpConditional::else_t::else_t(Expression*cond, std::list<Expression*>*tru)
|
|||
}
|
||||
|
||||
ExpConditional::else_t::else_t(const else_t&other)
|
||||
: LineInfo(other)
|
||||
{
|
||||
cond_ = other.cond_->clone();
|
||||
for(std::list<Expression*>::const_iterator it = other.true_clause_.begin();
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ int ExpName::elaborate_lval_(Entity*ent, ScopeBase*scope, bool is_sequ, ExpName*
|
|||
const VType*found_type = 0;
|
||||
|
||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||
if (cur->mode != PORT_OUT) {
|
||||
if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
|
||||
cerr << get_fileline() << ": error: Assignment to "
|
||||
"input port " << name_ << "." << endl;
|
||||
return errors + 1;
|
||||
|
|
@ -216,7 +216,7 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
|
|||
const VType*found_type = 0;
|
||||
|
||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||
if (cur->mode != PORT_OUT) {
|
||||
if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) {
|
||||
cerr << get_fileline() << ": error: Assignment to "
|
||||
"input port " << name_ << "." << endl;
|
||||
return errors += 1;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ bool ExpAttribute::evaluate(ScopeBase*scope, int64_t&val) const
|
|||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(base_type);
|
||||
if (arr == 0) {
|
||||
cerr << endl << get_fileline() << ": error: "
|
||||
<< "Cannot apply the 'length attribute to non-array objects"
|
||||
<< "Cannot apply the '" << name_ << " attribute to non-array objects"
|
||||
<< endl;
|
||||
ivl_assert(*this, false);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ void Package::write_to_stream(ostream&fd) const
|
|||
if (is_global_type(cur->first))
|
||||
continue;
|
||||
|
||||
if(!dynamic_cast<const VTypeDef*>(cur->second))
|
||||
fd << "sub";
|
||||
|
||||
fd << "type " << cur->first << " is ";
|
||||
cur->second->write_type_to_stream(fd);
|
||||
fd << "; -- imported" << endl;
|
||||
|
|
@ -85,6 +88,9 @@ void Package::write_to_stream(ostream&fd) const
|
|||
if (is_global_type(cur->first))
|
||||
continue;
|
||||
|
||||
if(!dynamic_cast<const VTypeDef*>(cur->second))
|
||||
fd << "sub";
|
||||
|
||||
fd << "type " << cur->first << " is ";
|
||||
cur->second->write_type_to_stream(fd);
|
||||
fd << ";" << endl;
|
||||
|
|
|
|||
|
|
@ -1584,6 +1584,7 @@ loop_statement
|
|||
mode
|
||||
: K_in { $$ = PORT_IN; }
|
||||
| K_out { $$ = PORT_OUT; }
|
||||
| K_inout { $$ = PORT_INOUT; }
|
||||
;
|
||||
|
||||
mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ int Subprogram::emit_package(ostream&fd) const
|
|||
case PORT_OUT:
|
||||
fd << "output ";
|
||||
break;
|
||||
case PORT_INOUT:
|
||||
fd << "inout ";
|
||||
break;
|
||||
case PORT_NONE:
|
||||
fd << "inout /* PORT_NONE? */ ";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -273,11 +273,9 @@ void VTypeArray::evaluate_ranges(ScopeBase*scope) {
|
|||
}
|
||||
}
|
||||
|
||||
VTypeRange::VTypeRange(const VType*base, int64_t max_val, int64_t min_val)
|
||||
: base_(base)
|
||||
VTypeRange::VTypeRange(const VType*base, int64_t end_val, int64_t start_val)
|
||||
: base_(base), end_(end_val), start_(start_val)
|
||||
{
|
||||
max_ = max_val;
|
||||
min_ = min_val;
|
||||
}
|
||||
|
||||
VTypeRange::~VTypeRange()
|
||||
|
|
|
|||
|
|
@ -275,10 +275,10 @@ class VTypeArray : public VType {
|
|||
class VTypeRange : public VType {
|
||||
|
||||
public:
|
||||
VTypeRange(const VType*base, int64_t max_val, int64_t min_val);
|
||||
VTypeRange(const VType*base, int64_t end, int64_t start);
|
||||
~VTypeRange();
|
||||
|
||||
VType*clone() const { return new VTypeRange(base_->clone(), max_, min_); }
|
||||
VType*clone() const { return new VTypeRange(base_->clone(), start_, end_); }
|
||||
|
||||
// Get the type that is limited by the range.
|
||||
inline const VType* base_type() const { return base_; }
|
||||
|
|
@ -289,7 +289,7 @@ class VTypeRange : public VType {
|
|||
|
||||
private:
|
||||
const VType*base_;
|
||||
int64_t max_, min_;
|
||||
int64_t end_, start_;
|
||||
};
|
||||
|
||||
class VTypeEnum : public VType {
|
||||
|
|
|
|||
|
|
@ -41,14 +41,16 @@ void VTypeArray::write_to_stream(ostream&fd) const
|
|||
// Special cases: std_logic_vector & string
|
||||
if (etype_ == &primitive_STDLOGIC) {
|
||||
fd << "std_logic_vector";
|
||||
if (! ranges_.empty() && ! ranges_[0].is_box()) {
|
||||
if (!ranges_.empty() && !ranges_[0].is_box()) {
|
||||
write_range_to_stream_(fd);
|
||||
}
|
||||
return;
|
||||
} else if (etype_ == &primitive_CHARACTER) {
|
||||
fd << "string";
|
||||
if (!ranges_.empty() && !ranges_[0].is_box()) {
|
||||
write_range_to_stream_(fd);
|
||||
}
|
||||
return;
|
||||
} else if (etype_ == &primitive_CHARACTER &&
|
||||
ranges_.size() == 1 && ranges_[0].is_box()) {
|
||||
fd << "string";
|
||||
return;
|
||||
}
|
||||
|
||||
bool typedefed = false;
|
||||
|
|
@ -104,6 +106,13 @@ void VTypeArray::write_type_to_stream(ostream&fd) const
|
|||
}
|
||||
return;
|
||||
}
|
||||
else if (etype_ == &primitive_CHARACTER) {
|
||||
fd << "string";
|
||||
if (! ranges_.empty() && ! ranges_[0].is_box()) {
|
||||
write_range_to_stream_(fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fd << "array ";
|
||||
|
||||
|
|
@ -171,14 +180,16 @@ void VTypeRange::write_to_stream(ostream&fd) const
|
|||
// Detect some special cases that can be written as ieee or
|
||||
// standard types.
|
||||
if (const VTypePrimitive*tmp = dynamic_cast<const VTypePrimitive*> (base_)) {
|
||||
if (min_==0 && max_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) {
|
||||
if (start_==0 && end_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) {
|
||||
fd << "natural";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base_->write_to_stream(fd);
|
||||
fd << " range " << min_ << " to " << max_;
|
||||
fd << " range " << start_;
|
||||
fd << (start_ < end_ ? " to " : " downto ");
|
||||
fd << end_;
|
||||
}
|
||||
|
||||
void VTypeRecord::write_to_stream(ostream&fd) const
|
||||
|
|
|
|||
Loading…
Reference in New Issue