Merge pull request #69 from orsonmmz/fixes

Various fixes
This commit is contained in:
Stephen Williams 2015-05-21 10:05:26 -07:00
commit ced9759c65
15 changed files with 76 additions and 23 deletions

View File

@ -27,6 +27,11 @@ LineInfo::LineInfo()
{ {
} }
LineInfo::LineInfo(const LineInfo&that) :
file_(that.file_), lineno_(that.lineno_)
{
}
LineInfo::~LineInfo() LineInfo::~LineInfo()
{ {
} }

View File

@ -36,6 +36,7 @@ using namespace std;
class LineInfo { class LineInfo {
public: public:
LineInfo(); LineInfo();
LineInfo(const LineInfo&that);
virtual ~LineInfo(); virtual ~LineInfo();
// Get a fully formatted file/lineno // Get a fully formatted file/lineno

View File

@ -150,6 +150,22 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
arc->set_cur_component(this); 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_; out << cname_;
if (! generic_map_.empty()) { if (! generic_map_.empty()) {
out << " #("; out << " #(";

View File

@ -27,7 +27,7 @@
# include "StringHeap.h" # include "StringHeap.h"
# include "LineInfo.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 Architecture;
class Expression; class Expression;
@ -63,6 +63,7 @@ class ComponentBase : public LineInfo {
const InterfacePort* find_port(perm_string by_name) const; const InterfacePort* find_port(perm_string by_name) const;
const InterfacePort* find_generic(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 // Declare the ports for the entity. The parser calls this
// method with a list of interface elements that were parsed // method with a list of interface elements that were parsed

View File

@ -50,10 +50,13 @@ int Entity::emit(ostream&out)
const InterfacePort*curp = *cur; const InterfacePort*curp = *cur;
if (cur != parms_.begin()) if (cur != parms_.begin())
out << ", "; out << ", ";
out << "parameter \\" << curp->name << " "; out << "parameter \\" << curp->name << " = ";
if(curp->expr) { if(curp->expr) {
out << "= ";
errors += curp->expr->emit(out, this, 0); 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 << ") "; out << ") ";
@ -74,17 +77,21 @@ int Entity::emit(ostream&out)
switch (port->mode) { switch (port->mode) {
case PORT_NONE: // Should not happen case PORT_NONE: // Should not happen
cerr << get_fileline() << ": error: Undefined port direction." << endl;
out << "NO_PORT " << port->name; out << "NO_PORT " << port->name;
break; break;
case PORT_IN: case PORT_IN:
out << "input "; out << "input ";
errors += decl.emit(out, port->name);
break; break;
case PORT_OUT: case PORT_OUT:
out << "output "; out << "output ";
errors += decl.emit(out, port->name); break;
case PORT_INOUT:
out << "inout ";
break; break;
} }
errors += decl.emit(out, port->name);
} }
cout << ")"; cout << ")";
} }

View File

@ -69,6 +69,9 @@ void ComponentBase::write_to_stream(ostream&fd) const
case PORT_OUT: case PORT_OUT:
fd << "out "; fd << "out ";
break; break;
case PORT_INOUT:
fd << "inout ";
break;
} }
item->type->write_to_stream(fd); item->type->write_to_stream(fd);

View File

@ -311,6 +311,7 @@ ExpConditional::else_t::else_t(Expression*cond, std::list<Expression*>*tru)
} }
ExpConditional::else_t::else_t(const else_t&other) ExpConditional::else_t::else_t(const else_t&other)
: LineInfo(other)
{ {
cond_ = other.cond_->clone(); cond_ = other.cond_->clone();
for(std::list<Expression*>::const_iterator it = other.true_clause_.begin(); for(std::list<Expression*>::const_iterator it = other.true_clause_.begin();

View File

@ -112,7 +112,7 @@ int ExpName::elaborate_lval_(Entity*ent, ScopeBase*scope, bool is_sequ, ExpName*
const VType*found_type = 0; const VType*found_type = 0;
if (const InterfacePort*cur = ent->find_port(name_)) { 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 " cerr << get_fileline() << ": error: Assignment to "
"input port " << name_ << "." << endl; "input port " << name_ << "." << endl;
return errors + 1; return errors + 1;
@ -216,7 +216,7 @@ int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
const VType*found_type = 0; const VType*found_type = 0;
if (const InterfacePort*cur = ent->find_port(name_)) { 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 " cerr << get_fileline() << ": error: Assignment to "
"input port " << name_ << "." << endl; "input port " << name_ << "." << endl;
return errors += 1; return errors += 1;

View File

@ -106,7 +106,7 @@ bool ExpAttribute::evaluate(ScopeBase*scope, int64_t&val) const
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(base_type); const VTypeArray*arr = dynamic_cast<const VTypeArray*>(base_type);
if (arr == 0) { if (arr == 0) {
cerr << endl << get_fileline() << ": error: " cerr << endl << get_fileline() << ": error: "
<< "Cannot apply the 'length attribute to non-array objects" << "Cannot apply the '" << name_ << " attribute to non-array objects"
<< endl; << endl;
ivl_assert(*this, false); ivl_assert(*this, false);
return false; return false;

View File

@ -74,6 +74,9 @@ void Package::write_to_stream(ostream&fd) const
if (is_global_type(cur->first)) if (is_global_type(cur->first))
continue; continue;
if(!dynamic_cast<const VTypeDef*>(cur->second))
fd << "sub";
fd << "type " << cur->first << " is "; fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd); cur->second->write_type_to_stream(fd);
fd << "; -- imported" << endl; fd << "; -- imported" << endl;
@ -85,6 +88,9 @@ void Package::write_to_stream(ostream&fd) const
if (is_global_type(cur->first)) if (is_global_type(cur->first))
continue; continue;
if(!dynamic_cast<const VTypeDef*>(cur->second))
fd << "sub";
fd << "type " << cur->first << " is "; fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd); cur->second->write_type_to_stream(fd);
fd << ";" << endl; fd << ";" << endl;

View File

@ -1584,6 +1584,7 @@ loop_statement
mode mode
: K_in { $$ = PORT_IN; } : K_in { $$ = PORT_IN; }
| K_out { $$ = PORT_OUT; } | K_out { $$ = PORT_OUT; }
| K_inout { $$ = PORT_INOUT; }
; ;
mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ; mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ;

View File

@ -50,6 +50,9 @@ int Subprogram::emit_package(ostream&fd) const
case PORT_OUT: case PORT_OUT:
fd << "output "; fd << "output ";
break; break;
case PORT_INOUT:
fd << "inout ";
break;
case PORT_NONE: case PORT_NONE:
fd << "inout /* PORT_NONE? */ "; fd << "inout /* PORT_NONE? */ ";
break; break;

View File

@ -273,11 +273,9 @@ void VTypeArray::evaluate_ranges(ScopeBase*scope) {
} }
} }
VTypeRange::VTypeRange(const VType*base, int64_t max_val, int64_t min_val) VTypeRange::VTypeRange(const VType*base, int64_t end_val, int64_t start_val)
: base_(base) : base_(base), end_(end_val), start_(start_val)
{ {
max_ = max_val;
min_ = min_val;
} }
VTypeRange::~VTypeRange() VTypeRange::~VTypeRange()

View File

@ -275,10 +275,10 @@ class VTypeArray : public VType {
class VTypeRange : public VType { class VTypeRange : public VType {
public: public:
VTypeRange(const VType*base, int64_t max_val, int64_t min_val); VTypeRange(const VType*base, int64_t end, int64_t start);
~VTypeRange(); ~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. // Get the type that is limited by the range.
inline const VType* base_type() const { return base_; } inline const VType* base_type() const { return base_; }
@ -289,7 +289,7 @@ class VTypeRange : public VType {
private: private:
const VType*base_; const VType*base_;
int64_t max_, min_; int64_t end_, start_;
}; };
class VTypeEnum : public VType { class VTypeEnum : public VType {

View File

@ -45,9 +45,11 @@ void VTypeArray::write_to_stream(ostream&fd) const
write_range_to_stream_(fd); write_range_to_stream_(fd);
} }
return; return;
} else if (etype_ == &primitive_CHARACTER && } else if (etype_ == &primitive_CHARACTER) {
ranges_.size() == 1 && ranges_[0].is_box()) {
fd << "string"; fd << "string";
if (!ranges_.empty() && !ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return; return;
} }
@ -104,6 +106,13 @@ void VTypeArray::write_type_to_stream(ostream&fd) const
} }
return; return;
} }
else if (etype_ == &primitive_CHARACTER) {
fd << "string";
if (! ranges_.empty() && ! ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return;
}
fd << "array "; 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 // Detect some special cases that can be written as ieee or
// standard types. // standard types.
if (const VTypePrimitive*tmp = dynamic_cast<const VTypePrimitive*> (base_)) { 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"; fd << "natural";
return; return;
} }
} }
base_->write_to_stream(fd); 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 void VTypeRecord::write_to_stream(ostream&fd) const