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:
parent
43b3df00c8
commit
cab974c0c2
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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*)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue