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),
port_msb_(0), port_lsb_(0), port_set_(false),
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) {
type_ = NetNet::REG;
@ -135,19 +135,6 @@ bool PWire::get_isint() const
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)
{
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 Design;
class discipline_t;
/*
* The different type of PWire::set_range() calls.
@ -78,10 +79,12 @@ class PWire : public LineInfo {
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_net_range();
void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(discipline_t*);
discipline_t* get_discipline(void) const;
map<perm_string,PExpr*> attributes;
// Write myself to the specified stream.
@ -112,6 +115,8 @@ class PWire : public LineInfo {
PExpr*lidx_;
PExpr*ridx_;
discipline_t*discipline_;
private: // not implemented
PWire(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;
}
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
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,
PWSRType rt)
{
PWire*cur = get_wire_in_scope(name);
PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) {
VLerror("error: name is not a valid net.");
return;
@ -1338,7 +1338,7 @@ void pform_makewire(const vlltype&li, perm_string name,
ivl_variable_type_t dt,
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
// what the type is yet) then set the type now.
@ -1452,7 +1452,7 @@ void pform_makewire(const vlltype&li,
SR_NET);
}
PWire*cur = get_wire_in_scope(first->name);
PWire*cur = pform_get_wire_in_scope(first->name);
if (cur != 0) {
PEIdent*lval = new PEIdent(first->name);
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,
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
* 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,
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()
; cur != names->end() ; cur ++ ) {
cerr << yylloc.text << ";" << yylloc.first_line << ": : "
<< "discipline=" << discipline->name()
<< ", net=" << *cur << endl;
PWire* cur_net = pform_get_wire_in_scope(*cur);
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 "PGenerate.h"
# include "PSpec.h"
# include "discipline.h"
# include <iostream>
# include <iomanip>
# include <typeinfo>
@ -128,6 +129,26 @@ ostream& operator<< (ostream&o, const pform_name_t&that)
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
{
out << typeid(*this).name();
@ -300,6 +321,10 @@ void PWire::dump(ostream&out, unsigned ind) const
out << " signed";
}
if (discipline_) {
out << " discipline<" << discipline_->name() << ">";
}
if (port_set_) {
if (port_msb_ == 0) {
out << " port<scalar>";
@ -1123,3 +1148,10 @@ void PUdp::dump(ostream&out) const
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;
}