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:
parent
a506a18970
commit
93b400c4d7
25
PWire.cc
25
PWire.cc
|
|
@ -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_;
|
||||
}
|
||||
|
|
|
|||
7
PWire.h
7
PWire.h
|
|
@ -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&);
|
||||
|
|
|
|||
8
pform.cc
8
pform.cc
|
|
@ -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);
|
||||
|
|
|
|||
7
pform.h
7
pform.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue