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),
|
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_;
|
||||||
|
}
|
||||||
|
|
|
||||||
7
PWire.h
7
PWire.h
|
|
@ -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&);
|
||||||
|
|
|
||||||
8
pform.cc
8
pform.cc
|
|
@ -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);
|
||||||
|
|
|
||||||
7
pform.h
7
pform.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue