2 * Copyright (c) 2003 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
20 #ident "$Id: draw_vpi.c,v 1.17 2007/02/14 05:59:24 steve Exp $"
23 # include "vvp_priv.h"
31 static const char* magic_sfuncs
[] = {
39 static int is_magic_sfunc(const char*name
)
42 for (idx
= 0 ; magic_sfuncs
[idx
] ; idx
+= 1)
43 if (strcmp(magic_sfuncs
[idx
],name
) == 0)
49 static int is_fixed_memory_word(ivl_expr_t net
)
53 if (ivl_expr_type(net
) != IVL_EX_SIGNAL
)
56 sig
= ivl_expr_signal(net
);
58 if (ivl_signal_array_count(sig
) == 1)
61 if (number_is_immediate(ivl_expr_oper1(net
), 8*sizeof(unsigned)))
67 static void draw_vpi_taskfunc_args(const char*call_string
,
72 unsigned parm_count
= tnet
73 ? ivl_stmt_parm_count(tnet
)
74 : ivl_expr_parms(fnet
);
75 struct vector_info
*vec
= 0x0;
81 /* Figure out how many expressions are going to be evaluated
82 for this task call. I won't need to evaluate expressions
83 for items that are VPI objects directly. */
84 for (idx
= 0 ; idx
< parm_count
; idx
+= 1) {
85 ivl_expr_t expr
= tnet
86 ? ivl_stmt_parm(tnet
, idx
)
87 : ivl_expr_parm(fnet
, idx
);
89 switch (ivl_expr_type(expr
)) {
91 /* These expression types can be handled directly,
92 with VPI handles of their own. Therefore, skip
93 them in the process of evaluating expressions. */
103 if (is_magic_sfunc(ivl_expr_name(expr
)))
109 /* If the signal node is narrower then the signal
110 itself, then this is a part select so I'm going
111 to need to evaluate the expression.
113 Also, if the signedness of the expression is
114 different from the signedness of the
115 signal. This could be caused by a $signed or
116 $unsigned system function.
118 If I don't need to do any evaluating, then skip
119 it as I'll be passing the handle to the signal
121 if (ivl_expr_width(expr
) !=
122 ivl_signal_width(ivl_expr_signal(expr
))) {
125 } else if (ivl_expr_signed(expr
) !=
126 ivl_signal_signed(ivl_expr_signal(expr
))) {
128 } else if (! is_fixed_memory_word(expr
)){
131 /* Some array selects need to be evaluated. */
132 ivl_expr_t word_ex
= ivl_expr_oper1(expr
);
133 if (word_ex
&& !number_is_immediate(word_ex
,
134 8*sizeof(unsigned))) {
142 if (!ivl_expr_oper1(expr
)) {
146 /* Everything else will need to be evaluated and
147 passed as a constant to the vpi task. */
152 vec
= (struct vector_info
*)
153 realloc(vec
, (vecs
+1)*sizeof(struct vector_info
));
155 switch (ivl_expr_value(expr
)) {
158 vec
[vecs
] = draw_eval_expr(expr
, 0);
161 vec
[vecs
].base
= draw_eval_real(expr
);
170 fprintf(vvp_out
, "%s", call_string
);
172 for (idx
= 0 ; idx
< parm_count
; idx
+= 1) {
173 ivl_expr_t expr
= tnet
174 ? ivl_stmt_parm(tnet
, idx
)
175 : ivl_expr_parm(fnet
, idx
);
177 switch (ivl_expr_type(expr
)) {
179 fprintf(vvp_out
, ", \" \"");
183 fprintf(vvp_out
, ", v%p", ivl_expr_signal(expr
));
186 case IVL_EX_NUMBER
: {
187 unsigned bit
, wid
= ivl_expr_width(expr
);
188 const char*bits
= ivl_expr_bits(expr
);
190 fprintf(vvp_out
, ", %u'%sb", wid
,
191 ivl_expr_signed(expr
)? "s" : "");
192 for (bit
= wid
; bit
> 0 ; bit
-= 1)
193 fputc(bits
[bit
-1], vvp_out
);
198 /* If this is a part select, then the value was
199 calculated above. Otherwise, just pass the
201 if (ivl_expr_width(expr
) !=
202 ivl_signal_width(ivl_expr_signal(expr
))) {
205 } else if (ivl_expr_signed(expr
) !=
206 ivl_signal_signed(ivl_expr_signal(expr
))) {
209 } else if (! is_fixed_memory_word(expr
)){
213 ivl_signal_t sig
= ivl_expr_signal(expr
);
214 unsigned use_word
= 0;
215 ivl_expr_t word_ex
= ivl_expr_oper1(expr
);
217 /* Some array select have been evaluated. */
218 if (!number_is_immediate(word_ex
,
219 8*sizeof(unsigned))) {
222 use_word
= get_number_immediate(word_ex
);
224 fprintf(vvp_out
, ", v%p_%u", sig
, use_word
);
231 if (( par
= ivl_expr_parameter(expr
) )) {
232 fprintf(vvp_out
, ", P_%p", par
);
235 fprintf(vvp_out
, ", \"%s\"",
236 ivl_expr_string(expr
));
241 fprintf(vvp_out
, ", E_%p", ivl_expr_event(expr
));
245 fprintf(vvp_out
, ", S_%p", ivl_expr_scope(expr
));
249 if (is_magic_sfunc(ivl_expr_name(expr
))) {
250 fprintf(vvp_out
, ", %s", ivl_expr_name(expr
));
260 switch (ivl_expr_value(expr
)) {
264 fprintf(vvp_out
, ", T<%u,%u,%s>", vec
[veci
].base
,
265 vec
[veci
].wid
, ivl_expr_signed(expr
)? "s" : "u");
269 fprintf(vvp_out
, ", W<%u,r>", vec
[veci
].base
);
278 assert(veci
== vecs
);
281 for (idx
= 0; idx
< vecs
; idx
++) {
282 if (vec
[idx
].wid
> 0)
283 clr_vector(vec
[idx
]);
284 else if (vec
[idx
].wid
== 0)
285 clr_word(vec
[idx
].base
);
290 fprintf(vvp_out
, ";\n");
293 void draw_vpi_task_call(ivl_statement_t tnet
)
295 char call_string
[1024];
296 sprintf(call_string
, " %%vpi_call \"%s\"", ivl_stmt_name(tnet
));
297 draw_vpi_taskfunc_args(call_string
, tnet
, 0);
300 struct vector_info
draw_vpi_func_call(ivl_expr_t fnet
, unsigned wid
)
302 char call_string
[1024];
303 struct vector_info res
;
305 res
.base
= allocate_vector(wid
);
307 sprintf(call_string
, " %%vpi_func \"%s\", %u, %u",
308 ivl_expr_name(fnet
), res
.base
, res
.wid
);
310 draw_vpi_taskfunc_args(call_string
, 0, fnet
);
315 int draw_vpi_rfunc_call(ivl_expr_t fnet
)
317 char call_string
[1024];
318 int res
= allocate_word();
320 sprintf(call_string
, " %%vpi_func/r \"%s\", %d",
321 ivl_expr_name(fnet
), res
);
323 draw_vpi_taskfunc_args(call_string
, 0, fnet
);