Attach natures to disciplines
Pform parse enough of the natures that they can be mapped and the disciplines can bind to them. Since Verilog-AMS expects natures to be declared before use, we can do the binding early.
This commit is contained in:
parent
93b400c4d7
commit
7166aea1d7
|
|
@ -19,8 +19,18 @@
|
||||||
|
|
||||||
# include "discipline.h"
|
# include "discipline.h"
|
||||||
|
|
||||||
discipline_t::discipline_t(perm_string name, ddomain_t domain)
|
nature_t::nature_t(perm_string name, perm_string access)
|
||||||
: name_(name), domain_(domain)
|
: name_(name), access_(access)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nature_t::~nature_t()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
discipline_t::discipline_t(perm_string name, ddomain_t domain,
|
||||||
|
nature_t*pot, nature_t*flow)
|
||||||
|
: name_(name), domain_(domain), potential_(pot), flow_(flow)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
30
discipline.h
30
discipline.h
|
|
@ -33,19 +33,43 @@
|
||||||
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
|
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
|
||||||
extern std::ostream& operator << (std::ostream&, ddomain_t);
|
extern std::ostream& operator << (std::ostream&, ddomain_t);
|
||||||
|
|
||||||
|
class nature_t : public LineInfo {
|
||||||
|
public:
|
||||||
|
explicit nature_t(perm_string name, perm_string access);
|
||||||
|
~nature_t();
|
||||||
|
|
||||||
|
perm_string name() const { return name_; }
|
||||||
|
// Identifier for the access function for this nature
|
||||||
|
perm_string access() const { return access_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string name_;
|
||||||
|
perm_string access_;
|
||||||
|
};
|
||||||
|
|
||||||
class discipline_t : public LineInfo {
|
class discipline_t : public LineInfo {
|
||||||
public:
|
public:
|
||||||
explicit discipline_t (perm_string name, ddomain_t dom);
|
explicit discipline_t (perm_string name, ddomain_t dom,
|
||||||
|
nature_t*pot, nature_t*flow);
|
||||||
~discipline_t();
|
~discipline_t();
|
||||||
|
|
||||||
perm_string name() const { return name_; }
|
perm_string name() const { return name_; }
|
||||||
ddomain_t domain() const { return domain_; }
|
ddomain_t domain() const { return domain_; }
|
||||||
|
const nature_t*potential() const { return potential_; }
|
||||||
|
const nature_t*flow() const { return flow_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
ddomain_t domain_;
|
ddomain_t domain_;
|
||||||
|
nature_t*potential_;
|
||||||
|
nature_t*flow_;
|
||||||
|
|
||||||
|
private: // not implemented
|
||||||
|
discipline_t(const discipline_t&);
|
||||||
|
discipline_t& operator = (const discipline_t&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern map<perm_string,nature_t*> natures;
|
||||||
extern map<perm_string,discipline_t*> disciplines;
|
extern map<perm_string,discipline_t*> disciplines;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
5
main.cc
5
main.cc
|
|
@ -684,6 +684,11 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
if (pf_path) {
|
if (pf_path) {
|
||||||
ofstream out (pf_path);
|
ofstream out (pf_path);
|
||||||
|
out << "PFORM DUMP NATURES:" << endl;
|
||||||
|
for (map<perm_string,nature_t*>::iterator cur = natures.begin()
|
||||||
|
; cur != natures.end() ; cur ++ ) {
|
||||||
|
pform_dump(out, (*cur).second);
|
||||||
|
}
|
||||||
out << "PFORM DUMP DISCIPLINES:" << endl;
|
out << "PFORM DUMP DISCIPLINES:" << endl;
|
||||||
for (map<perm_string,discipline_t*>::iterator cur = disciplines.begin()
|
for (map<perm_string,discipline_t*>::iterator cur = disciplines.begin()
|
||||||
; cur != disciplines.end() ; cur ++ ) {
|
; cur != disciplines.end() ; cur ++ ) {
|
||||||
|
|
|
||||||
11
parse.y
11
parse.y
|
|
@ -686,18 +686,21 @@ discipline_items
|
||||||
|
|
||||||
discipline_item
|
discipline_item
|
||||||
: K_domain K_discrete ';'
|
: K_domain K_discrete ';'
|
||||||
|
{ pform_discipline_domain(@1, DD_DISCRETE); }
|
||||||
| K_domain K_continuous ';'
|
| K_domain K_continuous ';'
|
||||||
|
{ pform_discipline_domain(@1, DD_CONTINUOUS); }
|
||||||
| K_potential IDENTIFIER ';'
|
| K_potential IDENTIFIER ';'
|
||||||
{ delete[] $2; }
|
{ pform_discipline_potential(@1, $2); delete[] $2; }
|
||||||
| K_flow IDENTIFIER ';'
|
| K_flow IDENTIFIER ';'
|
||||||
{ delete[] $2; }
|
{ pform_discipline_flow(@1, $2); delete[] $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
nature_declaration
|
nature_declaration
|
||||||
: K_nature IDENTIFIER ';'
|
: K_nature IDENTIFIER ';'
|
||||||
|
{ pform_start_nature($2); }
|
||||||
nature_items
|
nature_items
|
||||||
K_endnature
|
K_endnature
|
||||||
{ delete[] $2; }
|
{ pform_end_nature(@1); delete[] $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
nature_items
|
nature_items
|
||||||
|
|
@ -710,7 +713,7 @@ nature_item
|
||||||
{ delete[] $3; }
|
{ delete[] $3; }
|
||||||
| K_abstol '=' expression ';'
|
| K_abstol '=' expression ';'
|
||||||
| K_access '=' IDENTIFIER ';'
|
| K_access '=' IDENTIFIER ';'
|
||||||
{ delete[] $3; }
|
{ pform_nature_access(@1, $3); delete[] $3; }
|
||||||
| K_idt_nature '=' IDENTIFIER ';'
|
| K_idt_nature '=' IDENTIFIER ';'
|
||||||
{ delete[] $3; }
|
{ delete[] $3; }
|
||||||
| K_ddt_nature '=' IDENTIFIER ';'
|
| K_ddt_nature '=' IDENTIFIER ';'
|
||||||
|
|
|
||||||
13
pform.h
13
pform.h
|
|
@ -30,6 +30,7 @@
|
||||||
# include "PUdp.h"
|
# include "PUdp.h"
|
||||||
# include "PWire.h"
|
# include "PWire.h"
|
||||||
# include "verinum.h"
|
# include "verinum.h"
|
||||||
|
# include "discipline.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <string>
|
# include <string>
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -364,12 +365,22 @@ extern void pform_error_nested_modules();
|
||||||
*/
|
*/
|
||||||
class discipline_t;
|
class discipline_t;
|
||||||
|
|
||||||
|
extern void pform_start_nature(const char*name);
|
||||||
|
extern void pform_end_nature(const struct vlltype&loc);
|
||||||
|
|
||||||
|
extern void pform_nature_access(const struct vlltype&loc, const char*name);
|
||||||
|
|
||||||
extern void pform_start_discipline(const char*name);
|
extern void pform_start_discipline(const char*name);
|
||||||
extern void pform_end_discipline(const struct vlltype&loc);
|
extern void pform_end_discipline(const struct vlltype&loc);
|
||||||
|
|
||||||
|
extern void pform_discipline_domain(const struct vlltype&loc, ddomain_t use_domain);
|
||||||
|
extern void pform_discipline_potential(const struct vlltype&loc, const char*name);
|
||||||
|
extern void pform_discipline_flow(const struct vlltype&loc, const char*name);
|
||||||
|
|
||||||
extern void pform_attach_discipline(const struct vlltype&loc,
|
extern void pform_attach_discipline(const struct vlltype&loc,
|
||||||
discipline_t*discipline, list<perm_string>*names);
|
discipline_t*discipline, list<perm_string>*names);
|
||||||
|
|
||||||
extern void pform_dump(ostream&out, discipline_t*);
|
extern void pform_dump(ostream&out, const nature_t*);
|
||||||
|
extern void pform_dump(ostream&out, const discipline_t*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,58 @@
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
# include "discipline.h"
|
# include "discipline.h"
|
||||||
|
|
||||||
|
map<perm_string,nature_t*> natures;
|
||||||
map<perm_string,discipline_t*> disciplines;
|
map<perm_string,discipline_t*> disciplines;
|
||||||
|
|
||||||
|
static perm_string nature_name = perm_string::perm_string();
|
||||||
|
static perm_string nature_access = perm_string::perm_string();
|
||||||
|
|
||||||
|
void pform_start_nature(const char*name)
|
||||||
|
{
|
||||||
|
nature_name = lex_strings.make(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pform_nature_access(const struct vlltype&loc, const char*name)
|
||||||
|
{
|
||||||
|
if (nature_access) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "Too many access names for nature "
|
||||||
|
<< nature_name << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nature_access = lex_strings.make(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pform_end_nature(const struct vlltype&loc)
|
||||||
|
{
|
||||||
|
// The nature access function is required. If it is missing,
|
||||||
|
// then signal an error. For a temporary expedient, we can set
|
||||||
|
// the nature name as the access function, but don't expect it
|
||||||
|
// to work.
|
||||||
|
if (! nature_access) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "Missing access name for nature "
|
||||||
|
<< nature_name << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
nature_access = nature_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
nature_t*tmp = new nature_t(nature_name, nature_access);
|
||||||
|
natures[nature_name] = tmp;
|
||||||
|
|
||||||
|
FILE_NAME(tmp, loc);
|
||||||
|
|
||||||
|
nature_name = perm_string::perm_string();
|
||||||
|
nature_access = perm_string::perm_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static perm_string discipline_name;
|
static perm_string discipline_name;
|
||||||
static ddomain_t discipline_domain = DD_NONE;
|
static ddomain_t discipline_domain = DD_NONE;
|
||||||
|
static nature_t* discipline_potential = 0;
|
||||||
|
static nature_t* discipline_flow = 0;
|
||||||
|
|
||||||
void pform_start_discipline(const char*name)
|
void pform_start_discipline(const char*name)
|
||||||
{
|
{
|
||||||
|
|
@ -34,9 +82,72 @@ void pform_start_discipline(const char*name)
|
||||||
discipline_domain = DD_NONE;
|
discipline_domain = DD_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_discipline_domain(const struct vlltype&loc, ddomain_t use_domain)
|
||||||
|
{
|
||||||
|
assert(use_domain != DD_NONE);
|
||||||
|
|
||||||
|
if (discipline_domain != DD_NONE) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "Too many domain attributes for discipline "
|
||||||
|
<< discipline_name << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
discipline_domain = use_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pform_discipline_potential(const struct vlltype&loc, const char*name)
|
||||||
|
{
|
||||||
|
if (discipline_potential) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "Too many potential natures for discipline "
|
||||||
|
<< discipline_name << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
perm_string key = lex_strings.make(name);
|
||||||
|
discipline_potential = natures[key];
|
||||||
|
|
||||||
|
if (discipline_potential == 0) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "nature " << key << " is not declared." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pform_discipline_flow(const struct vlltype&loc, const char*name)
|
||||||
|
{
|
||||||
|
if (discipline_flow) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "Too many flow natures for discipline "
|
||||||
|
<< discipline_name << "." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
perm_string key = lex_strings.make(name);
|
||||||
|
discipline_flow = natures[key];
|
||||||
|
|
||||||
|
if (discipline_flow == 0) {
|
||||||
|
cerr << loc.text << ":" << loc.first_line << ": error: "
|
||||||
|
<< "nature " << key << " is not declared." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pform_end_discipline(const struct vlltype&loc)
|
void pform_end_discipline(const struct vlltype&loc)
|
||||||
{
|
{
|
||||||
discipline_t*tmp = new discipline_t(discipline_name, discipline_domain);
|
// If the domain is not otherwise specified, then take it to
|
||||||
|
// be continuous if potential or flow natures are given.
|
||||||
|
if (discipline_domain == DD_NONE && discipline_potential||discipline_flow)
|
||||||
|
discipline_domain = DD_CONTINUOUS;
|
||||||
|
|
||||||
|
discipline_t*tmp = new discipline_t(discipline_name, discipline_domain,
|
||||||
|
discipline_potential, discipline_flow);
|
||||||
disciplines[discipline_name] = tmp;
|
disciplines[discipline_name] = tmp;
|
||||||
|
|
||||||
FILE_NAME(tmp, loc);
|
FILE_NAME(tmp, loc);
|
||||||
|
|
@ -44,6 +155,8 @@ void pform_end_discipline(const struct vlltype&loc)
|
||||||
/* Clear the static variables for the next item. */
|
/* Clear the static variables for the next item. */
|
||||||
discipline_name = perm_string::perm_string();
|
discipline_name = perm_string::perm_string();
|
||||||
discipline_domain = DD_NONE;
|
discipline_domain = DD_NONE;
|
||||||
|
discipline_potential = 0;
|
||||||
|
discipline_flow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1149,9 +1149,20 @@ void PUdp::dump(ostream&out) const
|
||||||
out << "endprimitive" << endl;
|
out << "endprimitive" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_dump(std::ostream&out, discipline_t*dis)
|
void pform_dump(std::ostream&out, const nature_t*nat)
|
||||||
|
{
|
||||||
|
out << "nature " << nat->name() << endl;
|
||||||
|
out << " access " << nat->access() << ";" << endl;
|
||||||
|
out << "endnature" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pform_dump(std::ostream&out, const discipline_t*dis)
|
||||||
{
|
{
|
||||||
out << "discipline " << dis->name() << endl;
|
out << "discipline " << dis->name() << endl;
|
||||||
out << " domain " << dis->domain() << ";" << endl;
|
out << " domain " << dis->domain() << ";" << endl;
|
||||||
|
if (const nature_t*tmp = dis->potential())
|
||||||
|
out << " potential " << tmp->name() << ";" << endl;
|
||||||
|
if (const nature_t*tmp = dis->flow())
|
||||||
|
out << " flow " << tmp->name() << ";" << endl;
|
||||||
out << "enddiscipline" << endl;
|
out << "enddiscipline" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue