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;
|
int errors = 0;
|
||||||
|
|
||||||
// Elaborate the l-value expression.
|
// 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
|
// The elaborate_lval should have resolved the type of the
|
||||||
// l-value expression. We'll use that type to elaborate 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
|
// assignment. This generates an error for most cases, but
|
||||||
// expressions that are valid l-values return 0 and set any
|
// expressions that are valid l-values return 0 and set any
|
||||||
// flags needed to indicate their status as writable variables.
|
// 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
|
// This virtual method probes the expression to get the most
|
||||||
// constrained type for the expression. For a given instance,
|
// constrained type for the expression. For a given instance,
|
||||||
|
|
@ -319,7 +320,7 @@ class ExpName : public Expression {
|
||||||
~ExpName();
|
~ExpName();
|
||||||
|
|
||||||
public: // Base methods
|
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;
|
const VType* probe_type(Entity*ent, Architecture*arc) const;
|
||||||
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
|
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
|
||||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||||
|
|
@ -340,7 +341,7 @@ class ExpNameALL : public ExpName {
|
||||||
ExpNameALL() : ExpName(perm_string()) { }
|
ExpNameALL() : ExpName(perm_string()) { }
|
||||||
|
|
||||||
public:
|
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;
|
const VType* probe_type(Entity*ent, Architecture*arc) const;
|
||||||
void dump(ostream&out, int indent =0) const;
|
void dump(ostream&out, int indent =0) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
using namespace std;
|
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;
|
cerr << get_fileline() << ": error: Expression is not a valie l-value." << endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -39,7 +39,7 @@ const VType* Expression::probe_type(Entity*, Architecture*) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
|
int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
|
|
@ -50,7 +50,9 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
|
||||||
return errors += 1;
|
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);
|
set_type(cur->type);
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
@ -62,13 +64,16 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc)
|
||||||
return errors + 1;
|
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());
|
set_type(sig->peek_type());
|
||||||
return errors;
|
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*)
|
int Expression::elaborate_expr(Entity*, Architecture*, const VType*)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ int SignalSeqAssignment::elaborate(Entity*ent, Architecture*arc)
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
// Elaborate the l-value expression.
|
// 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
|
// The elaborate_lval should have resolved the type of the
|
||||||
// l-value expression. We'll use that type to elaborate the
|
// l-value expression. We'll use that type to elaborate the
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Signal::Signal(perm_string nam, const VType*typ)
|
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;
|
VType::decl_t decl;
|
||||||
type_->elaborate(decl);
|
type_->elaborate(decl);
|
||||||
|
if (refcnt_sequ_ > 0)
|
||||||
|
decl.reg_flag = true;
|
||||||
errors += decl.emit(out, name_);
|
errors += decl.emit(out, name_);
|
||||||
out << ";" << endl;
|
out << ";" << endl;
|
||||||
return errors;
|
return errors;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ class Signal : public LineInfo {
|
||||||
|
|
||||||
const VType* peek_type(void) const { return type_; }
|
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);
|
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||||
|
|
||||||
void dump(ostream&out, int indent = 0) const;
|
void dump(ostream&out, int indent = 0) const;
|
||||||
|
|
@ -42,9 +46,16 @@ class Signal : public LineInfo {
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
const VType*type_;
|
const VType*type_;
|
||||||
|
|
||||||
|
unsigned refcnt_sequ_;
|
||||||
|
|
||||||
private: // Not implemented
|
private: // Not implemented
|
||||||
Signal(const Signal&);
|
Signal(const Signal&);
|
||||||
Signal& operator = (const Signal&);
|
Signal& operator = (const Signal&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void Signal::count_ref_sequ()
|
||||||
|
{
|
||||||
|
refcnt_sequ_ += 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue