source: vis_dev/vl2mv-2.3/src/parser/vl_write.c @ 18

Last change on this file since 18 was 18, checked in by cecile, 13 years ago

vl2mv added

File size: 161.6 KB
Line 
1/*
2
3  Copyright (c) 1992, 1993
4        Regents of the University of California
5  All rights reserved.
6
7  Use and copying of this software and preparation of derivative works
8  based upon this software are permitted.  However, any distribution of
9  this software or derivative works must include the above copyright
10  notice.
11
12  This software is made available AS IS, and neither the Electronics
13  Research Laboratory or the Universify of California make any
14  warranty about the software, its performance or its conformity to
15  any specification.
16
17  Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU
18          10/92
19          10/93
20
21  $Id: vl_write.c,v 1.6 2009/03/09 20:25:58 fabio Exp $
22
23
24*/
25
26
27#include <stdio.h>
28#include <math.h>
29#include "util.h"
30#include "st.h"
31#include "array.h"
32#include "list.h"
33#include "set.h"
34#include "graph.h"
35#include "stack.h"
36#include "set.h"
37#include "vl_types.h"
38#include "vl_defs.h"
39#include "vlr_int.h"
40#include "vl_create.h"
41#include "vl_traverse.h"
42#include "vl_write.h"
43#include "vl_write_util.h"
44#include "vl_fg_defs.h"
45#include "vl_fg_types.h"
46#include "vl_flowgraph.h"
47#include "vl_mux.h"
48#include "vl_vardecl.h"
49#include "vl_edgedetector.h"
50#include "vl_nonblock.h"
51#include "verilog.h"
52#include <stdarg.h>
53
54
55extern vl_desc *mod_list;
56extern int ith_module;
57extern int dflow_analysis;
58extern int vlTimedSystem;
59extern int vis_nond_var;
60extern int vis_nond;
61
62extern int Warn_Uninitialized;
63extern int encodeTimer;
64
65static int WrtTrace = 0;
66static int Being_Conditioned=0;
67static int recordCombAlways=0;
68static array_t *assign_array=NIL(array_t);
69static st_table *auxSigST=NIL(st_table);
70int dumpSyncCkt = 0;
71int implicitClockWire = 0;
72int vl_noTimers = 0;
73int vl_preDeclare = 0;
74int debug_mode = 0;
75int Use_MV_Lib = 0;
76int set_notation = 1;
77int do_encoding = 0;
78int implicitDeclare = 1;
79int implicitClocking = 1;
80int instantiateAll = 1;
81int combinationalReduction = 0;
82int chk_IncompleteBranch = 1;
83int smartEvent = 1;
84int wireRegister = 0;
85int nd_check_ok = 0;
86int compatibleChecking = 0;
87int check_rhs_sensitivity = 1;
88int decomposeTable = DEFAULT_MAX_TABLE_SIZE;
89int Zconnection = 0;
90int NoDetailedComment = 0;
91int portPerLine = 20;
92double vl_expr_aux1_val=(double)0;
93double vl_expr_aux2_val=(double)0;
94double vl_expr_aux3_val=(double)0;
95int vl_expr_aux1_flag = 0;
96int vl_expr_aux2_flag = 0;
97int vl_expr_aux3_flag = 0;
98int silent_err = 0;
99int Vlerrno = 0;
100
101vl_module *vl_encloseModule;
102
103int lhs_hi, lhs_lo;
104vl_term *lhs_term=NIL(vl_term);
105int insideConcat=0;
106vl_term *Initial_Signal = NIL(vl_term);
107set_t *sensitiveList = NIL(set_t);
108vl_term *edge_triggering = NIL(vl_term);
109FILE *mv_file;
110int lhs_must_be_wire = 0;
111graph_t *vl_writeFlowGraph=NIL(graph_t);
112stack_t vl_pauseStack = (stack_t)0;
113lsList vl_current_pause_list = (lsList)0;
114lsList vl_current_vars_list = (lsList)0;
115vl_id_range *masterIdDfn = NIL(vl_id_range);
116char *cntxt_event;
117
118lsGen curModGen;
119lsHandle curModHandle;
120lsHandle *PcurModHandle;
121
122int rst_ckt = 0;
123int use_rst_ckt = 0;
124int mark_sel_var = 0;
125char *ctrl_syndrome = NIL(char);
126lsList ctrl_list;
127int ith_ctrl;
128char *rst_ctrl_syndrome = NIL(char);
129lsList rst_ctrl_list;
130int rst_ith_ctrl;
131st_table *vl_currentModule_combVar_st;
132
133static int in_procedure = 0;
134static st_table *vl_current_init_vars=NIL(st_table);
135static st_table *final_vars=NIL(st_table);
136array_t *cur_vars_array = NIL(array_t);
137
138static void vl_write_function_list ARGS((FILE *file));
139static void vl_write_formal_argument ARGS((FILE *file));
140static void vl_write_initial_generator ARGS((FILE *file));
141static void vl_write_timer ARGS((FILE *file, lsList graph_list));
142static void vl_write_encoding ARGS((FILE *file));
143static void vl_write_prim_table ARGS((FILE *file, vl_primitive *prim, char *edge_detectors));
144static void instantiate_prim_latch ARGS((FILE *file, st_table *sig_st));
145static void instantiate_edge_detector ARGS((FILE *file, vl_primitive *prim));
146static void non_block_assignment ARGS((FILE *file, st_table *vars));
147static void quasi_cont_assignment ARGS((FILE *file));
148static void vl_write_gate_inst_list ARGS((FILE *file, vl_gate_inst_list *gate_list));
149static void vl_write_tesla_timer_inst_list ARGS((FILE *file, vl_gate_inst_list *gate_list));
150static void vl_write_prim_inst_list ARGS((FILE *file, vl_mod_prim_inst_list *priminstlist));
151static void vl_predefine_vars ARGS((FILE *file, st_table *vars));
152static void vl_timed_init_mux ARGS((FILE *file, vl_term *ctrl_term,
153                                    st_table *orig_vars, st_table *init_vars,
154                                    st_table *feedback_vars));
155static void vl_write_prim_inst ARGS((FILE *file, vl_primitive *master,
156                                     vl_mod_prim_inst *inst));
157static void vl_write_gate_inst ARGS((FILE *file, short type, vl_gate_inst *gate));
158static void vl_write_tesla_timer_inst ARGS((FILE *file, vl_gate_inst *gate,
159                                            int lb, int ub));
160static void vl_register_pause ARGS((vertex_t *pause_node, st_table *old_vars));
161static void vl_prioritize_sequence ARGS((FILE *file, lsList vars_list,
162                                         lsList pause_list,
163                                         st_table *result_st));
164static void vl_write_vector_red_op ARGS((FILE *file, short type,
165                                         vl_term *in, int inverted,
166                                         vl_term *out));
167
168enum st_retval vl_write_desc(char *name, char *value, char *arg)
169{
170
171    if (!Initial_Signal)
172        Initial_Signal = vl_create_term(vl_create_id_range(vlStrdup("_initial_"),NIL(vl_range)), 0, -1);
173
174    if (((typestructPtr)value)->type == ModDecl) {
175        vl_write_module(mv_file, (vl_module*)value);
176    } else if (((typestructPtr)value)->type == CombPrimDecl ||
177               ((typestructPtr)value)->type == SeqPrimDecl) {
178        vl_write_primitive(mv_file, (vl_primitive*)value);
179    }
180
181
182    name = name;
183    arg = arg;
184    return ST_CONTINUE;
185}
186
187void vl_write_module(FILE *file, vl_module *mod)
188{
189    char *dummy;
190
191    if (mod == NULL) return;
192    if (st_lookup(mod_list->mod_holes, mod->name->name, &dummy)) return;
193
194    ASSERT(mod->type==ModDecl, "Expecting ModDecl");
195    vl_currentModule = mod;
196    WrtTRACE("writing module\n");
197
198    ctrl_syndrome = (char*)chk_malloc(mod->syndrome_width+1);
199    memset(ctrl_syndrome, (int)'-', mod->syndrome_width);
200    ctrl_syndrome[mod->syndrome_width] = '\0';
201    rst_ctrl_syndrome = (char*)chk_malloc(mod->rst_syndrome_width+1);
202    memset(rst_ctrl_syndrome, (int)'-', mod->rst_syndrome_width);
203    rst_ctrl_syndrome[mod->rst_syndrome_width] = '\0';
204    ctrl_list = lsCreate();
205    rst_ctrl_list = lsCreate();
206    ith_ctrl = 0;
207    rst_ith_ctrl = 0;
208
209    fprintf(file, "%s %s ", HSIS_MODEL, mod->name->name);
210    vl_write_formal_argument(file);
211    fprintf(file, "\n");
212    vl_write_io_list(file);
213    vl_write_svar(file);
214    vl_write_consts(file);
215    if (vlTimedSystem || !implicitClocking) {
216        vl_preDeclare = 1;
217        vl_write_timer(file, mod->flow_graphs);
218    }
219    vl_write_mod_item_list(file, mod->mod_items);
220    if (vlTimedSystem || !implicitClocking) {
221        vl_preDeclare = 0;
222        vl_write_timer(file, mod->flow_graphs);
223    }
224    vl_write_initial_generator(file);
225    fprintf(file, ".end\n");
226
227    vl_write_function_list(file);
228    vl_write_encoding(file);
229    vl_currentModule = NIL(vl_module);
230
231    lsDestroy(ctrl_list, 0);
232    lsDestroy(rst_ctrl_list, 0);
233    vl_chk_free(ctrl_syndrome);
234    vl_chk_free(rst_ctrl_syndrome);
235    ctrl_syndrome = NIL(char);
236    rst_ctrl_syndrome = NIL(char);
237}
238
239
240void vl_write_primitive(FILE *file, vl_primitive *prim)
241{
242    char *edge_detectors;
243
244    if (prim == NULL) return;
245
246    assert(prim->type==CombPrimDecl || prim->type==SeqPrimDecl);
247    vl_currentPrimitive = prim;
248    vl_currentModule = (vl_module*)prim;
249    WrtTRACE("writing primitive\n");
250
251    fprintf(file, "%s %s\n", HSIS_MODEL, prim->name->name);
252    vl_write_io_list(file);
253    instantiate_prim_latch(file, prim->sig_st);
254    vl_write_svar(file);
255    edge_detectors = vl_write_prim_table_header(file, prim);
256    vl_write_prim_table(file, prim, edge_detectors);
257    instantiate_edge_detector(file, prim);
258    fprintf(file, ".end\n\n\n");
259
260    vl_currentModule = NIL(vl_module);
261    vl_currentPrimitive = NIL(vl_primitive);
262    vl_chk_free(edge_detectors);
263}
264
265
266static void vl_write_function_list(FILE *file)
267{
268    st_generator *gen;
269    char *fname;
270    vl_function *func_def;
271
272    gen = st_init_gen(vl_currentModule->func_st);
273    while (st_gen(gen, (char**)&fname, (char**)&func_def)) {
274        vl_write_function(file, func_def);
275    }
276    st_free_gen(gen);
277}
278
279
280void vl_write_function(FILE *file, vl_function *func)
281{
282    st_table *vars_touched;
283    array_t *vars_array;
284    vl_module *old_module;
285
286    if (func == NIL(vl_function)) return;
287
288    old_module = vl_currentModule;
289    vl_encloseModule = vl_currentModule;
290    vl_currentModule = (vl_module*)func;
291    vl_currentFunction = func;
292    vl_pauseStack = create_stack();
293    WrtTRACE("writing function\n");
294
295    vars_array = array_alloc(st_table*, 0);
296    vars_touched = st_init_table(strcmp, st_strhash);
297
298    fprintf(file, "%s %s ", HSIS_MODEL, func->name->name);
299    vl_write_formal_argument(file);
300    fprintf(file, "\n");
301
302    vl_write_io_list(file);
303    vl_write_svar(file);
304    vl_write_stmt_list(file, func->stmts, NO_MUX, NIL(vl_term), vars_touched);
305    array_insert_last(st_table*, vars_array, vars_touched);
306    func_conflict_arbitrator(file, vl_currentFunction->name,
307                             vars_array);
308    fprintf(file, ".end\n\n\n");
309    vl_currentModule = old_module;
310    vl_currentFunction = NIL(vl_function);
311    vl_encloseModule = NIL(vl_module);
312    destroy_stack(vl_pauseStack, 0);
313    vl_pauseStack = (lsList)0;
314}
315
316
317static void vl_write_formal_argument(FILE *file)
318{
319}
320
321
322void vl_write_io_list(FILE *file)
323{
324    st_generator *gen;
325    char *key;
326    vl_id_range *id_sym;
327    int lo, hi;
328    char *dir;
329    lsGen ports_gen;
330    lsHandle port_handle, port_id_handle;
331    vl_port *port;
332    vl_id_range *port_id, *port_id_sym;
333    int ithItem;
334
335    fprintf(file, "%s I/O ports\n", HSIS_COMMENT);
336
337    if (vl_currentModule->flags & WithInitial)
338        if (ith_module!=0)
339            if (use_rst_ckt)
340                fprintf(file,".inputs %s\n", Initial_Signal->name->name);
341
342
343    if (vl_currentModule->ports) {
344        ports_gen = lsStart(vl_currentModule->ports);
345        while (lsNext(ports_gen,(lsGeneric*)&port,&port_handle) != LS_NOMORE) {
346            if (!vl_currentFunction) {
347                if (!port->port_exp) continue;
348                lsFirstItem(port->port_exp, (lsGeneric*)&port_id,
349                            &port_id_handle);
350            } else
351                port_id = (vl_id_range*)port;
352            if (!st_lookup(vl_currentModule->sig_st,
353                           port_id->name, (char**)&port_id_sym)) {
354                char buf[MAXSTRLEN];
355                yylineno = -1;
356                sprintf(buf, "port %s is not defined in module %s",
357                        port_id->name, vl_currentModule->name->name);
358                compile_error(buf);
359            }
360
361            if (!(port_id_sym->flags & InPort) &&
362                !(port_id_sym->flags & OutPort)) {
363                char buf[MAXSTRLEN];
364                yylineno = -1;
365                sprintf(buf, "port %s has no direction in module %s",
366                        port_id->name, vl_currentModule->name->name);
367                compile_error(buf);
368            }
369        }
370        lsFinish(ports_gen);
371    }
372
373    ithItem = 0;
374    gen = st_init_gen(vl_currentModule->sig_st);
375    while (st_gen(gen, (char**)&key, (char**)&id_sym)) {
376        if (!(id_sym->flags & InPort) && !(id_sym->flags & OutPort))
377            continue;
378
379        if (strstr(id_sym->name, SEP_LATCH)) continue;
380        if (strstr(id_sym->name, SEP_QUASI)) continue;
381
382
383        if (!vl_currentFunction && implicitClocking && !vlTimedSystem) {
384            if (vl_currentModule->clk) {
385                if (!strcmp(vl_currentModule->clk->expr->u.name->name,
386                            key) &&
387                    !vl_currentPrimitive) {
388                    if (!implicitClockWire)
389                        continue;
390                }
391            } else {
392                if (!strcmp(key, CLOCK)) {
393                    if (!implicitClockWire)
394                        continue;
395                }
396            }
397        }
398
399        dir = (id_sym->flags & InPort) ? ".inputs":".outputs";
400        if (id_sym->flags & MVar) {
401            declare_mvar_io(file, dir, id_sym);
402        } else {
403            get_hilo(id_sym, &hi, &lo);
404            if (lo > hi) {
405                declare_bin_scalar_io(file, dir, id_sym);
406            } else {
407                declare_bin_vector_io(file, dir, id_sym);
408            }
409        }
410    }
411    st_free_gen(gen);
412
413}
414
415void vl_write_svar(FILE *file)
416{
417    st_generator *gen;
418    char *key;
419    vl_id_range *id_sym;
420    lsList domain;
421    int lo, hi;
422
423    gen = st_init_gen(vl_currentModule->sig_st);
424    while (st_gen(gen, &key, (char**)&id_sym)) {
425        vl_enumerator *enum_elt;
426        lsGen enum_gen;
427        lsHandle enum_handle;
428        int j;
429
430        if (str_matchtail(id_sym->name,SEP_LATCH)) continue;
431
432
433        if (!vl_currentFunction && implicitClocking && !vlTimedSystem) {
434            if (vl_currentModule->clk) {
435                if (!strcmp(vl_currentModule->clk->expr->u.name->name, key) &&
436                    !vl_currentPrimitive) {
437                    if (!implicitClockWire)
438                        continue;
439                    else
440                        fprintf(file, "%s %s ;\n", SMV_CLOCK,
441                                vl_currentModule->clk->expr->u.name->name);
442                }
443            }
444        }
445
446        if (!(id_sym->flags & MVar)) {
447            continue;
448        }
449
450        if (!id_sym->range) {
451            domain = id_sym->id_type->specifier->u.enum_type->domain_list;
452            get_hilo(id_sym, &hi, &lo);
453            fprintf(file, ".mv %s %d ", id_sym->name, lsLength(domain));
454            for (enum_gen=lsStart(domain), j=0;
455                 lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=
456                     LS_NOMORE;
457                 j++) {
458                fprintf(file, "%s ", enum_elt->name);
459            }
460            lsFinish(enum_gen);
461            fprintf(file, "\n");
462        } else {
463            int idx_hi, idx_lo, idx;
464            idx_lo = vl_eval_expr(id_sym->range->left);
465            if (id_sym->range->right)
466                idx_hi = vl_eval_expr(id_sym->range->right);
467            else
468                idx_hi = idx_lo;
469            for (idx=idx_lo; idx<=idx_hi; idx++) {
470                domain = id_sym->id_type->specifier->u.enum_type->domain_list;
471                get_hilo(id_sym, &hi, &lo);
472                fprintf(file, ".mv %s%s%d%s %d ",
473                        id_sym->name, SEP_LARRAY, idx, SEP_RARRAY,
474                        lsLength(domain));
475                for (enum_gen=lsStart(domain);
476                     lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=
477                     LS_NOMORE;) {
478                    fprintf(file, "%s ", enum_elt->name);
479                }
480                lsFinish(enum_gen);
481                fprintf(file, "\n");
482            }
483        }
484    }
485    st_free_gen(gen);
486}
487
488void vl_write_mod_item_list (FILE *file, lsList mitems)
489{
490    vl_decl *item;
491    lsHandle fg_handle;
492    lsGen fg_gen;
493    array_t *vars_array;
494    st_table *var_touched, *final_vars;
495    st_table *comb_st, *tmp_st;
496    st_table *old_sensitiveList;
497
498    WrtTRACE("writing Module Items\n");
499
500    vars_array = array_alloc(st_table*, 0);
501    cur_vars_array = vars_array;
502    vl_currentModule_combVar_st = comb_st = st_init_table(strcmp, st_strhash);
503    if (mitems != (lsList)0) {
504        for (curModGen = lsStart(mitems),
505             fg_gen = lsStart(vl_currentModule->flow_graphs);
506             lsNext(curModGen, (lsGeneric*)&item, &curModHandle) !=
507                 LS_NOMORE; ) {
508            PcurModHandle = &curModHandle;
509            if (((vl_decl*)item)->type == AlwaysStmt)
510                lsNext(fg_gen, (lsGeneric*)&vl_writeFlowGraph, &fg_handle);
511            else
512                vl_writeFlowGraph = NIL(graph_t);
513
514
515            old_sensitiveList = sensitiveList;
516            recordCombAlways = 0;
517
518            if ((sensitiveList=
519                fg_graph_has_one_data_detector(vl_writeFlowGraph))  &&
520                combinationalReduction && implicitClocking) {
521                vl_currentModule->combVar_st = tmp_st =
522                    st_init_table(strcmp, st_strhash);
523                recordCombAlways = 1;
524            } else {
525                vl_currentModule->combVar_st = tmp_st = NIL(st_table);
526            }
527
528            var_touched = vl_write_mod_item(file, item, NIL(st_table));
529            vl_writeFlowGraph = NIL(graph_t);
530            if (var_touched) {
531                array_insert_last(st_table*, vars_array, var_touched);
532            }
533
534
535            if (!vl_currentModule->combVar_st) {
536                st_generator *gen;
537                char *key;
538                char *dummy;
539                if (var_touched) {
540                    gen = st_init_gen(var_touched);
541                    while (st_gen(gen, &key, (char**)&dummy))
542                        if (!st_lookup(vl_currentModule->seqVar_st,
543                                       key, &dummy))
544                            st_insert(vl_currentModule->seqVar_st,
545                                      key, (char*)0);
546                    st_free_gen(gen);
547                }
548            }
549
550
551            if (tmp_st) {
552                if (vl_currentModule->combVar_st) {
553
554                    st_generator *gen;
555                    vl_id_range *id_sym;
556                    char *key;
557                    gen = st_init_gen(vl_currentModule->combVar_st);
558                    while (st_gen(gen, &key, (char**)&id_sym)) {
559                        st_insert(comb_st, key, (char*)id_sym);
560
561                    }
562                    st_free_gen(gen);
563                }
564                st_free_table(tmp_st);
565            }
566
567            sensitiveList = old_sensitiveList;
568        }
569        (void) lsFinish(fg_gen);
570    }
571
572    vl_currentModule->combVar_st = comb_st;
573    vl_currentModule_combVar_st = NIL(st_table);
574    final_vars = conflict_arbitrator(file, vars_array);
575    non_block_assignment(file, final_vars);
576    instantiate_latch(file, final_vars);
577    quasi_cont_assignment(file);
578    cur_vars_array = NIL(array_t);
579}
580
581
582char *vl_write_prim_table_header(FILE *file, vl_primitive *prim)
583{
584    lsGen port_gen;
585    vl_port *port;
586    lsHandle port_handle, port_id_handle;
587    vl_id_range *port_id, *port_id_sym;
588    int ith_port=0;
589    char *retval;
590
591    fprintf(file, ".names ");
592
593    retval = (char*)chk_malloc(lsLength(prim->ports)+1);
594
595    port_gen = lsStart(prim->ports);
596    while (lsNext(port_gen, (lsGeneric*)&port, &port_handle) != LS_NOMORE) {
597        lsFirstItem(port->port_exp, (lsGeneric*)&port_id, &port_id_handle);
598        if (!st_lookup(prim->sig_st, port_id->name, (char**)&port_id_sym)) {
599            char buf[MAXSTRLEN];
600            yylineno = -1;
601            sprintf(buf, "port %s is not defined in primitive %s",
602                    port_id->name, vl_currentModule->name->name);
603            compile_error(buf);
604        }
605
606        retval[ith_port] = 0;
607        if (prim->type ==SeqPrimDecl) {
608            if (port_id_sym->flags & InPort) {
609                if (need_edge_detector(prim->entries, ith_port)) {
610                    port_id_sym->flags |= EdgeDetector;
611                    fprintf(file, "%s%s %s ",
612                            port_id_sym->name, PIN_DELAYED, port_id_sym->name);
613                    retval[ith_port] = 1;
614                } else {
615                    fprintf(file, "%s ", port_id_sym->name);
616                }
617                ith_port++;
618            }
619        } else {
620            if (port_id_sym->flags & InPort) {
621                fprintf(file, "%s ", port_id_sym->name);
622                ith_port++;
623            }
624        }
625    }
626    lsFinish(port_gen);
627
628    port_gen = lsStart(prim->ports);
629    while (lsNext(port_gen, (lsGeneric*)&port, &port_handle) != LS_NOMORE) {
630        lsFirstItem(port->port_exp, (lsGeneric*)&port_id, &port_id_handle);
631        st_lookup(prim->sig_st, port_id->name, (char**)&port_id_sym);
632
633        if (port_id_sym->flags & OutPort) {
634            if (prim->type == SeqPrimDecl)
635                fprintf(file, "%s %s%s\n", port_id_sym->name,
636                        port_id_sym->name, SEP_LATCH);
637            else
638                fprintf(file, "%s\n", port_id_sym->name);
639        }
640    }
641    lsFinish(port_gen);
642
643    return retval;
644}
645
646
647static void vl_write_prim_table(FILE *file, vl_primitive *prim, char *edge_detectors)
648{
649    vl_prim_entry *e;
650    int i, bin, c, num_combination, ith_dup;
651    lsHandle handle;
652    lsGen gen;
653
654    if (prim->entries == NULL) return;
655
656    WrtTRACE("Writing primitive table\n");
657    for(gen = lsStart(prim->entries);
658        lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE; ) {
659        for (i=0, num_combination=1; i<10; i++) {
660            if (e->inputs[i] == PrimNone)
661                break;
662            else {
663                if (!(IS_TRANSITION(e->inputs[i]) || !edge_detectors[i]))
664                    if (!strcmp(vl_translate_prim_symbol(e->inputs[i]),"-"))
665                        num_combination <<= 1;
666            }
667        }
668
669        for (c=0; c<num_combination; c++) {
670            bin=0;
671dump_entry:
672            ith_dup=0;
673            for (i=0; i<10; i++) {
674                if (e->inputs[i] == PrimNone)
675                    break;
676                else {
677                    if (IS_TRANSITION(e->inputs[i]) || !edge_detectors[i])
678                        fprintf(file,"%s ",
679                                vl_translate_prim_symbol(e->inputs[i]));
680                    else if (!strcmp(vl_translate_prim_symbol(e->inputs[i]),
681                                    "-")) {
682                        fprintf(file, "%d %d ", (c>>ith_dup)&1,(c>>ith_dup)&1);
683                        ith_dup++;
684                    } else
685                        fprintf(file,"%s %s ",
686                                vl_translate_prim_symbol(e->inputs[i]),
687                                vl_translate_prim_symbol(e->inputs[i]));
688                }
689            }
690
691            if (prim->type == SeqPrimDecl && e->next_state == PrimM) {
692                if (!strcmp(vl_translate_prim_symbol(e->next_state), "-")) {
693                    fprintf(file, "%d %d\n", bin, bin);
694                    if (bin++ < 1) goto dump_entry;
695                } else {
696                    fprintf(file, "%s %s\n",
697                            vl_translate_prim_symbol(e->state),
698                            vl_translate_prim_symbol(e->state));
699                }
700                continue;
701            }
702
703            if (prim->type == SeqPrimDecl)
704                fprintf(file, "%s ", vl_translate_prim_symbol(e->state));
705
706            fprintf(file, "%s ", vl_translate_prim_symbol(e->next_state));
707            fprintf(file, "%s\n", vl_translate_prim_symbol(e->state));
708        }
709    }
710    (void) lsFinish(gen);
711}
712
713
714st_table *vl_write_mod_item(FILE *file, vl_decl *item, st_table *other_vars)
715{
716    st_table *var_touched=NIL(st_table);
717    vl_term *ctrl_term;
718
719    switch(item->type) {
720
721    case RealDecl:      case EventDecl:
722        break;
723
724    case IntDecl:       case TimeDecl:
725        break;
726
727    case InputDecl:     case OutputDecl:
728    case InoutDecl:     case RegDecl:
729        break;
730
731    case ParamDecl:     case DefparamDecl:
732        break;
733
734
735    case WireDecl:
736        var_touched = st_init_table(strcmp, st_strhash);
737        vl_write_wiring_assign(file, (vl_netdecl*)item, var_touched);
738        break;
739
740
741    case TriDecl:
742    case Tri0Decl:      case Tri1Decl:
743    case Supply0Decl:   case Supply1Decl:
744    case WandDecl:      case TriandDecl:
745    case WorDecl:       case TriorDecl:
746    case TriregDecl:
747        break;
748
749    case ContAssign:
750        var_touched = st_init_table(strcmp, st_strhash);
751        vl_write_cont_assign(file, (vl_cont_assign*)item, var_touched);
752        break;
753
754    case TaskDecl:
755        break;
756
757    case IntFuncDecl: {
758        char buf[MAXSTRLEN];
759        sprintf(buf, "'%s': can handle int function %s yet",
760                vl_currentModule->name->name,
761                ((vl_function*)item)->name->name);
762        Translate_Warning(buf);
763        break;
764    }
765    case RealFuncDecl: {
766        char buf[MAXSTRLEN];
767        sprintf(buf, "'%s': can handle real function %s yet",
768                vl_currentModule->name->name,
769                ((vl_function*)item)->name->name);
770        Translate_Warning(buf);
771        break;
772    }
773
774    case RangeFuncDecl:
775        break;
776
777    case AndGate:       case NandGate:
778    case OrGate:        case NorGate:
779    case XorGate:       case XnorGate:
780    case BufGate:       case Bufif0Gate:
781    case Bufif1Gate:    case NotGate:
782    case Notif0Gate:    case Notif1Gate:
783    case PulldownGate:  case PullupGate:
784    case NmosGate:      case RnmosGate:
785    case PmosGate:      case RpmosGate:
786    case CmosGate:      case RcmosGate:
787    case TranGate:      case RtranGate:
788    case Tranif0Gate:   case Rtranif0Gate:
789    case Tranif1Gate:   case Rtranif1Gate:
790        vl_write_gate_inst_list(file, (vl_gate_inst_list*)item);
791        break;
792
793    case TeslaTimerGate:
794        vl_write_tesla_timer_inst_list(file, (vl_gate_inst_list*)item);
795        break;
796
797    case ModInst: {
798        char *mp;
799
800        if (st_lookup(vl_description->mp_st,
801                       ((vl_mod_prim_inst_list *)item)->name->name,
802                       &mp)) {
803            if (((typestructPtr)mp)->type == CombPrimDecl ||
804                ((typestructPtr)mp)->type == SeqPrimDecl)
805                goto write_prim_inst;
806        }
807        }
808
809        vl_write_mod_inst_list(file, (vl_mod_prim_inst_list*)item);
810        break;
811
812write_prim_inst:
813
814    case PrimInst:
815        vl_write_prim_inst_list(file, (vl_mod_prim_inst_list*)item);
816        break;
817
818    case InitialStmt:
819        vl_write_reset(file, (vl_procstmt*)item);
820        break;
821    case AlwaysStmt:
822        if (((fg_graph_info*)vl_writeFlowGraph->user_data)->fg_id == -1) {
823            fg_new_fg_id();
824            ((fg_graph_info*)vl_writeFlowGraph->user_data)->fg_id = fg_fg_id();
825        } else {
826            fg_set_fg_id(((fg_graph_info*)vl_writeFlowGraph->user_data)
827                         ->fg_id);
828        }
829        var_touched = st_init_table(strcmp, st_strhash);
830        if (vlTimedSystem) {
831            vl_current_init_vars = st_init_table(strcmp, st_strhash);
832            vl_predefine_vars(file, var_touched);
833        }
834        var_touched = vl_write_procstmt(file, (vl_procstmt*)item, var_touched);
835        if (vlTimedSystem) {
836
837            ctrl_term = test_against_lc_init(file);
838            if (final_vars && vlTimedSystem)
839                vl_timed_init_mux(file, ctrl_term, NIL(st_table),
840                                  vl_current_init_vars, final_vars);
841            else
842                vl_timed_init_mux(file, ctrl_term, NIL(st_table),
843                                  vl_current_init_vars, var_touched);
844            final_vars = NIL(st_table);
845            st_free_table(vl_current_init_vars);
846            vl_current_init_vars = NIL(st_table);
847        }
848        fg_associate_id_vars(fg_fg_id(), var_touched);
849        break;
850
851    default:
852        internal_error("Unexpected Module Item");
853        break;
854    }
855
856
857    other_vars = other_vars;
858
859    return var_touched;
860}
861
862void vl_write_mod_inst_list(FILE *file, vl_mod_prim_inst_list *modinstlist)
863
864{
865    vl_module *mod;
866    vl_mod_prim_inst *modinst;
867
868    if (st_lookup(mod_list->mp_st,
869                  modinstlist->name->name, (char**)&mod)) {
870        lsGen gen;
871        lsHandle handle;
872
873        gen = lsStart(modinstlist->mps);
874        if (lsNext(gen, (lsGeneric*)&modinst, &handle) == LS_OK) {
875            vl_write_mod_inst(file, mod, modinst);
876            while (lsNext(gen, (lsGeneric*)&modinst, &handle) != LS_NOMORE) {
877                vl_write_mod_inst(file, mod, modinst);
878            }
879        }
880        lsFinish(gen);
881    } else {
882        char msg[MAXSTRLEN];
883
884        sprintf(msg,
885                "module %s used without definition", modinstlist->name->name);
886        Translate_Warning(msg);
887    }
888}
889
890
891static void vl_write_prim_inst_list(FILE *file, vl_mod_prim_inst_list *priminstlist)
892{
893    vl_primitive *prim;
894    vl_mod_prim_inst *priminst;
895
896    if (st_lookup(mod_list->mp_st,
897                  priminstlist->name->name, (char**)&prim)) {
898        lsGen gen;
899        lsHandle handle;
900
901        gen = lsStart(priminstlist->mps);
902        if (lsNext(gen, (lsGeneric*)&priminst, &handle) == LS_OK) {
903            vl_write_prim_inst(file, prim, priminst);
904            while (lsNext(gen, (lsGeneric*)&priminst, &handle) != LS_NOMORE) {
905                vl_write_prim_inst(file, prim, priminst);
906            }
907        }
908        lsFinish(gen);
909    } else {
910        char msg[MAXSTRLEN];
911
912        sprintf(msg, "primitive %s is used without definition",
913                priminstlist->name->name);
914        Translate_Warning(msg);
915    }
916}
917
918
919static void vl_write_gate_inst_list(FILE *file, vl_gate_inst_list *gate_list)
920{
921    vl_gate_inst *gate;
922    lsGen gen;
923    lsHandle handle;
924
925    gen = lsStart(gate_list->gates);
926    if (lsNext(gen, (lsGeneric*)&gate, &handle) == LS_OK) {
927        vl_write_gate_inst(file, gate_list->type, gate);
928        while(lsNext(gen, (lsGeneric*)&gate, &handle) != LS_NOMORE) {
929            vl_write_gate_inst(file, gate_list->type, gate);
930        }
931    }
932    (void) lsFinish(gen);
933}
934
935
936static void vl_write_tesla_timer_inst_list(FILE *file,
937                                           vl_gate_inst_list *gate_list)
938{
939    vl_gate_inst *gate;
940    lsGen gen;
941    lsHandle handle;
942    int lb=0, ub=0;
943
944    if (!gate_list->delays) {
945        char buf[MAXSTRLEN];
946        sprintf(buf, "%s:teslaTimer needs #(LB:UB) delay specified",
947                vl_currentModule->name->name);
948        Translate_Warning(buf);
949    }
950    if (gate_list->delays->delay1->type == IntExpr) {
951        char buf[MAXSTRLEN];
952        sprintf(buf, "%s:teslaTimer needs #(LB:UB) delay specified",
953                vl_currentModule->name->name);
954        Translate_Warning(buf);
955    }
956
957    lb = vl_eval_expr(gate_list->delays->delay1->u.exprs.e1);
958    ub = vl_eval_expr(gate_list->delays->delay1->u.exprs.e2);
959    for (gen=lsStart(gate_list->gates);
960         lsNext(gen, (lsGeneric*)&gate, &handle)!=LS_NOMORE; ) {
961        vl_write_tesla_timer_inst(file, gate, lb, ub);
962    }
963    (void) lsFinish(gen);
964}
965
966
967void vl_write_mod_inst(FILE *file, vl_module *master, vl_mod_prim_inst *inst)
968{
969    int lo, hi;
970    int constConnection;
971    lsHandle inst_handle, mast_handle;
972    lsGen inst_gen, mast_gen;
973    vl_port_connect *inst_item;
974    vl_port *mast_item;
975    vl_expr *old_item_expr;
976    lsList input_consts;
977    const_term *ct;
978    vl_enumerator *enum_elt;
979    int ith_port;
980    st_generator *stgen;
981    char *key;
982    int dummy;
983    lsList back_patch_list;
984    lsGen backgen;
985    lsHandle backhandle;
986    vl_expr *backexpr;
987    char modbuf[MAXSTRLEN*8];
988    char workbuf[MAXSTRLEN];
989
990    if (inst->name)
991        sprintf(modbuf, ".subckt %s %s ",
992                master->name->name, inst->name->name);
993    else
994        sprintf(modbuf, ".subckt %s %s ",
995                master->name->name, new_termname());
996
997    if (master->flags & WithInitial) {
998        if (use_rst_ckt) {
999            sprintf(workbuf, "%s=%s ",
1000                    Initial_Signal->name->name, Initial_Signal->name->name);
1001            strcat(modbuf, workbuf);
1002        }
1003    }
1004
1005    if (inst->ports && master->ports) {
1006        lsHandle handle;
1007        lsGen gen;
1008        vl_id_range *id, *cur_sig;
1009        int named_connection;
1010
1011
1012
1013        input_consts = lsCreate();
1014        back_patch_list = lsCreate();
1015        auxSigST = st_init_table(strcmp, st_strhash);
1016
1017
1018        ith_port=0;
1019        named_connection = 0;
1020        inst_gen = lsStart(inst->ports);
1021        mast_gen = lsStart(master->ports);
1022        while (lsNext(mast_gen,
1023                      (lsGeneric*)&mast_item, &mast_handle) != LS_NOMORE) {
1024            if (lsNext(inst_gen,
1025                   (lsGeneric*)&inst_item, &inst_handle) != LS_NOMORE) {
1026
1027                if (!mast_item->port_exp && !inst_item->expr) continue;
1028                else if ((!mast_item->port_exp && inst_item->expr) ||
1029                         (!inst_item->expr && mast_item->port_exp)) {
1030                    char buf[MAXSTRLEN];
1031                    sprintf(buf, "'%s': try to instantiate module %s with incompatible arguments",
1032                            vl_currentModule->name->name, master->name->name);
1033                    yylineno = -1;
1034                    compile_error(buf);
1035                }
1036            } else if (!named_connection)
1037
1038                break;
1039
1040
1041            lsFirstItem(mast_item->port_exp, (lsGeneric*)&id, &handle);
1042
1043            if (!st_lookup(master->sig_st, id->name, (char**)&id)) {
1044                char buf[MAXSTRLEN];
1045
1046                sprintf(buf, "port '%s' is not defined in module '%s'",
1047                        id->name, master->name->name);
1048                semantic_error(buf);
1049            }
1050
1051            old_item_expr = NIL(vl_expr);
1052
1053            if (!named_connection)
1054                named_connection = (inst_item->type == NamedConnect);
1055            if (named_connection) {
1056
1057                mast_item = search_match_port(inst_item->id->name,
1058                                              master->ports);
1059
1060                lsFirstItem(mast_item->port_exp, (lsGeneric*)&id, &handle);
1061                if (!st_lookup(master->sig_st, id->name, (char**)&id)) {
1062                    char buf[MAXSTRLEN];
1063
1064                    sprintf(buf, "port '%s' is not defined in module '%s'",
1065                            id->name, master->name->name);
1066                    semantic_error(buf);
1067                }
1068            }
1069
1070
1071            if ((id->flags&OutPort) && Zconnection) {
1072                lsList assign_list;
1073                vl_id_range *tmp_id;
1074                vl_lval *tmp_lhs;
1075                vl_expr *tmp_rhs;
1076                vl_cont_assign *assign_stmt;
1077                tmp_id = vl_create_id_range(vlStrdup(new_termname()),
1078                                            NIL(vl_range));
1079                if (inst_item->expr->type == ConcatExpr)
1080                    tmp_lhs = vl_create_lval(ConcatExpr,
1081                                             NIL(vl_id_range),NIL(vl_range),
1082                                             (lsList)inst_item->expr->u.name);
1083                else
1084                    tmp_lhs = vl_create_lval(inst_item->expr->type,
1085                                             inst_item->expr->u.idrng,
1086                                             inst_item->expr->u.idrng->range,
1087                                             (lsList)0);
1088                tmp_rhs = vl_create_expr(IDExpr, 0, (double)0.0,
1089                                         tmp_id, NIL(void), NIL(void));
1090                assign_list = lsCreate();
1091                lsNewEnd(assign_list,
1092                         (lsGeneric)vl_create_bassign_stmt(AssignStmt,
1093                                                           tmp_lhs,
1094                                                           NIL(void),
1095                                                           tmp_rhs),
1096                         0);
1097                assign_stmt = vl_create_cont_assign_stmt(0, NIL(vl_delay),
1098                                                         assign_list);
1099                if (inst_item->expr->type == IDExpr ||
1100                    inst_item->expr->type == BitSelExpr ||
1101                    inst_item->expr->type == PartSelExpr) {
1102                    int inVar=0;
1103                    if (st_lookup(vl_currentModule->sig_st,
1104                                  inst_item->expr->u.name->name,
1105                                  (char**)&cur_sig))
1106                        inVar = ((cur_sig->flags & InPort) &&
1107                                !(cur_sig->flags & OutPort));
1108                    if (!inVar)
1109                        lsInAfter(curModGen,
1110                                  (lsGeneric)assign_stmt, PcurModHandle);
1111                }
1112                chkUndefPorts(inst_item->expr, auxSigST);
1113                old_item_expr = inst_item->expr;
1114                inst_item->expr = vl_create_expr(IDExpr, 0, (double)0.0,
1115                                                 tmp_id, NIL(void), NIL(void));
1116            }
1117
1118
1119            if ((id->flags&OutPort) && (inst_item->expr->type==ConcatExpr)) {
1120                int m_lo, m_hi;
1121                get_hilo(id, &m_hi, &m_lo);
1122                write_out_port(file, id, m_hi,m_lo, inst_item->expr, auxSigST);
1123                write_var_decl(file, inst_item->expr->term);
1124                lsNewEnd(back_patch_list, (lsGeneric)inst_item->expr, 0);
1125            } else {
1126                masterIdDfn = id;
1127                if (old_item_expr)
1128                    if (old_item_expr->type == ConcatExpr)
1129                        vl_write_expr(file, old_item_expr, NIL(st_table));
1130                vl_write_expr(file, inst_item->expr, NIL(st_table));
1131                masterIdDfn = NIL(vl_id_range);
1132            }
1133
1134            constConnection = 0;
1135            if (!inst_item->expr) {
1136                constConnection = 1;
1137            } else if (!inst_item->expr->term) {
1138                constConnection = 1;
1139            } else {
1140                if (id->id_type) {
1141                    if (inst_item->expr->type == IDExpr &&
1142                        st_lookup(id->id_type->specifier->
1143                                  u.enum_type->domain_st,
1144                                  inst_item->expr->u.name->name,
1145                                  (char**)&enum_elt))
1146                        constConnection = 1;
1147                }
1148            }
1149
1150            if (constConnection) {
1151
1152                int hi, lo;
1153                vl_term *term_out;
1154                char conn[MAXSTRLEN];
1155
1156
1157                get_hilo(id, &hi, &lo);
1158                term_out = typed_new_term(id->id_type,NIL(vl_range),lo,hi);
1159                term_out->flag |= id->flags;
1160                lsNewEnd(input_consts,
1161                    (lsGeneric)create_const_term(inst_item->expr,term_out),0);
1162
1163                put_const_port_connect(NIL(FILE), conn,
1164                                       id, inst_item, input_consts, term_out);
1165                strcat(modbuf, conn);
1166                continue;
1167            }
1168
1169            if (inst_item->expr->type == IDExpr ||
1170                inst_item->expr->type == BitSelExpr ||
1171                inst_item->expr->type == PartSelExpr) {
1172                int retval = st_lookup(vl_currentModule->sig_st,
1173                                       inst_item->expr->u.name->name,
1174                                       (char**)&cur_sig);
1175                assert(retval);
1176            }
1177
1178
1179            if (implicitClocking && !vlTimedSystem && !implicitClockWire) {
1180                if (master->clk)
1181                    if (!strcmp(master->clk->expr->u.name->name, id->name))
1182                        continue;
1183                if (!strcmp(id->name,CLOCK))
1184                    continue;
1185            }
1186
1187            {
1188                char conn[MAXSTRLEN];
1189
1190                if (id->flags & MVar) {
1191
1192                    put_mvar_port_connect(NIL(FILE), conn, id, inst_item);
1193                } else {
1194                    get_hilo(id, &hi, &lo);
1195                    if (lo > hi) {
1196
1197                        put_bin_scalar_port_connect(NIL(FILE), conn,
1198                                                    id, inst_item);
1199                    } else {
1200
1201                        put_bin_vector_port_connect(NIL(FILE), conn,
1202                                                    id, inst_item);
1203                    }
1204                }
1205
1206                strcat(modbuf, conn);
1207                strcat(modbuf, " ");
1208            }
1209
1210            ith_port++;
1211        }
1212        lsFinish(inst_gen);
1213        lsFinish(mast_gen);
1214
1215        backgen = lsStart(back_patch_list);
1216        while (lsNext(backgen,(lsGeneric*)&backexpr,&backhandle)!=LS_NOMORE) {
1217            vl_write_outport_connect(file, backexpr);
1218        }
1219        lsFinish(backgen);
1220
1221        gen = lsStart(input_consts);
1222        while(lsNext(gen, (lsGeneric*)&ct, &handle) != LS_NOMORE) {
1223            if (!isOutPort(ct->term->flag))
1224                write_var_decl(file, ct->term);
1225                vl_write_const(file, ct->const_expr, ct->term);
1226        }
1227        lsFinish(gen);
1228
1229        stgen = st_init_gen(auxSigST);
1230        while (st_gen(stgen, &key, (char**)&dummy)) {
1231            if (!dummy)
1232                fprintf(file, "%s %s %s %s;\n",
1233                        SMV_VAR, key, SMV_COLON, SMV_BOOLEAN);
1234            else {
1235                int mhi, mlo;
1236                get_hilo((vl_id_range*)dummy, &mhi, &mlo);
1237                if (mhi < mlo)
1238                    fprintf(file, "%s %s %s %s;\n",
1239                            SMV_VAR, key, SMV_COLON, SMV_BOOLEAN);
1240                else
1241                    fprintf(file, "%s %s %s %s %d%s%d %s %s;\n", SMV_VAR,
1242                            key, SMV_COLON, SMV_ARRAY, mhi, SMV_RANGE, mlo,
1243                            SMV_OF, SMV_BOOLEAN);
1244            }
1245        }
1246        st_free_gen(stgen);
1247        auxSigST = NIL(st_table);
1248
1249        fprintf(file, "%s\n", modbuf);
1250
1251        lsDestroy(input_consts, 0);
1252    }
1253}
1254
1255
1256static void vl_write_prim_inst(FILE *file, vl_primitive *master,
1257                               vl_mod_prim_inst *inst)
1258{
1259    vl_write_mod_inst(file, (vl_module*)master, inst);
1260}
1261
1262
1263static void vl_write_gate_inst(FILE *file, short type, vl_gate_inst *gate)
1264{
1265    lsGen inst_gen;
1266    lsHandle inst_handle;
1267    vl_expr *inst_expr;
1268    vl_term *conn_term;
1269    vl_expr *old_item_expr = NIL(vl_expr);
1270    int constConnection;
1271    int ith_port;
1272    char buf[MAXSTRLEN];
1273    char outbuf[MAXSTRLEN];
1274    char *cp;
1275
1276    cp = outbuf;
1277    *cp = '\0';
1278    cp = strappendS(cp, ".subckt");
1279    cp = strappend(cp, "__sis_");
1280    cp = strappend(cp, GATE_NAME(type));
1281
1282    if (lsLength(gate->terms)>3) sprintf(buf,"%d",lsLength(gate->terms)-1);
1283    else buf[0]='\0';
1284    cp = strappendS(cp, buf);
1285    if (gate->name)
1286        cp = strappendS(cp, gate->name->name);
1287    else
1288        cp = strappendS(cp, new_termname());
1289
1290    inst_gen = lsStart(gate->terms);
1291    ith_port = 1;
1292    while (lsNext(inst_gen,
1293                  (lsGeneric*)&inst_expr, &inst_handle) != LS_NOMORE) {
1294
1295        if ((ith_port==1 || type == TranGate) && Zconnection) {
1296            lsList assign_list;
1297            vl_id_range *tmp_id;
1298            vl_term *tmp_term;
1299            vl_lval *tmp_lhs;
1300            vl_expr *tmp_rhs;
1301            vl_cont_assign *assign_stmt;
1302            char *dummy;
1303            int no_resolve;
1304
1305            no_resolve = 0;
1306            tmp_id = vl_create_id_range(vlStrdup(new_termname()),
1307                                        NIL(vl_range));
1308            tmp_term = vl_create_term(tmp_id, 0, -1);
1309            write_var_decl(file, tmp_term);
1310            if (inst_expr->type == ConcatExpr)
1311                tmp_lhs = vl_create_lval(ConcatExpr,
1312                                         NIL(vl_id_range),NIL(vl_range),
1313                                         (lsList)inst_expr->u.name);
1314            else {
1315
1316
1317                if (implicitDeclare && inst_expr->type == IDExpr) {
1318                    if (!st_lookup(vl_currentModule->sig_st,
1319                                   inst_expr->u.idrng->name, &dummy)) {
1320                        st_insert(vl_currentModule->sig_st,
1321                                  inst_expr->u.idrng->name,
1322                                  (char*)vl_create_id_range(inst_expr->u.idrng->name, NIL(vl_range)));
1323                    } else {
1324                        no_resolve = !((((vl_id_range*)dummy)->flags & InPort) &&
1325                                       (((vl_id_range*)dummy)->flags & OutPort)) &&
1326                                     type == TranGate;
1327                    }
1328                }
1329                tmp_lhs = vl_create_lval(inst_expr->type,
1330                                         inst_expr->u.idrng,
1331                                         inst_expr->u.idrng->range,
1332                                         (lsList)0);
1333            }
1334
1335            if (!no_resolve) {
1336                tmp_rhs = vl_create_expr(IDExpr, 0, (double)0.0,
1337                                         tmp_id, NIL(void), NIL(void));
1338                assign_list = lsCreate();
1339                lsNewEnd(assign_list,
1340                         (lsGeneric)vl_create_bassign_stmt(AssignStmt,
1341                                                           tmp_lhs,
1342                                                           NIL(void),
1343                                                           tmp_rhs),
1344                         0);
1345                assign_stmt = vl_create_cont_assign_stmt(0, NIL(vl_delay),
1346                                                         assign_list);
1347                lsInAfter(curModGen, (lsGeneric)assign_stmt, PcurModHandle);
1348            }
1349
1350            old_item_expr = inst_expr;
1351            inst_expr = vl_create_expr(IDExpr, 0, (double)0.0,
1352                                       tmp_id, NIL(void), NIL(void));
1353        }
1354
1355        vl_write_expr(file, inst_expr, NIL(st_table));
1356
1357        constConnection = 0;
1358        if (!inst_expr) {
1359            constConnection = 1;
1360        } else if (!inst_expr->term) {
1361            constConnection = 1;
1362        }
1363
1364        if (constConnection) {
1365            conn_term = new_term(NIL(vl_range),0,-1);
1366            vl_write_const(file, inst_expr, conn_term);
1367        } else {
1368            conn_term = inst_expr->term;
1369        }
1370
1371
1372        if (inst_expr->term->lo > inst_expr->term->hi) {
1373            sprintf(buf, "%c=%s", (ith_port==1)?'o':'a'+ith_port-2,
1374                    conn_term->name->name);
1375        } else {
1376            sprintf(buf, "%c=%s%s%d%s", (ith_port==1)?'o':'a'+ith_port-2,
1377                    conn_term->name->name,
1378                    SEP_LBITSELECT, inst_expr->term->lo, SEP_RBITSELECT);
1379        }
1380
1381        cp = strappendS(cp, buf);
1382        ith_port++;
1383    }
1384    lsFinish(inst_gen);
1385
1386    fprintf(file, "%s\n", outbuf);
1387}
1388
1389
1390static void vl_write_tesla_timer_inst(FILE *file, vl_gate_inst *gate,
1391                                      int lb, int ub)
1392{
1393    static int teslaTimerCounter = 0;
1394    char ps[MAXSTRLEN], ns[MAXSTRLEN];
1395    char timer[MAXSTRLEN];
1396    vl_term *(w[5]);
1397    int constConnection;
1398    int i;
1399    lsGen inst_gen;
1400    lsHandle inst_handle;
1401    vl_expr *inst_expr;
1402
1403    if (lsLength(gate->terms) != 5) {
1404        char buf[MAXSTRLEN];
1405        sprintf(buf, "%s:teslaTimer needs exactly 3 inputs + 2 outputs\n",
1406                vl_currentModule->name->name);
1407        Translate_Warning(buf);
1408    }
1409
1410    for (inst_gen=lsStart(gate->terms), i=0;
1411         lsNext(inst_gen, (lsGeneric*)&inst_expr, &inst_handle) != LS_NOMORE;
1412         i++) {
1413        vl_write_expr(file, inst_expr, NIL(st_table));
1414
1415        constConnection = 0;
1416        if (!inst_expr) {
1417          constConnection = 1;
1418        } else if (!inst_expr->term) {
1419          constConnection = 1;
1420        }
1421
1422        if (constConnection) {
1423          w[i] = new_term(NIL(vl_range),0,-1);
1424          vl_write_const(file, inst_expr, w[i]);
1425        } else
1426          w[i] = inst_expr->term;
1427    }
1428    lsFinish(inst_gen);
1429
1430    sprintf(ps, "%s", new_termname());
1431    sprintf(ns, "%s", new_termname());
1432    sprintf(timer, "TESLATM%d", teslaTimerCounter++);
1433    fprintf(file, ".mv %s, %s 4 s w t1 t2\n", ps, ns);
1434    fprintf(file, ".latch %s %s\n.r %s\ns\n", ns, ps, ps);
1435    fprintf(file, ".timers %s\n", timer);
1436    fprintf(file, ".names %s %s %s %s %s %s %s %s\n",
1437            ps, w[0]->name->name, w[1]->name->name, w[4]->name->name,
1438            HSIS_ARROW,
1439            w[2]->name->name, w[3]->name->name, ns);
1440    fprintf(file, "s 0 - - 0 0 s\n");
1441    fprintf(file, "s - 1 - 0 0 s\n");
1442    if (lb==0)
1443        fprintf(file, "s 1 0 1 1 0 s\n");
1444    else
1445        fprintf(file, "s 1 0 1 0 1 t1\n");
1446    fprintf(file, "s 1 0 0 0 0 w && %s=0\n", timer);
1447    fprintf(file, "w - 1 - 0 0 s\n");
1448    fprintf(file, "w - 0 0 0 0 w && %s<=%d\n", timer, ub);
1449    fprintf(file, "w - 0 1 1 0 s && %s>=%d && %s<=%d\n", timer, lb, timer, ub);
1450    fprintf(file, "w - 0 1 0 1 t1 && %s<%d\n", timer, lb);
1451    fprintf(file, "w - 0 - 0 1 t2 && %s>%d\n", timer, ub);
1452    fprintf(file, "t1 - 0 - 0 1 t1\n");
1453    fprintf(file, "t1 - 1 - 0 1 s\n");
1454    fprintf(file, "t2 - 0 - 0 1 t2\n");
1455    fprintf(file, "t2 - 1 - 0 1 s\n");
1456}
1457
1458
1459
1460void vl_write_reset(FILE *file, vl_procstmt *init_stmt)
1461{
1462    st_table *reset_vars=NIL(st_table);
1463    st_generator *gen;
1464    char *key;
1465    var_info *id_var;
1466    vl_id_range *id_sym;
1467
1468    reset_vars = st_init_table(strcmp, st_strhash);
1469    rst_ckt = 1;
1470    vl_write_reset_stmt(file, init_stmt->stmt, reset_vars);
1471    non_block_assignment(file, reset_vars);
1472    gen = st_init_gen(reset_vars);
1473    while (st_gen(gen, &key, (char**)&id_var)) {
1474        if (st_lookup(vl_currentModule->sig_st, key, (char**)&id_sym)) {
1475            lsNewEnd(id_sym->initial, (lsGeneric)id_var->current_terminal, 0);
1476            if (strstr(id_sym->name, SEP_LATCH)) {
1477                char buf[MAXSTRLEN];
1478                strcpy(buf, id_sym->name);
1479                strip_char(buf, SEP_LATCH);
1480                if (st_lookup(vl_currentModule->sig_st, buf, (char**)&id_sym))
1481                    lsNewEnd(id_sym->initial,
1482                             (lsGeneric)id_var->current_terminal, 0);
1483            }
1484        }
1485    }
1486    st_free_gen(gen);
1487    rst_ckt = 0;
1488}
1489
1490
1491st_table *vl_write_procstmt(FILE *file, vl_procstmt *procstmt, st_table *vars)
1492{
1493    int old_lhs_must_be_wire;
1494
1495    WrtTRACE("Writing always/initial statement");
1496
1497
1498
1499    vl_pauseStack = create_stack();
1500    vl_current_pause_list = lsCreate();
1501    vl_current_vars_list = lsCreate();
1502
1503    in_procedure = 1;
1504    if (procstmt->type == AlwaysStmt) {
1505        old_lhs_must_be_wire = lhs_must_be_wire;
1506        if (((vl_bassign_stmt*)procstmt->stmt)->type != EventControlStmt) {
1507            lhs_must_be_wire = 1;
1508
1509        }
1510
1511
1512        vars = vl_write_stmt(file, procstmt->stmt,NO_MUX,NIL(vl_term),vars);
1513
1514        if (vlTimedSystem) final_vars = vars;
1515        lhs_must_be_wire = old_lhs_must_be_wire;
1516
1517        if (procstmt->flags & PseudoAlways) {
1518
1519            vl_register_pause((vertex_t *) procstmt->fg_info, vars);
1520        }
1521
1522
1523        if (lsLength(vl_current_pause_list) > 1 && vlTimedSystem) {
1524            st_table *new_table;
1525            new_table = st_init_table(strcmp, st_strhash);
1526            vl_prioritize_sequence(file,
1527                                   vl_current_vars_list, vl_current_pause_list,
1528                                   new_table);
1529            vars = new_table;
1530        }
1531    }
1532    in_procedure = 0;
1533
1534    destroy_stack(vl_pauseStack, 0);
1535    vl_pauseStack = (lsList)0;
1536    lsDestroy(vl_current_pause_list, 0);
1537    lsDestroy(vl_current_vars_list, 0);
1538    vl_current_pause_list = (lsList)0;
1539    vl_current_vars_list = (lsList)0;
1540
1541    return vars;
1542}
1543
1544
1545st_table *vl_write_stmt(FILE *file, void *stmt, int muxed, vl_term *muxsel, st_table *vars)
1546{
1547    vl_id_range *id_sym;
1548    vl_term *out_term;
1549    vl_term *new_out;
1550    vl_term *tmp_term;
1551    vl_term *sel;
1552    st_table *pre_cond=NIL(st_table);
1553    st_table *old_init_vars=NIL(st_table);
1554    int using_ith_ctrl;
1555    int fg_id;
1556    int cur_bit_pos;
1557    int num_lhs_vars;
1558    lsList lhs_list;
1559    lsGen lhs_gen=(lsGen)0;
1560    lsHandle lhs_handle;
1561    vl_expr *lhs_expr;
1562    vl_id_range *lhs_var;
1563    vl_range *lhs_range;
1564    int old_check_rhs_sen;
1565    int i;
1566
1567    if (stmt == NIL(void)) {
1568        return vars;
1569    }
1570
1571    WrtTRACE("Writing statement");
1572
1573    switch(((vl_bassign_stmt *)stmt)->type) {
1574    case BeginEndStmt:
1575        vars = vl_write_begin_end_stmt(file, stmt, muxed, muxsel, vars);
1576        break;
1577    case IfElseStmt:
1578        Being_Conditioned++;
1579        vars = vl_write_if_else_stmt(file, stmt, vars);
1580        Being_Conditioned--;
1581        break;
1582    case CaseStmt:
1583    case CasexStmt:
1584    case CasezStmt:
1585        Being_Conditioned++;
1586        vars = vl_write_case_stmt(file, stmt, vars);
1587        Being_Conditioned--;
1588        break;
1589    case CaseItem:
1590        break;
1591    case DefaultItem:
1592        break;
1593    case ForeverStmt:
1594        break;
1595    case RepeatStmt:
1596        break;
1597    case WhileStmt: {
1598        if (!rst_ckt) {
1599            st_table *fork_in_vars;
1600            vl_term *dom_sel;
1601
1602            using_ith_ctrl = rst_ith_ctrl;
1603            rst_ith_ctrl++;
1604            vl_write_expr(file, ((vl_while_stmt*)stmt)->cond, vars);
1605
1606
1607
1608            tmp_term = new_term(NIL(vl_range), 0, -1);
1609            if (!((vl_while_stmt*)stmt)->cond->term) {
1610                sel = new_term(NIL(vl_range), 0, -1);
1611                vl_write_const(file, ((vl_while_stmt*)stmt)->cond, sel);
1612                ((vl_while_stmt*)stmt)->cond->term = sel;
1613            } else if (((vl_while_stmt*)stmt)->cond->term->lo <=
1614                       ((vl_while_stmt*)stmt)->cond->term->hi) {
1615                sel = new_term(NIL(vl_range), 0, -1);
1616                vl_write_vector_bop(file, UorExpr,
1617                                    ((vl_while_stmt*)stmt)->cond->term,
1618                                    NIL(vl_term), sel);
1619            } else {
1620                sel = ((vl_while_stmt*)stmt)->cond->term;
1621            }
1622
1623            assert ((((vl_while_stmt*)stmt)->cond->fg_info1 && ((vl_while_stmt*)stmt)->cond->fg_info2) || (!((vl_while_stmt*)stmt)->cond->fg_info1 && !((vl_while_stmt*)stmt)->cond->fg_info2));
1624
1625
1626            if (((vl_while_stmt*)stmt)->cond->fg_info1) {
1627
1628                fg_loop_collect_pause(file,
1629                    (vertex_t*)((vl_while_stmt*)stmt)->cond->fg_info1,
1630                    (vertex_t*)((vl_while_stmt*)stmt)->cond->fg_info2,
1631                    &dom_sel);
1632
1633            }
1634
1635
1636            if (((vl_while_stmt*)stmt)->cond->fg_info1)
1637                fg_update_node_info((vertex_t*)
1638                                    (((vl_while_stmt*)stmt)->cond->fg_info1),
1639                                    (char*)sel);
1640
1641            vl_write_bin_connect(file, sel, tmp_term, 0);
1642            lsNewEnd(rst_ctrl_list, (lsGeneric)tmp_term, 0);
1643            rst_ctrl_syndrome[using_ith_ctrl] = '1';
1644
1645            old_init_vars = vl_current_init_vars;
1646            vl_current_init_vars = st_init_table(strcmp, st_strhash);
1647            fork_in_vars = st_copy(vars);
1648            vl_predefine_vars(file, vars);
1649
1650            vars = vl_write_stmt(file,
1651                                 ((vl_while_stmt*)stmt)->stmt,
1652                                 muxed,muxsel,vars);
1653
1654            rst_ctrl_syndrome[using_ith_ctrl] = '-';
1655            vl_timed_init_mux(file, dom_sel, vars,
1656                              vl_current_init_vars, fork_in_vars);
1657            vl_current_init_vars = old_init_vars;
1658        }
1659        break;
1660    }
1661    case ForStmt: {
1662        if (!rst_ckt) {
1663            st_table *fork_in_vars;
1664            vl_term *dom_sel;
1665
1666            vl_write_stmt(file, ((vl_for_stmt*)stmt)->init,muxed,muxsel,vars);
1667
1668            old_init_vars = vl_current_init_vars;
1669            vl_current_init_vars = st_init_table(strcmp, st_strhash);
1670            fork_in_vars = st_copy(vars);
1671            vl_predefine_vars(file, vars);
1672
1673            using_ith_ctrl = rst_ith_ctrl;
1674            rst_ith_ctrl++;
1675            vl_write_expr(file, ((vl_for_stmt*)stmt)->cond, vars);
1676
1677            tmp_term = new_term(NIL(vl_range), 0, -1);
1678            if (!((vl_for_stmt*)stmt)->cond->term) {
1679                sel = new_term(NIL(vl_range), 0, -1);
1680                vl_write_const(file, ((vl_for_stmt*)stmt)->cond, sel);
1681                ((vl_for_stmt*)stmt)->cond->term = sel;
1682            } else if (((vl_for_stmt*)stmt)->cond->term->lo <=
1683                       ((vl_for_stmt*)stmt)->cond->term->hi) {
1684                sel = new_term(NIL(vl_range), 0, -1);
1685                vl_write_vector_bop(file, UorExpr,
1686                                    ((vl_for_stmt*)stmt)->cond->term,
1687                                    NIL(vl_term), sel);
1688            } else {
1689                sel = ((vl_for_stmt*)stmt)->cond->term;
1690            }
1691
1692            assert ((((vl_for_stmt*)stmt)->cond->fg_info1 && ((vl_for_stmt*)stmt)->cond->fg_info2) || (!((vl_for_stmt*)stmt)->cond->fg_info1 && !((vl_for_stmt*)stmt)->cond->fg_info2));
1693
1694            if (((vl_for_stmt*)stmt)->cond->fg_info1) {
1695
1696                fg_loop_collect_pause(file,
1697                    (vertex_t*)((vl_for_stmt*)stmt)->cond->fg_info1,
1698                    (vertex_t*)((vl_for_stmt*)stmt)->cond->fg_info2,
1699                    &dom_sel);
1700            }
1701
1702            if (((vl_for_stmt*)stmt)->cond->fg_info1)
1703                fg_update_node_info((vertex_t*)
1704                                        (((vl_for_stmt*)stmt)->cond->fg_info1),
1705                                    (char*)sel);
1706
1707            vl_write_bin_connect(file, sel, tmp_term, 0);
1708            lsNewEnd(rst_ctrl_list, (lsGeneric)tmp_term, 0);
1709            rst_ctrl_syndrome[using_ith_ctrl] = '1';
1710
1711            vars = vl_write_stmt(file,
1712                                 ((vl_for_stmt*)stmt)->stmt,muxed,muxsel,vars);
1713
1714            vars = vl_write_stmt(file,
1715                                 ((vl_for_stmt*)stmt)->end,muxed,muxsel,vars);
1716
1717            rst_ctrl_syndrome[using_ith_ctrl] = '-';
1718            vl_timed_init_mux(file, dom_sel, vars,
1719                              vl_current_init_vars, fork_in_vars);
1720            vl_current_init_vars = old_init_vars;
1721        }
1722        break;
1723    }
1724
1725    case DelayControlStmt: {
1726
1727        vl_register_pause((vertex_t *)((vl_delay_control_stmt*)stmt)->fg_info,
1728                          vars);
1729        vars = st_init_table(strcmp, st_strhash);
1730        vl_write_stmt(file, ((vl_delay_control_stmt*)stmt)->stmt,
1731                      muxed, muxsel, vars);
1732        break;
1733    }
1734
1735    case EventControlStmt: {
1736
1737        vl_register_pause((vertex_t *)((vl_event_control_stmt*)stmt)->fg_info,
1738                          vars);
1739        vars = st_init_table(strcmp, st_strhash);
1740        vars = vl_write_stmt(file, ((vl_event_control_stmt*)stmt)->stmt,
1741                             muxed, muxsel, vars);
1742        break;
1743    }
1744
1745    case DelayBassignStmt:
1746    case DelayNbassignStmt: {
1747        char buf[MAXSTRLEN];
1748
1749        yylineno = ((vl_bassign_stmt*)stmt)->lineno;
1750
1751        sprintf(buf, "'%s' contains delay, do not know how to synthesize it",
1752                vl_currentModule->name->name);
1753        Translate_Warning(buf);
1754        break;
1755    }
1756
1757    case AssignStmt:
1758    case BassignStmt:
1759    case NbassignStmt:
1760    case EventBassignStmt:
1761    case EventNbassignStmt: {
1762
1763        yylineno = ((vl_bassign_stmt*)stmt)->lineno;
1764
1765
1766        if (((vl_bassign_stmt*)stmt)->lhs->type == ConcatExpr) {
1767
1768            num_lhs_vars = lsLength(((vl_bassign_stmt*)stmt)->lhs->concat);
1769            lhs_list = ((vl_bassign_stmt*)stmt)->lhs->concat;
1770            lhs_gen = lsStart(lhs_list);
1771        } else {
1772            num_lhs_vars = 1;
1773            lhs_list = (lsList)0;
1774        }
1775
1776
1777        for (i=0; i<num_lhs_vars; i++) {
1778            if (lhs_list) {
1779                int retval = lsNext(lhs_gen,(lsGeneric*)&lhs_expr,&lhs_handle);
1780                assert(retval != LS_NOMORE);
1781                lhs_var = lhs_expr->u.name;
1782                lhs_range = lhs_var->range;
1783            } else {
1784                lhs_var = ((vl_bassign_stmt*)stmt)->lhs->name;
1785                lhs_range = ((vl_bassign_stmt*)stmt)->lhs->range;
1786            }
1787
1788            if (!st_lookup(vl_currentModule->sig_st, lhs_var->name,
1789                           (char**)&id_sym)) {
1790                char buf[MAXSTRLEN];
1791
1792                sprintf(buf, "variable %s not declared while used as lhs",
1793                        lhs_var->name);
1794                compile_error(buf);
1795                id_sym = lhs_var;
1796                st_insert(vl_currentModule->sig_st,
1797                          id_sym->name, (char*)id_sym);
1798            }
1799
1800            if (lhs_range)
1801                if (((vl_bassign_stmt *)stmt)->type == NbassignStmt ||
1802                    ((vl_bassign_stmt *)stmt)->type == EventNbassignStmt) {
1803                    char buf[MAXSTRLEN];
1804                    sprintf(buf,
1805                            "'%s':non-blocking to partial vector, array element",
1806                            id_sym->name);
1807                    compile_error(buf);
1808                }
1809
1810            if (id_sym->flags & InPort) {
1811                char buf[MAXSTRLEN];
1812
1813                sprintf(buf, "trying to assign to input variable %s",
1814                        id_sym->name);
1815                yylineno = ((vl_bassign_stmt*)stmt)->lineno;
1816                compile_error(buf);
1817            }
1818
1819            id_sym->edge_trigger = edge_triggering;
1820
1821            if (recordCombAlways && !edge_triggering) {
1822
1823                vl_id_range *temp_id_sym;
1824
1825                if (!st_lookup(vl_currentModule->combVar_st, id_sym->name,
1826                               (char**)&temp_id_sym)) {
1827                    st_insert(vl_currentModule->combVar_st, id_sym->name,
1828                              (char*)id_sym);
1829                }
1830            } else {
1831                id_sym->sensitiveList = sensitiveList;
1832            }
1833        }
1834
1835        if (lhs_list) lsFinish(lhs_gen);
1836
1837        old_check_rhs_sen = check_rhs_sensitivity;
1838        check_rhs_sensitivity =
1839            !(((vl_bassign_stmt*)stmt)->type == AssignStmt && vars);
1840        out_term = vl_write_assign(file,(vl_bassign_stmt*)stmt,
1841                                   muxed,muxsel,vars);
1842        check_rhs_sensitivity = old_check_rhs_sen;
1843
1844        if (lhs_list) {
1845            lhs_gen = lsStart(((vl_bassign_stmt*)stmt)->lhs->concat);
1846            assert(array_n(assign_array) == num_lhs_vars);
1847        }
1848
1849        for (i=0, cur_bit_pos=0; i<num_lhs_vars; i++) {
1850            if (lhs_list) {
1851                int retval = lsNext(lhs_gen,(lsGeneric*)&lhs_expr,&lhs_handle);
1852                assert(retval != LS_NOMORE);
1853                lhs_var = lhs_expr->u.name;
1854                retval = st_lookup(vl_currentModule->sig_st,
1855                                   lhs_expr->u.name->name, (char**)&id_sym);
1856                assert(retval);
1857            }
1858
1859            if (((vl_bassign_stmt*)stmt)->type == NbassignStmt ||
1860                ((vl_bassign_stmt*)stmt)->type == DelayNbassignStmt ||
1861                ((vl_bassign_stmt*)stmt)->type == EventNbassignStmt) {
1862
1863                char buf[MAXSTRLEN];
1864                sprintf(buf, "%s%s", id_sym->name, SEP_LATCH);
1865                st_lookup(vl_currentModule->sig_st, buf, (char**)&id_sym);
1866            } else if (((vl_bassign_stmt*)stmt)->type == AssignStmt && vars) {
1867
1868                char buf[MAXSTRLEN];
1869                sprintf(buf, "%s%s", id_sym->name, SEP_QUASI);
1870                st_lookup(vl_currentModule->sig_st, buf, (char**)&id_sym);
1871            }
1872
1873            if (!out_term) break;
1874            if (lhs_list) out_term = array_fetch(vl_term*, assign_array, i);
1875            new_out = vl_copy_term(out_term);
1876            if (lhs_list) {
1877
1878                int hi, lo;
1879                get_hilo(id_sym, &hi, &lo);
1880                if (hi < lo) hi=lo=0;
1881                new_out->lo = cur_bit_pos;
1882                new_out->hi = new_out->lo + (hi-lo+1) -1;
1883                cur_bit_pos = new_out->hi + 1;
1884            }
1885
1886            pre_cond =
1887                fg_assign_temporal_context((vertex_t*)
1888                                           (((vl_bassign_stmt*)stmt)->fg_info));
1889            fg_id = fg_fg_id();
1890
1891
1892            if (cntxt_event)
1893                record_pseudo_cntxt(file, fg_id, pre_cond,
1894                                    ctrl_syndrome, rst_ctrl_syndrome, vars);
1895
1896            if (!rst_ckt) {
1897                syndrome_expr *newCtrlExpr;
1898
1899                if (((vl_bassign_stmt *)stmt)->type == NbassignStmt ||
1900                    ((vl_bassign_stmt *)stmt)->type == DelayNbassignStmt ||
1901                    ((vl_bassign_stmt *)stmt)->type == EventNbassignStmt) {
1902                }
1903                newCtrlExpr = create_syndrome_expr(vlStrdup(ctrl_syndrome),
1904                                                   new_out, pre_cond, fg_id);
1905                lsNewEnd(id_sym->syndrome_expr_list, (lsGeneric)newCtrlExpr, 0);
1906
1907                st_insert(vars, id_sym->name,
1908                          (char*)create_var_info(vl_copy_id_range(id_sym),
1909                                                 out_term));
1910            } else {
1911                syndrome_expr *newCtrlExpr;
1912
1913                if (((vl_bassign_stmt *)stmt)->type == NbassignStmt ||
1914                    ((vl_bassign_stmt *)stmt)->type == DelayNbassignStmt ||
1915                    ((vl_bassign_stmt *)stmt)->type == EventNbassignStmt) {
1916                }
1917
1918                newCtrlExpr = create_syndrome_expr(vlStrdup(rst_ctrl_syndrome),
1919                                                   new_out, pre_cond, fg_id);
1920                lsNewEnd(id_sym->rst_syndrome_expr_list,
1921                         (lsGeneric)newCtrlExpr, 0);
1922
1923                st_insert(vars, id_sym->name,
1924                          (char*)create_var_info(vl_copy_id_range(id_sym),
1925                                                 out_term));
1926            }
1927        }
1928        break;
1929    }
1930    case WaitStmt: {
1931
1932        if (((vl_wait_stmt*)stmt)->cond == NIL(vl_expr)) {
1933            vl_write_begin_end_stmt(file, ((vl_wait_stmt*)stmt)->stmt,
1934                                    muxed, muxsel, vars);
1935        }
1936        break;
1937    }
1938    case ForkJoinStmt:
1939        break;
1940    case TaskEnableStmt:
1941    case SysTaskEnableStmt:
1942        break;
1943    case DisableStmt:
1944        break;
1945    case DeassignStmt: {
1946        syndrome_expr *newCtrlExpr;
1947        vl_term *operand_term;
1948        char quasi[MAXSTRLEN];
1949
1950        if (!st_lookup(vl_currentModule->sig_st,
1951                       ((vl_deassign_stmt*)stmt)->lhs->name->name,
1952                       (char**)&id_sym)) {
1953            char buf[MAXSTRLEN];
1954
1955            sprintf(buf, "%s:deassign '%s', which is undefined variable",
1956                    vl_currentModule->name->name,
1957                    ((vl_deassign_stmt*)stmt)->lhs->name->name);
1958            yylineno = -1;
1959            compile_error(buf);
1960        }
1961
1962        sprintf(quasi, "%s%s", id_sym->name, SEP_QUASI);
1963        if (!st_lookup(vl_currentModule->sig_st, quasi, (char**)&id_sym)) {
1964            int retval;
1965            collect_quasi(quasi);
1966            retval = st_lookup(vl_currentModule->sig_st,quasi,(char**)&id_sym);
1967            assert(retval);
1968        }
1969
1970        operand_term =
1971            vl_create_term(((vl_deassign_stmt*)stmt)->lhs->name, 0,-1);
1972        fg_id = fg_fg_id();
1973        pre_cond =
1974            fg_assign_temporal_context((vertex_t*)
1975                                       (((vl_deassign_stmt*)stmt)->fg_info));
1976        newCtrlExpr = create_syndrome_expr(vlStrdup(ctrl_syndrome),
1977                                           operand_term, pre_cond, fg_id);
1978        lsNewEnd((!rst_ckt)?id_sym->syndrome_expr_list:
1979                 id_sym->rst_syndrome_expr_list,
1980                 (lsGeneric)newCtrlExpr, 0);
1981        break;
1982    }
1983    case SendEventStmt: {
1984        char vnt_buf[MAXSTRLEN];
1985
1986        if (!st_lookup(vl_currentModule->sig_st,
1987                       ((vl_send_event_stmt*)stmt)->name->name,
1988                       (char**)&id_sym)) {
1989            char buf[MAXSTRLEN];
1990            sprintf(buf, "variable %s not declared while used as event",
1991                    ((vl_send_event_stmt*)stmt)->name->name);
1992            yylineno = -1;
1993            compile_error(buf);
1994        }
1995
1996        out_term = new_term(NIL(vl_range), 0, -1);
1997        sprintf(vnt_buf, "%s%s%s", id_sym->name, SEP_GATEPIN, PIN_EVENT);
1998        if (smartEvent)
1999            write_int_connect(file, 1, out_term);
2000        else
2001            vl_write_bit_connect(file, vnt_buf, out_term->name->name, 1);
2002        new_out = vl_copy_term(out_term);
2003
2004        pre_cond =
2005            fg_assign_temporal_context((vertex_t*)
2006                                       (((vl_send_event_stmt*)stmt)->fg_info));
2007        fg_id = fg_fg_id();
2008
2009        lsNewEnd(id_sym->syndrome_expr_list,
2010                 (lsGeneric)create_syndrome_expr(vlStrdup(ctrl_syndrome),
2011                                                 new_out, pre_cond, fg_id),
2012                 0);
2013
2014
2015
2016        st_insert(vars, id_sym->name,
2017                  (char*)create_var_info(vl_copy_id_range(id_sym), out_term));
2018        break;
2019    }
2020    default: {
2021        char msg[MAXSTRLEN];
2022        sprintf(msg, "vl_write_stmt:Unexpected Statement Type %d",
2023                ((vl_bassign_stmt *)stmt)->type);
2024        internal_error(msg);
2025    }
2026    }
2027    return vars;
2028}
2029
2030
2031void vl_write_reset_stmt(FILE *file, void *stmt, st_table *vars)
2032{
2033    if (stmt == NIL(void)) return;
2034
2035    WrtTRACE("Writing reset statement");
2036
2037    vl_write_stmt(file, stmt, NO_MUX, NIL(vl_term), vars);
2038}
2039
2040st_table *vl_write_begin_end_stmt(FILE *file, vl_begin_end_stmt *bestmt, int muxed, vl_term *control, st_table *vars)
2041{
2042    WrtTRACE("Writing begin/end\n");
2043
2044    vl_write_decl_list(file, bestmt->decls, muxed, control, vars);
2045    vars = vl_write_stmt_list(file, bestmt->stmts, muxed, control, vars);
2046    return vars;
2047}
2048
2049st_table *vl_write_if_else_stmt(FILE *file, vl_if_else_stmt *stmt, st_table *vars)
2050{
2051    st_table *t_vars, *f_vars;
2052    st_generator *gen;
2053    char *key;
2054    var_info *t_in, *f_in, *cur_var;
2055    int using_ith_ctrl;
2056    vl_term *sel, *tmp_term;
2057
2058    WrtTRACE("Writing if/then/else statement");
2059
2060    if (!rst_ckt) {
2061        using_ith_ctrl = ith_ctrl;
2062        ith_ctrl++;
2063    } else {
2064        using_ith_ctrl = rst_ith_ctrl;
2065        rst_ith_ctrl++;
2066    }
2067
2068
2069    if (!stmt->else_stmt) {
2070        if (sensitiveList && vl_currentModule->combVar_st) {
2071            if (chk_IncompleteBranch) {
2072                char buf[MAXSTRLEN];
2073                recordCombAlways = 0;
2074                vl_currentModule->combVar_st = NIL(set_t);
2075                vl_step_stmt(stderr, stmt);
2076                sprintf(buf,
2077                        "%s:incomplete if/ese, combinational reduction failed",
2078                        vl_currentModule->name->name);
2079                yylineno = -1;
2080                compile_error(buf);
2081            }
2082        }
2083    }
2084
2085    vl_write_expr(file, stmt->cond, vars);
2086
2087
2088
2089    tmp_term = new_term(NIL(vl_range), 0, -1);
2090    if (!stmt->cond->term) {
2091        sel = new_term(NIL(vl_range), 0, -1);
2092        vl_write_const(file, stmt->cond, sel);
2093        stmt->cond->term = sel;
2094    } else if (stmt->cond->term->lo <= stmt->cond->term->hi) {
2095        sel = new_term(NIL(vl_range), 0, -1);
2096        vl_write_vector_bop(file, UorExpr,
2097                            stmt->cond->term, NIL(vl_term), sel);
2098    } else {
2099        sel = stmt->cond->term;
2100    }
2101
2102    assert ((stmt->cond->fg_info1 && stmt->cond->fg_info2) || (!stmt->cond->fg_info1 && !stmt->cond->fg_info2));
2103
2104
2105    if (stmt->cond->fg_info1)
2106        fg_update_node_info((vertex_t*)(stmt->cond->fg_info1), (char*)sel);
2107
2108
2109    if (stmt->cond->fg_info1) {
2110
2111        fg_if_collect_pause_rewrite_ctrl(file,
2112            (vertex_t*)stmt->cond->fg_info1, (vertex_t*)stmt->cond->fg_info2,
2113            &sel);
2114        stmt->cond->term = sel;
2115    }
2116
2117    vl_write_bin_connect(file, sel, tmp_term, 0);
2118    if (!rst_ckt)
2119        lsNewEnd(ctrl_list, (lsGeneric)tmp_term, 0);
2120    else
2121        lsNewEnd(rst_ctrl_list, (lsGeneric)tmp_term, 0);
2122
2123    t_vars = st_copy(vars);
2124    f_vars = st_copy(vars);
2125    dup_info_var_in_st(t_vars);
2126    dup_info_var_in_st(f_vars);
2127    reset_cond_list_in_st(t_vars);
2128    reset_cond_list_in_st(f_vars);
2129
2130    if (!rst_ckt)
2131        ctrl_syndrome[using_ith_ctrl] = '1';
2132    else
2133        rst_ctrl_syndrome[using_ith_ctrl] = '1';
2134    t_vars = vl_write_stmt(file,stmt->if_stmt,MUX_T, stmt->cond->term,t_vars);
2135    if (!rst_ckt)
2136        ctrl_syndrome[using_ith_ctrl] = '0';
2137    else
2138        rst_ctrl_syndrome[using_ith_ctrl] = '0';
2139    f_vars = vl_write_stmt(file,stmt->else_stmt,MUX_F,stmt->cond->term,f_vars);
2140    if (!rst_ckt)
2141        ctrl_syndrome[using_ith_ctrl] = '-';
2142    else
2143        rst_ctrl_syndrome[using_ith_ctrl] = '-';
2144
2145    fprintf(file, "%s if/else (", HSIS_COMMENT);
2146    (void)vl_step_expr(file, stmt->cond);
2147    fprintf(file, ")\n");
2148
2149    vars = create_var_muxes(file, stmt->cond->term, t_vars, f_vars, vars);
2150
2151    gen = st_init_gen(t_vars);
2152    while (st_gen(gen, &key, (char**)&t_in)) {
2153        st_delete(t_vars, &key, (char**)&t_in);
2154        if (st_lookup(vars, key, (char**)&cur_var))
2155            if (cur_var == t_in)
2156                continue;
2157        free_var_info(t_in);
2158    }
2159    st_free_gen(gen);
2160    gen = st_init_gen(f_vars);
2161    while (st_gen(gen, &key, (char**)&f_in)) {
2162        st_delete(t_vars, &key, (char**)&f_in);
2163        if (st_lookup(vars, key, (char**)&cur_var))
2164            if (cur_var == f_in)
2165                continue;
2166        free_var_info(f_in);
2167    }
2168    st_free_gen(gen);
2169
2170
2171
2172    return vars;
2173}
2174
2175
2176st_table *vl_write_case_stmt(FILE *file, vl_case_stmt *stmt, st_table *vars)
2177{
2178    st_table **case_vars;
2179    int i;
2180    vl_case_item *item;
2181    lsHandle handle;
2182    lsGen gen;
2183    vl_term **controls, *prev_ctrl = NIL(vl_term);
2184    vl_term *pause_ripple=NIL(vl_term);
2185    int using_ith_ctrl = -1;
2186    char old_ctrl_syndrome[MAXSTRLEN];
2187
2188    WrtTRACE("Writing case\n");
2189
2190    if (!rst_ckt)
2191        strcpy(old_ctrl_syndrome, ctrl_syndrome);
2192    else
2193        strcpy(old_ctrl_syndrome, rst_ctrl_syndrome);
2194
2195    assert((stmt->cond->fg_info1 && stmt->cond->fg_info2) || (!stmt->cond->fg_info1 && !stmt->cond->fg_info2));
2196
2197    switch (stmt->type) {
2198    case CaseStmt:
2199    case CasexStmt:
2200    case CasezStmt: break;
2201    default:
2202        internal_error("Unexpected Case Type"); break;
2203    }
2204
2205
2206
2207    {
2208        vl_write_expr(file, stmt->cond, vars);
2209
2210        case_vars = (st_table**)chk_malloc(lsLength(stmt->case_items) *
2211                                           sizeof(st_table*));
2212        controls = (vl_term**)chk_malloc(lsLength(stmt->case_items) *
2213                                         sizeof(vl_term*));
2214        for (i=0; i<lsLength(stmt->case_items); i++) {
2215            case_vars[i] = NIL(st_table);
2216            controls[i] = NIL(vl_term);
2217        }
2218
2219        for (gen = lsStart(stmt->case_items),  i = 0;
2220             (lsNext(gen,(lsGeneric*)&item,&handle) != LS_NOMORE);
2221             i++) {
2222
2223            controls[i] =
2224                write_case_comparator(file,
2225                                      stmt->cond->term, item->exprs, vars);
2226
2227
2228            if (item->fg_info) {
2229                vertex_t *src_tag;
2230                src_tag = g_e_dest((edge_t*)item->fg_info);
2231                if (!controls[i]) {
2232                    controls[i] = true_term(file);
2233                }
2234                fg_update_node_info((vertex_t*)(item->fg_info),
2235                                    (char*)controls[i]);
2236                fg_case_collect_pause_rewrite_ctrl(file,
2237                    src_tag, (vertex_t*)stmt->cond->fg_info2,
2238                    &controls[i], &pause_ripple);
2239            }
2240
2241            if (item->type == CaseItem) {
2242                if (!rst_ckt) {
2243                    lsNewEnd(ctrl_list, (lsGeneric)controls[i], 0);
2244                    using_ith_ctrl = ith_ctrl;
2245                    ith_ctrl++;
2246                    ctrl_syndrome[using_ith_ctrl] = '1';
2247                } else {
2248                    lsNewEnd(rst_ctrl_list, (lsGeneric)controls[i], 0);
2249                    using_ith_ctrl = rst_ith_ctrl;
2250                    rst_ith_ctrl++;
2251                    rst_ctrl_syndrome[using_ith_ctrl] = '1';
2252                }
2253            }
2254
2255
2256
2257            case_vars[i] = st_copy(vars);
2258            dup_info_var_in_st(case_vars[i]);
2259            reset_cond_list_in_st(case_vars[i]);
2260            case_vars[i] =
2261                vl_write_stmt(file, item->stmt,
2262                              (controls[i])?MUX_T:NO_MUX,
2263                              (controls[i])?controls[i]:NIL(vl_term),
2264                              case_vars[i]);
2265            if (item->type == CaseItem) {
2266                if (!rst_ckt)
2267                    ctrl_syndrome[using_ith_ctrl] = '0';
2268                else
2269                    rst_ctrl_syndrome[using_ith_ctrl] = '0';
2270            }
2271
2272            prev_ctrl = controls[i];
2273        }
2274        (void)lsFinish(gen);
2275
2276        if (pause_ripple) {
2277            fprintf(file, ".names %s\n0\n", pause_ripple->name->name);
2278        }
2279    }
2280
2281    if (!rst_ckt)
2282        strcpy(ctrl_syndrome, old_ctrl_syndrome);
2283    else
2284        strcpy(rst_ctrl_syndrome, old_ctrl_syndrome);
2285
2286    fprintf(file, "%s case (", HSIS_COMMENT);
2287    vl_step_expr(file, stmt->cond);
2288    fprintf(file, ")\n");
2289
2290    if (!prev_ctrl || vl_currentFunction) {
2291
2292
2293        st_table *vars_tmp, *vars_else;
2294        i=lsLength(stmt->case_items)-1;
2295        vars_else = case_vars[i];
2296        for (i -= 2; i>=0; i--) {
2297            vars_tmp = st_copy(vars);
2298            dup_info_var_in_st(vars_tmp);
2299            reset_cond_list_in_st(vars_tmp);
2300            create_var_muxes(file, controls[i+1],
2301                             case_vars[i+1], vars_else, vars_tmp);
2302            vars_else = vars_tmp;
2303        }
2304        create_var_muxes(file, controls[0],
2305                         case_vars[0], vars_else, vars);
2306    } else {
2307
2308        for (i=lsLength(stmt->case_items)-1; i>=0; i--) {
2309            case_vars[i] = create_var_muxes(file, controls[i],
2310                                            case_vars[i], st_copy(vars), vars);
2311        }
2312    }
2313
2314    return vars;
2315}
2316
2317
2318void vl_write_cont_assign(FILE *file, vl_cont_assign *assign, st_table *vars)
2319{
2320    vl_id_range *lhs_id;
2321    lsGen gen;
2322    lsHandle handle;
2323    vl_bassign_stmt *a;
2324    vl_term *lhs_term;
2325    int true_hi=0, true_lo=0;
2326    int num_lhs_vars;
2327    int cur_bit_pos;
2328    lsList lhs_list;
2329    lsGen lhs_gen=(lsGen)0;
2330    lsHandle lhs_handle;
2331    vl_expr *lhs_expr;
2332    vl_id_range *lhs_var;
2333    vl_range *lhs_range;
2334    int i;
2335
2336    WrtTRACE("Writing cont_assign\n");
2337
2338    for (gen = lsStart(assign->assigns);
2339         lsNext(gen, (lsGeneric*)&a, &handle) != LS_NOMORE; ) {
2340        a->type = AssignStmt;
2341        if (a->lhs->type == MinTypMaxExpr)
2342            a->lhs->name = (vl_id_range*)((vl_expr*)a->lhs->name)->u.exprs.e1;
2343
2344        if (a->lhs->type == ConcatExpr) {
2345            num_lhs_vars = lsLength(a->lhs->concat);
2346            lhs_list = a->lhs->concat;
2347            lhs_gen = lsStart(lhs_list);
2348        } else {
2349            num_lhs_vars = 1;
2350            lhs_list = (lsList)0;
2351        }
2352
2353        for (i=0; i<num_lhs_vars; i++) {
2354            if (lhs_list) {
2355                int retval = lsNext(lhs_gen,(lsGeneric*)&lhs_expr,&lhs_handle);
2356                assert(retval != LS_NOMORE);
2357                lhs_var = lhs_expr->u.name;
2358                lhs_range = lhs_var->range;
2359            } else {
2360                lhs_var = a->lhs->name;
2361                lhs_range = a->lhs->range;
2362            }
2363            if (!st_lookup(vl_currentModule->sig_st,
2364                           lhs_var->name, (char**)&lhs_id)) {
2365                int retval;
2366                st_insert(vl_currentModule->sig_st, lhs_var->name,
2367                          (char*)vl_create_id_range(lhs_var->name,
2368                                                    NIL(vl_range)));
2369                retval = st_lookup(vl_currentModule->sig_st, lhs_var->name,
2370                                   (char**)&lhs_id);
2371                assert(retval);
2372            }
2373        }
2374        if (lhs_list) lsFinish(lhs_gen);
2375        nd_check_ok = 1;
2376
2377        lhs_term = vl_write_assign(file, a, 0, NIL(vl_term), NIL(st_table));
2378
2379        nd_check_ok = 0;
2380        if (vis_nond_var) {
2381            vis_nond_var = 0;
2382            return;
2383        }
2384
2385
2386        if (lhs_list) {
2387            assert(array_n(assign_array) == num_lhs_vars);
2388            lhs_gen = lsStart(lhs_list);
2389            true_lo = lhs_term->lo;
2390            true_hi = lhs_term->hi;
2391        }
2392        for (i=0, cur_bit_pos=0; i<num_lhs_vars; i++) {
2393            if (lhs_list) {
2394                int retval = lsNext(lhs_gen,(lsGeneric*)&lhs_expr,&lhs_handle);
2395                assert(retval != LS_NOMORE);
2396                retval = st_lookup(vl_currentModule->sig_st,
2397                                   lhs_expr->u.name->name, (char**)&lhs_id);
2398                assert(retval);
2399            }
2400            if (lhs_list) lhs_term = array_fetch(vl_term*, assign_array, i);
2401            if (!(lhs_id->flags & InPort && !(lhs_id->flags & OutPort)))
2402                st_insert(vars, lhs_id->name,
2403                          (char*)create_var_info(vl_copy_id_range(lhs_id),
2404                                                 lhs_term));
2405            else {
2406                vl_id_range *id_sym;
2407                int retval = st_lookup(vl_currentModule->sig_st,
2408                                       lhs_id->name, (char**)&id_sym);
2409                assert(retval);
2410                id_sym->name = lhs_term->name->name;
2411            }
2412        }
2413        if (lhs_list) {
2414            lsFinish(lhs_gen);
2415            lhs_term->lo = true_lo;
2416            lhs_term->hi = true_hi;
2417            array_free(assign_array);
2418        }
2419    }
2420    (void)lsFinish(gen);
2421}
2422
2423
2424void vl_write_wiring_assign(FILE *file, vl_netdecl *assignments, st_table *vars)
2425{
2426    vl_id_range *lhs_id;
2427    lsGen gen;
2428    lsHandle handle;
2429    vl_bassign_stmt *a;
2430    vl_term *lhs_term;
2431    int hi, lo;
2432
2433    WrtTRACE("Writing wire_assign\n");
2434
2435
2436
2437    gen = lsStart(assignments->ids);
2438    if (lsNext(gen, (lsGeneric*)&a, &handle) == LS_OK) {
2439        if (a->type == BassignStmt) {
2440            a->type = AssignStmt;
2441            st_lookup(vl_currentModule->sig_st,
2442                      a->lhs->name->name, (char**)&lhs_id);
2443            get_hilo(lhs_id, &hi, &lo);
2444            lhs_term = vl_write_assign(file,a,0,NIL(vl_term),NIL(st_table));
2445            st_insert(vars, lhs_id->name,
2446                      (char*)create_var_info(vl_copy_id_range(lhs_id),
2447                                             lhs_term));
2448        }
2449        while (lsNext(gen, (lsGeneric*)&a, &handle) != LS_NOMORE) {
2450            if (a->type == BassignStmt) {
2451                st_lookup(vl_currentModule->sig_st,
2452                          a->lhs->name->name, (char**)&lhs_id);
2453                get_hilo(lhs_id, &hi, &lo);
2454                a->type = AssignStmt;
2455                lhs_term = vl_write_assign(file,
2456                                           a, 0, NIL(vl_term), NIL(st_table));
2457                st_insert(vars, lhs_id->name,
2458                          (char*)create_var_info(vl_copy_id_range(lhs_id),
2459                                                 lhs_term));
2460            }
2461        }
2462    }
2463    (void)lsFinish(gen);
2464}
2465
2466st_table *vl_write_event_control_stmt(FILE *file, vl_event_control_stmt *stmt, st_table *vars)
2467{
2468    int old_recordCombAlways;
2469    set_t *old_sensitiveList;
2470    vl_term *old_edge_triggering;
2471
2472    WrtTRACE("Writing event_control_stmt\n");
2473
2474
2475
2476
2477
2478    old_recordCombAlways = recordCombAlways;
2479    if (stmt->event->type == OrEventExpr || stmt->event->type == EventExpr)
2480        recordCombAlways = 1;
2481
2482
2483
2484    old_edge_triggering = edge_triggering;
2485    old_sensitiveList = sensitiveList;
2486    sensitiveList = vl_write_event_expr(file, stmt->event);
2487
2488
2489
2490
2491    vars = vl_write_stmt(file, stmt->stmt, 0, NIL(vl_term), vars);
2492
2493    edge_triggering = old_edge_triggering;
2494    recordCombAlways = old_recordCombAlways;
2495    sensitiveList = old_sensitiveList;
2496
2497    return vars;
2498}
2499
2500
2501vl_term *vl_write_assign(FILE *file, vl_bassign_stmt *assign, int muxed, vl_term *muxsel, st_table *vars)
2502{
2503    char latch_name[MAXSTRLEN];
2504    vl_id_range *lhs_id=NIL(vl_id_range);
2505    vl_term *term_out=NIL(vl_term), *assign_term=NIL(vl_term),
2506            *retval=NIL(vl_term);
2507    int lo, hi;
2508    int old_lhs_hi, old_lhs_lo;
2509    vl_term *old_lhs_term;
2510    char buf[MAXSTRLEN];
2511    lsList lhs_list;
2512    lsGen lhs_gen=(lsGen)0;
2513    lsHandle lhs_handle;
2514    vl_expr *lhs_expr;
2515    int num_lhs_vars;
2516    vl_id_range *lhs_var;
2517    vl_range *lhs_range;
2518    int i;
2519
2520    WrtTRACE("Writing assign_stmt\n");
2521
2522    fprintf(file, "%s ", HSIS_COMMENT);
2523    if (!NoDetailedComment) vl_step_bassign_stmt(file, assign);
2524    fprintf(file, "\n");
2525
2526    assert(assign->type!=DelayBassignStmt &&
2527           assign->type != DelayNbassignStmt &&
2528           assign->type != EventBassignStmt &&
2529           assign->type != EventNbassignStmt);
2530
2531    if (assign->lhs->type == ConcatExpr) {
2532        num_lhs_vars = lsLength(assign->lhs->concat);
2533        lhs_list = assign->lhs->concat;
2534        lhs_gen = lsStart(lhs_list);
2535        assign_array = array_alloc(vl_term*, 0);
2536    } else {
2537        num_lhs_vars = 1;
2538        lhs_list = (lsList)0;
2539    }
2540
2541    for (i=0; i<num_lhs_vars; i++) {
2542        if (lhs_list) {
2543            int retval = lsNext(lhs_gen,(lsGeneric*)&lhs_expr,&lhs_handle);
2544            assert(retval != LS_NOMORE);
2545            lhs_var = lhs_expr->u.name;
2546            lhs_range = lhs_var->range;
2547        } else {
2548            lhs_var = assign->lhs->name;
2549            lhs_range = assign->lhs->range;
2550        }
2551
2552        if (!st_lookup(vl_currentModule->sig_st,
2553                       lhs_var->name, (char**)&lhs_id)) {
2554            char buf[MAXSTRLEN];
2555            yylineno = assign->lineno;
2556            sprintf(buf, "'%s':'%s' is an undeclared variable",
2557                    vl_currentModule->name->name, lhs_var->name);
2558            compile_error(buf);
2559        }
2560        if (assign->type == NbassignStmt ||
2561            assign->type == DelayNbassignStmt ||
2562            assign->type == EventNbassignStmt) {
2563
2564            vl_id_range *id_sym;
2565            sprintf(latch_name, "%s%s", lhs_var->name, SEP_LATCH);
2566            st_lookup(vl_currentModule->sig_st, latch_name, (char**)&id_sym);
2567            id_sym->flags = lhs_id->flags;
2568            lhs_id = id_sym;
2569        } else if (assign->type == AssignStmt && vars) {
2570
2571            vl_id_range *id_sym;
2572            sprintf(latch_name, "%s%s", lhs_var->name, SEP_QUASI);
2573            if (!st_lookup(vl_currentModule->sig_st,
2574                           latch_name,(char**)&id_sym)) {
2575                int retval;
2576                collect_quasi(lhs_var->name);
2577                retval = st_lookup(vl_currentModule->sig_st,
2578                                   latch_name,(char**)&id_sym);
2579                assert(retval);
2580            }
2581            id_sym->flags = lhs_id->flags;
2582            lhs_id = id_sym;
2583        } else {
2584
2585        }
2586
2587        if (lhs_id->flags & InPort && !(lhs_id->flags & OutPort)) {
2588            char msg[MAXSTRLEN];
2589            sprintf(msg, "%s:%s is input variable while used as lhs",
2590                    vl_currentModule->name->name, lhs_id->name);
2591
2592        }
2593
2594        if (!lhs_list) {
2595            if (vars)
2596                check_assign(assign, 1);
2597            else
2598                check_assign(assign, 0);
2599        }
2600        get_hilo(lhs_id, &hi, &lo);
2601
2602
2603        if (!muxed) {
2604            if (vars) {
2605
2606                sprintf(buf, "%s%s%s%s", lhs_id->name,
2607                        SEP_GATEPIN, PIN_RAWOUT, new_termname());
2608            } else {
2609
2610                sprintf(buf, "%s%s%s%s", lhs_id->name,
2611                        SEP_GATEPIN, PIN_RAWOUT, new_termname());
2612            }
2613        } else {
2614            if (muxed & 1) {
2615                sprintf(buf, "%s%s%s%s%s%s", lhs_id->name,
2616                        SEP_GATEPIN, muxsel->name->name, new_termname(),
2617                        SEP_GATEPIN, PIN_TRUE);
2618            } else {
2619                sprintf(buf, "%s%s%s%s%s%s", lhs_id->name,
2620                        SEP_GATEPIN, muxsel->name->name, new_termname(),
2621                        SEP_GATEPIN, PIN_FALSE);
2622            }
2623        }
2624        assign_term = term_out = create_rename_term(lhs_id, buf, lo, hi);
2625        assign_term->flag = lhs_id->flags;
2626        assign_term->term_type = lhs_id->id_type;
2627
2628        if (!(vis_nond && assign->rhs->type == NondExpr) || rst_ckt)
2629            write_var_decl(file, assign_term);
2630
2631        if (lhs_range) {
2632            if (lhs_id->range) {
2633
2634                var_info *cur_var;
2635                vl_term *orig_term;
2636
2637                vl_write_expr(file, lhs_range->left, vars);
2638                if (vars) {
2639                    if (st_lookup(vars, lhs_id->name, (char**)&cur_var)) {
2640                        orig_term = cur_var->current_terminal;
2641                    } else {
2642                        orig_term = vl_create_term(lhs_var, lo, hi);
2643                        orig_term->flag = lhs_id->flags;
2644                        orig_term->term_type = lhs_id->id_type;
2645                    }
2646                } else {
2647                    orig_term = vl_create_term(lhs_var, lo, hi);
2648                }
2649                assign_term = new_term(NIL(vl_range), lo, hi);
2650                assign_term->flag = lhs_id->flags;
2651                assign_term->term_type = lhs_id->id_type;
2652                write_var_decl(file, assign_term);
2653                write_switch(file, lhs_id, lhs_range->left->term,
2654                             lhs_range->left, orig_term, assign_term, term_out);
2655            } else {
2656
2657                int left, right;
2658
2659                left = vl_eval_expr(lhs_range->left);
2660                if (lhs_range->right)
2661                    right = vl_eval_expr(lhs_range->right);
2662                else
2663                    right = left;
2664                assign_term->term_type = lhs_id->id_type;
2665                assign_term->lo = left;
2666                assign_term->hi = right;
2667            }
2668        }
2669
2670        if (assign_term->lo > assign_term->hi) {
2671            if (assign_term->lo != 0 && assign_term->hi != -1) {
2672                int temp;
2673
2674                temp = assign_term->lo;
2675                assign_term->lo = assign_term->hi;
2676                assign_term->hi = temp;
2677            }
2678        }
2679
2680        if (lhs_list) {
2681
2682
2683            array_insert_last(vl_term*, assign_array, assign_term);
2684        }
2685    }
2686
2687    if (lhs_list) {
2688        lsFinish(lhs_gen);
2689        assign_term = concate_assigns(assign_array);
2690        write_var_decl(file, assign_term);
2691    }
2692
2693    switch(assign->type) {
2694
2695    case BassignStmt:
2696    case NbassignStmt:
2697    case AssignStmt: {
2698
2699        old_lhs_hi = lhs_hi;
2700        old_lhs_lo = lhs_lo;
2701        old_lhs_term = lhs_term;
2702        lhs_hi = assign_term->hi;
2703        lhs_lo = assign_term->lo;
2704        lhs_term = assign_term;
2705
2706        vl_write_expr(file, assign->rhs, vars);
2707
2708        lhs_hi = old_lhs_hi;
2709        lhs_lo = old_lhs_lo;
2710        lhs_term = old_lhs_term;
2711
2712        break;
2713    }
2714
2715    case DelayBassignStmt:  break;
2716    case DelayNbassignStmt: break;
2717
2718    case EventBassignStmt:  break;
2719    case EventNbassignStmt: break;
2720    default: break;
2721    }
2722
2723
2724    if (!rst_ckt) {
2725        if (!lhs_list)
2726            dump_debug_information(file, assign->lhs->name, assign_term,
2727                                   assign->lineno, ctrl_list, ctrl_syndrome);
2728    }
2729
2730    if (vis_nond_var && !vars) {
2731        return retval;
2732    }
2733
2734
2735    if (ISVLCONST(assign->rhs->type) && assign->rhs->type != BitExpr) {
2736        vl_write_const(file, assign->rhs, assign_term);
2737        if (!(assign_term->flag & MVar)) {
2738
2739            var_info *cur_var;
2740            vl_term *orig_term;
2741            if (vars && !lhs_list) {
2742
2743                if (st_lookup(vars, lhs_id->name, (char**)&cur_var)) {
2744                    orig_term = cur_var->current_terminal;
2745                } else {
2746                    orig_term = vl_create_term(assign->lhs->name, lo, hi);
2747                }
2748                patch_unaffected_term(file, lhs_id, orig_term, assign_term);
2749            } else if (lhs_list) {
2750                connect_concat(file, assign_term, assign_array);
2751            }
2752        }
2753    } else {
2754        if ((term_out->flag & MVar) == (assign->rhs->term->flag & MVar)) {
2755            if (assign->rhs->term->flag & MVar) {
2756                vl_write_mv_connect(file, assign->rhs->term, assign_term);
2757            } else {
2758                var_info *cur_var;
2759                vl_term *orig_term;
2760
2761                vl_write_bin_connect(file, assign->rhs->term, assign_term,  0);
2762
2763                if (vars && !lhs_list) {
2764                    if (st_lookup(vars, lhs_id->name, (char**)&cur_var)) {
2765                        orig_term = cur_var->current_terminal;
2766                    } else {
2767                        orig_term = vl_create_term(assign->lhs->name, lo, hi);
2768                    }
2769                    patch_unaffected_term(file, lhs_id, orig_term, assign_term);
2770                } else if (lhs_list) {
2771                    connect_concat(file, assign_term, assign_array);
2772                }
2773            }
2774        } else {
2775            char buf[MAXSTRLEN];
2776
2777            sprintf(buf, "connecting incompatible wires '%s' and '%s'",
2778                    assign_term->name->name,assign->rhs->term->name->name);
2779            compile_error(buf);
2780        }
2781        vl_free_term(assign->rhs->term);
2782    }
2783
2784    retval = term_out;
2785
2786    return retval;
2787}
2788
2789
2790st_table *vl_write_decl_list(FILE *file, void *decls, int muxed, vl_term *control, st_table *vars)
2791{
2792
2793    file = file;
2794    decls = decls;
2795    muxed = muxed;
2796    control = control;
2797
2798    return vars;
2799}
2800
2801st_table *vl_write_stmt_list(FILE *file, lsList stmts, int muxed, vl_term *control, st_table *vars)
2802{
2803    void *stmt;
2804    lsHandle handle;
2805    lsGen gen;
2806    st_table *new_vars;
2807    lsList vars_list, pause_list;
2808    set_t *pauseSet;
2809
2810    WrtTRACE("Writing stmt_list\n");
2811
2812    pauseSet = set_empty();
2813    if (vl_pauseStack) push_stack(vl_pauseStack, (void*)pauseSet);
2814    pause_list = lsCreate();
2815    vars_list = lsCreate();
2816
2817    for (gen = lsStart(stmts);
2818         lsNext(gen, (lsGeneric*)&stmt, &handle) != LS_NOMORE; ) {
2819        new_vars = vl_write_stmt(file, stmt, muxed, control, vars);
2820
2821
2822        vars = new_vars;
2823    }
2824    (void) lsFinish(gen);
2825    if (vl_pauseStack) pop_stack(vl_pauseStack, (void**)&pauseSet);
2826    set_destroy(pauseSet);
2827
2828
2829
2830    lsDestroy(vars_list, 0);
2831    lsDestroy(pause_list, (void (*)(lsGeneric))set_destroy);
2832
2833    return vars;
2834}
2835
2836
2837void vl_write_expr_list(FILE *file, lsList exprs, st_table *vars)
2838{
2839    vl_expr *expr;
2840    lsHandle handle;
2841    lsGen gen;
2842
2843    WrtTRACE("Writing expr_list\n");
2844
2845    if (!exprs) return;
2846    gen = lsStart(exprs);
2847    if (lsNext(gen, (lsGeneric*)&expr, &handle) == LS_OK) {
2848        vl_write_expr(file, expr, vars);
2849        while (lsNext(gen, (lsGeneric*)&expr, &handle) != LS_NOMORE) {
2850            vl_write_expr(file, expr, vars);
2851        }
2852    }
2853    (void)lsFinish(gen);
2854}
2855
2856
2857
2858void vl_write_expr(FILE *file, vl_expr *expr, st_table *vars)
2859{
2860    int lo, hi, sub_hi, sub_lo, inverted;
2861    vl_term *term_in1, *term_in2, *term_out, *idx_term;
2862    vl_id_range *id_sym;
2863    var_info *id_var_info;
2864    char term1[MAXSTRLEN/8];
2865    char *ripple=NIL(char);
2866    int auto_declared = 0;
2867    int hibit;
2868    FILE *bufStream;
2869
2870    if (!expr) return;
2871
2872    WrtTRACE("write expr");
2873
2874    switch (expr->type) {
2875    case BitExpr:
2876
2877        hibit = strlen((char*)expr->u.exprs.e3)-1;
2878        term_out = new_term(NIL(vl_range), 0, (hibit==0)?-1:hibit);
2879        write_var_decl(file, term_out);
2880        if (lhs_term)
2881            term_out->flag = lhs_term->flag;
2882        vl_write_const(file, expr, term_out);
2883        expr->term = term_out;
2884        break;
2885    case IntExpr: break;
2886    case RealExpr: break;
2887    case IDExpr:
2888        if (vars) {
2889
2890            if (st_lookup(vars, expr->u.name->name, (char**)&id_var_info)) {
2891
2892
2893                expr->term = term_out =
2894                    vl_copy_term(id_var_info->current_terminal);
2895                break;
2896            }
2897        }
2898
2899        {
2900            int const_expr;
2901            vl_id_range *ival;
2902            const_expr = 0;
2903            if (vl_currentModule->param_st) {
2904                if (st_lookup(vl_currentModule->param_st,
2905                              expr->u.name->name, (char**)&ival))
2906                    const_expr = 1;
2907            }
2908            if (!const_expr && vl_encloseModule) {
2909                if (vl_encloseModule->param_st)
2910                    if (st_lookup(vl_encloseModule->param_st,
2911                                  expr->u.name->name, (char**)&ival))
2912                        const_expr = 1;
2913            }
2914            if (const_expr) {
2915                write_const_param(file, expr, ival);
2916                break;
2917            }
2918        }
2919
2920
2921
2922        if (!st_lookup(vl_currentModule->sig_st,
2923                       expr->u.name->name, (char**)&id_sym)){
2924            if (implicitDeclare) {
2925                int retval;
2926                st_insert(vl_currentModule->sig_st, expr->u.name->name,
2927                          (char*)vl_create_id_range(expr->u.name->name,
2928                                                    NIL(vl_range)));
2929                retval = st_lookup(vl_currentModule->sig_st,expr->u.name->name,
2930                                   (char**)&id_sym);
2931                assert(retval);
2932                auto_declared = 1;
2933            } else {
2934                char msg[MAXSTRLEN/8];
2935                yylineno = -1;
2936                sprintf(msg, "'%s':%s not defined",
2937                        vl_currentModule->name->name, expr->u.name->name);
2938                compile_error(msg);
2939            }
2940        } else {
2941            id_sym->flags |= AccessedVar;
2942        }
2943
2944
2945
2946        if (sensitiveList) {
2947
2948            if (check_rhs_sensitivity) {
2949                if (!set_find(id_sym->name, sensitiveList)) {
2950                    recordCombAlways = 0;
2951                    if (vl_currentModule->combVar_st) {
2952                        vl_currentModule->combVar_st = NIL(set_t);
2953                        {
2954                            char buf[MAXSTRLEN/8];
2955                            sprintf(buf,
2956                                    "%s:combinational reduction failed on %s",
2957                                    vl_currentModule->name->name,
2958                                    id_sym->name);
2959                            yylineno = -1;
2960                            compile_error(buf);
2961                        }
2962                    }
2963                }
2964            }
2965        }
2966
2967        get_hilo(id_sym, &hi, &lo);
2968        if (!(id_sym->flags & RegVar) && !(id_sym->flags & InPort) &&
2969            !(id_sym->flags & WireVar) && in_procedure && wireRegister) {
2970
2971            char buf[MAXSTRLEN/8];
2972            sprintf(buf, "%s%s", expr->u.name->name, PIN_HIDDEN);
2973            id_sym->flags |= HiddenLatch;
2974            expr->term = term_out =
2975                create_rename_term(expr->u.name, vlStrdup(buf), lo, hi);
2976        } else if (!((id_sym->flags & InPort) && (id_sym->flags & RegVar))) {
2977            expr->term = term_out =
2978                vl_create_term(vl_copy_id_range(id_sym), lo, hi);
2979        } else {
2980
2981            char buf[MAXSTRLEN/8];
2982            expr->term = term_out =
2983                vl_create_term(vl_copy_id_range(expr->u.name), lo, hi);
2984            sprintf(buf, "%s%s%s", expr->term->name->name, SEP_DIR, PIN_IN);
2985            vl_chk_free(expr->term->name->name);
2986            expr->term->name->name = vlStrdup(buf);
2987        }
2988        if (auto_declared) id_sym->flags |= AutoDeclared;
2989        term_out->flag = id_sym->flags;
2990        term_out->term_type = id_sym->id_type;
2991        break;
2992
2993
2994
2995
2996
2997
2998    case BitSelExpr:   case PartSelExpr:
2999
3000        if (vars) {
3001
3002            int const_expr;
3003            vl_id_range *ival;
3004            const_expr = 0;
3005            if (vl_currentModule->param_st) {
3006                if (st_lookup(vl_currentModule->param_st,
3007                              expr->u.name->name, (char**)&ival))
3008                    const_expr = 1;
3009            }
3010            if (!const_expr && vl_encloseModule) {
3011                if (vl_encloseModule->param_st)
3012                    if (st_lookup(vl_encloseModule->param_st,
3013                                  expr->u.name->name, (char**)&ival))
3014                        const_expr = 1;
3015            }
3016            if (const_expr) {
3017                write_const_param(file, expr, ival);
3018                break;
3019            }
3020
3021            if (st_lookup(vars, expr->u.name->name, (char**)&id_var_info)) {
3022
3023                if (id_var_info->current_terminal->name->range) {
3024
3025                    vl_write_expr(file, expr->u.idrng->range->left, vars);
3026                    idx_term = expr->u.idrng->range->left->term;
3027                    expr->term = write_array_access(file,
3028                                     id_var_info->current_terminal->name,
3029                                     idx_term,
3030                                     expr->u.idrng->range->left);
3031                    break;
3032                }
3033            } else {
3034
3035                if (!st_lookup(vl_currentModule->sig_st,
3036                               expr->u.name->name, (char**)&id_sym)) {
3037                    char buf[MAXSTRLEN/8];
3038                    sprintf(buf, "'%s': indexing into an undeclared var %s",
3039                            vl_currentModule->name->name,
3040                            expr->u.name->name);
3041                    yylineno = -1;
3042                    compile_error(buf);
3043                }
3044                if (id_sym->range) {
3045                    vl_write_expr(file, expr->u.idrng->range->left, vars);
3046                    idx_term = expr->u.idrng->range->left->term;
3047                    expr->term = write_array_access(file, id_sym, idx_term,
3048                                     expr->u.idrng->range->left);
3049                    break;
3050                } else {
3051
3052                    expr = expr;
3053
3054                }
3055            }
3056        } else {
3057
3058            if (!st_lookup(vl_currentModule->sig_st,
3059                      expr->u.name->name, (char**)&id_sym)) {
3060                char buf[MAXSTRLEN/8];
3061
3062                sprintf(buf, "%s:'%s' is an undeclared indexing variable",
3063                        vl_currentModule->name->name, expr->u.name->name);
3064                yylineno = -1;
3065                compile_error(buf);
3066            }
3067
3068            if (id_sym->range) {
3069
3070                vl_write_expr(file, expr->u.idrng->range->left, vars);
3071                idx_term = expr->u.idrng->range->left->term;
3072                expr->term = write_array_access(file, id_sym, idx_term,
3073                                                expr->u.idrng->range->left);
3074                break;
3075            }  else {
3076
3077                expr = expr;
3078
3079            }
3080        }
3081
3082
3083
3084        if (vars) {
3085            if (st_lookup(vars, expr->u.name->name, (char**)&id_var_info)) {
3086
3087                expr->term = vl_copy_term(id_var_info->current_terminal);
3088                get_hilo(id_var_info->id, &hi, &lo);
3089            } else {
3090
3091                st_lookup(vl_currentModule->sig_st,
3092                          expr->u.name->name, (char**)&id_sym);
3093                get_hilo(id_sym, &hi, &lo);
3094                expr->term = vl_create_term(vl_copy_id_range(expr->u.name),
3095                                            lo, hi);
3096            }
3097        } else {
3098
3099            st_lookup(vl_currentModule->sig_st,
3100                      expr->u.name->name, (char**)&id_sym);
3101            get_hilo(id_sym, &hi, &lo);
3102            expr->term = vl_create_term(vl_copy_id_range(expr->u.name),
3103                                        lo, hi);
3104        }
3105
3106        if ((lo > hi) && (expr->term->flag & MVar)) {
3107            char buf[MAXSTRLEN/8];
3108            sprintf(buf,"idnexing into a scalar variable %s",
3109                    expr->term->name->name);
3110            semantic_error(buf);
3111        }
3112
3113
3114        sub_lo = MAX(lo, vl_eval_expr(expr->u.idrng->range->left));
3115        if (expr->u.idrng->range->right)
3116            sub_hi = MIN(hi, vl_eval_expr(expr->u.idrng->range->right));
3117        else
3118            sub_hi = sub_lo;
3119
3120        if (sub_hi < sub_lo)
3121            if (sub_hi != -1 && sub_lo != 0) {
3122                int temp;
3123
3124                temp = sub_lo;
3125                sub_lo = sub_hi;
3126                sub_hi = temp;
3127            }
3128
3129
3130        expr->term->lo = sub_lo;
3131        expr->term->hi = sub_hi;
3132        break;
3133
3134
3135    case MinTypMaxExpr:
3136        vl_write_expr(file, expr->u.exprs.e1, vars);
3137        expr->term = expr->u.exprs.e1->term;
3138        break;
3139    case ConcatExpr: {
3140        vl_expr *e;
3141        lsHandle handle;
3142        lsGen gen=(lsGen)0;
3143        int bitWidth=0;
3144        int i, j, rep=1;
3145        FILE *new_file;
3146
3147        expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3148        if (expr->u.exprs.e2) {
3149            rep = vl_eval_expr(expr->u.exprs.e2);
3150        }
3151
3152        insideConcat = 1;
3153        term_out->lo = -1;
3154        term_out->hi = -1;
3155        new_file = vl_begin_buffer();
3156        j = 0;
3157        for (i=0; i<rep; i++) {
3158            for (gen = lsEnd((lsList)(expr->u.exprs.e1));
3159                 lsPrev(gen, (lsGeneric*)&e, &handle) != LS_NOMORE;) {
3160                vl_write_expr(new_file, e, vars);
3161                if (e->term) {
3162                    bitWidth = (e->term->hi-e->term->lo+1);
3163                    bitWidth = (bitWidth>0) ? bitWidth : 1;
3164                    term_out->lo = term_out->hi + 1;
3165                    term_out->hi = term_out->lo + bitWidth - 1;
3166                    vl_write_bin_connect(new_file, e->term, term_out, 0);
3167                } else {
3168                  if (e->type == IntExpr) {
3169                    bitWidth = min_bit_width(e->u.intval);
3170                    bitWidth = (bitWidth>0) ? bitWidth : 1;
3171                    e->term = new_term(NIL(vl_range), 0, bitWidth-1);
3172                    write_int_connect(new_file, e->u.intval, e->term);
3173                    term_out->lo = term_out->hi + 1;
3174                    term_out->hi = term_out->lo + bitWidth - 1;
3175                    vl_write_bin_connect(new_file, e->term, term_out, 0);
3176                  } else {
3177                    Translate_Warning("unknown width const in concatenation");
3178                    bitWidth = 0;
3179                  }
3180                }
3181                j++;
3182            }
3183        }
3184        term_out->lo = 0;
3185        write_var_decl(file, term_out);
3186        vl_append_buffer(file, new_file);
3187        vl_close_buffer(new_file);
3188        bitWidth--;
3189        (void) lsFinish(gen);
3190        insideConcat = 0;
3191
3192        break;
3193    }
3194
3195    case StringExpr: break;
3196    case FuncExpr:  {
3197        vl_function *func_def;
3198        if (vl_currentFunction) {
3199            vl_currentModule = vl_encloseModule;
3200        }
3201        if (!st_lookup(vl_currentModule->func_st,expr->u.func_call.name->name,
3202                       (char**)&func_def)) {
3203            char buf[MAXSTRLEN/8];
3204            sprintf(buf, "'%s':function %s is used before declaration",
3205                    vl_currentModule->name->name,
3206                    expr->u.func_call.name->name);
3207            yylineno = -1;
3208            compile_error(buf);
3209        } else {
3210            expr->term = instantiate_function(file, func_def,
3211                                              expr->u.func_call.args, vars);
3212        }
3213        if (vl_currentFunction) {
3214            vl_currentModule = (vl_module*)vl_currentFunction;
3215        }
3216        break;
3217    }
3218    case UplusExpr:    case UminusExpr: {
3219        if (expr->type == UminusExpr) {
3220            vl_expr *fake_expr;
3221            fake_expr = vl_create_expr(BminusExpr, 0, (double)0.0,
3222                                       vl_create_expr(IntExpr, 0, (double)0.0,
3223                                                      NIL(void), NIL(void),
3224                                                      NIL(void)),
3225                                       expr->u.exprs.e1, NIL(void));
3226            vl_write_expr(file, fake_expr, vars);
3227            vl_chk_free((char*)fake_expr);
3228            expr->term = fake_expr->term;
3229        } else {
3230            vl_write_expr(file, expr->u.exprs.e1, vars);
3231            expr->term = expr->u.exprs.e1->term;
3232        }
3233        break;
3234    }
3235
3236    case UnotExpr:
3237    case UcomplExpr:inverted=1; goto write_expr;
3238
3239    case UnandExpr: expr->type = UandExpr; inverted=1; goto write_expr;
3240    case UnorExpr:  expr->type = UorExpr;  inverted=1; goto write_expr;
3241    case UxnorExpr: expr->type = UxorExpr; inverted=1; goto write_expr;
3242    case UandExpr:  inverted=0; goto write_expr;
3243    case UorExpr:   inverted=0; goto write_expr;
3244    case UxorExpr:  inverted=0;
3245
3246write_expr:
3247
3248        vl_write_expr(file, expr->u.exprs.e1, vars);
3249        if (!expr->u.exprs.e1->term) {
3250
3251            int val;
3252            val = vl_eval_expr(expr);
3253            expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3254            vl_write_const(file, expr, expr->term);
3255            break;
3256        }
3257        vl_mv_to_bin(expr->u.exprs.e1->term);
3258        term_in1=expr->u.exprs.e1->term;
3259
3260        expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3261
3262        ripple = BLIF_GND;
3263        if (term_in1->lo <= term_in1->hi) {
3264            if (expr->type != UcomplExpr) {
3265                write_var_decl(file, term_out);
3266                vl_write_vector_red_op(file, expr->type, term_in1, inverted,
3267                                       term_out);
3268            } else {
3269                term_out->lo = term_in1->lo;
3270                term_out->hi = term_in1->hi;
3271                write_var_decl(file, term_out);
3272                vl_write_bin_connect(file, term_in1, term_out, 1);
3273            }
3274        } else {
3275
3276            write_var_decl(file, term_out);
3277            vl_write_bit_connect(file,
3278                                 term_in1->name->name, term_out->name->name,
3279                                 inverted);
3280        }
3281        if (inverted) {
3282            switch (expr->type) {
3283            case UandExpr: expr->type = UnandExpr; break;
3284            case UorExpr:  expr->type = UnorExpr;  break;
3285            case UxorExpr: expr->type = UxnorExpr; break;
3286            }
3287        }
3288        vl_free_term(term_in1);
3289        break;
3290
3291
3292    case Beq3Expr:  case Bneq3Expr:
3293    case Beq2Expr:  case Bneq2Expr:
3294        expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3295
3296        vl_write_expr(file, expr->u.exprs.e1, vars);
3297        vl_write_expr(file, expr->u.exprs.e2, vars);
3298
3299        if (expr->u.exprs.e1->term && expr->u.exprs.e2->term) {
3300            if (expr->u.exprs.e1->term->flag & AutoDeclared &&
3301                expr->u.exprs.e2->term->flag & AutoDeclared) {
3302                char buf[MAXSTRLEN/8];
3303                vl_step_expr(stderr, expr);
3304                fprintf(stderr, "\n");
3305                sprintf(buf,
3306                        "'%s': too many undefined variables for the binary operator\n",
3307                        vl_currentModule->name->name);
3308                yylineno = -1;
3309                compile_error(buf);
3310            }
3311        }
3312
3313        if (!(expr->u.exprs.e1->term)) {
3314            lo = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->lo : 0;
3315            hi = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->hi :
3316                                            MAX(data_width(expr->u.exprs.e1),
3317                                                data_width(expr->u.exprs.e2));
3318            expr->u.exprs.e1->term = new_term(NIL(vl_range), lo, hi);
3319            if (expr->u.exprs.e2->term) {
3320                expr->u.exprs.e1->term->flag |= expr->u.exprs.e2->term->flag;
3321                expr->u.exprs.e1->term->term_type =
3322                    expr->u.exprs.e2->term->term_type;
3323            }
3324            write_var_decl(file, expr->u.exprs.e1->term);
3325            vl_write_const(file, expr->u.exprs.e1, expr->u.exprs.e1->term);
3326        }
3327        if (!(expr->u.exprs.e2->term)) {
3328            lo = (expr->u.exprs.e1->term) ? expr->u.exprs.e1->term->lo : 0;
3329            hi = (expr->u.exprs.e1->term) ? expr->u.exprs.e1->term->hi :
3330                                            MAX(data_width(expr->u.exprs.e2),
3331                                                data_width(expr->u.exprs.e1));
3332            expr->u.exprs.e2->term = new_term(NIL(vl_range), lo, hi);
3333            if (expr->u.exprs.e1->term) {
3334                expr->u.exprs.e2->term->flag |= expr->u.exprs.e1->term->flag;
3335                expr->u.exprs.e2->term->term_type =
3336                    expr->u.exprs.e1->term->term_type;
3337            }
3338            write_var_decl(file, expr->u.exprs.e2->term);
3339            vl_write_const(file, expr->u.exprs.e2, expr->u.exprs.e2->term);
3340        }
3341
3342        if ((expr->u.exprs.e1->term->term_type &&
3343             !expr->u.exprs.e2->term->term_type) ||
3344            (expr->u.exprs.e2->term->term_type &&
3345             !expr->u.exprs.e1->term->term_type)) {
3346            vl_expr *e1, *e2;
3347            vl_enumerator *enum_elt;
3348
3349            if (!expr->u.exprs.e1->term->term_type) {
3350                e1 = expr->u.exprs.e2;
3351                e2 = expr->u.exprs.e1;
3352            } else {
3353                e1 = expr->u.exprs.e1;
3354                e2 = expr->u.exprs.e2;
3355            }
3356
3357            if (e2->type != IDExpr) {
3358                char buf[MAXSTRLEN/8];
3359                sprintf(buf, "'%s':comparing symbolic var '%s' with incompatible expr '%s'",
3360                        vl_currentModule->name->name,
3361                        e1->term->name->name, e2->term->name->name);
3362                semantic_error(buf);
3363            }
3364
3365            if (st_lookup(e1->term->term_type->specifier->
3366                          u.enum_type->domain_st,
3367                          e2->u.name->name,
3368                          (char**)&enum_elt)) {
3369                e2->term = typed_new_term(e1->term->term_type,
3370                                          e1->term->name->range,
3371                                          e1->term->lo, e1->term->hi);
3372                e2->term->flag = e1->term->flag;
3373                write_var_decl(file, e2->term);
3374                e2->type = IntExpr;
3375                e2->u.intval = enum_elt->val;
3376                vl_write_const(file, e2, e2->term);
3377            } else {
3378                char buf[MAXSTRLEN/8];
3379
3380                sprintf(buf, "'%s':comparing '%s' and '%s' of different domains",
3381                        vl_currentModule->name->name,
3382                        e1->term->name->name, e2->term->name->name);
3383                semantic_error(buf);
3384            }
3385        }
3386
3387        fprintf(file, "%s ", HSIS_COMMENT);
3388        if (!NoDetailedComment) vl_step_expr(file, expr);
3389        fprintf(file, "\n");
3390
3391        term_in1=expr->u.exprs.e1->term;
3392        term_in2=expr->u.exprs.e2->term;
3393
3394        term_in2->flag |= (term_in1->flag & MVar);
3395
3396        if ((term_in1->flag&MVar) == (term_in2->flag&MVar)) {
3397            if (term_in1->flag & MVar) {
3398                vl_write_mv_comp(file, expr->type,
3399                                 term_in1, term_in2, term_out);
3400            } else {
3401                vl_write_bin_comp(file, expr->type,
3402                                  term_in1, term_in2, term_out);
3403            }
3404        } else if (term_in1->flag & MVar) {
3405            vl_mv_to_bin(term_in1);
3406            vl_write_bin_comp(file, expr->type,
3407                              term_in1, term_in2, term_out);
3408        } else if (term_in2->flag & MVar) {
3409            vl_mv_to_bin(term_in2);
3410            vl_write_bin_comp(file, expr->type,
3411                              term_in1, term_in2, term_out);
3412        }
3413
3414        vl_free_term(term_in1);
3415        vl_free_term(term_in2);
3416        break;
3417
3418    case BtimesExpr:  case BdivExpr:  case BremExpr:
3419        sprintf(term1, "'%s':operator '*', '/', '%%' are not supported",
3420                vl_currentModule->name->name);
3421        yylineno = -1;
3422        compile_error(term1);
3423        break;
3424    case BlshiftExpr: case BrshiftExpr:
3425        sprintf(term1, "'%s':operator '<<', '>>' are not supported",
3426                vl_currentModule->name->name);
3427        yylineno = -1;
3428        compile_error(term1);
3429        break;
3430
3431    case BlandExpr: case BlorExpr:
3432    case BltExpr:  case BleExpr:  case BgtExpr:  case BgeExpr:
3433
3434    case BplusExpr:  case BminusExpr:
3435    case BandExpr:  case BorExpr:  case BxorExpr:  case BxnorExpr:
3436        vl_write_expr(file, expr->u.exprs.e1, vars);
3437        vl_write_expr(file, expr->u.exprs.e2, vars);
3438        if (!(expr->u.exprs.e1->term)) {
3439            lo = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->lo : 0;
3440            hi = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->hi :
3441                MAX(data_width(expr->u.exprs.e1)-1,
3442                    data_width(expr->u.exprs.e2)-1);
3443            if (lo==0 && hi==0) hi = -1;
3444            expr->u.exprs.e1->term = new_term(NIL(vl_range), lo, hi);
3445            write_var_decl(file, expr->u.exprs.e1->term);
3446            vl_write_const(file, expr->u.exprs.e1, expr->u.exprs.e1->term);
3447        }
3448        if (!(expr->u.exprs.e2->term)) {
3449            lo = (expr->u.exprs.e1->term) ? expr->u.exprs.e1->term->lo : 0;
3450            hi = (expr->u.exprs.e1->term) ? expr->u.exprs.e1->term->hi :
3451                MAX(data_width(expr->u.exprs.e2)-1,
3452                    data_width(expr->u.exprs.e1)-1);
3453            if (lo==0 && hi==0) hi = -1;
3454            expr->u.exprs.e2->term = new_term(NIL(vl_range), lo, hi);
3455            write_var_decl(file, expr->u.exprs.e2->term);
3456            vl_write_const(file, expr->u.exprs.e2, expr->u.exprs.e2->term);
3457        }
3458        vl_mv_to_bin(expr->u.exprs.e1->term);
3459        vl_mv_to_bin(expr->u.exprs.e2->term);
3460
3461        if (IS_VLR_LOG_OP(expr->type)) {
3462            if (vector_width(expr->u.exprs.e1->term->lo,
3463                             expr->u.exprs.e1->term->hi) != 1) {
3464                vl_term *red_term;
3465                red_term = new_term(NIL(vl_range), 0, -1);
3466                write_red_op(file, UorExpr,
3467                             expr->u.exprs.e1->term, NIL(vl_term), red_term);
3468                expr->u.exprs.e1->term = red_term;
3469            }
3470            if (vector_width(expr->u.exprs.e2->term->lo,
3471                             expr->u.exprs.e2->term->hi) != 1) {
3472                vl_term *red_term;
3473                red_term = new_term(NIL(vl_range), 0, -1);
3474                write_red_op(file, UorExpr,
3475                             expr->u.exprs.e2->term, NIL(vl_term), red_term);
3476                expr->u.exprs.e2->term = red_term;
3477            }
3478        }
3479        term_in1=expr->u.exprs.e1->term;
3480        term_in2=expr->u.exprs.e2->term;
3481
3482        fprintf(file, "%s ", HSIS_COMMENT);
3483        if (!NoDetailedComment) vl_step_expr(file, expr);
3484        fprintf(file, "\n");
3485
3486        expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3487        if (term_in1)
3488            if (term_in1->name->unintType)
3489                expr->term->name->unintType = term_in1->name->unintType;
3490        if (term_in2)
3491            if (term_in2->name->unintType)
3492                expr->term->name->unintType = term_in2->name->unintType;
3493
3494        if (term_in1->lo > term_in1->hi) {
3495            term_out->lo = term_in2->lo;
3496            term_out->hi = term_in2->hi;
3497        } else if (term_in2->lo > term_in2->hi) {
3498            term_out->lo = term_in1->lo;
3499            term_out->hi = term_in1->hi;
3500        } else {
3501            term_out->lo = 0;
3502
3503            term_out->hi = MAX(term_in1->hi-term_in1->lo,
3504                               term_in2->hi-term_in2->lo);
3505        }
3506
3507        if (expr->type == BplusExpr || expr->type ==BminusExpr) {
3508            if (vector_width(lhs_lo,lhs_hi) >
3509                vector_width(term_out->lo,term_out->hi)) {
3510                if (term_out->lo > term_out->hi)
3511                    term_out->hi = 1;
3512                else
3513                    term_out->hi++;
3514            }
3515        } else if (expr->type == BlshiftExpr || expr->type == BrshiftExpr) {
3516            if (vector_width(lhs_lo,lhs_hi) >
3517                vector_width(term_out->lo, term_out->hi)) {
3518               term_out->lo = lhs_lo;
3519               term_out->hi = lhs_hi;
3520             }
3521        }
3522
3523        bufStream = openStream();
3524        if (Use_MV_Lib)
3525            vl_write_mv_lib(bufStream,
3526                            expr->type, term_in1, term_in2, term_out);
3527        else
3528            ripple = vl_write_vector_bop(bufStream, expr->type,
3529                                         term_in1, term_in2, term_out);
3530        write_var_decl(file, term_out);
3531        dumpStream(file, bufStream);
3532        closeStream(bufStream);
3533
3534        if (Use_MV_Lib) {
3535            if (expr->type == BplusExpr || expr->type == BminusExpr) {
3536                char buf[MAXSTRLEN/8];
3537
3538                sprintf(buf, "%s%s%d%s",
3539                        term_out->name->name,
3540                        SEP_LBITSELECT, ++term_out->hi, SEP_RBITSELECT);
3541                vl_write_bit_connect(file, ripple, buf, 0);
3542            }
3543        }
3544
3545        vl_free_term(term_in1);
3546        vl_free_term(term_in2);
3547        break;
3548
3549    case TcondExpr:
3550        vl_write_expr(file, expr->u.exprs.e1, vars);
3551        vl_write_expr(file, expr->u.exprs.e2, vars);
3552        vl_write_expr(file, expr->u.exprs.e3, vars);
3553        if (!(expr->u.exprs.e1->term)) {
3554
3555            expr->u.exprs.e1->term = new_term(NIL(vl_range), 0, -1);
3556            vl_write_const(file, expr->u.exprs.e1, expr->u.exprs.e1->term);
3557        }
3558        if (!expr->u.exprs.e2->term && !expr->u.exprs.e3->term &&
3559            lhs_term) {
3560            lo = lhs_lo;  hi = lhs_hi;
3561
3562            expr->u.exprs.e2->term = new_term(NIL(vl_range), lo, hi);
3563            expr->u.exprs.e2->term->flag = lhs_term->flag;
3564            expr->u.exprs.e2->term->term_type = lhs_term->term_type;
3565            write_var_decl(file, expr->u.exprs.e2->term);
3566            vl_write_const(file, expr->u.exprs.e2, expr->u.exprs.e2->term);
3567
3568            expr->u.exprs.e3->term = new_term(NIL(vl_range), lo, hi);
3569            expr->u.exprs.e3->term->flag = lhs_term->flag;
3570            expr->u.exprs.e3->term->term_type = lhs_term->term_type;
3571            write_var_decl(file, expr->u.exprs.e3->term);
3572            vl_write_const(file, expr->u.exprs.e3, expr->u.exprs.e3->term);
3573        }
3574        if (!(expr->u.exprs.e2->term)) {
3575            lo = (expr->u.exprs.e3->term) ? expr->u.exprs.e3->term->lo : 0;
3576            hi = (expr->u.exprs.e3->term) ? expr->u.exprs.e3->term->hi :
3577                                            MAX(data_width(expr->u.exprs.e2),
3578                                                data_width(expr->u.exprs.e3));
3579            expr->u.exprs.e2->term = new_term(NIL(vl_range), lo, hi);
3580            expr->u.exprs.e2->term->flag = expr->u.exprs.e3->term->flag;
3581            expr->u.exprs.e2->term->term_type =
3582                expr->u.exprs.e3->term->term_type;
3583            write_var_decl(file, expr->u.exprs.e2->term);
3584            vl_write_const(file, expr->u.exprs.e2, expr->u.exprs.e2->term);
3585        }
3586        if (!(expr->u.exprs.e3->term)) {
3587            lo = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->lo : 0;
3588            hi = (expr->u.exprs.e2->term) ? expr->u.exprs.e2->term->hi :
3589                                            MAX(data_width(expr->u.exprs.e3),
3590                                                data_width(expr->u.exprs.e2));
3591            expr->u.exprs.e3->term = new_term(NIL(vl_range), lo, hi);
3592            expr->u.exprs.e3->term->flag = expr->u.exprs.e2->term->flag;
3593            expr->u.exprs.e3->term->term_type =
3594                expr->u.exprs.e2->term->term_type;
3595            write_var_decl(file, expr->u.exprs.e3->term);
3596            vl_write_const(file, expr->u.exprs.e3, expr->u.exprs.e3->term);
3597        }
3598
3599        if ((expr->u.exprs.e2->term->term_type &&
3600             !expr->u.exprs.e3->term->term_type) ||
3601            (expr->u.exprs.e3->term->term_type &&
3602             !expr->u.exprs.e2->term->term_type)) {
3603            vl_expr *e1, *e2;
3604            vl_enumerator *enum_elt;
3605
3606            if (!expr->u.exprs.e2->term->term_type) {
3607                e1 = expr->u.exprs.e3;
3608                e2 = expr->u.exprs.e2;
3609            } else {
3610                e1 = expr->u.exprs.e2;
3611                e2 = expr->u.exprs.e3;
3612            }
3613
3614            if (st_lookup(e1->term->term_type->specifier->
3615                          u.enum_type->domain_st,
3616                          e2->u.name->name,
3617                          (char**)&enum_elt)) {
3618                e2->term = typed_new_term(e1->term->term_type,
3619                                          e1->term->name->range,
3620                                          e1->term->lo, e1->term->hi);
3621                e2->term->flag = e1->term->flag;
3622                write_var_decl(file, e2->term);
3623                e2->type = IntExpr;
3624                e2->u.intval = enum_elt->val;
3625                vl_write_const(file, e2, e2->term);
3626            } else {
3627                char buf[MAXSTRLEN/8];
3628
3629                sprintf(buf, "'%s':comparing '%s' and '%s' of different domains",
3630                        vl_currentModule->name->name,
3631                        e1->term->name->name, e2->term->name->name);
3632                semantic_error(buf);
3633            }
3634        }
3635
3636        if (!expr->u.exprs.e2 && !expr->u.exprs.e3) {
3637            vl_expr *e;
3638            vl_enumerator *enum_elt;
3639
3640            e = expr->u.exprs.e2;
3641            if (st_lookup(lhs_term->term_type->specifier->
3642                          u.enum_type->domain_st,
3643                          e->u.name->name, (char**)&enum_elt)) {
3644                e->term = typed_new_term(lhs_term->term_type,
3645                                         lhs_term->name->range,
3646                                         lhs_term->lo, lhs_term->hi);
3647                e->term->flag = lhs_term->flag;
3648                write_var_decl(file, e->term);
3649                e->type = IntExpr;
3650                e->u.intval = enum_elt->val;
3651                vl_write_const(file, e, e->term);
3652            } else {
3653                char buf[MAXSTRLEN/8];
3654
3655                sprintf(buf, "'%s':assign '%s' to '%s' of different domains",
3656                        vl_currentModule->name->name,
3657                        e->term->name->name, lhs_term->name->name);
3658                semantic_error(buf);
3659            }
3660
3661            e = expr->u.exprs.e3;
3662            if (st_lookup(lhs_term->term_type->specifier->
3663                          u.enum_type->domain_st,
3664                          e->u.name->name, (char**)&enum_elt)) {
3665                e->term = typed_new_term(lhs_term->term_type,
3666                                         lhs_term->name->range,
3667                                         lhs_term->lo, lhs_term->hi);
3668                e->term->flag = lhs_term->flag;
3669                write_var_decl(file, e->term);
3670                e->type = IntExpr;
3671                e->u.intval = enum_elt->val;
3672                vl_write_const(file, e, e->term);
3673            } else {
3674                char buf[MAXSTRLEN/8];
3675
3676                sprintf(buf, "'%s':assign '%s' to '%s' of different domains",
3677                        vl_currentModule->name->name,
3678                        e->term->name->name, lhs_term->name->name);
3679                semantic_error(buf);
3680            }
3681        }
3682
3683        term_in1=expr->u.exprs.e2->term;
3684        term_in2=expr->u.exprs.e3->term;
3685
3686        fprintf(file, "%s ", HSIS_COMMENT);
3687        if (!NoDetailedComment) vl_step_expr(file, expr);
3688        fprintf(file, "\n");
3689
3690        expr->term = term_out = new_term(NIL(vl_range), 0, -1);
3691        term_out->flag = term_in1->flag;
3692        term_out->term_type = term_in1->term_type;
3693
3694        if (lhs_term) {
3695            if (insideConcat) {
3696                if (vector_width(term_in1->lo, term_in1->hi) ==
3697                    vector_width(term_in2->lo, term_in2->hi)) {
3698
3699
3700                    term_out->lo = 0;
3701                    term_out->hi = vector_width(term_in1->lo,term_in1->hi)-1;
3702                } else {
3703
3704                    term_out->lo = lhs_term->lo;
3705                    term_out->hi = lhs_term->hi;
3706                }
3707            } else {
3708                term_out->lo = lhs_term->lo;
3709                term_out->hi = lhs_term->hi;
3710            }
3711
3712
3713            if (vector_width(term_in1->lo, term_in1->hi) <
3714                vector_width(term_out->lo, term_out->hi)) {
3715                vl_term *tmp_term;
3716                tmp_term = new_term(NIL(vl_range), term_out->lo, term_out->hi);
3717                write_var_decl(file, tmp_term);
3718                expand_term(file, term_in1, tmp_term);
3719                vl_free_term(term_in1);
3720                term_in1 = tmp_term;
3721            } else if (vector_width(term_in1->lo, term_in1->hi) >
3722                       vector_width(term_out->lo, term_out->hi)) {
3723                vl_term *tmp_term;
3724                tmp_term = new_term(NIL(vl_range), term_out->lo, term_out->hi);
3725                write_var_decl(file, tmp_term);
3726                shrink_term(file, term_in1, tmp_term);
3727                vl_free_term(term_in1);
3728                term_in1 = tmp_term;
3729            }
3730            if (vector_width(term_in2->lo, term_in2->hi) <
3731                vector_width(term_out->lo, term_out->hi)) {
3732                vl_term *tmp_term;
3733                tmp_term = new_term(NIL(vl_range), term_out->lo, term_out->hi);
3734                write_var_decl(file, tmp_term);
3735                expand_term(file, term_in2, tmp_term);
3736                vl_free_term(term_in2);
3737                term_in2 = tmp_term;
3738            } else if (vector_width(term_in2->lo, term_in2->hi) >
3739                       vector_width(term_out->lo, term_out->hi)) {
3740                vl_term *tmp_term;
3741                tmp_term = new_term(NIL(vl_range), term_out->lo, term_out->hi);
3742                write_var_decl(file, tmp_term);
3743                shrink_term(file, term_in2, tmp_term);
3744                vl_free_term(term_in2);
3745                term_in2 = tmp_term;
3746            }
3747        } else {
3748            if (term_in1->lo > term_in1->hi) {
3749
3750                term_out->lo = term_in2->lo;
3751                term_out->hi = term_in2->hi;
3752            } else if (term_in2->lo > term_in2->hi) {
3753                term_out->lo = term_in1->lo;
3754                term_out->hi = term_in1->hi;
3755            } else {
3756                term_out->lo = 0;
3757                if (term_in1->hi-term_in1->lo != term_in2->hi-term_in2->lo) {
3758                    char buf[MAXSTRLEN/8];
3759
3760                    sprintf(buf, "'%s':different vector sizes %s %s",
3761                            vl_currentModule->name->name,
3762                            term_in1->name->name, term_in2->name->name);
3763                    Translate_Warning(buf);
3764                }
3765                term_out->hi = MIN(term_in1->hi-term_in1->lo,
3766                                   term_in2->hi-term_in2->lo);
3767            }
3768        }
3769        write_var_decl(file, term_out);
3770
3771        instantiate_mux(file, term_in1, term_in2, expr->u.exprs.e1->term,
3772                        term_out);
3773
3774        vl_free_term(term_in1);
3775        vl_free_term(term_in2);
3776        break;
3777
3778    case NondExpr: {
3779        vl_term *nond_term=NIL(vl_term), *ctrl_term=NIL(vl_term);
3780        lsList nond_list;
3781        lsGen gen;
3782        lsHandle handle;
3783        vl_expr *nexp;
3784        int i;
3785
3786        if (vars && !rst_ckt)
3787            semantic_error("don't use $ND in procedural block");
3788
3789        nond_list = lsCreate();
3790        if ((nd_check_ok == 0 && vis_nond) && !rst_ckt) {
3791            char buf[MAXSTRLEN/8];
3792            yylineno = -1;
3793            sprintf(buf, "'%s': The legal usage of $ND is continuous assignment:\n\tassign <var> = $ND(...);",
3794                    vl_currentModule->name->name);
3795            compile_error(buf);
3796        }
3797        for (gen=lsStart(expr->u.expr_list), i=0;
3798             lsNext(gen, (lsGeneric*)&nexp, &handle) != LS_NOMORE; i++) {
3799            vl_write_expr(file, nexp, vars);
3800            if (nexp->type == EventExpr || nexp->type == PosedgeEventExpr ||
3801                nexp->type == NegedgeEventExpr || nexp->type == OrEventExpr) {
3802
3803                ctrl_term = NIL(vl_term);
3804            } else {
3805                lsNewEnd(nond_list, (lsGeneric)nexp, 0);
3806            }
3807        }
3808        lsFinish(gen);
3809        nond_term = vl_write_nond_wire(file, ctrl_term, nond_list,
3810                                       lhs_term);
3811        lsDestroy(nond_list, 0);
3812        expr->term = nond_term;
3813        if (!rst_ckt)
3814            nd_check_ok = -1;
3815        break;
3816    }
3817    }
3818
3819    if (nd_check_ok == -1 && expr->type != NondExpr && vis_nond) {
3820        char buf[MAXSTRLEN/8];
3821        yylineno = -1;
3822        sprintf(buf, "'%s': The legal usage of $ND is continuous assignment:\n\tassign <var> = $ND(...);",
3823                vl_currentModule->name->name);
3824        compile_error(buf);
3825    }
3826    if (nd_check_ok != -1)
3827        nd_check_ok = 0;
3828}
3829
3830
3831
3832set_t *vl_write_event_expr(FILE *file, vl_event_expr *event)
3833{
3834    set_t *retval=NIL(set_t);
3835    vl_event_expr *e;
3836    lsGen gen;
3837    lsHandle handle;
3838    st_generator *stgen;
3839    vl_term *et;
3840    char *dummy;
3841    int i, j;
3842
3843    WrtTRACE("writing event_expr\n");
3844    if (event == NIL(vl_event_expr)) return retval;
3845
3846    switch(event->type) {
3847    case OrEventExpr:
3848        retval = st_init_table(ptrcmp, ptrhash);
3849        gen = lsStart(event->list);
3850        while (lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE) {
3851            vl_write_event_expr(file, e);
3852            st_insert(retval, (char*)edge_triggering, 0);
3853        }
3854        lsFinish(gen);
3855
3856        assert(st_count(retval) == lsLength(event->list));
3857        edge_triggering = new_term(NIL(vl_range), 0, -1);
3858        fprintf(file, ".names ");
3859        stgen = st_init_gen(retval);
3860        while (st_gen(stgen, (char**)&et, &dummy)) {
3861            fprintf(file, "%s ", et->name->name);
3862        }
3863        st_free_gen(stgen);
3864        fprintf(file, "%s\n%s 0\n",
3865                edge_triggering->name->name, HSIS_DEFAULT);
3866        for (i=0; i<st_count(retval); i++) {
3867            for (j=0; j<i; j++) fprintf(file, "- ");
3868            j++; fprintf(file, "1 ");
3869            for (; j<st_count(retval); j++) fprintf(file, "- ");
3870            fprintf(file, "1\n");
3871        }
3872        retval = NIL(set_t);
3873
3874
3875        break;
3876    case NegedgeEventExpr:
3877        edge_triggering = write_edge_detector(file, event->expr, -1);
3878        break;
3879    case PosedgeEventExpr:
3880        edge_triggering = write_edge_detector(file, event->expr, 1);
3881        break;
3882    case EdgeEventExpr:
3883        break;
3884    case EventExpr:
3885
3886        edge_triggering = write_edge_detector(file, event->expr, 0);
3887        break;
3888    default:
3889        internal_error("Unexpected EventExpr Type");
3890        break;
3891    }
3892
3893    return retval;
3894}
3895
3896
3897
3898int vl_eval_expr(vl_expr *expr)
3899{
3900    int i, val;
3901    int min, typ, max;
3902    double minf=0, typf=0, maxf=0;
3903    int aux1_flag, aux2_flag, aux3_flag;
3904
3905    if (!expr) return 0;
3906    switch (expr->type) {
3907    case BitExpr: return expr->u.bexpr.part1;
3908    case IntExpr: return expr->u.intval;
3909    case RealExpr:
3910      vl_expr_aux1_val = expr->u.realval;
3911      vl_expr_aux1_flag = 1;
3912      return (int)expr->u.realval;
3913    case IDExpr:  {
3914        vl_id_range *id_sym;
3915        int cant_evaluate=0;
3916        int cant_find=0;
3917
3918        if (vl_currentPrimitive)
3919            cant_evaluate = 1;
3920        if (!vl_currentModule->param_st)
3921            cant_evaluate = 1;
3922        if (!cant_evaluate)
3923            if (!st_lookup(vl_currentModule->param_st, expr->u.name->name,
3924                           (char**)&id_sym))
3925                cant_find = 1;
3926        if (vl_encloseModule && !cant_evaluate)
3927            if (cant_find)
3928                if (st_lookup(vl_encloseModule->param_st, expr->u.name->name,
3929                               (char**)&id_sym))
3930                    cant_find=0;
3931        if (cant_evaluate || cant_find) {
3932            char buf[MAXSTRLEN];
3933            sprintf(buf, "%s:eval_expr:need constant instead of variable %s",
3934                    vl_currentModule->name->name,
3935                    expr->u.name->name);
3936            yylineno = -1;
3937            if (silent_err) {
3938                Vlerrno = 1;
3939                return 0;
3940            } else
3941                compile_error(buf);
3942        }
3943
3944        return (int)(id_sym->mpg_master_exp);
3945    }
3946    case BitSelExpr:   case PartSelExpr:
3947      if (!silent_err) {
3948          vl_step_expr(stderr, expr);
3949          yylineno = -1;
3950          compile_error("need constant instead of variable");
3951      } else {
3952          Vlerrno = 1;
3953          return 0;
3954      }
3955    case ConcatExpr: {
3956        int i, rep=1;
3957        int acc=0, val, width;
3958        lsGen gen;
3959        lsHandle handle;
3960        vl_expr *e;
3961        if (expr->u.exprs.e2) {
3962            rep = vl_eval_expr(expr->u.exprs.e2);
3963        }
3964        for (i=0; i<rep; i++) {
3965            for (gen=lsStart((lsList)(expr->u.exprs.e1));
3966                 lsNext(gen, (lsGeneric*)&e, &handle) != LS_NOMORE;) {
3967                if (e->type != BitExpr) width_unknown();
3968                val = vl_eval_expr(e);
3969                width = strlen((char*)e->u.exprs.e3);
3970                acc = (acc << width) | val;
3971            }
3972            lsFinish(gen);
3973        }
3974
3975        return acc;
3976    }
3977
3978    case MinTypMaxExpr:
3979      aux1_flag = aux2_flag = aux3_flag = 0;
3980      min = vl_eval_expr(expr->u.exprs.e1);
3981      aux1_flag=1;
3982      if (vl_expr_aux1_val) minf=vl_expr_aux1_val;
3983      else minf = min;
3984      if (expr->u.exprs.e2) {
3985          typ = vl_eval_expr(expr->u.exprs.e2);
3986          aux2_flag=1;
3987          if (vl_expr_aux1_val) typf=vl_expr_aux1_val;
3988          else typf = typ;
3989      }
3990      if (expr->u.exprs.e3) {
3991          max = vl_eval_expr(expr->u.exprs.e2);
3992          aux3_flag=1;
3993          if (vl_expr_aux1_val) maxf=vl_expr_aux1_val;
3994          else maxf = max;
3995      }
3996      if (!vl_expr_aux3_flag) {
3997          aux3_flag = aux2_flag;
3998          aux2_flag = 0;
3999          max = typ;  maxf = typf;
4000          typ = 0;    typf = (double)0;
4001      }
4002      vl_expr_aux1_flag = aux1_flag;
4003      vl_expr_aux2_flag = aux2_flag;
4004      vl_expr_aux3_flag = aux3_flag;
4005      vl_expr_aux1_val = minf;
4006      vl_expr_aux2_val = typf;
4007      vl_expr_aux3_val = maxf;
4008      return min;
4009    case StringExpr: break;
4010    case FuncExpr:
4011    case UplusExpr:  return vl_eval_expr(expr->u.exprs.e1);
4012    case UminusExpr: return -vl_eval_expr(expr->u.exprs.e1);
4013    case UnotExpr:   return !vl_eval_expr(expr->u.exprs.e1);
4014    case UcomplExpr: return ~vl_eval_expr(expr->u.exprs.e1);
4015
4016    case UnandExpr: case UandExpr:
4017    case UnorExpr:  case UorExpr:
4018    case UxnorExpr: case UxorExpr:
4019        Translate_Warning("reduction on constant");
4020        for (i=0, val = vl_eval_expr(expr->u.exprs.e1); i<MAXBITNUM-2; i++) {
4021            switch (expr->type) {
4022            case UnandExpr: case UandExpr:
4023                val = (val & 1) & (val >> 1); break;
4024            case UnorExpr:  case UorExpr:
4025                val = (val & 1) | (val >> 1); break;
4026            case UxnorExpr: case UxorExpr:
4027                val = (val & 1) ^ (val >> 1); break;
4028            }
4029            val >>= 1;
4030        }
4031        if (expr->type == UnandExpr ||
4032            expr->type == UnorExpr ||
4033            expr->type == UxnorExpr)
4034            val = !val;
4035
4036    case BtimesExpr:
4037        return vl_eval_expr(expr->u.exprs.e1) * vl_eval_expr(expr->u.exprs.e2);
4038    case BdivExpr:
4039        return vl_eval_expr(expr->u.exprs.e1) / vl_eval_expr(expr->u.exprs.e2);
4040    case BremExpr:
4041        return vl_eval_expr(expr->u.exprs.e1) % vl_eval_expr(expr->u.exprs.e2);
4042    case BlshiftExpr:
4043        return vl_eval_expr(expr->u.exprs.e1) << vl_eval_expr(expr->u.exprs.e2);
4044    case BrshiftExpr:
4045        return vl_eval_expr(expr->u.exprs.e1) >> vl_eval_expr(expr->u.exprs.e2);
4046
4047
4048
4049    case Beq3Expr:
4050        return vl_eval_expr(expr->u.exprs.e1) == vl_eval_expr(expr->u.exprs.e2);
4051    case Bneq3Expr:
4052        return vl_eval_expr(expr->u.exprs.e1) != vl_eval_expr(expr->u.exprs.e2);
4053    case Beq2Expr:
4054        return vl_eval_expr(expr->u.exprs.e1) == vl_eval_expr(expr->u.exprs.e2);
4055    case Bneq2Expr:
4056        return vl_eval_expr(expr->u.exprs.e1) != vl_eval_expr(expr->u.exprs.e2);
4057
4058    case BlandExpr:
4059        return vl_eval_expr(expr->u.exprs.e1) && vl_eval_expr(expr->u.exprs.e2);
4060    case BlorExpr:
4061        return vl_eval_expr(expr->u.exprs.e1) || vl_eval_expr(expr->u.exprs.e2);
4062    case BltExpr:
4063        return vl_eval_expr(expr->u.exprs.e1) < vl_eval_expr(expr->u.exprs.e2);
4064    case BleExpr:
4065        return vl_eval_expr(expr->u.exprs.e1) <= vl_eval_expr(expr->u.exprs.e2);
4066    case BgtExpr:
4067        return vl_eval_expr(expr->u.exprs.e1) > vl_eval_expr(expr->u.exprs.e2);
4068    case BgeExpr:
4069        return vl_eval_expr(expr->u.exprs.e1) >= vl_eval_expr(expr->u.exprs.e2);
4070    case BplusExpr:
4071        return vl_eval_expr(expr->u.exprs.e1) + vl_eval_expr(expr->u.exprs.e2);
4072    case BminusExpr:
4073        return vl_eval_expr(expr->u.exprs.e1) - vl_eval_expr(expr->u.exprs.e2);
4074    case BandExpr:
4075        return vl_eval_expr(expr->u.exprs.e1) & vl_eval_expr(expr->u.exprs.e2);
4076    case BorExpr:
4077        return vl_eval_expr(expr->u.exprs.e1) | vl_eval_expr(expr->u.exprs.e2);
4078    case BxorExpr:
4079        return vl_eval_expr(expr->u.exprs.e1) ^ vl_eval_expr(expr->u.exprs.e2);
4080    case BxnorExpr:
4081        return ~(vl_eval_expr(expr->u.exprs.e1) ^vl_eval_expr(expr->u.exprs.e2));
4082
4083    case TcondExpr:
4084        return (vl_eval_expr(expr->u.exprs.e1)) ?
4085            vl_eval_expr(expr->u.exprs.e2) : vl_eval_expr(expr->u.exprs.e3);
4086    }
4087
4088    return 0;
4089}
4090
4091
4092st_table *create_var_muxes(FILE *file, vl_term *sel, st_table *t_vars, st_table *f_vars, st_table *vars)
4093{
4094    int lo=0, hi=0;
4095    var_info *cur_var;
4096    st_generator *gen;
4097    var_info *t_in, *f_in;
4098    char *key, buf[MAXSTRLEN];
4099    vl_term *term_out;
4100
4101
4102    gen = st_init_gen(t_vars);
4103    while (st_gen(gen, &key, (char**)&t_in)) {
4104
4105        if (strstr(key,SEP_LATCH)) continue;
4106        if (strstr(key,SEP_QUASI)) continue;
4107
4108        sprintf(buf, "%s%s%s%s%s%s",
4109                t_in->id->name, SEP_GATEPIN, descape(sel->name->name,'\\','_'),
4110                SEP_GATEPIN, PIN_RAWOUT, new_termname());
4111        if (st_lookup(f_vars, key, (char**)&f_in)) {
4112            if (st_lookup(vars, key, (char**)&cur_var)) {
4113                int t_in_cur_var, f_in_cur_var;
4114
4115                t_in_cur_var = !strcmp(t_in->current_terminal->name->name,
4116                                       cur_var->current_terminal->name->name);
4117                f_in_cur_var = !strcmp(f_in->current_terminal->name->name,
4118                                       cur_var->current_terminal->name->name);
4119
4120
4121                if ( t_in_cur_var && f_in_cur_var)
4122                    continue;
4123
4124
4125                if ((strstr(t_in->current_terminal->name->name, SEP_GATEPIN) ||
4126                    strstr(f_in->current_terminal->name->name, SEP_GATEPIN)) &&
4127                    !(t_in->current_terminal->hi == -1 ||
4128                      f_in->current_terminal->hi == -1) &&
4129                    (t_in->current_terminal->hi!=f_in->current_terminal->hi ||
4130                     t_in->current_terminal->lo!=f_in->current_terminal->lo)) {
4131                    if (t_in->current_terminal->hi !=
4132                        f_in->current_terminal->hi ||
4133                        t_in->current_terminal->lo !=
4134                        f_in->current_terminal->lo) {
4135                        int i, t_need_extend, f_need_extend;
4136                        char in_buf[MAXSTRLEN], out_buf[MAXSTRLEN];
4137                        vl_term *t_new_term=NIL(vl_term),
4138                                *f_new_term=NIL(vl_term);
4139
4140                        hi = MAX(t_in->current_terminal->hi,f_in->current_terminal->hi);
4141                        lo = MIN(t_in->current_terminal->lo,f_in->current_terminal->lo);
4142                        t_need_extend = (hi > t_in->current_terminal->hi ||
4143                                         lo < t_in->current_terminal->lo);
4144                        f_need_extend = (hi > f_in->current_terminal->hi ||
4145                                         lo < f_in->current_terminal->lo);
4146                        if (t_need_extend) {
4147                            t_new_term =
4148                            typed_new_term(t_in->current_terminal->term_type,
4149                                           t_in->id->range, lo, hi);
4150                            write_var_decl(file, t_new_term);
4151                        }
4152                        if (f_need_extend) {
4153                            f_new_term =
4154                            typed_new_term(f_in->current_terminal->term_type,
4155                                           f_in->id->range, lo, hi);
4156                            write_var_decl(file, f_new_term);
4157                        }
4158                        for (i=lo; i<=hi; i++) {
4159                            if (t_need_extend) {
4160                                if (i < t_in->current_terminal->lo ||
4161                                    i > t_in->current_terminal->hi) {
4162                                    var_info *curr_var_info;
4163
4164                                    st_lookup(vars, t_in->id->name,
4165                                              (char**)&curr_var_info);
4166                                    if (i >=
4167                                        curr_var_info->current_terminal->lo &&
4168                                        i <=
4169                                        curr_var_info->current_terminal->hi) {
4170                                        sprintf(in_buf, "%s%s%d%s",
4171                                            curr_var_info->
4172                                                current_terminal->name->name,
4173                                                SEP_LBITSELECT,
4174                                                i,
4175                                                SEP_RBITSELECT);
4176
4177                                    } else {
4178                                        sprintf(in_buf, "%s%s%d%s",
4179                                                t_in->id->name,
4180                                                SEP_LBITSELECT,
4181                                                i,
4182                                                SEP_RBITSELECT);
4183                                    }
4184                                } else {
4185                                    sprintf(in_buf, "%s%s%d%s",
4186                                            t_in->current_terminal->name->name,
4187                                            SEP_LBITSELECT, i, SEP_RBITSELECT);
4188                                }
4189                                sprintf(out_buf, "%s%s%d%s",
4190                                        t_new_term->name->name,
4191                                        SEP_LBITSELECT, i, SEP_RBITSELECT);
4192                                vl_write_bit_connect(file, in_buf, out_buf, 0);
4193                            }
4194                            if (f_need_extend) {
4195                                if (i < f_in->current_terminal->lo ||
4196                                    i > f_in->current_terminal->hi) {
4197                                    var_info *curr_var_info;
4198
4199                                    st_lookup(vars, t_in->id->name,
4200                                              (char**)&curr_var_info);
4201                                    if (i >=
4202                                        curr_var_info->current_terminal->lo &&
4203                                        i <=
4204                                        curr_var_info->current_terminal->hi) {
4205                                        sprintf(in_buf, "%s%s%d%s",
4206                                            curr_var_info->
4207                                                current_terminal->name->name,
4208                                                SEP_LBITSELECT,
4209                                                i,
4210                                                SEP_RBITSELECT);
4211                                  } else {
4212                                    sprintf(in_buf, "%s%s%d%s",
4213                                            f_in->id->name,
4214                                            SEP_LBITSELECT,
4215                                            i,
4216                                            SEP_RBITSELECT);
4217                                  }
4218                                } else {
4219                                    sprintf(in_buf, "%s%s%d%s",
4220                                            f_in->current_terminal->name->name,
4221                                            SEP_LBITSELECT, i, SEP_RBITSELECT);
4222                                }
4223                                sprintf(out_buf, "%s%s%d%s",
4224                                        f_new_term->name->name,
4225                                        SEP_LBITSELECT, i, SEP_RBITSELECT);
4226                                vl_write_bit_connect(file, in_buf, out_buf, 0);
4227                            }
4228                        }
4229                        if (t_need_extend)
4230                            t_in->current_terminal = t_new_term;
4231                        if (f_need_extend)
4232                            f_in->current_terminal = f_new_term;
4233                    }
4234                } else {
4235                    if (t_in->current_terminal->hi-t_in->current_terminal->lo>=
4236                        f_in->current_terminal->hi-f_in->current_terminal->lo){
4237                        lo = t_in->current_terminal->lo;
4238                        hi = t_in->current_terminal->hi;
4239                    } else {
4240                        lo = f_in->current_terminal->lo;
4241                        hi = f_in->current_terminal->hi;
4242                    }
4243                }
4244                term_out = create_rename_term(t_in->id, buf, lo, hi);
4245                term_out->flag = t_in->current_terminal->flag;
4246
4247                write_var_decl(file, term_out);
4248                instantiate_mux(file,
4249                                t_in->current_terminal,
4250                                f_in->current_terminal,
4251                                sel, term_out);
4252                cur_var->current_terminal = term_out;
4253
4254
4255                if (!t_in_cur_var && !f_in_cur_var) {
4256                    continue;
4257                }
4258
4259
4260                if (!t_in_cur_var && f_in_cur_var) {
4261                    continue;
4262                }
4263
4264
4265                if (t_in_cur_var && !f_in_cur_var) {
4266                    continue;
4267                }
4268            }
4269        }
4270    }
4271    st_free_gen(gen);
4272
4273    gen = st_init_gen(t_vars);
4274    while (st_gen(gen, &key, (char**)&t_in)) {
4275
4276        if (strstr(key,SEP_LATCH)) continue;
4277        if (strstr(key,SEP_QUASI)) continue;
4278
4279        sprintf(buf, "%s%s%s%s%s%s",
4280                t_in->id->name, SEP_GATEPIN, descape(sel->name->name,'\\','_'),
4281                SEP_GATEPIN, PIN_RAWOUT, new_termname());
4282        if (st_lookup(f_vars, key, (char**)&f_in)) {
4283            if (!st_lookup(vars, key, (char**)&cur_var)) {
4284
4285                if (t_in->current_terminal->hi-t_in->current_terminal->lo >=
4286                    f_in->current_terminal->hi-f_in->current_terminal->lo) {
4287                    lo = t_in->current_terminal->lo;
4288                    hi = t_in->current_terminal->hi;
4289                } else {
4290                    lo = f_in->current_terminal->lo;
4291                    hi = f_in->current_terminal->hi;
4292                }
4293                term_out = create_rename_term(t_in->id, buf, lo, hi);
4294                term_out->flag |= t_in->current_terminal->flag;
4295                write_var_decl(file, term_out);
4296                instantiate_mux(file, t_in->current_terminal,
4297                                f_in->current_terminal,
4298                                sel, term_out);
4299
4300
4301                assert(!st_lookup(vars,key,(char**)&cur_var));
4302                st_insert(vars, key,
4303                          (char*)create_var_info(vl_copy_id_range(t_in->id),
4304                                                 term_out));
4305
4306
4307            }
4308        }
4309    }
4310    st_free_gen(gen);
4311
4312
4313
4314    gen = st_init_gen(t_vars);
4315    while (st_gen(gen, &key, (char**)&t_in)) {
4316
4317        if (strstr(key,SEP_LATCH)) continue;
4318        if (strstr(key,SEP_QUASI)) continue;
4319
4320        sprintf(buf, "%s%s%s%s%s%s",
4321                t_in->id->name, SEP_GATEPIN, descape(sel->name->name,'\\','_'),
4322                SEP_GATEPIN, PIN_RAWOUT, new_termname());
4323        if (!st_lookup(f_vars, key, (char**)&f_in)) {
4324            vl_term *orig_id;
4325            char *dummy;
4326
4327
4328            term_out = create_rename_term(t_in->id, buf,
4329                                          t_in->current_terminal->lo,
4330                                          t_in->current_terminal->hi);
4331            term_out->flag |= t_in->current_terminal->flag;
4332            orig_id =
4333                vl_create_term(((t_in->id->flags & EventVar) && smartEvent)?
4334                               vl_create_id_range(WRT_BLIF_GND(file),
4335                                                  NIL(vl_range))           :
4336                               vl_copy_id_range(t_in->id),
4337                                     t_in->current_terminal->lo,
4338                                     t_in->current_terminal->hi);
4339            if (vl_currentModule->combVar_st)
4340                if (st_lookup(vl_currentModule->combVar_st,
4341                              orig_id->name->name, &dummy)) {
4342                    vl_free_term(orig_id);
4343                    orig_id = true_term(file);
4344                }
4345            if (vl_currentFunction) {
4346                vl_free_term(orig_id);
4347                orig_id = true_term(file);
4348            }
4349            orig_id->flag = t_in->current_terminal->flag;
4350            write_var_decl(file, term_out);
4351            if (rst_ckt) {
4352                instantiate_mux(file, t_in->current_terminal,
4353                                t_in->current_terminal,
4354                                sel, term_out);
4355            } else {
4356                instantiate_mux(file, t_in->current_terminal, orig_id,
4357                                sel, term_out);
4358            }
4359            vl_free_term(orig_id);
4360
4361            st_insert(vars, key,
4362                      (char*)create_var_info(vl_copy_id_range(t_in->id),
4363                                             term_out));
4364        }
4365    }
4366    st_free_gen(gen);
4367
4368
4369
4370    gen = st_init_gen(f_vars);
4371    while (st_gen(gen, &key, (char**)&f_in)) {
4372
4373        if (strstr(key,SEP_LATCH)) continue;
4374        if (strstr(key,SEP_QUASI)) continue;
4375
4376        sprintf(buf, "%s%s%s%s%s%s",
4377                f_in->id->name, SEP_GATEPIN, descape(sel->name->name,'\\','_'),
4378                SEP_GATEPIN, PIN_RAWOUT, new_termname());
4379        if (!st_lookup(t_vars, key, (char**)&t_in)) {
4380            vl_term *orig_id;
4381
4382
4383            term_out = create_rename_term(f_in->id, buf,
4384                                          f_in->current_terminal->lo,
4385                                          f_in->current_terminal->hi);
4386            term_out->flag |= f_in->current_terminal->flag;
4387            orig_id =
4388                vl_create_term(((f_in->id->flags & EventVar) && smartEvent)?
4389                                   vl_create_id_range(WRT_BLIF_GND(file),
4390                                                      NIL(vl_range))       :
4391                                   vl_copy_id_range(f_in->id),
4392                                     f_in->current_terminal->lo,
4393                                     f_in->current_terminal->hi);
4394            orig_id->flag = f_in->current_terminal->flag;
4395
4396            write_var_decl(file, term_out);
4397            if (rst_ckt) {
4398                instantiate_mux(file, f_in->current_terminal,
4399                                f_in->current_terminal,
4400                                sel, term_out);
4401            } else {
4402                instantiate_mux(file, orig_id, f_in->current_terminal,
4403                                sel, term_out);
4404            }
4405            vl_free_term(orig_id);
4406
4407            st_insert(vars, key,
4408                      (char*)create_var_info(vl_copy_id_range(f_in->id),
4409                                             term_out));
4410        }
4411    }
4412    st_free_gen(gen);
4413
4414    return vars;
4415}
4416
4417
4418vl_term *write_case_comparator(FILE *file, vl_term *selector, lsList tags, st_table *vars)
4419{
4420    int j;
4421    vl_expr *expr;
4422    lsHandle handle;
4423    lsGen gen;
4424    vl_term *term_out;
4425    vl_term *comp_result;
4426    char buf[MAXSTRLEN];
4427
4428    if (!tags) return NIL(vl_term);
4429
4430    buf[0] = '\0';
4431    term_out = new_term(NIL(vl_range), 0, -1);
4432
4433    for (gen = lsStart(tags);
4434         lsNext(gen, (lsGeneric*)&expr, &handle) != LS_NOMORE; ) {
4435        comp_result = new_term(NIL(vl_range), 0, -1);
4436
4437        write_case_tag_const(file, selector, expr, vars);
4438
4439        write_comparator(file, selector, expr->term, comp_result);
4440        strcat(buf, comp_result->name->name);
4441        strcat(buf, " ");
4442        vl_free_term(comp_result);
4443        comp_result = NIL(vl_term);
4444        vl_free_term(expr->term);
4445        expr->term = NIL(vl_term);
4446    }
4447    (void)lsFinish(gen);
4448
4449    fprintf(file, ".names %s %s\n", buf, term_out->name->name);
4450
4451    fprintf(file, ".def 1\n");
4452    for (j=0; j<lsLength(tags); j++) {
4453        fprintf(file, "0 ");
4454    }
4455    fprintf(file, "0\n");
4456
4457    return term_out;
4458}
4459
4460char *vl_write_vector_bop(FILE *file, short type, vl_term *in1, vl_term *in2, vl_term *out)
4461{
4462    char *ripple = NIL(char);
4463
4464    if (ISREDUCTION(type)) {
4465        ripple = write_red_op(file, type, in1, in2, out);
4466    } else if (IS_VLR_REL_OP(type)) {
4467        ripple = write_rel_vector_bop(file, type, in1, in2, out);
4468    } else {
4469        ripple = write_op_vector_bop(file, type, in1, in2, out);
4470    }
4471
4472    return ripple;
4473}
4474
4475
4476#define BLIF_BITCONNECT   0
4477#define BLIF_NOT          1
4478#define BLIF_AND          2
4479#define BLIF_NAND         3
4480#define BLIF_OR           4
4481#define BLIF_NOR          5
4482#define BLIF_XOR          6
4483#define BLIF_XNOR         7
4484#define BLIF_ADD          8
4485#define BLIF_SUB          10
4486#define BLIF_MUX          12
4487
4488#define EXPR_TO_BLIF_FUNC(exprval) \
4489    ((exprval)==BlandExpr)? BLIF_AND : \
4490    ((exprval)==BlorExpr) ? BLIF_OR  : \
4491    ((exprval)==BandExpr) ? BLIF_AND : \
4492    ((exprval)==BorExpr)  ? BLIF_OR  : \
4493    ((exprval)==BxorExpr) ? BLIF_XOR : \
4494    ((exprval)==BxnorExpr)? BLIF_XNOR: \
4495    ((exprval)==BplusExpr)? BLIF_ADD : \
4496    ((exprval)==BminusExpr)?BLIF_SUB : \
4497    ((exprval)==BltExpr)  ? BLIF_SUB : \
4498    ((exprval)==BleExpr)  ? BLIF_SUB : \
4499    ((exprval)==BgtExpr)  ? BLIF_SUB : \
4500    ((exprval)==BgeExpr)  ? BLIF_SUB : \
4501    ((exprval)==UandExpr) ? BLIF_AND : \
4502    ((exprval)==UnandExpr)? BLIF_NAND: \
4503    ((exprval)==UorExpr)  ? BLIF_OR  : \
4504    ((exprval)==UnorExpr) ? BLIF_NOR : \
4505    ((exprval)==UxorExpr) ? BLIF_XOR : 0
4506
4507#define EXPR_TO_SMV_FUNC(exprval) \
4508    ((exprval)==BlandExpr)? SMV_AND : \
4509    ((exprval)==BlorExpr) ? SMV_OR  : \
4510    ((exprval)==BandExpr) ? SMV_AND : \
4511    ((exprval)==BorExpr)  ? SMV_OR  : \
4512    ((exprval)==BxnorExpr)? SMV_EQUIV:\
4513    ((exprval)==BxorExpr) ? SMV_EQUIV: "???"
4514
4515static char *log_function[] = {
4516    "0 0  \n1 1  \n",
4517    "0 1  \n1 0  \n",
4518    "0 0 0\n0 1 0\n1 0 0\n1 1 1\n",
4519    "0 0 1\n0 1 1\n1 0 1\n1 1 0\n",
4520    "0 0 0\n0 1 1\n1 0 1\n1 1 1\n",
4521    "0 0 1\n0 1 0\n1 0 0\n1 1 0\n",
4522    "0 0 0\n0 1 1\n1 0 1\n1 1 0\n",
4523    "0 0 1\n0 1 0\n1 0 0\n1 1 1\n",
4524    "0 0 0 0\n0 0 1 1\n0 1 0 1\n0 1 1 0\n1 0 0 1\n1 0 1 0\n1 1 0 0\n1 1 1 1\n",
4525    "0 0 0 0\n0 0 1 0\n0 1 0 0\n0 1 1 1\n1 0 0 0\n1 0 1 1\n1 1 0 1\n1 1 1 1\n",
4526    "0 0 0 0\n0 0 1 1\n0 1 0 1\n0 1 1 0\n1 0 0 1\n1 0 1 0\n1 1 0 0\n1 1 1 1\n",
4527    "0 0 0 0\n0 0 1 1\n0 1 0 1\n0 1 1 1\n1 0 0 0\n1 0 1 0\n1 1 0 0\n1 1 1 1\n",
4528    "0 - 0 0\n1 - 0 1\n- 0 1 0\n- 1 1 1\n"
4529    };
4530
4531static char *set_log_function[] = {
4532    "0 0  \n1 1  \n",
4533    "0 1  \n1 0  \n",
4534    ".def 0\n1 1 1\n",
4535    ".def 1\n1 1 0\n",
4536    ".def 1\n0 0 0\n",
4537    ".def 0\n0 0 1\n",
4538    ".def 0\n0 1 1\n1 0 1\n",
4539    ".def 1\n0 1 0\n1 0 0\n",
4540    ".def 0\n0 0 1 1\n0 1 0 1\n1 0 0 1\n1 1 1 1\n",
4541    ".def 0\n- 1 1 1\n1 - 1 1\n1 1 - 1\n",
4542    ".def 0\n0 0 1 1\n0 1 0 1\n1 0 0 1\n1 1 1 1\n",
4543    ".def 0\n0 - 1 1\n0 1 - 1\n- 1 1 1\n",
4544    "0 - 0 0\n1 - 0 1\n- 0 1 0\n- 1 1 1\n"
4545    };
4546
4547
4548char *vl_write_bop(FILE *file, short type, char *in1, char *in2, char *auxin, char *out, int forbidden_ripple)
4549{
4550    int mv_func;
4551    char sbuf[MAXSTRLEN];
4552    static char ripplenet[MAXSTRLEN];
4553    char **func;
4554
4555    func = (set_notation)?set_log_function:log_function;
4556    switch(type) {
4557    case BlandExpr: case BlorExpr:
4558    case BandExpr:  case BorExpr:  case BxorExpr:  case BxnorExpr:
4559        mv_func = EXPR_TO_BLIF_FUNC(type);
4560        fprintf(file, ".names %s %s %s\n", in1, in2, out);
4561        fprintf(file, "%s", func[mv_func]);
4562        sprintf(sbuf, "%s", out);
4563        break;
4564    case UnotExpr: type = UorExpr;
4565
4566    case UandExpr:  case UnandExpr:
4567    case UorExpr:  case UnorExpr:
4568    case UxorExpr:    case UxnorExpr:
4569        sprintf(sbuf, "%s", new_termname());
4570        mv_func = EXPR_TO_BLIF_FUNC(type);
4571        fprintf(file, ".names %s %s %s\n", in1, in2, sbuf);
4572        fprintf(file, "%s", func[mv_func]);
4573        sprintf(ripplenet, "%s", sbuf);
4574        break;
4575    case BplusExpr:  case BminusExpr:
4576    case BltExpr:  case BleExpr:  case BgtExpr:  case BgeExpr:
4577        mv_func = EXPR_TO_BLIF_FUNC(type);
4578        fprintf(file, ".names %s %s %s %s\n",
4579                in1, in2,
4580                (auxin)?auxin:WRT_BLIF_GND(file), (out)?out:new_termname());
4581        fprintf(file, "%s", func[mv_func]);
4582        if (!forbidden_ripple) {
4583            sprintf(sbuf, "%s", new_termname());
4584            fprintf(file, "%s carry/borrow\n", HSIS_COMMENT);
4585            fprintf(file, ".names %s %s %s %s\n",
4586                    in1, in2, (auxin)?auxin:WRT_BLIF_GND(file), sbuf);
4587            fprintf(file, "%s", func[mv_func+1]);
4588            sprintf(ripplenet, "%s", sbuf);
4589        }
4590        break;
4591    }
4592
4593    return ripplenet;
4594}
4595
4596
4597static void vl_write_vector_red_op(FILE *file, short type,
4598                                   vl_term *in, int inverted,
4599                                   vl_term *out)
4600{
4601    int i;
4602    char rip_buf[MAXSTRLEN], in1[MAXSTRLEN], in2[MAXSTRLEN];
4603
4604    if (in->lo == in->hi) {
4605        if (out->lo > out->hi) {
4606            sprintf(in1, "%s%s%d%s", in->name->name,
4607                    SEP_LBITSELECT, in->lo, SEP_RBITSELECT);
4608            sprintf(in2, "%s", out->name->name);
4609            vl_write_bit_connect(file, in1, in2, inverted);
4610            return;
4611        } else {
4612            sprintf(in1, "%s%s%d%s", in->name->name,
4613                    SEP_LBITSELECT, in->lo, SEP_RBITSELECT);
4614            sprintf(in2, "%s%s%d%s", out->name->name,
4615                    SEP_LBITSELECT, in->lo, SEP_RBITSELECT);
4616            vl_write_bit_connect(file, in1, in2, inverted);
4617            return;
4618        }
4619    }
4620
4621    sprintf(rip_buf, "%s", new_termname());
4622    sprintf(in1, "%s%s%d%s", in->name->name,
4623            SEP_LBITSELECT, in->lo, SEP_RBITSELECT);
4624    sprintf(in2, "%s%s%d%s", in->name->name,
4625            SEP_LBITSELECT, in->lo+1, SEP_RBITSELECT);
4626    strcpy(rip_buf,
4627           vl_write_bop(file, type, in1, in2, NIL(char), NIL(char), 1));
4628
4629    for (i=in->lo+2; i<=in->hi; i++) {
4630        strcpy(in1, rip_buf);
4631        sprintf(in2, "%s%s%d%s", in->name->name,
4632                SEP_LBITSELECT, i, SEP_RBITSELECT);
4633        strcpy(rip_buf,
4634               vl_write_bop(file, type, in1, in2, NIL(char), NIL(char), 1));
4635    }
4636
4637    vl_write_bit_connect(file, rip_buf, out->name->name, inverted);
4638}
4639
4640
4641
4642void vl_write_bit_connect(FILE *file, char *in, char *out, int inverted)
4643{
4644    char **func;
4645
4646    func = (set_notation)?set_log_function:log_function;
4647    fprintf(file, ".names %s %s\n", in, out);
4648
4649    if (set_notation) {
4650        if (!inverted)
4651            fprintf(file, "- %s%s\n", HSIS_EQUAL, in);
4652        else
4653            fprintf(file, "%s", func[BLIF_NOT]);
4654    } else {
4655        if (!inverted)
4656            fprintf(file, "%s", func[BLIF_BITCONNECT]);
4657        else
4658            fprintf(file, "%s", func[BLIF_NOT]);
4659    }
4660}
4661
4662void write_comparator(FILE *file, vl_term *in1, vl_term *in2, vl_term *out)
4663{
4664    if ((in1->flag&MVar) == (in2->flag&MVar)) {
4665        if (in1->flag & MVar) {
4666            vl_write_mv_comp(file, (short)Beq2Expr, in1, in2, out);
4667        } else {
4668            vl_write_bin_comp(file, (short)Beq2Expr, in1, in2, out);
4669        }
4670    } else if (in1->flag & MVar) {
4671        vl_mv_to_bin(in1);
4672        vl_write_bin_comp(file, (short)Beq2Expr, in1, in2, out);
4673    } else if (in1->flag & MVar) {
4674        vl_mv_to_bin(in2);
4675        vl_write_bin_comp(file, (short)Beq2Expr, in1, in2, out);
4676   }
4677}
4678
4679
4680vl_term *instantiate_function(FILE *file, vl_function *master, lsList args, st_table *vars)
4681{
4682    vl_port_connect *i_port;
4683    vl_term *retval;
4684    int hi, lo, temp;
4685    int constConnection;
4686    lsGen mast_gen, inst_gen, gen;
4687    lsHandle mast_handle, inst_handle, handle;
4688    vl_id_range *m;
4689    vl_expr *i;
4690    const_term *ct;
4691    vl_enumerator *enum_elt;
4692    lsList input_consts;
4693
4694    i_port = vl_create_port_connect(ModuleConnect,
4695                                    NIL(vl_id_range), NIL(vl_expr));
4696    input_consts = lsCreate();
4697
4698    if (lsLength(args)!=0 && lsLength(master->ports)!=0) {
4699        mast_gen = lsStart(master->ports);
4700        inst_gen = lsStart(args);
4701        lsNext(mast_gen, (lsGeneric*)&m, &mast_handle);
4702
4703        while (lsNext(inst_gen, (lsGeneric*)&i, &inst_handle) != LS_NOMORE &&
4704               lsNext(mast_gen, (lsGeneric*)&m, &mast_handle) != LS_NOMORE) {
4705            if (!st_lookup(master->sig_st, m->name, (char**)&m)) {
4706                char buf[MAXSTRLEN];
4707
4708                sprintf(buf, "port '%s' is not defined in module '%s'",
4709                        m->name, master->name->name);
4710                semantic_error(buf);
4711            }
4712
4713            vl_write_expr(file, i, vars);
4714        }
4715        lsFinish(inst_gen);
4716        lsFinish(mast_gen);
4717    }
4718
4719
4720    if (master->range) {
4721        lo = vl_eval_expr(master->range->left);
4722        hi = vl_eval_expr(master->range->right);
4723        if (hi < lo) {
4724            temp = hi;
4725            hi = lo;
4726            lo = temp;
4727        }
4728    } else {
4729        lo = 0;
4730        hi = -1;
4731    }
4732    retval = new_term(NIL(vl_range), lo, hi);
4733    write_var_decl(file, retval);
4734
4735    fprintf(file, ".subckt %s %s ", master->name->name, new_termname());
4736
4737    if (lsLength(args)!=0 && lsLength(master->ports)!=0) {
4738        mast_gen = lsStart(master->ports);
4739        inst_gen = lsStart(args);
4740        lsNext(mast_gen, (lsGeneric*)&m, &mast_handle);
4741        if (lo > hi) {
4742
4743            put_bin_scalar_func_connect(file, m, retval);
4744        } else {
4745
4746            put_bin_vector_func_connect(file, m, retval);
4747        }
4748        while (lsNext(inst_gen, (lsGeneric*)&i, &inst_handle) != LS_NOMORE &&
4749               lsNext(mast_gen, (lsGeneric*)&m, &mast_handle) != LS_NOMORE) {
4750
4751            constConnection = 0;
4752            if (!i) {
4753                constConnection = 1;
4754            } else if (!i->term) {
4755                constConnection = 1;
4756            } else {
4757                if (m->id_type) {
4758                    if (i->type == IDExpr &&
4759                        st_lookup(m->id_type->specifier->
4760                                    u.enum_type->domain_st,
4761                                  i->u.name->name,
4762                                  (char**)&enum_elt))
4763                        constConnection = 1;
4764                }
4765            }
4766
4767            i_port->expr = i;
4768
4769            if (constConnection) {
4770
4771                put_const_port_connect(file, NIL(char),
4772                                       m, i_port, input_consts, retval);
4773                continue;
4774            }
4775
4776            if (m->flags & MVar) {
4777
4778                put_mvar_port_connect(file, NIL(char), m, i_port);
4779            } else {
4780                get_hilo(m, &hi, &lo);
4781                if (lo > hi) {
4782
4783                    put_bin_scalar_port_connect(file, NIL(char), m, i_port);
4784                } else {
4785
4786                    put_bin_vector_port_connect(file, NIL(char), m, i_port);
4787                }
4788            }
4789        }
4790        lsFinish(inst_gen);
4791        lsFinish(mast_gen);
4792
4793        fprintf(file, "\n");
4794
4795        gen = lsStart(input_consts);
4796        while(lsNext(gen, (lsGeneric*)&ct, &handle) != LS_NOMORE) {
4797            if (!isOutPort(ct->term->flag))
4798                write_var_decl(file, ct->term);
4799                vl_write_const(file, ct->const_expr, ct->term);
4800        }
4801        lsFinish(gen);
4802
4803        lsDestroy(input_consts, 0);
4804    }
4805
4806    return retval;
4807}
4808
4809
4810void connect_func_output(FILE *file, vl_id_range *out_id_sym, st_table *vars)
4811{
4812    vl_id_range *orig_id_sym;
4813    var_info *var;
4814    int hi, lo;
4815    int old_flags;
4816    int retval;
4817
4818    if (!st_lookup(vars, out_id_sym->name, (char**)&var)) {
4819        char buf[MAXSTRLEN];
4820        sprintf(buf, "function %s has no return value", out_id_sym->name);
4821        yylineno = -1;
4822        compile_error(buf);
4823    }
4824
4825    retval = st_lookup(vl_currentFunction->sig_st, out_id_sym->name,
4826                       (char**)&orig_id_sym);
4827    assert(retval);
4828    get_hilo(orig_id_sym, &hi, &lo);
4829    old_flags = orig_id_sym->flags;
4830    orig_id_sym->flags &= ~RegVar;
4831
4832
4833    if (var->current_terminal->flag & MVar) {
4834        instantiate_mvar_latch(file, 0, 0, lo, hi,
4835                               out_id_sym, orig_id_sym, var,
4836                               orig_id_sym->name);
4837    } else {
4838        if (lo > hi) {
4839            instantiate_bin_scalar_latch(file, 0, 0,
4840                                         out_id_sym, orig_id_sym, var,
4841                                         orig_id_sym->name);
4842        } else {
4843            instantiate_bin_vector_latch(file, 0, 0, lo, hi,
4844                                         out_id_sym, orig_id_sym, var,
4845                                         orig_id_sym->name);
4846        }
4847    }
4848
4849    orig_id_sym->flags = old_flags;
4850}
4851
4852
4853
4854void instantiate_latch(FILE *file, st_table *vars)
4855{
4856    vl_id_range *id_sym, *orig_id_sym;
4857    st_generator *gen;
4858    char *key, *ps_buf, *dummy;
4859    var_info *var, *lvar;
4860    blif_latch *latch;
4861    char latch_name[MAXSTRLEN];
4862    int lo, hi;
4863    int non_block_var;
4864
4865
4866    fprintf(file, "%s latches\n", HSIS_COMMENT);
4867    gen = st_init_gen(vars);
4868    while (st_gen(gen, &key, (char**)&var)) {
4869        sprintf(latch_name, "%s%s", key, SEP_LATCH);
4870        if (vl_currentModule->latch_st) {
4871            if (st_lookup(vl_currentModule->sig_st, key, (char**)&id_sym)) {
4872                if (!(id_sym->flags & RegVar)  &&
4873                    !str_matchtail(id_sym->name,SEP_LATCH))
4874                    continue;
4875                non_block_var = str_matchtail(id_sym->name,SEP_LATCH);
4876
4877                if (st_lookup(vl_currentModule->latch_st, key, (char**)&latch))
4878                    if (latch->flags & NBASSIGN_IN_ALWAYS)
4879                        continue;
4880
4881                if (dflow_analysis &&
4882                    !(id_sym->flags & OutPort) && !(id_sym->flags & InPort) &&
4883                    !(str_matchtail(id_sym->name,SEP_LATCH)) &&
4884                    !set_find(id_sym->name, vl_currentModule->uninit_set))
4885                    continue;
4886
4887                if (!st_lookup(vars, latch_name, (char**)&lvar)) lvar = var;
4888
4889                get_hilo(var->id, &hi, &lo);
4890
4891                ps_buf = vlStrdup(var->id->name);
4892                if (str_matchtail(id_sym->name,SEP_LATCH)) {
4893                    strip_char(ps_buf,SEP_LATCH);
4894                    st_lookup(vl_currentModule->sig_st,
4895                              ps_buf, (char**)&orig_id_sym);
4896                } else {
4897                    orig_id_sym = id_sym;
4898                }
4899
4900
4901                if (st_lookup(vl_currentModule->quasi_st,
4902                              ps_buf, (char**)&dummy)){
4903                    char *old_termname;
4904                    char *dc;
4905                    int n_entries;
4906                    char qbuf[MAXSTRLEN];
4907                    vl_id_range *qid_sym;
4908                    int retval;
4909                    sprintf(qbuf, "%s%s", ps_buf, SEP_QUASI);
4910                    retval = st_lookup(vl_currentModule->sig_st,
4911                                       qbuf, (char**)&qid_sym);
4912                    assert(retval);
4913                    old_termname = lvar->current_terminal->name->name;
4914                    dc = check_dc((!rst_ckt)?qid_sym->syndrome_expr_list:
4915                                  qid_sym->rst_syndrome_expr_list);
4916                    n_entries = lsLength((!rst_ckt)?
4917                                         qid_sym->syndrome_expr_list:
4918                                         qid_sym->rst_syndrome_expr_list);
4919
4920                    lvar->current_terminal->name->name =
4921                        vlStrdup(new_termname());
4922                    write_var_decl(file, lvar->current_terminal);
4923                    put_quasi_table(file, dc, ps_buf, old_termname,
4924                                    qid_sym, lvar->current_terminal,
4925                                    lo, hi, n_entries);
4926                    vl_chk_free(old_termname);
4927                    vl_chk_free(dc);
4928                }
4929
4930
4931                if (!use_rst_ckt && (orig_id_sym->flags  & RegVar)) {
4932
4933                    if ((lsLength(id_sym->initial)==0) && Warn_Uninitialized) {
4934                        char buf[MAXSTRLEN];
4935                        sprintf(buf, "%s:%s: uninitialized",
4936                                vl_currentModule->name->name, id_sym->name);
4937                        Translate_Notice(buf);
4938                    }
4939
4940                    if ((orig_id_sym->flags) & MVar) {
4941
4942                        reset_mvar_latch(file, non_block_var,
4943                                               id_sym, lo, hi, ps_buf);
4944                    } else {
4945
4946                        if (lo > hi) {
4947
4948                            reset_bin_scalar_latch(file, non_block_var,
4949                                                   id_sym, ps_buf);
4950                        } else {
4951
4952                            reset_bin_vector_latch(file, non_block_var,
4953                                                   id_sym, lo, hi, ps_buf);
4954                        }
4955                    }
4956                } else {
4957
4958                    if (lsLength(id_sym->initial)>0 &&
4959                        get_decl_flags(var->id->mpg_master_exp) & RegVar) {
4960
4961
4962
4963                        instantiate_reset_mux(file, id_sym, lo, hi, var, lvar);
4964                    }
4965                }
4966
4967
4968                if (var->current_terminal->flag & MVar) {
4969                    instantiate_mvar_latch(file, non_block_var, mark_sel_var,
4970                                           lo, hi,
4971                                           id_sym, orig_id_sym, lvar, ps_buf);
4972                } else {
4973                    if (lo > hi) {
4974                        instantiate_bin_scalar_latch(file,
4975                            non_block_var, mark_sel_var,
4976                            id_sym, orig_id_sym, lvar, ps_buf);
4977                    } else {
4978                        instantiate_bin_vector_latch(file,
4979                            non_block_var, mark_sel_var, lo, hi,
4980                            id_sym, orig_id_sym, lvar, ps_buf);
4981                    }
4982                }
4983                vl_chk_free(ps_buf);
4984            }
4985        }
4986    }
4987    st_free_gen(gen);
4988
4989
4990    gen = st_init_gen(vl_currentModule->sig_st);
4991    while (st_gen(gen, &key, (char**)&id_sym)) {
4992        instantiate_input_latch(file, id_sym);
4993        if (wireRegister)
4994            instantiate_hidden_latch(file, id_sym);
4995    }
4996    st_free_gen(gen);
4997}
4998
4999
5000static void instantiate_prim_latch(FILE *file, st_table *sig_st)
5001{
5002    st_generator *sig_gen;
5003    vl_id_range *id_sym;
5004    char *key;
5005
5006    sig_gen = st_init_gen(sig_st);
5007    while (st_gen(sig_gen, (char**)&key, (char**)&id_sym)) {
5008        if (!(id_sym->flags & RegVar)) continue;
5009
5010        fprintf(file, ".latch %s%s %s\n",
5011                id_sym->name, SEP_LATCH, id_sym->name);
5012        fprintf(file, ".r %s\n-\n", id_sym->name);
5013    }
5014    st_free_gen(sig_gen);
5015}
5016
5017
5018static void instantiate_edge_detector(FILE *file, vl_primitive *prim)
5019{
5020    lsGen port_gen;
5021    lsHandle port_handle, port_id_handle;
5022    vl_port *port;
5023    vl_id_range *port_id, *port_id_sym;
5024
5025    port_gen = lsStart(prim->ports);
5026    while (lsNext(port_gen, (lsGeneric*)&port, &port_handle) != LS_NOMORE) {
5027        int retval;
5028        lsFirstItem(port->port_exp, (lsGeneric*)&port_id, &port_id_handle);
5029        retval = st_lookup(prim->sig_st, port_id->name, (char**)&port_id_sym);
5030        assert(retval);
5031
5032        if (port_id_sym->flags & EdgeDetector) {
5033            fprintf(file, ".latch %s %s%s\n",
5034                    port_id_sym->name, port_id_sym->name, PIN_DELAYED);
5035            fprintf(file, ".r %s%s\n-\n", port_id_sym->name, PIN_DELAYED);
5036        }
5037    }
5038    lsFinish(port_gen);
5039}
5040
5041
5042static char *lib_fun[][2] = {
5043    {"vlr_mux", " %s a=%s b=%s s=%s o=%s\n"}
5044    };
5045
5046
5047void vl_put_lib(FILE *file, ...)
5048{
5049    char buf[MAXSTRLEN];
5050    char typ_buf[MAXSTRLEN];
5051    char *cp, *tcp;
5052    int code;
5053    va_list args;
5054    vl_term *type_term;
5055    void *decl;
5056    lsList domain;
5057    lsGen enum_gen;
5058    lsHandle enum_handle;
5059    vl_enumerator *enum_elt;
5060
5061    va_start(args, file);
5062    code = va_arg(args, int);
5063    type_term = va_arg(args, vl_term*);
5064
5065    cp = buf; *cp = '\0';
5066    cp = strappendS(cp, ".subckt");
5067    cp = strappend(cp, lib_fun[code][0]);
5068
5069    tcp = typ_buf; *tcp = '\0';
5070    tcp = strappend(tcp, SEP_LTRANGE);
5071
5072    if (type_term->flag & MVar) {
5073        (void) va_arg(args, char*);
5074        (void)vfprintf(file, ".names %s %s %s %s\n", args);
5075        if (!st_lookup(mod_list->decl_st,
5076                       (char*)type_term->term_type, (char**)&decl)) {
5077            st_insert(mod_list->decl_st,
5078                      (char*)type_term->term_type,
5079                      (char*)type_term->term_type);
5080        }
5081        domain = type_term->term_type->specifier->u.enum_type->domain_list;
5082        for (enum_gen=lsStart(domain);
5083             lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=
5084                 LS_NOMORE;) {
5085            fprintf(file, "%s - 1 %s\n", enum_elt->name, enum_elt->name);
5086            fprintf(file, "- %s 0 %s\n", enum_elt->name, enum_elt->name);
5087        }
5088        lsFinish(enum_gen);
5089    } else {
5090        char *tbuf, *fbuf, *selbuf, *obuf;
5091        (void) va_arg(args, char*);
5092        tbuf = va_arg(args, char *);
5093        fbuf = va_arg(args, char *);
5094        selbuf = va_arg(args, char *);
5095        obuf = va_arg(args, char *);
5096        fprintf(file, ".names %s %s %s %s\n.def 0\n",
5097                selbuf, tbuf, fbuf, obuf);
5098        fprintf(file, "1 1 - 1\n0 - 1 1\n");
5099    }
5100    va_end(args);
5101}
5102
5103
5104void vl_write_mv_lib(FILE *file, short type, vl_term *in1, vl_term *in2, vl_term *out)
5105{
5106    int i;
5107    lsList domain;
5108    lsGen enum_gen;
5109    lsHandle enum_handle;
5110    vl_enumerator *enum_elt;
5111
5112    fprintf(file, ".subckt ");
5113    switch(type) {
5114    case BandExpr: fprintf(file, "%s", BLIF_LIB_AND); break;
5115    case BorExpr:  fprintf(file, "%s", BLIF_LIB_OR); break;
5116    case BxorExpr: fprintf(file, "%s", BLIF_LIB_XOR); break;
5117    case BxnorExpr:fprintf(file, "%s", BLIF_LIB_XNOR); break;
5118    case BplusExpr: fprintf(file, "%s", BLIF_LIB_ADD); break;
5119    case BminusExpr:fprintf(file, "%s", BLIF_LIB_SUB); break;
5120    case UandExpr:  case UnandExpr:
5121    case UorExpr:  case UnorExpr:
5122    case UxorExpr:    case UxnorExpr: break;
5123    }
5124    if (in1->term_type != in2->term_type) {
5125        char buf[MAXSTRLEN];
5126        sprintf(buf,"operation between var %s & %s of different types",
5127                in1->name->name, in2->name->name);
5128        semantic_error(buf);
5129    }
5130
5131    domain = in1->term_type->specifier->u.enum_type->domain_list;
5132
5133    fprintf(file, "%s", SEP_LTRANGE);
5134    for (enum_gen=lsStart(domain), i=1;
5135         lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE;
5136         i++)
5137        fprintf(file, "%s%c", enum_elt->name, (i==lsLength(domain)?'\0':':'));
5138    fprintf(file, "%s", SEP_RTRANGE);
5139    fprintf(file, " %s %s %s %s\n", new_termname(),
5140            in1->name->name, in2->name->name, out->name->name);
5141}
5142
5143
5144st_table *conflict_arbitrator(FILE *file, array_t *vars_array)
5145{
5146    st_generator *gen;
5147    st_table *vars, *retval;
5148    char *key;
5149    var_info *cur_var;
5150    array_t *controls;
5151    vl_term *ctrl_i;
5152    int lo, hi;
5153    int num_changer;
5154    int i;
5155    vl_id_range *id_sym, *temp_id_sym;
5156
5157    fprintf(file,"%s conflict arbitrators\n", HSIS_COMMENT);
5158    retval = st_init_table(strcmp, st_strhash);
5159
5160    gen = st_init_gen(vl_currentModule->sig_st);
5161    while (st_gen(gen, &key, (char**)&id_sym)) {
5162
5163        if ((id_sym->flags & InPort) && !(id_sym->flags & OutPort)) continue;
5164
5165        if (!vl_currentPrimitive && !vl_currentFunction) {
5166            if (strstr(key,SEP_LATCH))
5167                continue;
5168            if (strstr(key,SEP_QUASI))
5169                continue;
5170        }
5171
5172        if (!vl_currentPrimitive && !vl_currentFunction)
5173            if (dflow_analysis &&
5174                !(id_sym->flags & OutPort) && !(id_sym->flags & InPort) &&
5175                !(str_matchtail(id_sym->name,SEP_LATCH)) &&
5176                !set_find(id_sym->name, vl_currentModule->uninit_set))
5177                continue;
5178
5179        if (!(id_sym->flags & RegVar) &&
5180            !str_matchtail(id_sym->name,SEP_LATCH)) {
5181            create_wire_nondeterminism(file, key, id_sym, vars_array);
5182            continue;
5183        }
5184
5185        if (!vl_currentPrimitive && !vl_currentFunction)
5186            if (vl_currentModule->combVar_st) {
5187                if (st_lookup(vl_currentModule->combVar_st,
5188                              id_sym->name, (char**)&temp_id_sym) &&
5189                    !st_lookup(vl_currentModule->seqVar_st,
5190                               id_sym->name, (char**)&temp_id_sym)){
5191                    create_wire_nondeterminism(file, key, id_sym, vars_array);
5192                    continue;
5193                }
5194            }
5195
5196        controls = array_alloc(vl_term*, 0);
5197
5198        num_changer = 0;
5199        for (i=0; i<array_n(vars_array); i++) {
5200            vars = array_fetch(st_table*, vars_array, i);
5201            if (vars) {
5202                if (st_lookup(vars, key, (char**)&cur_var)) {
5203                    ctrl_i = syndrome_to_control(file, key, vars);
5204                    array_insert_last(vl_term*, controls, ctrl_i);
5205                    num_changer++;
5206                    continue;
5207                }
5208            }
5209            array_insert_last(vl_term*, controls, NIL(vl_term));
5210        }
5211
5212        assert(array_n(vars_array) == array_n(controls));
5213        get_hilo(id_sym, &hi, &lo);
5214        if (id_sym->flags &MVar) {
5215
5216            create_mvar_nondeterminism(file, retval, key, id_sym, lo, hi,
5217                                       controls, vars_array);
5218        } else {
5219
5220            if (lo > hi) {
5221
5222                create_bin_scalar_nondeterminism(file, retval, key, id_sym,
5223                                                 controls, vars_array);
5224            } else {
5225
5226                create_bin_vector_nondeterminism(file, retval, key, id_sym,
5227                                                 lo, hi, controls, vars_array);
5228            }
5229        }
5230
5231    }
5232    st_free_gen(gen);
5233
5234    return retval;
5235}
5236
5237
5238st_table *func_conflict_arbitrator(FILE *file, vl_id_range *out_id_sym, array_t *vars_array)
5239{
5240    st_generator *gen;
5241    st_table *retval;
5242    char *key;
5243    int old_flags;
5244    vl_id_range *id_sym, *temp_id_sym;
5245    blif_latch *latch;
5246
5247    fprintf(file,"%s conflict arbitrators\n", HSIS_COMMENT);
5248    retval = st_init_table(strcmp, st_strhash);
5249
5250    gen = st_init_gen(vl_currentModule->sig_st);
5251    while (st_gen(gen, &key, (char**)&id_sym)) {
5252
5253        if (id_sym->flags & InPort) continue;
5254
5255        if (!vl_currentPrimitive && !vl_currentFunction)
5256            if (st_lookup(vl_currentModule->latch_st, key, (char**)&latch) ||
5257                strstr(key,SEP_LATCH)) continue;
5258
5259        if (!vl_currentPrimitive && !vl_currentFunction)
5260            if (dflow_analysis &&
5261                !(id_sym->flags & OutPort) && !(id_sym->flags & InPort) &&
5262                !(str_matchtail(id_sym->name,SEP_LATCH)) &&
5263                !set_find(id_sym->name, vl_currentModule->uninit_set))
5264                continue;
5265
5266        if (!(id_sym->flags & RegVar) &&
5267            !str_matchtail(id_sym->name,SEP_LATCH)) {
5268            create_wire_nondeterminism(file, key, id_sym, vars_array);
5269            continue;
5270        }
5271
5272        if (!vl_currentPrimitive && !vl_currentFunction)
5273            if (vl_currentModule->combVar_st) {
5274                if (st_lookup(vl_currentModule->combVar_st,
5275                              id_sym->name, (char**)&temp_id_sym)){
5276                    create_wire_nondeterminism(file, key, id_sym, vars_array);
5277                    continue;
5278                }
5279            }
5280
5281        if (vl_currentFunction && strcmp(out_id_sym->name, key))
5282            continue;
5283        else {
5284            old_flags = id_sym->flags;
5285            id_sym->flags &= ~RegVar;
5286
5287            create_wire_nondeterminism(file, key, id_sym, vars_array);
5288
5289            id_sym->flags = old_flags;
5290        }
5291    }
5292    st_free_gen(gen);
5293
5294    return retval;
5295}
5296
5297static void vl_write_initial_generator(FILE *file)
5298{
5299    char buf[MAXSTRLEN];
5300
5301
5302    if (ith_module!=0) return;
5303
5304
5305    if (!use_rst_ckt) return;
5306
5307    sprintf(buf, "%s%s", Initial_Signal->name->name, "_PS");
5308    fprintf(file, ".r %s\n1\n", Initial_Signal->name->name);
5309    fprintf(file, ".names %s\n", buf);
5310    fprintf(file, "0\n");
5311    fprintf(file, ".latch %s %s\n", buf, Initial_Signal->name->name);
5312}
5313
5314
5315static void vl_write_encoding(FILE *file)
5316{
5317    st_generator *id_gen, *symbolic_gen;
5318    char *key, *symbolic_value, *code;
5319    vl_id_range *id_sym;
5320    int hi, lo, v;
5321    int idx, idx_lo, idx_hi;
5322    int i;
5323
5324    if (!do_encoding) return;
5325
5326    id_gen = st_init_gen(vl_currentModule->sig_st);
5327    while (st_gen(id_gen, &key, (char**)&id_sym)) {
5328        if (id_sym->symbolic_values) {
5329            if (!st_count(id_sym->symbolic_values)) continue;
5330            if (!(id_sym->flags & MVar)) {
5331                get_hilo(id_sym, &hi, &lo);
5332                if (lo < hi) {
5333                    if (!id_sym->range) {
5334                        fprintf(file, ".encode ");
5335                        for (i=lo; i<=hi; i++)
5336                            fprintf(file, "%s%s%d%s ", id_sym->name,
5337                                    SEP_LBITSELECT, i, SEP_RBITSELECT);
5338                        fprintf(file, "%s\n", id_sym->name);
5339                        symbolic_gen = st_init_gen(id_sym->symbolic_values);
5340                        while (st_gen(symbolic_gen, &symbolic_value, &code)) {
5341                            for (i=lo, v=atoi(code); i<=hi; i++, v >>= 1)
5342                                fprintf(file, "%d ", v&1);
5343                            fprintf(file, "%s\n", symbolic_value);
5344                        }
5345                        st_free_gen(symbolic_gen);
5346                        fprintf(file, ".endcode\n\n");
5347                    } else {
5348                        idx_lo = vl_eval_expr(id_sym->range->left);
5349                        if (id_sym->range->right)
5350                            idx_hi = vl_eval_expr(id_sym->range->right);
5351                        else
5352                            idx_hi = idx_lo;
5353
5354                        for (idx=idx_lo; idx<=idx_hi; idx++) {
5355                            fprintf(file, ".encode ");
5356                            for (i=lo; i<=hi; i++)
5357                                fprintf(file, "%s%s%d%s%s%d%s ", id_sym->name,
5358                                        SEP_LARRAY, idx, SEP_RARRAY,
5359                                        SEP_LBITSELECT, i, SEP_RBITSELECT);
5360                            fprintf(file, "%s%s%d%s\n",
5361                                    id_sym->name, SEP_LARRAY, idx, SEP_RARRAY);
5362                            symbolic_gen =
5363                                st_init_gen(id_sym->symbolic_values);
5364                            while (st_gen(symbolic_gen,
5365                                          &symbolic_value, &code)) {
5366                                for (i=lo, v=atoi(code); i<=hi; i++, v >>= 1)
5367                                    fprintf(file, "%d ", v&1);
5368                                fprintf(file, "%s\n", symbolic_value);
5369                            }
5370                            st_free_gen(symbolic_gen);
5371                            fprintf(file, ".endcode\n\n");
5372                        }
5373                    }
5374                }
5375            }
5376        }
5377    }
5378    st_free_gen(id_gen);
5379}
5380
5381static void non_block_assignment(FILE *file, st_table *vars)
5382{
5383    st_generator *gen;
5384    lsList ripple=(lsList)0;
5385    char *key;
5386    char latch_name[MAXSTRLEN];
5387    char *dc;
5388    vl_id_range *id_sym, *orig_id_sym;
5389    var_info *id_var;
5390    vl_term *out_term;
5391    vl_term *procedural_ctrl, *procedural_term;
5392    int n_entries, hi, lo;
5393    int non_block_wire = 0;
5394
5395    fprintf(file, "%s non-blocking assignments %s\n",
5396            HSIS_COMMENT, (rst_ckt)?"for initial":"");
5397    gen = st_init_gen(vl_currentModule->sig_st);
5398    while (st_gen(gen, &key, (char**)&id_sym)) {
5399        non_block_wire = 0;
5400        ripple = (lsList)0;
5401        procedural_ctrl = NIL(vl_term);
5402        procedural_term = NIL(vl_term);
5403        if (!strstr(key,SEP_LATCH)) continue;
5404
5405        if (!rst_ckt && lsLength(id_sym->syndrome_expr_list)==0) continue;
5406        if (rst_ckt && lsLength(id_sym->rst_syndrome_expr_list)==0) continue;
5407
5408
5409        strcpy(latch_name, id_sym->name);
5410        strip_char(latch_name, SEP_LATCH);
5411
5412        if (rst_ckt &&
5413            !st_lookup(vars, latch_name, (char**)&id_var) &&
5414            !st_lookup(vars, key, (char**)&id_var)) continue;
5415
5416
5417        if (st_lookup(vars, latch_name, (char**)&id_var)) {
5418            if (id_var->extra) {
5419                procedural_ctrl = array_or(file, (array_t*)(id_var->extra));
5420                procedural_term = id_var->current_terminal;
5421                decomposeTable = 1;
5422            }
5423        }
5424
5425        if (st_lookup(vl_currentModule->sig_st,
5426                      latch_name, (char**)&orig_id_sym)) {
5427            vl_id_range *temp_id_sym;
5428
5429            if (!(orig_id_sym->flags&RegVar)) non_block_wire = 1;
5430
5431            if (vl_currentModule->combVar_st) {
5432                if (st_lookup(vl_currentModule->combVar_st,
5433                              latch_name, (char**)&temp_id_sym)) {
5434
5435                    non_block_wire = 1;
5436                }
5437            }
5438        }
5439        n_entries = lsLength((!rst_ckt)?
5440                             id_sym->syndrome_expr_list:
5441                             id_sym->rst_syndrome_expr_list);
5442        get_hilo(id_sym, &hi, &lo);
5443        out_term = new_term(id_sym->range, lo, hi);
5444        out_term->flag = id_sym->flags;
5445        out_term->term_type = id_sym->id_type;
5446        out_term->name->unintType = id_sym->unintType;
5447        write_var_decl(file, out_term);
5448
5449
5450        dc = check_dc((!rst_ckt)?id_sym->syndrome_expr_list:
5451                                 id_sym->rst_syndrome_expr_list);
5452
5453        if ((id_sym->flags & MVar) || (lo > hi)) {
5454
5455            if (!id_sym->range) {
5456                put_nblock_scalar_simple_table(file, dc, id_sym,
5457                    non_block_wire, latch_name, out_term,
5458                    n_entries, lo, hi, ripple,
5459                    procedural_ctrl, procedural_term);
5460            } else {
5461                put_nblock_scalar_array_table(file, dc, id_sym,
5462                                              non_block_wire,
5463                                              latch_name, out_term,
5464                                              n_entries, lo, hi, ripple);
5465            }
5466        } else {
5467
5468            put_nblock_vector_table(file, dc, id_sym,
5469                                    non_block_wire,
5470                                    latch_name, out_term,
5471                                    n_entries, lo, hi, &ripple,
5472                                    procedural_ctrl, procedural_term);
5473        }
5474
5475
5476        st_insert(vars, key,
5477                  (char*)create_var_info(vl_copy_id_range(id_sym), out_term));
5478
5479        vl_chk_free(dc);
5480    }
5481    st_free_gen(gen);
5482}
5483
5484
5485static void quasi_cont_assignment(FILE *file)
5486{
5487    st_generator *gen;
5488    char *key;
5489    vl_id_range *id_sym;
5490    char quasi_name[MAXSTRLEN];
5491    char sync_name[MAXSTRLEN];
5492    char *dc;
5493    int n_entries, hi, lo;
5494    vl_term *out_term;
5495
5496    fprintf(file, "%s quasi-continuous assignment\n", HSIS_COMMENT);
5497
5498    gen = st_init_gen(vl_currentModule->sig_st);
5499    while (st_gen(gen, &key, (char**)&id_sym)) {
5500        if (!strstr(key,SEP_QUASI)) continue;
5501        if (!rst_ckt && lsLength(id_sym->syndrome_expr_list) == 0) continue;
5502        if (rst_ckt && lsLength(id_sym->rst_syndrome_expr_list) == 0) continue;
5503
5504        strcpy(quasi_name, id_sym->name);
5505        strip_char(quasi_name, SEP_QUASI);
5506
5507        get_hilo(id_sym, &hi, &lo);
5508        out_term = new_term(id_sym->range, lo, hi);
5509        out_term->flag = id_sym->flags;
5510        out_term->term_type = id_sym->id_type;
5511        vl_chk_free(out_term->name->name);
5512        out_term->name->name = strip_char(vlStrdup(id_sym->name),SEP_QUASI);
5513
5514
5515
5516        dc = check_dc((!rst_ckt)?id_sym->syndrome_expr_list:
5517                                 id_sym->rst_syndrome_expr_list);
5518
5519        n_entries = lsLength((!rst_ckt)?
5520                             id_sym->syndrome_expr_list:
5521                             id_sym->rst_syndrome_expr_list);
5522
5523        sprintf(sync_name, "%s%s%s", quasi_name, SEP_GATEPIN, PIN_PS);
5524
5525        put_quasi_table(file, dc, quasi_name, sync_name, id_sym, out_term,
5526                        lo, hi, n_entries);
5527
5528        vl_chk_free(dc);
5529    }
5530    st_free_gen(gen);
5531}
5532
5533
5534static void vl_prioritize_sequence(FILE *file, lsList vars_list,
5535                                   lsList pause_list,
5536                                   st_table *result_st)
5537{
5538    st_generator *vars_gen;
5539    lsGen gen, pause_gen, pt_gen;
5540    lsHandle handle, pause_handle, pt_handle;
5541    lsList pt_list;
5542    vl_id_range *id_sym;
5543    char *key;
5544    st_table *new_vars, *pause_set;
5545    st_table *t_set, *i_set;
5546    var_info *id_var_info;
5547    int touched;
5548    vl_term *pause_term, *new_term;
5549    int hi, lo, i, j, k;
5550    int bit, idx;
5551    int table_width=0;
5552    int t_dup=0, val;
5553    char header_buf[MAXSTRLEN], buf[MAXSTRLEN], var_buf[MAXSTRLEN];
5554    char *t_name;
5555
5556    assert(lsLength(vars_list) == lsLength(pause_list));
5557
5558    if (lsLength(vars_list) == 0) return;
5559
5560    fprintf(file, "%s sequence prioritizer\n", HSIS_COMMENT);
5561
5562    vars_gen = st_init_gen(vl_currentModule->sig_st);
5563    while (st_gen(vars_gen, &key, (char**)&id_sym)) {
5564        table_width = 0;
5565
5566        for (gen=lsStart(vars_list), touched = 0;
5567             lsNext(gen,(lsGeneric*)&new_vars,&handle) != LS_NOMORE; ) {
5568            if (st_lookup(new_vars, key, (char**)&id_var_info)) {
5569                touched = 1;
5570                break;
5571            }
5572        }
5573        (void)lsFinish(gen);
5574        if (!touched) continue;
5575
5576        get_hilo(id_sym, &hi, &lo);
5577        new_term = typed_new_term(id_sym->id_type, id_sym->range, lo, hi);
5578        new_term->flag |= (id_sym->flags & MVar) ? MVar : 0;
5579        write_var_decl(file, new_term);
5580
5581        t_set = st_init_table(strcmp, st_strhash);
5582        i_set = st_init_table(st_ptrcmp, st_ptrhash);
5583
5584        sprintf(header_buf, ".names ");
5585
5586        pt_list = lsCreate();
5587        for (gen=lsStart(vars_list), pause_gen=lsStart(pause_list), i=0;
5588             lsNext(gen,(lsGeneric*)&new_vars,&handle) != LS_NOMORE&&
5589             lsNext(pause_gen,(lsGeneric*)&pause_set,&pause_handle) !=
5590             LS_NOMORE; ) {
5591            if (st_lookup(new_vars, key, (char**)&id_var_info)) {
5592                table_width++;
5593
5594                pause_term = fg_write_lc_in_LabelSet(file, pause_set, 1);
5595                lsNewEnd(pt_list, (lsGeneric)pause_term, 0);
5596
5597
5598                t_dup=0;
5599                if (st_lookup(t_set,
5600                              id_var_info->current_terminal->name->name,
5601                              &t_name)) {
5602                    st_insert(i_set, (char*)i, 0);
5603                    t_dup=1;
5604                } else {
5605                    st_insert(t_set,
5606                              id_var_info->current_terminal->name->name,
5607                              0);
5608                }
5609                i++;
5610
5611                new_term->flag |= id_var_info->current_terminal->flag;
5612            }
5613        }
5614        (void)lsFinish(gen);
5615        (void)lsFinish(pause_gen);
5616
5617        sprintf(var_buf, "%s", id_sym->name);
5618        strip_char(var_buf, SEP_LATCH);
5619        if (!id_sym->range) {
5620            if (lo > hi || id_sym->flags &MVar) {
5621                sprintf(buf, "%s\n", new_term->name->name);
5622                strcat(header_buf, buf);
5623                sprintf(buf, "%s -\n", HSIS_DEFAULT);
5624                strcat(header_buf, buf);
5625            } else {
5626                sprintf(buf, "%s ", HSIS_ARROW);
5627                strcat(header_buf, buf);
5628                for (bit=lo; bit<=hi; bit++) {
5629                    sprintf(buf, "%s%s%d%s ",
5630                            new_term->name->name,
5631                            SEP_LBITSELECT, bit, SEP_RBITSELECT);
5632                    strcat(header_buf, buf);
5633                }
5634                strcat(header_buf, "\n");
5635                sprintf(buf, "%s ", HSIS_DEFAULT);
5636                strcat(header_buf, buf);
5637                for (bit=lo; bit<=hi; bit++) {
5638                    sprintf(buf, "- ");
5639                    strcat(header_buf, buf);
5640                }
5641                strcat(header_buf, "\n");
5642            }
5643        } else {
5644            int idx_hi, idx_lo;
5645            idx_lo = vl_eval_expr(id_sym->range->left);
5646            if (id_sym->range->right)
5647                idx_hi = vl_eval_expr(id_sym->range->right);
5648            else
5649                idx_hi = idx_lo;
5650
5651            sprintf(buf, "%s ", HSIS_ARROW);
5652            strcat(header_buf, buf);
5653            for (idx=idx_lo; idx<=idx_hi; idx++) {
5654                if (lo > hi || id_sym->flags &MVar) {
5655                    sprintf(buf, "%s%s%d%s ",
5656                            new_term->name->name,
5657                            SEP_LARRAY, idx, SEP_RARRAY);
5658                    strcat(header_buf, buf);
5659                } else {
5660                    for (bit=lo; bit<=hi; bit++) {
5661                        sprintf(buf, "%s%s%d%s%s%d%s ",
5662                                new_term->name->name,
5663                                SEP_LARRAY, idx, SEP_RARRAY,
5664                                SEP_LBITSELECT, bit, SEP_RBITSELECT);
5665                        strcat(header_buf, buf);
5666                    }
5667                }
5668            }
5669            strcat(header_buf, "\n");
5670            sprintf(buf, "%s ", HSIS_DEFAULT);
5671            strcat(header_buf, buf);
5672            for (idx=idx_lo; idx<=idx_hi; idx++) {
5673                if (lo > hi || id_sym->flags & MVar) {
5674                    sprintf(buf, "- ");
5675                    strcat(header_buf, buf);
5676                } else {
5677                    for (bit=lo; bit<=hi; bit++) {
5678                        sprintf(buf, "- ");
5679                        strcat(header_buf, buf);
5680                    }
5681                }
5682            }
5683        }
5684
5685        fprintf(file, "%s", header_buf);
5686
5687        for (gen=lsStart(vars_list),
5688             pause_gen=lsStart(pause_list),
5689             pt_gen=lsStart(pt_list),
5690             i=0;
5691             lsNext(gen,(lsGeneric*)&new_vars,&handle) != LS_NOMORE&&
5692             lsNext(pause_gen,(lsGeneric*)&pause_set,&pause_handle) !=
5693                 LS_NOMORE; ) {
5694            if (st_lookup(new_vars, key, (char**)&id_var_info)) {
5695                int retval = lsNext(pt_gen,(lsGeneric*)&pause_term,&pt_handle);
5696                assert(retval != LS_NOMORE);
5697                if (!id_sym->range) {
5698
5699                    if (lo > hi || id_sym->flags & MVar) {
5700
5701                        for (j=0; j<i; j++)
5702                            if (st_lookup(i_set, (char*)j, (char**)&val))
5703                                fprintf(file, "- ");
5704                            else
5705                                fprintf(file, "- - ");
5706                        if (st_lookup(i_set, (char*)j, (char**)&val))
5707                            fprintf(file, "1 ");
5708                        else
5709                            fprintf(file, "1 - ");
5710                        j++;
5711                        for (; j<table_width; j++)
5712                            if (st_lookup(i_set, (char*)j, (char**)&val))
5713                                fprintf(file, "- ");
5714                            else
5715                                fprintf(file, "- - ");
5716                        fprintf(file, "%s%s\n", HSIS_EQUAL,
5717                                id_var_info->current_terminal->name->name);
5718                        i++;
5719                    } else {
5720
5721                        for (j=0; j<i; j++) {
5722                            fprintf(file, "- ");
5723                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5724                                for (k=lo; k<=hi; k++) fprintf(file, "- ");
5725                        }
5726                        fprintf(file, "1 ");
5727                        if (!st_lookup(i_set, (char*)j, (char**)&val))
5728                            for (k=lo; k<=hi; k++) fprintf(file, "- ");
5729                        j++;
5730                        for (; j<table_width; j++) {
5731                            fprintf(file, "- ");
5732                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5733                                for (k=lo; k<=hi; k++) fprintf(file, "- ");
5734                        }
5735                        for (k=lo; k<=hi; k++)
5736                            fprintf(file, "%s%s%s%d%s ", HSIS_EQUAL,
5737                                    id_var_info->
5738                                    current_terminal->name->name,
5739                                    SEP_LBITSELECT, k, SEP_RBITSELECT);
5740                        fprintf(file, "\n");
5741                        i++;
5742                    }
5743                } else {
5744
5745                    int idx_hi, idx_lo;
5746                    idx_lo = vl_eval_expr(id_sym->range->left);
5747                    if (id_sym->range->right)
5748                        idx_hi = vl_eval_expr(id_sym->range->right);
5749                    else
5750                        idx_hi = idx_lo;
5751
5752                    if (lo > hi || id_sym->flags & MVar) {
5753
5754                        for (j=0; j<i; j++) {
5755                            fprintf(file, "- ");
5756                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5757                                for (idx=idx_lo; idx<=idx_hi; idx++)
5758                                    fprintf(file, "- ");
5759                        }
5760                        fprintf(file, "1 ");
5761                        if (!st_lookup(i_set, (char*)j, (char**)&val))
5762                            for (idx=idx_lo; idx<=idx_hi; idx++)
5763                                fprintf(file, "- ");
5764                        j++;
5765                        for (; j<table_width; j++) {
5766                            fprintf(file, "- ");
5767                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5768                                for (idx=idx_lo; idx<=idx_hi; idx++)
5769                                    fprintf(file, "- ");
5770                        }
5771                        for (idx=idx_lo; idx<=idx_hi; idx++)
5772                            fprintf(file, "%s%s%s%d%s\n", HSIS_EQUAL,
5773                                    id_var_info->current_terminal->name->name,
5774                                    SEP_LARRAY, idx, SEP_RARRAY);
5775                        i++;
5776                    } else {
5777
5778                        for (j=0; j<i; j++) {
5779                            fprintf(file, "- ");
5780                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5781                                for (idx=idx_lo; idx<=idx_hi; idx++)
5782                                    for (k=lo; k<=hi; k++)
5783                                        fprintf(file, "- ");
5784                        }
5785                        fprintf(file, "1 ");
5786                        if (!st_lookup(i_set, (char*)j, (char**)&val))
5787                            for (idx=idx_lo; idx<=idx_hi; idx++)
5788                                for (k=lo; k<=hi; k++) fprintf(file, "- ");
5789                        j++;
5790                        for (; j<table_width; j++) {
5791                            fprintf(file, "- ");
5792                            if (!st_lookup(i_set, (char*)j, (char**)&val))
5793                                for (idx=idx_lo; idx<=idx_hi; idx++)
5794                                    for (k=lo; k<=hi; k++)
5795                                        fprintf(file, "- ");
5796                        }
5797                        for (idx=idx_lo; idx<=idx_hi; idx++)
5798                            for (k=lo; k<=hi; k++)
5799                                fprintf(file, "%s%s%s%d%s%s%d%s\n",
5800                                        HSIS_EQUAL,
5801                                        id_var_info->current_terminal->name->name,
5802                                        SEP_LARRAY, idx, SEP_RARRAY,
5803                                        SEP_LBITSELECT, k, SEP_RBITSELECT);
5804                        i++;
5805                    }
5806                }
5807            }
5808        }
5809        (void)lsFinish(gen);
5810        (void)lsFinish(pause_gen);
5811        (void)lsFinish(pt_gen);
5812
5813        st_insert(result_st, id_sym->name,
5814                  (char*)create_var_info(vl_copy_id_range(id_sym),
5815                                         new_term));
5816
5817    }
5818    st_free_gen(vars_gen);
5819}
5820
5821
5822static void vl_register_pause(vertex_t *pause_node, st_table *old_vars)
5823{
5824    set_t *pause_set;
5825
5826
5827    pause_set = set_empty();
5828    set_add(((fg_node_info*)pause_node->user_data)->loc, pause_set);
5829    lsNewEnd(vl_current_pause_list, (lsGeneric)pause_set, 0);
5830    lsNewEnd(vl_current_vars_list, (lsGeneric)old_vars, 0);
5831}
5832
5833
5834
5835static void vl_predefine_vars(FILE *file, st_table *vars)
5836{
5837    st_generator *gen;
5838    char *key;
5839    vl_id_range *id_sym;
5840    vl_term *init_term;
5841    int hi, lo;
5842    var_info *id_var;
5843    char *dummy;
5844
5845    gen = st_init_gen(vl_currentModule->sig_st);
5846    while (st_gen(gen, &key, (char**)&id_sym)) {
5847
5848        if (!(id_sym->flags & RegVar)) continue;
5849        if (strstr(id_sym->name, SEP_LATCH)) continue;
5850        if (strstr(id_sym->name, SEP_QUASI)) continue;
5851        if (vl_currentModule_combVar_st)
5852            if (st_lookup(vl_currentModule_combVar_st, id_sym->name, &dummy))
5853                continue;
5854
5855        get_hilo(id_sym, &hi, &lo);
5856        init_term = typed_new_term(id_sym->id_type, id_sym->range, lo, hi);
5857        init_term->flag = id_sym->flags;
5858        id_var = create_var_info(vl_copy_id_range(id_sym), init_term);
5859        st_insert(vars, id_sym->name, (char*)id_var);
5860        id_var = create_var_info(vl_copy_id_range(id_sym), init_term);
5861        st_insert(vl_current_init_vars, id_sym->name, (char*)id_var);
5862    }
5863    st_free_gen(gen);
5864}
5865
5866
5867
5868static void vl_timed_init_mux(FILE *file, vl_term *ctrl_term,
5869                              st_table *orig_vars, st_table *init_vars,
5870                              st_table *feedback_vars)
5871{
5872    st_generator *gen;
5873    char *key;
5874    var_info *init_var, *feedback_var, *orig_var;
5875    vl_term *orig_term=NIL(vl_term);
5876    int hi, lo;
5877    char *buf;
5878    int use_defined_term=0;
5879
5880    fprintf(file, "%s feedback mux\n", HSIS_COMMENT);
5881
5882    gen = st_init_gen(init_vars);
5883    while (st_gen(gen, &key, (char**)&init_var)) {
5884        use_defined_term=0;
5885        if (orig_vars) {
5886            if (st_lookup(orig_vars, key, (char**)&orig_var)) {
5887                orig_term = orig_var->current_terminal;
5888                use_defined_term=1;
5889            }
5890        }
5891        if (!use_defined_term) {
5892            get_hilo(init_var->id, &hi, &lo);
5893            buf = vlStrdup(init_var->id->name);
5894            orig_term = ((init_var->id->flags & EventVar) && smartEvent) ?
5895              vl_create_term(vl_create_id_range(WRT_BLIF_GND(file),
5896                                                NIL(vl_range)), 0, -1) :
5897              create_rename_term(init_var->id, buf, lo, hi);
5898            orig_term->flag = init_var->current_terminal->flag;
5899            write_var_decl(file, init_var->current_terminal);
5900        }
5901        if (st_lookup(feedback_vars, key, (char**)&feedback_var)) {
5902            instantiate_mux(file, orig_term, feedback_var->current_terminal,
5903                            ctrl_term, init_var->current_terminal);
5904        } else {
5905            if (orig_term->flag & MVar)
5906                vl_write_mv_connect(file,
5907                                    orig_term, init_var->current_terminal);
5908            else {
5909                if ((init_var->id->flags & EventVar) && smartEvent)
5910                    write_int_connect(file, 0, init_var->current_terminal);
5911                else
5912                    vl_write_bin_connect(file,
5913                                         orig_term, init_var->current_terminal,
5914                                         0);
5915            }
5916
5917        }
5918    }
5919    st_free_gen(gen);
5920}
5921
5922
5923vl_term *test_against_lc_init(FILE *file)
5924{
5925    vl_term *retval;
5926
5927    retval = new_term(NIL(vl_range), 0, -1);
5928
5929    fprintf(file, ".names %s%06x %s\n%s 0\n%s%d%s 1\n",
5930            FG_LC_PS,((fg_graph_info*)vl_writeFlowGraph->user_data)->fg_id,
5931            retval->name->name, HSIS_DEFAULT, FG_LLOC, 0, FG_RLOC);
5932
5933    return retval;
5934}
5935
5936
5937static void vl_write_timer(FILE *file, lsList graph_list)
5938{
5939    lsGen gen;
5940    lsHandle handle;
5941    graph_t *graph;
5942    fg_graph_info *gdata;
5943    int i;
5944
5945    for (gen=lsStart(graph_list);
5946         lsNext(gen, (lsGeneric*)&graph, &handle) != LS_NOMORE; ) {
5947        if (vl_preDeclare) {
5948            gdata = ((fg_graph_info*)graph->user_data);
5949            if (gdata->fg_id == -1) {
5950                fg_new_fg_id();
5951                gdata->fg_id = fg_fg_id();
5952            }
5953            fprintf(file, ".mv %s%06x, %s%06x %d %s%d%s ",
5954                    FG_LC_PS, gdata->fg_id, FG_LC_NS, gdata->fg_id,
5955                    (gdata->pause_hi-gdata->pause_lo)*2+2,
5956                    FG_LLOC, 0, FG_RLOC);
5957            for (i=gdata->pause_lo; i<gdata->pause_hi; i++)
5958                fprintf(file, "%s%d%s %s%d%s%s ",
5959                        FG_LLOC, i, FG_RLOC, FG_LLOC, i,
5960                        FG_RLOC, FG_TIMER_PRIME);
5961            fprintf(file, "%s%s\n", FG_LLOC, FG_RLOC);
5962            continue;
5963        }
5964
5965        if (graph) {
5966            if (!fg_check_timer_consistency(file, graph)) {
5967                char buf[MAXSTRLEN];
5968                yylineno = -1;
5969                sprintf(buf, "%s: contains delay free cycle(s)",
5970                        vl_currentModule->name->name);
5971                fprintf(stderr, "%s\n", buf);
5972            }
5973            fg_set_fg(graph);
5974            fg_write_timer(file, graph);
5975            fg_set_fg(NIL(graph_t));
5976        }
5977    }
5978    lsFinish(gen);
5979}
5980
5981
5982FILE *openStream()
5983{
5984    return tmpfile();
5985}
5986
5987void closeStream(FILE *stream)
5988{
5989    fclose(stream);
5990}
5991
5992void dumpStream(FILE *to, FILE *from)
5993{
5994    char buf[MAXSTRLEN];
5995
5996    rewind(from);
5997    while(fgets(buf, MAXSTRLEN, from)!=NULL)
5998        fputs(buf, to);
5999}
6000
6001
6002char * cfsm_inputs(char *inputs)
6003{
6004    int len, i;
6005    char arg[MAXSTRLEN];
6006    char token[MAXSTRLEN];
6007    char *cp;
6008    static char buf[MAXSTRLEN];
6009
6010    buf[0] = '\0';
6011    len = strlen(inputs);
6012    for (cp=inputs; cp<inputs+len; ) {
6013        i = 0;
6014        while ((*cp == ' ' || *cp == '\t') && *cp != '\0') cp++;
6015        while ((*cp != ' ' && *cp != '\t') && *cp != '\0') {
6016            token[i] = *cp;
6017            cp++;  i++;
6018        }
6019        if (i > 0) {
6020            token[i] = '\0';
6021            sprintf(arg, " %s=%s", token, token);
6022            strcat(buf, arg);
6023        }
6024    }
6025
6026    return buf;
6027}
6028
6029char *cfsm_ports(char *ports)
6030{
6031    int len, i;
6032    char arg[MAXSTRLEN];
6033    char token[MAXSTRLEN];
6034    char *cp;
6035    static char buf[MAXSTRLEN];
6036    int ithToken;
6037
6038    buf[0] = '\0';
6039    len = strlen(ports);
6040    ithToken=0;
6041    for (cp=ports; cp<ports+len; ) {
6042        i = 0;
6043        while ((*cp == ' ' || *cp == '\t') && *cp != '\0') cp++;
6044        while ((*cp != ' ' && *cp != '\t') && *cp != '\0') {
6045            token[i] = *cp;
6046            cp++;  i++;
6047        }
6048        if (i > 0) {
6049            token[i] = '\0';
6050            if (ithToken > 0)
6051                sprintf(arg, " , %s", token);
6052            else
6053                sprintf(arg, " %s", token);
6054            strcat(buf, arg);
6055            ithToken++;
6056        }
6057    }
6058
6059    return buf;
6060}
6061
6062
6063FILE *vl_begin_buffer()
6064{
6065    return tmpfile();
6066}
6067
6068
6069void vl_close_buffer(FILE *buffer)
6070{
6071    fclose(buffer);
6072}
6073
6074
6075void vl_append_buffer(FILE *main_stream, FILE *buffer)
6076{
6077    char buf[MAXSTRLEN];
6078
6079    rewind(buffer);
6080    while(fgets(buf, MAXSTRLEN, buffer)!=NULL)
6081        fputs(buf, main_stream);
6082}
Note: See TracBrowser for help on using the repository browser.