Attach disciplines to wires

Allow discipline declaration of nets that attaches the discipline to
a new wire or a wire that is already declared.
This commit is contained in:
Stephen Williams 2008-05-11 17:30:33 -07:00
parent a506a18970
commit 93b400c4d7
6 changed files with 85 additions and 53 deletions

View File

@ -30,7 +30,7 @@ PWire::PWire(perm_string n,
signed_(false), isint_(false), signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false), port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0), net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
lidx_(0), ridx_(0) lidx_(0), ridx_(0), discipline_(0)
{ {
if (t == NetNet::INTEGER) { if (t == NetNet::INTEGER) {
type_ = NetNet::REG; type_ = NetNet::REG;
@ -135,19 +135,6 @@ bool PWire::get_isint() const
return isint_; return isint_;
} }
/*
* Since implicitly defined list of port declarations are no longer
* considered fully defined we no longer need this routine to force
* them to be fully defined.
*
void PWire::set_net_range()
{
net_msb_ = port_msb_;
net_lsb_ = port_lsb_;
net_set_ = true;
}
*/
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type) void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
{ {
switch (type) { switch (type) {
@ -211,3 +198,13 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
} }
} }
void PWire::set_discipline(discipline_t*d)
{
assert(discipline_ == 0);
discipline_ = d;
}
discipline_t* PWire::get_discipline(void) const
{
return discipline_;
}

View File

@ -36,6 +36,7 @@ class ostream;
class PExpr; class PExpr;
class Design; class Design;
class discipline_t;
/* /*
* The different type of PWire::set_range() calls. * The different type of PWire::set_range() calls.
@ -78,10 +79,12 @@ class PWire : public LineInfo {
ivl_variable_type_t get_data_type() const; ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb, PWSRType type); void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_net_range();
void set_memory_idx(PExpr*ldx, PExpr*rdx); void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(discipline_t*);
discipline_t* get_discipline(void) const;
map<perm_string,PExpr*> attributes; map<perm_string,PExpr*> attributes;
// Write myself to the specified stream. // Write myself to the specified stream.
@ -112,6 +115,8 @@ class PWire : public LineInfo {
PExpr*lidx_; PExpr*lidx_;
PExpr*ridx_; PExpr*ridx_;
discipline_t*discipline_;
private: // not implemented private: // not implemented
PWire(const PWire&); PWire(const PWire&);
PWire& operator= (const PWire&); PWire& operator= (const PWire&);

View File

@ -131,7 +131,7 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block; return block;
} }
static PWire*get_wire_in_scope(perm_string name) PWire*pform_get_wire_in_scope(perm_string name)
{ {
/* Note that if we are processing a generate, then the /* Note that if we are processing a generate, then the
scope depth will be empty because generate schemes scope depth will be empty because generate schemes
@ -919,7 +919,7 @@ static void pform_set_net_range(perm_string name,
ivl_variable_type_t dt, ivl_variable_type_t dt,
PWSRType rt) PWSRType rt)
{ {
PWire*cur = get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) { if (cur == 0) {
VLerror("error: name is not a valid net."); VLerror("error: name is not a valid net.");
return; return;
@ -1338,7 +1338,7 @@ void pform_makewire(const vlltype&li, perm_string name,
ivl_variable_type_t dt, ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr) svector<named_pexpr_t*>*attr)
{ {
PWire*cur = get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
// If this is not implicit ("implicit" meaning we don't know // If this is not implicit ("implicit" meaning we don't know
// what the type is yet) then set the type now. // what the type is yet) then set the type now.
@ -1452,7 +1452,7 @@ void pform_makewire(const vlltype&li,
SR_NET); SR_NET);
} }
PWire*cur = get_wire_in_scope(first->name); PWire*cur = pform_get_wire_in_scope(first->name);
if (cur != 0) { if (cur != 0) {
PEIdent*lval = new PEIdent(first->name); PEIdent*lval = new PEIdent(first->name);
FILE_NAME(lval, li.text, li.first_line); FILE_NAME(lval, li.text, li.first_line);

View File

@ -121,6 +121,13 @@ extern void pform_set_default_nettype(NetNet::Type net,
const char*file, const char*file,
unsigned lineno); unsigned lineno);
/*
* Look for the given wire in the current lexical scope. If the wire
* (including variables of any type) cannot be found in the current
* scope, then return 0.
*/
extern PWire* pform_get_wire_in_scope(perm_string name);
/* /*
* The parser uses startmodule and endmodule together to build up a * The parser uses startmodule and endmodule together to build up a
* module as it parses it. The startmodule tells the pform code that a * module as it parses it. The startmodule tells the pform code that a

View File

@ -47,45 +47,36 @@ void pform_end_discipline(const struct vlltype&loc)
} }
/* /*
* The parser uses this function to attach a discipline to a declared wire. * The parser uses this function to attach a discipline to a wire. The
* wire may be declared by now, or will be declared further later. If
* it is already declared, we just attach the discipline. If it is not
* declared yet, then this is the declaration and we create the signal
* in the current lexical scope.
*/ */
void pform_attach_discipline(const struct vlltype&loc, void pform_attach_discipline(const struct vlltype&loc,
discipline_t*discipline, list<perm_string>*names) discipline_t*discipline, list<perm_string>*names)
{ {
error_count += 1;
cerr << yylloc.text << ";" << yylloc.first_line << ": sorry: "
<< "Net discipline declarations not supported." << endl;
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; cur ++ ) { ; cur != names->end() ; cur ++ ) {
cerr << yylloc.text << ";" << yylloc.first_line << ": : "
<< "discipline=" << discipline->name() PWire* cur_net = pform_get_wire_in_scope(*cur);
<< ", net=" << *cur << endl; if (cur_net == 0) {
/* Not declared yet, declare it now. */
pform_makewire(loc, *cur, NetNet::WIRE,
NetNet::NOT_A_PORT, IVL_VT_REAL, 0);
cur_net = pform_get_wire_in_scope(*cur);
assert(cur_net);
}
if (discipline_t*tmp = cur_net->get_discipline()) {
cerr << loc.text << ":" << loc.first_line << ": error: "
<< "discipline " << discipline->name()
<< " cannot override existing discipline " << tmp->name()
<< " on net " << cur_net->basename() << endl;
error_count += 1;
} else {
cur_net->set_discipline(discipline);
}
} }
} }
void pform_dump(std::ostream&out, discipline_t*dis)
{
out << "discipline " << dis->name() << endl;
out << " domain " << dis->domain() << ";" << endl;
out << "enddiscipline" << endl;
}
std::ostream& operator << (std::ostream&out, ddomain_t dom)
{
switch (dom) {
case DD_NONE:
out << "no-domain";
break;
case DD_DISCRETE:
out << "discrete";
break;
case DD_CONTINUOUS:
out << "continuous";
break;
default:
assert(0);
break;
}
return out;
}

View File

@ -29,6 +29,7 @@
# include "PEvent.h" # include "PEvent.h"
# include "PGenerate.h" # include "PGenerate.h"
# include "PSpec.h" # include "PSpec.h"
# include "discipline.h"
# include <iostream> # include <iostream>
# include <iomanip> # include <iomanip>
# include <typeinfo> # include <typeinfo>
@ -128,6 +129,26 @@ ostream& operator<< (ostream&o, const pform_name_t&that)
return o; return o;
} }
std::ostream& operator << (std::ostream&out, ddomain_t dom)
{
switch (dom) {
case DD_NONE:
out << "no-domain";
break;
case DD_DISCRETE:
out << "discrete";
break;
case DD_CONTINUOUS:
out << "continuous";
break;
default:
assert(0);
break;
}
return out;
}
void PExpr::dump(ostream&out) const void PExpr::dump(ostream&out) const
{ {
out << typeid(*this).name(); out << typeid(*this).name();
@ -300,6 +321,10 @@ void PWire::dump(ostream&out, unsigned ind) const
out << " signed"; out << " signed";
} }
if (discipline_) {
out << " discipline<" << discipline_->name() << ">";
}
if (port_set_) { if (port_set_) {
if (port_msb_ == 0) { if (port_msb_ == 0) {
out << " port<scalar>"; out << " port<scalar>";
@ -1123,3 +1148,10 @@ void PUdp::dump(ostream&out) const
out << "endprimitive" << endl; out << "endprimitive" << endl;
} }
void pform_dump(std::ostream&out, discipline_t*dis)
{
out << "discipline " << dis->name() << endl;
out << " domain " << dis->domain() << ";" << endl;
out << "enddiscipline" << endl;
}