ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ioWriteVerilog.c
Go to the documentation of this file.
1
20
21#include "ioAbc.h"
22#include "base/main/main.h"
23#include "map/mio/mio.h"
24
26
27
31
32static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds, int fNewInterface );
33static void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
34static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start, int fNewInterface );
35static void Io_WriteVerilogAssigns( FILE * pFile, Abc_Ntk_t * pNtk );
36static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
37static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
38static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk );
39static void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds );
40static int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk );
41static char * Io_WriteVerilogGetName( char * pName );
42
46
58void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds, int fNewInterface )
59{
60 Abc_Ntk_t * pNetlist;
61 FILE * pFile;
62 int i;
63
64 // can only write nodes represented using local AIGs
65 if ( !Abc_NtkIsAigNetlist(pNtk) && !Abc_NtkIsMappedNetlist(pNtk) )
66 {
67 printf( "Io_WriteVerilog(): Can produce Verilog for mapped or AIG netlists only.\n" );
68 return;
69 }
70 // start the output stream
71 pFile = fopen( pFileName, "w" );
72 if ( pFile == NULL )
73 {
74 fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
75 return;
76 }
77
78 // write the equations for the network
79 fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
80 fprintf( pFile, "\n" );
81
82 // write modules
83 if ( pNtk->pDesign )
84 {
85 // write the network first
86 Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds, fNewInterface );
87 // write other things
88 Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNetlist, i )
89 {
90 assert( Abc_NtkIsNetlist(pNetlist) );
91 if ( pNetlist == pNtk )
92 continue;
93 fprintf( pFile, "\n" );
94 Io_WriteVerilogInt( pFile, pNetlist, fOnlyAnds, fNewInterface );
95 }
96 }
97 else
98 {
99 Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds, fNewInterface );
100 }
101
102 fprintf( pFile, "\n" );
103 fclose( pFile );
104}
105
117void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds, int fNewInterface )
118{
119 // write inputs and outputs
120// fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) );
121 fprintf( pFile, "module %s ( ", Io_WriteVerilogGetName(Abc_NtkName(pNtk)) );
122 // add the clock signal if it does not exist
123 if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
124 fprintf( pFile, "clock, " );
125 // write other primary inputs
126 fprintf( pFile, "\n " );
127 if ( Abc_NtkPiNum(pNtk) > 0 )
128 {
129 Io_WriteVerilogPis( pFile, pNtk, 3 );
130 fprintf( pFile, ",\n " );
131 }
132 if ( Abc_NtkPoNum(pNtk) > 0 )
133 Io_WriteVerilogPos( pFile, pNtk, 3, fNewInterface );
134 fprintf( pFile, " );\n" );
135 // add the clock signal if it does not exist
136 if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
137 fprintf( pFile, " input clock;\n" );
138 // write inputs, outputs, registers, and wires
139 if ( Abc_NtkPiNum(pNtk) > 0 )
140 {
141// fprintf( pFile, " input gclk," );
142 fprintf( pFile, " input " );
143 Io_WriteVerilogPis( pFile, pNtk, 10 );
144 fprintf( pFile, ";\n" );
145 }
146 if ( Abc_NtkPoNum(pNtk) > 0 )
147 {
148 fprintf( pFile, " output" );
149 Io_WriteVerilogPos( pFile, pNtk, 5, fNewInterface );
150 fprintf( pFile, ";\n" );
151 }
152 // if this is not a blackbox, write internal signals
153 if ( !Abc_NtkHasBlackbox(pNtk) )
154 {
155 if ( Abc_NtkLatchNum(pNtk) > 0 )
156 {
157 fprintf( pFile, " reg" );
158 Io_WriteVerilogRegs( pFile, pNtk, 4 );
159 fprintf( pFile, ";\n" );
160 }
161 if ( Io_WriteVerilogWiresCount(pNtk) > 0 )
162 {
163 fprintf( pFile, " wire" );
164 Io_WriteVerilogWires( pFile, pNtk, 4 );
165 fprintf( pFile, ";\n" );
166 }
167 // write nodes
168 Io_WriteVerilogObjects( pFile, pNtk, fOnlyAnds );
169 // write registers
170 if ( Abc_NtkLatchNum(pNtk) > 0 )
171 Io_WriteVerilogLatches( pFile, pNtk );
172 }
173 if ( fNewInterface )
174 Io_WriteVerilogAssigns( pFile, pNtk );
175 // finalize the file
176 fprintf( pFile, "endmodule\n\n" );
177}
178
190void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
191{
192 Abc_Obj_t * pTerm, * pNet;
193 int LineLength;
194 int AddedLength;
195 int NameCounter;
196 int i;
197
198 LineLength = Start;
199 NameCounter = 0;
200 Abc_NtkForEachPi( pNtk, pTerm, i )
201 {
202 pNet = Abc_ObjFanout0(pTerm);
203 // get the line length after this name is written
204 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
205 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
206 { // write the line extender
207 fprintf( pFile, "\n " );
208 // reset the line length
209 LineLength = 3;
210 NameCounter = 0;
211 }
212 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (i==Abc_NtkPiNum(pNtk)-1)? "" : "," );
213 LineLength += AddedLength;
214 NameCounter++;
215 }
216}
217
229void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start, int fNewInterface )
230{
231 Abc_Obj_t * pTerm, * pNet, * pSkip;
232 char Name[100], * pName = Name;
233 int LineLength;
234 int AddedLength;
235 int NameCounter;
236 int i;
237 int nskip;
238
239 pSkip = 0;
240 nskip = 0;
241
242 LineLength = Start;
243 NameCounter = 0;
244 Abc_NtkForEachPo( pNtk, pTerm, i )
245 {
246 pNet = Abc_ObjFanin0(pTerm);
247
248 if ( Abc_ObjIsPi(Abc_ObjFanin0(pNet)) )
249 {
250 // Skip this output since it is a feedthrough -- the same
251 // name will appear as an input and an output which other
252 // tools reading verilog do not like.
253
254 nskip++;
255 pSkip = pNet; // save an example of skipped net
256 continue;
257 }
258
259 // get the line length after this name is written
260 if ( fNewInterface )
261 sprintf( Name, "po_username%d", i );
262 else
263 pName = Abc_ObjName(pNet);
264 AddedLength = strlen(Io_WriteVerilogGetName(pName)) + 2;
265 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
266 { // write the line extender
267 fprintf( pFile, "\n " );
268 // reset the line length
269 LineLength = 3;
270 NameCounter = 0;
271 }
272 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pName), (i==Abc_NtkPoNum(pNtk)-1)? "" : "," );
273 LineLength += AddedLength;
274 NameCounter++;
275 }
276
277 if (nskip != 0)
278 {
279 assert (pSkip);
280 printf( "Io_WriteVerilogPos(): Omitted %d feedthrough nets from output list of module (e.g. %s).\n", nskip, Abc_ObjName(pSkip) );
281 return;
282 }
283
284}
285
297void Io_WriteVerilogAssigns( FILE * pFile, Abc_Ntk_t * pNtk )
298{
299 Abc_Obj_t * pTerm, * pNet, * pSkip;
300 int i;
301 Abc_NtkForEachPo( pNtk, pTerm, i )
302 {
303 pNet = Abc_ObjFanin0(pTerm);
304 if ( Abc_ObjIsPi(Abc_ObjFanin0(pNet)) )
305 {
306 // Skip this output since it is a feedthrough -- the same
307 // name will appear as an input and an output which other
308 // tools reading verilog do not like.
309
310 pSkip = pNet; // save an example of skipped net
311 continue;
312 }
313 fprintf( pFile, " assign po_username%d = %s;\n", i, Abc_ObjName(pNet) );
314 }
315}
316
328void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
329{
330 Abc_Obj_t * pObj, * pNet, * pBox, * pTerm;
331 int LineLength;
332 int AddedLength;
333 int NameCounter;
334 int i, k, Counter, nNodes;
335
336 // count the number of wires
337 nNodes = Io_WriteVerilogWiresCount( pNtk );
338
339 // write the wires
340 Counter = 0;
341 LineLength = Start;
342 NameCounter = 0;
343 Abc_NtkForEachNode( pNtk, pObj, i )
344 {
345 if ( i == 0 )
346 continue;
347 pNet = Abc_ObjFanout0(pObj);
348 if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
349 continue;
350 Counter++;
351 // get the line length after this name is written
352 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
353 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
354 { // write the line extender
355 fprintf( pFile, "\n " );
356 // reset the line length
357 LineLength = 3;
358 NameCounter = 0;
359 }
360 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
361 LineLength += AddedLength;
362 NameCounter++;
363 }
364 Abc_NtkForEachLatch( pNtk, pObj, i )
365 {
366 pNet = Abc_ObjFanin0(Abc_ObjFanin0(pObj));
367 Counter++;
368 // get the line length after this name is written
369 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
370 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
371 { // write the line extender
372 fprintf( pFile, "\n " );
373 // reset the line length
374 LineLength = 3;
375 NameCounter = 0;
376 }
377 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
378 LineLength += AddedLength;
379 NameCounter++;
380 }
381 Abc_NtkForEachBox( pNtk, pBox, i )
382 {
383 if ( Abc_ObjIsLatch(pBox) )
384 continue;
385 Abc_ObjForEachFanin( pBox, pTerm, k )
386 {
387 pNet = Abc_ObjFanin0(pTerm);
388 Counter++;
389 // get the line length after this name is written
390 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
391 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
392 { // write the line extender
393 fprintf( pFile, "\n " );
394 // reset the line length
395 LineLength = 3;
396 NameCounter = 0;
397 }
398 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
399 LineLength += AddedLength;
400 NameCounter++;
401 }
402 Abc_ObjForEachFanout( pBox, pTerm, k )
403 {
404 pNet = Abc_ObjFanout0(pTerm);
405 if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
406 continue;
407 Counter++;
408 // get the line length after this name is written
409 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
410 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
411 { // write the line extender
412 fprintf( pFile, "\n " );
413 // reset the line length
414 LineLength = 3;
415 NameCounter = 0;
416 }
417 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
418 LineLength += AddedLength;
419 NameCounter++;
420 }
421 }
422 assert( Counter == nNodes );
423}
424
436void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
437{
438 Abc_Obj_t * pLatch, * pNet;
439 int LineLength;
440 int AddedLength;
441 int NameCounter;
442 int i, Counter, nNodes;
443
444 // count the number of latches
445 nNodes = Abc_NtkLatchNum(pNtk);
446
447 // write the wires
448 Counter = 0;
449 LineLength = Start;
450 NameCounter = 0;
451 Abc_NtkForEachLatch( pNtk, pLatch, i )
452 {
453 pNet = Abc_ObjFanout0(Abc_ObjFanout0(pLatch));
454 Counter++;
455 // get the line length after this name is written
456 AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
457 if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
458 { // write the line extender
459 fprintf( pFile, "\n " );
460 // reset the line length
461 LineLength = 3;
462 NameCounter = 0;
463 }
464 fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
465 LineLength += AddedLength;
466 NameCounter++;
467 }
468}
469
481void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
482{
483 Abc_Obj_t * pLatch;
484 int i;
485 if ( Abc_NtkLatchNum(pNtk) == 0 )
486 return;
487 // write the latches
488// fprintf( pFile, " always @(posedge %s) begin\n", Io_WriteVerilogGetName(Abc_ObjFanout0(Abc_NtkPi(pNtk,0))) );
489// fprintf( pFile, " always begin\n" );
490 fprintf( pFile, " always @ (posedge clock) begin\n" );
491 Abc_NtkForEachLatch( pNtk, pLatch, i )
492 {
493 fprintf( pFile, " %s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
494 fprintf( pFile, " <= %s;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin0(pLatch)))) );
495 }
496 fprintf( pFile, " end\n" );
497 // check if there are initial values
498 Abc_NtkForEachLatch( pNtk, pLatch, i )
499 if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO || Abc_LatchInit(pLatch) == ABC_INIT_ONE )
500 break;
501 if ( i == Abc_NtkLatchNum(pNtk) )
502 return;
503 // write the initial values
504 fprintf( pFile, " initial begin\n" );
505 Abc_NtkForEachLatch( pNtk, pLatch, i )
506 {
507 if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO )
508 fprintf( pFile, " %s <= 1\'b0;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
509 else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE )
510 fprintf( pFile, " %s <= 1\'b1;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
511 }
512 fprintf( pFile, " end\n" );
513}
514
526void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds )
527{
528 int fUseSimpleGateNames = 0;
529 Vec_Vec_t * vLevels;
530 Abc_Ntk_t * pNtkBox;
531 Abc_Obj_t * pObj, * pTerm, * pFanin;
532 Hop_Obj_t * pFunc;
533 int i, k, Counter, nDigits, Length;
534
535 // write boxes
536 nDigits = Abc_Base10Log( Abc_NtkBoxNum(pNtk)-Abc_NtkLatchNum(pNtk) );
537 Counter = 0;
538 Abc_NtkForEachBox( pNtk, pObj, i )
539 {
540 if ( Abc_ObjIsLatch(pObj) )
541 continue;
542 pNtkBox = (Abc_Ntk_t *)pObj->pData;
543 fprintf( pFile, " %s box%0*d", pNtkBox->pName, nDigits, Counter++ );
544 fprintf( pFile, "(" );
545 Abc_NtkForEachPi( pNtkBox, pTerm, k )
546 {
547 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pTerm))) );
548 fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin(pObj,k)))) );
549 }
550 Abc_NtkForEachPo( pNtkBox, pTerm, k )
551 {
552 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(pTerm))) );
553 fprintf( pFile, "(%s)%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout(pObj,k)))), k==Abc_NtkPoNum(pNtkBox)-1? "":", " );
554 }
555 fprintf( pFile, ");\n" );
556 }
557 // write nodes
558 if ( Abc_NtkHasMapping(pNtk) )
559 {
561 nDigits = Abc_Base10Log( Abc_NtkNodeNum(pNtk) );
562 Counter = 0;
563 Abc_NtkForEachNode( pNtk, pObj, k )
564 {
565 Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
566 Mio_Pin_t * pGatePin;
567 if ( Abc_ObjFaninNum(pObj) == 0 && (!strcmp(Mio_GateReadName(pGate), "_const0_") || !strcmp(Mio_GateReadName(pGate), "_const1_")) )
568 {
569 fprintf( pFile, " %-*s %s = 1\'b%d;\n", Length, "assign", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )), !strcmp(Mio_GateReadName(pGate), "_const1_") );
570 continue;
571 }
572 // write the node
573 if ( fUseSimpleGateNames )
574 {
575 fprintf( pFile, "%-*s ", Length, Mio_GateReadName(pGate) );
576 fprintf( pFile, "( %s", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )) );
577 for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
578 fprintf( pFile, ", %s", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanin(pObj,i) )) );
579 assert ( i == Abc_ObjFaninNum(pObj) );
580 fprintf( pFile, " );\n" );
581 }
582 else
583 {
584 fprintf( pFile, " %-*s g%0*d", Length, Mio_GateReadName(pGate), nDigits, Counter++ );
585 fprintf( pFile, "(" );
586 for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
587 {
588 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_PinReadName(pGatePin)) );
589 fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanin(pObj,i) )) );
590 }
591 assert ( i == Abc_ObjFaninNum(pObj) );
592 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName(pGate)) );
593 fprintf( pFile, "(%s)", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )) );
594 fprintf( pFile, ");\n" );
595 }
596 }
597 }
598 else
599 {
600 //Vec_Int_t * vMap = Vec_IntStartFull( 2*Abc_NtkObjNumMax(pNtk) );
601 vLevels = Vec_VecAlloc( 10 );
602 Abc_NtkForEachNode( pNtk, pObj, i )
603 {
604 if ( Abc_ObjFaninNum(pObj) == 0 )
605 {
606 fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
607 fprintf( pFile, "1\'b%d;\n", Abc_NodeIsConst1(pObj) );
608 continue;
609 }
610 /*
611 if ( Abc_ObjFaninNum(pObj) == 1 || Abc_ObjIsCo(Abc_ObjFanout0(Abc_ObjFanout0(pObj))) )
612 {
613 int iLit = Abc_Var2Lit( Abc_ObjId( Abc_ObjFanin0(Abc_ObjFanin0(pObj)) ), Abc_NodeIsInv(pObj) );
614 int iObj = Vec_IntEntry( vMap, iLit );
615 if ( iObj == -1 )
616 Vec_IntWriteEntry( vMap, iLit, Abc_ObjId(Abc_ObjFanout0(pObj)) );
617 else
618 {
619 fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
620 fprintf( pFile, "%s;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_NtkObj(pNtk, iObj))) );
621 continue;
622 }
623 }
624 */
625 pFunc = (Hop_Obj_t *)pObj->pData;
626 fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
627 // set the input names
628 Abc_ObjForEachFanin( pObj, pFanin, k )
629 Hop_IthVar((Hop_Man_t *)pNtk->pManFunc, k)->pData = Extra_UtilStrsav(Io_WriteVerilogGetName(Abc_ObjName(pFanin)));
630 // write the formula
631 Hop_ObjPrintVerilog( pFile, pFunc, vLevels, 0, fOnlyAnds );
632 if ( pObj->fPersist )
633 {
634 Abc_Obj_t * pFan0 = Abc_ObjFanin0(Abc_ObjFanin(pObj, 0));
635 Abc_Obj_t * pFan1 = Abc_ObjFanin0(Abc_ObjFanin(pObj, 1));
636 int Cond = Abc_ObjIsNode(pFan0) && Abc_ObjIsNode(pFan1) && !pFan0->fPersist && !pFan1->fPersist;
637 fprintf( pFile, "; // MUXF7 %s\n", Cond ? "":"to be legalized" );
638 }
639 else
640 fprintf( pFile, ";\n" );
641 // clear the input names
642 Abc_ObjForEachFanin( pObj, pFanin, k )
643 ABC_FREE( Hop_IthVar((Hop_Man_t *)pNtk->pManFunc, k)->pData );
644 }
645 Vec_VecFree( vLevels );
646 //Vec_IntFree( vMap );
647 }
648}
649
661int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk )
662{
663 Abc_Obj_t * pObj, * pNet, * pBox;
664 int i, k, nWires;
665 nWires = Abc_NtkLatchNum(pNtk);
666 Abc_NtkForEachNode( pNtk, pObj, i )
667 {
668 if ( i == 0 )
669 continue;
670 pNet = Abc_ObjFanout0(pObj);
671 if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
672 continue;
673 nWires++;
674 }
675 Abc_NtkForEachBox( pNtk, pBox, i )
676 {
677 if ( Abc_ObjIsLatch(pBox) )
678 continue;
679 nWires += Abc_ObjFaninNum(pBox);
680 Abc_ObjForEachFanout( pBox, pObj, k )
681 {
682 pNet = Abc_ObjFanout0(pObj);
683 if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
684 continue;
685 nWires++;
686 }
687 }
688 return nWires;
689}
690
702char * Io_WriteVerilogGetName( char * pName )
703{
704 static char Buffer[500];
705 int i, Length = strlen(pName);
706 if ( pName[0] < '0' || pName[0] > '9' )
707 {
708 for ( i = 0; i < Length; i++ )
709 if ( !((pName[i] >= 'a' && pName[i] <= 'z') ||
710 (pName[i] >= 'A' && pName[i] <= 'Z') ||
711 (pName[i] >= '0' && pName[i] <= '9') || pName[i] == '_') )
712 break;
713 if ( i == Length )
714 return pName;
715 }
716 // create Verilog style name
717 Buffer[0] = '\\';
718 for ( i = 0; i < Length; i++ )
719 Buffer[i+1] = pName[i];
720 Buffer[Length+1] = ' ';
721 Buffer[Length+2] = 0;
722 return Buffer;
723}
724
725
737void Io_WriteLutModule( FILE * pFile, int nLutSize )
738{
739 fprintf( pFile, "module lut%d #( parameter TT = %d\'h0 ) ( input [%d:0] in, output out );\n", nLutSize, 1<<nLutSize, nLutSize-1 );
740 fprintf( pFile, " assign out = TT[in];\n" );
741 fprintf( pFile, "endmodule\n\n" );
742}
743void Io_WriteFixedModules( FILE * pFile )
744{
745 fprintf( pFile, "module LUT6 #( parameter INIT = 64\'h0000000000000000 ) (\n" );
746 fprintf( pFile, " output O,\n" );
747 fprintf( pFile, " input I0,\n" );
748 fprintf( pFile, " input I1,\n" );
749 fprintf( pFile, " input I2,\n" );
750 fprintf( pFile, " input I3,\n" );
751 fprintf( pFile, " input I4,\n" );
752 fprintf( pFile, " input I5\n" );
753 fprintf( pFile, ");\n" );
754 fprintf( pFile, " assign O = INIT[ {I5, I4, I3, I2, I1, I0} ];\n" );
755 fprintf( pFile, "endmodule\n\n" );
756
757 fprintf( pFile, "module MUXF7 (\n" );
758 fprintf( pFile, " output O,\n" );
759 fprintf( pFile, " input I0,\n" );
760 fprintf( pFile, " input I1,\n" );
761 fprintf( pFile, " input S\n" );
762 fprintf( pFile, ");\n" );
763 fprintf( pFile, " assign O = S ? I1 : I0;\n" );
764 fprintf( pFile, "endmodule\n\n" );
765
766 fprintf( pFile, "module MUXF8 (\n" );
767 fprintf( pFile, " output O,\n" );
768 fprintf( pFile, " input I0,\n" );
769 fprintf( pFile, " input I1,\n" );
770 fprintf( pFile, " input S\n" );
771 fprintf( pFile, ");\n" );
772 fprintf( pFile, " assign O = S ? I1 : I0;\n" );
773 fprintf( pFile, "endmodule\n\n" );
774}
775void Io_WriteVerilogObjectsLut( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed )
776{
777 Abc_Ntk_t * pNtkBox;
778 Abc_Obj_t * pObj, * pTerm;
779 int i, k, Counter, nDigits, Length = 0;
780
781 // write boxes
782 nDigits = Abc_Base10Log( Abc_NtkBoxNum(pNtk)-Abc_NtkLatchNum(pNtk) );
783 Counter = 0;
784 Abc_NtkForEachBox( pNtk, pObj, i )
785 {
786 if ( Abc_ObjIsLatch(pObj) )
787 continue;
788 pNtkBox = (Abc_Ntk_t *)pObj->pData;
789 fprintf( pFile, " %s box%0*d", pNtkBox->pName, nDigits, Counter++ );
790 fprintf( pFile, "(" );
791 Abc_NtkForEachPi( pNtkBox, pTerm, k )
792 {
793 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pTerm))) );
794 fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin(pObj,k)))) );
795 }
796 Abc_NtkForEachPo( pNtkBox, pTerm, k )
797 {
798 fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(pTerm))) );
799 fprintf( pFile, "(%s)%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout(pObj,k)))), k==Abc_NtkPoNum(pNtkBox)-1? "":", " );
800 }
801 fprintf( pFile, ");\n" );
802 }
803
804 // find the longest signal name
805 Abc_NtkForEachNode( pNtk, pObj, i )
806 {
807 Length = Abc_MaxInt( Length, strlen(Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj)))) );
808 Abc_ObjForEachFanin( pObj, pTerm, k )
809 Length = Abc_MaxInt( Length, strlen(Io_WriteVerilogGetName(Abc_ObjName(pTerm))) );
810 }
811
812 // write LUT instances
813 nDigits = Abc_Base10Log( Abc_NtkNodeNum(pNtk) );
814 Counter = 0;
815 if ( fFixed )
816 Abc_NtkForEachNode( pNtk, pObj, i )
817 {
818 if ( pObj->fPersist )
819 {
820 int One = Abc_ObjFanin0(Abc_ObjFanin(pObj, 1))->fPersist && Abc_ObjFanin0(Abc_ObjFanin(pObj, 2))->fPersist;
821 fprintf( pFile, " MUXF%d ", 7+One );
822 fprintf( pFile, " mux_%0*d (", nDigits, Counter++ );
823 fprintf( pFile, " %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
824 for ( k = Abc_ObjFaninNum(pObj) - 1; k >= 0; k-- )
825 fprintf( pFile, ", %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))) );
826 fprintf( pFile, " );\n" );
827 }
828 else
829 {
830 word Truth = Abc_SopToTruth( (char *)pObj->pData, Abc_ObjFaninNum(pObj) );
831 fprintf( pFile, " LUT6 #(64\'h" );
832 fprintf( pFile, "%08x%08x", (unsigned)(Truth >> 32), (unsigned)Truth );
833 fprintf( pFile, ") lut_%0*d (", nDigits, Counter++ );
834 fprintf( pFile, " %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
835 for ( k = 0; k < Abc_ObjFaninNum(pObj); k++ )
836 fprintf( pFile, ", %*s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))) );
837 for ( ; k < 6; k++ )
838 fprintf( pFile, ", %*s", Length, "1\'b0" );
839 fprintf( pFile, " );\n" );
840 }
841 }
842 else
843 Abc_NtkForEachNode( pNtk, pObj, i )
844 {
845 word Truth = Abc_SopToTruth( (char *)pObj->pData, Abc_ObjFaninNum(pObj) );
846 fprintf( pFile, " lut%d #(%d\'h", nLutSize, 1<<nLutSize );
847 if ( nLutSize == 6 )
848 fprintf( pFile, "%08x%08x", (unsigned)(Truth >> 32), (unsigned)Truth );
849 else
850 fprintf( pFile, "%0*x", 1<<(nLutSize-2), Abc_InfoMask(1 << nLutSize) & (unsigned)Truth );
851 fprintf( pFile, ") lut_%0*d ( {", nDigits, Counter++ );
852 for ( k = nLutSize - 1; k >= Abc_ObjFaninNum(pObj); k-- )
853 fprintf( pFile, "%*s, ", Length, "1\'b0" );
854 for ( k = Abc_ObjFaninNum(pObj) - 1; k >= 0; k-- )
855 fprintf( pFile, "%*s%s", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin(pObj, k))), k==0 ? "":", " );
856 fprintf( pFile, "}, %*s );\n", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
857 }
858}
859void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed, int fNewInterface )
860{
861 // write inputs and outputs
862// fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) );
863 fprintf( pFile, "module %s ( ", Io_WriteVerilogGetName(Abc_NtkName(pNtk)) );
864 // add the clock signal if it does not exist
865 if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
866 fprintf( pFile, "clock, " );
867 // write other primary inputs
868 fprintf( pFile, "\n " );
869 if ( Abc_NtkPiNum(pNtk) > 0 )
870 {
871 Io_WriteVerilogPis( pFile, pNtk, 3 );
872 fprintf( pFile, ",\n " );
873 }
874 if ( Abc_NtkPoNum(pNtk) > 0 )
875 Io_WriteVerilogPos( pFile, pNtk, 3, fNewInterface );
876 fprintf( pFile, " );\n\n" );
877 // add the clock signal if it does not exist
878 if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
879 fprintf( pFile, " input clock;\n" );
880 // write inputs, outputs, registers, and wires
881 if ( Abc_NtkPiNum(pNtk) > 0 )
882 {
883// fprintf( pFile, " input gclk," );
884 fprintf( pFile, " input " );
885 Io_WriteVerilogPis( pFile, pNtk, 10 );
886 fprintf( pFile, ";\n" );
887 }
888 if ( Abc_NtkPoNum(pNtk) > 0 )
889 {
890 fprintf( pFile, " output" );
891 Io_WriteVerilogPos( pFile, pNtk, 5, fNewInterface );
892 fprintf( pFile, ";\n\n" );
893 }
894 // if this is not a blackbox, write internal signals
895 if ( !Abc_NtkHasBlackbox(pNtk) )
896 {
897 if ( Abc_NtkLatchNum(pNtk) > 0 )
898 {
899 fprintf( pFile, " reg" );
900 Io_WriteVerilogRegs( pFile, pNtk, 4 );
901 fprintf( pFile, ";\n\n" );
902 }
903 if ( Io_WriteVerilogWiresCount(pNtk) > 0 )
904 {
905 fprintf( pFile, " wire" );
906 Io_WriteVerilogWires( pFile, pNtk, 4 );
907 fprintf( pFile, ";\n\n" );
908 }
909 // write nodes
910 Io_WriteVerilogObjectsLut( pFile, pNtk, nLutSize, fFixed );
911 // write registers
912 if ( Abc_NtkLatchNum(pNtk) > 0 )
913 {
914 fprintf( pFile, "\n" );
915 Io_WriteVerilogLatches( pFile, pNtk );
916 }
917 }
918 if ( fNewInterface )
919 Io_WriteVerilogAssigns( pFile, pNtk );
920 // finalize the file
921 fprintf( pFile, "\nendmodule\n\n" );
922}
923void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules, int fNewInterface )
924{
925 FILE * pFile;
926 Abc_Ntk_t * pNtkTemp;
927 Abc_Obj_t * pObj;
928 int i, Counter = 0;
929 Abc_NtkForEachNode( pNtk, pObj, i )
930 if ( Abc_ObjFaninNum(pObj) > nLutSize )
931 {
932 if ( Counter < 3 )
933 printf( "Node \"%s\" has the fanin count (%d) larger than the LUT size (%d).\n", Abc_ObjName(pObj), Abc_ObjFaninNum(pObj), nLutSize );
934 Counter++;
935 }
936 if ( Counter )
937 {
938 printf( "In total, %d internal logic nodes exceed the fanin count limit. Verilog is not written.\n", Counter );
939 return;
940 }
941
942 // start the output stream
943 pFile = fopen( pFileName, "w" );
944 if ( pFile == NULL )
945 {
946 fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
947 return;
948 }
949
950 // write the equations for the network
951 fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
952 fprintf( pFile, "\n" );
953 if ( !fNoModules )
954 {
955 if ( fFixed )
956 Io_WriteFixedModules( pFile );
957 else
958 Io_WriteLutModule( pFile, nLutSize );
959 }
960 pNtkTemp = Abc_NtkToNetlist( pNtk );
961 Abc_NtkToSop( pNtkTemp, -1, ABC_INFINITY );
962 Io_WriteVerilogLutInt( pFile, pNtkTemp, nLutSize, fFixed, fNewInterface );
963 Abc_NtkDelete( pNtkTemp );
964
965 fprintf( pFile, "\n" );
966 fclose( pFile );
967}
968
972
973
975
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition abc.h:520
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition abc.h:500
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
@ ABC_OBJ_PI
Definition abc.h:89
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
@ ABC_INIT_ZERO
Definition abc.h:104
@ ABC_INIT_ONE
Definition abc.h:105
ABC_DLL Abc_Ntk_t * Abc_NtkToNetlist(Abc_Ntk_t *pNtk)
Definition abcNetlist.c:100
ABC_DLL int Abc_NtkToSop(Abc_Ntk_t *pNtk, int fMode, int nCubeLimit)
Definition abcFunc.c:1261
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition abc.h:516
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
ABC_DLL word Abc_SopToTruth(char *pSop, int nInputs)
Definition abcSop.c:1314
#define Abc_NtkForEachBox(pNtk, pObj, i)
Definition abc.h:498
ABC_DLL int Abc_NodeIsConst1(Abc_Obj_t *pNode)
Definition abcObj.c:916
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition abc.h:464
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
char * Extra_UtilStrsav(const char *s)
char * Extra_TimeStamp()
typedefABC_NAMESPACE_HEADER_START struct Hop_Man_t_ Hop_Man_t
INCLUDES ///.
Definition hop.h:49
Hop_Obj_t * Hop_IthVar(Hop_Man_t *p, int i)
FUNCTION DEFINITIONS ///.
Definition hopOper.c:63
void Hop_ObjPrintVerilog(FILE *pFile, Hop_Obj_t *pObj, Vec_Vec_t *vLevels, int Level, int fOnlyAnds)
Definition hopUtil.c:369
struct Hop_Obj_t_ Hop_Obj_t
Definition hop.h:50
#define IO_WRITE_LINE_LENGTH
MACRO DEFINITIONS ///.
Definition ioAbc.h:75
void Io_WriteVerilogLutInt(FILE *pFile, Abc_Ntk_t *pNtk, int nLutSize, int fFixed, int fNewInterface)
void Io_WriteVerilog(Abc_Ntk_t *pNtk, char *pFileName, int fOnlyAnds, int fNewInterface)
FUNCTION DEFINITIONS ///.
void Io_WriteVerilogLut(Abc_Ntk_t *pNtk, char *pFileName, int nLutSize, int fFixed, int fNoModules, int fNewInterface)
void Io_WriteVerilogObjectsLut(FILE *pFile, Abc_Ntk_t *pNtk, int nLutSize, int fFixed)
void Io_WriteLutModule(FILE *pFile, int nLutSize)
void Io_WriteFixedModules(FILE *pFile)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
Mio_Pin_t * Mio_GateReadPins(Mio_Gate_t *pGate)
Definition mioApi.c:173
struct Mio_LibraryStruct_t_ Mio_Library_t
Definition mio.h:42
char * Mio_PinReadName(Mio_Pin_t *pPin)
Definition mioApi.c:208
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition mioApi.c:169
Mio_Pin_t * Mio_PinReadNext(Mio_Pin_t *pPin)
Definition mioApi.c:217
int Mio_LibraryReadGateNameMax(Mio_Library_t *pLib)
Definition mioApi.c:81
struct Mio_PinStruct_t_ Mio_Pin_t
Definition mio.h:44
char * Mio_GateReadOutName(Mio_Gate_t *pGate)
Definition mioApi.c:170
struct Mio_GateStruct_t_ Mio_Gate_t
Definition mio.h:43
int Nm_ManFindIdByName(Nm_Man_t *p, char *pName, int Type)
Definition nmApi.c:219
Vec_Ptr_t * vModules
Definition abc.h:225
char * pName
Definition abc.h:158
Abc_Des_t * pDesign
Definition abc.h:180
void * pManFunc
Definition abc.h:191
Nm_Man_t * pManName
Definition abc.h:160
void * pData
Definition abc.h:145
unsigned fPersist
Definition abc.h:139
void * pData
Definition hop.h:68
#define assert(ex)
Definition util_old.h:213
int strlen()
int strcmp()
char * sprintf()
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42