Use stackmap<> in AST ProcessGenerator
[yosys.git] / frontends / ast / ast.h
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * ---
19 *
20 * This is the AST frontend library.
21 *
22 * The AST frontend library is not a frontend on it's own but provides a
23 * generic abstract syntax tree (AST) abstraction for HDL code and can be
24 * used by HDL frontends. See "ast.h" for an overview of the API and the
25 * Verilog frontend for an usage example.
26 *
27 */
28
29 #ifndef AST_H
30 #define AST_H
31
32 #include "kernel/rtlil.h"
33 #include <stdint.h>
34 #include <set>
35
36 YOSYS_NAMESPACE_BEGIN
37
38 namespace AST
39 {
40 // all node types, type2str() must be extended
41 // whenever a new node type is added here
42 enum AstNodeType
43 {
44 AST_NONE,
45 AST_DESIGN,
46 AST_MODULE,
47 AST_TASK,
48 AST_FUNCTION,
49
50 AST_WIRE,
51 AST_MEMORY,
52 AST_AUTOWIRE,
53 AST_PARAMETER,
54 AST_LOCALPARAM,
55 AST_DEFPARAM,
56 AST_PARASET,
57 AST_ARGUMENT,
58 AST_RANGE,
59 AST_MULTIRANGE,
60 AST_CONSTANT,
61 AST_REALVALUE,
62 AST_CELLTYPE,
63 AST_IDENTIFIER,
64 AST_PREFIX,
65 AST_ASSERT,
66
67 AST_FCALL,
68 AST_TO_BITS,
69 AST_TO_SIGNED,
70 AST_TO_UNSIGNED,
71 AST_CONCAT,
72 AST_REPLICATE,
73 AST_BIT_NOT,
74 AST_BIT_AND,
75 AST_BIT_OR,
76 AST_BIT_XOR,
77 AST_BIT_XNOR,
78 AST_REDUCE_AND,
79 AST_REDUCE_OR,
80 AST_REDUCE_XOR,
81 AST_REDUCE_XNOR,
82 AST_REDUCE_BOOL,
83 AST_SHIFT_LEFT,
84 AST_SHIFT_RIGHT,
85 AST_SHIFT_SLEFT,
86 AST_SHIFT_SRIGHT,
87 AST_LT,
88 AST_LE,
89 AST_EQ,
90 AST_NE,
91 AST_EQX,
92 AST_NEX,
93 AST_GE,
94 AST_GT,
95 AST_ADD,
96 AST_SUB,
97 AST_MUL,
98 AST_DIV,
99 AST_MOD,
100 AST_POW,
101 AST_POS,
102 AST_NEG,
103 AST_LOGIC_AND,
104 AST_LOGIC_OR,
105 AST_LOGIC_NOT,
106 AST_TERNARY,
107 AST_MEMRD,
108 AST_MEMWR,
109
110 AST_TCALL,
111 AST_ASSIGN,
112 AST_CELL,
113 AST_PRIMITIVE,
114 AST_CELLARRAY,
115 AST_ALWAYS,
116 AST_INITIAL,
117 AST_BLOCK,
118 AST_ASSIGN_EQ,
119 AST_ASSIGN_LE,
120 AST_CASE,
121 AST_COND,
122 AST_DEFAULT,
123 AST_FOR,
124 AST_WHILE,
125 AST_REPEAT,
126
127 AST_GENVAR,
128 AST_GENFOR,
129 AST_GENIF,
130 AST_GENCASE,
131 AST_GENBLOCK,
132
133 AST_POSEDGE,
134 AST_NEGEDGE,
135 AST_EDGE
136 };
137
138 // convert an node type to a string (e.g. for debug output)
139 std::string type2str(AstNodeType type);
140
141 // The AST is built using instances of this struct
142 struct AstNode
143 {
144 // this nodes type
145 AstNodeType type;
146
147 // the list of child nodes for this node
148 std::vector<AstNode*> children;
149
150 // the list of attributes assigned to this node
151 std::map<RTLIL::IdString, AstNode*> attributes;
152 bool get_bool_attribute(RTLIL::IdString id);
153
154 // node content - most of it is unused in most node types
155 std::string str;
156 std::vector<RTLIL::State> bits;
157 bool is_input, is_output, is_reg, is_signed, is_string, range_valid, range_swapped;
158 int port_id, range_left, range_right;
159 uint32_t integer;
160 double realvalue;
161
162 // if this is a multirange memory then this vector contains offset and length of each dimension
163 std::vector<int> multirange_dimensions;
164
165 // this is set by simplify and used during RTLIL generation
166 AstNode *id2ast;
167
168 // this is used by simplify to detect if basic analysis has been performed already on the node
169 bool basic_prep;
170
171 // this is the original sourcecode location that resulted in this AST node
172 // it is automatically set by the constructor using AST::current_filename and
173 // the AST::get_line_num() callback function.
174 std::string filename;
175 int linenum;
176
177 // creating and deleting nodes
178 AstNode(AstNodeType type = AST_NONE, AstNode *child1 = NULL, AstNode *child2 = NULL);
179 AstNode *clone();
180 void cloneInto(AstNode *other);
181 void delete_children();
182 ~AstNode();
183
184 enum mem2reg_flags
185 {
186 /* status flags */
187 MEM2REG_FL_ALL = 0x00000001,
188 MEM2REG_FL_ASYNC = 0x00000002,
189 MEM2REG_FL_INIT = 0x00000004,
190
191 /* candidate flags */
192 MEM2REG_FL_FORCED = 0x00000100,
193 MEM2REG_FL_SET_INIT = 0x00000200,
194 MEM2REG_FL_SET_ELSE = 0x00000400,
195 MEM2REG_FL_SET_ASYNC = 0x00000800,
196 MEM2REG_FL_EQ2 = 0x00001000,
197 MEM2REG_FL_CMPLX_LHS = 0x00002000,
198
199 /* proc flags */
200 MEM2REG_FL_EQ1 = 0x01000000,
201 };
202
203 // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc.
204 // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
205 bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
206 void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map);
207 void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules);
208 void mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
209 std::map<AstNode*, uint32_t> &mem2reg_flags, std::map<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
210 void mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
211 void meminfo(int &mem_width, int &mem_size, int &addr_bits);
212
213 // additional functionality for evaluating constant functions
214 struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
215 bool has_const_only_constructs(bool &recommend_const_eval);
216 void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
217 AstNode *eval_const_function(AstNode *fcall);
218
219 // create a human-readable text representation of the AST (for debugging)
220 void dumpAst(FILE *f, std::string indent);
221 void dumpVlog(FILE *f, std::string indent);
222
223 // used by genRTLIL() for detecting expression width and sign
224 void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL);
225 void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL);
226
227 // create RTLIL code for this AST node
228 // for expressions the resulting signal vector is returned
229 // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module
230 RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false);
231 RTLIL::SigSpec genWidthRTLIL(int width, const std::map<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL);
232
233 // compare AST nodes
234 bool operator==(const AstNode &other) const;
235 bool operator!=(const AstNode &other) const;
236 bool contains(const AstNode *other) const;
237
238 // helper functions for creating AST nodes for constants
239 static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32);
240 static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed);
241 static AstNode *mkconst_str(const std::vector<RTLIL::State> &v);
242 static AstNode *mkconst_str(const std::string &str);
243
244 // helper function for creating sign-extended const objects
245 RTLIL::Const bitsAsConst(int width, bool is_signed);
246 RTLIL::Const bitsAsConst(int width = -1);
247 RTLIL::Const asAttrConst();
248 RTLIL::Const asParaConst();
249 bool asBool();
250
251 // helper functions for real valued const eval
252 int isConst(); // return '1' for AST_CONSTANT and '2' for AST_REALVALUE
253 double asReal(bool is_signed);
254 RTLIL::Const realAsConst(int width);
255 };
256
257 // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
258 void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire);
259
260 // parametric modules are supported directly by the AST library
261 // therfore we need our own derivate of RTLIL::Module with overloaded virtual functions
262 struct AstModule : RTLIL::Module {
263 AstNode *ast;
264 bool nolatches, nomem2reg, mem2reg, lib, noopt, icells, autowire;
265 virtual ~AstModule();
266 virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
267 virtual RTLIL::Module *clone() const;
268 };
269
270 // this must be set by the language frontend before parsing the sources
271 // the AstNode constructor then uses current_filename and get_line_num()
272 // to initialize the filename and linenum properties of new nodes
273 extern std::string current_filename;
274 extern void (*set_line_num)(int);
275 extern int (*get_line_num)();
276
277 // set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive
278 // to control the filename and linenum properties of new nodes not generated by a frontend parser)
279 void use_internal_line_num();
280 }
281
282 namespace AST_INTERNAL
283 {
284 // internal state variables
285 extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
286 extern AST::AstNode *current_ast, *current_ast_mod;
287 extern std::map<std::string, AST::AstNode*> current_scope;
288 extern const std::map<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
289 extern RTLIL::SigSpec ignoreThisSignalsInInitial;
290 extern AST::AstNode *current_top_block, *current_block, *current_block_child;
291 extern AST::AstModule *current_module;
292 struct ProcessGenerator;
293 }
294
295 YOSYS_NAMESPACE_END
296
297 #endif