1 #ifndef IVL_pform_types_H
2 #define IVL_pform_types_H
3 /*
4  * Copyright (c) 2007-2019 Stephen Williams (steve@icarus.com)
5  *
6  *    This source code is free software; you can redistribute it
7  *    and/or modify it in source code form under the terms of the GNU
8  *    General Public License as published by the Free Software
9  *    Foundation; either version 2 of the License, or (at your option)
10  *    any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with this program; if not, write to the Free Software
19  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 // This for the perm_string type.
23 # include  "StringHeap.h"
24 # include  "PNamedItem.h"
25 # include  "verinum.h"
26 # include  "named.h"
27 # include  "netstruct.h"
28 # include  "property_qual.h"
29 # include  "ivl_target.h"
30 # include  <iostream>
31 # include  <list>
32 # include  <vector>
33 # include  <map>
34 # include  <memory>
35 
36 #if __cplusplus < 201103L
37 #define unique_ptr auto_ptr
38 #endif
39 
40 /*
41  * parse-form types.
42  */
43 
44 class Design;
45 class NetScope;
46 class Definitions;
47 class PExpr;
48 class PWire;
49 class Statement;
50 class ivl_type_s;
51 class netclass_t;
52 class netenum_t;
53 typedef named<verinum> named_number_t;
54 typedef named<PExpr*> named_pexpr_t;
55 
56 /*
57  * The pform_range_t holds variable dimensions for type
58  * declarations. The two expressions are interpreted as the first and
59  * last values of the range. For example:
60  *
61  *   [<expr1> : <expr2>]  -- Normal array range
62  *       first == <expr1>
63  *       second = <expr2>
64  *
65  *   [<expr>] -- SystemVerilog canonical range
66  *       first = PENumber(0)
67  *       second = <expr> - 1;
68  *
69  *   [ ] -- Dynamic array
70  *       first = 0
71  *       second = 0
72  *
73  *   [ $ ] -- Queue type
74  *       first = PENull
75  *       second = 0
76  */
77 typedef std::pair<PExpr*,PExpr*> pform_range_t;
78 
79 /*
80  * The pform_port_t holds the name and optional unpacked dimensions
81  * and initialization expression for a single port in a list of port
82  * declarations.
83  */
84 struct pform_port_t {
pform_port_tpform_port_t85       pform_port_t(perm_string n, list<pform_range_t>*ud, PExpr*e)
86 	: name(n), udims(ud), expr(e) { }
~pform_port_tpform_port_t87       ~pform_port_t() { }
88 
89       perm_string name;
90       list<pform_range_t>*udims;
91       PExpr*expr;
92 };
93 
94 /*
95  * Semantic NOTES:
96  * - The SEL_BIT is a single expression. This might me a bit select
97  * of a vector, or a word select of an array.
98  *
99  * - The SEL_BIT_LAST index component is an array/queue [$] index,
100  * that is the last item in the variable.
101  */
102 struct index_component_t {
103       enum ctype_t { SEL_NONE, SEL_BIT, SEL_BIT_LAST, SEL_PART, SEL_IDX_UP, SEL_IDX_DO };
104 
index_component_tindex_component_t105       index_component_t() : sel(SEL_NONE), msb(0), lsb(0) { };
~index_component_tindex_component_t106       ~index_component_t() { }
107 
108       ctype_t sel;
109       class PExpr*msb;
110       class PExpr*lsb;
111 };
112 
113 struct name_component_t {
name_component_tname_component_t114       explicit name_component_t(perm_string n) : name(n) { }
~name_component_tname_component_t115       ~name_component_t() { }
116 
117       perm_string name;
118       std::list<index_component_t>index;
119 };
120 
121 struct decl_assignment_t {
122       perm_string name;
123       std::list<pform_range_t>index;
124       std::unique_ptr<PExpr> expr;
125 };
126 
127 struct pform_tf_port_t {
128       PWire*port;
129       PExpr*defe;
130 
pform_tf_port_tpform_tf_port_t131       inline pform_tf_port_t() : port(0), defe(0) { }
pform_tf_port_tpform_tf_port_t132       inline explicit pform_tf_port_t(PWire*p) : port(p), defe(0) { }
133 };
134 
135 /*
136  * This is the base class for data types that are matched by the
137  * "data_type" rule in the parse rule. We make the type virtual so
138  * that dynamic types will work.
139  */
140 class data_type_t : public PNamedItem {
141     public:
data_type_t()142       inline explicit data_type_t() { }
143       virtual ~data_type_t() = 0;
144 	// This method is used to figure out the base type of a packed
145 	// compound object. Return IVL_VT_NO_TYPE if the type is not packed.
146       virtual ivl_variable_type_t figure_packed_base_type(void)const;
147 	// This method is used by the pform dumper to diagnostic dump.
148       virtual void pform_dump(std::ostream&out, unsigned indent) const;
149 
150       ivl_type_s* elaborate_type(Design*des, NetScope*scope);
151 
152       virtual SymbolType symbol_type() const;
153 
154       perm_string name;
155 
156     private:
157 	// Elaborate the type to an ivl_type_s type.
158       virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
159 
160 	// Keep per-scope elaboration results cached.
161       std::map<Definitions*,ivl_type_s*> cache_type_elaborate_;
162 };
163 
164 struct void_type_t : public data_type_t {
165       virtual void pform_dump(std::ostream&out, unsigned indent) const;
166 };
167 
168 /*
169  * The enum_type_t holds the parsed declaration to represent an
170  * enumeration. Since this is in the pform, it represents the type
171  * before elaboration so the range, for example, may not be complete
172  * until it is elaborated in a scope.
173  */
174 struct enum_type_t : public data_type_t {
175 	// Return the elaborated version of the type.
176       virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
177 
178       SymbolType symbol_type() const;
179 
180       ivl_variable_type_t base_type;
181       bool signed_flag;
182       bool integer_flag; // True if "integer" was used
183       std::unique_ptr< list<pform_range_t> > range;
184       std::unique_ptr< list<named_pexpr_t> > names;
185       LineInfo li;
186 };
187 
188 struct struct_member_t : public LineInfo {
189       std::unique_ptr<data_type_t> type;
190       std::unique_ptr< list<decl_assignment_t*> > names;
191       void pform_dump(std::ostream&out, unsigned indent) const;
192 };
193 
194 struct struct_type_t : public data_type_t {
195       virtual ivl_variable_type_t figure_packed_base_type(void)const;
196       virtual void pform_dump(std::ostream&out, unsigned indent) const;
197       virtual netstruct_t* elaborate_type_raw(Design*des, NetScope*scope) const;
198 
199       bool packed_flag;
200       bool union_flag;
201       std::unique_ptr< list<struct_member_t*> > members;
202 };
203 
204 struct atom2_type_t : public data_type_t {
atom2_type_tatom2_type_t205       inline explicit atom2_type_t(int tc, bool flag)
206       : type_code(tc), signed_flag(flag) { }
207       int type_code;
208       bool signed_flag;
209 
210       ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
211 };
212 
213 extern atom2_type_t size_type;
214 
215 /*
216  * The vector_type_t class represents types in the old Verilog
217  * way. Some typical examples:
218  *
219  *   logic signed [7:0] foo
220  *   bit unsigned foo
221  *   reg foo
222  *
223  * There are a few special cases:
224  *
225  * For the most part, Verilog treats "logic" and "reg" as synonyms,
226  * but there are a few cases where the parser needs to know the
227  * difference. So "reg_flag" is set to true if the IVL_VT_LOGIC type
228  * is due to the "reg" keyword.
229  *
230  * If there are no reg/logic/bit/bool keywords, then Verilog will
231  * assume the type is logic, but the context may need to know about
232  * this case, so the implicit_flag member is set to true in that case.
233  */
234 struct vector_type_t : public data_type_t {
vector_type_tvector_type_t235       inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
236 				    std::list<pform_range_t>*pd)
237       : base_type(bt), signed_flag(sf), reg_flag(false), integer_flag(false), implicit_flag(false), pdims(pd) { }
238       virtual ivl_variable_type_t figure_packed_base_type(void)const;
239       virtual void pform_dump(std::ostream&out, unsigned indent) const;
240       ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
241 
242       ivl_variable_type_t base_type;
243       bool signed_flag;
244       bool reg_flag; // True if "reg" was used
245       bool integer_flag; // True if "integer" was used
246       bool implicit_flag; // True if this type is implicitly logic/reg
247       std::unique_ptr< list<pform_range_t> > pdims;
248 };
249 
250 struct array_base_t : public data_type_t {
251     public:
array_base_tarray_base_t252       inline explicit array_base_t(data_type_t*btype, std::list<pform_range_t>*pd)
253       : base_type(btype), dims(pd) { }
254 
255       data_type_t*base_type;
256       std::unique_ptr< list<pform_range_t> > dims;
257 };
258 
259 /*
260  * The parray_type_t is a generalization of the vector_type_t in that
261  * the base type is another general data type. Ultimately, the subtype
262  * must also be packed (as this is a packed array) but that may be
263  * worked out during elaboration.
264  */
265 struct parray_type_t : public array_base_t {
parray_type_tparray_type_t266       inline explicit parray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
267       : array_base_t(btype, pd) { }
268 
269       virtual ivl_variable_type_t figure_packed_base_type(void)const;
270       virtual void pform_dump(std::ostream&out, unsigned indent) const;
271       virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
272 };
273 
274 /*
275  * The uarray_type_t represents unpacked array types.
276  */
277 struct uarray_type_t : public array_base_t {
uarray_type_tuarray_type_t278       inline explicit uarray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
279       : array_base_t(btype, pd) { }
280 
281     public:
282       virtual void pform_dump(std::ostream&out, unsigned indent) const;
283       virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
284 };
285 
286 struct real_type_t : public data_type_t {
287       enum type_t { REAL, SHORTREAL };
real_type_treal_type_t288       inline explicit real_type_t(type_t tc) : type_code(tc) { }
289       type_t type_code;
290 
291       ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
292 };
293 
294 struct string_type_t : public data_type_t {
string_type_tstring_type_t295       inline explicit string_type_t() { }
296       ~string_type_t();
297 
298       ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
299 };
300 
301 struct class_type_t : public data_type_t {
302 
class_type_tclass_type_t303       inline explicit class_type_t(perm_string n)
304       : base_type(0), save_elaborated_type(0) { name = n; }
305 
306       void pform_dump(std::ostream&out, unsigned indent) const;
307       void pform_dump_init(std::ostream&out, unsigned indent) const;
308 
309 	// This is the named type that is supposed to be the base
310 	// class that we are extending. This is nil if there is no
311 	// hierarchy. If there are arguments to the base class, then
312 	// put them in the base_args vector.
313       data_type_t*base_type;
314       std::list<PExpr*>base_args;
315 
316 	// This is a map of the properties. Map the name to the type.
317       struct prop_info_t {
prop_info_tclass_type_t::prop_info_t318 	    inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { }
prop_info_tclass_type_t::prop_info_t319 	    inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { }
320 	    property_qualifier_t qual;
321 	    data_type_t* type;
322       };
323       std::map<perm_string, struct prop_info_t> properties;
324 
325 	// This is an ordered list of property initializers. The name
326 	// is the name of the property to be assigned, and the val is
327 	// the expression that is assigned.
328       std::vector<Statement*> initialize;
329 
330 	// This is an ordered list of property initializers for static
331 	// properties. These are run in a synthetic "initial" block
332 	// without waiting for any constructor.
333       std::vector<Statement*> initialize_static;
334 
335       ivl_type_s* elaborate_type_raw(Design*, NetScope*) const;
336 	// The save_elaborated_type member must be set to the pointer
337 	// to the netclass_t object that is created to represent this
338 	// type. The elaborate_type_raw() method uses this pointer,
339 	// and it is used in some other situations as well.
340       netclass_t* save_elaborated_type;
341 
342       virtual SymbolType symbol_type() const;
343 };
344 
345 /*
346  * The pform_name_t is the general form for a hierarchical
347  * identifier. It is an ordered list of name components. Each name
348  * component is an identifier and an optional list of bit/part
349  * selects. The simplest name component is a simple identifier:
350  *
351  *    foo
352  *
353  * The bit/part selects come from the source and are made part of the
354  * name component. A bit select is a single number that may be a bit
355  * select of a vector or a word select of an array:
356  *
357  *    foo[5]     -- a bit select/word index
358  *    foo[6:4]   -- a part select
359  *
360  * The index components of a name component are collected into an
361  * ordered list, so there may be many, for example:
362  *
363  *    foo[5][6:4] -- a part select of an array word
364  *
365  * The pform_name_t, then, is an ordered list of these name
366  * components. The list of names comes from a hierarchical name in the
367  * source, like this:
368  *
369  *    foo[5].bar[6:4]  -- a part select of a vector in sub-scope foo[5].
370  */
371 typedef std::list<name_component_t> pform_name_t;
372 
373 
peek_head_name(const pform_name_t & that)374 inline perm_string peek_head_name(const pform_name_t&that)
375 {
376       return that.front().name;
377 }
378 
peek_tail_name(const pform_name_t & that)379 inline perm_string peek_tail_name(const pform_name_t&that)
380 {
381       return that.back().name;
382 }
383 
384 extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
385 extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
386 extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
387 
388 #if __cplusplus < 201103L
389 #undef unique_ptr
390 #endif
391 
392 #endif /* IVL_pform_types_H */
393