Merge pull request #2339 from zachjs/display-format-0s
[yosys.git] / frontends / ast / ast.h
1 /* -*- c++ -*-
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 AST_DPI_FUNCTION,
50
51 AST_WIRE,
52 AST_MEMORY,
53 AST_AUTOWIRE,
54 AST_PARAMETER,
55 AST_LOCALPARAM,
56 AST_DEFPARAM,
57 AST_PARASET,
58 AST_ARGUMENT,
59 AST_RANGE,
60 AST_MULTIRANGE,
61 AST_CONSTANT,
62 AST_REALVALUE,
63 AST_CELLTYPE,
64 AST_IDENTIFIER,
65 AST_PREFIX,
66 AST_ASSERT,
67 AST_ASSUME,
68 AST_LIVE,
69 AST_FAIR,
70 AST_COVER,
71 AST_ENUM,
72 AST_ENUM_ITEM,
73
74 AST_FCALL,
75 AST_TO_BITS,
76 AST_TO_SIGNED,
77 AST_TO_UNSIGNED,
78 AST_SELFSZ,
79 AST_CAST_SIZE,
80 AST_CONCAT,
81 AST_REPLICATE,
82 AST_BIT_NOT,
83 AST_BIT_AND,
84 AST_BIT_OR,
85 AST_BIT_XOR,
86 AST_BIT_XNOR,
87 AST_REDUCE_AND,
88 AST_REDUCE_OR,
89 AST_REDUCE_XOR,
90 AST_REDUCE_XNOR,
91 AST_REDUCE_BOOL,
92 AST_SHIFT_LEFT,
93 AST_SHIFT_RIGHT,
94 AST_SHIFT_SLEFT,
95 AST_SHIFT_SRIGHT,
96 AST_SHIFTX,
97 AST_SHIFT,
98 AST_LT,
99 AST_LE,
100 AST_EQ,
101 AST_NE,
102 AST_EQX,
103 AST_NEX,
104 AST_GE,
105 AST_GT,
106 AST_ADD,
107 AST_SUB,
108 AST_MUL,
109 AST_DIV,
110 AST_MOD,
111 AST_POW,
112 AST_POS,
113 AST_NEG,
114 AST_LOGIC_AND,
115 AST_LOGIC_OR,
116 AST_LOGIC_NOT,
117 AST_TERNARY,
118 AST_MEMRD,
119 AST_MEMWR,
120 AST_MEMINIT,
121
122 AST_TCALL,
123 AST_ASSIGN,
124 AST_CELL,
125 AST_PRIMITIVE,
126 AST_CELLARRAY,
127 AST_ALWAYS,
128 AST_INITIAL,
129 AST_BLOCK,
130 AST_ASSIGN_EQ,
131 AST_ASSIGN_LE,
132 AST_CASE,
133 AST_COND,
134 AST_CONDX,
135 AST_CONDZ,
136 AST_DEFAULT,
137 AST_FOR,
138 AST_WHILE,
139 AST_REPEAT,
140
141 AST_GENVAR,
142 AST_GENFOR,
143 AST_GENIF,
144 AST_GENCASE,
145 AST_GENBLOCK,
146 AST_TECALL,
147
148 AST_POSEDGE,
149 AST_NEGEDGE,
150 AST_EDGE,
151
152 AST_INTERFACE,
153 AST_INTERFACEPORT,
154 AST_INTERFACEPORTTYPE,
155 AST_MODPORT,
156 AST_MODPORTMEMBER,
157 AST_PACKAGE,
158
159 AST_WIRETYPE,
160 AST_TYPEDEF,
161 AST_STRUCT,
162 AST_UNION,
163 AST_STRUCT_ITEM
164 };
165
166 struct AstSrcLocType {
167 unsigned int first_line, last_line;
168 unsigned int first_column, last_column;
169 AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {}
170 AstSrcLocType(int _first_line, int _first_column, int _last_line, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {}
171 };
172
173 // convert an node type to a string (e.g. for debug output)
174 std::string type2str(AstNodeType type);
175
176 // The AST is built using instances of this struct
177 struct AstNode
178 {
179 // for dict<> and pool<>
180 unsigned int hashidx_;
181 unsigned int hash() const { return hashidx_; }
182
183 // this nodes type
184 AstNodeType type;
185
186 // the list of child nodes for this node
187 std::vector<AstNode*> children;
188
189 // the list of attributes assigned to this node
190 std::map<RTLIL::IdString, AstNode*> attributes;
191 bool get_bool_attribute(RTLIL::IdString id);
192
193 // node content - most of it is unused in most node types
194 std::string str;
195 std::vector<RTLIL::State> bits;
196 bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
197 int port_id, range_left, range_right;
198 uint32_t integer;
199 double realvalue;
200 // set for IDs typed to an enumeration, not used
201 bool is_enum;
202
203 // if this is a multirange memory then this vector contains offset and length of each dimension
204 std::vector<int> multirange_dimensions;
205
206 // this is set by simplify and used during RTLIL generation
207 AstNode *id2ast;
208
209 // this is used by simplify to detect if basic analysis has been performed already on the node
210 bool basic_prep;
211
212 // this is used for ID references in RHS expressions that should use the "new" value for non-blocking assignments
213 bool lookahead;
214
215 // this is the original sourcecode location that resulted in this AST node
216 // it is automatically set by the constructor using AST::current_filename and
217 // the AST::get_line_num() callback function.
218 std::string filename;
219 AstSrcLocType location;
220
221 // creating and deleting nodes
222 AstNode(AstNodeType type = AST_NONE, AstNode *child1 = NULL, AstNode *child2 = NULL, AstNode *child3 = NULL);
223 AstNode *clone() const;
224 void cloneInto(AstNode *other) const;
225 void delete_children();
226 ~AstNode();
227
228 enum mem2reg_flags
229 {
230 /* status flags */
231 MEM2REG_FL_ALL = 0x00000001,
232 MEM2REG_FL_ASYNC = 0x00000002,
233 MEM2REG_FL_INIT = 0x00000004,
234
235 /* candidate flags */
236 MEM2REG_FL_FORCED = 0x00000100,
237 MEM2REG_FL_SET_INIT = 0x00000200,
238 MEM2REG_FL_SET_ELSE = 0x00000400,
239 MEM2REG_FL_SET_ASYNC = 0x00000800,
240 MEM2REG_FL_EQ2 = 0x00001000,
241 MEM2REG_FL_CMPLX_LHS = 0x00002000,
242 MEM2REG_FL_CONST_LHS = 0x00004000,
243 MEM2REG_FL_VAR_LHS = 0x00008000,
244
245 /* proc flags */
246 MEM2REG_FL_EQ1 = 0x01000000,
247 };
248
249 // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc.
250 // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
251 bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
252 AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
253 void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map, bool original_scope = true);
254 void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules);
255 void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
256 dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
257 bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block);
258 bool mem2reg_check(pool<AstNode*> &mem2reg_set);
259 void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
260 void meminfo(int &mem_width, int &mem_size, int &addr_bits);
261 bool detect_latch(const std::string &var);
262
263 // additional functionality for evaluating constant functions
264 struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
265 bool has_const_only_constructs(bool &recommend_const_eval);
266 void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
267 AstNode *eval_const_function(AstNode *fcall);
268 bool is_simple_const_expr();
269 std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint);
270
271 // create a human-readable text representation of the AST (for debugging)
272 void dumpAst(FILE *f, std::string indent) const;
273 void dumpVlog(FILE *f, std::string indent) const;
274
275 // used by genRTLIL() for detecting expression width and sign
276 void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL);
277 void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL);
278
279 // create RTLIL code for this AST node
280 // for expressions the resulting signal vector is returned
281 // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module
282 RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false);
283 RTLIL::SigSpec genWidthRTLIL(int width, const dict<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL);
284
285 // compare AST nodes
286 bool operator==(const AstNode &other) const;
287 bool operator!=(const AstNode &other) const;
288 bool contains(const AstNode *other) const;
289
290 // helper functions for creating AST nodes for constants
291 static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32);
292 static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized);
293 static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed);
294 static AstNode *mkconst_str(const std::vector<RTLIL::State> &v);
295 static AstNode *mkconst_str(const std::string &str);
296
297 // helper function for creating sign-extended const objects
298 RTLIL::Const bitsAsConst(int width, bool is_signed);
299 RTLIL::Const bitsAsConst(int width = -1);
300 RTLIL::Const bitsAsUnsizedConst(int width);
301 RTLIL::Const asAttrConst();
302 RTLIL::Const asParaConst();
303 uint64_t asInt(bool is_signed);
304 bool bits_only_01() const;
305 bool asBool() const;
306
307 // helper functions for real valued const eval
308 int isConst() const; // return '1' for AST_CONSTANT and '2' for AST_REALVALUE
309 double asReal(bool is_signed);
310 RTLIL::Const realAsConst(int width);
311
312 // helpers for enum
313 void allocateDefaultEnumValues();
314 void annotateTypedEnums(AstNode *template_node);
315 };
316
317 // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
318 void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit,
319 bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire);
320
321 // parametric modules are supported directly by the AST library
322 // therefore we need our own derivate of RTLIL::Module with overloaded virtual functions
323 struct AstModule : RTLIL::Module {
324 AstNode *ast;
325 bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
326 ~AstModule() override;
327 RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override;
328 RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
329 std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet = false);
330 void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
331 RTLIL::Module *clone() const override;
332 void loadconfig() const;
333 };
334
335 // this must be set by the language frontend before parsing the sources
336 // the AstNode constructor then uses current_filename and get_line_num()
337 // to initialize the filename and linenum properties of new nodes
338 extern std::string current_filename;
339 extern void (*set_line_num)(int);
340 extern int (*get_line_num)();
341
342 // set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive
343 // to control the filename and linenum properties of new nodes not generated by a frontend parser)
344 void use_internal_line_num();
345
346 // call a DPI function
347 AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args);
348
349 // Helper functions related to handling SystemVerilog interfaces
350 std::pair<std::string,std::string> split_modport_from_type(std::string name_type);
351 AstNode * find_modport(AstNode *intf, std::string name);
352 void explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport);
353 }
354
355 namespace AST_INTERNAL
356 {
357 // internal state variables
358 extern bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
359 extern bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_pwires, flag_autowire;
360 extern AST::AstNode *current_ast, *current_ast_mod;
361 extern std::map<std::string, AST::AstNode*> current_scope;
362 extern const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
363 extern RTLIL::SigSpec ignoreThisSignalsInInitial;
364 extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child;
365 extern AST::AstModule *current_module;
366 extern bool current_always_clocked;
367 struct LookaheadRewriter;
368 struct ProcessGenerator;
369 }
370
371 YOSYS_NAMESPACE_END
372
373 #endif