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:
Stephen Williams 2008-05-11 18:52:27 -07:00
parent 93b400c4d7
commit 7166aea1d7
7 changed files with 189 additions and 12 deletions

View File

@ -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)
{
}

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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;
}
/*

View File

@ -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;
}