1 #ifndef IVL_compile_H 2 #define IVL_compile_H 3 /* 4 * Copyright (c) 2001-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 <cstdio> 23 # include <fstream> 24 # include <list> 25 # include <vector> 26 # include "parse_misc.h" 27 # include "sv_vpi_user.h" 28 # include "vvp_net.h" 29 30 using namespace std; 31 32 /* 33 * The file names are kept in this vector. Entry 0 is "N/A" and 1 is 34 * for interactive commands. 35 */ 36 extern vector<const char*> file_names; 37 38 /* 39 * The functions described here are the compile time support 40 * functions. Various bits of the compile process are taken care of 41 * here. What is called when is mostly controlled by the parser. 42 * 43 * Before compilation takes place, the compile_init function must be 44 * called once to set stuff up. 45 */ 46 47 extern void compile_init(void); 48 49 extern void compile_cleanup(void); 50 51 extern bool verbose_flag; 52 53 /* 54 * If this file opened, then write debug information to this 55 * file. This is used for debugging the VVP runtime itself. 56 */ 57 extern ofstream debug_file; 58 59 /* 60 * Connect a list of symbols to a contiguous set of ipoints. 61 * Constants C<?> are handled by setting the ival of the ipoint. 62 */ 63 extern void inputs_connect(vvp_net_t*fdx, unsigned argc, struct symb_s*argv); 64 extern void input_connect(vvp_net_t*fdx, unsigned port, char*label); 65 66 /* 67 * This function is an expansion of the inputs_connect function. It 68 * uses the inputs_connect function, but it creates vvp_wide_fun_t 69 * nodes to handle arbitrary width nodes, and connects those nodes to 70 * the vvp_wide_fun_core object passed in. 71 */ 72 extern void wide_inputs_connect(vvp_wide_fun_core*core, 73 unsigned argc, struct symb_s*argv); 74 75 extern vvp_net_t* vvp_net_lookup(const char*label); 76 extern vpiHandle vvp_lookup_handle(const char*label); 77 78 /* 79 * Add a functor to the symbol table 80 */ 81 extern void define_functor_symbol(const char*label, vvp_net_t*ipt); 82 83 84 /* 85 * This is a count of errors encountered during compilation. If this 86 * is non-zero, then simulation is not recommended. 87 */ 88 extern unsigned compile_errors; 89 90 extern const char* module_path; 91 extern void compile_load_vpi_module(char*name); 92 93 extern void compile_vpi_time_precision(long pre); 94 95 /* 96 * This function is called by the parser to compile a functor 97 * statement. The strings passed in are allocated by the lexor, but 98 * this function will free them. (Or save them permanently.) This 99 * includes the argv array and the strings it references. 100 * 101 * The argc and argv are a list of char* that are the port parameters 102 * of the functor. The compile should match those port parameters up 103 * to existing functors to manage the linking. 104 */ 105 extern void compile_functor(char*label, char*type, unsigned width, 106 unsigned ostr0, unsigned ostr1, 107 unsigned argc, struct symb_s*argv); 108 109 110 /* 111 * This is called by the parser to make a resolver. This is a special 112 * kind of functor; a strength aware functor. It has up to 4 inputs 113 * that are blended to make a resolved output. The type string selects 114 * a resolution algorithm. 115 */ 116 extern void compile_resolver(char*label, char*type, 117 unsigned argc, struct symb_s*argv); 118 119 extern void compile_concat(char*label, unsigned w0, unsigned w1, 120 unsigned w2, unsigned w3, 121 unsigned argc, struct symb_s*argv); 122 123 extern void compile_concat8(char*label, unsigned w0, unsigned w1, 124 unsigned w2, unsigned w3, 125 unsigned argc, struct symb_s*argv); 126 127 extern void compile_substitute(char*label, unsigned width, 128 unsigned soff, unsigned swidth, 129 unsigned argc, struct symb_s*argv); 130 131 /* 132 * Arrange for the system task/function call to have its compiletf 133 * function called. 134 */ 135 extern void compile_compiletf(struct __vpiSysTaskCall*); 136 137 /* 138 * Compile delay nodes of various form. 139 */ 140 extern void compile_delay(char*label, unsigned width, 141 vvp_delay_t*del, struct symb_s input); 142 extern void compile_delay(char*label, unsigned width, 143 unsigned argc, struct symb_s*argv, 144 bool ignore_decay); 145 146 /* 147 * This is called by the parser to create a part select node. 148 * See the PART SELECT STATEMENT section in the README.txt 149 */ 150 extern void compile_part_select(char*label, char*src, 151 unsigned base, unsigned wid); 152 extern void compile_part_select_pv(char*label, char*src, 153 unsigned base, unsigned wid, 154 unsigned vec_wid); 155 extern void compile_part_select_var(char*label, char*src, 156 char*var, unsigned wid, bool is_signed); 157 158 /* 159 * This is called by the parser to make the various arithmetic and 160 * comparison functors. 161 */ 162 extern void compile_arith_pow(char*label, long width, bool signed_flag, 163 unsigned argc, struct symb_s*argv); 164 extern void compile_arith_abs(char*label, 165 unsigned argc, struct symb_s*argv); 166 extern void compile_arith_cast_int(char*label, long width, 167 unsigned argc, struct symb_s*argv); 168 extern void compile_arith_cast_real(char*label, bool signed_flag, 169 unsigned argc, struct symb_s*argv); 170 extern void compile_arith_cast_vec2(char*label, long width, 171 unsigned argc, struct symb_s*argv); 172 extern void compile_arith_div(char*label, long width, bool signed_flag, 173 unsigned argc, struct symb_s*argv); 174 extern void compile_arith_mod(char*label, long width, bool signed_flag, 175 unsigned argc, struct symb_s*argv); 176 extern void compile_arith_mult(char*label, long width, 177 unsigned argc, struct symb_s*argv); 178 extern void compile_arith_sum(char*label, long width, 179 unsigned argc, struct symb_s*argv); 180 extern void compile_arith_sub(char*label, long width, 181 unsigned argc, struct symb_s*argv); 182 extern void compile_cmp_eeq(char*label, long width, 183 unsigned argc, struct symb_s*argv); 184 extern void compile_cmp_nee(char*label, long width, 185 unsigned argc, struct symb_s*argv); 186 extern void compile_cmp_eq(char*label, long width, 187 unsigned argc, struct symb_s*argv); 188 extern void compile_cmp_eqx(char*label, long width, 189 unsigned argc, struct symb_s*argv); 190 extern void compile_cmp_eqz(char*label, long width, 191 unsigned argc, struct symb_s*argv); 192 extern void compile_cmp_ne(char*label, long width, 193 unsigned argc, struct symb_s*argv); 194 extern void compile_cmp_ge(char*label, long width, bool signed_flag, 195 unsigned argc, struct symb_s*argv); 196 extern void compile_cmp_gt(char*label, long width, bool signed_flag, 197 unsigned argc, struct symb_s*argv); 198 extern void compile_cmp_weq(char*label, long width, 199 unsigned argc, struct symb_s*argv); 200 extern void compile_cmp_wne(char*label, long width, 201 unsigned argc, struct symb_s*argv); 202 203 extern void compile_arith_mult_r(char*label, unsigned argc, 204 struct symb_s*argv); 205 extern void compile_arith_pow_r(char*label, unsigned argc, struct symb_s*argv); 206 extern void compile_arith_div_r(char*label, unsigned argc, struct symb_s*argv); 207 extern void compile_arith_mod_r(char*label, unsigned argc, struct symb_s*argv); 208 extern void compile_arith_sum_r(char*label, unsigned argc, struct symb_s*argv); 209 extern void compile_arith_sub_r(char*label, unsigned argc, struct symb_s*argv); 210 extern void compile_cmp_eq_r(char*label, unsigned argc, struct symb_s*argv); 211 extern void compile_cmp_ne_r(char*label, unsigned argc, struct symb_s*argv); 212 extern void compile_cmp_ge_r(char*label, unsigned argc, struct symb_s*argv); 213 extern void compile_cmp_gt_r(char*label, unsigned argc, struct symb_s*argv); 214 215 extern void compile_dff(char*label, unsigned width, bool negedge, 216 struct symb_s arg_d, 217 struct symb_s arg_c, 218 struct symb_s arg_e); 219 220 extern void compile_dff_aclr(char*label, unsigned width, bool negedge, 221 struct symb_s arg_d, 222 struct symb_s arg_c, 223 struct symb_s arg_e, 224 struct symb_s arg_a); 225 extern void compile_dff_aset(char*label, unsigned width, bool negedge, 226 struct symb_s arg_d, 227 struct symb_s arg_c, 228 struct symb_s arg_e, 229 struct symb_s arg_a, 230 char*asc_value); 231 232 extern void compile_latch(char*label, unsigned width, 233 struct symb_s arg_d, 234 struct symb_s arg_e); 235 236 extern void compile_enum2_type(char*label, long width, bool signed_flag, 237 std::list<struct enum_name_s>*names); 238 extern void compile_enum4_type(char*label, long width, bool signed_flag, 239 std::list<struct enum_name_s>*names); 240 241 struct __vpiModPath; 242 extern __vpiModPath* compile_modpath(char*label, 243 unsigned width, 244 struct symb_s drv, 245 struct symb_s dest); 246 extern void compile_modpath_src(__vpiModPath*dst, 247 char edge, 248 const struct symb_s&src, 249 struct numbv_s&vals, 250 const struct symb_s&condit_src, 251 const struct symb_s&path_term_in); 252 extern void compile_modpath_src(__vpiModPath*dst, 253 char edge, 254 const struct symb_s&src, 255 struct numbv_s&vals, 256 int condit_src, /* match with '0' */ 257 const struct symb_s&path_term_in, 258 bool ifnone); 259 260 extern void compile_reduce_and(char*label, const struct symb_s&arg); 261 extern void compile_reduce_or(char*label, const struct symb_s&arg); 262 extern void compile_reduce_xor(char*label, const struct symb_s&arg); 263 extern void compile_reduce_nand(char*label, const struct symb_s&arg); 264 extern void compile_reduce_nor(char*label, const struct symb_s&arg); 265 extern void compile_reduce_xnor(char*label, const struct symb_s&arg); 266 267 extern void compile_extend_signed(char*label, long width, struct symb_s arg); 268 269 extern void compile_sfunc(char*label, char*name, char*format_string, 270 long file_idx, long lineno, 271 unsigned argc, struct symb_s*argv, 272 char*trigger_label); 273 274 extern void compile_repeat(char*label, long width, long repeat, 275 struct symb_s arg); 276 277 extern void compile_shiftl(char*label, long width, 278 unsigned argc, struct symb_s*argv); 279 extern void compile_shiftr(char*label, long width, bool signed_flag, 280 unsigned argc, struct symb_s*argv); 281 282 extern void compile_timescale(long units, long precision); 283 284 extern void compile_vpi_symbol(const char*label, vpiHandle obj); 285 extern void compile_vpi_lookup(vpiHandle *objref, char*label); 286 287 extern void compile_param_string(char*label, char*name, char*value, 288 bool local_flag, 289 long file_idx, long lineno); 290 extern void compile_param_logic(char*label, char*name, char*value, 291 bool signed_flag, bool local_flag, 292 long file_idx, long lineno); 293 extern void compile_param_real(char*label, char*name, char*value, 294 bool local_flag, 295 long file_idx, long lineno); 296 297 /* 298 * The resolv_list_s is the base class for a symbol resolve 299 * action. Some function creates an instance of a resolv_list_s object 300 * that contains the data pertinent to that resolution request, and 301 * executes it with the resolv_submit function. If the operation can 302 * complete, then the resolv_submit deletes the object. Otherwise, it 303 * pushes it onto the resolv_list for later processing. 304 * 305 * Derived classes implement the resolve function to perform the 306 * actual binding or resolution that the instance requires. If the 307 * function succeeds, the resolve method returns true and the object 308 * can be deleted any time. 309 * 310 * The mes parameter of the resolve method tells the resolver that 311 * this call is its last chance. If it cannot complete the operation, 312 * it must print an error message and return false. 313 */ 314 class resolv_list_s { 315 316 public: resolv_list_s(char * lab)317 explicit resolv_list_s(char*lab) : label_(lab) { 318 next = NULL; 319 } 320 virtual ~resolv_list_s(); 321 virtual bool resolve(bool mes = false) = 0; 322 323 protected: label()324 const char*label() const { return label_; } 325 326 private: 327 friend void resolv_submit(class resolv_list_s*cur); 328 friend void compile_cleanup(void); 329 330 char*label_; 331 class resolv_list_s*next; 332 }; 333 334 /* 335 * This function schedules a lookup of an indexed label. The ref 336 * points to the vvp_net_t that receives the result. The result may 337 * be assigned later, if the symbol is defined later in the source 338 * file, so the memory that ref points to must persist. 339 * 340 * The text for the label will be deleted by this function, or the 341 * cleanup that completes the binding. 342 */ 343 extern void functor_ref_lookup(vvp_net_t**ref, char*lab); 344 345 /* 346 * This function schedules a lookup of the labeled instruction. The 347 * code points to a code structure that points to the instruction 348 * field that receives the result, and the label is the name to 349 * lookup. The lookup will free the label text when it is done. 350 * 351 * The cptr2 flag tells the lookup to write the code pointer into the 352 * cptr2 member of the code, instead of the cptr member. 353 */ 354 extern void code_label_lookup(struct vvp_code_s *code, char *label, bool cptr2); 355 356 /* 357 * The `compile_udp_def' function creates a UDP. The `table' is a 358 * NULL terminated array of char*, as assembled by `compile_udp_table'. 359 * `compile_udp_table' is called with `table'==NULL to create a new 360 * table, or with an existing table to append to. 361 * 362 * `compile_udp_functor' creates a mode-3 functor referring to the 363 * labeled UDP. 364 */ 365 366 extern void compile_udp_def(int sequ, char*label, char *name, 367 unsigned nin, unsigned init, char **table); 368 369 extern void compile_udp_functor(char*label, char*type, 370 unsigned argc, struct symb_s*argv); 371 372 extern char **compile_udp_table(char **table, char *row); 373 374 /* 375 * Memory Instances, Ports, and Initialization 376 */ 377 378 extern void compile_var_array(char*label, char*name, 379 int last, int first, 380 int msb, int lsb, char signed_flag); 381 extern void compile_var2_array(char*label, char*name, 382 int last, int first, 383 int msb, int lsb, bool signed_flag); 384 extern void compile_real_array(char*label, char*name, 385 int last, int first); 386 extern void compile_string_array(char*label, char*name, 387 int last, int first); 388 extern void compile_object_array(char*label, char*name, 389 int last, int first); 390 extern void compile_net_array(char*label, char*name, 391 int last, int first); 392 extern void compile_array_alias(char*label, char*name, char*src); 393 394 /* Index is a net. */ 395 extern void compile_array_port(char*label, char*name, char*addr); 396 /* Index is a constant address */ 397 extern void compile_array_port(char*label, char*name, long addr); 398 399 extern void compile_array_cleanup(void); 400 401 /* 402 * Compile the .ufunc statement. 403 */ 404 extern void compile_ufunc_real(char*label, char*code, unsigned wid, 405 unsigned argc, struct symb_s*argv, 406 unsigned portc, struct symb_s*portv, 407 char*scope_label, char*trigger_label); 408 extern void compile_ufunc_vec4(char*label, char*code, unsigned wid, 409 unsigned argc, struct symb_s*argv, 410 unsigned portc, struct symb_s*portv, 411 char*scope_label, char*trigger_label); 412 413 /* 414 * The compile_event function takes the parts of the event statement 415 * and makes the various objects needed to simulate it. This includes 416 * the functor that receives the signals and the event_t that holds 417 * the threads. 418 */ 419 extern void compile_event(char*label, char*type, 420 unsigned argc, struct symb_s*argv); 421 extern void compile_named_event(char*label, char*type, bool local_flag=false); 422 423 424 /* 425 * A code statement is a label, an opcode and up to 3 operands. There 426 * are a few lexical types that the parser recognizes of the operands, 427 * given by the ltype_e enumeration. The compile_code function takes 428 * the label, mnemonic and parsed operands and writes a properly 429 * formed instruction into the code space. The label is set into the 430 * symbol table with the address of the instruction. 431 */ 432 433 #define OPERAND_MAX 3 434 enum ltype_e { L_NUMB, L_SYMB, L_STRING }; 435 436 struct comp_operands_s { 437 unsigned argc; 438 struct { 439 enum ltype_e ltype; 440 union { 441 unsigned long numb; 442 struct symb_s symb; 443 const char *text; 444 }; 445 } argv[OPERAND_MAX]; 446 }; 447 448 typedef struct comp_operands_s*comp_operands_t; 449 450 extern void compile_code(char*label, char*mnem, comp_operands_t opa); 451 452 extern void compile_file_line(char*label, long file_idx, long lineno, 453 char*description); 454 455 extern void compile_vpi_call(char*label, char*name, 456 bool func_as_task_err, bool func_as_task_warn, 457 long file_idx, long lineno, 458 unsigned argc, vpiHandle*argv, 459 unsigned vec4_stack, 460 unsigned real_stack, 461 unsigned string_stack); 462 463 /* Compile a function call. The vbit and vwid encode the return 464 type. If the vwid >0, the return type is a vector. If the vwid is 465 <0, the return type is -vpiRealConst or some other constant subtype 466 code that represents the function type. */ 467 extern void compile_vpi_func_call(char*label, char*name, 468 int val_type, unsigned val_wid, 469 long file_idx, long lineno, 470 unsigned argc, vpiHandle*argv, 471 unsigned vec4_stack, 472 unsigned real_stack, 473 unsigned string_stack); 474 extern void print_vpi_call_errors(); 475 476 extern void compile_codelabel(char*label); 477 478 /* 479 * The parser uses these functions to compile .scope statements. 480 * The implementations of these live in the vpi_scope.cc file. 481 */ 482 extern void compile_scope_decl(char*typ, char*lab, char*nam, char*tnam, 483 char*par, long file_idx, long lineno, 484 long def_file_idx, long def_lineno, 485 long is_cell); 486 extern void compile_scope_recall(char*sym); 487 488 /* 489 * The parser uses this function to declare a thread. The start_sym is 490 * the start instruction, and must already be defined. 491 */ 492 extern void compile_thread(char*start_sym, char*flag); 493 494 /* 495 * This function is called to create a var vector with the given name. 496 * 497 * The vpi_type_code argument of compile_variable() is one of the vpi 498 * object codes that identify the type: vpiReg, vpiIntegerVar, 499 * vpiIntVar, etc. 500 */ 501 extern void compile_variable(char*label, char*name, 502 int msb, int lsb, int vpi_type_code, 503 bool signed_flag, bool local_flag); 504 505 extern void compile_var_real(char*label, char*name); 506 extern void compile_var_string(char*label, char*name); 507 extern void compile_var_darray(char*label, char*name, unsigned size); 508 extern void compile_var_cobject(char*label, char*name); 509 extern void compile_var_queue(char*label, char*name, unsigned size); 510 511 /* 512 * This function is used to create a scope port 513 * Current ONLY module ports are supported and ports exist purely 514 * as meta-data for VPI queries (i.e. there is NO corresponding net etc) 515 * as elaboration internally eliminates port-nets by directly connecting 516 * nets connected through module ports. 517 */ 518 519 extern void compile_port_info( unsigned index, int vpi_port_type, unsigned width, const char *name ); 520 521 522 /* 523 * The compile_net function is called to create a .net vector with a 524 * given name. 525 * 526 * The vpi_type_code argument of compile_net() is one of the vpi 527 * object codes for the equivalent variable types. The supported codes 528 * are: 529 * vpiLogic -- 4-value logic 530 * vpiIntVar -- 2-value logic 531 * -vpiLogic -- 8-value (i.e. strength aware) logic 532 */ 533 extern void compile_net(char*label, char*name, int msb, int lsb, 534 int vpi_type_code, bool signed_flag, bool local_flag, 535 unsigned argc, struct symb_s*argv); 536 537 extern void compile_net_real(char*label, char*name, 538 int msb, int lsb, bool local_flag, 539 unsigned argc, struct symb_s*argv); 540 541 extern void compile_netw(char*label, char*array_label, unsigned long array_addr, 542 int msb, int lsb, int vpi_type_code, bool signed_flag, 543 unsigned argc, struct symb_s*argv); 544 545 extern void compile_netw_real(char*label, char*array_symbol, 546 unsigned long array_addr, 547 int msb, int lsb, 548 unsigned argc, struct symb_s*argv); 549 550 551 extern void compile_island(char*label, char*type); 552 extern void compile_island_port(char*label, char*island, char*src); 553 extern void compile_island_import(char*label, char*island, char*src); 554 extern void compile_island_export(char*label, char*island); 555 extern void compile_island_cleanup(void); 556 557 extern void compile_island_tran(char*label); 558 extern void compile_island_tranif(int sense, char*island, 559 char*ba, char*bb, char*src, bool resistive); 560 extern void compile_island_tranvp(char*island, char*ba, char*bb, 561 unsigned width, unsigned part, unsigned off); 562 563 extern void delete_udp_symbols(void); 564 565 extern void compile_class_start(char*lab, char*nam, unsigned nprop); 566 extern void compile_class_property(unsigned idx, char*nam, char*typ, uint64_t array_size); 567 extern void compile_class_done(void); 568 569 #endif /* IVL_compile_H */ 570