1 #ifndef IVL_PGenerate_H
2 #define IVL_PGenerate_H
3 /*
4  * Copyright (c) 2006-2020 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 # include  "PNamedItem.h"
23 # include  "StringHeap.h"
24 # include  "HName.h"
25 # include  "PScope.h"
26 # include  <list>
27 # include  <map>
28 # include  <valarray>
29 # include  "pform_types.h"
30 
31 class Design;
32 class NetScope;
33 class PExpr;
34 class PFunction;
35 class PProcess;
36 class PTask;
37 class PGate;
38 class PWire;
39 
40 /*
41  * This represents a generate scheme. The interpretation of the
42  * members depends on the scheme_type.
43  *
44  * GS_LOOP
45  *
46  * GS_CASE
47  *    loop_test is the expression to be compared.
48  *    generates contains only GS_CASE_ITEM schemes.
49  * GS_CASE_ITEM
50  *    The parent points to the GS_CASE that contains this item.
51  *    the loop_test is compared with the parent->loop_test expression.
52  */
53 class PGenerate : public PNamedItem, public LexicalScope {
54 
55     public:
56       explicit PGenerate(LexicalScope*parent, unsigned id_number);
57       ~PGenerate();
58 
59 	// Generate schemes have an ID number, for when the scope is
60 	// implicit.
61       const unsigned id_number;
62       perm_string scope_name;
63 
64 	// This is used during parsing to stack lexical scopes within
65 	// this generate scheme.
66 //      LexicalScope*lexical_scope;
67 
68       enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
69 		     GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
70       scheme_t scheme_type;
71 
72 	// generate loops have an index variable and three
73 	// expressions: for (index = <init>; <test>; index=<step>)
74 	// the index is local if it was declared in the init expression,
75 	// e.g. for (genvar index = <init>; <test>; index=<step>)
76       bool local_index;
77       perm_string loop_index;
78       PExpr*loop_init;
79       PExpr*loop_test;
80       PExpr*loop_step;
81 	// Case items may have multiple guard expression values. It is
82 	// enough for any on of the guards to match the case statement
83 	// test value.
84       std::valarray<PExpr*> item_test;
85 
86 	// defparam assignments found in this scope.
87       typedef pair<pform_name_t,PExpr*> named_expr_t;
88       list<named_expr_t>defparms;
89 
90       list<PGate*> gates;
91       void add_gate(PGate*);
92 
93 	// Tasks instantiated within this scheme.
94       map<perm_string,PTask*> tasks;
95       map<perm_string,PFunction*>funcs;
96 
97 	// Generate schemes can contain further generate schemes.
98       list<PGenerate*> generate_schemes;
99 //      PGenerate*parent;
100 
101 	// This method is called by the elaboration of a module to
102 	// generate scopes. the container is the scope that is to
103 	// contain the generated scope.
104       bool generate_scope(Design*des, NetScope*container);
105 
106 	// Elaborate signals within any of the generated scopes that
107 	// were made by this generate block within the given container scope.
108       bool elaborate_sig(Design*des, NetScope*container) const;
109       bool elaborate(Design*des, NetScope*container) const;
110 
111       void dump(ostream&out, unsigned indent) const;
112 
113       SymbolType symbol_type() const;
114 
115     private:
116       bool generate_scope_loop_(Design*des, NetScope*container);
117       bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
118       bool generate_scope_case_(Design*des, NetScope*container);
119       bool generate_scope_nblock_(Design*des, NetScope*container);
120 
121 	// Call probe during elaborate_scope to calculate the
122 	// direct_nested_ flag. It is OK to store the direct_nested_
123 	// information here because "direct nested" is a property of
124 	// the lexical generate code.
125       void probe_for_direct_nesting_(void);
126       bool direct_nested_;
127 
128 	// Elaborate_scope within a generated scope.
129       void elaborate_subscope_(Design*des, NetScope*scope);
130       void elaborate_subscope_direct_(Design*des, NetScope*scope);
131 
132 	// These are the scopes created by generate_scope.
133       list<NetScope*>scope_list_;
134 	// internal function called on each scope generated by this scheme.
135       bool elaborate_sig_(Design*des, NetScope*scope) const;
136       bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
137       bool elaborate_(Design*des, NetScope*scope) const;
138       bool elaborate_direct_(Design*des, NetScope*scope) const;
139 
140     private: // not implemented
141       PGenerate(const PGenerate&);
142       PGenerate& operator= (const PGenerate&);
143 };
144 
145 extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
146 
147 #endif /* IVL_PGenerate_H */
148