2 * Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 # include "StringHeap.h"
29 static StringHeap api_strings
;
31 /* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
33 extern "C" const char*ivl_design_flag(ivl_design_t des
, const char*key
)
35 return des
->self
->get_flag(key
);
38 extern "C" int ivl_design_process(ivl_design_t des
,
42 for (ivl_process_t idx
= des
->threads_
; idx
; idx
= idx
->next_
) {
43 int rc
= (func
)(idx
, cd
);
51 extern "C" ivl_scope_t
ivl_design_root(ivl_design_t des
)
53 cerr
<< "ANACHRONISM: ivl_design_root called. "
54 "Use ivl_design_roots instead." << endl
;
56 assert (des
->nroots_
);
57 return des
->roots_
[0];
60 extern "C" void ivl_design_roots(ivl_design_t des
, ivl_scope_t
**scopes
,
61 unsigned int *nscopes
)
63 assert (nscopes
&& scopes
);
64 *scopes
= &des
->roots_
[0];
65 *nscopes
= des
->nroots_
;
68 extern "C" int ivl_design_time_precision(ivl_design_t des
)
70 return des
->time_precision
;
73 extern "C" unsigned ivl_design_consts(ivl_design_t des
)
78 extern "C" ivl_net_const_t
ivl_design_const(ivl_design_t des
, unsigned idx
)
80 assert(idx
< des
->nconsts
);
81 return des
->consts
[idx
];
84 extern "C" ivl_expr_type_t
ivl_expr_type(ivl_expr_t net
)
91 extern "C" const char*ivl_expr_file(ivl_expr_t net
)
94 return net
->file
.str();
97 extern "C" unsigned ivl_expr_lineno(ivl_expr_t net
)
103 inline static const char *basename(ivl_scope_t scope
, const char *inst
)
105 inst
+= strlen(ivl_scope_name(scope
));
106 assert(*inst
== '.');
110 extern "C" ivl_variable_type_t
ivl_const_type(ivl_net_const_t net
)
116 extern "C" const char*ivl_const_bits(ivl_net_const_t net
)
122 if (net
->width_
<= sizeof(net
->b
.bit_
))
132 extern "C" ivl_expr_t
ivl_const_delay(ivl_net_const_t net
, unsigned transition
)
134 assert(transition
< 3);
135 return net
->delay
[transition
];
138 extern "C" ivl_nexus_t
ivl_const_nex(ivl_net_const_t net
)
144 extern "C" double ivl_const_real(ivl_net_const_t net
)
147 assert(net
->type
== IVL_VT_REAL
);
148 return net
->b
.real_value
;
151 extern "C" int ivl_const_signed(ivl_net_const_t net
)
157 extern "C" unsigned ivl_const_width(ivl_net_const_t net
)
163 extern "C" const char* ivl_event_name(ivl_event_t net
)
165 static char*name_buffer
= 0;
166 static unsigned name_size
= 0;
168 ivl_scope_t scope
= net
->scope
;
169 const char*sn
= ivl_scope_name(scope
);
171 unsigned need
= strlen(sn
) + 1 + strlen(net
->name
) + 1;
172 if (need
> name_size
) {
173 name_buffer
= (char*)realloc(name_buffer
, need
);
177 strcpy(name_buffer
, sn
);
178 char*tmp
= name_buffer
+ strlen(sn
);
180 strcpy(tmp
, net
->name
);
182 cerr
<< "ANACHRONISM: Call to anachronistic ivl_event_name." << endl
;
187 extern "C" const char* ivl_event_basename(ivl_event_t net
)
192 extern "C" ivl_scope_t
ivl_event_scope(ivl_event_t net
)
197 extern "C" unsigned ivl_event_nany(ivl_event_t net
)
203 extern "C" ivl_nexus_t
ivl_event_any(ivl_event_t net
, unsigned idx
)
206 assert(idx
< net
->nany
);
207 return net
->pins
[idx
];
210 extern "C" unsigned ivl_event_nneg(ivl_event_t net
)
216 extern "C" ivl_nexus_t
ivl_event_neg(ivl_event_t net
, unsigned idx
)
219 assert(idx
< net
->nneg
);
220 return net
->pins
[net
->nany
+ idx
];
223 extern "C" unsigned ivl_event_npos(ivl_event_t net
)
229 extern "C" ivl_nexus_t
ivl_event_pos(ivl_event_t net
, unsigned idx
)
232 assert(idx
< net
->npos
);
233 return net
->pins
[net
->nany
+ net
->nneg
+ idx
];
236 extern "C" const char* ivl_expr_bits(ivl_expr_t net
)
238 assert(net
&& (net
->type_
== IVL_EX_NUMBER
));
239 return net
->u_
.number_
.bits_
;
242 extern "C" ivl_scope_t
ivl_expr_def(ivl_expr_t net
)
246 switch (net
->type_
) {
249 return net
->u_
.ufunc_
.def
;
258 extern "C" double ivl_expr_dvalue(ivl_expr_t net
)
260 assert(net
->type_
== IVL_EX_REALNUM
);
261 return net
->u_
.real_
.value
;
264 extern "C" const char* ivl_expr_name(ivl_expr_t net
)
266 switch (net
->type_
) {
269 return net
->u_
.sfunc_
.name_
;
272 return net
->u_
.signal_
.sig
->name_
;
280 extern "C" char ivl_expr_opcode(ivl_expr_t net
)
283 switch (net
->type_
) {
285 return net
->u_
.binary_
.op_
;
288 return net
->u_
.unary_
.op_
;
296 extern "C" ivl_expr_t
ivl_expr_oper1(ivl_expr_t net
)
299 switch (net
->type_
) {
302 return net
->u_
.binary_
.lef_
;
305 return net
->u_
.unary_
.sub_
;
308 return net
->u_
.memory_
.idx_
;
311 return net
->u_
.signal_
.word
;
314 return net
->u_
.ternary_
.cond
;
323 extern "C" ivl_expr_t
ivl_expr_oper2(ivl_expr_t net
)
326 switch (net
->type_
) {
329 return net
->u_
.binary_
.rig_
;
332 return net
->u_
.ternary_
.true_e
;
341 extern "C" ivl_expr_t
ivl_expr_oper3(ivl_expr_t net
)
344 switch (net
->type_
) {
347 return net
->u_
.ternary_
.false_e
;
355 extern "C" ivl_parameter_t
ivl_expr_parameter(ivl_expr_t net
)
357 switch (net
->type_
) {
359 return net
->u_
.number_
.parameter
;
361 return net
->u_
.string_
.parameter
;
363 return net
->u_
.real_
.parameter
;
369 extern "C" ivl_expr_t
ivl_expr_parm(ivl_expr_t net
, unsigned idx
)
372 switch (net
->type_
) {
375 assert(idx
< net
->u_
.concat_
.parms
);
376 return net
->u_
.concat_
.parm
[idx
];
379 assert(idx
< net
->u_
.sfunc_
.parms
);
380 return net
->u_
.sfunc_
.parm
[idx
];
383 assert(idx
< net
->u_
.ufunc_
.parms
);
384 return net
->u_
.ufunc_
.parm
[idx
];
392 extern "C" unsigned ivl_expr_parms(ivl_expr_t net
)
395 switch (net
->type_
) {
398 return net
->u_
.concat_
.parms
;
401 return net
->u_
.sfunc_
.parms
;
404 return net
->u_
.ufunc_
.parms
;
412 extern "C" unsigned ivl_expr_repeat(ivl_expr_t net
)
415 assert(net
->type_
== IVL_EX_CONCAT
);
416 return net
->u_
.concat_
.rept
;
419 extern "C" ivl_event_t
ivl_expr_event(ivl_expr_t net
)
422 assert(net
->type_
== IVL_EX_EVENT
);
423 return net
->u_
.event_
.event
;
426 extern "C" ivl_scope_t
ivl_expr_scope(ivl_expr_t net
)
429 assert(net
->type_
== IVL_EX_SCOPE
);
430 return net
->u_
.scope_
.scope
;
433 extern "C" ivl_signal_t
ivl_expr_signal(ivl_expr_t net
)
436 switch (net
->type_
) {
440 return net
->u_
.signal_
.sig
;
448 extern "C" int ivl_expr_signed(ivl_expr_t net
)
454 extern "C" const char* ivl_expr_string(ivl_expr_t net
)
456 assert(net
->type_
== IVL_EX_STRING
);
457 return net
->u_
.string_
.value_
;
460 extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net
)
462 switch (net
->type_
) {
465 return net
->u_
.ulong_
.value
;
467 case IVL_EX_NUMBER
: {
468 unsigned long val
= 0;
469 for (unsigned long idx
= 0 ; idx
< net
->width_
; idx
+= 1) {
470 if (net
->u_
.number_
.bits_
[idx
] == '1')
483 extern "C" ivl_variable_type_t
ivl_expr_value(ivl_expr_t net
)
489 extern "C" unsigned ivl_expr_width(ivl_expr_t net
)
496 * ivl_file_table_index puts entries in the map as needed and returns
497 * the appropriate index.
498 * ivl_file_table_size returns the number of entries in the table.
499 * ivl_file_table_item returns the file name for the given index.
503 bool operator()(const char*s1
, const char*s2
) const
505 return strcmp(s1
, s2
) < 0;
508 static map
<const char*, unsigned, ltstr
> fn_map
;
509 static vector
<const char*> fn_vector
;
511 static void ivl_file_table_init()
513 /* The first two index entries do not depend on a real
514 * file name and are always available. */
515 fn_vector
.push_back("N/A");
517 fn_vector
.push_back("<interactive>");
518 fn_map
["<interactive>"] = 1;
521 extern "C" const char* ivl_file_table_item(unsigned idx
)
523 if (fn_vector
.empty()) {
524 ivl_file_table_init();
527 assert(idx
< fn_vector
.size());
528 return fn_vector
[idx
];
531 extern "C" unsigned ivl_file_table_index(const char*name
)
533 if (fn_vector
.empty()) {
534 ivl_file_table_init();
537 if (name
== NULL
) return 0;
539 /* The new index is the current map size. This is inserted only
540 * if the file name is not currently in the map. */
541 pair
<map
<const char*, unsigned, ltstr
>::iterator
, bool> result
;
542 result
= fn_map
.insert(make_pair(name
, fn_vector
.size()));
544 fn_vector
.push_back(name
);
546 return result
.first
->second
;
549 extern "C" unsigned ivl_file_table_size()
551 if (fn_vector
.empty()) {
552 ivl_file_table_init();
555 return fn_vector
.size();
558 extern "C" const char* ivl_logic_attr(ivl_net_logic_t net
, const char*key
)
563 for (idx
= 0 ; idx
< net
->nattr
; idx
+= 1) {
565 if (strcmp(net
->attr
[idx
].key
, key
) == 0)
566 return net
->attr
[idx
].type
== IVL_ATT_STR
567 ? net
->attr
[idx
].val
.str
574 extern "C" unsigned ivl_logic_attr_cnt(ivl_net_logic_t net
)
579 extern "C" ivl_attribute_t
ivl_logic_attr_val(ivl_net_logic_t net
,
582 assert(idx
< net
->nattr
);
583 return net
->attr
+ idx
;
586 extern "C" ivl_drive_t
ivl_logic_drive0(ivl_net_logic_t net
)
588 ivl_nexus_t nex
= ivl_logic_pin(net
, 0);
590 for (unsigned idx
= 0 ; idx
< ivl_nexus_ptrs(nex
) ; idx
+= 1) {
591 ivl_nexus_ptr_t cur
= ivl_nexus_ptr(nex
, idx
);
592 if (ivl_nexus_ptr_log(cur
) != net
)
594 if (ivl_nexus_ptr_pin(cur
) != 0)
596 return ivl_nexus_ptr_drive0(cur
);
600 return IVL_DR_STRONG
;
603 extern "C" ivl_drive_t
ivl_logic_drive1(ivl_net_logic_t net
)
605 ivl_nexus_t nex
= ivl_logic_pin(net
, 0);
607 for (unsigned idx
= 0 ; idx
< ivl_nexus_ptrs(nex
) ; idx
+= 1) {
608 ivl_nexus_ptr_t cur
= ivl_nexus_ptr(nex
, idx
);
609 if (ivl_nexus_ptr_log(cur
) != net
)
611 if (ivl_nexus_ptr_pin(cur
) != 0)
613 return ivl_nexus_ptr_drive1(cur
);
617 return IVL_DR_STRONG
;
620 extern "C" const char* ivl_logic_name(ivl_net_logic_t net
)
623 cerr
<< "ANACHRONISM: Call to anachronistic ivl_logic_name." << endl
;
627 extern "C" const char* ivl_logic_basename(ivl_net_logic_t net
)
633 extern "C" ivl_scope_t
ivl_logic_scope(ivl_net_logic_t net
)
639 extern "C" ivl_logic_t
ivl_logic_type(ivl_net_logic_t net
)
644 extern "C" unsigned ivl_logic_pins(ivl_net_logic_t net
)
649 extern "C" ivl_nexus_t
ivl_logic_pin(ivl_net_logic_t net
, unsigned pin
)
651 assert(pin
< net
->npins_
);
652 return net
->pins_
[pin
];
655 extern "C" ivl_udp_t
ivl_logic_udp(ivl_net_logic_t net
)
657 assert(net
->type_
== IVL_LO_UDP
);
662 extern "C" ivl_expr_t
ivl_logic_delay(ivl_net_logic_t net
, unsigned transition
)
664 assert(transition
< 3);
665 return net
->delay
[transition
];
668 extern "C" unsigned ivl_logic_width(ivl_net_logic_t net
)
674 extern "C" int ivl_udp_sequ(ivl_udp_t net
)
679 extern "C" unsigned ivl_udp_nin(ivl_udp_t net
)
684 extern "C" unsigned ivl_udp_init(ivl_udp_t net
)
689 extern "C" const char* ivl_udp_row(ivl_udp_t net
, unsigned idx
)
691 assert(idx
< net
->nrows
);
693 assert(net
->table
[idx
]);
694 return net
->table
[idx
];
697 extern "C" unsigned ivl_udp_rows(ivl_udp_t net
)
702 extern "C" const char* ivl_udp_name(ivl_udp_t net
)
708 extern "C" const char* ivl_lpm_basename(ivl_lpm_t net
)
713 extern "C" ivl_nexus_t
ivl_lpm_async_clr(ivl_lpm_t net
)
718 return net
->u_
.ff
.aclr
;
725 extern "C" ivl_nexus_t
ivl_lpm_sync_clr(ivl_lpm_t net
)
730 return net
->u_
.ff
.sclr
;
737 extern "C" ivl_expr_t
ivl_lpm_delay(ivl_lpm_t net
, unsigned transition
)
739 assert(transition
< 3);
740 return net
->delay
[transition
];
743 extern "C" ivl_nexus_t
ivl_lpm_async_set(ivl_lpm_t net
)
748 return net
->u_
.ff
.aset
;
755 extern "C" ivl_nexus_t
ivl_lpm_sync_set(ivl_lpm_t net
)
760 return net
->u_
.ff
.sset
;
767 extern "C" ivl_signal_t
ivl_lpm_array(ivl_lpm_t net
)
772 return net
->u_
.array
.sig
;
779 extern "C" unsigned ivl_lpm_base(ivl_lpm_t net
)
783 case IVL_LPM_PART_VP
:
784 case IVL_LPM_PART_PV
:
785 case IVL_LPM_PART_BI
:
786 return net
->u_
.part
.base
;
793 extern "C" ivl_nexus_t
ivl_lpm_clk(ivl_lpm_t net
)
798 return net
->u_
.ff
.clk
;
805 extern "C" ivl_expr_t
ivl_lpm_aset_value(ivl_lpm_t net
)
810 return net
->u_
.ff
.aset_value
;
816 extern "C" ivl_expr_t
ivl_lpm_sset_value(ivl_lpm_t net
)
821 return net
->u_
.ff
.sset_value
;
828 extern "C" ivl_scope_t
ivl_lpm_define(ivl_lpm_t net
)
833 return net
->u_
.ufunc
.def
;
840 extern "C" ivl_nexus_t
ivl_lpm_enable(ivl_lpm_t net
)
845 return net
->u_
.ff
.we
;
852 /* The file name and line number are only set for system functions! */
853 extern "C" const char* ivl_lpm_file(ivl_lpm_t net
)
855 return net
->file
.str();
858 extern "C" unsigned ivl_lpm_lineno(ivl_lpm_t net
)
863 extern "C" ivl_nexus_t
ivl_lpm_data(ivl_lpm_t net
, unsigned idx
)
868 case IVL_LPM_CMP_EEQ
:
873 case IVL_LPM_CMP_NEE
:
881 return net
->u_
.arith
.a
;
883 return net
->u_
.arith
.b
;
886 assert(idx
< net
->u_
.mux
.size
);
887 return net
->u_
.mux
.d
[idx
];
892 case IVL_LPM_RE_NAND
:
894 case IVL_LPM_RE_XNOR
:
895 case IVL_LPM_SIGN_EXT
:
897 return net
->u_
.reduce
.a
;
903 return net
->u_
.shift
.d
;
905 return net
->u_
.shift
.s
;
909 return net
->u_
.ff
.d
.pin
;
912 assert(idx
< net
->u_
.concat
.inputs
);
913 return net
->u_
.concat
.pins
[idx
+1];
915 case IVL_LPM_PART_VP
:
916 case IVL_LPM_PART_PV
:
917 case IVL_LPM_PART_BI
:
920 return net
->u_
.part
.a
;
922 return net
->u_
.part
.s
;
926 return net
->u_
.repeat
.a
;
929 // Skip the return port.
930 assert(idx
< (net
->u_
.sfunc
.ports
-1));
931 return net
->u_
.sfunc
.pins
[idx
+1];
934 // Skip the return port.
935 assert(idx
< (net
->u_
.ufunc
.ports
-1));
936 return net
->u_
.ufunc
.pins
[idx
+1];
944 extern "C" ivl_nexus_t
ivl_lpm_datab(ivl_lpm_t net
, unsigned idx
)
946 cerr
<< "ANACHRONISM: Call to anachronistic ivl_lpm_datab." << endl
;
961 return net
->u_
.arith
.b
;
971 * This function returns the hierarchical name for the LPM device. The
972 * name needs to be built up from the scope name and the lpm base
975 * Anachronism: This function is provided for
976 * compatibility. Eventually, it will be removed.
978 extern "C" const char* ivl_lpm_name(ivl_lpm_t net
)
980 static char*name_buffer
= 0;
981 static unsigned name_size
= 0;
983 ivl_scope_t scope
= ivl_lpm_scope(net
);
984 const char*sn
= ivl_scope_name(scope
);
986 unsigned need
= strlen(sn
) + 1 + strlen(net
->name
) + 1;
987 if (need
> name_size
) {
988 name_buffer
= (char*)realloc(name_buffer
, need
);
992 strcpy(name_buffer
, sn
);
993 char*tmp
= name_buffer
+ strlen(sn
);
995 strcpy(tmp
, net
->name
);
1000 extern "C" ivl_nexus_t
ivl_lpm_q(ivl_lpm_t net
, unsigned idx
)
1004 switch (net
->type
) {
1006 case IVL_LPM_DIVIDE
:
1012 return net
->u_
.arith
.q
;
1014 case IVL_LPM_CMP_GE
:
1015 case IVL_LPM_CMP_GT
:
1016 case IVL_LPM_CMP_EQ
:
1017 case IVL_LPM_CMP_NE
:
1018 case IVL_LPM_CMP_EEQ
:
1019 case IVL_LPM_CMP_NEE
:
1021 return net
->u_
.arith
.q
;
1025 return net
->u_
.ff
.q
.pin
;
1029 return net
->u_
.mux
.q
;
1031 case IVL_LPM_RE_AND
:
1033 case IVL_LPM_RE_XOR
:
1034 case IVL_LPM_RE_NAND
:
1035 case IVL_LPM_RE_NOR
:
1036 case IVL_LPM_RE_XNOR
:
1037 case IVL_LPM_SIGN_EXT
:
1039 return net
->u_
.reduce
.q
;
1041 case IVL_LPM_SHIFTL
:
1042 case IVL_LPM_SHIFTR
:
1044 return net
->u_
.shift
.q
;
1048 return net
->u_
.sfunc
.pins
[0];
1052 return net
->u_
.ufunc
.pins
[0];
1054 case IVL_LPM_CONCAT
:
1055 return net
->u_
.concat
.pins
[0];
1057 case IVL_LPM_PART_VP
:
1058 case IVL_LPM_PART_PV
:
1059 case IVL_LPM_PART_BI
:
1061 return net
->u_
.part
.q
;
1063 case IVL_LPM_REPEAT
:
1065 return net
->u_
.repeat
.q
;
1069 return net
->u_
.array
.q
;
1077 extern "C" ivl_scope_t
ivl_lpm_scope(ivl_lpm_t net
)
1083 extern "C" ivl_nexus_t
ivl_lpm_select(ivl_lpm_t net
)
1085 switch (net
->type
) {
1088 return net
->u_
.mux
.s
;
1091 return net
->u_
.array
.a
;
1099 extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net
)
1101 switch (net
->type
) {
1103 return net
->u_
.mux
.swid
;
1105 return net
->u_
.array
.swid
;
1106 case IVL_LPM_CONCAT
:
1107 return net
->u_
.concat
.inputs
;
1114 extern "C" int ivl_lpm_signed(ivl_lpm_t net
)
1117 switch (net
->type
) {
1122 case IVL_LPM_CMP_EEQ
:
1123 case IVL_LPM_CMP_EQ
:
1124 case IVL_LPM_CMP_GE
:
1125 case IVL_LPM_CMP_GT
:
1126 case IVL_LPM_CMP_NE
:
1127 case IVL_LPM_CMP_NEE
:
1128 case IVL_LPM_DIVIDE
:
1133 return net
->u_
.arith
.signed_flag
;
1134 case IVL_LPM_RE_AND
:
1136 case IVL_LPM_RE_XOR
:
1137 case IVL_LPM_RE_NAND
:
1138 case IVL_LPM_RE_NOR
:
1139 case IVL_LPM_RE_XNOR
:
1141 case IVL_LPM_SHIFTL
:
1142 case IVL_LPM_SHIFTR
:
1143 return net
->u_
.shift
.signed_flag
;
1144 case IVL_LPM_SIGN_EXT
: // Sign extend is always signed.
1150 case IVL_LPM_CONCAT
: // Concatenations are always unsigned
1152 case IVL_LPM_PART_VP
:
1153 case IVL_LPM_PART_PV
:
1154 case IVL_LPM_PART_BI
:
1155 return net
->u_
.part
.signed_flag
;
1156 case IVL_LPM_REPEAT
:
1158 case IVL_LPM_ARRAY
: // Array ports take the signedness of the array.
1159 return net
->u_
.array
.sig
->signed_
;
1166 extern "C" unsigned ivl_lpm_size(ivl_lpm_t net
)
1168 switch (net
->type
) {
1170 return net
->u_
.mux
.size
;
1172 return net
->u_
.sfunc
.ports
- 1;
1174 return net
->u_
.ufunc
.ports
- 1;
1175 case IVL_LPM_REPEAT
:
1176 return net
->u_
.repeat
.count
;
1183 extern "C" const char* ivl_lpm_string(ivl_lpm_t net
)
1185 assert(net
->type
== IVL_LPM_SFUNC
);
1186 return net
->u_
.sfunc
.fun_name
;
1189 extern "C" ivl_lpm_type_t
ivl_lpm_type(ivl_lpm_t net
)
1194 extern "C" unsigned ivl_lpm_width(ivl_lpm_t net
)
1200 extern "C" ivl_expr_t
ivl_lval_mux(ivl_lval_t net
)
1203 if (net
->type_
== IVL_LVAL_MUX
)
1208 extern "C" ivl_expr_t
ivl_lval_idx(ivl_lval_t net
)
1212 if (net
->type_
== IVL_LVAL_ARR
)
1217 extern "C" ivl_expr_t
ivl_lval_part_off(ivl_lval_t net
)
1223 extern "C" unsigned ivl_lval_width(ivl_lval_t net
)
1229 extern "C" ivl_signal_t
ivl_lval_sig(ivl_lval_t net
)
1232 switch (net
->type_
) {
1244 * The nexus name is rarely needed. (Shouldn't be needed at all!) This
1245 * function will calculate the name if it is not already calculated.
1247 extern "C" const char* ivl_nexus_name(ivl_nexus_t net
)
1250 if (net
->name_
== 0) {
1251 net
->name_
= api_strings
.add(net
->nexus_
->name());
1256 extern "C" void* ivl_nexus_get_private(ivl_nexus_t net
)
1259 return net
->private_data
;
1262 extern "C" void ivl_nexus_set_private(ivl_nexus_t net
, void*data
)
1265 net
->private_data
= data
;
1268 extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net
)
1274 extern "C" ivl_nexus_ptr_t
ivl_nexus_ptr(ivl_nexus_t net
, unsigned idx
)
1277 assert(idx
< net
->nptr_
);
1278 return net
->ptrs_
+ idx
;
1281 extern "C" ivl_drive_t
ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net
)
1284 return (ivl_drive_t
)(net
->drive0
);
1287 extern "C" ivl_drive_t
ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net
)
1290 return (ivl_drive_t
)(net
->drive1
);
1293 extern "C" unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net
)
1299 extern "C" ivl_net_const_t
ivl_nexus_ptr_con(ivl_nexus_ptr_t net
)
1303 if (net
->type_
!= __NEXUS_PTR_CON
)
1308 extern "C" ivl_net_logic_t
ivl_nexus_ptr_log(ivl_nexus_ptr_t net
)
1312 if (net
->type_
!= __NEXUS_PTR_LOG
)
1317 extern "C" ivl_lpm_t
ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net
)
1321 if (net
->type_
!= __NEXUS_PTR_LPM
)
1326 extern "C" ivl_signal_t
ivl_nexus_ptr_sig(ivl_nexus_ptr_t net
)
1330 if (net
->type_
!= __NEXUS_PTR_SIG
)
1335 extern "C" const char* ivl_parameter_basename(ivl_parameter_t net
)
1338 return net
->basename
;
1341 extern "C" ivl_expr_t
ivl_parameter_expr(ivl_parameter_t net
)
1347 extern "C" const char* ivl_parameter_file(ivl_parameter_t net
)
1350 return net
->file
.str();
1353 extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net
)
1359 extern "C" ivl_scope_t
ivl_parameter_scope(ivl_parameter_t net
)
1365 extern "C" ivl_nexus_t
ivl_path_condit(ivl_delaypath_t obj
)
1371 extern "C" int ivl_path_is_condit(ivl_delaypath_t obj
)
1374 return obj
->conditional
? 1 : 0;
1377 extern uint64_t ivl_path_delay(ivl_delaypath_t obj
, ivl_path_edge_t edg
)
1380 return obj
->delay
[edg
];
1383 extern ivl_scope_t
ivl_path_scope(ivl_delaypath_t obj
)
1390 extern ivl_nexus_t
ivl_path_source(ivl_delaypath_t net
)
1395 extern int ivl_path_source_posedge(ivl_delaypath_t net
)
1397 return net
->posedge
? 1 : 0;
1400 extern int ivl_path_source_negedge(ivl_delaypath_t net
)
1402 return net
->negedge
? 1 : 0;
1405 extern "C" ivl_process_type_t
ivl_process_type(ivl_process_t net
)
1410 extern "C" ivl_scope_t
ivl_process_scope(ivl_process_t net
)
1415 extern "C" ivl_statement_t
ivl_process_stmt(ivl_process_t net
)
1420 extern "C" unsigned ivl_process_attr_cnt(ivl_process_t net
)
1425 extern "C" ivl_attribute_t
ivl_process_attr_val(ivl_process_t net
,
1428 assert(idx
< net
->nattr
);
1429 return net
->attr
+ idx
;
1432 extern "C" unsigned ivl_scope_attr_cnt(ivl_scope_t net
)
1438 extern "C" ivl_attribute_t
ivl_scope_attr_val(ivl_scope_t net
,
1441 assert(idx
< net
->nattr
);
1442 return net
->attr
+ idx
;
1445 extern "C" const char* ivl_scope_basename(ivl_scope_t net
)
1452 extern "C" int ivl_scope_children(ivl_scope_t net
,
1456 for (ivl_scope_t cur
= net
->child_
; cur
; cur
= cur
->sibling_
) {
1457 int rc
= func(cur
, cd
);
1465 extern "C" ivl_statement_t
ivl_scope_def(ivl_scope_t net
)
1471 extern "C" const char*ivl_scope_def_file(ivl_scope_t net
)
1474 return net
->def_file
.str();
1477 extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net
)
1480 return net
->def_lineno
;
1483 extern "C" unsigned ivl_scope_events(ivl_scope_t net
)
1486 return net
->nevent_
;
1489 extern "C" ivl_event_t
ivl_scope_event(ivl_scope_t net
, unsigned idx
)
1492 assert(idx
< net
->nevent_
);
1493 return net
->event_
[idx
];
1496 extern "C" const char*ivl_scope_file(ivl_scope_t net
)
1499 return net
->file
.str();
1502 extern "C" unsigned ivl_scope_lineno(ivl_scope_t net
)
1508 extern "C" unsigned ivl_scope_logs(ivl_scope_t net
)
1514 extern "C" ivl_net_logic_t
ivl_scope_log(ivl_scope_t net
, unsigned idx
)
1517 assert(idx
< net
->nlog_
);
1518 return net
->log_
[idx
];
1521 extern "C" unsigned ivl_scope_lpms(ivl_scope_t net
)
1527 extern "C" ivl_lpm_t
ivl_scope_lpm(ivl_scope_t net
, unsigned idx
)
1530 assert(idx
< net
->nlpm_
);
1531 return net
->lpm_
[idx
];
1534 static unsigned scope_name_len(ivl_scope_t net
)
1538 for (ivl_scope_t cur
= net
; cur
; cur
= cur
->parent
)
1539 len
+= strlen(cur
->name_
) + 1;
1544 static void push_scope_basename(ivl_scope_t net
, char*buf
)
1546 if (net
->parent
== 0) {
1547 strcpy(buf
, net
->name_
);
1551 push_scope_basename(net
->parent
, buf
);
1553 strcat(buf
, net
->name_
);
1556 extern "C" const char* ivl_scope_name(ivl_scope_t net
)
1558 static char*name_buffer
= 0;
1559 static unsigned name_size
= 0;
1561 if (net
->parent
== 0)
1564 unsigned needlen
= scope_name_len(net
);
1566 if (name_size
< needlen
) {
1567 name_buffer
= (char*)realloc(name_buffer
, needlen
);
1568 name_size
= needlen
;
1572 push_scope_basename(net
, name_buffer
);
1577 extern "C" unsigned ivl_scope_params(ivl_scope_t net
)
1580 return net
->nparam_
;
1583 extern "C" ivl_parameter_t
ivl_scope_param(ivl_scope_t net
, unsigned idx
)
1586 assert(idx
< net
->nparam_
);
1587 return net
->param_
+ idx
;
1590 extern "C" ivl_scope_t
ivl_scope_parent(ivl_scope_t net
)
1596 extern "C" unsigned ivl_scope_ports(ivl_scope_t net
)
1599 assert(net
->type_
== IVL_SCT_FUNCTION
);
1603 extern "C" ivl_signal_t
ivl_scope_port(ivl_scope_t net
, unsigned idx
)
1606 assert(net
->type_
== IVL_SCT_FUNCTION
);
1607 assert(idx
< net
->ports
);
1608 return net
->port
[idx
];
1611 extern "C" unsigned ivl_scope_sigs(ivl_scope_t net
)
1617 extern "C" ivl_signal_t
ivl_scope_sig(ivl_scope_t net
, unsigned idx
)
1620 assert(idx
< net
->nsigs_
);
1621 return net
->sigs_
[idx
];
1624 extern "C" int ivl_scope_time_precision(ivl_scope_t net
)
1627 return net
->time_precision
;
1630 extern "C" int ivl_scope_time_units(ivl_scope_t net
)
1633 return net
->time_units
;
1636 extern "C" ivl_scope_type_t
ivl_scope_type(ivl_scope_t net
)
1642 extern "C" const char* ivl_scope_tname(ivl_scope_t net
)
1648 extern "C" int ivl_signal_array_base(ivl_signal_t net
)
1650 return net
->array_base
;
1653 extern "C" unsigned ivl_signal_array_count(ivl_signal_t net
)
1655 return net
->array_words
;
1658 extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net
)
1660 return net
->array_dimensions_
;
1663 extern "C" const char* ivl_signal_attr(ivl_signal_t net
, const char*key
)
1665 if (net
->nattr
== 0)
1668 for (unsigned idx
= 0 ; idx
< net
->nattr
; idx
+= 1)
1670 if (strcmp(key
, net
->attr
[idx
].key
) == 0)
1671 return net
->attr
[idx
].type
== IVL_ATT_STR
1672 ? net
->attr
[idx
].val
.str
1678 extern "C" unsigned ivl_signal_attr_cnt(ivl_signal_t net
)
1683 extern "C" ivl_attribute_t
ivl_signal_attr_val(ivl_signal_t net
, unsigned idx
)
1685 assert(idx
< net
->nattr
);
1686 return net
->attr
+ idx
;
1689 extern "C" const char* ivl_signal_basename(ivl_signal_t net
)
1694 extern "C" const char* ivl_signal_name(ivl_signal_t net
)
1696 static char*name_buffer
= 0;
1697 static unsigned name_size
= 0;
1699 unsigned needlen
= scope_name_len(net
->scope_
);
1700 needlen
+= strlen(net
->name_
) + 2;
1702 if (name_size
< needlen
) {
1703 name_buffer
= (char*)realloc(name_buffer
, needlen
);
1704 name_size
= needlen
;
1707 push_scope_basename(net
->scope_
, name_buffer
);
1708 strcat(name_buffer
, ".");
1709 strcat(name_buffer
, net
->name_
);
1714 extern "C" ivl_nexus_t
ivl_signal_nex(ivl_signal_t net
, unsigned word
)
1716 assert(word
< net
->array_words
);
1717 if (net
->array_words
> 1)
1718 return net
->pins
[word
];
1723 extern "C" int ivl_signal_msb(ivl_signal_t net
)
1725 assert(net
->lsb_dist
== 1 || net
->lsb_dist
== -1);
1726 return net
->lsb_index
+ net
->lsb_dist
* (net
->width_
- 1);
1729 extern "C" int ivl_signal_lsb(ivl_signal_t net
)
1731 return net
->lsb_index
;
1734 extern "C" unsigned ivl_signal_width(ivl_signal_t net
)
1739 extern "C" ivl_signal_port_t
ivl_signal_port(ivl_signal_t net
)
1744 extern "C" int ivl_signal_local(ivl_signal_t net
)
1749 extern "C" int ivl_signal_signed(ivl_signal_t net
)
1751 return net
->signed_
;
1754 extern "C" const char* ivl_signal_file(ivl_signal_t net
)
1757 return net
->file
.str();
1760 extern "C" unsigned ivl_signal_lineno(ivl_signal_t net
)
1766 extern "C" int ivl_signal_integer(ivl_signal_t net
)
1771 extern "C" ivl_variable_type_t
ivl_signal_data_type(ivl_signal_t net
)
1773 return net
->data_type
;
1776 extern "C" unsigned ivl_signal_npath(ivl_signal_t net
)
1781 extern "C" ivl_delaypath_t
ivl_signal_path(ivl_signal_t net
, unsigned idx
)
1783 assert(idx
< net
->npath
);
1784 return net
->path
+ idx
;
1787 extern "C" ivl_signal_type_t
ivl_signal_type(ivl_signal_t net
)
1792 extern "C" ivl_statement_type_t
ivl_statement_type(ivl_statement_t net
)
1797 extern "C" const char* ivl_stmt_file(ivl_statement_t net
)
1799 return net
->file
.str();
1802 extern "C" unsigned ivl_stmt_lineno(ivl_statement_t net
)
1807 extern "C" ivl_scope_t
ivl_stmt_block_scope(ivl_statement_t net
)
1809 switch (net
->type_
) {
1812 return net
->u_
.block_
.scope
;
1819 extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net
)
1821 switch (net
->type_
) {
1824 return net
->u_
.block_
.nstmt_
;
1831 extern "C" ivl_statement_t
ivl_stmt_block_stmt(ivl_statement_t net
,
1834 switch (net
->type_
) {
1837 return net
->u_
.block_
.stmt_
+ i
;
1844 extern "C" ivl_scope_t
ivl_stmt_call(ivl_statement_t net
)
1846 switch (net
->type_
) {
1847 case IVL_ST_DISABLE
:
1848 return net
->u_
.disable_
.scope
;
1851 return net
->u_
.utask_
.def
;
1858 extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net
)
1860 switch (net
->type_
) {
1865 return net
->u_
.case_
.ncase
;
1872 extern "C" ivl_expr_t
ivl_stmt_case_expr(ivl_statement_t net
, unsigned idx
)
1874 switch (net
->type_
) {
1879 assert(idx
< net
->u_
.case_
.ncase
);
1880 return net
->u_
.case_
.case_ex
[idx
];
1888 extern "C" ivl_statement_t
ivl_stmt_case_stmt(ivl_statement_t net
, unsigned idx
)
1890 switch (net
->type_
) {
1895 assert(idx
< net
->u_
.case_
.ncase
);
1896 return net
->u_
.case_
.case_st
+ idx
;
1904 extern "C" ivl_expr_t
ivl_stmt_cond_expr(ivl_statement_t net
)
1906 switch (net
->type_
) {
1908 return net
->u_
.condit_
.cond_
;
1914 return net
->u_
.case_
.cond
;
1918 return net
->u_
.while_
.cond_
;
1926 extern "C" ivl_statement_t
ivl_stmt_cond_false(ivl_statement_t net
)
1928 assert(net
->type_
== IVL_ST_CONDIT
);
1929 if (net
->u_
.condit_
.stmt_
[1].type_
== IVL_ST_NONE
)
1932 return net
->u_
.condit_
.stmt_
+ 1;
1935 extern "C" ivl_statement_t
ivl_stmt_cond_true(ivl_statement_t net
)
1937 assert(net
->type_
== IVL_ST_CONDIT
);
1938 if (net
->u_
.condit_
.stmt_
[0].type_
== IVL_ST_NONE
)
1941 return net
->u_
.condit_
.stmt_
+ 0;
1944 extern "C" ivl_expr_t
ivl_stmt_delay_expr(ivl_statement_t net
)
1946 switch (net
->type_
) {
1948 case IVL_ST_ASSIGN_NB
:
1949 return net
->u_
.assign_
.delay
;
1952 return net
->u_
.delayx_
.expr
;
1960 extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net
)
1962 assert(net
->type_
== IVL_ST_DELAY
);
1963 return net
->u_
.delay_
.delay_
;
1966 extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net
)
1968 switch (net
->type_
) {
1970 return net
->u_
.wait_
.nevent
;
1972 case IVL_ST_TRIGGER
:
1981 extern "C" ivl_event_t
ivl_stmt_events(ivl_statement_t net
, unsigned idx
)
1983 switch (net
->type_
) {
1985 assert(idx
< net
->u_
.wait_
.nevent
);
1986 if (net
->u_
.wait_
.nevent
== 1)
1987 return net
->u_
.wait_
.event
;
1989 return net
->u_
.wait_
.events
[idx
];
1991 case IVL_ST_TRIGGER
:
1993 return net
->u_
.wait_
.event
;
2000 extern "C" ivl_lval_t
ivl_stmt_lval(ivl_statement_t net
, unsigned idx
)
2002 switch (net
->type_
) {
2004 case IVL_ST_ASSIGN_NB
:
2005 case IVL_ST_CASSIGN
:
2006 case IVL_ST_DEASSIGN
:
2008 case IVL_ST_RELEASE
:
2009 assert(idx
< net
->u_
.assign_
.lvals_
);
2010 return net
->u_
.assign_
.lval_
+ idx
;
2018 extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net
)
2020 switch (net
->type_
) {
2022 case IVL_ST_ASSIGN_NB
:
2023 case IVL_ST_CASSIGN
:
2024 case IVL_ST_DEASSIGN
:
2026 case IVL_ST_RELEASE
:
2027 return net
->u_
.assign_
.lvals_
;
2035 extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net
)
2037 assert((net
->type_
== IVL_ST_ASSIGN
)
2038 || (net
->type_
== IVL_ST_ASSIGN_NB
)
2039 || (net
->type_
== IVL_ST_CASSIGN
)
2040 || (net
->type_
== IVL_ST_DEASSIGN
)
2041 || (net
->type_
== IVL_ST_FORCE
)
2042 || (net
->type_
== IVL_ST_RELEASE
));
2047 struct ivl_lval_s
*lvals
;
2048 nlvals
= net
->u_
.assign_
.lvals_
;
2049 lvals
= net
->u_
.assign_
.lval_
;
2051 for (unsigned idx
= 0 ; idx
< nlvals
; idx
+= 1) {
2052 ivl_lval_t cur
= lvals
+ idx
;
2053 switch(cur
->type_
) {
2059 sum
+= ivl_lval_width(cur
);
2069 extern "C" const char* ivl_stmt_name(ivl_statement_t net
)
2071 switch (net
->type_
) {
2073 return net
->u_
.stask_
.name_
;
2081 extern "C" ivl_expr_t
ivl_stmt_parm(ivl_statement_t net
, unsigned idx
)
2083 switch (net
->type_
) {
2085 assert(idx
< net
->u_
.stask_
.nparm_
);
2086 return net
->u_
.stask_
.parms_
[idx
];
2094 extern "C" unsigned ivl_stmt_parm_count(ivl_statement_t net
)
2096 switch (net
->type_
) {
2098 return net
->u_
.stask_
.nparm_
;
2105 extern "C" ivl_expr_t
ivl_stmt_rval(ivl_statement_t net
)
2107 switch (net
->type_
) {
2109 case IVL_ST_ASSIGN_NB
:
2110 case IVL_ST_CASSIGN
:
2112 return net
->u_
.assign_
.rval_
;
2120 extern "C" ivl_statement_t
ivl_stmt_sub_stmt(ivl_statement_t net
)
2122 switch (net
->type_
) {
2124 return net
->u_
.delay_
.stmt_
;
2126 return net
->u_
.delayx_
.stmt_
;
2127 case IVL_ST_FOREVER
:
2128 return net
->u_
.forever_
.stmt_
;
2130 return net
->u_
.wait_
.stmt_
;
2133 return net
->u_
.while_
.stmt_
;