vhdl sequential l-values cause variables to be reg vs. net.

When a signal (or port) is assigned by a sequential assignment,
the signal or port becomes a reg, instead of a wire(net). Detect
this distinction during elaboration and generate the correct
signal/port declaration.
This commit is contained in:
Stephen Williams 2011-06-12 15:38:03 -07:00
parent 43b3df00c8
commit cab974c0c2
6 changed files with 30 additions and 11 deletions

View File

@ -215,7 +215,7 @@ int SignalAssignment::elaborate(Entity*ent, Architecture*arc)
int errors = 0;
// Elaborate the l-value expression.
errors += lval_->elaborate_lval(ent, arc);
errors += lval_->elaborate_lval(ent, arc, false);
// The elaborate_lval should have resolved the type of the
// l-value expression. We'll use that type to elaborate the

View File

@ -49,7 +49,8 @@ class Expression : public LineInfo {
// assignment. This generates an error for most cases, but
// expressions that are valid l-values return 0 and set any
// flags needed to indicate their status as writable variables.
virtual int elaborate_lval(Entity*ent, Architecture*arc);
virtual int elaborate_lval(Entity*ent, Architecture*arc,
bool is_sequ);
// This virtual method probes the expression to get the most
// constrained type for the expression. For a given instance,
@ -319,7 +320,7 @@ class ExpName : public Expression {
~ExpName();
public: // Base methods
int elaborate_lval(Entity*ent, Architecture*arc);
int elaborate_lval(Entity*ent, Architecture*arc, bool);
const VType* probe_type(Entity*ent, Architecture*arc) const;
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
int emit(ostream&out, Entity*ent, Architecture*arc);
@ -340,7 +341,7 @@ class ExpNameALL : public ExpName {
ExpNameALL() : ExpName(perm_string()) { }
public:
int elaborate_lval(Entity*ent, Architecture*arc);
int elaborate_lval(Entity*ent, Architecture*arc, bool);
const VType* probe_type(Entity*ent, Architecture*arc) const;
void dump(ostream&out, int indent =0) const;
};

View File

@ -28,7 +28,7 @@
using namespace std;
int Expression::elaborate_lval(Entity*, Architecture*)
int Expression::elaborate_lval(Entity*, Architecture*, bool)
{
cerr << get_fileline() << ": error: Expression is not a valie l-value." << endl;
return 1;
@ -39,7 +39,7 @@ const VType* Expression::probe_type(Entity*, Architecture*) const
return 0;
}
int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
{
int errors = 0;
@ -50,7 +50,9 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
return errors += 1;
}
ent->set_declaration_l_value(name_, true);
if (is_sequ)
ent->set_declaration_l_value(name_, is_sequ);
set_type(cur->type);
return errors;
}
@ -62,13 +64,16 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
return errors + 1;
}
// Tell the target signal that this may be a sequential l-value.
if (is_sequ) sig->count_ref_sequ();
set_type(sig->peek_type());
return errors;
}
int ExpNameALL::elaborate_lval(Entity*ent, Architecture*arc)
int ExpNameALL::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
{
return Expression::elaborate_lval(ent, arc);
return Expression::elaborate_lval(ent, arc, is_sequ);
}
int Expression::elaborate_expr(Entity*, Architecture*, const VType*)

View File

@ -49,7 +49,7 @@ int SignalSeqAssignment::elaborate(Entity*ent, Architecture*arc)
int errors = 0;
// Elaborate the l-value expression.
errors += lval_->elaborate_lval(ent, arc);
errors += lval_->elaborate_lval(ent, arc, true);
// The elaborate_lval should have resolved the type of the
// l-value expression. We'll use that type to elaborate the

View File

@ -24,7 +24,7 @@
using namespace std;
Signal::Signal(perm_string nam, const VType*typ)
: name_(nam), type_(typ)
: name_(nam), type_(typ), refcnt_sequ_(0)
{
}
@ -38,6 +38,8 @@ int Signal::emit(ostream&out, Entity*, Architecture*)
VType::decl_t decl;
type_->elaborate(decl);
if (refcnt_sequ_ > 0)
decl.reg_flag = true;
errors += decl.emit(out, name_);
out << ";" << endl;
return errors;

View File

@ -34,6 +34,10 @@ class Signal : public LineInfo {
const VType* peek_type(void) const { return type_; }
// Call this method for each occasion where this signal is the
// l-value of a sequential assignment.
void count_ref_sequ();
int emit(ostream&out, Entity*ent, Architecture*arc);
void dump(ostream&out, int indent = 0) const;
@ -42,9 +46,16 @@ class Signal : public LineInfo {
perm_string name_;
const VType*type_;
unsigned refcnt_sequ_;
private: // Not implemented
Signal(const Signal&);
Signal& operator = (const Signal&);
};
inline void Signal::count_ref_sequ()
{
refcnt_sequ_ += 1;
}
#endif