-
Notifications
You must be signed in to change notification settings - Fork 531
/
PGenerate.h
143 lines (120 loc) · 4.79 KB
/
PGenerate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef IVL_PGenerate_H
#define IVL_PGenerate_H
/*
* Copyright (c) 2006-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "PNamedItem.h"
# include "StringHeap.h"
# include "HName.h"
# include "PScope.h"
# include <list>
# include <map>
# include <valarray>
# include "pform_types.h"
class Design;
class NetScope;
class PExpr;
class PFunction;
class PProcess;
class PTask;
class PGate;
class PWire;
/*
* This represents a generate scheme. The interpretation of the
* members depends on the scheme_type.
*
* GS_LOOP
*
* GS_CASE
* loop_test is the expression to be compared.
* generates contains only GS_CASE_ITEM schemes.
* GS_CASE_ITEM
* The parent points to the GS_CASE that contains this item.
* the loop_test is compared with the parent->loop_test expression.
*/
class PGenerate : public PNamedItem, public LexicalScope {
public:
explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
// implicit.
const unsigned id_number;
perm_string scope_name;
// This is used during parsing to stack lexical scopes within
// this generate scheme.
// LexicalScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
scheme_t scheme_type;
bool directly_nested;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
// the index is local if it was declared in the init expression,
// e.g. for (genvar index = <init>; <test>; index=<step>)
bool local_index;
perm_string loop_index;
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
// Case items may have multiple guard expression values. It is
// enough for any on of the guards to match the case statement
// test value.
std::valarray<PExpr*> item_test;
// defparam assignments found in this scope.
typedef std::pair<pform_name_t,PExpr*> named_expr_t;
std::list<named_expr_t>defparms;
std::list<PGate*> gates;
void add_gate(PGate*);
// Tasks instantiated within this scheme.
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs;
// Generate schemes can contain further generate schemes.
std::list<PGenerate*> generate_schemes;
// PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.
bool generate_scope(Design*des, NetScope*container);
// Elaborate signals within any of the generated scopes that
// were made by this generate block within the given container scope.
bool elaborate_sig(Design*des, NetScope*container) const;
bool elaborate(Design*des, NetScope*container) const;
void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const;
private:
void check_for_valid_genvar_value_(long value);
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
void elaborate_subscope_direct_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
std::list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
bool elaborate_direct_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
#endif /* IVL_PGenerate_H */