[18] | 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 | $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/vl_mux.c,v 1.2 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 "vl_types.h" |
---|
| 37 | #include "vl_defs.h" |
---|
| 38 | #include "vlr_int.h" |
---|
| 39 | #include "vl_create.h" |
---|
| 40 | #include "vl_traverse.h" |
---|
| 41 | #include "vl_write.h" |
---|
| 42 | #include "vl_write_util.h" |
---|
| 43 | #include "vl_fg_defs.h" |
---|
| 44 | #include "vl_fg_types.h" |
---|
| 45 | #include "vl_flowgraph.h" |
---|
| 46 | #include "vl_mux.h" |
---|
| 47 | #include "vl_vardecl.h" |
---|
| 48 | #include "verilog.h" |
---|
| 49 | |
---|
| 50 | extern int set_notation; |
---|
| 51 | extern vl_desc *mod_list; |
---|
| 52 | |
---|
| 53 | static int need_mux = 0; |
---|
| 54 | |
---|
| 55 | |
---|
| 56 | |
---|
| 57 | void vl_dump_libs(file, decl_st) |
---|
| 58 | FILE *file; |
---|
| 59 | st_table *decl_st; |
---|
| 60 | { |
---|
| 61 | st_generator *gen; |
---|
| 62 | char *key; |
---|
| 63 | void *decl; |
---|
| 64 | int i; |
---|
| 65 | char buf[MAXSTRLEN], tmp[MAXSTRLEN], *cp; |
---|
| 66 | lsList domain; |
---|
| 67 | lsGen enum_gen; |
---|
| 68 | lsHandle enum_handle; |
---|
| 69 | vl_enumerator *enum_elt; |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | if (need_mux & B_MUX) { |
---|
| 73 | fprintf(file, "%s vlr_mux%s0%s1%s\n", HSIS_MODEL, |
---|
| 74 | SEP_LTRANGE, SEP_GATEPIN, SEP_RTRANGE); |
---|
| 75 | fprintf(file, ".inputs a b s\n"); |
---|
| 76 | fprintf(file, ".outputs o\n"); |
---|
| 77 | fprintf(file, ".names a b s o\n"); |
---|
| 78 | fprintf(file, "0 - 1 0\n"); |
---|
| 79 | fprintf(file, "1 - 1 1\n"); |
---|
| 80 | fprintf(file, "- 0 0 0\n"); |
---|
| 81 | fprintf(file, "- 1 0 1\n"); |
---|
| 82 | fprintf(file, ".end\n\n"); |
---|
| 83 | } |
---|
| 84 | |
---|
| 85 | |
---|
| 86 | gen = st_init_gen(decl_st); |
---|
| 87 | while (st_gen(gen, &key, (char**)&decl)) { |
---|
| 88 | cp = buf; *cp = '\0'; |
---|
| 89 | domain = ((vl_type*)decl)->specifier->u.enum_type->domain_list; |
---|
| 90 | for (enum_gen=lsStart(domain), i=1; |
---|
| 91 | lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE; |
---|
| 92 | i++) { |
---|
| 93 | if (i!=lsLength(domain)) |
---|
| 94 | sprintf(tmp, "%s%s", enum_elt->name, SEP_GATEPIN); |
---|
| 95 | else |
---|
| 96 | sprintf(tmp, "%s", enum_elt->name); |
---|
| 97 | cp = strappend(cp, tmp); |
---|
| 98 | } |
---|
| 99 | lsFinish(enum_gen); |
---|
| 100 | |
---|
| 101 | fprintf(file, "%s vlr_mux%s%s%s\n", HSIS_MODEL, |
---|
| 102 | SEP_LTRANGE, buf, SEP_RTRANGE); |
---|
| 103 | |
---|
| 104 | fprintf(file, ".inputs a b s\n"); |
---|
| 105 | fprintf(file, ".outputs o\n"); |
---|
| 106 | |
---|
| 107 | cp = buf; *cp = '\0'; |
---|
| 108 | domain = ((vl_type*)decl)->specifier->u.enum_type->domain_list; |
---|
| 109 | for (enum_gen=lsStart(domain), i=1; |
---|
| 110 | lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE; |
---|
| 111 | i++) { |
---|
| 112 | if (i!=lsLength(domain)) |
---|
| 113 | sprintf(tmp, "%s ", enum_elt->name); |
---|
| 114 | else |
---|
| 115 | sprintf(tmp, "%s", enum_elt->name); |
---|
| 116 | cp = strappend(cp, tmp); |
---|
| 117 | } |
---|
| 118 | lsFinish(enum_gen); |
---|
| 119 | |
---|
| 120 | fprintf(file, ".mv a %d %s\n", lsLength(domain), buf); |
---|
| 121 | fprintf(file, ".mv b %d %s\n", lsLength(domain), buf); |
---|
| 122 | fprintf(file, ".mv o %d %s\n", lsLength(domain), buf); |
---|
| 123 | fprintf(file, ".names a b s o\n"); |
---|
| 124 | |
---|
| 125 | for (enum_gen=lsStart(domain); |
---|
| 126 | lsNext(enum_gen,(lsGeneric*)&enum_elt,&enum_handle)!=LS_NOMORE;) { |
---|
| 127 | fprintf(file, "%s - 1 %s\n", enum_elt->name, enum_elt->name); |
---|
| 128 | fprintf(file, "- %s 0 %s\n", enum_elt->name, enum_elt->name); |
---|
| 129 | } |
---|
| 130 | lsFinish(enum_gen); |
---|
| 131 | |
---|
| 132 | fprintf(file, ".end\n\n"); |
---|
| 133 | } |
---|
| 134 | st_free_gen(gen); |
---|
| 135 | } |
---|
| 136 | |
---|
| 137 | |
---|
| 138 | void instantiate_mux(file, t, f, sel, out) |
---|
| 139 | FILE *file; |
---|
| 140 | vl_term *t; |
---|
| 141 | vl_term *f; |
---|
| 142 | vl_term *sel; |
---|
| 143 | vl_term *out; |
---|
| 144 | { |
---|
| 145 | vl_term *term_control; |
---|
| 146 | char t_buf[MAXSTRLEN], f_buf[MAXSTRLEN], out_buf[MAXSTRLEN]; |
---|
| 147 | vl_term *t_elt, *f_elt, *out_elt; |
---|
| 148 | int idx; |
---|
| 149 | int hi, lo, bit_lo, bit_hi; |
---|
| 150 | |
---|
| 151 | term_control = sel; |
---|
| 152 | |
---|
| 153 | if (sel->lo <= sel->hi) { |
---|
| 154 | term_control = new_term(NIL(vl_range), 0, -1); |
---|
| 155 | vl_write_vector_bop(file, UorExpr, |
---|
| 156 | sel, NIL(vl_term), term_control); |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | if (!out->name->range) { |
---|
| 160 | if (out->flag & MVar) |
---|
| 161 | instantiate_smux(file, t, f, term_control, out); |
---|
| 162 | else |
---|
| 163 | instantiate_bmux(file, t, f, term_control, out); |
---|
| 164 | } else { |
---|
| 165 | bit_lo = out->lo; bit_hi = out->hi; |
---|
| 166 | |
---|
| 167 | lo = vl_eval_expr(out->name->range->left); |
---|
| 168 | if (out->name->range->right) |
---|
| 169 | hi = vl_eval_expr(out->name->range->right); |
---|
| 170 | else |
---|
| 171 | hi = lo; |
---|
| 172 | |
---|
| 173 | for (idx=lo; idx<=hi; idx++) { |
---|
| 174 | sprintf(t_buf, "%s%s%d%s", |
---|
| 175 | t->name->name, SEP_LARRAY, idx, SEP_RARRAY); |
---|
| 176 | sprintf(f_buf, "%s%s%d%s", |
---|
| 177 | f->name->name, SEP_LARRAY, idx, SEP_RARRAY); |
---|
| 178 | sprintf(out_buf, "%s%s%d%s", |
---|
| 179 | out->name->name, SEP_LARRAY, idx, SEP_RARRAY); |
---|
| 180 | |
---|
| 181 | t_elt = create_rename_term(t->name, t_buf, bit_lo, bit_hi); |
---|
| 182 | f_elt = create_rename_term(f->name, f_buf, bit_lo, bit_hi); |
---|
| 183 | out_elt = create_rename_term(out->name, out_buf, bit_lo, bit_hi); |
---|
| 184 | if (out->flag & MVar) |
---|
| 185 | instantiate_smux(file, t_elt, f_elt, term_control, out_elt); |
---|
| 186 | else |
---|
| 187 | instantiate_bmux(file, t_elt, f_elt, term_control, out_elt); |
---|
| 188 | } |
---|
| 189 | } |
---|
| 190 | } |
---|
| 191 | |
---|
| 192 | void instantiate_smux(file, t, f, sel, out) |
---|
| 193 | FILE *file; |
---|
| 194 | vl_term *t; |
---|
| 195 | vl_term *f; |
---|
| 196 | vl_term *sel; |
---|
| 197 | vl_term *out; |
---|
| 198 | { |
---|
| 199 | need_mux |= S_MUX; |
---|
| 200 | |
---|
| 201 | vl_bin_to_mv(t); |
---|
| 202 | vl_bin_to_mv(f); |
---|
| 203 | |
---|
| 204 | if (t->lo!=f->lo || t->lo!=out->lo || |
---|
| 205 | t->hi!=t->hi || t->hi!=out->hi || |
---|
| 206 | f->lo!=out->lo || f->hi!=out->hi) |
---|
| 207 | Translate_Warning("inconsistent MVar range"); |
---|
| 208 | |
---|
| 209 | if (set_notation) { |
---|
| 210 | fprintf(file, ".names %s %s %s %s\n", sel->name->name, t->name->name, |
---|
| 211 | f->name->name, out->name->name); |
---|
| 212 | fprintf(file, "0 - - %s%s\n", HSIS_EQUAL, f->name->name); |
---|
| 213 | fprintf(file, "1 - - %s%s\n", HSIS_EQUAL, t->name->name); |
---|
| 214 | } else { |
---|
| 215 | vl_put_lib(file, LIB_MUX, out, new_termname(), |
---|
| 216 | t->name->name, f->name->name, |
---|
| 217 | descape(sel->name->name,'\\','_'), |
---|
| 218 | out->name->name); |
---|
| 219 | } |
---|
| 220 | } |
---|
| 221 | |
---|
| 222 | |
---|
| 223 | void instantiate_bmux(file, t, f, sel, out) |
---|
| 224 | FILE *file; |
---|
| 225 | vl_term *t; |
---|
| 226 | vl_term *f; |
---|
| 227 | vl_term *sel; |
---|
| 228 | vl_term *out; |
---|
| 229 | { |
---|
| 230 | char fbuf[MAXSTRLEN], tbuf[MAXSTRLEN], obuf[MAXSTRLEN]; |
---|
| 231 | int i; |
---|
| 232 | |
---|
| 233 | vl_mv_to_bin(t); |
---|
| 234 | vl_mv_to_bin(f); |
---|
| 235 | |
---|
| 236 | if (t->hi-t->lo != f->hi-f->lo) { |
---|
| 237 | |
---|
| 238 | |
---|
| 239 | vl_term *new_term; |
---|
| 240 | int bpos; |
---|
| 241 | char inbuf[MAXSTRLEN], outbuf[MAXSTRLEN]; |
---|
| 242 | |
---|
| 243 | if (t->hi-t->lo > f->hi-f->lo) { |
---|
| 244 | assert(t->hi >= f->hi && t->lo <= f->lo); |
---|
| 245 | new_term = typed_new_term(f->term_type, NIL(vl_range), |
---|
| 246 | t->lo, t->hi); |
---|
| 247 | for(bpos=f->lo; bpos<=f->hi; bpos++) { |
---|
| 248 | sprintf(inbuf, "%s%s%d%s", f->name->name, |
---|
| 249 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 250 | sprintf(outbuf, "%s%s%d%s", new_term->name->name, |
---|
| 251 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 252 | vl_write_bit_connect(file, inbuf, outbuf, 0); |
---|
| 253 | } |
---|
| 254 | for(bpos=t->lo; bpos<=t->hi; bpos++) { |
---|
| 255 | if (bpos < f->lo || bpos > f->hi) { |
---|
| 256 | sprintf(inbuf, "%s%s%d%s", t->name->name, |
---|
| 257 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 258 | sprintf(outbuf, "%s%s%d%s", new_term->name->name, |
---|
| 259 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 260 | vl_write_bit_connect(file, inbuf, outbuf, 0); |
---|
| 261 | } |
---|
| 262 | } |
---|
| 263 | f = new_term; |
---|
| 264 | } else { |
---|
| 265 | assert(f->hi >= t->hi && f->lo <= t->lo); |
---|
| 266 | new_term = typed_new_term(t->term_type, NIL(vl_range), |
---|
| 267 | f->lo, f->hi); |
---|
| 268 | for(bpos=t->lo; bpos<=t->hi; bpos++) { |
---|
| 269 | sprintf(inbuf, "%s%s%d%s", t->name->name, |
---|
| 270 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 271 | sprintf(outbuf, "%s%s%d%s", new_term->name->name, |
---|
| 272 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 273 | vl_write_bit_connect(file, inbuf, outbuf, 0); |
---|
| 274 | } |
---|
| 275 | for(bpos=f->lo; bpos<=f->hi; bpos++) { |
---|
| 276 | if (bpos < t->lo || bpos > t->hi) { |
---|
| 277 | sprintf(inbuf, "%s%s%d%s", f->name->name, |
---|
| 278 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 279 | sprintf(outbuf, "%s%s%d%s", new_term->name->name, |
---|
| 280 | SEP_LBITSELECT, bpos, SEP_RBITSELECT); |
---|
| 281 | vl_write_bit_connect(file, inbuf, outbuf, 0); |
---|
| 282 | } |
---|
| 283 | } |
---|
| 284 | t = new_term; |
---|
| 285 | } |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | out->lo = f->lo; out->hi = f->hi; |
---|
| 289 | |
---|
| 290 | if (out->lo > out->hi) { |
---|
| 291 | |
---|
| 292 | sprintf(tbuf, "%s", t->name->name); |
---|
| 293 | sprintf(fbuf, "%s", f->name->name); |
---|
| 294 | sprintf(obuf, "%s", out->name->name); |
---|
| 295 | vl_put_lib(file, LIB_MUX, out, new_termname(), tbuf, |
---|
| 296 | fbuf, descape(sel->name->name,'\\','_'), obuf); |
---|
| 297 | } else { |
---|
| 298 | |
---|
| 299 | for (i=f->lo; i<=f->hi; i++) { |
---|
| 300 | if ((i-f->lo) <= (t->hi-t->lo)) { |
---|
| 301 | int idx; |
---|
| 302 | idx = i + t->lo - f->lo; |
---|
| 303 | sprintf(tbuf, "%s%s%d%s", t->name->name, |
---|
| 304 | SEP_LBITSELECT, idx, SEP_RBITSELECT); |
---|
| 305 | } else { |
---|
| 306 | sprintf(tbuf, "%s%s%d%s", f->name->name, |
---|
| 307 | SEP_LBITSELECT, i, SEP_RBITSELECT); |
---|
| 308 | } |
---|
| 309 | sprintf(fbuf, "%s%s%d%s", f->name->name, |
---|
| 310 | SEP_LBITSELECT, i, SEP_RBITSELECT); |
---|
| 311 | sprintf(obuf, "%s%s%d%s", out->name->name, |
---|
| 312 | SEP_LBITSELECT, i+out->lo-f->lo, SEP_RBITSELECT); |
---|
| 313 | vl_put_lib(file, LIB_MUX, out, new_termname(), tbuf, |
---|
| 314 | fbuf, descape(sel->name->name,'\\','_'), obuf); |
---|
| 315 | } |
---|
| 316 | } |
---|
| 317 | } |
---|