2 * Copyright (c) 2008 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 # include "compiler.h"
23 # include "parse_misc.h"
24 # include "discipline.h"
26 map
<perm_string
,nature_t
*> natures
;
27 map
<perm_string
,discipline_t
*> disciplines
;
29 static perm_string nature_name
= perm_string::perm_string();
30 static perm_string nature_access
= perm_string::perm_string();
32 void pform_start_nature(const char*name
)
34 nature_name
= lex_strings
.make(name
);
37 void pform_nature_access(const struct vlltype
&loc
, const char*name
)
40 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
41 << "Too many access names for nature "
42 << nature_name
<< "." << endl
;
47 nature_access
= lex_strings
.make(name
);
50 void pform_end_nature(const struct vlltype
&loc
)
52 // The nature access function is required. If it is missing,
53 // then signal an error. For a temporary expedient, we can set
54 // the nature name as the access function, but don't expect it
56 if (! nature_access
) {
57 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
58 << "Missing access name for nature "
59 << nature_name
<< "." << endl
;
61 nature_access
= nature_name
;
64 nature_t
*tmp
= new nature_t(nature_name
, nature_access
);
65 natures
[nature_name
] = tmp
;
69 nature_name
= perm_string::perm_string();
70 nature_access
= perm_string::perm_string();
74 static perm_string discipline_name
;
75 static ddomain_t discipline_domain
= DD_NONE
;
76 static nature_t
* discipline_potential
= 0;
77 static nature_t
* discipline_flow
= 0;
79 void pform_start_discipline(const char*name
)
81 discipline_name
= lex_strings
.make(name
);
82 discipline_domain
= DD_NONE
;
85 void pform_discipline_domain(const struct vlltype
&loc
, ddomain_t use_domain
)
87 assert(use_domain
!= DD_NONE
);
89 if (discipline_domain
!= DD_NONE
) {
90 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
91 << "Too many domain attributes for discipline "
92 << discipline_name
<< "." << endl
;
97 discipline_domain
= use_domain
;
100 void pform_discipline_potential(const struct vlltype
&loc
, const char*name
)
102 if (discipline_potential
) {
103 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
104 << "Too many potential natures for discipline "
105 << discipline_name
<< "." << endl
;
110 perm_string key
= lex_strings
.make(name
);
111 discipline_potential
= natures
[key
];
113 if (discipline_potential
== 0) {
114 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
115 << "nature " << key
<< " is not declared." << endl
;
121 void pform_discipline_flow(const struct vlltype
&loc
, const char*name
)
123 if (discipline_flow
) {
124 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
125 << "Too many flow natures for discipline "
126 << discipline_name
<< "." << endl
;
131 perm_string key
= lex_strings
.make(name
);
132 discipline_flow
= natures
[key
];
134 if (discipline_flow
== 0) {
135 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
136 << "nature " << key
<< " is not declared." << endl
;
142 void pform_end_discipline(const struct vlltype
&loc
)
144 // If the domain is not otherwise specified, then take it to
145 // be continuous if potential or flow natures are given.
146 if (discipline_domain
== DD_NONE
&& (discipline_potential
||discipline_flow
))
147 discipline_domain
= DD_CONTINUOUS
;
149 discipline_t
*tmp
= new discipline_t(discipline_name
, discipline_domain
,
150 discipline_potential
, discipline_flow
);
151 disciplines
[discipline_name
] = tmp
;
155 /* Clear the static variables for the next item. */
156 discipline_name
= perm_string::perm_string();
157 discipline_domain
= DD_NONE
;
158 discipline_potential
= 0;
163 * The parser uses this function to attach a discipline to a wire. The
164 * wire may be declared by now, or will be declared further later. If
165 * it is already declared, we just attach the discipline. If it is not
166 * declared yet, then this is the declaration and we create the signal
167 * in the current lexical scope.
169 void pform_attach_discipline(const struct vlltype
&loc
,
170 discipline_t
*discipline
, list
<perm_string
>*names
)
172 for (list
<perm_string
>::iterator cur
= names
->begin()
173 ; cur
!= names
->end() ; cur
++ ) {
175 PWire
* cur_net
= pform_get_wire_in_scope(*cur
);
177 /* Not declared yet, declare it now. */
178 pform_makewire(loc
, *cur
, NetNet::WIRE
,
179 NetNet::NOT_A_PORT
, IVL_VT_REAL
, 0);
180 cur_net
= pform_get_wire_in_scope(*cur
);
184 if (discipline_t
*tmp
= cur_net
->get_discipline()) {
185 cerr
<< loc
.text
<< ":" << loc
.first_line
<< ": error: "
186 << "discipline " << discipline
->name()
187 << " cannot override existing discipline " << tmp
->name()
188 << " on net " << cur_net
->basename() << endl
;
192 cur_net
->set_discipline(discipline
);