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