1 | /**CFile*********************************************************************** |
---|
2 | |
---|
3 | FileName [ ioWriteBlif.c ] |
---|
4 | |
---|
5 | PackageName [ io ] |
---|
6 | |
---|
7 | Synopsis [ This file contains blifmv -> blif write routines ] |
---|
8 | |
---|
9 | Description [ Routines for (determinizing, encoding and) writing a blifmv table |
---|
10 | into a blif description are provided. The encoding of multivalued |
---|
11 | vars is written to separate files. ] |
---|
12 | |
---|
13 | SeeAlso [ ioReadBlifmv.c, ioWriteBlifIo.c, IoWriteBlifUtil.c] |
---|
14 | |
---|
15 | Author [ Sunil P. Khatri ] |
---|
16 | |
---|
17 | Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. |
---|
18 | All rights reserved. |
---|
19 | |
---|
20 | Permission is hereby granted, without written agreement and without license |
---|
21 | or royalty fees, to use, copy, modify, and distribute this software and its |
---|
22 | documentation for any purpose, provided that the above copyright notice and |
---|
23 | the following two paragraphs appear in all copies of this software. |
---|
24 | |
---|
25 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
---|
26 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
---|
27 | OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
---|
28 | CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
29 | |
---|
30 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
---|
31 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
---|
32 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN |
---|
33 | "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE |
---|
34 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] |
---|
35 | |
---|
36 | ******************************************************************************/ |
---|
37 | |
---|
38 | #include "ioInt.h" |
---|
39 | |
---|
40 | static char rcsid[] UNUSED = "$Id: ioWriteBlif.c,v 1.14 2005/04/29 14:23:29 fabio Exp $"; |
---|
41 | |
---|
42 | /*---------------------------------------------------------------------------*/ |
---|
43 | /* Constant declarations */ |
---|
44 | /*---------------------------------------------------------------------------*/ |
---|
45 | #define MAX_NUMBER_BDD_VARS 500 |
---|
46 | |
---|
47 | /*---------------------------------------------------------------------------*/ |
---|
48 | /* Macro declarations */ |
---|
49 | /*---------------------------------------------------------------------------*/ |
---|
50 | |
---|
51 | |
---|
52 | |
---|
53 | /**AutomaticStart*************************************************************/ |
---|
54 | |
---|
55 | /*---------------------------------------------------------------------------*/ |
---|
56 | /* Static function prototypes */ |
---|
57 | /*---------------------------------------------------------------------------*/ |
---|
58 | |
---|
59 | static int _IoTableWriteBlif(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, Tbl_Table_t *origBlifmvTable, st_table *blifInputsStTable, FILE *fp, FILE *encFp, int verbosity); |
---|
60 | static int _IoMakeInitialEncodings(IoBlifInfo_t *blifInfo, Hrc_Node_t *hnode); |
---|
61 | static void _IoDeterminizeEncodeOutputPart(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable); |
---|
62 | static void _IoDeterminizeEncodeRows(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable); |
---|
63 | static void _IoMakeDcTables(IoBlifInfo_t *blifInfo); |
---|
64 | static void _IoMakeBinTable(IoBlifInfo_t *blifInfo); |
---|
65 | static int _IoCheckHnodeTreeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, st_table *modelTable, boolean *pSymVarsPresent, int verbosity); |
---|
66 | static int _IoCheckHnodeVarsAreBoolean(Hrc_Node_t *hnode, boolean *pSymVarsPresent); |
---|
67 | static int _IoCheckHnodeLatchResetIsConstant(Hrc_Node_t *hnode); |
---|
68 | static int _IoCheckHnodeTablesAreDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode); |
---|
69 | static void _MddManagerResetIfNecessary(mdd_manager **mddMgr); |
---|
70 | static void _IoHnodeWriteBlifRecursively(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, st_table *modelTable, FILE *fp, FILE *encFp, int verbosity); |
---|
71 | static int _IoHnodeWriteBlifRecursivelyStep(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, FILE *fp, FILE *encFp, int verbosity); |
---|
72 | static int _IoCheckHnodeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, boolean *pSymVarsPresent); |
---|
73 | static int _IoCheckPseudoinputIsPO(Tbl_Table_t *table); |
---|
74 | |
---|
75 | /**AutomaticEnd***************************************************************/ |
---|
76 | |
---|
77 | |
---|
78 | /*---------------------------------------------------------------------------*/ |
---|
79 | /* Definition of exported functions */ |
---|
80 | /*---------------------------------------------------------------------------*/ |
---|
81 | |
---|
82 | /**Function*********************************************************** |
---|
83 | |
---|
84 | |
---|
85 | Synopsis [ Recursively write out the entire hierarchy below the current |
---|
86 | hnode to a blif file. ] |
---|
87 | |
---|
88 | Description [ This routine recursively writes out the entire hierarchy below |
---|
89 | the given hnode to a named blif file. This sub-hierarchy must |
---|
90 | comply with the following restrictions. First all tables in it |
---|
91 | should be deterministic. Secondly, all variables should be |
---|
92 | binary. The function returns a 0 upon success, 1 in case of |
---|
93 | failure. Upon failure, appropriate error messages are printed |
---|
94 | to stderr. The function is passed an enumerated type called |
---|
95 | encodingType, only SIMPLE is supported. Refer to the description |
---|
96 | of Io_HnodeWriteBlif for more information on this. The hnode |
---|
97 | is passed, along with the file pointer fp, for the file into which |
---|
98 | the resulting blif network is to be written. A verbosity flag |
---|
99 | (valid values are between 0 and 2) causes intermediate information |
---|
100 | to be printed to stderr. |
---|
101 | ] |
---|
102 | |
---|
103 | SideEffects [ ] |
---|
104 | |
---|
105 | SeeAlso [ ] |
---|
106 | **********************************************************************/ |
---|
107 | int |
---|
108 | Io_HnodeWriteBlifTotal( |
---|
109 | Io_Encoding_Type_t encodingType, |
---|
110 | Hrc_Node_t *hnode, |
---|
111 | FILE *fp, |
---|
112 | int verbosity) |
---|
113 | { |
---|
114 | st_table *modelTable; |
---|
115 | Hrc_Manager_t *manager; |
---|
116 | mdd_manager *mddMgr; |
---|
117 | FILE *encFp; |
---|
118 | boolean symVarsPresent; |
---|
119 | |
---|
120 | manager = Hrc_NodeReadManager(hnode); |
---|
121 | modelTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
122 | mddMgr = mdd_init_empty(); |
---|
123 | bdd_dynamic_reordering(mddMgr, BDD_REORDER_SIFT, BDD_REORDER_VERBOSITY_DEFAULT); |
---|
124 | symVarsPresent = FALSE; |
---|
125 | |
---|
126 | /* check that the node and all its children are boolean and deterministic. */ |
---|
127 | if(_IoCheckHnodeTreeIsBooleanAndDeterministic(&mddMgr, hnode, modelTable, &symVarsPresent, verbosity)){ |
---|
128 | mdd_quit(mddMgr); |
---|
129 | st_free_table(modelTable); |
---|
130 | return 1; |
---|
131 | } |
---|
132 | if(verbosity > 0){ |
---|
133 | fprintf(vis_stderr, "Done with hierarcy checks\n"); |
---|
134 | } |
---|
135 | |
---|
136 | if(symVarsPresent == TRUE){ |
---|
137 | fprintf(vis_stderr, "Warning - some variables in the hierarchy are symbolic\n"); |
---|
138 | } |
---|
139 | |
---|
140 | st_free_table(modelTable); |
---|
141 | modelTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
142 | encFp = Cmd_FileOpen("/dev/null", "w", NIL(char *), 1); |
---|
143 | |
---|
144 | _IoHnodeWriteBlifRecursively(encodingType, hnode, modelTable, fp, encFp, verbosity); |
---|
145 | Hrc_ManagerSetCurrentNode(manager, hnode); |
---|
146 | |
---|
147 | st_free_table(modelTable); |
---|
148 | mdd_quit(mddMgr); |
---|
149 | return 0; |
---|
150 | } |
---|
151 | |
---|
152 | |
---|
153 | /**Function*********************************************************** |
---|
154 | |
---|
155 | |
---|
156 | Synopsis [ Determinize, encode and write all blifmv tables in a hnode |
---|
157 | to a blif file. Also writes all encoding information to a |
---|
158 | encoding file. This encoding file can later be read in, along |
---|
159 | with the blif file (potentially after optimization in SIS), |
---|
160 | into that hnode (see "read_blif -i" for details). Currently, only the |
---|
161 | combinational part of the hnode is written to the blif file.] |
---|
162 | |
---|
163 | Description [ This routine determinizes, encodes and writes all blifmv tables |
---|
164 | in a hnode to a named blif file. |
---|
165 | It also writes encoding information to another named file. |
---|
166 | This encoding file must be used while reading back the (optimized) |
---|
167 | blif file into blifmv. |
---|
168 | The function returns a 0 upon success, 1 in case of failure. It |
---|
169 | should be supplied a Io_Encoding_Type_t. Currently only SIMPLE is |
---|
170 | supported. Under this scheme, binary encoding is done on the |
---|
171 | multi-valued variables, and the binary variable with smallest length |
---|
172 | is chosen at any step of the determinization process. Other parameters |
---|
173 | to this function include a Hrc_Node_t *, and file pointers for the |
---|
174 | blif output file and the encoding file. The default blif file is |
---|
175 | stdout, and the default encoding file is <model>.enc. A verbosity flag |
---|
176 | (valid values are between 0 and 2) print intermediate information to |
---|
177 | stdout. |
---|
178 | ] |
---|
179 | |
---|
180 | SideEffects [ ] |
---|
181 | |
---|
182 | SeeAlso [ ] |
---|
183 | **********************************************************************/ |
---|
184 | int |
---|
185 | Io_HnodeWriteBlif( |
---|
186 | Io_Encoding_Type_t encodingType, |
---|
187 | Hrc_Node_t *hnode, |
---|
188 | FILE *fp, |
---|
189 | FILE *encFp, |
---|
190 | int verbosity, |
---|
191 | int combinationalOnly, |
---|
192 | int makeLatchIOsPOs) |
---|
193 | { |
---|
194 | Tbl_Table_t *table, *singleOutputTable; |
---|
195 | Tbl_Entry_t *entry; |
---|
196 | int i, j, k, numVal, numInputs, numOutputs; |
---|
197 | Var_Variable_t *var, *actualVar, *outputVar; |
---|
198 | char *name, *instanceName, *modelName, *newModelName; |
---|
199 | st_generator *gen; |
---|
200 | st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable; |
---|
201 | st_table *encOutputsStTable, *encInputsStTable; |
---|
202 | Hrc_Node_t *subcktHnode; |
---|
203 | Hrc_Model_t *model, *subcktModel; |
---|
204 | Hrc_Subckt_t *subckt; |
---|
205 | Hrc_Manager_t *manager; |
---|
206 | array_t *subcktActualInputVars, *subcktActualOutputVars; |
---|
207 | |
---|
208 | |
---|
209 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
210 | if(_IoCheckPseudoinputIsPO(table)){ |
---|
211 | fprintf(stdout, "Hnode contains a pseudoinput which is also a primary output - quitting\n"); |
---|
212 | return 1; |
---|
213 | } |
---|
214 | for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ |
---|
215 | entry = Tbl_TableDefaultReadEntry(table, j); |
---|
216 | if(entry != NIL(Tbl_Entry_t)){ |
---|
217 | if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){ |
---|
218 | if(Tbl_EntryReadNumValues(entry) > 1){ |
---|
219 | outputVar = Tbl_TableReadIndexVar(table, j, 1); |
---|
220 | (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar)); |
---|
221 | return 1; |
---|
222 | } |
---|
223 | } |
---|
224 | else{ |
---|
225 | var = Tbl_EntryReadVar(table, entry); |
---|
226 | k = Tbl_TableReadVarIndex(table, var, 1); |
---|
227 | if(k<0){ |
---|
228 | outputVar = Tbl_TableReadIndexVar(table, j, 1); |
---|
229 | (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar)); |
---|
230 | return 1; |
---|
231 | } |
---|
232 | } |
---|
233 | } |
---|
234 | } |
---|
235 | } |
---|
236 | |
---|
237 | printedMvsStTable = st_init_table(strcmp, st_strhash); |
---|
238 | |
---|
239 | if(!(combinationalOnly || makeLatchIOsPOs)){ |
---|
240 | fprintf(encFp,"# This encoding file and the blif file that was written out with it cannot\n"); |
---|
241 | fprintf(encFp,"# currently be read back into VIS. If you would like to read the blif and\n"); |
---|
242 | fprintf(encFp,"# encoding files back into VIS, then use the 'write_blif -l' or\n"); |
---|
243 | fprintf(encFp,"#'write_blif -c' options.\n"); |
---|
244 | } |
---|
245 | |
---|
246 | /* .model */ |
---|
247 | modelName = Hrc_NodeReadModelName(hnode); |
---|
248 | manager = Hrc_NodeReadManager(hnode); |
---|
249 | model = Hrc_ManagerFindModelByName(manager, modelName); |
---|
250 | newModelName = ALLOC(char, strlen(modelName) + 256); |
---|
251 | i = 0; |
---|
252 | sprintf(newModelName, "%s[%d]", modelName, i); |
---|
253 | |
---|
254 | while(Hrc_ManagerFindModelByName(manager, newModelName) != NIL(Hrc_Model_t)){ |
---|
255 | i++; |
---|
256 | sprintf(newModelName, "%s[%d]", modelName, i); |
---|
257 | } |
---|
258 | (void)fprintf(encFp,".model %s\n",newModelName); |
---|
259 | FREE(newModelName); |
---|
260 | /* .inputs line of enc file*/ |
---|
261 | if (Hrc_NodeReadNumFormalInputs(hnode) != 0){ |
---|
262 | (void)fprintf(encFp,".inputs "); |
---|
263 | Hrc_NodeForEachFormalInput(hnode,i,var){ |
---|
264 | (void)fprintf(encFp,"%s ",Var_VariableReadName(var)); |
---|
265 | } |
---|
266 | (void)fprintf(encFp,"\n"); |
---|
267 | } |
---|
268 | |
---|
269 | /* .outputs line of enc file*/ |
---|
270 | if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){ |
---|
271 | (void)fprintf(encFp,".outputs "); |
---|
272 | Hrc_NodeForEachFormalOutput(hnode,i,var){ |
---|
273 | (void)fprintf(encFp,"%s ",Var_VariableReadName(var)); |
---|
274 | } |
---|
275 | (void)fprintf(encFp,"\n"); |
---|
276 | } |
---|
277 | |
---|
278 | /* .mv for primary inputs, printed to enc file*/ |
---|
279 | Hrc_NodeForEachFormalInput(hnode,i,var){ |
---|
280 | IoMvCheckPrint(encFp,var,printedMvsStTable); |
---|
281 | } |
---|
282 | /* .mv for primary outputs, printed to enc file*/ |
---|
283 | Hrc_NodeForEachFormalOutput(hnode,i,var){ |
---|
284 | IoMvCheckPrint(encFp,var,printedMvsStTable); |
---|
285 | } |
---|
286 | |
---|
287 | /* .subckt stuff */ |
---|
288 | Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){ |
---|
289 | subcktModel = Hrc_SubcktReadModel(subckt); |
---|
290 | subcktHnode = Hrc_ModelReadMasterNode(subcktModel); |
---|
291 | subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt); |
---|
292 | subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt); |
---|
293 | |
---|
294 | /* .mv for subckt inputs */ |
---|
295 | for (i=0; i < array_n(subcktActualInputVars); i++){ |
---|
296 | var = array_fetch(Var_Variable_t *,subcktActualInputVars,i); |
---|
297 | IoMvCheckPrint(encFp,var,printedMvsStTable); |
---|
298 | } |
---|
299 | |
---|
300 | /* .mv for subckt outputs */ |
---|
301 | for (i=0; i < array_n(subcktActualOutputVars); i++){ |
---|
302 | var = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); |
---|
303 | IoMvCheckPrint(encFp,var,printedMvsStTable); |
---|
304 | } |
---|
305 | |
---|
306 | /* .subckt declarations */ |
---|
307 | (void)fprintf(encFp,".subckt %s %s ", |
---|
308 | Hrc_ModelReadName(subcktModel), Hrc_SubcktReadInstanceName(subckt)); |
---|
309 | Hrc_NodeForEachFormalInput(subcktHnode,i,var){ |
---|
310 | actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i); |
---|
311 | (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); |
---|
312 | } |
---|
313 | Hrc_NodeForEachFormalOutput(subcktHnode,i,var){ |
---|
314 | actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); |
---|
315 | (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); |
---|
316 | } |
---|
317 | (void)fprintf(encFp,"\n"); |
---|
318 | } |
---|
319 | |
---|
320 | encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
321 | encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
322 | blifInputsStTable = st_init_table(strcmp, st_strhash); |
---|
323 | blifOutputsStTable = st_init_table(strcmp, st_strhash); |
---|
324 | |
---|
325 | /* encoding tables to .enc file */ |
---|
326 | IoEncWriteMvToBinTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly); |
---|
327 | |
---|
328 | /* decoding tables to .enc file */ |
---|
329 | IoEncWriteBinToMvTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs); |
---|
330 | |
---|
331 | /* if write_blif called without -c or -l options, then print a warning saying |
---|
332 | that the files cant be read back into vis.. |
---|
333 | */ |
---|
334 | if(!(combinationalOnly || makeLatchIOsPOs)){ |
---|
335 | fprintf(fp,"# This blif file and the encoding file that was written out with it cannot\n"); |
---|
336 | fprintf(fp,"# currently be read back into VIS. If you would like to read the blif and\n"); |
---|
337 | fprintf(fp,"# encoding files back into VIS, then use the 'write_blif -l' or\n"); |
---|
338 | fprintf(fp,"#'write_blif -c' options.\n"); |
---|
339 | } |
---|
340 | |
---|
341 | /* .inputs declarations for blif file */ |
---|
342 | fprintf(fp,".model %s\n",modelName ); |
---|
343 | numInputs = IoBlifWriteInputs(hnode, fp, blifInputsStTable, combinationalOnly, makeLatchIOsPOs); |
---|
344 | |
---|
345 | /* .outputs declarations for blif file */ |
---|
346 | numOutputs = IoBlifWriteOutputs(hnode, fp, blifOutputsStTable, combinationalOnly, makeLatchIOsPOs); |
---|
347 | |
---|
348 | if((numInputs == 0) && (numOutputs != 0)){ |
---|
349 | fprintf(vis_stderr, "Warning: Blif file has zero inputs\n"); |
---|
350 | } |
---|
351 | if((numOutputs == 0) && (numInputs != 0)){ |
---|
352 | fprintf(vis_stderr, "Warning: Blif file has zero outputs\n"); |
---|
353 | } |
---|
354 | if((numInputs == 0) && (numOutputs == 0)){ |
---|
355 | fprintf(vis_stderr, "Warning: Blif file has zero inputs and zero outputs\n"); |
---|
356 | } |
---|
357 | |
---|
358 | /* .latch declarations for blif file */ |
---|
359 | IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs, verbosity); |
---|
360 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
361 | if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){ |
---|
362 | (void)fprintf(stdout, "Warning: "); |
---|
363 | Tbl_TableForEachOutputVar(table, j, var){ |
---|
364 | (void)fprintf(stdout, "%s, ", Var_VariableReadName(var)); |
---|
365 | } |
---|
366 | (void)fprintf(stdout, "assumed to be pseudoinputs\n"); |
---|
367 | Tbl_TableForEachOutputVar(table, j, var){ |
---|
368 | singleOutputTable = Tbl_TableAlloc(); |
---|
369 | Tbl_TableAddColumn(singleOutputTable, var, 1); |
---|
370 | (void) Tbl_TableAddRow(singleOutputTable); |
---|
371 | entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); |
---|
372 | numVal = Var_VariableReadNumValues(var); |
---|
373 | Tbl_EntrySetValue(entry, 0, numVal - 1); |
---|
374 | Tbl_TableSetEntry(singleOutputTable, entry, 0, 0, 1); |
---|
375 | _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, |
---|
376 | verbosity); |
---|
377 | Tbl_TableFree(singleOutputTable); |
---|
378 | } |
---|
379 | } |
---|
380 | else{ |
---|
381 | if(IoOutputExpansionRequired(table)){ |
---|
382 | if(verbosity > 0){ |
---|
383 | (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n"); |
---|
384 | } |
---|
385 | for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ |
---|
386 | singleOutputTable = IoMakeSingleOutputTable(table, j); |
---|
387 | _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, |
---|
388 | verbosity); |
---|
389 | Tbl_TableFree(singleOutputTable); |
---|
390 | } |
---|
391 | } |
---|
392 | else{ |
---|
393 | if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){ |
---|
394 | _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp, |
---|
395 | verbosity); |
---|
396 | } |
---|
397 | } |
---|
398 | } |
---|
399 | } |
---|
400 | st_foreach_item_int(blifInputsStTable, gen, &name, &i){ |
---|
401 | FREE(name); |
---|
402 | } |
---|
403 | st_free_table(blifInputsStTable); |
---|
404 | st_foreach_item_int(blifOutputsStTable, gen, &name, &i){ |
---|
405 | FREE(name); |
---|
406 | } |
---|
407 | st_free_table(blifOutputsStTable); |
---|
408 | st_free_table(encInputsStTable); |
---|
409 | st_free_table(encOutputsStTable); |
---|
410 | st_foreach_item_int(printedMvsStTable, gen, &name, &i){ |
---|
411 | FREE(name); |
---|
412 | } |
---|
413 | st_free_table(printedMvsStTable); |
---|
414 | /* printing an empty .exdc network keeps sis from sweeping away the |
---|
415 | dummy buffers that latch outputs are made to drive as a result of the |
---|
416 | "write_blif -l" cmd. The dummy buffers were added because if they were |
---|
417 | not present, sis would introduce buffers whenever latch outputs drive POs |
---|
418 | directly (in the "xdc" command), ruining the name correspondence required |
---|
419 | for read_blif to work and reinstate mv latches. |
---|
420 | */ |
---|
421 | fprintf(fp,".exdc\n"); |
---|
422 | fprintf(fp,".end\n"); |
---|
423 | if(encFp != stdout){ |
---|
424 | (void) fclose(encFp); |
---|
425 | } |
---|
426 | return 0; |
---|
427 | } |
---|
428 | |
---|
429 | |
---|
430 | /*---------------------------------------------------------------------------*/ |
---|
431 | /* Definition of internal functions */ |
---|
432 | /*---------------------------------------------------------------------------*/ |
---|
433 | |
---|
434 | |
---|
435 | /*---------------------------------------------------------------------------*/ |
---|
436 | /* Definition of static functions */ |
---|
437 | /*---------------------------------------------------------------------------*/ |
---|
438 | |
---|
439 | |
---|
440 | /**Function*********************************************************** |
---|
441 | |
---|
442 | |
---|
443 | Synopsis [ Determinize, encode and write a blifmv table to blif file ] |
---|
444 | |
---|
445 | Description [ Note that this routine cannot handle the "=" construct of |
---|
446 | blifmv. It is my opinion that a front-end routine should be |
---|
447 | used to remove the "="'s. ] |
---|
448 | |
---|
449 | SideEffects [ ] |
---|
450 | |
---|
451 | SeeAlso [ ] |
---|
452 | **********************************************************************/ |
---|
453 | static int |
---|
454 | _IoTableWriteBlif( |
---|
455 | Io_Encoding_Type_t encodingType, |
---|
456 | Hrc_Node_t *hnode, |
---|
457 | Tbl_Table_t *origBlifmvTable, |
---|
458 | st_table *blifInputsStTable, |
---|
459 | FILE *fp, |
---|
460 | FILE *encFp, |
---|
461 | int verbosity ) |
---|
462 | { |
---|
463 | IoBlifInfo_t *blifInfo; |
---|
464 | |
---|
465 | blifInfo = ALLOC(IoBlifInfo_t, 1); |
---|
466 | if(verbosity > 1){ |
---|
467 | (void)fprintf(stdout, "Original Blifmv Table :\n"); |
---|
468 | Tbl_TableWriteBlifMvToFile(origBlifmvTable, 0, stdout); |
---|
469 | } |
---|
470 | IoInitBlifInfo(blifInfo, origBlifmvTable, fp, encFp, verbosity); |
---|
471 | if(encodingType == SIMPLE){ |
---|
472 | if(_IoMakeInitialEncodings(blifInfo, hnode)){ |
---|
473 | blifInfo->binTblArray = array_alloc(Tbl_Table_t *, 0); |
---|
474 | IoFreeBlifInfo(blifInfo); |
---|
475 | return 0; |
---|
476 | } |
---|
477 | _IoDeterminizeEncodeOutputPart(blifInfo, blifInputsStTable); |
---|
478 | _IoMakeBinTable(blifInfo); |
---|
479 | if(blifInfo->verbosity > 0){ |
---|
480 | (void)fprintf(stdout, "Done with Output Singletonization\n"); |
---|
481 | } |
---|
482 | if(blifInfo->verbosity > 1){ |
---|
483 | (void)fprintf(stdout, "Final Blifmv Table After Output Singletonization:\n"); |
---|
484 | Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout); |
---|
485 | (void)fprintf(stdout, "Bin Table After Output Singletonization:\n"); |
---|
486 | Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); |
---|
487 | } |
---|
488 | _IoDeterminizeEncodeRows(blifInfo, blifInputsStTable); |
---|
489 | if(blifInfo->verbosity > 0){ |
---|
490 | (void)fprintf(stdout, "Done with Row Intersection and Determinization\n"); |
---|
491 | } |
---|
492 | if(blifInfo->verbosity > 1){ |
---|
493 | (void)fprintf(stdout, "Final Bin Table After Determinization \n"); |
---|
494 | Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); |
---|
495 | } |
---|
496 | _IoMakeDcTables(blifInfo); |
---|
497 | blifInfo->binTblArray = Tbl_TableSplit(blifInfo->binTable); |
---|
498 | IoWriteBinTablesToFile(blifInfo); |
---|
499 | IoFreeBlifInfo(blifInfo); |
---|
500 | return 0; |
---|
501 | } |
---|
502 | else{ |
---|
503 | (void)fprintf(vis_stderr, "This encoding strategy has not been implemented yet\n"); |
---|
504 | return 1; |
---|
505 | } |
---|
506 | } |
---|
507 | |
---|
508 | |
---|
509 | /**Function******************************************************************** |
---|
510 | |
---|
511 | Synopsis [Encodes variables based on their ranges] |
---|
512 | |
---|
513 | Description [Returns encodings in the form of an array of tables for each |
---|
514 | multivalued variable. ] |
---|
515 | |
---|
516 | SideEffects [Populates the array of tables describing the encoding] |
---|
517 | |
---|
518 | SeeAlso [] |
---|
519 | |
---|
520 | ******************************************************************************/ |
---|
521 | static int |
---|
522 | _IoMakeInitialEncodings( |
---|
523 | IoBlifInfo_t *blifInfo, |
---|
524 | Hrc_Node_t *hnode |
---|
525 | ) |
---|
526 | { |
---|
527 | Var_Variable_t *var, *origVar; |
---|
528 | int i, colnum, numRows, numValues, varRange, value, numEncBits; |
---|
529 | char *name, *varname, *dupName; |
---|
530 | Tbl_Entry_t *entry, *newEntry, *defEntry, *newDefEntry; |
---|
531 | lsGen gen; |
---|
532 | Tbl_Range_t *range; |
---|
533 | Tbl_Table_t *table, *origTable; |
---|
534 | |
---|
535 | if(Tbl_TableReadNumInputs(blifInfo->blifmvTable) == 0){ |
---|
536 | value = -1; |
---|
537 | if(Tbl_TableReadNumRows(blifInfo->blifmvTable) != 0){ |
---|
538 | entry = Tbl_TableReadEntry(blifInfo->blifmvTable, 0, 0, 1); |
---|
539 | numValues = Tbl_EntryReadNumValues(entry); |
---|
540 | } |
---|
541 | else{ |
---|
542 | entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, 0); |
---|
543 | numValues = Tbl_EntryReadNumValues(entry); |
---|
544 | } |
---|
545 | origTable = Tbl_TableHardDup(blifInfo->blifmvTable); |
---|
546 | |
---|
547 | if(Tbl_TableReadNumRows(blifInfo->blifmvTable) <= 1){ |
---|
548 | if(numValues == 1){ |
---|
549 | /* not a pseudoinput */ |
---|
550 | Tbl_EntryForEachValue(entry, value, gen, range); |
---|
551 | assert(value != -1); |
---|
552 | var = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1); |
---|
553 | varRange = Var_VariableReadNumValues(var); |
---|
554 | numEncBits = IoNumEncBits(varRange); |
---|
555 | varname = Var_VariableReadName(var); |
---|
556 | for(i = numEncBits - 1; i >= 0; i--){ |
---|
557 | dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); |
---|
558 | sprintf(dupName, "%s%d", varname, i); |
---|
559 | (void)fprintf(blifInfo->BlifFp, ".names %s\n", dupName); |
---|
560 | FREE(dupName); |
---|
561 | if(value > (int) pow((double) 2, (double) i)){ |
---|
562 | (void)fprintf(blifInfo->BlifFp, "1\n"); |
---|
563 | value -= (int) pow((double) 2, (double) i); |
---|
564 | } |
---|
565 | else{ |
---|
566 | (void)fprintf(blifInfo->BlifFp, "0\n"); |
---|
567 | } |
---|
568 | } |
---|
569 | Tbl_TableFree(origTable); |
---|
570 | return 1; |
---|
571 | } |
---|
572 | else{ |
---|
573 | /* is a pseudoinput! */ |
---|
574 | /* make it look like a table with many rows, and singleton output entries per row */ |
---|
575 | table = Tbl_TableAlloc(); |
---|
576 | |
---|
577 | Tbl_TableForEachOutputVar(blifInfo->blifmvTable, i, var){ |
---|
578 | Tbl_TableAddColumn(table, var, 1); |
---|
579 | } |
---|
580 | Tbl_TableForEachDefaultEntry(blifInfo->blifmvTable, defEntry, i) { |
---|
581 | if (defEntry != NIL(Tbl_Entry_t)) { |
---|
582 | newDefEntry = Tbl_EntryDup(defEntry); |
---|
583 | } |
---|
584 | else { |
---|
585 | newDefEntry = NIL(Tbl_Entry_t); |
---|
586 | } |
---|
587 | (void) Tbl_TableDefaultSetEntry(table, newDefEntry, i); |
---|
588 | } |
---|
589 | Tbl_EntryForEachValue(entry, value, gen, range){ |
---|
590 | i = Tbl_TableAddRow(table); |
---|
591 | newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c); |
---|
592 | Tbl_EntrySetValue(newEntry, value, value); |
---|
593 | Tbl_TableSetEntry(table, newEntry, i, 0, 1); |
---|
594 | } |
---|
595 | Tbl_TableFree(blifInfo->blifmvTable); |
---|
596 | blifInfo->blifmvTable = table; |
---|
597 | } |
---|
598 | } |
---|
599 | /* it is a pseudoinput, and has been singletonized wrt outputs */ |
---|
600 | if(Tbl_TableReadNumRows(blifInfo->blifmvTable) > 1){ |
---|
601 | name = ALLOC(char, 256); |
---|
602 | i = 0; |
---|
603 | sprintf(name, "[%d]", i); |
---|
604 | while(!(Hrc_NodeFindVariableByName(hnode, name) == NULL)){ |
---|
605 | i++; |
---|
606 | sprintf(name, "[%d]", i); |
---|
607 | } |
---|
608 | |
---|
609 | blifInfo->pseudoinputFlag = TRUE; |
---|
610 | var = Var_VariableAlloc(hnode, name); |
---|
611 | Tbl_TableAddColumn(blifInfo->blifmvTable, var, 0); |
---|
612 | (void)fprintf(blifInfo->BlifFp, ".inputs %s0\n", name); |
---|
613 | origVar = Tbl_TableReadIndexVar(origTable, 0, 1); |
---|
614 | IoMvPrint(blifInfo->EncFp, origVar); |
---|
615 | Tbl_TableWriteBlifMvToFile(origTable, 0, blifInfo->EncFp); |
---|
616 | Tbl_TableFree(origTable); |
---|
617 | numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); |
---|
618 | for(i = 0; i < numRows; i++){ |
---|
619 | if(i % 2 == 1){ |
---|
620 | entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); |
---|
621 | Tbl_EntrySetValue(entry, 1, 1); |
---|
622 | Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0); |
---|
623 | } |
---|
624 | else{ |
---|
625 | entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); |
---|
626 | Tbl_EntrySetValue(entry, 0, 0); |
---|
627 | Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0); |
---|
628 | } |
---|
629 | } |
---|
630 | FREE(name); |
---|
631 | } |
---|
632 | } |
---|
633 | |
---|
634 | Tbl_TableForEachInputVar(blifInfo->blifmvTable, colnum, var){ |
---|
635 | IoEncodeVariable(blifInfo, var, colnum, 0); |
---|
636 | } |
---|
637 | |
---|
638 | Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){ |
---|
639 | IoEncodeVariable(blifInfo, var, colnum, 1); |
---|
640 | } |
---|
641 | return 0; |
---|
642 | } |
---|
643 | |
---|
644 | |
---|
645 | /**Function******************************************************************** |
---|
646 | |
---|
647 | Synopsis [Encodes variables to make singleton output values in every row] |
---|
648 | |
---|
649 | Description [Returns modified table along with a modified array of tables for |
---|
650 | encoding the multivalued variables. If the original table |
---|
651 | has singleton output values then it is returned unmodified, |
---|
652 | with the unmodified variable encoding tables.] |
---|
653 | |
---|
654 | SideEffects [Potentially modifies the array of tables describing the encoding] |
---|
655 | |
---|
656 | SeeAlso [] |
---|
657 | |
---|
658 | ******************************************************************************/ |
---|
659 | static void |
---|
660 | _IoDeterminizeEncodeOutputPart( |
---|
661 | IoBlifInfo_t *blifInfo, |
---|
662 | st_table *blifInputsStTable |
---|
663 | ) |
---|
664 | { |
---|
665 | Tbl_Entry_t *entry; |
---|
666 | int numValues, i, j, numRows, numOutputs; |
---|
667 | IoVarEncEntry_t *varEnc; |
---|
668 | array_t *MvOutputArray; |
---|
669 | |
---|
670 | numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); |
---|
671 | numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable); |
---|
672 | for(i = 0; i < numRows; i++){ |
---|
673 | MvOutputArray = array_alloc(int, 0); |
---|
674 | numValues = 1; |
---|
675 | for(j = 0; j < numOutputs; j++){ |
---|
676 | entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, j, 1); |
---|
677 | numValues *= Tbl_EntryReadNumValues(entry); |
---|
678 | array_insert_last(int, MvOutputArray, Tbl_EntryReadNumValues(entry)); |
---|
679 | } |
---|
680 | if(numValues > 1){ |
---|
681 | varEnc = IoFindSmallestCode(blifInfo); |
---|
682 | if(blifInfo->verbosity > 2){ |
---|
683 | (void)fprintf(stdout, "Singletonizing Outputs in Row %d\n", i); |
---|
684 | (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable)); |
---|
685 | } |
---|
686 | IoIncreaseCodeSize(varEnc, numValues, blifInfo->verbosity); |
---|
687 | IoChangeBlifmvTableEntries(blifInfo, i, numValues, varEnc, MvOutputArray); |
---|
688 | IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, numValues); |
---|
689 | i = -1; |
---|
690 | array_free(MvOutputArray); |
---|
691 | |
---|
692 | if(blifInfo->verbosity > 2){ |
---|
693 | (void)fprintf(stdout, "Blifmv Table After Output Singletonization\n"); |
---|
694 | Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout); |
---|
695 | } |
---|
696 | } |
---|
697 | else{ |
---|
698 | array_free(MvOutputArray); |
---|
699 | } |
---|
700 | } |
---|
701 | } |
---|
702 | |
---|
703 | |
---|
704 | /**Function******************************************************************** |
---|
705 | |
---|
706 | Synopsis [Encodes variables to make table deterministic] |
---|
707 | |
---|
708 | Description [Returns modified table along with a modified array of tables for |
---|
709 | encoding the multivalued variables. If the original table |
---|
710 | is deterministic, then it is returned unmodified, |
---|
711 | with the unmodified variable encoding tables.] |
---|
712 | |
---|
713 | SideEffects [Potentially modifies the array of tables describing the encoding] |
---|
714 | |
---|
715 | SeeAlso [] |
---|
716 | |
---|
717 | ******************************************************************************/ |
---|
718 | static void |
---|
719 | _IoDeterminizeEncodeRows( |
---|
720 | IoBlifInfo_t *blifInfo, |
---|
721 | st_table *blifInputsStTable |
---|
722 | ) |
---|
723 | { |
---|
724 | int i, j, k, numRows, numOutputs, numInputs, mvValue; |
---|
725 | boolean rowsIntersect; |
---|
726 | IoVarEncEntry_t *varEnc; |
---|
727 | char *pseudoInputName, *realPseudoInputName; |
---|
728 | Var_Variable_t *outvar, *var, *origVar; |
---|
729 | Tbl_Entry_t *entry; |
---|
730 | |
---|
731 | |
---|
732 | numRows = Tbl_TableReadNumRows(blifInfo->binTable); |
---|
733 | for(i = 0; i < numRows; i++){ |
---|
734 | for(j = i + 1; j < numRows; j++){ |
---|
735 | if(blifInfo->verbosity > 2){ |
---|
736 | (void)fprintf(stdout, "Intersecting Rows %d and %d \n", i, j); |
---|
737 | } |
---|
738 | rowsIntersect = Tbl_RowInputIntersect(blifInfo->binTable, i, j); |
---|
739 | if(rowsIntersect == 1){ |
---|
740 | if(blifInfo->verbosity > 2){ |
---|
741 | (void)fprintf(stdout, "Input Intersection non-null\n"); |
---|
742 | } |
---|
743 | if(!Tbl_RowOutputIntersect(blifInfo->binTable, i, j)){ |
---|
744 | varEnc = IoFindSmallestCode(blifInfo); |
---|
745 | if(blifInfo->verbosity > 2){ |
---|
746 | (void)fprintf(stdout, "Output Intersection null\n"); |
---|
747 | (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable)); |
---|
748 | |
---|
749 | } |
---|
750 | IoIncreaseCodeSize(varEnc, 2, blifInfo->verbosity); |
---|
751 | IoChangeBlifmvTableRows(blifInfo, varEnc, i, j); |
---|
752 | IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, 2); |
---|
753 | |
---|
754 | if(blifInfo->verbosity > 2){ |
---|
755 | (void)fprintf(stdout, "Bin Table After Row Overlap elimination \n"); |
---|
756 | Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); |
---|
757 | } |
---|
758 | } |
---|
759 | } |
---|
760 | } |
---|
761 | } |
---|
762 | if(blifInfo->pseudoinputFlag == TRUE){ |
---|
763 | /* pseudoinput cant have .def construct */ |
---|
764 | outvar = Tbl_TableReadIndexVar(blifInfo->binTable, 0, 1); |
---|
765 | pseudoInputName = Var_VariableReadName(outvar); |
---|
766 | realPseudoInputName = ALLOC(char, strlen(pseudoInputName) + 2); |
---|
767 | sprintf(realPseudoInputName, "%s", pseudoInputName); |
---|
768 | realPseudoInputName[strlen(pseudoInputName) - 1] = '\0'; |
---|
769 | numOutputs = Tbl_TableReadNumOutputs(blifInfo->binTable); |
---|
770 | numInputs = Tbl_TableReadNumInputs(blifInfo->binTable); |
---|
771 | for(i = 0; i < numInputs; i++){ |
---|
772 | (void)fprintf(blifInfo->EncFp, ".table %s ->", realPseudoInputName); |
---|
773 | var = Tbl_TableReadIndexVar(blifInfo->binTable, i, 0); |
---|
774 | (void)fprintf(blifInfo->EncFp, "%s\n", Var_VariableReadName(var)); |
---|
775 | (void)fprintf(blifInfo->EncFp, ".default 0\n"); |
---|
776 | for(j = 0; j < numRows; j++){ |
---|
777 | mvValue = 0; |
---|
778 | for(k = 0; k < numOutputs; k++){ |
---|
779 | entry = Tbl_TableReadEntry(blifInfo->binTable, j, k, 1); |
---|
780 | if(Tbl_EntryCheckRange(entry, 1, 1)){ |
---|
781 | mvValue += (int) pow((double)2, (double) k); |
---|
782 | } |
---|
783 | } |
---|
784 | origVar = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1); |
---|
785 | if(Var_VariableTestIsSymbolic(origVar)){ |
---|
786 | (void)fprintf(blifInfo->EncFp, "%s ", |
---|
787 | Var_VariableReadSymbolicValueFromIndex(origVar, mvValue)); |
---|
788 | } |
---|
789 | else{ |
---|
790 | (void)fprintf(blifInfo->EncFp, "%d ", mvValue); |
---|
791 | } |
---|
792 | |
---|
793 | entry = Tbl_TableReadEntry(blifInfo->binTable, j, i, 0); |
---|
794 | if(Tbl_EntryCheckRange(entry, 1, 1)){ |
---|
795 | (void)fprintf(blifInfo->EncFp, "%d\n", 1); |
---|
796 | } |
---|
797 | else{ |
---|
798 | if(Tbl_EntryCheckRange(entry, 0, 0)){ |
---|
799 | (void)fprintf(blifInfo->EncFp, "%d\n", 0); |
---|
800 | } |
---|
801 | else{ |
---|
802 | (void)fprintf(blifInfo->EncFp, "-\n"); |
---|
803 | } |
---|
804 | } |
---|
805 | } |
---|
806 | } |
---|
807 | FREE(realPseudoInputName); |
---|
808 | } |
---|
809 | } |
---|
810 | |
---|
811 | |
---|
812 | /**Function******************************************************************** |
---|
813 | |
---|
814 | Synopsis [Creates Dont-Care Tables for Variable Encodings] |
---|
815 | |
---|
816 | Description [For each table in the blifInfo->inputEncTblArray, this |
---|
817 | function creates dont-care tables] |
---|
818 | |
---|
819 | SideEffects [] |
---|
820 | |
---|
821 | SeeAlso [] |
---|
822 | |
---|
823 | ******************************************************************************/ |
---|
824 | static void |
---|
825 | _IoMakeDcTables( |
---|
826 | IoBlifInfo_t *blifInfo |
---|
827 | ) |
---|
828 | { |
---|
829 | } |
---|
830 | |
---|
831 | |
---|
832 | |
---|
833 | /**Function******************************************************************** |
---|
834 | |
---|
835 | Synopsis [Writes out blifmvTable to binTable in encoded form] |
---|
836 | |
---|
837 | Description [] |
---|
838 | |
---|
839 | SideEffects [] |
---|
840 | |
---|
841 | SeeAlso [] |
---|
842 | |
---|
843 | ******************************************************************************/ |
---|
844 | static void |
---|
845 | _IoMakeBinTable( |
---|
846 | IoBlifInfo_t *blifInfo |
---|
847 | ) |
---|
848 | { |
---|
849 | int i, j, k, m, n, colnum, numRowsAfterExpansion, numEncBits; |
---|
850 | int rootCol, rootRow, entryRepetitionCount, numCycles, value, numBits, currRow; |
---|
851 | int numOutputs, numRows, numInputs, defValue, varRange; |
---|
852 | Tbl_Entry_t *entry, *workingEntry; |
---|
853 | array_t *binRangesArray, *mvEntryBinRanges; |
---|
854 | IoVarEncEntry_t *varEnc; |
---|
855 | char *varname, *dupName; |
---|
856 | Var_Variable_t *var; |
---|
857 | lsGen gen, gen2; |
---|
858 | Tbl_Range_t *range, *range2; |
---|
859 | IoBinRangeEntry_t *binRangeEntry; |
---|
860 | |
---|
861 | |
---|
862 | /* initialize the binTable, defining input vars etc */ |
---|
863 | |
---|
864 | numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); |
---|
865 | numInputs = Tbl_TableReadNumInputs(blifInfo->blifmvTable); |
---|
866 | numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable); |
---|
867 | for(j = 0; j < Tbl_TableReadNumInputs(blifInfo->blifmvTable); j++){ |
---|
868 | varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, j); |
---|
869 | numEncBits = varEnc->numEncBits; |
---|
870 | for(k = 0; k < numEncBits ; k++){ |
---|
871 | varname = Var_VariableReadName(varEnc->variable); |
---|
872 | dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); |
---|
873 | sprintf(dupName, "%s%d", varname, k); |
---|
874 | var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName); |
---|
875 | FREE(dupName); |
---|
876 | array_insert_last(Var_Variable_t *, blifInfo->varArray, var); |
---|
877 | colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 0); |
---|
878 | } |
---|
879 | } |
---|
880 | |
---|
881 | for(j = 0; j < Tbl_TableReadNumOutputs(blifInfo->blifmvTable); j++){ |
---|
882 | varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->outputEncTblArray, j); |
---|
883 | numEncBits = varEnc->numEncBits; |
---|
884 | for(k = 0; k < numEncBits ; k++){ |
---|
885 | varname = Var_VariableReadName(varEnc->variable); |
---|
886 | dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); |
---|
887 | sprintf(dupName, "%s%d", varname, k); |
---|
888 | var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName); |
---|
889 | FREE(dupName); |
---|
890 | array_insert_last(Var_Variable_t *, blifInfo->varArray, var); |
---|
891 | colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 1); |
---|
892 | } |
---|
893 | } |
---|
894 | |
---|
895 | |
---|
896 | /* |
---|
897 | fprintf(stdout, "\n"); |
---|
898 | */ |
---|
899 | for(i = 0; i < numRows; i++){ |
---|
900 | |
---|
901 | /* make temp array of number of values for each input var */ |
---|
902 | numRowsAfterExpansion = 1; |
---|
903 | binRangesArray = array_alloc(array_t *, 0); |
---|
904 | |
---|
905 | for(colnum = 0; colnum < numInputs; colnum++){ |
---|
906 | entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 0); |
---|
907 | workingEntry = Tbl_EntryDup(entry); |
---|
908 | mvEntryBinRanges = IoMakeBinaryRangesArray(workingEntry, colnum, blifInfo); |
---|
909 | numRowsAfterExpansion *= array_n(mvEntryBinRanges); |
---|
910 | array_insert_last(array_t *, binRangesArray, mvEntryBinRanges); |
---|
911 | } |
---|
912 | |
---|
913 | /* |
---|
914 | for(j = 0; j < array_n(binRangesArray); j++){ |
---|
915 | mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j); |
---|
916 | for(k = 0; k < array_n(mvEntryBinRanges); k++){ |
---|
917 | binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, k); |
---|
918 | fprintf(stdout, "start %d\t runlen%d\t skip %d\n", binRangeEntry->startValue, binRangeEntry->runLength, binRangeEntry->skipLength); |
---|
919 | } |
---|
920 | (void)fprintf(stdout, "\n"); |
---|
921 | } |
---|
922 | fprintf(stdout, "numRowsAfterExpansion %d\n", numRowsAfterExpansion); |
---|
923 | |
---|
924 | */ |
---|
925 | /* add numRowsAfterExpansion rows to binTable */ |
---|
926 | |
---|
927 | rootCol = 0; |
---|
928 | rootRow = Tbl_TableReadNumRows(blifInfo->binTable); |
---|
929 | for(j = 0; j < numRowsAfterExpansion; j++){ |
---|
930 | Tbl_TableAddRow(blifInfo->binTable); |
---|
931 | } |
---|
932 | |
---|
933 | /* write out binary encoded variable values for the determinized, encoded blifmvTable |
---|
934 | (input parts) */ |
---|
935 | |
---|
936 | entryRepetitionCount = numRowsAfterExpansion; |
---|
937 | m = 0; |
---|
938 | numCycles = 1; |
---|
939 | |
---|
940 | for(colnum = 0; colnum < numInputs; colnum++){ |
---|
941 | mvEntryBinRanges = array_fetch(array_t *, binRangesArray, colnum); |
---|
942 | currRow = rootRow; |
---|
943 | rootCol += IoNumBinVars(colnum, blifInfo->inputEncTblArray); |
---|
944 | entryRepetitionCount = entryRepetitionCount / array_n(array_fetch(array_t *, binRangesArray, m)); |
---|
945 | numCycles *= IoNumValuesFromBinRangesArray(colnum, binRangesArray); |
---|
946 | numBits = IoNumBinVars(colnum + 1, blifInfo->inputEncTblArray); |
---|
947 | for(k=0; k<numCycles; k++){ |
---|
948 | for(n = 0; n < array_n(mvEntryBinRanges); n++){ |
---|
949 | binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n); |
---|
950 | IoWriteExpandedValueToBinTable(blifInfo->binTable, currRow, rootCol, binRangeEntry, entryRepetitionCount, numBits, 0); |
---|
951 | currRow = currRow + entryRepetitionCount; |
---|
952 | } |
---|
953 | } |
---|
954 | m++; |
---|
955 | } |
---|
956 | |
---|
957 | /* write out binary encoded variable values for the determinized, encoded blifmvTable |
---|
958 | (output parts) */ |
---|
959 | |
---|
960 | rootCol = 0; |
---|
961 | |
---|
962 | for(colnum = 0; colnum < numOutputs; colnum++){ |
---|
963 | entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 1); |
---|
964 | rootCol += IoNumBinVars(colnum, blifInfo->outputEncTblArray); |
---|
965 | numBits = IoNumBinVars(colnum + 1, blifInfo->outputEncTblArray); |
---|
966 | Tbl_EntryForEachValue(entry, value, gen, range){ |
---|
967 | binRangeEntry = ALLOC(IoBinRangeEntry_t, 1); |
---|
968 | binRangeEntry->startValue = value; |
---|
969 | binRangeEntry->runLength = 1; |
---|
970 | binRangeEntry->skipLength = 1; |
---|
971 | IoWriteExpandedValueToBinTable(blifInfo->binTable, rootRow, rootCol, binRangeEntry, numRowsAfterExpansion, numBits, 1); |
---|
972 | FREE(binRangeEntry); |
---|
973 | } |
---|
974 | } |
---|
975 | for(j = 0; j < array_n(binRangesArray); j++){ |
---|
976 | mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j); |
---|
977 | for(n = 0; n < array_n(mvEntryBinRanges); n++){ |
---|
978 | binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n); |
---|
979 | FREE(binRangeEntry); |
---|
980 | } |
---|
981 | array_free(mvEntryBinRanges); |
---|
982 | } |
---|
983 | array_free(binRangesArray); |
---|
984 | } |
---|
985 | |
---|
986 | rootCol = 0; |
---|
987 | Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){ |
---|
988 | entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, colnum); |
---|
989 | if(entry != NIL(Tbl_Entry_t)){ |
---|
990 | varRange = Var_VariableReadNumValues(var); |
---|
991 | numEncBits = IoNumEncBits(varRange); |
---|
992 | defValue = -1; |
---|
993 | Tbl_EntryForEachValue(entry, value, gen2, range2){ |
---|
994 | defValue = value; |
---|
995 | assert(defValue != -1); |
---|
996 | } |
---|
997 | for(j = numEncBits - 1; j >= 0; j--){ |
---|
998 | if(((int)(defValue / pow((double) 2, (double) j))) == 1){ |
---|
999 | IoInvertBinTableOutput(blifInfo, rootCol + j); |
---|
1000 | defValue = defValue - (int)pow((double)2,(double)j); |
---|
1001 | } |
---|
1002 | } |
---|
1003 | rootCol += numEncBits; |
---|
1004 | } |
---|
1005 | } |
---|
1006 | } |
---|
1007 | |
---|
1008 | |
---|
1009 | /**Function******************************************************************** |
---|
1010 | |
---|
1011 | Synopsis [Checks that all hnodes rooted at the give hnode are boolean and |
---|
1012 | deterministic] |
---|
1013 | |
---|
1014 | Description [] |
---|
1015 | |
---|
1016 | SideEffects [] |
---|
1017 | |
---|
1018 | SeeAlso [] |
---|
1019 | |
---|
1020 | ******************************************************************************/ |
---|
1021 | static int |
---|
1022 | _IoCheckHnodeTreeIsBooleanAndDeterministic( |
---|
1023 | mdd_manager **mddMgr, |
---|
1024 | Hrc_Node_t *hnode, |
---|
1025 | st_table *modelTable, |
---|
1026 | boolean *pSymVarsPresent, |
---|
1027 | int verbosity |
---|
1028 | ) |
---|
1029 | { |
---|
1030 | char *modelName, *childName; |
---|
1031 | Hrc_Model_t *model; |
---|
1032 | st_generator *stGen; |
---|
1033 | Hrc_Manager_t *manager; |
---|
1034 | Hrc_Node_t *childNode; |
---|
1035 | |
---|
1036 | manager = Hrc_NodeReadManager(hnode); |
---|
1037 | /* enter current model in modelTable */ |
---|
1038 | modelName = Hrc_NodeReadModelName(hnode); |
---|
1039 | model = Hrc_ManagerFindModelByName(manager, modelName); |
---|
1040 | if(st_is_member(modelTable, (char *) model)){ |
---|
1041 | return 0; |
---|
1042 | } |
---|
1043 | else{ |
---|
1044 | st_insert(modelTable, (char *)model, (char *) (long) (-1)); |
---|
1045 | } |
---|
1046 | |
---|
1047 | if(_IoCheckHnodeIsBooleanAndDeterministic(mddMgr, hnode, pSymVarsPresent)){ |
---|
1048 | if(verbosity > 1){ |
---|
1049 | fprintf(vis_stderr, "Model %s is NOT boolean and deterministic\n", modelName); |
---|
1050 | } |
---|
1051 | return 1; |
---|
1052 | } |
---|
1053 | if(verbosity > 1){ |
---|
1054 | fprintf(vis_stderr, "Model %s is boolean and deterministic\n", modelName); |
---|
1055 | } |
---|
1056 | Hrc_NodeForEachChild(hnode, stGen, childName, childNode){ |
---|
1057 | if(_IoCheckHnodeTreeIsBooleanAndDeterministic(mddMgr, childNode, modelTable, pSymVarsPresent, verbosity)){ |
---|
1058 | st_free_gen(stGen); |
---|
1059 | return 1; |
---|
1060 | } |
---|
1061 | } |
---|
1062 | return 0; |
---|
1063 | } |
---|
1064 | |
---|
1065 | |
---|
1066 | /**Function******************************************************************** |
---|
1067 | |
---|
1068 | Synopsis [Checks that the given hnode is boolean and deterministic] |
---|
1069 | |
---|
1070 | Description [] |
---|
1071 | |
---|
1072 | SideEffects [] |
---|
1073 | |
---|
1074 | SeeAlso [] |
---|
1075 | |
---|
1076 | ******************************************************************************/ |
---|
1077 | static int |
---|
1078 | _IoCheckHnodeIsBooleanAndDeterministic( |
---|
1079 | mdd_manager **mddMgr, |
---|
1080 | Hrc_Node_t *hnode, |
---|
1081 | boolean *pSymVarsPresent |
---|
1082 | ) |
---|
1083 | { |
---|
1084 | |
---|
1085 | /* check that variables of all models are boolean */ |
---|
1086 | if(_IoCheckHnodeVarsAreBoolean(hnode, pSymVarsPresent)){ |
---|
1087 | return 1; |
---|
1088 | } |
---|
1089 | |
---|
1090 | /* check that latch resets of all models are either 0/1/2 */ |
---|
1091 | if(_IoCheckHnodeLatchResetIsConstant(hnode)){ |
---|
1092 | return 1; |
---|
1093 | } |
---|
1094 | |
---|
1095 | /* check that tables of all models are deterministic */ |
---|
1096 | if(_IoCheckHnodeTablesAreDeterministic(mddMgr, hnode)){ |
---|
1097 | return 1; |
---|
1098 | } |
---|
1099 | |
---|
1100 | return 0; |
---|
1101 | } |
---|
1102 | |
---|
1103 | /**Function******************************************************************** |
---|
1104 | |
---|
1105 | Synopsis [Checks that the variables of a model are boolean] |
---|
1106 | |
---|
1107 | Description [] |
---|
1108 | |
---|
1109 | SideEffects [] |
---|
1110 | |
---|
1111 | SeeAlso [] |
---|
1112 | |
---|
1113 | ******************************************************************************/ |
---|
1114 | static int |
---|
1115 | _IoCheckHnodeVarsAreBoolean( |
---|
1116 | Hrc_Node_t *hnode, |
---|
1117 | boolean *pSymVarsPresent |
---|
1118 | ) |
---|
1119 | { |
---|
1120 | st_generator *stGen; |
---|
1121 | char *varName; |
---|
1122 | Var_Variable_t *var; |
---|
1123 | |
---|
1124 | Hrc_NodeForEachVariable(hnode, stGen, varName, var){ |
---|
1125 | if(Var_VariableReadNumValues(var) > 2){ |
---|
1126 | fprintf(vis_stderr, "Variable %s is not boolean - quitting.\n", varName); |
---|
1127 | st_free_gen(stGen); |
---|
1128 | return 1; |
---|
1129 | } |
---|
1130 | if(Var_VariableTestIsSymbolic(var)){ |
---|
1131 | *pSymVarsPresent = TRUE; |
---|
1132 | } |
---|
1133 | } |
---|
1134 | return 0; |
---|
1135 | } |
---|
1136 | |
---|
1137 | |
---|
1138 | /**Function******************************************************************** |
---|
1139 | |
---|
1140 | Synopsis [Checks that the latches of a model have constant reset tables] |
---|
1141 | |
---|
1142 | Description [] |
---|
1143 | |
---|
1144 | SideEffects [] |
---|
1145 | |
---|
1146 | SeeAlso [] |
---|
1147 | |
---|
1148 | ******************************************************************************/ |
---|
1149 | static int |
---|
1150 | _IoCheckHnodeLatchResetIsConstant( |
---|
1151 | Hrc_Node_t *hnode |
---|
1152 | ) |
---|
1153 | { |
---|
1154 | st_generator *stGen; |
---|
1155 | char *latchName; |
---|
1156 | Hrc_Latch_t *latch; |
---|
1157 | boolean test; |
---|
1158 | Tbl_Table_t *table, *resetTable; |
---|
1159 | Tbl_Entry_t *entry; |
---|
1160 | Var_Variable_t *var, *parentVar; |
---|
1161 | int i, j; |
---|
1162 | |
---|
1163 | Hrc_NodeForEachLatch(hnode, stGen, latchName, latch){ |
---|
1164 | resetTable = Hrc_LatchReadResetTable(latch); |
---|
1165 | test = Tbl_TableTestIsConstant(resetTable, 0); |
---|
1166 | /* |
---|
1167 | Tbl_TableTestIsConstant gives 0 result for reset tables of |
---|
1168 | the type .reset a ->b; - =a; where a is a constant defined |
---|
1169 | in another table. So check for this case as well. |
---|
1170 | */ |
---|
1171 | if(test == FALSE){ |
---|
1172 | if(Tbl_TableReadNumRows(resetTable) == 1){ |
---|
1173 | entry = Tbl_TableReadEntry(resetTable, 0, 0, 1); |
---|
1174 | if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ |
---|
1175 | parentVar = Tbl_EntryReadVar(resetTable, entry); |
---|
1176 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
1177 | Tbl_TableForEachOutputVar(table, j, var){ |
---|
1178 | if(var == parentVar){ |
---|
1179 | test = Tbl_TableTestIsConstant(table, j); |
---|
1180 | } |
---|
1181 | } |
---|
1182 | } |
---|
1183 | } |
---|
1184 | } |
---|
1185 | } |
---|
1186 | if (test == FALSE){ |
---|
1187 | fprintf(vis_stderr, "Latch %s has a non-constant reset value - quitting.\n", latchName); |
---|
1188 | st_free_gen(stGen); |
---|
1189 | return 1; |
---|
1190 | } |
---|
1191 | } |
---|
1192 | return 0; |
---|
1193 | } |
---|
1194 | |
---|
1195 | /**Function******************************************************************** |
---|
1196 | |
---|
1197 | Synopsis [Checks that all tables in a model are deterministic] |
---|
1198 | |
---|
1199 | Description [] |
---|
1200 | |
---|
1201 | SideEffects [] |
---|
1202 | |
---|
1203 | SeeAlso [] |
---|
1204 | |
---|
1205 | ******************************************************************************/ |
---|
1206 | static int |
---|
1207 | _IoCheckHnodeTablesAreDeterministic( |
---|
1208 | mdd_manager **mddMgr, |
---|
1209 | Hrc_Node_t *hnode |
---|
1210 | ) |
---|
1211 | { |
---|
1212 | int i, j, k, index, colNum, offset, numInputs; |
---|
1213 | Tbl_Table_t *table; |
---|
1214 | Var_Variable_t *inputVar, *outputVar, *var; |
---|
1215 | Mvf_Function_t *faninMvf, *outMvf; |
---|
1216 | array_t *faninMvfArray; |
---|
1217 | array_t *mvarValues; |
---|
1218 | Tbl_Entry_t *entry; |
---|
1219 | |
---|
1220 | |
---|
1221 | /* note that reset tables are not handled here */ |
---|
1222 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
1223 | Tbl_TableForEachOutputVar(table, index, outputVar){ |
---|
1224 | |
---|
1225 | faninMvfArray = array_alloc(Mvf_Function_t *, 0); |
---|
1226 | mvarValues = array_alloc(int, 0); |
---|
1227 | |
---|
1228 | /* Create MDD variables for the table inputs. */ |
---|
1229 | Tbl_TableForEachInputVar(table, colNum, inputVar) { |
---|
1230 | array_insert_last(int, mvarValues, Var_VariableReadNumValues(inputVar)); |
---|
1231 | } |
---|
1232 | offset = array_n(mdd_ret_mvar_list(*mddMgr)); /* number of existing mvars */ |
---|
1233 | mdd_create_variables(*mddMgr, mvarValues, NIL(array_t), NIL(array_t)); |
---|
1234 | array_free(mvarValues); |
---|
1235 | |
---|
1236 | /* |
---|
1237 | * Construct an MVF for each table input. The MVF for column j is the MVF |
---|
1238 | * for MDD variable j. |
---|
1239 | */ |
---|
1240 | |
---|
1241 | numInputs = Tbl_TableReadNumInputs(table ); |
---|
1242 | for (j = 0; j < numInputs; j++) { |
---|
1243 | faninMvf = Mvf_FunctionCreateFromVariable(*mddMgr, (j + offset)); |
---|
1244 | array_insert_last(Mvf_Function_t *, faninMvfArray, faninMvf); |
---|
1245 | } |
---|
1246 | |
---|
1247 | /* Compute the MVF of the output indexed by index. */ |
---|
1248 | outMvf = Tbl_TableBuildMvfFromFanins(table, index, faninMvfArray, *mddMgr); |
---|
1249 | Mvf_FunctionArrayFree(faninMvfArray); |
---|
1250 | |
---|
1251 | /* |
---|
1252 | * If the function is a non-deterministic constant, or it has some |
---|
1253 | * inputs, and is non-deterministic, then fail |
---|
1254 | */ |
---|
1255 | if((numInputs > 0) && !Mvf_FunctionTestIsDeterministic(outMvf)){ |
---|
1256 | (void) fprintf(vis_stderr, "Table %s is non-deterministic - quitting\n", Var_VariableReadName(outputVar)); |
---|
1257 | Mvf_FunctionFree(outMvf); |
---|
1258 | return 1; |
---|
1259 | } |
---|
1260 | if(Mvf_FunctionTestIsNonDeterministicConstant(outMvf)){ |
---|
1261 | (void) fprintf(vis_stderr, "Table %s is a non-deterministic constant - quitting\n", Var_VariableReadName(outputVar)); |
---|
1262 | Mvf_FunctionFree(outMvf); |
---|
1263 | return 1; |
---|
1264 | } |
---|
1265 | if (!Mvf_FunctionTestIsCompletelySpecified(outMvf)) { |
---|
1266 | (void) fprintf(vis_stderr, "Table %s is not completely specified - quitting\n", Var_VariableReadName(outputVar)); |
---|
1267 | Mvf_FunctionFree(outMvf); |
---|
1268 | return 1; |
---|
1269 | } |
---|
1270 | Mvf_FunctionFree(outMvf); |
---|
1271 | _MddManagerResetIfNecessary(mddMgr); |
---|
1272 | |
---|
1273 | } |
---|
1274 | } |
---|
1275 | |
---|
1276 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
1277 | for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ |
---|
1278 | entry = Tbl_TableDefaultReadEntry(table, j); |
---|
1279 | if(entry != NIL(Tbl_Entry_t)){ |
---|
1280 | if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){ |
---|
1281 | if(Tbl_EntryReadNumValues(entry) > 1){ |
---|
1282 | outputVar = Tbl_TableReadIndexVar(table, j, 1); |
---|
1283 | (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar)); |
---|
1284 | return 1; |
---|
1285 | } |
---|
1286 | } |
---|
1287 | else{ |
---|
1288 | var = Tbl_EntryReadVar(table, entry); |
---|
1289 | k = Tbl_TableReadVarIndex(table, var, 1); |
---|
1290 | if(k<0){ |
---|
1291 | outputVar = Tbl_TableReadIndexVar(table, j, 1); |
---|
1292 | (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar)); |
---|
1293 | return 1; |
---|
1294 | } |
---|
1295 | } |
---|
1296 | } |
---|
1297 | } |
---|
1298 | } |
---|
1299 | return 0; |
---|
1300 | } |
---|
1301 | |
---|
1302 | |
---|
1303 | /**Function******************************************************************** |
---|
1304 | |
---|
1305 | Synopsis [Potentially quits mddMgr and starts a new one.] |
---|
1306 | |
---|
1307 | Description [Quits mddMgr if the number of binary variables exceeds |
---|
1308 | MAX_NUMBER_BDD_VARS, and starts a new manager with no variables. |
---|
1309 | Initializing an empty MDD manager is costly in some BDD packages, so we want |
---|
1310 | to avoid doing it often (say, once per table). On the other hand, we don't |
---|
1311 | want the manager to have too many variables, because then reordering becomes |
---|
1312 | expensive.] |
---|
1313 | |
---|
1314 | SideEffects [] |
---|
1315 | |
---|
1316 | ******************************************************************************/ |
---|
1317 | static void |
---|
1318 | _MddManagerResetIfNecessary( |
---|
1319 | mdd_manager **mddMgr) |
---|
1320 | { |
---|
1321 | if (bdd_num_vars(*mddMgr) > MAX_NUMBER_BDD_VARS) { |
---|
1322 | mdd_quit(*mddMgr); |
---|
1323 | *mddMgr = mdd_init_empty(); |
---|
1324 | } |
---|
1325 | } |
---|
1326 | |
---|
1327 | |
---|
1328 | |
---|
1329 | /**Function******************************************************************** |
---|
1330 | |
---|
1331 | Synopsis [Write out a Hnode and recurse on its children] |
---|
1332 | |
---|
1333 | Description [Call the function to write out the given hnode in blif, and |
---|
1334 | recursively call the same function on its children.] |
---|
1335 | |
---|
1336 | SideEffects [] |
---|
1337 | |
---|
1338 | ******************************************************************************/ |
---|
1339 | static void |
---|
1340 | _IoHnodeWriteBlifRecursively( |
---|
1341 | Io_Encoding_Type_t encodingType, |
---|
1342 | Hrc_Node_t *hnode, |
---|
1343 | st_table *modelTable, |
---|
1344 | FILE *fp, |
---|
1345 | FILE *encFp, |
---|
1346 | int verbosity |
---|
1347 | ) |
---|
1348 | { |
---|
1349 | char *modelName, *childName; |
---|
1350 | Hrc_Model_t *model; |
---|
1351 | Hrc_Manager_t *manager; |
---|
1352 | st_generator *stGen; |
---|
1353 | Hrc_Node_t *childNode; |
---|
1354 | |
---|
1355 | manager = Hrc_NodeReadManager(hnode); |
---|
1356 | /* enter current model in modelTable */ |
---|
1357 | modelName = Hrc_NodeReadModelName(hnode); |
---|
1358 | model = Hrc_ManagerFindModelByName(manager, modelName); |
---|
1359 | if(st_is_member(modelTable, (char *) model)){ |
---|
1360 | return; |
---|
1361 | } |
---|
1362 | else{ |
---|
1363 | st_insert(modelTable, (char *)model, (char *) (long) (-1)); |
---|
1364 | } |
---|
1365 | |
---|
1366 | _IoHnodeWriteBlifRecursivelyStep(encodingType, hnode, fp, encFp, verbosity); |
---|
1367 | Hrc_NodeForEachChild(hnode, stGen, childName, childNode){ |
---|
1368 | _IoHnodeWriteBlifRecursively(encodingType, childNode, modelTable, fp, encFp, verbosity); |
---|
1369 | } |
---|
1370 | return; |
---|
1371 | } |
---|
1372 | |
---|
1373 | |
---|
1374 | /**Function*********************************************************** |
---|
1375 | |
---|
1376 | |
---|
1377 | Synopsis [ Writes out an hnode to blif] |
---|
1378 | |
---|
1379 | Description [ Writes out IO declarations, subckt declarations and tables to |
---|
1380 | the blif file specified.] |
---|
1381 | |
---|
1382 | SideEffects [ ] |
---|
1383 | |
---|
1384 | SeeAlso [ ] |
---|
1385 | **********************************************************************/ |
---|
1386 | static int |
---|
1387 | _IoHnodeWriteBlifRecursivelyStep( |
---|
1388 | Io_Encoding_Type_t encodingType, |
---|
1389 | Hrc_Node_t *hnode, |
---|
1390 | FILE *fp, |
---|
1391 | FILE *encFp, |
---|
1392 | int verbosity) |
---|
1393 | { |
---|
1394 | Tbl_Table_t *table, *singleOutputTable; |
---|
1395 | int i, j; |
---|
1396 | Var_Variable_t *var, *actualVar; |
---|
1397 | char *name, *instanceName, *modelName; |
---|
1398 | st_generator *gen; |
---|
1399 | st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable; |
---|
1400 | st_table *encOutputsStTable, *encInputsStTable; |
---|
1401 | Hrc_Node_t *subcktHnode; |
---|
1402 | Hrc_Model_t *model, *subcktModel; |
---|
1403 | Hrc_Subckt_t *subckt; |
---|
1404 | Hrc_Manager_t *manager; |
---|
1405 | array_t *subcktActualInputVars, *subcktActualOutputVars; |
---|
1406 | |
---|
1407 | |
---|
1408 | printedMvsStTable = st_init_table(strcmp, st_strhash); |
---|
1409 | |
---|
1410 | /* .model */ |
---|
1411 | modelName = Hrc_NodeReadModelName(hnode); |
---|
1412 | manager = Hrc_NodeReadManager(hnode); |
---|
1413 | model = Hrc_ManagerFindModelByName(manager, modelName); |
---|
1414 | (void)fprintf(fp,".model %s\n", modelName); |
---|
1415 | |
---|
1416 | /* .inputs line of blif file*/ |
---|
1417 | if (Hrc_NodeReadNumFormalInputs(hnode) != 0){ |
---|
1418 | (void)fprintf(fp,".inputs "); |
---|
1419 | Hrc_NodeForEachFormalInput(hnode,i,var){ |
---|
1420 | (void)fprintf(fp,"%s0 ",Var_VariableReadName(var)); |
---|
1421 | } |
---|
1422 | (void)fprintf(fp,"\n"); |
---|
1423 | } |
---|
1424 | |
---|
1425 | /* .outputs line of blif file*/ |
---|
1426 | if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){ |
---|
1427 | (void)fprintf(fp,".outputs "); |
---|
1428 | Hrc_NodeForEachFormalOutput(hnode,i,var){ |
---|
1429 | (void)fprintf(fp,"%s0 ",Var_VariableReadName(var)); |
---|
1430 | } |
---|
1431 | (void)fprintf(fp,"\n"); |
---|
1432 | } |
---|
1433 | |
---|
1434 | /* .subckt stuff */ |
---|
1435 | Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){ |
---|
1436 | subcktModel = Hrc_SubcktReadModel(subckt); |
---|
1437 | subcktHnode = Hrc_ModelReadMasterNode(subcktModel); |
---|
1438 | subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt); |
---|
1439 | subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt); |
---|
1440 | |
---|
1441 | /* .subckt declarations */ |
---|
1442 | (void)fprintf(fp,".subckt %s ", |
---|
1443 | Hrc_ModelReadName(subcktModel)); |
---|
1444 | Hrc_NodeForEachFormalInput(subcktHnode,i,var){ |
---|
1445 | actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i); |
---|
1446 | (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); |
---|
1447 | } |
---|
1448 | Hrc_NodeForEachFormalOutput(subcktHnode,i,var){ |
---|
1449 | actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); |
---|
1450 | (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); |
---|
1451 | } |
---|
1452 | (void)fprintf(fp,"\n"); |
---|
1453 | } |
---|
1454 | |
---|
1455 | encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
1456 | encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
1457 | blifInputsStTable = st_init_table(strcmp, st_strhash); |
---|
1458 | blifOutputsStTable = st_init_table(strcmp, st_strhash); |
---|
1459 | |
---|
1460 | /* .latch declarations for blif file */ |
---|
1461 | IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, 0, 0, verbosity); |
---|
1462 | Hrc_NodeForEachNameTable(hnode, i, table){ |
---|
1463 | if(IoOutputExpansionRequired(table)){ |
---|
1464 | if(verbosity > 0){ |
---|
1465 | (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n"); |
---|
1466 | } |
---|
1467 | for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ |
---|
1468 | singleOutputTable = IoMakeSingleOutputTable(table, j); |
---|
1469 | _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, |
---|
1470 | verbosity); |
---|
1471 | Tbl_TableFree(singleOutputTable); |
---|
1472 | } |
---|
1473 | } |
---|
1474 | else{ |
---|
1475 | if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){ |
---|
1476 | _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp, |
---|
1477 | verbosity); |
---|
1478 | } |
---|
1479 | } |
---|
1480 | } |
---|
1481 | st_foreach_item_int(blifInputsStTable, gen, &name, &i){ |
---|
1482 | FREE(name); |
---|
1483 | } |
---|
1484 | st_foreach_item_int(blifOutputsStTable, gen, &name, &i){ |
---|
1485 | FREE(name); |
---|
1486 | } |
---|
1487 | st_free_table(blifInputsStTable); |
---|
1488 | st_free_table(blifOutputsStTable); |
---|
1489 | st_free_table(encInputsStTable); |
---|
1490 | st_free_table(encOutputsStTable); |
---|
1491 | st_foreach_item_int(printedMvsStTable, gen, &name, &i){ |
---|
1492 | FREE(name); |
---|
1493 | } |
---|
1494 | st_free_table(printedMvsStTable); |
---|
1495 | fprintf(fp,".end\n"); |
---|
1496 | return 1; |
---|
1497 | } |
---|
1498 | |
---|
1499 | |
---|
1500 | |
---|
1501 | /**Function*********************************************************** |
---|
1502 | |
---|
1503 | |
---|
1504 | Synopsis [ Checks if pseudoinput is also a PO] |
---|
1505 | |
---|
1506 | Description [ Checks if table has 0input, >1 output, or 1 output |
---|
1507 | with multiple valued entry] |
---|
1508 | |
---|
1509 | SideEffects [ ] |
---|
1510 | |
---|
1511 | SeeAlso [ ] |
---|
1512 | **********************************************************************/ |
---|
1513 | static int |
---|
1514 | _IoCheckPseudoinputIsPO( |
---|
1515 | Tbl_Table_t *table) |
---|
1516 | { |
---|
1517 | int j; |
---|
1518 | Var_Variable_t *var = NIL(Var_Variable_t); /* to suppress warning */ |
---|
1519 | Tbl_Entry_t *entry; |
---|
1520 | int numValues; |
---|
1521 | |
---|
1522 | if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){ |
---|
1523 | /* assume all are pseudoinputs */ |
---|
1524 | Tbl_TableForEachOutputVar(table, j, var){ |
---|
1525 | if(Var_VariableTestIsPO(var)){ |
---|
1526 | return 1; |
---|
1527 | } |
---|
1528 | } |
---|
1529 | } |
---|
1530 | |
---|
1531 | if(Tbl_TableReadNumInputs(table) == 0){ |
---|
1532 | if(Tbl_TableReadNumRows(table) != 0){ |
---|
1533 | entry = Tbl_TableReadEntry(table, 0, 0, 1); |
---|
1534 | numValues = Tbl_EntryReadNumValues(entry); |
---|
1535 | } |
---|
1536 | else{ |
---|
1537 | entry = Tbl_TableDefaultReadEntry(table, 0); |
---|
1538 | numValues = Tbl_EntryReadNumValues(entry); |
---|
1539 | } |
---|
1540 | |
---|
1541 | Tbl_TableForEachOutputVar(table, j, var); |
---|
1542 | if(Tbl_TableReadNumRows(table) <= 1){ |
---|
1543 | if(numValues > 1){ |
---|
1544 | if(Var_VariableTestIsPO(var)){ |
---|
1545 | return 1; |
---|
1546 | } |
---|
1547 | } |
---|
1548 | } |
---|
1549 | else{ |
---|
1550 | if(Var_VariableTestIsPO(var)){ |
---|
1551 | return 1; |
---|
1552 | } |
---|
1553 | } |
---|
1554 | } |
---|
1555 | |
---|
1556 | return 0; |
---|
1557 | } |
---|