/* Copyright (c) 1992, 1993 Regents of the University of California All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. However, any distribution of this software or derivative works must include the above copyright notice. This software is made available AS IS, and neither the Electronics Research Laboratory or the Universify of California make any warranty about the software, its performance or its conformity to any specification. Author: Szu-Tsung Cheng, stcheng@ic.Berkeley.EDU 10/92 10/93 $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/vl_mux.c,v 1.2 2009/03/09 20:25:58 fabio Exp $ */ #include #include #include "util.h" #include "st.h" #include "array.h" #include "list.h" #include "set.h" #include "graph.h" #include "stack.h" #include "vl_types.h" #include "vl_defs.h" #include "vlr_int.h" #include "vl_create.h" #include "vl_traverse.h" #include "vl_write.h" #include "vl_write_util.h" #include "vl_fg_defs.h" #include "vl_fg_types.h" #include "vl_flowgraph.h" #include "vl_mux.h" #include "vl_vardecl.h" #include "verilog.h" extern int set_notation; extern vl_desc *mod_list; static int need_mux = 0; void vl_dump_libs(file, decl_st) FILE *file; st_table *decl_st; { st_generator *gen; char *key; void *decl; int i; char buf[MAXSTRLEN], tmp[MAXSTRLEN], *cp; lsList domain; lsGen enum_gen; lsHandle enum_handle; vl_enumerator *enum_elt; if (need_mux & B_MUX) { fprintf(file, "%s vlr_mux%s0%s1%s\n", HSIS_MODEL, SEP_LTRANGE, SEP_GATEPIN, SEP_RTRANGE); fprintf(file, ".inputs a b s\n"); fprintf(file, ".outputs o\n"); fprintf(file, ".names a b s o\n"); fprintf(file, "0 - 1 0\n"); fprintf(file, "1 - 1 1\n"); fprintf(file, "- 0 0 0\n"); fprintf(file, "- 1 0 1\n"); fprintf(file, ".end\n\n"); } gen = st_init_gen(decl_st); while (st_gen(gen, &key, (char**)&decl)) { cp = buf; *cp = '\0'; domain = ((vl_type*)decl)->specifier->u.enum_type->domain_list; for (enum_gen=lsStart(domain), i=1; lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE; i++) { if (i!=lsLength(domain)) sprintf(tmp, "%s%s", enum_elt->name, SEP_GATEPIN); else sprintf(tmp, "%s", enum_elt->name); cp = strappend(cp, tmp); } lsFinish(enum_gen); fprintf(file, "%s vlr_mux%s%s%s\n", HSIS_MODEL, SEP_LTRANGE, buf, SEP_RTRANGE); fprintf(file, ".inputs a b s\n"); fprintf(file, ".outputs o\n"); cp = buf; *cp = '\0'; domain = ((vl_type*)decl)->specifier->u.enum_type->domain_list; for (enum_gen=lsStart(domain), i=1; lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE; i++) { if (i!=lsLength(domain)) sprintf(tmp, "%s ", enum_elt->name); else sprintf(tmp, "%s", enum_elt->name); cp = strappend(cp, tmp); } lsFinish(enum_gen); fprintf(file, ".mv a %d %s\n", lsLength(domain), buf); fprintf(file, ".mv b %d %s\n", lsLength(domain), buf); fprintf(file, ".mv o %d %s\n", lsLength(domain), buf); fprintf(file, ".names a b s o\n"); for (enum_gen=lsStart(domain); lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE;) { fprintf(file, "%s - 1 %s\n", enum_elt->name, enum_elt->name); fprintf(file, "- %s 0 %s\n", enum_elt->name, enum_elt->name); } lsFinish(enum_gen); fprintf(file, ".end\n\n"); } st_free_gen(gen); } void instantiate_mux(file, t, f, sel, out) FILE *file; vl_term *t; vl_term *f; vl_term *sel; vl_term *out; { vl_term *term_control; char t_buf[MAXSTRLEN], f_buf[MAXSTRLEN], out_buf[MAXSTRLEN]; vl_term *t_elt, *f_elt, *out_elt; int idx; int hi, lo, bit_lo, bit_hi; term_control = sel; if (sel->lo <= sel->hi) { term_control = new_term(NIL(vl_range), 0, -1); vl_write_vector_bop(file, UorExpr, sel, NIL(vl_term), term_control); } if (!out->name->range) { if (out->flag & MVar) instantiate_smux(file, t, f, term_control, out); else instantiate_bmux(file, t, f, term_control, out); } else { bit_lo = out->lo; bit_hi = out->hi; lo = vl_eval_expr(out->name->range->left); if (out->name->range->right) hi = vl_eval_expr(out->name->range->right); else hi = lo; for (idx=lo; idx<=hi; idx++) { sprintf(t_buf, "%s%s%d%s", t->name->name, SEP_LARRAY, idx, SEP_RARRAY); sprintf(f_buf, "%s%s%d%s", f->name->name, SEP_LARRAY, idx, SEP_RARRAY); sprintf(out_buf, "%s%s%d%s", out->name->name, SEP_LARRAY, idx, SEP_RARRAY); t_elt = create_rename_term(t->name, t_buf, bit_lo, bit_hi); f_elt = create_rename_term(f->name, f_buf, bit_lo, bit_hi); out_elt = create_rename_term(out->name, out_buf, bit_lo, bit_hi); if (out->flag & MVar) instantiate_smux(file, t_elt, f_elt, term_control, out_elt); else instantiate_bmux(file, t_elt, f_elt, term_control, out_elt); } } } void instantiate_smux(file, t, f, sel, out) FILE *file; vl_term *t; vl_term *f; vl_term *sel; vl_term *out; { need_mux |= S_MUX; vl_bin_to_mv(t); vl_bin_to_mv(f); if (t->lo!=f->lo || t->lo!=out->lo || t->hi!=t->hi || t->hi!=out->hi || f->lo!=out->lo || f->hi!=out->hi) Translate_Warning("inconsistent MVar range"); if (set_notation) { fprintf(file, ".names %s %s %s %s\n", sel->name->name, t->name->name, f->name->name, out->name->name); fprintf(file, "0 - - %s%s\n", HSIS_EQUAL, f->name->name); fprintf(file, "1 - - %s%s\n", HSIS_EQUAL, t->name->name); } else { vl_put_lib(file, LIB_MUX, out, new_termname(), t->name->name, f->name->name, descape(sel->name->name,'\\','_'), out->name->name); } } void instantiate_bmux(file, t, f, sel, out) FILE *file; vl_term *t; vl_term *f; vl_term *sel; vl_term *out; { char fbuf[MAXSTRLEN], tbuf[MAXSTRLEN], obuf[MAXSTRLEN]; int i; vl_mv_to_bin(t); vl_mv_to_bin(f); if (t->hi-t->lo != f->hi-f->lo) { vl_term *new_term; int bpos; char inbuf[MAXSTRLEN], outbuf[MAXSTRLEN]; if (t->hi-t->lo > f->hi-f->lo) { assert(t->hi >= f->hi && t->lo <= f->lo); new_term = typed_new_term(f->term_type, NIL(vl_range), t->lo, t->hi); for(bpos=f->lo; bpos<=f->hi; bpos++) { sprintf(inbuf, "%s%s%d%s", f->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); sprintf(outbuf, "%s%s%d%s", new_term->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); vl_write_bit_connect(file, inbuf, outbuf, 0); } for(bpos=t->lo; bpos<=t->hi; bpos++) { if (bpos < f->lo || bpos > f->hi) { sprintf(inbuf, "%s%s%d%s", t->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); sprintf(outbuf, "%s%s%d%s", new_term->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); vl_write_bit_connect(file, inbuf, outbuf, 0); } } f = new_term; } else { assert(f->hi >= t->hi && f->lo <= t->lo); new_term = typed_new_term(t->term_type, NIL(vl_range), f->lo, f->hi); for(bpos=t->lo; bpos<=t->hi; bpos++) { sprintf(inbuf, "%s%s%d%s", t->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); sprintf(outbuf, "%s%s%d%s", new_term->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); vl_write_bit_connect(file, inbuf, outbuf, 0); } for(bpos=f->lo; bpos<=f->hi; bpos++) { if (bpos < t->lo || bpos > t->hi) { sprintf(inbuf, "%s%s%d%s", f->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); sprintf(outbuf, "%s%s%d%s", new_term->name->name, SEP_LBITSELECT, bpos, SEP_RBITSELECT); vl_write_bit_connect(file, inbuf, outbuf, 0); } } t = new_term; } } out->lo = f->lo; out->hi = f->hi; if (out->lo > out->hi) { sprintf(tbuf, "%s", t->name->name); sprintf(fbuf, "%s", f->name->name); sprintf(obuf, "%s", out->name->name); vl_put_lib(file, LIB_MUX, out, new_termname(), tbuf, fbuf, descape(sel->name->name,'\\','_'), obuf); } else { for (i=f->lo; i<=f->hi; i++) { if ((i-f->lo) <= (t->hi-t->lo)) { int idx; idx = i + t->lo - f->lo; sprintf(tbuf, "%s%s%d%s", t->name->name, SEP_LBITSELECT, idx, SEP_RBITSELECT); } else { sprintf(tbuf, "%s%s%d%s", f->name->name, SEP_LBITSELECT, i, SEP_RBITSELECT); } sprintf(fbuf, "%s%s%d%s", f->name->name, SEP_LBITSELECT, i, SEP_RBITSELECT); sprintf(obuf, "%s%s%d%s", out->name->name, SEP_LBITSELECT, i+out->lo-f->lo, SEP_RBITSELECT); vl_put_lib(file, LIB_MUX, out, new_termname(), tbuf, fbuf, descape(sel->name->name,'\\','_'), obuf); } } }