1 /* -*- c++ -*- 2 * yosys -- Yosys Open SYnthesis Suite 3 * 4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com> 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 AST_BIND 165 }; 166 167 struct AstSrcLocType { 168 unsigned int first_line, last_line; 169 unsigned int first_column, last_column; AstSrcLocTypeAstSrcLocType170 AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {} AstSrcLocTypeAstSrcLocType171 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) {} 172 }; 173 174 // convert an node type to a string (e.g. for debug output) 175 std::string type2str(AstNodeType type); 176 177 // The AST is built using instances of this struct 178 struct AstNode 179 { 180 // for dict<> and pool<> 181 unsigned int hashidx_; hashAstNode182 unsigned int hash() const { return hashidx_; } 183 184 // this nodes type 185 AstNodeType type; 186 187 // the list of child nodes for this node 188 std::vector<AstNode*> children; 189 190 // the list of attributes assigned to this node 191 std::map<RTLIL::IdString, AstNode*> attributes; 192 bool get_bool_attribute(RTLIL::IdString id); 193 194 // node content - most of it is unused in most node types 195 std::string str; 196 std::vector<RTLIL::State> bits; 197 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; 198 int port_id, range_left, range_right; 199 uint32_t integer; 200 double realvalue; 201 // set for IDs typed to an enumeration, not used 202 bool is_enum; 203 204 // if this is a multirange memory then this vector contains offset and length of each dimension 205 std::vector<int> multirange_dimensions; 206 std::vector<bool> multirange_swapped; // true if range is swapped, not used for structs 207 208 // this is set by simplify and used during RTLIL generation 209 AstNode *id2ast; 210 211 // this is used by simplify to detect if basic analysis has been performed already on the node 212 bool basic_prep; 213 214 // this is used for ID references in RHS expressions that should use the "new" value for non-blocking assignments 215 bool lookahead; 216 217 // this is the original sourcecode location that resulted in this AST node 218 // it is automatically set by the constructor using AST::current_filename and 219 // the AST::get_line_num() callback function. 220 std::string filename; 221 AstSrcLocType location; 222 223 // creating and deleting nodes 224 AstNode(AstNodeType type = AST_NONE, AstNode *child1 = nullptr, AstNode *child2 = nullptr, AstNode *child3 = nullptr, AstNode *child4 = nullptr); 225 AstNode *clone() const; 226 void cloneInto(AstNode *other) const; 227 void delete_children(); 228 ~AstNode(); 229 230 enum mem2reg_flags 231 { 232 /* status flags */ 233 MEM2REG_FL_ALL = 0x00000001, 234 MEM2REG_FL_ASYNC = 0x00000002, 235 MEM2REG_FL_INIT = 0x00000004, 236 237 /* candidate flags */ 238 MEM2REG_FL_FORCED = 0x00000100, 239 MEM2REG_FL_SET_INIT = 0x00000200, 240 MEM2REG_FL_SET_ELSE = 0x00000400, 241 MEM2REG_FL_SET_ASYNC = 0x00000800, 242 MEM2REG_FL_EQ2 = 0x00001000, 243 MEM2REG_FL_CMPLX_LHS = 0x00002000, 244 MEM2REG_FL_CONST_LHS = 0x00004000, 245 MEM2REG_FL_VAR_LHS = 0x00008000, 246 247 /* proc flags */ 248 MEM2REG_FL_EQ1 = 0x01000000, 249 }; 250 251 // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc. 252 // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() 253 bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); 254 void replace_result_wire_name_in_function(const std::string &from, const std::string &to); 255 AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init); 256 void expand_genblock(const std::string &prefix); 257 void label_genblks(std::set<std::string>& existing, int &counter); 258 void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places, 259 dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags); 260 bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block); 261 bool mem2reg_check(pool<AstNode*> &mem2reg_set); 262 void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes); 263 void meminfo(int &mem_width, int &mem_size, int &addr_bits); 264 bool detect_latch(const std::string &var); 265 const RTLIL::Module* lookup_cell_module(); 266 267 // additional functionality for evaluating constant functions 268 struct varinfo_t { 269 RTLIL::Const val; 270 int offset; 271 bool is_signed; 272 AstNode *arg = nullptr; 273 bool explicitly_sized; 274 }; 275 bool has_const_only_constructs(); 276 bool replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall, bool must_succeed); 277 AstNode *eval_const_function(AstNode *fcall, bool must_succeed); 278 bool is_simple_const_expr(); 279 std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint); 280 281 bool is_recursive_function() const; 282 std::pair<AstNode*, AstNode*> get_tern_choice(); 283 284 // create a human-readable text representation of the AST (for debugging) 285 void dumpAst(FILE *f, std::string indent) const; 286 void dumpVlog(FILE *f, std::string indent) const; 287 288 // Generate RTLIL for a bind construct 289 std::vector<RTLIL::Binding *> genBindings() const; 290 291 // used by genRTLIL() for detecting expression width and sign 292 void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL); 293 void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL); 294 295 // create RTLIL code for this AST node 296 // for expressions the resulting signal vector is returned 297 // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module 298 RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); 299 RTLIL::SigSpec genWidthRTLIL(int width, bool sgn, const dict<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL); 300 301 // compare AST nodes 302 bool operator==(const AstNode &other) const; 303 bool operator!=(const AstNode &other) const; 304 bool contains(const AstNode *other) const; 305 306 // helper functions for creating AST nodes for constants 307 static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32); 308 static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized); 309 static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed); 310 static AstNode *mkconst_str(const std::vector<RTLIL::State> &v); 311 static AstNode *mkconst_str(const std::string &str); 312 313 // helper function for creating sign-extended const objects 314 RTLIL::Const bitsAsConst(int width, bool is_signed); 315 RTLIL::Const bitsAsConst(int width = -1); 316 RTLIL::Const bitsAsUnsizedConst(int width); 317 RTLIL::Const asAttrConst() const; 318 RTLIL::Const asParaConst() const; 319 uint64_t asInt(bool is_signed); 320 bool bits_only_01() const; 321 bool asBool() const; 322 323 // helper functions for real valued const eval 324 int isConst() const; // return '1' for AST_CONSTANT and '2' for AST_REALVALUE 325 double asReal(bool is_signed); 326 RTLIL::Const realAsConst(int width); 327 328 // helpers for enum 329 void allocateDefaultEnumValues(); 330 void annotateTypedEnums(AstNode *template_node); 331 332 // helpers for locations 333 std::string loc_string() const; 334 335 // Helper for looking up identifiers which are prefixed with the current module name 336 std::string try_pop_module_prefix() const; 337 }; 338 339 // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code 340 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, 341 bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire); 342 343 // parametric modules are supported directly by the AST library 344 // therefore we need our own derivate of RTLIL::Module with overloaded virtual functions 345 struct AstModule : RTLIL::Module { 346 AstNode *ast; 347 bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire; 348 ~AstModule() override; 349 RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override; 350 RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override; 351 std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false); 352 void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override; 353 bool reprocess_if_necessary(RTLIL::Design *design) override; 354 RTLIL::Module *clone() const override; 355 void loadconfig() const; 356 }; 357 358 // this must be set by the language frontend before parsing the sources 359 // the AstNode constructor then uses current_filename and get_line_num() 360 // to initialize the filename and linenum properties of new nodes 361 extern std::string current_filename; 362 extern void (*set_line_num)(int); 363 extern int (*get_line_num)(); 364 365 // set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive 366 // to control the filename and linenum properties of new nodes not generated by a frontend parser) 367 void use_internal_line_num(); 368 369 // call a DPI function 370 AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args); 371 372 // Helper functions related to handling SystemVerilog interfaces 373 std::pair<std::string,std::string> split_modport_from_type(std::string name_type); 374 AstNode * find_modport(AstNode *intf, std::string name); 375 void explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport); 376 377 // Helper for setting the src attribute. 378 void set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast); 379 380 // struct helper exposed from simplify for genrtlil 381 AstNode *make_struct_member_range(AstNode *node, AstNode *member_node); 382 383 // generate standard $paramod... derived module name; parameters should be 384 // in the order they are declared in the instantiated module 385 std::string derived_module_name(std::string stripped_name, const std::vector<std::pair<RTLIL::IdString, RTLIL::Const>> ¶meters); 386 387 // used to provide simplify() access to the current design for looking up 388 // modules, ports, wires, etc. 389 void set_simplify_design_context(const RTLIL::Design *design); 390 } 391 392 namespace AST_INTERNAL 393 { 394 // internal state variables 395 extern bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_rtlil, flag_nolatches, flag_nomeminit; 396 extern bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_pwires, flag_autowire; 397 extern AST::AstNode *current_ast, *current_ast_mod; 398 extern std::map<std::string, AST::AstNode*> current_scope; 399 extern const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr; 400 extern RTLIL::SigSpec ignoreThisSignalsInInitial; 401 extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; 402 extern RTLIL::Module *current_module; 403 extern bool current_always_clocked; 404 extern dict<std::string, int> current_memwr_count; 405 extern dict<std::string, pool<int>> current_memwr_visible; 406 struct LookaheadRewriter; 407 struct ProcessGenerator; 408 409 // Create and add a new AstModule from new_ast, then use it to replace 410 // old_module in design, renaming old_module to move it out of the way. 411 // Return the new module. 412 // 413 // If original_ast is not null, it will be used as the AST node for the 414 // new module. Otherwise, new_ast will be used. 415 RTLIL::Module * 416 process_and_replace_module(RTLIL::Design *design, 417 RTLIL::Module *old_module, 418 AST::AstNode *new_ast, 419 AST::AstNode *original_ast = nullptr); 420 } 421 422 YOSYS_NAMESPACE_END 423 424 #endif 425