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()
{
}

View File

@ -36,6 +36,7 @@ using namespace std;
class LineInfo {
public:
LineInfo();
LineInfo(const LineInfo&that);
virtual ~LineInfo();
// 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);
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 << " #(";

View File

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

View File

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

View File

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

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)
: LineInfo(other)
{
cond_ = other.cond_->clone();
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;
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;

View File

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

View File

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

View File

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

View File

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

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)
: 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()

View File

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

View File

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