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
)
869 return net
->u_
.arith
.a
;
872 case IVL_LPM_CMP_EEQ
:
877 case IVL_LPM_CMP_NEE
:
885 return net
->u_
.arith
.a
;
887 return net
->u_
.arith
.b
;
890 assert(idx
< net
->u_
.mux
.size
);
891 return net
->u_
.mux
.d
[idx
];
896 case IVL_LPM_RE_NAND
:
898 case IVL_LPM_RE_XNOR
:
899 case IVL_LPM_SIGN_EXT
:
901 return net
->u_
.reduce
.a
;
907 return net
->u_
.shift
.d
;
909 return net
->u_
.shift
.s
;
913 return net
->u_
.ff
.d
.pin
;
916 assert(idx
< net
->u_
.concat
.inputs
);
917 return net
->u_
.concat
.pins
[idx
+1];
919 case IVL_LPM_PART_VP
:
920 case IVL_LPM_PART_PV
:
921 case IVL_LPM_PART_BI
:
924 return net
->u_
.part
.a
;
926 return net
->u_
.part
.s
;
930 return net
->u_
.repeat
.a
;
933 // Skip the return port.
934 assert(idx
< (net
->u_
.sfunc
.ports
-1));
935 return net
->u_
.sfunc
.pins
[idx
+1];
938 // Skip the return port.
939 assert(idx
< (net
->u_
.ufunc
.ports
-1));
940 return net
->u_
.ufunc
.pins
[idx
+1];
948 extern "C" ivl_nexus_t
ivl_lpm_datab(ivl_lpm_t net
, unsigned idx
)
950 cerr
<< "ANACHRONISM: Call to anachronistic ivl_lpm_datab." << endl
;
965 return net
->u_
.arith
.b
;
975 * This function returns the hierarchical name for the LPM device. The
976 * name needs to be built up from the scope name and the lpm base
979 * Anachronism: This function is provided for
980 * compatibility. Eventually, it will be removed.
982 extern "C" const char* ivl_lpm_name(ivl_lpm_t net
)
984 static char*name_buffer
= 0;
985 static unsigned name_size
= 0;
987 ivl_scope_t scope
= ivl_lpm_scope(net
);
988 const char*sn
= ivl_scope_name(scope
);
990 unsigned need
= strlen(sn
) + 1 + strlen(net
->name
) + 1;
991 if (need
> name_size
) {
992 name_buffer
= (char*)realloc(name_buffer
, need
);
996 strcpy(name_buffer
, sn
);
997 char*tmp
= name_buffer
+ strlen(sn
);
999 strcpy(tmp
, net
->name
);
1004 extern "C" ivl_nexus_t
ivl_lpm_q(ivl_lpm_t net
, unsigned idx
)
1008 switch (net
->type
) {
1011 case IVL_LPM_DIVIDE
:
1017 return net
->u_
.arith
.q
;
1019 case IVL_LPM_CMP_GE
:
1020 case IVL_LPM_CMP_GT
:
1021 case IVL_LPM_CMP_EQ
:
1022 case IVL_LPM_CMP_NE
:
1023 case IVL_LPM_CMP_EEQ
:
1024 case IVL_LPM_CMP_NEE
:
1026 return net
->u_
.arith
.q
;
1030 return net
->u_
.ff
.q
.pin
;
1034 return net
->u_
.mux
.q
;
1036 case IVL_LPM_RE_AND
:
1038 case IVL_LPM_RE_XOR
:
1039 case IVL_LPM_RE_NAND
:
1040 case IVL_LPM_RE_NOR
:
1041 case IVL_LPM_RE_XNOR
:
1042 case IVL_LPM_SIGN_EXT
:
1044 return net
->u_
.reduce
.q
;
1046 case IVL_LPM_SHIFTL
:
1047 case IVL_LPM_SHIFTR
:
1049 return net
->u_
.shift
.q
;
1053 return net
->u_
.sfunc
.pins
[0];
1057 return net
->u_
.ufunc
.pins
[0];
1059 case IVL_LPM_CONCAT
:
1060 return net
->u_
.concat
.pins
[0];
1062 case IVL_LPM_PART_VP
:
1063 case IVL_LPM_PART_PV
:
1064 case IVL_LPM_PART_BI
:
1066 return net
->u_
.part
.q
;
1068 case IVL_LPM_REPEAT
:
1070 return net
->u_
.repeat
.q
;
1074 return net
->u_
.array
.q
;
1082 extern "C" ivl_scope_t
ivl_lpm_scope(ivl_lpm_t net
)
1088 extern "C" ivl_nexus_t
ivl_lpm_select(ivl_lpm_t net
)
1090 switch (net
->type
) {
1093 return net
->u_
.mux
.s
;
1096 return net
->u_
.array
.a
;
1104 extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net
)
1106 switch (net
->type
) {
1108 return net
->u_
.mux
.swid
;
1110 return net
->u_
.array
.swid
;
1111 case IVL_LPM_CONCAT
:
1112 return net
->u_
.concat
.inputs
;
1119 extern "C" int ivl_lpm_signed(ivl_lpm_t net
)
1122 switch (net
->type
) {
1128 case IVL_LPM_CMP_EEQ
:
1129 case IVL_LPM_CMP_EQ
:
1130 case IVL_LPM_CMP_GE
:
1131 case IVL_LPM_CMP_GT
:
1132 case IVL_LPM_CMP_NE
:
1133 case IVL_LPM_CMP_NEE
:
1134 case IVL_LPM_DIVIDE
:
1139 return net
->u_
.arith
.signed_flag
;
1140 case IVL_LPM_RE_AND
:
1142 case IVL_LPM_RE_XOR
:
1143 case IVL_LPM_RE_NAND
:
1144 case IVL_LPM_RE_NOR
:
1145 case IVL_LPM_RE_XNOR
:
1147 case IVL_LPM_SHIFTL
:
1148 case IVL_LPM_SHIFTR
:
1149 return net
->u_
.shift
.signed_flag
;
1150 case IVL_LPM_SIGN_EXT
: // Sign extend is always signed.
1156 case IVL_LPM_CONCAT
: // Concatenations are always unsigned
1158 case IVL_LPM_PART_VP
:
1159 case IVL_LPM_PART_PV
:
1160 case IVL_LPM_PART_BI
:
1161 return net
->u_
.part
.signed_flag
;
1162 case IVL_LPM_REPEAT
:
1164 case IVL_LPM_ARRAY
: // Array ports take the signedness of the array.
1165 return net
->u_
.array
.sig
->signed_
;
1172 extern "C" unsigned ivl_lpm_size(ivl_lpm_t net
)
1174 switch (net
->type
) {
1176 return net
->u_
.mux
.size
;
1178 return net
->u_
.sfunc
.ports
- 1;
1180 return net
->u_
.ufunc
.ports
- 1;
1181 case IVL_LPM_REPEAT
:
1182 return net
->u_
.repeat
.count
;
1189 extern "C" const char* ivl_lpm_string(ivl_lpm_t net
)
1191 assert(net
->type
== IVL_LPM_SFUNC
);
1192 return net
->u_
.sfunc
.fun_name
;
1195 extern "C" ivl_lpm_type_t
ivl_lpm_type(ivl_lpm_t net
)
1200 extern "C" unsigned ivl_lpm_width(ivl_lpm_t net
)
1206 extern "C" ivl_expr_t
ivl_lval_mux(ivl_lval_t net
)
1209 if (net
->type_
== IVL_LVAL_MUX
)
1214 extern "C" ivl_expr_t
ivl_lval_idx(ivl_lval_t net
)
1218 if (net
->type_
== IVL_LVAL_ARR
)
1223 extern "C" ivl_expr_t
ivl_lval_part_off(ivl_lval_t net
)
1229 extern "C" unsigned ivl_lval_width(ivl_lval_t net
)
1235 extern "C" ivl_signal_t
ivl_lval_sig(ivl_lval_t net
)
1238 switch (net
->type_
) {
1250 * The nexus name is rarely needed. (Shouldn't be needed at all!) This
1251 * function will calculate the name if it is not already calculated.
1253 extern "C" const char* ivl_nexus_name(ivl_nexus_t net
)
1256 if (net
->name_
== 0) {
1257 net
->name_
= api_strings
.add(net
->nexus_
->name());
1262 extern "C" void* ivl_nexus_get_private(ivl_nexus_t net
)
1265 return net
->private_data
;
1268 extern "C" void ivl_nexus_set_private(ivl_nexus_t net
, void*data
)
1271 net
->private_data
= data
;
1274 extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net
)
1280 extern "C" ivl_nexus_ptr_t
ivl_nexus_ptr(ivl_nexus_t net
, unsigned idx
)
1283 assert(idx
< net
->nptr_
);
1284 return net
->ptrs_
+ idx
;
1287 extern "C" ivl_drive_t
ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net
)
1290 return (ivl_drive_t
)(net
->drive0
);
1293 extern "C" ivl_drive_t
ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net
)
1296 return (ivl_drive_t
)(net
->drive1
);
1299 extern "C" unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net
)
1305 extern "C" ivl_net_const_t
ivl_nexus_ptr_con(ivl_nexus_ptr_t net
)
1309 if (net
->type_
!= __NEXUS_PTR_CON
)
1314 extern "C" ivl_net_logic_t
ivl_nexus_ptr_log(ivl_nexus_ptr_t net
)
1318 if (net
->type_
!= __NEXUS_PTR_LOG
)
1323 extern "C" ivl_lpm_t
ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net
)
1327 if (net
->type_
!= __NEXUS_PTR_LPM
)
1332 extern "C" ivl_signal_t
ivl_nexus_ptr_sig(ivl_nexus_ptr_t net
)
1336 if (net
->type_
!= __NEXUS_PTR_SIG
)
1341 extern "C" const char* ivl_parameter_basename(ivl_parameter_t net
)
1344 return net
->basename
;
1347 extern "C" ivl_expr_t
ivl_parameter_expr(ivl_parameter_t net
)
1353 extern "C" const char* ivl_parameter_file(ivl_parameter_t net
)
1356 return net
->file
.str();
1359 extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net
)
1365 extern "C" ivl_scope_t
ivl_parameter_scope(ivl_parameter_t net
)
1371 extern "C" ivl_nexus_t
ivl_path_condit(ivl_delaypath_t obj
)
1377 extern "C" int ivl_path_is_condit(ivl_delaypath_t obj
)
1380 return obj
->conditional
? 1 : 0;
1383 extern uint64_t ivl_path_delay(ivl_delaypath_t obj
, ivl_path_edge_t edg
)
1386 return obj
->delay
[edg
];
1389 extern ivl_scope_t
ivl_path_scope(ivl_delaypath_t obj
)
1396 extern ivl_nexus_t
ivl_path_source(ivl_delaypath_t net
)
1401 extern int ivl_path_source_posedge(ivl_delaypath_t net
)
1403 return net
->posedge
? 1 : 0;
1406 extern int ivl_path_source_negedge(ivl_delaypath_t net
)
1408 return net
->negedge
? 1 : 0;
1411 extern "C" ivl_process_type_t
ivl_process_type(ivl_process_t net
)
1416 extern "C" ivl_scope_t
ivl_process_scope(ivl_process_t net
)
1421 extern "C" ivl_statement_t
ivl_process_stmt(ivl_process_t net
)
1426 extern "C" unsigned ivl_process_attr_cnt(ivl_process_t net
)
1431 extern "C" ivl_attribute_t
ivl_process_attr_val(ivl_process_t net
,
1434 assert(idx
< net
->nattr
);
1435 return net
->attr
+ idx
;
1438 extern "C" unsigned ivl_scope_attr_cnt(ivl_scope_t net
)
1444 extern "C" ivl_attribute_t
ivl_scope_attr_val(ivl_scope_t net
,
1447 assert(idx
< net
->nattr
);
1448 return net
->attr
+ idx
;
1451 extern "C" const char* ivl_scope_basename(ivl_scope_t net
)
1458 extern "C" int ivl_scope_children(ivl_scope_t net
,
1462 for (ivl_scope_t cur
= net
->child_
; cur
; cur
= cur
->sibling_
) {
1463 int rc
= func(cur
, cd
);
1471 extern "C" ivl_statement_t
ivl_scope_def(ivl_scope_t net
)
1477 extern "C" const char*ivl_scope_def_file(ivl_scope_t net
)
1480 return net
->def_file
.str();
1483 extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net
)
1486 return net
->def_lineno
;
1489 extern "C" unsigned ivl_scope_events(ivl_scope_t net
)
1492 return net
->nevent_
;
1495 extern "C" ivl_event_t
ivl_scope_event(ivl_scope_t net
, unsigned idx
)
1498 assert(idx
< net
->nevent_
);
1499 return net
->event_
[idx
];
1502 extern "C" const char*ivl_scope_file(ivl_scope_t net
)
1505 return net
->file
.str();
1508 extern "C" unsigned ivl_scope_lineno(ivl_scope_t net
)
1514 extern "C" unsigned ivl_scope_logs(ivl_scope_t net
)
1520 extern "C" ivl_net_logic_t
ivl_scope_log(ivl_scope_t net
, unsigned idx
)
1523 assert(idx
< net
->nlog_
);
1524 return net
->log_
[idx
];
1527 extern "C" unsigned ivl_scope_lpms(ivl_scope_t net
)
1533 extern "C" ivl_lpm_t
ivl_scope_lpm(ivl_scope_t net
, unsigned idx
)
1536 assert(idx
< net
->nlpm_
);
1537 return net
->lpm_
[idx
];
1540 static unsigned scope_name_len(ivl_scope_t net
)
1544 for (ivl_scope_t cur
= net
; cur
; cur
= cur
->parent
)
1545 len
+= strlen(cur
->name_
) + 1;
1550 static void push_scope_basename(ivl_scope_t net
, char*buf
)
1552 if (net
->parent
== 0) {
1553 strcpy(buf
, net
->name_
);
1557 push_scope_basename(net
->parent
, buf
);
1559 strcat(buf
, net
->name_
);
1562 extern "C" const char* ivl_scope_name(ivl_scope_t net
)
1564 static char*name_buffer
= 0;
1565 static unsigned name_size
= 0;
1567 if (net
->parent
== 0)
1570 unsigned needlen
= scope_name_len(net
);
1572 if (name_size
< needlen
) {
1573 name_buffer
= (char*)realloc(name_buffer
, needlen
);
1574 name_size
= needlen
;
1578 push_scope_basename(net
, name_buffer
);
1583 extern "C" unsigned ivl_scope_params(ivl_scope_t net
)
1586 return net
->nparam_
;
1589 extern "C" ivl_parameter_t
ivl_scope_param(ivl_scope_t net
, unsigned idx
)
1592 assert(idx
< net
->nparam_
);
1593 return net
->param_
+ idx
;
1596 extern "C" ivl_scope_t
ivl_scope_parent(ivl_scope_t net
)
1602 extern "C" unsigned ivl_scope_ports(ivl_scope_t net
)
1605 assert(net
->type_
== IVL_SCT_FUNCTION
);
1609 extern "C" ivl_signal_t
ivl_scope_port(ivl_scope_t net
, unsigned idx
)
1612 assert(net
->type_
== IVL_SCT_FUNCTION
);
1613 assert(idx
< net
->ports
);
1614 return net
->port
[idx
];
1617 extern "C" unsigned ivl_scope_sigs(ivl_scope_t net
)
1623 extern "C" ivl_signal_t
ivl_scope_sig(ivl_scope_t net
, unsigned idx
)
1626 assert(idx
< net
->nsigs_
);
1627 return net
->sigs_
[idx
];
1630 extern "C" unsigned ivl_scope_switches(ivl_scope_t net
)
1633 return net
->switches
.size();
1636 extern "C" ivl_switch_t
ivl_scope_switch(ivl_scope_t net
, unsigned idx
)
1639 assert(idx
< net
->switches
.size());
1640 return net
->switches
[idx
];
1643 extern "C" int ivl_scope_time_precision(ivl_scope_t net
)
1646 return net
->time_precision
;
1649 extern "C" int ivl_scope_time_units(ivl_scope_t net
)
1652 return net
->time_units
;
1655 extern "C" ivl_scope_type_t
ivl_scope_type(ivl_scope_t net
)
1661 extern "C" const char* ivl_scope_tname(ivl_scope_t net
)
1667 extern "C" int ivl_signal_array_base(ivl_signal_t net
)
1669 return net
->array_base
;
1672 extern "C" unsigned ivl_signal_array_count(ivl_signal_t net
)
1674 return net
->array_words
;
1677 extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net
)
1679 return net
->array_dimensions_
;
1682 extern "C" const char* ivl_signal_attr(ivl_signal_t net
, const char*key
)
1684 if (net
->nattr
== 0)
1687 for (unsigned idx
= 0 ; idx
< net
->nattr
; idx
+= 1)
1689 if (strcmp(key
, net
->attr
[idx
].key
) == 0)
1690 return net
->attr
[idx
].type
== IVL_ATT_STR
1691 ? net
->attr
[idx
].val
.str
1697 extern "C" unsigned ivl_signal_attr_cnt(ivl_signal_t net
)
1702 extern "C" ivl_attribute_t
ivl_signal_attr_val(ivl_signal_t net
, unsigned idx
)
1704 assert(idx
< net
->nattr
);
1705 return net
->attr
+ idx
;
1708 extern "C" const char* ivl_signal_basename(ivl_signal_t net
)
1713 extern "C" const char* ivl_signal_name(ivl_signal_t net
)
1715 static char*name_buffer
= 0;
1716 static unsigned name_size
= 0;
1718 unsigned needlen
= scope_name_len(net
->scope_
);
1719 needlen
+= strlen(net
->name_
) + 2;
1721 if (name_size
< needlen
) {
1722 name_buffer
= (char*)realloc(name_buffer
, needlen
);
1723 name_size
= needlen
;
1726 push_scope_basename(net
->scope_
, name_buffer
);
1727 strcat(name_buffer
, ".");
1728 strcat(name_buffer
, net
->name_
);
1733 extern "C" ivl_nexus_t
ivl_signal_nex(ivl_signal_t net
, unsigned word
)
1735 assert(word
< net
->array_words
);
1736 if (net
->array_words
> 1)
1737 return net
->pins
[word
];
1742 extern "C" int ivl_signal_msb(ivl_signal_t net
)
1744 assert(net
->lsb_dist
== 1 || net
->lsb_dist
== -1);
1745 return net
->lsb_index
+ net
->lsb_dist
* (net
->width_
- 1);
1748 extern "C" int ivl_signal_lsb(ivl_signal_t net
)
1750 return net
->lsb_index
;
1753 extern "C" unsigned ivl_signal_width(ivl_signal_t net
)
1758 extern "C" ivl_signal_port_t
ivl_signal_port(ivl_signal_t net
)
1763 extern "C" int ivl_signal_local(ivl_signal_t net
)
1768 extern "C" int ivl_signal_signed(ivl_signal_t net
)
1770 return net
->signed_
;
1773 extern "C" const char* ivl_signal_file(ivl_signal_t net
)
1776 return net
->file
.str();
1779 extern "C" unsigned ivl_signal_lineno(ivl_signal_t net
)
1785 extern "C" int ivl_signal_integer(ivl_signal_t net
)
1790 extern "C" ivl_variable_type_t
ivl_signal_data_type(ivl_signal_t net
)
1792 return net
->data_type
;
1795 extern "C" unsigned ivl_signal_npath(ivl_signal_t net
)
1800 extern "C" ivl_delaypath_t
ivl_signal_path(ivl_signal_t net
, unsigned idx
)
1802 assert(idx
< net
->npath
);
1803 return net
->path
+ idx
;
1806 extern "C" ivl_signal_type_t
ivl_signal_type(ivl_signal_t net
)
1811 extern "C" ivl_statement_type_t
ivl_statement_type(ivl_statement_t net
)
1816 extern "C" const char* ivl_stmt_file(ivl_statement_t net
)
1818 return net
->file
.str();
1821 extern "C" unsigned ivl_stmt_lineno(ivl_statement_t net
)
1826 extern "C" ivl_scope_t
ivl_stmt_block_scope(ivl_statement_t net
)
1828 switch (net
->type_
) {
1831 return net
->u_
.block_
.scope
;
1838 extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net
)
1840 switch (net
->type_
) {
1843 return net
->u_
.block_
.nstmt_
;
1850 extern "C" ivl_statement_t
ivl_stmt_block_stmt(ivl_statement_t net
,
1853 switch (net
->type_
) {
1856 return net
->u_
.block_
.stmt_
+ i
;
1863 extern "C" ivl_scope_t
ivl_stmt_call(ivl_statement_t net
)
1865 switch (net
->type_
) {
1866 case IVL_ST_DISABLE
:
1867 return net
->u_
.disable_
.scope
;
1870 return net
->u_
.utask_
.def
;
1877 extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net
)
1879 switch (net
->type_
) {
1884 return net
->u_
.case_
.ncase
;
1891 extern "C" ivl_expr_t
ivl_stmt_case_expr(ivl_statement_t net
, unsigned idx
)
1893 switch (net
->type_
) {
1898 assert(idx
< net
->u_
.case_
.ncase
);
1899 return net
->u_
.case_
.case_ex
[idx
];
1907 extern "C" ivl_statement_t
ivl_stmt_case_stmt(ivl_statement_t net
, unsigned idx
)
1909 switch (net
->type_
) {
1914 assert(idx
< net
->u_
.case_
.ncase
);
1915 return net
->u_
.case_
.case_st
+ idx
;
1923 extern "C" ivl_expr_t
ivl_stmt_cond_expr(ivl_statement_t net
)
1925 switch (net
->type_
) {
1927 return net
->u_
.condit_
.cond_
;
1933 return net
->u_
.case_
.cond
;
1937 return net
->u_
.while_
.cond_
;
1945 extern "C" ivl_statement_t
ivl_stmt_cond_false(ivl_statement_t net
)
1947 assert(net
->type_
== IVL_ST_CONDIT
);
1948 if (net
->u_
.condit_
.stmt_
[1].type_
== IVL_ST_NONE
)
1951 return net
->u_
.condit_
.stmt_
+ 1;
1954 extern "C" ivl_statement_t
ivl_stmt_cond_true(ivl_statement_t net
)
1956 assert(net
->type_
== IVL_ST_CONDIT
);
1957 if (net
->u_
.condit_
.stmt_
[0].type_
== IVL_ST_NONE
)
1960 return net
->u_
.condit_
.stmt_
+ 0;
1963 extern "C" ivl_expr_t
ivl_stmt_delay_expr(ivl_statement_t net
)
1965 switch (net
->type_
) {
1967 case IVL_ST_ASSIGN_NB
:
1968 return net
->u_
.assign_
.delay
;
1971 return net
->u_
.delayx_
.expr
;
1979 extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net
)
1981 assert(net
->type_
== IVL_ST_DELAY
);
1982 return net
->u_
.delay_
.delay_
;
1985 extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net
)
1987 switch (net
->type_
) {
1989 return net
->u_
.wait_
.nevent
;
1991 case IVL_ST_TRIGGER
:
2000 extern "C" ivl_event_t
ivl_stmt_events(ivl_statement_t net
, unsigned idx
)
2002 switch (net
->type_
) {
2004 assert(idx
< net
->u_
.wait_
.nevent
);
2005 if (net
->u_
.wait_
.nevent
== 1)
2006 return net
->u_
.wait_
.event
;
2008 return net
->u_
.wait_
.events
[idx
];
2010 case IVL_ST_TRIGGER
:
2012 return net
->u_
.wait_
.event
;
2019 extern "C" ivl_lval_t
ivl_stmt_lval(ivl_statement_t net
, unsigned idx
)
2021 switch (net
->type_
) {
2023 case IVL_ST_ASSIGN_NB
:
2024 case IVL_ST_CASSIGN
:
2025 case IVL_ST_DEASSIGN
:
2027 case IVL_ST_RELEASE
:
2028 assert(idx
< net
->u_
.assign_
.lvals_
);
2029 return net
->u_
.assign_
.lval_
+ idx
;
2037 extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net
)
2039 switch (net
->type_
) {
2041 case IVL_ST_ASSIGN_NB
:
2042 case IVL_ST_CASSIGN
:
2043 case IVL_ST_DEASSIGN
:
2045 case IVL_ST_RELEASE
:
2046 return net
->u_
.assign_
.lvals_
;
2054 extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net
)
2056 assert((net
->type_
== IVL_ST_ASSIGN
)
2057 || (net
->type_
== IVL_ST_ASSIGN_NB
)
2058 || (net
->type_
== IVL_ST_CASSIGN
)
2059 || (net
->type_
== IVL_ST_DEASSIGN
)
2060 || (net
->type_
== IVL_ST_FORCE
)
2061 || (net
->type_
== IVL_ST_RELEASE
));
2066 struct ivl_lval_s
*lvals
;
2067 nlvals
= net
->u_
.assign_
.lvals_
;
2068 lvals
= net
->u_
.assign_
.lval_
;
2070 for (unsigned idx
= 0 ; idx
< nlvals
; idx
+= 1) {
2071 ivl_lval_t cur
= lvals
+ idx
;
2072 switch(cur
->type_
) {
2078 sum
+= ivl_lval_width(cur
);
2088 extern "C" const char* ivl_stmt_name(ivl_statement_t net
)
2090 switch (net
->type_
) {
2092 return net
->u_
.stask_
.name_
;
2100 extern "C" ivl_expr_t
ivl_stmt_parm(ivl_statement_t net
, unsigned idx
)
2102 switch (net
->type_
) {
2104 assert(idx
< net
->u_
.stask_
.nparm_
);
2105 return net
->u_
.stask_
.parms_
[idx
];
2113 extern "C" unsigned ivl_stmt_parm_count(ivl_statement_t net
)
2115 switch (net
->type_
) {
2117 return net
->u_
.stask_
.nparm_
;
2124 extern "C" ivl_expr_t
ivl_stmt_rval(ivl_statement_t net
)
2126 switch (net
->type_
) {
2128 case IVL_ST_ASSIGN_NB
:
2129 case IVL_ST_CASSIGN
:
2131 return net
->u_
.assign_
.rval_
;
2139 extern "C" ivl_statement_t
ivl_stmt_sub_stmt(ivl_statement_t net
)
2141 switch (net
->type_
) {
2143 return net
->u_
.delay_
.stmt_
;
2145 return net
->u_
.delayx_
.stmt_
;
2146 case IVL_ST_FOREVER
:
2147 return net
->u_
.forever_
.stmt_
;
2149 return net
->u_
.wait_
.stmt_
;
2152 return net
->u_
.while_
.stmt_
;
2160 extern "C" const char*ivl_switch_basename(ivl_switch_t net
)
2165 extern "C" ivl_switch_type_t
ivl_switch_type(ivl_switch_t net
)
2170 extern "C" ivl_nexus_t
ivl_switch_a(ivl_switch_t net
)
2172 return net
->pins
[0];
2175 extern "C" ivl_nexus_t
ivl_switch_b(ivl_switch_t net
)
2177 return net
->pins
[1];
2180 extern "C" ivl_nexus_t
ivl_switch_enable(ivl_switch_t net
)
2182 return net
->pins
[2];