/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/register.h"
#include "kernel/sigtools.h"
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//**CFile****************************************************************
FileName [ioWriteBlifMv.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedures to write BLIF-MV files.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioWriteBlifMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ioAbc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteBlifMvNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch );
static void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteBlifMvValues( FILE * pFile, Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Write the network into a BLIF file with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName )
{
FILE * pFile;
Abc_Ntk_t * pNtkTemp;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
assert( Abc_NtkHasBlifMv(pNtk) );
// start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteBlifMv(): Cannot open the output file.\n" );
return;
}
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
// write the master network
Io_NtkWriteBlifMv( pFile, pNtk );
// write the remaining networks
if ( pNtk->pDesign )
{
Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i )
{
if ( pNtkTemp == pNtk )
continue;
fprintf( pFile, "\n\n" );
Io_NtkWriteBlifMv( pFile, pNtkTemp );
}
}
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Write the network into a BLIF file with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk )
{
assert( Abc_NtkIsNetlist(pNtk) );
// write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_NtkWriteBlifMvOne( pFile, pNtk );
// write EXDC network if it exists
if ( Abc_NtkExdc(pNtk) )
printf( "Io_NtkWriteBlifMv(): EXDC is not written.\n" );
// finalize the file
fprintf( pFile, ".end\n\n\n" );
}
/**Function*************************************************************
Synopsis [Write one network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk )
{
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pTerm, * pLatch;
int i;
// write the PIs
fprintf( pFile, ".inputs" );
Io_NtkWriteBlifMvPis( pFile, pNtk );
fprintf( pFile, "\n" );
// write the POs
fprintf( pFile, ".outputs" );
Io_NtkWriteBlifMvPos( pFile, pNtk );
fprintf( pFile, "\n" );
// write the MV directives
fprintf( pFile, "\n" );
Abc_NtkForEachCi( pNtk, pTerm, i )
if ( Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) );
Abc_NtkForEachCo( pNtk, pTerm, i )
if ( Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanin0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) );
// write the blackbox
if ( Abc_NtkHasBlackbox( pNtk ) )
{
fprintf( pFile, ".blackbox\n" );
return;
}
// write the timing info
// Io_WriteTimingInfo( pFile, pNtk );
// write the latches
if ( !Abc_NtkIsComb(pNtk) )
{
fprintf( pFile, "\n" );
Abc_NtkForEachLatch( pNtk, pLatch, i )
Io_NtkWriteBlifMvLatch( pFile, pLatch );
fprintf( pFile, "\n" );
}
/*
// write the subcircuits
assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
if ( Abc_NtkBlackboxNum(pNtk) > 0 )
{
fprintf( pFile, "\n" );
Abc_NtkForEachBlackbox( pNtk, pNode, i )
Io_NtkWriteBlifMvSubckt( pFile, pNode );
fprintf( pFile, "\n" );
}
*/
if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
{
fprintf( pFile, "\n" );
Abc_NtkForEachBox( pNtk, pNode, i )
{
if ( Abc_ObjIsLatch(pNode) )
continue;
Io_NtkWriteBlifMvSubckt( pFile, pNode );
}
fprintf( pFile, "\n" );
}
// write each internal node
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Io_NtkWriteBlifMvNode( pFile, pNode );
}
Extra_ProgressBarStop( pProgress );
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pTerm, * pNet;
int LineLength;
int AddedLength;
int NameCounter;
int i;
LineLength = 7;
NameCounter = 0;
Abc_NtkForEachPi( pNtk, pTerm, i )
{
pNet = Abc_ObjFanout0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pTerm, * pNet;
int LineLength;
int AddedLength;
int NameCounter;
int i;
LineLength = 8;
NameCounter = 0;
Abc_NtkForEachPo( pNtk, pTerm, i )
{
pNet = Abc_ObjFanin0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Write the latch into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch )
{
Abc_Obj_t * pNetLi, * pNetLo;
int Reset;
pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) );
Reset = (int)(ABC_PTRUINT_T)Abc_ObjData( pLatch );
// write the latch line
fprintf( pFile, ".latch" );
fprintf( pFile, " %10s", Abc_ObjName(pNetLi) );
fprintf( pFile, " %10s", Abc_ObjName(pNetLo) );
fprintf( pFile, "\n" );
// write the reset node
fprintf( pFile, ".reset %s\n", Abc_ObjName(pNetLo) );
fprintf( pFile, "%d\n", Reset-1 );
}
/**Function*************************************************************
Synopsis [Write the latch into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode )
{
Abc_Ntk_t * pModel = (Abc_Ntk_t *)pNode->pData;
Abc_Obj_t * pTerm;
int i;
// write the MV directives
fprintf( pFile, "\n" );
Abc_ObjForEachFanin( pNode, pTerm, i )
if ( Abc_ObjMvVarNum(pTerm) > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) );
Abc_ObjForEachFanout( pNode, pTerm, i )
if ( Abc_ObjMvVarNum(pTerm) > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) );
// write the subcircuit
fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) );
// write pairs of the formal=actual names
Abc_NtkForEachPi( pModel, pTerm, i )
{
fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
pTerm = Abc_ObjFanin( pNode, i );
fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
}
Abc_NtkForEachPo( pModel, pTerm, i )
{
fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
pTerm = Abc_ObjFanout( pNode, i );
fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
}
fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis [Write the node into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin;
char * pCur;
int nValues, iFanin, i;
// write .mv directives for the fanins
fprintf( pFile, "\n" );
Abc_ObjForEachFanin( pNode, pFanin, i )
{
// nValues = atoi(pCur);
nValues = Abc_ObjMvVarNum( pFanin );
if ( nValues > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pFanin), nValues );
// while ( *pCur++ != ' ' );
}
// write .mv directives for the node
// nValues = atoi(pCur);
nValues = Abc_ObjMvVarNum( Abc_ObjFanout0(pNode) );
if ( nValues > 2 )
fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), nValues );
// while ( *pCur++ != '\n' );
// write the .names line
fprintf( pFile, ".table" );
Io_NtkWriteBlifMvNodeFanins( pFile, pNode );
fprintf( pFile, "\n" );
// write the cubes
pCur = (char *)Abc_ObjData(pNode);
if ( *pCur == 'd' )
{
fprintf( pFile, ".default " );
pCur++;
}
// write the literals
for ( ; *pCur; pCur++ )
{
fprintf( pFile, "%c", *pCur );
if ( *pCur != '=' )
continue;
// get the number
iFanin = atoi( pCur+1 );
fprintf( pFile, "%s", Abc_ObjName(Abc_ObjFanin(pNode,iFanin)) );
// scroll on to the next symbol
while ( *pCur != ' ' && *pCur != '\n' )
pCur++;
pCur--;
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteBlifMvNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
{
Abc_Obj_t * pNet;
int LineLength;
int AddedLength;
int NameCounter;
char * pName;
int i;
LineLength = 6;
NameCounter = 0;
Abc_ObjForEachFanin( pNode, pNet, i )
{
// get the fanin name
pName = Abc_ObjName(pNet);
// get the line length after the fanin name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
// get the output name
pName = Abc_ObjName(Abc_ObjFanout0(pNode));
// get the line length after the output name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength > 75 )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END