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"
|
||||
|
||||
discipline_t::discipline_t(perm_string name, ddomain_t domain)
|
||||
: name_(name), domain_(domain)
|
||||
nature_t::nature_t(perm_string name, perm_string access)
|
||||
: 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;
|
||||
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 {
|
||||
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();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
ddomain_t domain() const { return domain_; }
|
||||
perm_string name() const { return name_; }
|
||||
ddomain_t domain() const { return domain_; }
|
||||
const nature_t*potential() const { return potential_; }
|
||||
const nature_t*flow() const { return flow_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
5
main.cc
5
main.cc
|
|
@ -684,6 +684,11 @@ int main(int argc, char*argv[])
|
|||
|
||||
if (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;
|
||||
for (map<perm_string,discipline_t*>::iterator cur = disciplines.begin()
|
||||
; cur != disciplines.end() ; cur ++ ) {
|
||||
|
|
|
|||
11
parse.y
11
parse.y
|
|
@ -686,18 +686,21 @@ discipline_items
|
|||
|
||||
discipline_item
|
||||
: K_domain K_discrete ';'
|
||||
{ pform_discipline_domain(@1, DD_DISCRETE); }
|
||||
| K_domain K_continuous ';'
|
||||
{ pform_discipline_domain(@1, DD_CONTINUOUS); }
|
||||
| K_potential IDENTIFIER ';'
|
||||
{ delete[] $2; }
|
||||
{ pform_discipline_potential(@1, $2); delete[] $2; }
|
||||
| K_flow IDENTIFIER ';'
|
||||
{ delete[] $2; }
|
||||
{ pform_discipline_flow(@1, $2); delete[] $2; }
|
||||
;
|
||||
|
||||
nature_declaration
|
||||
: K_nature IDENTIFIER ';'
|
||||
{ pform_start_nature($2); }
|
||||
nature_items
|
||||
K_endnature
|
||||
{ delete[] $2; }
|
||||
{ pform_end_nature(@1); delete[] $2; }
|
||||
;
|
||||
|
||||
nature_items
|
||||
|
|
@ -710,7 +713,7 @@ nature_item
|
|||
{ delete[] $3; }
|
||||
| K_abstol '=' expression ';'
|
||||
| K_access '=' IDENTIFIER ';'
|
||||
{ delete[] $3; }
|
||||
{ pform_nature_access(@1, $3); delete[] $3; }
|
||||
| K_idt_nature '=' IDENTIFIER ';'
|
||||
{ delete[] $3; }
|
||||
| K_ddt_nature '=' IDENTIFIER ';'
|
||||
|
|
|
|||
13
pform.h
13
pform.h
|
|
@ -30,6 +30,7 @@
|
|||
# include "PUdp.h"
|
||||
# include "PWire.h"
|
||||
# include "verinum.h"
|
||||
# include "discipline.h"
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
# include <list>
|
||||
|
|
@ -364,12 +365,22 @@ extern void pform_error_nested_modules();
|
|||
*/
|
||||
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_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,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -23,10 +23,58 @@
|
|||
# include "parse_misc.h"
|
||||
# include "discipline.h"
|
||||
|
||||
map<perm_string,nature_t*> natures;
|
||||
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 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)
|
||||
{
|
||||
|
|
@ -34,9 +82,72 @@ void pform_start_discipline(const char*name)
|
|||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
FILE_NAME(tmp, loc);
|
||||
|
|
@ -44,6 +155,8 @@ void pform_end_discipline(const struct vlltype&loc)
|
|||
/* Clear the static variables for the next item. */
|
||||
discipline_name = perm_string::perm_string();
|
||||
discipline_domain = DD_NONE;
|
||||
discipline_potential = 0;
|
||||
discipline_flow = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1149,9 +1149,20 @@ void PUdp::dump(ostream&out) const
|
|||
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 << " 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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue