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 | } |
---|