Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
abc
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
abc
Commits
79f04c66
Commit
79f04c66
authored
Jan 21, 2022
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experiments with word-level data structures.
parent
48498af8
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
2385 additions
and
153 deletions
+2385
-153
abclib.dsp
+8
-0
src/aig/gia/giaDup.c
+14
-0
src/aig/gia/giaPat2.c
+1
-1
src/aig/miniaig/abcOper.h
+4
-0
src/base/main/mainInt.h
+1
-0
src/base/wlc/wlcCom.c
+210
-126
src/base/wln/module.make
+2
-0
src/base/wln/wln.h
+4
-0
src/base/wln/wlnBlast.c
+388
-0
src/base/wln/wlnRead.c
+1733
-0
src/base/wln/wlnRtl.c
+20
-26
No files found.
abclib.dsp
View file @
79f04c66
...
@@ -1127,6 +1127,10 @@ SOURCE=.\src\base\wln\wln.h
...
@@ -1127,6 +1127,10 @@ SOURCE=.\src\base\wln\wln.h
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\base\wln\wlnBlast.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wln\wlnMem.c
SOURCE=.\src\base\wln\wlnMem.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
...
@@ -1143,6 +1147,10 @@ SOURCE=.\src\base\wln\wlnObj.c
...
@@ -1143,6 +1147,10 @@ SOURCE=.\src\base\wln\wlnObj.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\base\wln\wlnRead.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wln\wlnRetime.c
SOURCE=.\src\base\wln\wlnRetime.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
...
...
src/aig/gia/giaDup.c
View file @
79f04c66
...
@@ -1086,6 +1086,20 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo )
...
@@ -1086,6 +1086,20 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo )
Gia_ManSetRegNum
(
pNew
,
Gia_ManRegNum
(
pOne
)
+
Gia_ManRegNum
(
pTwo
)
);
Gia_ManSetRegNum
(
pNew
,
Gia_ManRegNum
(
pOne
)
+
Gia_ManRegNum
(
pTwo
)
);
return
pNew
;
return
pNew
;
}
}
void
Gia_ManDupRebuild
(
Gia_Man_t
*
pNew
,
Gia_Man_t
*
p
,
Vec_Int_t
*
vLits
)
{
Gia_Obj_t
*
pObj
;
int
i
;
assert
(
Vec_IntSize
(
vLits
)
==
Gia_ManCiNum
(
p
)
);
Gia_ManConst0
(
p
)
->
Value
=
0
;
Gia_ManForEachCi
(
p
,
pObj
,
i
)
pObj
->
Value
=
Vec_IntEntry
(
vLits
,
i
);
Gia_ManForEachAnd
(
p
,
pObj
,
i
)
pObj
->
Value
=
Gia_ManHashAnd
(
pNew
,
Gia_ObjFanin0Copy
(
pObj
),
Gia_ObjFanin1Copy
(
pObj
)
);
Vec_IntClear
(
vLits
);
Gia_ManForEachCo
(
p
,
pObj
,
i
)
Vec_IntPush
(
vLits
,
Gia_ObjFanin0Copy
(
pObj
)
);
assert
(
Vec_IntSize
(
vLits
)
==
Gia_ManCoNum
(
p
)
);
}
/**Function*************************************************************
/**Function*************************************************************
...
...
src/aig/gia/giaPat2.c
View file @
79f04c66
...
@@ -1027,7 +1027,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
...
@@ -1027,7 +1027,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
if
(
fVerbose
)
if
(
fVerbose
)
Abc_PrintTime
(
1
,
"Simulation time "
,
clkSim
);
Abc_PrintTime
(
1
,
"Simulation time "
,
clkSim
);
if
(
fVerbose
)
if
(
fVerbose
)
Abc_PrintTime
(
1
,
"SAT solving time"
,
clkSat
);
Abc_PrintTime
(
1
,
"SAT solving time
"
,
clkSat
);
//Vec_WecPrint( vCexes, 0 );
//Vec_WecPrint( vCexes, 0 );
if
(
vOuts
!=
vOuts0
)
if
(
vOuts
!=
vOuts0
)
Vec_IntFreeP
(
&
vOuts
);
Vec_IntFreeP
(
&
vOuts
);
...
...
src/aig/miniaig/abcOper.h
View file @
79f04c66
...
@@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )
...
@@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )
if
(
Type
==
ABC_OPER_ZEROPAD
)
return
"zPad"
;
if
(
Type
==
ABC_OPER_ZEROPAD
)
return
"zPad"
;
if
(
Type
==
ABC_OPER_SIGNEXT
)
return
"sExt"
;
if
(
Type
==
ABC_OPER_SIGNEXT
)
return
"sExt"
;
if
(
Type
==
ABC_OPER_BIT_MUX
)
return
"mux"
;
if
(
Type
==
ABC_OPER_SEL_NMUX
)
return
"nmux"
;
if
(
Type
==
ABC_OPER_SEL_SEL
)
return
"pmux"
;
if
(
Type
==
ABC_OPER_CONST
)
return
"const"
;
if
(
Type
==
ABC_OPER_CONST
)
return
"const"
;
if
(
Type
==
ABC_OPER_TABLE
)
return
"table"
;
if
(
Type
==
ABC_OPER_TABLE
)
return
"table"
;
if
(
Type
==
ABC_OPER_LUT
)
return
"lut"
;
if
(
Type
==
ABC_OPER_LUT
)
return
"lut"
;
...
...
src/base/main/mainInt.h
View file @
79f04c66
...
@@ -145,6 +145,7 @@ struct Abc_Frame_t_
...
@@ -145,6 +145,7 @@ struct Abc_Frame_t_
void
*
pAbc85Delay
;
void
*
pAbc85Delay
;
void
*
pAbcWlc
;
void
*
pAbcWlc
;
Vec_Int_t
*
pAbcWlcInv
;
Vec_Int_t
*
pAbcWlcInv
;
void
*
pAbcRtl
;
void
*
pAbcBac
;
void
*
pAbcBac
;
void
*
pAbcCba
;
void
*
pAbcCba
;
void
*
pAbcPla
;
void
*
pAbcPla
;
...
...
src/base/wlc/wlcCom.c
View file @
79f04c66
...
@@ -32,7 +32,6 @@ ABC_NAMESPACE_IMPL_START
...
@@ -32,7 +32,6 @@ ABC_NAMESPACE_IMPL_START
static
int
Abc_CommandReadWlc
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandReadWlc
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandWriteWlc
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandWriteWlc
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandYosys
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandPs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandPs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandCone
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandCone
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
...
@@ -55,12 +54,20 @@ static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -55,12 +54,20 @@ static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv )
static
int
Abc_CommandInvMin
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandInvMin
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandTest
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandTest
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandYosys
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandSolve
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
inline
Wlc_Ntk_t
*
Wlc_AbcGetNtk
(
Abc_Frame_t
*
pAbc
)
{
return
(
Wlc_Ntk_t
*
)
pAbc
->
pAbcWlc
;
}
static
inline
Wlc_Ntk_t
*
Wlc_AbcGetNtk
(
Abc_Frame_t
*
pAbc
)
{
return
(
Wlc_Ntk_t
*
)
pAbc
->
pAbcWlc
;
}
static
inline
void
Wlc_AbcFreeNtk
(
Abc_Frame_t
*
pAbc
)
{
if
(
pAbc
->
pAbcWlc
)
Wlc_NtkFree
(
Wlc_AbcGetNtk
(
pAbc
));
}
static
inline
void
Wlc_AbcFreeNtk
(
Abc_Frame_t
*
pAbc
)
{
if
(
pAbc
->
pAbcWlc
)
Wlc_NtkFree
(
Wlc_AbcGetNtk
(
pAbc
));
}
static
inline
void
Wlc_AbcUpdateNtk
(
Abc_Frame_t
*
pAbc
,
Wlc_Ntk_t
*
pNtk
)
{
Wlc_AbcFreeNtk
(
pAbc
);
pAbc
->
pAbcWlc
=
pNtk
;
}
static
inline
void
Wlc_AbcUpdateNtk
(
Abc_Frame_t
*
pAbc
,
Wlc_Ntk_t
*
pNtk
)
{
Wlc_AbcFreeNtk
(
pAbc
);
pAbc
->
pAbcWlc
=
pNtk
;
}
static
inline
Vec_Int_t
*
Wlc_AbcGetInv
(
Abc_Frame_t
*
pAbc
)
{
return
pAbc
->
pAbcWlcInv
;
}
static
inline
Vec_Int_t
*
Wlc_AbcGetInv
(
Abc_Frame_t
*
pAbc
)
{
return
pAbc
->
pAbcWlcInv
;
}
static
inline
Rtl_Lib_t
*
Wlc_AbcGetRtl
(
Abc_Frame_t
*
pAbc
)
{
return
(
Rtl_Lib_t
*
)
pAbc
->
pAbcRtl
;
}
static
inline
void
Wlc_AbcFreeRtl
(
Abc_Frame_t
*
pAbc
)
{
if
(
pAbc
->
pAbcRtl
)
Rtl_LibFree
(
Wlc_AbcGetRtl
(
pAbc
));
}
static
inline
void
Wlc_AbcUpdateRtl
(
Abc_Frame_t
*
pAbc
,
Rtl_Lib_t
*
pLib
)
{
Wlc_AbcFreeRtl
(
pAbc
);
pAbc
->
pAbcRtl
=
pLib
;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
@@ -80,7 +87,6 @@ void Wlc_Init( Abc_Frame_t * pAbc )
...
@@ -80,7 +87,6 @@ void Wlc_Init( Abc_Frame_t * pAbc )
{
{
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%read"
,
Abc_CommandReadWlc
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%read"
,
Abc_CommandReadWlc
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%write"
,
Abc_CommandWriteWlc
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%write"
,
Abc_CommandWriteWlc
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%yosys"
,
Abc_CommandYosys
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%ps"
,
Abc_CommandPs
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%ps"
,
Abc_CommandPs
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%cone"
,
Abc_CommandCone
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%cone"
,
Abc_CommandCone
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%abs"
,
Abc_CommandAbs
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%abs"
,
Abc_CommandAbs
,
0
);
...
@@ -97,6 +103,9 @@ void Wlc_Init( Abc_Frame_t * pAbc )
...
@@ -97,6 +103,9 @@ void Wlc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%show"
,
Abc_CommandShow
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%show"
,
Abc_CommandShow
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%test"
,
Abc_CommandTest
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%test"
,
Abc_CommandTest
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%yosys"
,
Abc_CommandYosys
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"%solve"
,
Abc_CommandSolve
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_ps"
,
Abc_CommandInvPs
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_ps"
,
Abc_CommandInvPs
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_print"
,
Abc_CommandInvPrint
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_print"
,
Abc_CommandInvPrint
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_check"
,
Abc_CommandInvCheck
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Word level"
,
"inv_check"
,
Abc_CommandInvCheck
,
0
);
...
@@ -308,130 +317,6 @@ usage:
...
@@ -308,130 +317,6 @@ usage:
SeeAlso []
SeeAlso []
******************************************************************************/
******************************************************************************/
int
Abc_CommandYosys
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
extern
Gia_Man_t
*
Wln_BlastSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fSkipStrash
,
int
fInvert
,
int
fTechMap
,
int
fVerbose
);
extern
Wln_Ntk_t
*
Wln_ReadSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fVerbose
);
FILE
*
pFile
;
char
*
pFileName
=
NULL
;
char
*
pTopModule
=
NULL
;
int
fCollapse
=
0
;
int
fBlast
=
0
;
int
fInvert
=
0
;
int
fTechMap
=
0
;
int
fSkipStrash
=
0
;
int
c
,
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"Tcaismvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'T'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-T
\"
should be followed by a file name.
\n
"
);
goto
usage
;
}
pTopModule
=
argv
[
globalUtilOptind
];
globalUtilOptind
++
;
break
;
case
'c'
:
fCollapse
^=
1
;
break
;
case
'a'
:
fBlast
^=
1
;
break
;
case
'i'
:
fInvert
^=
1
;
break
;
case
's'
:
fSkipStrash
^=
1
;
break
;
case
'm'
:
fTechMap
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
argc
!=
globalUtilOptind
+
1
)
{
printf
(
"Abc_CommandReadWlc(): Input file name should be given on the command line.
\n
"
);
return
0
;
}
// get the file name
pFileName
=
argv
[
globalUtilOptind
];
if
(
(
pFile
=
fopen
(
pFileName
,
"r"
))
==
NULL
)
{
Abc_Print
(
1
,
"Cannot open input file
\"
%s
\"
. "
,
pFileName
);
if
(
(
pFileName
=
Extra_FileGetSimilarName
(
pFileName
,
".v"
,
".sv"
,
NULL
,
NULL
,
NULL
))
)
Abc_Print
(
1
,
"Did you mean
\"
%s
\"
?"
,
pFileName
);
Abc_Print
(
1
,
"
\n
"
);
return
0
;
}
fclose
(
pFile
);
// perform reading
if
(
fBlast
)
{
Gia_Man_t
*
pNew
=
NULL
;
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"v"
)
)
pNew
=
Wln_BlastSystemVerilog
(
pFileName
,
pTopModule
,
fSkipStrash
,
fInvert
,
fTechMap
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"sv"
)
)
pNew
=
Wln_BlastSystemVerilog
(
pFileName
,
pTopModule
,
fSkipStrash
,
fInvert
,
fTechMap
,
fVerbose
);
else
{
printf
(
"Abc_CommandYosys(): Unknown file extension.
\n
"
);
return
0
;
}
Abc_FrameUpdateGia
(
pAbc
,
pNew
);
}
else
{
Wln_Ntk_t
*
pNtk
=
NULL
;
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"v"
)
)
pNtk
=
Wln_ReadSystemVerilog
(
pFileName
,
pTopModule
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"sv"
)
)
pNtk
=
Wln_ReadSystemVerilog
(
pFileName
,
pTopModule
,
fVerbose
);
else
{
printf
(
"Abc_CommandYosys(): Unknown file extension.
\n
"
);
return
0
;
}
//Wlc_AbcUpdateNtk( pAbc, pNtk );
}
return
0
;
usage:
Abc_Print
(
-
2
,
"usage: %%yosys [-T <module>] [-caismvh] <file_name>
\n
"
);
Abc_Print
(
-
2
,
"
\t
reads Verilog or SystemVerilog using Yosys
\n
"
);
Abc_Print
(
-
2
,
"
\t
-T : specify the top module name (default uses
\"
-auto-top
\"\n
"
);
Abc_Print
(
-
2
,
"
\t
-c : toggle collapsing the design using Yosys [default = %s]
\n
"
,
fCollapse
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-a : toggle bit-blasting the design using Yosys [default = %s]
\n
"
,
fBlast
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-i : toggle interting the outputs (useful for miters) [default = %s]
\n
"
,
fInvert
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-s : toggle no structural hashing during bit-blasting [default = %s]
\n
"
,
fSkipStrash
?
"no strash"
:
"strash"
);
Abc_Print
(
-
2
,
"
\t
-m : toggle using
\"
techmap
\"
to blast operators [default = %s]
\n
"
,
fTechMap
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-v : toggle printing verbose information [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
}
/**Function********************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
******************************************************************************/
int
Abc_CommandPs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
int
Abc_CommandPs
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
{
Wlc_Ntk_t
*
pNtk
=
Wlc_AbcGetNtk
(
pAbc
);
Wlc_Ntk_t
*
pNtk
=
Wlc_AbcGetNtk
(
pAbc
);
...
@@ -2097,6 +1982,205 @@ usage:
...
@@ -2097,6 +1982,205 @@ usage:
return
1
;
return
1
;
}
}
/**Function********************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
******************************************************************************/
int
Abc_CommandYosys
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
extern
Gia_Man_t
*
Wln_BlastSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fSkipStrash
,
int
fInvert
,
int
fTechMap
,
int
fVerbose
);
extern
Rtl_Lib_t
*
Wln_ReadSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fCollapse
,
int
fVerbose
);
FILE
*
pFile
;
char
*
pFileName
=
NULL
;
char
*
pTopModule
=
NULL
;
int
fBlast
=
0
;
int
fInvert
=
0
;
int
fTechMap
=
1
;
int
fSkipStrash
=
0
;
int
fCollapse
=
0
;
int
c
,
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"Tbismcvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'T'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-T
\"
should be followed by a file name.
\n
"
);
goto
usage
;
}
pTopModule
=
argv
[
globalUtilOptind
];
globalUtilOptind
++
;
break
;
case
'b'
:
fBlast
^=
1
;
break
;
case
'i'
:
fInvert
^=
1
;
break
;
case
's'
:
fSkipStrash
^=
1
;
break
;
case
'm'
:
fTechMap
^=
1
;
break
;
case
'c'
:
fCollapse
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
argc
!=
globalUtilOptind
+
1
)
{
printf
(
"Abc_CommandReadWlc(): Input file name should be given on the command line.
\n
"
);
return
0
;
}
// get the file name
pFileName
=
argv
[
globalUtilOptind
];
if
(
(
pFile
=
fopen
(
pFileName
,
"r"
))
==
NULL
)
{
Abc_Print
(
1
,
"Cannot open input file
\"
%s
\"
. "
,
pFileName
);
if
(
(
pFileName
=
Extra_FileGetSimilarName
(
pFileName
,
".v"
,
".sv"
,
NULL
,
NULL
,
NULL
))
)
Abc_Print
(
1
,
"Did you mean
\"
%s
\"
?"
,
pFileName
);
Abc_Print
(
1
,
"
\n
"
);
return
0
;
}
fclose
(
pFile
);
// perform reading
if
(
fBlast
)
{
Gia_Man_t
*
pNew
=
NULL
;
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"v"
)
)
pNew
=
Wln_BlastSystemVerilog
(
pFileName
,
pTopModule
,
fSkipStrash
,
fInvert
,
fTechMap
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"sv"
)
)
pNew
=
Wln_BlastSystemVerilog
(
pFileName
,
pTopModule
,
fSkipStrash
,
fInvert
,
fTechMap
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"rtlil"
)
)
pNew
=
Wln_BlastSystemVerilog
(
pFileName
,
pTopModule
,
fSkipStrash
,
fInvert
,
fTechMap
,
fVerbose
);
else
{
printf
(
"Abc_CommandYosys(): Unknown file extension.
\n
"
);
return
0
;
}
Abc_FrameUpdateGia
(
pAbc
,
pNew
);
}
else
{
Rtl_Lib_t
*
pLib
=
NULL
;
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"v"
)
)
pLib
=
Wln_ReadSystemVerilog
(
pFileName
,
pTopModule
,
fCollapse
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"sv"
)
)
pLib
=
Wln_ReadSystemVerilog
(
pFileName
,
pTopModule
,
fCollapse
,
fVerbose
);
else
if
(
!
strcmp
(
Extra_FileNameExtension
(
pFileName
),
"rtlil"
)
)
pLib
=
Wln_ReadSystemVerilog
(
pFileName
,
pTopModule
,
fCollapse
,
fVerbose
);
else
{
printf
(
"Abc_CommandYosys(): Unknown file extension.
\n
"
);
return
0
;
}
Wlc_AbcUpdateRtl
(
pAbc
,
pLib
);
}
return
0
;
usage:
Abc_Print
(
-
2
,
"usage: %%yosys [-T <module>] [-bismcvh] <file_name>
\n
"
);
Abc_Print
(
-
2
,
"
\t
reads Verilog or SystemVerilog using Yosys
\n
"
);
Abc_Print
(
-
2
,
"
\t
-T : specify the top module name (default uses
\"
-auto-top
\"\n
"
);
Abc_Print
(
-
2
,
"
\t
-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]
\n
"
,
fBlast
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-i : toggle interting the outputs (useful for miters) [default = %s]
\n
"
,
fInvert
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-s : toggle no structural hashing during bit-blasting [default = %s]
\n
"
,
fSkipStrash
?
"no strash"
:
"strash"
);
Abc_Print
(
-
2
,
"
\t
-m : toggle using
\"
techmap
\"
to blast operators [default = %s]
\n
"
,
fTechMap
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-c : toggle collapsing design hierarchy using Yosys [default = %s]
\n
"
,
fCollapse
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-v : toggle printing verbose information [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
}
/**Function********************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
******************************************************************************/
int
Abc_CommandSolve
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
extern
void
Rtl_LibPrintStats
(
Rtl_Lib_t
*
p
);
extern
void
Rtl_LibPrint
(
char
*
pFileName
,
Rtl_Lib_t
*
p
);
extern
void
Rtl_LibNormRanges
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibOrderWires
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibOrderCells
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibBlast
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibReorderModules
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibSolve
(
Rtl_Lib_t
*
pLib
);
extern
void
Rtl_LibPreprocess
(
Rtl_Lib_t
*
pLib
);
Gia_Man_t
*
pGia
=
NULL
;
Rtl_Lib_t
*
pLib
=
Wlc_AbcGetRtl
(
pAbc
);
int
c
,
fPrepro
=
0
,
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"pvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'p'
:
fPrepro
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
Rtl_LibPrintStats
(
pLib
);
//Rtl_LibPrint( NULL, pLib );
Rtl_LibOrderWires
(
pLib
);
Rtl_LibOrderCells
(
pLib
);
Rtl_LibBlast
(
pLib
);
//Rtl_LibReorderModules( pLib );
//Rtl_LibPrintStats( pLib );
if
(
fPrepro
)
Rtl_LibPreprocess
(
pLib
);
Rtl_LibSolve
(
pLib
);
//Rtl_LibPrint( NULL, pLib );
Wlc_AbcUpdateRtl
(
pAbc
,
NULL
);
Gia_ManStopP
(
&
pGia
);
return
0
;
usage:
Abc_Print
(
-
2
,
"usage: %%solve [-pvh]
\n
"
);
Abc_Print
(
-
2
,
"
\t
experiments with word-level networks
\n
"
);
Abc_Print
(
-
2
,
"
\t
-p : toggle preprocessing for verification [default = %s]
\n
"
,
fPrepro
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-v : toggle printing verbose information [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
...
src/base/wln/module.make
View file @
79f04c66
SRC
+=
src/base/wln/wln.c
\
SRC
+=
src/base/wln/wln.c
\
src/base/wln/wlnBlast.c
\
src/base/wln/wlnMem.c
\
src/base/wln/wlnMem.c
\
src/base/wln/wlnNdr.c
\
src/base/wln/wlnNdr.c
\
src/base/wln/wlnNtk.c
\
src/base/wln/wlnNtk.c
\
src/base/wln/wlnObj.c
\
src/base/wln/wlnObj.c
\
src/base/wln/wlnRead.c
\
src/base/wln/wlnRetime.c
\
src/base/wln/wlnRetime.c
\
src/base/wln/wlnRtl.c
\
src/base/wln/wlnRtl.c
\
src/base/wln/wlnWlc.c
\
src/base/wln/wlnWlc.c
\
...
...
src/base/wln/wln.h
View file @
79f04c66
...
@@ -251,6 +251,10 @@ extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );
...
@@ -251,6 +251,10 @@ extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );
/*=== wlcWriteVer.c ========================================================*/
/*=== wlcWriteVer.c ========================================================*/
extern
void
Wln_WriteVer
(
Wln_Ntk_t
*
p
,
char
*
pFileName
);
extern
void
Wln_WriteVer
(
Wln_Ntk_t
*
p
,
char
*
pFileName
);
/*=== wlcRead.c ========================================================*/
typedef
struct
Rtl_Lib_t_
Rtl_Lib_t
;
extern
Rtl_Lib_t
*
Rtl_LibReadFile
(
char
*
pFileName
,
char
*
pFileSpec
);
extern
void
Rtl_LibFree
(
Rtl_Lib_t
*
p
);
ABC_NAMESPACE_HEADER_END
ABC_NAMESPACE_HEADER_END
...
...
src/base/wln/wlnBlast.c
0 → 100644
View file @
79f04c66
/**CFile****************************************************************
FileName [wlnBlast.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Word-level network.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 23, 2018.]
Revision [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
***********************************************************************/
#include "wln.h"
#include "base/wlc/wlc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Rtl_VecExtend
(
Vec_Int_t
*
p
,
int
nRange
,
int
fSigned
)
{
Vec_IntFillExtra
(
p
,
nRange
,
fSigned
?
Vec_IntEntryLast
(
p
)
:
0
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Rtl_NtkBlastNode
(
Gia_Man_t
*
pNew
,
int
Type
,
int
nIns
,
Vec_Int_t
*
vDatas
,
int
nRange
,
int
fSign0
,
int
fSign1
)
{
extern
void
Wlc_BlastMinus
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
Vec_Int_t
*
vRes
);
extern
int
Wlc_BlastReduction
(
Gia_Man_t
*
pNew
,
int
*
pFans
,
int
nFans
,
int
Type
);
extern
int
Wlc_BlastLess
(
Gia_Man_t
*
pNew
,
int
*
pArg0
,
int
*
pArg1
,
int
nBits
);
extern
int
Wlc_BlastLessSigned
(
Gia_Man_t
*
pNew
,
int
*
pArg0
,
int
*
pArg1
,
int
nBits
);
extern
void
Wlc_BlastShiftRight
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
int
*
pShift
,
int
nShift
,
int
fSticky
,
Vec_Int_t
*
vRes
);
extern
void
Wlc_BlastShiftLeft
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
int
*
pShift
,
int
nShift
,
int
fSticky
,
Vec_Int_t
*
vRes
);
extern
int
Wlc_BlastAdder
(
Gia_Man_t
*
pNew
,
int
*
pAdd0
,
int
*
pAdd1
,
int
nBits
,
int
Carry
);
// result is in pAdd0
extern
void
Wlc_BlastSubtract
(
Gia_Man_t
*
pNew
,
int
*
pAdd0
,
int
*
pAdd1
,
int
nBits
,
int
Carry
);
// result is in pAdd0
extern
int
Wlc_NtkCountConstBits
(
int
*
pArray
,
int
nSize
);
extern
void
Wlc_BlastBooth
(
Gia_Man_t
*
pNew
,
int
*
pArgA
,
int
*
pArgB
,
int
nArgA
,
int
nArgB
,
Vec_Int_t
*
vRes
,
int
fSigned
,
int
fCla
,
Vec_Wec_t
**
pvProds
);
extern
void
Wlc_BlastMultiplier3
(
Gia_Man_t
*
pNew
,
int
*
pArgA
,
int
*
pArgB
,
int
nArgA
,
int
nArgB
,
Vec_Int_t
*
vRes
,
int
fSigned
,
int
fCla
,
Vec_Wec_t
**
pvProds
);
extern
void
Wlc_BlastZeroCondition
(
Gia_Man_t
*
pNew
,
int
*
pDiv
,
int
nDiv
,
Vec_Int_t
*
vRes
);
extern
void
Wlc_BlastDivider
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
int
*
pDiv
,
int
nDiv
,
int
fQuo
,
Vec_Int_t
*
vRes
);
extern
void
Wlc_BlastDividerSigned
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
int
*
pDiv
,
int
nDiv
,
int
fQuo
,
Vec_Int_t
*
vRes
);
extern
void
Wlc_BlastPower
(
Gia_Man_t
*
pNew
,
int
*
pNum
,
int
nNum
,
int
*
pExp
,
int
nExp
,
Vec_Int_t
*
vTemp
,
Vec_Int_t
*
vRes
);
int
k
,
iLit
,
iLit0
,
iLit1
;
if
(
nIns
==
1
)
{
Vec_Int_t
*
vArg
=
vDatas
;
Vec_Int_t
*
vRes
=
vDatas
+
3
;
assert
(
Vec_IntSize
(
vRes
)
==
0
);
if
(
Type
==
ABC_OPER_BIT_INV
)
// Y = ~A $not
{
assert
(
Vec_IntSize
(
vArg
)
==
nRange
);
Vec_IntForEachEntry
(
vArg
,
iLit
,
k
)
Vec_IntPush
(
vRes
,
Abc_LitNot
(
iLit
)
);
return
;
}
if
(
Type
==
ABC_OPER_BIT_BUF
)
// Y = +A $pos
{
assert
(
Vec_IntSize
(
vArg
)
==
nRange
);
Vec_IntForEachEntry
(
vArg
,
iLit
,
k
)
Vec_IntPush
(
vRes
,
iLit
);
return
;
}
if
(
Type
==
ABC_OPER_ARI_MIN
)
// Y = -A $neg
{
assert
(
Vec_IntSize
(
vArg
)
==
nRange
);
Wlc_BlastMinus
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
vRes
);
return
;
}
if
(
Type
==
ABC_OPER_RED_AND
)
// Y = &A $reduce_and
{
assert
(
nRange
==
1
);
Vec_IntPush
(
vRes
,
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
WLC_OBJ_REDUCT_AND
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_RED_OR
)
// Y = |A $reduce_or $reduce_bool
{
assert
(
nRange
==
1
);
Vec_IntPush
(
vRes
,
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
WLC_OBJ_REDUCT_OR
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_RED_XOR
)
// Y = ^A $reduce_xor
{
assert
(
nRange
==
1
);
Vec_IntPush
(
vRes
,
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
WLC_OBJ_REDUCT_XOR
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_RED_NXOR
)
// Y = ~^A $reduce_xnor
{
assert
(
nRange
==
1
);
Vec_IntPush
(
vRes
,
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
WLC_OBJ_REDUCT_NXOR
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_LOGIC_NOT
)
// Y = !A $logic_not
{
int
iLit
=
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg
),
Vec_IntSize
(
vArg
),
WLC_OBJ_REDUCT_OR
);
assert
(
nRange
==
1
);
Vec_IntFill
(
vRes
,
1
,
Abc_LitNot
(
iLit
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
assert
(
0
);
return
;
}
if
(
nIns
==
2
)
{
Vec_Int_t
*
vArg0
=
vDatas
;
Vec_Int_t
*
vArg1
=
vDatas
+
1
;
Vec_Int_t
*
vRes
=
vDatas
+
3
;
int
nRangeMax
=
Abc_MaxInt
(
nRange
,
Abc_MaxInt
(
Vec_IntSize
(
vArg0
),
Vec_IntSize
(
vArg1
))
);
int
nSizeArg0
=
Vec_IntSize
(
vArg0
);
int
nSizeArg1
=
Vec_IntSize
(
vArg1
);
Rtl_VecExtend
(
vArg0
,
nRangeMax
,
fSign0
);
Rtl_VecExtend
(
vArg1
,
nRangeMax
,
fSign1
);
assert
(
Vec_IntSize
(
vArg0
)
==
Vec_IntSize
(
vArg1
)
);
assert
(
Vec_IntSize
(
vRes
)
==
0
);
if
(
Type
==
ABC_OPER_LOGIC_AND
)
// Y = A && B $logic_and
{
int
iLit0
=
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntSize
(
vArg0
),
WLC_OBJ_REDUCT_OR
);
int
iLit1
=
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg1
),
WLC_OBJ_REDUCT_OR
);
assert
(
1
==
nRange
);
Vec_IntFill
(
vRes
,
1
,
Gia_ManHashAnd
(
pNew
,
iLit0
,
iLit1
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_LOGIC_OR
)
// Y = A || B $logic_or
{
int
iLit0
=
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntSize
(
vArg0
),
WLC_OBJ_REDUCT_OR
);
int
iLit1
=
Wlc_BlastReduction
(
pNew
,
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg1
),
WLC_OBJ_REDUCT_OR
);
assert
(
1
==
nRange
);
Vec_IntFill
(
vRes
,
1
,
Gia_ManHashOr
(
pNew
,
iLit0
,
iLit1
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_BIT_AND
)
// Y = A & B $and
{
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
Vec_IntPush
(
vRes
,
Gia_ManHashAnd
(
pNew
,
iLit0
,
iLit1
)
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
if
(
Type
==
ABC_OPER_BIT_OR
)
// Y = A | B $or
{
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
Vec_IntPush
(
vRes
,
Gia_ManHashOr
(
pNew
,
iLit0
,
iLit1
)
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
if
(
Type
==
ABC_OPER_BIT_XOR
)
// Y = A ^ B $xor
{
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
Vec_IntPush
(
vRes
,
Gia_ManHashXor
(
pNew
,
iLit0
,
iLit1
)
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
if
(
Type
==
ABC_OPER_BIT_NXOR
)
// Y = A ~^ B $xnor
{
assert
(
Vec_IntSize
(
vArg0
)
==
nRange
);
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
Vec_IntPush
(
vRes
,
Abc_LitNot
(
Gia_ManHashXor
(
pNew
,
iLit0
,
iLit1
))
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
/*
if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
*/
if
(
Type
==
ABC_OPER_COMP_EQU
||
Type
==
ABC_OPER_COMP_NOTEQU
)
{
iLit
=
0
;
assert
(
nRange
==
1
);
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
iLit
=
Gia_ManHashOr
(
pNew
,
iLit
,
Gia_ManHashXor
(
pNew
,
iLit0
,
iLit1
)
);
Vec_IntFill
(
vRes
,
1
,
Abc_LitNotCond
(
iLit
,
Type
==
ABC_OPER_COMP_EQU
)
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
if
(
Type
==
ABC_OPER_COMP_LESS
||
Type
==
ABC_OPER_COMP_LESSEQU
||
Type
==
ABC_OPER_COMP_MORE
||
Type
==
ABC_OPER_COMP_MOREEQU
)
{
int
fSigned
=
fSign0
&&
fSign1
;
int
fSwap
=
(
Type
==
ABC_OPER_COMP_MORE
||
Type
==
ABC_OPER_COMP_LESSEQU
);
int
fCompl
=
(
Type
==
ABC_OPER_COMP_MOREEQU
||
Type
==
ABC_OPER_COMP_LESSEQU
);
assert
(
Vec_IntSize
(
vArg0
)
==
Vec_IntSize
(
vArg1
)
);
assert
(
nRange
==
1
);
if
(
fSwap
)
ABC_SWAP
(
Vec_Int_t
,
*
vArg0
,
*
vArg1
)
if
(
fSigned
)
iLit
=
Wlc_BlastLessSigned
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg0
)
);
else
iLit
=
Wlc_BlastLess
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg0
)
);
iLit
=
Abc_LitNotCond
(
iLit
,
fCompl
);
Vec_IntFill
(
vRes
,
1
,
iLit
);
for
(
k
=
1
;
k
<
nRange
;
k
++
)
Vec_IntPush
(
vRes
,
0
);
return
;
}
/*
if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
*/
if
(
Type
==
ABC_OPER_SHIFT_R
||
Type
==
ABC_OPER_SHIFT_RA
||
Type
==
ABC_OPER_SHIFT_L
||
Type
==
ABC_OPER_SHIFT_LA
)
{
Vec_IntShrink
(
vArg1
,
nSizeArg1
);
if
(
Type
==
ABC_OPER_SHIFT_R
||
Type
==
ABC_OPER_SHIFT_RA
)
Wlc_BlastShiftRight
(
pNew
,
Vec_IntArray
(
vArg0
),
nRangeMax
,
Vec_IntArray
(
vArg1
),
nSizeArg1
,
fSign0
&&
Type
==
ABC_OPER_SHIFT_RA
,
vRes
);
else
Wlc_BlastShiftLeft
(
pNew
,
Vec_IntArray
(
vArg0
),
nRangeMax
,
Vec_IntArray
(
vArg1
),
nSizeArg1
,
0
,
vRes
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
/*
if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
*/
if
(
Type
==
ABC_OPER_ARI_ADD
||
Type
==
ABC_OPER_ARI_SUB
)
{
//Vec_IntPrint( vArg0 );
//Vec_IntPrint( vArg1 );
Vec_IntAppend
(
vRes
,
vArg0
);
if
(
Type
==
ABC_OPER_ARI_ADD
)
Wlc_BlastAdder
(
pNew
,
Vec_IntArray
(
vRes
),
Vec_IntArray
(
vArg1
),
nRangeMax
,
0
);
// result is in pFan0 (vRes)
else
Wlc_BlastSubtract
(
pNew
,
Vec_IntArray
(
vRes
),
Vec_IntArray
(
vArg1
),
nRangeMax
,
1
);
// result is in pFan0 (vRes)
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
if
(
Type
==
ABC_OPER_ARI_MUL
)
{
int
fBooth
=
1
;
int
fCla
=
0
;
int
fSigned
=
fSign0
&&
fSign1
;
Vec_IntShrink
(
vArg0
,
nSizeArg0
);
Vec_IntShrink
(
vArg1
,
nSizeArg1
);
if
(
Wlc_NtkCountConstBits
(
Vec_IntArray
(
vArg0
),
Vec_IntSize
(
vArg0
))
<
Wlc_NtkCountConstBits
(
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg1
))
)
ABC_SWAP
(
Vec_Int_t
,
*
vArg0
,
*
vArg1
)
if
(
fBooth
)
Wlc_BlastBooth
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg0
),
Vec_IntSize
(
vArg1
),
vRes
,
fSigned
,
fCla
,
NULL
);
else
Wlc_BlastMultiplier3
(
pNew
,
Vec_IntArray
(
vArg0
),
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg0
),
Vec_IntSize
(
vArg1
),
vRes
,
fSigned
,
fCla
,
NULL
);
if
(
nRange
>
Vec_IntSize
(
vRes
)
)
Vec_IntFillExtra
(
vRes
,
nRange
,
fSigned
?
Vec_IntEntryLast
(
vRes
)
:
0
);
else
Vec_IntShrink
(
vRes
,
nRange
);
assert
(
Vec_IntSize
(
vRes
)
==
nRange
);
return
;
}
if
(
Type
==
ABC_OPER_ARI_DIV
||
Type
==
ABC_OPER_ARI_MOD
)
{
int
fDivBy0
=
1
;
// correct with 1
int
fSigned
=
fSign0
&&
fSign1
;
if
(
fSigned
)
Wlc_BlastDividerSigned
(
pNew
,
Vec_IntArray
(
vArg0
),
nRangeMax
,
Vec_IntArray
(
vArg1
),
nRangeMax
,
Type
==
ABC_OPER_ARI_DIV
,
vRes
);
else
Wlc_BlastDivider
(
pNew
,
Vec_IntArray
(
vArg0
),
nRangeMax
,
Vec_IntArray
(
vArg1
),
nRangeMax
,
Type
==
ABC_OPER_ARI_DIV
,
vRes
);
Vec_IntShrink
(
vRes
,
nRange
);
if
(
!
fDivBy0
)
Wlc_BlastZeroCondition
(
pNew
,
Vec_IntArray
(
vArg1
),
nRange
,
vRes
);
return
;
}
if
(
Type
==
ABC_OPER_ARI_POW
)
{
Vec_Int_t
*
vTemp
=
vDatas
+
4
;
Vec_IntGrow
(
vTemp
,
nRangeMax
);
Vec_IntGrow
(
vRes
,
nRangeMax
);
Vec_IntShrink
(
vArg1
,
nSizeArg1
);
Wlc_BlastPower
(
pNew
,
Vec_IntArray
(
vArg0
),
nRangeMax
,
Vec_IntArray
(
vArg1
),
Vec_IntSize
(
vArg1
),
vTemp
,
vRes
);
Vec_IntShrink
(
vRes
,
nRange
);
return
;
}
}
if
(
nIns
==
3
)
{
if
(
Type
==
ABC_OPER_SEL_NMUX
)
// $mux
{
Vec_Int_t
*
vArg0
=
vDatas
;
Vec_Int_t
*
vArg1
=
vDatas
+
1
;
Vec_Int_t
*
vArgS
=
vDatas
+
2
;
Vec_Int_t
*
vRes
=
vDatas
+
3
;
int
iCtrl
=
Vec_IntEntry
(
vArgS
,
0
);
//Vec_IntPrint( vArg0 );
//Vec_IntPrint( vArg1 );
//Vec_IntPrint( vArgS );
assert
(
Vec_IntSize
(
vArg0
)
==
Vec_IntSize
(
vArg1
)
);
assert
(
Vec_IntSize
(
vArg0
)
==
nRange
);
assert
(
Vec_IntSize
(
vArgS
)
==
1
);
assert
(
Vec_IntSize
(
vRes
)
==
0
);
Vec_IntForEachEntryTwo
(
vArg0
,
vArg1
,
iLit0
,
iLit1
,
k
)
Vec_IntPush
(
vRes
,
Gia_ManHashMux
(
pNew
,
iCtrl
,
iLit1
,
iLit0
)
);
return
;
}
if
(
Type
==
ABC_OPER_SEL_SEL
)
// $pmux
{
int
i
,
k
,
iLit
;
Vec_Int_t
*
vArgA
=
vDatas
;
Vec_Int_t
*
vArgB
=
vDatas
+
1
;
Vec_Int_t
*
vArgS
=
vDatas
+
2
;
Vec_Int_t
*
vRes
=
vDatas
+
3
;
Vec_Int_t
*
vTemp
=
vDatas
+
4
;
assert
(
Vec_IntSize
(
vArgA
)
==
nRange
);
// widthA = widthY
assert
(
Vec_IntSize
(
vArgB
)
==
Vec_IntSize
(
vArgA
)
*
Vec_IntSize
(
vArgS
)
);
// widthB == widthA*widthS
assert
(
Vec_IntSize
(
vRes
)
==
0
);
for
(
i
=
0
;
i
<
nRange
;
i
++
)
{
int
iCond
=
1
;
Vec_IntClear
(
vTemp
);
Vec_IntForEachEntry
(
vArgS
,
iLit
,
k
)
// iLit = S[i]
{
//Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i]
Vec_IntPush
(
vTemp
,
Abc_LitNot
(
Gia_ManHashAnd
(
pNew
,
iLit
,
Vec_IntEntry
(
vArgB
,
nRange
*
k
+
i
))
)
);
// B[widthA*k+i]
iCond
=
Gia_ManHashAnd
(
pNew
,
iCond
,
Abc_LitNot
(
iLit
)
);
}
Vec_IntPush
(
vTemp
,
Abc_LitNot
(
Gia_ManHashAnd
(
pNew
,
iCond
,
Vec_IntEntry
(
vArgA
,
i
))
)
);
Vec_IntPush
(
vRes
,
Abc_LitNot
(
Gia_ManHashAndMulti
(
pNew
,
vTemp
)
)
);
}
return
;
}
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/base/wln/wlnRead.c
0 → 100644
View file @
79f04c66
/**CFile****************************************************************
FileName [wln.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Word-level network.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 23, 2018.]
Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
***********************************************************************/
#include "wln.h"
#include "proof/cec/cec.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define MAX_LINE 10000
#define MAX_MAP 32
#define CELL_NUM 8
#define WIRE_NUM 5
#define TEMP_NUM 5
//typedef struct Rtl_Lib_t_ Rtl_Lib_t;
struct
Rtl_Lib_t_
{
char
*
pSpec
;
// input file name
Vec_Ptr_t
*
vNtks
;
// modules
Abc_Nam_t
*
pManName
;
// object names
Vec_Int_t
vConsts
;
// constants
Vec_Int_t
vSlices
;
// selections
Vec_Int_t
vConcats
;
// concatenations
FILE
*
pFile
;
// temp file
Vec_Int_t
*
vTokens
;
// temp tokens
int
pMap
[
MAX_MAP
];
// temp map
Vec_Int_t
*
vMap
;
// mapping NameId into wires
Vec_Int_t
vAttrTemp
;
// temp
Vec_Int_t
vTemp
[
TEMP_NUM
];
// temp
};
typedef
struct
Rtl_Ntk_t_
Rtl_Ntk_t
;
struct
Rtl_Ntk_t_
{
int
NameId
;
// model name
int
nInputs
;
// word-level inputs
int
nOutputs
;
// word-level outputs
Vec_Int_t
vWires
;
// wires (name{upto,signed,in,out}+width+offset+number)
Vec_Int_t
vCells
;
// instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[6]mark+(attr+params+conns))
Vec_Int_t
vConns
;
// connection pairs
Vec_Int_t
vStore
;
// storage for cells
Vec_Int_t
vAttrs
;
// attributes
Rtl_Lib_t
*
pLib
;
// parent
Vec_Int_t
vOrder
;
// topological order
Vec_Int_t
vLits
;
// bit-level view
Vec_Int_t
vBitTemp
;
// storage for bits
Gia_Man_t
*
pGia
;
// derived by bit-blasting
int
Slice0
;
// first slice
int
Slice1
;
// last slice
int
iCopy
;
// place in array
};
static
inline
int
Rtl_LibNtkNum
(
Rtl_Lib_t
*
pLib
)
{
return
Vec_PtrSize
(
pLib
->
vNtks
);
}
static
inline
Rtl_Ntk_t
*
Rtl_LibNtk
(
Rtl_Lib_t
*
pLib
,
int
i
)
{
return
(
Rtl_Ntk_t
*
)
Vec_PtrEntry
(
pLib
->
vNtks
,
i
);
}
static
inline
Rtl_Ntk_t
*
Rtl_LibTop
(
Rtl_Lib_t
*
pLib
)
{
return
Rtl_LibNtk
(
pLib
,
Rtl_LibNtkNum
(
pLib
)
-
1
);
}
static
inline
Rtl_Ntk_t
*
Rtl_NtkModule
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Rtl_LibNtk
(
p
->
pLib
,
i
);
}
static
inline
int
Rtl_NtkStrId
(
Rtl_Ntk_t
*
p
,
char
*
s
)
{
return
Abc_NamStrFind
(
p
->
pLib
->
pManName
,
s
);
}
static
inline
char
*
Rtl_NtkStr
(
Rtl_Ntk_t
*
p
,
int
h
)
{
return
Abc_NamStr
(
p
->
pLib
->
pManName
,
h
);
}
static
inline
char
*
Rtl_NtkName
(
Rtl_Ntk_t
*
p
)
{
return
Rtl_NtkStr
(
p
,
p
->
NameId
);
}
static
inline
FILE
*
Rtl_NtkFile
(
Rtl_Ntk_t
*
p
)
{
return
p
->
pLib
->
pFile
;
}
static
inline
int
Rtl_NtkTokId
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
i
<
Vec_IntSize
(
p
->
pLib
->
vTokens
)
?
Vec_IntEntry
(
p
->
pLib
->
vTokens
,
i
)
:
-
1
;
}
static
inline
char
*
Rtl_NtkTokStr
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
i
<
Vec_IntSize
(
p
->
pLib
->
vTokens
)
?
Rtl_NtkStr
(
p
,
Vec_IntEntry
(
p
->
pLib
->
vTokens
,
i
))
:
NULL
;
}
static
inline
int
Rtl_NtkTokCheck
(
Rtl_Ntk_t
*
p
,
int
i
,
int
Tok
)
{
return
i
==
p
->
pLib
->
pMap
[
Tok
];
}
static
inline
int
Rtl_NtkPosCheck
(
Rtl_Ntk_t
*
p
,
int
i
,
int
Tok
)
{
return
Vec_IntEntry
(
p
->
pLib
->
vTokens
,
i
)
==
p
->
pLib
->
pMap
[
Tok
];
}
static
inline
int
Rtl_NtkInputNum
(
Rtl_Ntk_t
*
p
)
{
return
p
->
nInputs
;
}
static
inline
int
Rtl_NtkOutputNum
(
Rtl_Ntk_t
*
p
)
{
return
p
->
nOutputs
;
}
static
inline
int
Rtl_NtkAttrNum
(
Rtl_Ntk_t
*
p
)
{
return
Vec_IntSize
(
&
p
->
vAttrs
)
/
2
;
}
static
inline
int
Rtl_NtkWireNum
(
Rtl_Ntk_t
*
p
)
{
return
Vec_IntSize
(
&
p
->
vWires
)
/
WIRE_NUM
;
}
static
inline
int
Rtl_NtkCellNum
(
Rtl_Ntk_t
*
p
)
{
return
Vec_IntSize
(
&
p
->
vCells
);
}
static
inline
int
Rtl_NtkConNum
(
Rtl_Ntk_t
*
p
)
{
return
Vec_IntSize
(
&
p
->
vConns
)
/
2
;
}
static
inline
int
Rtl_NtkObjNum
(
Rtl_Ntk_t
*
p
)
{
return
p
->
nInputs
+
p
->
nOutputs
+
Rtl_NtkCellNum
(
p
)
+
Rtl_NtkConNum
(
p
);
}
static
inline
int
*
Rtl_NtkWire
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntryP
(
&
p
->
vWires
,
WIRE_NUM
*
i
);
}
static
inline
int
*
Rtl_NtkCell
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntryP
(
&
p
->
vStore
,
Vec_IntEntry
(
&
p
->
vCells
,
i
));
}
static
inline
int
*
Rtl_NtkCon
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntryP
(
&
p
->
vConns
,
2
*
i
);
}
static
inline
int
Rtl_WireName
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
)
>>
4
;
}
static
inline
char
*
Rtl_WireNameStr
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Rtl_NtkStr
(
p
,
Rtl_WireName
(
p
,
i
));
}
static
inline
int
Rtl_WireFirst
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
);
}
static
inline
int
Rtl_WireWidth
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
1
);
}
static
inline
int
Rtl_WireOffset
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
2
);
}
static
inline
int
Rtl_WireNumber
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
3
);
}
static
inline
int
Rtl_WireBitStart
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
4
);
}
static
inline
int
Rtl_WireMapNameToId
(
Rtl_Ntk_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
p
->
pLib
->
vMap
,
i
);
}
static
inline
int
Rtl_CellType
(
int
*
pCell
)
{
return
pCell
[
0
];
}
static
inline
int
Rtl_CellName
(
int
*
pCell
)
{
return
pCell
[
1
];
}
static
inline
int
Rtl_CellModule
(
int
*
pCell
)
{
return
pCell
[
2
];
}
static
inline
int
Rtl_CellInputNum
(
int
*
pCell
)
{
return
pCell
[
3
];
}
static
inline
int
Rtl_CellOutputNum
(
int
*
pCell
)
{
return
pCell
[
6
]
-
pCell
[
3
];
}
static
inline
int
Rtl_CellAttrNum
(
int
*
pCell
)
{
return
pCell
[
4
];
}
static
inline
int
Rtl_CellParamNum
(
int
*
pCell
)
{
return
pCell
[
5
];
}
static
inline
int
Rtl_CellConNum
(
int
*
pCell
)
{
return
pCell
[
6
];
}
static
inline
int
Rtl_CellMark
(
int
*
pCell
)
{
return
pCell
[
7
];
}
static
inline
Rtl_Ntk_t
*
Rtl_CellNtk
(
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
return
Rtl_CellModule
(
pCell
)
>=
ABC_INFINITY
?
Rtl_NtkModule
(
p
,
Rtl_CellModule
(
pCell
)
-
ABC_INFINITY
)
:
NULL
;
}
static
inline
char
*
Rtl_CellTypeStr
(
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
return
Rtl_NtkStr
(
p
,
Rtl_CellType
(
pCell
));
}
static
inline
char
*
Rtl_CellNameStr
(
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
return
Rtl_NtkStr
(
p
,
Rtl_CellName
(
pCell
));
}
static
inline
int
Rtl_SigIsNone
(
int
s
)
{
return
(
s
&
0x3
)
==
0
;
}
static
inline
int
Rtl_SigIsConst
(
int
s
)
{
return
(
s
&
0x3
)
==
1
;
}
static
inline
int
Rtl_SigIsSlice
(
int
s
)
{
return
(
s
&
0x3
)
==
2
;
}
static
inline
int
Rtl_SigIsConcat
(
int
s
)
{
return
(
s
&
0x3
)
==
3
;
}
#define Rtl_NtkForEachAttr( p, Par, Val, i ) \
for ( i = 0; i < Rtl_NtkAttrNum(p) && (Par = Vec_IntEntry(&p->vAttrs, 2*i)) && (Val = Vec_IntEntry(&p->vAttrs, 2*i+1)); i++ )
#define Rtl_NtkForEachWire( p, pWire, i ) \
for ( i = 0; i < Rtl_NtkWireNum(p) && (pWire = Vec_IntEntryP(&p->vWires, WIRE_NUM*i)); i++ )
#define Rtl_NtkForEachCell( p, pCell, i ) \
for ( i = 0; i < Rtl_NtkCellNum(p) && (pCell = Rtl_NtkCell(p, i)); i++ )
#define Rtl_NtkForEachCon( p, pCon, i ) \
for ( i = 0; i < Rtl_NtkConNum(p) && (pCon = Vec_IntEntryP(&p->vConns, 2*i)); i++ )
#define Rtl_CellForEachAttr( p, pCell, Par, Val, i ) \
for ( i = 0; i < pCell[4] && (Par = pCell[CELL_NUM+2*i]) && (Val = pCell[CELL_NUM+2*i+1]); i++ )
#define Rtl_CellForEachParam( p, pCell, Par, Val, i ) \
for ( i = 0; i < pCell[5] && (Par = pCell[CELL_NUM+2*(pCell[4]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+i)+1]); i++ )
#define Rtl_CellForEachConnect( p, pCell, Par, Val, i ) \
for ( i = 0; i < pCell[6] && (Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)+1]); i++ )
#define Rtl_CellForEachInput( p, pCell, Par, Val, i ) \
Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i >= Rtl_CellInputNum(pCell) ) continue; else
#define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \
Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Rtl_Ntk_t
*
Rtl_NtkAlloc
(
Rtl_Lib_t
*
pLib
)
{
Rtl_Ntk_t
*
p
=
ABC_CALLOC
(
Rtl_Ntk_t
,
1
);
Vec_IntGrow
(
&
p
->
vWires
,
4
);
Vec_IntGrow
(
&
p
->
vCells
,
4
);
Vec_IntGrow
(
&
p
->
vConns
,
4
);
Vec_IntGrow
(
&
p
->
vStore
,
8
);
Vec_IntGrow
(
&
p
->
vAttrs
,
8
);
Vec_PtrPush
(
pLib
->
vNtks
,
(
void
*
)
p
);
p
->
pLib
=
pLib
;
return
p
;
}
void
Rtl_NtkFree
(
Rtl_Ntk_t
*
p
)
{
Gia_ManStopP
(
&
p
->
pGia
);
ABC_FREE
(
p
->
vWires
.
pArray
);
ABC_FREE
(
p
->
vCells
.
pArray
);
ABC_FREE
(
p
->
vConns
.
pArray
);
ABC_FREE
(
p
->
vStore
.
pArray
);
ABC_FREE
(
p
->
vAttrs
.
pArray
);
ABC_FREE
(
p
->
vOrder
.
pArray
);
ABC_FREE
(
p
->
vLits
.
pArray
);
ABC_FREE
(
p
->
vBitTemp
.
pArray
);
ABC_FREE
(
p
);
}
void
Rtl_NtkCountPio
(
Rtl_Ntk_t
*
p
,
int
Counts
[
4
]
)
{
int
i
,
*
pWire
;
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
{
if
(
pWire
[
0
]
&
1
)
// PI
Counts
[
0
]
++
,
Counts
[
1
]
+=
pWire
[
1
];
if
(
pWire
[
0
]
&
2
)
// PO
Counts
[
2
]
++
,
Counts
[
3
]
+=
pWire
[
1
];
}
assert
(
p
->
nInputs
==
Counts
[
0
]
);
assert
(
p
->
nOutputs
==
Counts
[
2
]
);
}
void
Rtl_NtkPrintOpers
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pCell
,
nBlack
=
0
,
nUser
=
0
,
Counts
[
ABC_OPER_LAST
]
=
{
0
};
if
(
Rtl_NtkCellNum
(
p
)
==
0
)
return
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
if
(
Rtl_CellModule
(
pCell
)
<
ABC_OPER_LAST
)
Counts
[
Rtl_CellModule
(
pCell
)]
++
;
else
if
(
Rtl_CellModule
(
pCell
)
==
ABC_OPER_LAST
-
1
)
nBlack
++
;
else
nUser
++
;
printf
(
"There are %d instances in this network:
\n
"
,
Rtl_NtkCellNum
(
p
)
);
if
(
nBlack
)
printf
(
" %s (%d)"
,
"blackbox"
,
nBlack
);
if
(
nUser
)
printf
(
" %s (%d)"
,
"user"
,
nUser
);
for
(
i
=
0
;
i
<
ABC_OPER_LAST
;
i
++
)
if
(
Counts
[
i
]
)
printf
(
" %s (%d)"
,
Abc_OperName
(
i
),
Counts
[
i
]
);
printf
(
"
\n
"
);
}
void
Rtl_NtkPrintStats
(
Rtl_Ntk_t
*
p
,
int
nNameSymbs
)
{
int
Counts
[
4
]
=
{
0
};
Rtl_NtkCountPio
(
p
,
Counts
);
printf
(
"%*s : "
,
nNameSymbs
,
Rtl_NtkName
(
p
)
);
printf
(
"PI = %3d (%3d) "
,
Counts
[
0
],
Counts
[
1
]
);
printf
(
"PO = %3d (%3d) "
,
Counts
[
2
],
Counts
[
3
]
);
printf
(
"Wire = %6d "
,
Rtl_NtkWireNum
(
p
)
);
printf
(
"Cell = %6d "
,
Rtl_NtkCellNum
(
p
)
);
printf
(
"Con = %6d"
,
Rtl_NtkConNum
(
p
)
);
printf
(
"
\n
"
);
//Rtl_NtkPrintOpers( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Rtl_Lib_t
*
Rtl_LibAlloc
()
{
Rtl_Lib_t
*
p
=
ABC_CALLOC
(
Rtl_Lib_t
,
1
);
p
->
vNtks
=
Vec_PtrAlloc
(
100
);
Vec_IntGrow
(
&
p
->
vConsts
,
1000
);
Vec_IntGrow
(
&
p
->
vSlices
,
1000
);
Vec_IntGrow
(
&
p
->
vConcats
,
1000
);
return
p
;
}
void
Rtl_LibFree
(
Rtl_Lib_t
*
p
)
{
Rtl_Ntk_t
*
pNtk
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
Rtl_NtkFree
(
pNtk
);
ABC_FREE
(
p
->
vConsts
.
pArray
);
ABC_FREE
(
p
->
vSlices
.
pArray
);
ABC_FREE
(
p
->
vConcats
.
pArray
);
ABC_FREE
(
p
->
vAttrTemp
.
pArray
);
for
(
i
=
0
;
i
<
TEMP_NUM
;
i
++
)
ABC_FREE
(
p
->
vTemp
[
i
].
pArray
);
Vec_IntFreeP
(
&
p
->
vMap
);
Vec_IntFreeP
(
&
p
->
vTokens
);
Abc_NamStop
(
p
->
pManName
);
Vec_PtrFree
(
p
->
vNtks
);
ABC_FREE
(
p
->
pSpec
);
ABC_FREE
(
p
);
}
int
Rtl_LibFindModule
(
Rtl_Lib_t
*
p
,
int
NameId
)
{
Rtl_Ntk_t
*
pNtk
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
if
(
pNtk
->
NameId
==
NameId
)
return
i
;
return
-
1
;
}
void
Rtl_LibPrintStats
(
Rtl_Lib_t
*
p
)
{
Rtl_Ntk_t
*
pNtk
;
int
i
,
nSymbs
=
0
;
printf
(
"Modules found in
\"
%s
\"
:
\n
"
,
p
->
pSpec
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
nSymbs
=
Abc_MaxInt
(
nSymbs
,
strlen
(
Rtl_NtkName
(
pNtk
))
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
Rtl_NtkPrintStats
(
pNtk
,
nSymbs
+
2
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
typedef
enum
{
RTL_NONE
=
0
,
// 0: unused
RTL_MODULE
,
// 1: "module"
RTL_END
,
// 2: "end"
RTL_INPUT
,
// 3: "input"
RTL_OUTPUT
,
// 4: "output"
RTL_INOUT
,
// 5: "inout"
RTL_UPTO
,
// 6: "upto"
RTL_SIGNED
,
// 7: "signed"
RTL_OFFSET
,
// 8: "offset"
RTL_PARAMETER
,
// 9: "parameter"
RTL_WIRE
,
// 10: "wire"
RTL_CONNECT
,
// 11: "connect"
RTL_CELL
,
// 12: "cell"
RTL_WIDTH
,
// 13: "width"
RTL_ATTRIBUTE
,
// 14: "attribute"
RTL_UNUSED
// 15: unused
}
Rtl_Type_t
;
static
inline
char
*
Rtl_Num2Name
(
int
i
)
{
if
(
i
==
1
)
return
"module"
;
if
(
i
==
2
)
return
"end"
;
if
(
i
==
3
)
return
"input"
;
if
(
i
==
4
)
return
"output"
;
if
(
i
==
5
)
return
"inout"
;
if
(
i
==
6
)
return
"upto"
;
if
(
i
==
7
)
return
"signed"
;
if
(
i
==
8
)
return
"offset"
;
if
(
i
==
9
)
return
"parameter"
;
if
(
i
==
10
)
return
"wire"
;
if
(
i
==
11
)
return
"connect"
;
if
(
i
==
12
)
return
"cell"
;
if
(
i
==
13
)
return
"width"
;
if
(
i
==
14
)
return
"attribute"
;
return
NULL
;
}
static
inline
void
Rtl_LibDeriveMap
(
Rtl_Lib_t
*
p
)
{
int
i
;
p
->
pMap
[
0
]
=
-
1
;
for
(
i
=
1
;
i
<
RTL_UNUSED
;
i
++
)
p
->
pMap
[
i
]
=
Abc_NamStrFind
(
p
->
pManName
,
Rtl_Num2Name
(
i
)
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Rtl_LibReadType
(
char
*
pType
)
{
if
(
!
strcmp
(
pType
,
"$not"
)
)
return
ABC_OPER_BIT_INV
;
// Y = ~A $not
if
(
!
strcmp
(
pType
,
"$pos"
)
)
return
ABC_OPER_BIT_BUF
;
// Y = +A $pos
if
(
!
strcmp
(
pType
,
"$neg"
)
)
return
ABC_OPER_ARI_MIN
;
// Y = -A $neg
if
(
!
strcmp
(
pType
,
"$reduce_and"
)
)
return
ABC_OPER_RED_AND
;
// Y = &A $reduce_and
if
(
!
strcmp
(
pType
,
"$reduce_or"
)
)
return
ABC_OPER_RED_OR
;
// Y = |A $reduce_or
if
(
!
strcmp
(
pType
,
"$reduce_xor"
)
)
return
ABC_OPER_RED_XOR
;
// Y = ^A $reduce_xor
if
(
!
strcmp
(
pType
,
"$reduce_xnor"
)
)
return
ABC_OPER_RED_NXOR
;
// Y = ~^A $reduce_xnor
if
(
!
strcmp
(
pType
,
"$reduce_bool"
)
)
return
ABC_OPER_RED_OR
;
// Y = |A $reduce_bool
if
(
!
strcmp
(
pType
,
"$logic_not"
)
)
return
ABC_OPER_LOGIC_NOT
;
// Y = !A $logic_not
if
(
!
strcmp
(
pType
,
"$and"
)
)
return
ABC_OPER_BIT_AND
;
// Y = A & B $and
if
(
!
strcmp
(
pType
,
"$or"
)
)
return
ABC_OPER_BIT_OR
;
// Y = A | B $or
if
(
!
strcmp
(
pType
,
"$xor"
)
)
return
ABC_OPER_BIT_XOR
;
// Y = A ^ B $xor
if
(
!
strcmp
(
pType
,
"$xnor"
)
)
return
ABC_OPER_BIT_NXOR
;
// Y = A ~^ B $xnor
if
(
!
strcmp
(
pType
,
"$shl"
)
)
return
ABC_OPER_SHIFT_L
;
// Y = A << B $shl
if
(
!
strcmp
(
pType
,
"$shr"
)
)
return
ABC_OPER_SHIFT_R
;
// Y = A >> B $shr
if
(
!
strcmp
(
pType
,
"$sshl"
)
)
return
ABC_OPER_SHIFT_LA
;
// Y = A <<< B $sshl
if
(
!
strcmp
(
pType
,
"$sshr"
)
)
return
ABC_OPER_SHIFT_RA
;
// Y = A >>> B $sshr
if
(
!
strcmp
(
pType
,
"$shiftx"
)
)
return
ABC_OPER_SHIFT_R
;
// Y = A << B $shl <== temporary
if
(
!
strcmp
(
pType
,
"$logic_and"
)
)
return
ABC_OPER_LOGIC_AND
;
// Y = A && B $logic_and
if
(
!
strcmp
(
pType
,
"$logic_or"
)
)
return
ABC_OPER_LOGIC_OR
;
// Y = A || B $logic_or
if
(
!
strcmp
(
pType
,
"$lt"
)
)
return
ABC_OPER_COMP_LESS
;
// Y = A < B $lt
if
(
!
strcmp
(
pType
,
"$le"
)
)
return
ABC_OPER_COMP_LESSEQU
;
// Y = A <= B $le
if
(
!
strcmp
(
pType
,
"$ge"
)
)
return
ABC_OPER_COMP_MOREEQU
;
// Y = A >= B $ge
if
(
!
strcmp
(
pType
,
"$gt"
)
)
return
ABC_OPER_COMP_MORE
;
// Y = A > B $gt
if
(
!
strcmp
(
pType
,
"$eq"
)
)
return
ABC_OPER_COMP_EQU
;
// Y = A == B $eq
if
(
!
strcmp
(
pType
,
"$ne"
)
)
return
ABC_OPER_COMP_NOTEQU
;
// Y = A != B $ne
if
(
!
strcmp
(
pType
,
"$eqx"
)
)
return
ABC_OPER_COMP_EQU
;
// Y = A === B $eqx
if
(
!
strcmp
(
pType
,
"$nex"
)
)
return
ABC_OPER_COMP_NOTEQU
;
// Y = A !== B $nex
if
(
!
strcmp
(
pType
,
"$add"
)
)
return
ABC_OPER_ARI_ADD
;
// Y = A + B $add
if
(
!
strcmp
(
pType
,
"$sub"
)
)
return
ABC_OPER_ARI_SUB
;
// Y = A - B $sub
if
(
!
strcmp
(
pType
,
"$mul"
)
)
return
ABC_OPER_ARI_MUL
;
// Y = A * B $mul
if
(
!
strcmp
(
pType
,
"$div"
)
)
return
ABC_OPER_ARI_DIV
;
// Y = A / B $div
if
(
!
strcmp
(
pType
,
"$mod"
)
)
return
ABC_OPER_ARI_MOD
;
// Y = A % B $mod
if
(
!
strcmp
(
pType
,
"$pow"
)
)
return
ABC_OPER_ARI_POW
;
// Y = A ** B $pow
if
(
!
strcmp
(
pType
,
"$modfoor"
)
)
return
ABC_OPER_NONE
;
// [N/A] $modfoor
if
(
!
strcmp
(
pType
,
"$divfloor"
)
)
return
ABC_OPER_NONE
;
// [N/A] $divfloor
if
(
!
strcmp
(
pType
,
"$mux"
)
)
return
ABC_OPER_SEL_NMUX
;
// $mux
if
(
!
strcmp
(
pType
,
"$pmux"
)
)
return
ABC_OPER_SEL_SEL
;
// $pmux
if
(
!
strcmp
(
pType
,
"$dff"
)
)
return
ABC_OPER_DFF
;
if
(
!
strcmp
(
pType
,
"$adff"
)
)
return
ABC_OPER_DFF
;
if
(
!
strcmp
(
pType
,
"$sdff"
)
)
return
ABC_OPER_DFF
;
assert
(
0
);
return
-
1
;
}
int
Rtl_NtkReadType
(
Rtl_Ntk_t
*
p
,
int
Type
)
{
extern
int
Rtl_LibFindModule
(
Rtl_Lib_t
*
p
,
int
NameId
);
char
*
pType
=
Rtl_NtkStr
(
p
,
Type
);
if
(
pType
[
0
]
==
'$'
&&
strncmp
(
pType
,
"$paramod"
,
strlen
(
"$paramod"
))
)
return
Rtl_LibReadType
(
pType
);
return
ABC_INFINITY
+
Rtl_LibFindModule
(
p
->
pLib
,
Type
);
}
/**Function*************************************************************
Synopsis [There is no need to normalize ranges in Yosys.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Rtl_NtkRangeWires
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pWire
,
nBits
=
0
;
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
{
//printf( "%s -> %d\n", Rtl_WireNameStr(p, i), nBits );
pWire
[
4
]
=
nBits
,
nBits
+=
Rtl_WireWidth
(
p
,
i
);
}
return
nBits
;
}
void
Rtl_NtkMapWires
(
Rtl_Ntk_t
*
p
,
int
fUnmap
)
{
int
i
,
Value
;
assert
(
Vec_IntSize
(
p
->
pLib
->
vMap
)
==
Abc_NamObjNumMax
(
p
->
pLib
->
pManName
)
);
for
(
i
=
0
;
i
<
Rtl_NtkWireNum
(
p
);
i
++
)
{
int
NameId
=
Rtl_WireName
(
p
,
i
);
assert
(
Vec_IntEntry
(
p
->
pLib
->
vMap
,
NameId
)
==
(
fUnmap
?
i
:
-
1
)
);
Vec_IntWriteEntry
(
p
->
pLib
->
vMap
,
NameId
,
fUnmap
?
-
1
:
i
);
}
if
(
fUnmap
)
Vec_IntForEachEntry
(
p
->
pLib
->
vMap
,
Value
,
i
)
assert
(
Value
==
-
1
);
}
void
Rtl_NtkNormRanges
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pWire
;
Rtl_NtkMapWires
(
p
,
0
);
for
(
i
=
p
->
Slice0
;
i
<
p
->
Slice1
;
i
+=
3
)
{
int
NameId
=
Vec_IntEntry
(
&
p
->
pLib
->
vSlices
,
i
);
int
Left
=
Vec_IntEntry
(
&
p
->
pLib
->
vSlices
,
i
+
1
);
int
Right
=
Vec_IntEntry
(
&
p
->
pLib
->
vSlices
,
i
+
2
);
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
Offset
=
Rtl_WireOffset
(
p
,
Wire
);
int
First
=
Rtl_WireFirst
(
p
,
Wire
);
assert
(
First
>>
4
==
NameId
);
if
(
Offset
);
{
Left
-=
Offset
;
Right
-=
Offset
;
}
if
(
First
&
8
)
// upto
{
Vec_IntWriteEntry
(
&
p
->
pLib
->
vSlices
,
i
+
1
,
Right
);
Vec_IntWriteEntry
(
&
p
->
pLib
->
vSlices
,
i
+
2
,
Left
);
}
}
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
{
Vec_IntWriteEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
0
,
Rtl_WireFirst
(
p
,
i
)
&
~
0x8
);
// upto
Vec_IntWriteEntry
(
&
p
->
vWires
,
WIRE_NUM
*
i
+
2
,
0
);
// offset
}
Rtl_NtkMapWires
(
p
,
1
);
}
void
Rtl_LibNormRanges
(
Rtl_Lib_t
*
pLib
)
{
Rtl_Ntk_t
*
p
;
int
i
;
if
(
pLib
->
vMap
==
NULL
)
pLib
->
vMap
=
Vec_IntStartFull
(
Abc_NamObjNumMax
(
pLib
->
pManName
)
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
Rtl_NtkNormRanges
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
*
Rlt_NtkFindIOPerm
(
Rtl_Ntk_t
*
p
)
{
Vec_Int_t
*
vCost
=
Vec_IntAlloc
(
100
);
int
i
,
*
pWire
,
*
pPerm
=
NULL
,
Count
=
0
;
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
{
int
First
=
Rtl_WireFirst
(
p
,
i
);
int
Number
=
Rtl_WireNumber
(
p
,
i
);
int
fIsPi
=
(
int
)((
First
&
1
)
>
0
);
int
fIsPo
=
(
int
)((
First
&
2
)
>
0
);
assert
(
(
fIsPi
||
fIsPo
)
==
(
Number
>
0
)
);
if
(
fIsPi
||
fIsPo
)
Vec_IntPush
(
vCost
,
fIsPo
*
ABC_INFINITY
+
Number
);
else
Vec_IntPush
(
vCost
,
2
*
ABC_INFINITY
+
Count
++
);
}
pPerm
=
Abc_MergeSortCost
(
Vec_IntArray
(
vCost
),
Vec_IntSize
(
vCost
)
);
Vec_IntFree
(
vCost
);
return
pPerm
;
}
void
Rtl_NtkOrderWires
(
Rtl_Ntk_t
*
p
)
{
Vec_Int_t
*
vTemp
=
Vec_IntAlloc
(
Vec_IntSize
(
&
p
->
vWires
)
);
int
i
,
k
,
*
pWire
,
*
pPerm
=
Rlt_NtkFindIOPerm
(
p
);
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
{
pWire
=
Vec_IntEntryP
(
&
p
->
vWires
,
WIRE_NUM
*
pPerm
[
i
]
);
for
(
k
=
0
;
k
<
WIRE_NUM
;
k
++
)
Vec_IntPush
(
vTemp
,
pWire
[
k
]
);
}
ABC_FREE
(
pPerm
);
assert
(
Vec_IntSize
(
&
p
->
vWires
)
==
Vec_IntSize
(
vTemp
)
);
ABC_SWAP
(
Vec_Int_t
,
p
->
vWires
,
*
vTemp
);
Vec_IntFree
(
vTemp
);
}
void
Rtl_LibUpdateInstances
(
Rtl_Ntk_t
*
p
)
{
Vec_Int_t
*
vMap
=
p
->
pLib
->
vMap
;
Vec_Int_t
*
vTemp
=
&
p
->
pLib
->
vTemp
[
2
];
int
i
,
k
,
Par
,
Val
,
*
pCell
,
Value
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
if
(
Rtl_CellModule
(
pCell
)
>=
ABC_INFINITY
)
{
Rtl_Ntk_t
*
pModel
=
Rtl_NtkModule
(
p
,
Rtl_CellModule
(
pCell
)
-
ABC_INFINITY
);
assert
(
pCell
[
6
]
==
pModel
->
nInputs
+
pModel
->
nOutputs
);
Rtl_CellForEachConnect
(
p
,
pCell
,
Par
,
Val
,
k
)
Vec_IntWriteEntry
(
vMap
,
Par
>>
2
,
k
);
Vec_IntClear
(
vTemp
);
for
(
k
=
0
;
k
<
pCell
[
6
];
k
++
)
{
int
Perm
=
Vec_IntEntry
(
vMap
,
Rtl_WireName
(
pModel
,
k
)
);
int
Par
=
pCell
[
CELL_NUM
+
2
*
(
pCell
[
4
]
+
pCell
[
5
]
+
Perm
)];
int
Val
=
pCell
[
CELL_NUM
+
2
*
(
pCell
[
4
]
+
pCell
[
5
]
+
Perm
)
+
1
];
assert
(
(
Par
>>
2
)
==
Rtl_WireName
(
pModel
,
k
)
);
Vec_IntWriteEntry
(
vMap
,
Par
>>
2
,
-
1
);
Vec_IntPushTwo
(
vTemp
,
Par
,
Val
);
assert
(
Perm
>=
0
);
}
memcpy
(
pCell
+
CELL_NUM
+
2
*
(
pCell
[
4
]
+
pCell
[
5
]),
Vec_IntArray
(
vTemp
),
sizeof
(
int
)
*
Vec_IntSize
(
vTemp
)
);
}
Vec_IntForEachEntry
(
p
->
pLib
->
vMap
,
Value
,
i
)
assert
(
Value
==
-
1
);
}
void
Rtl_LibOrderWires
(
Rtl_Lib_t
*
pLib
)
{
Rtl_Ntk_t
*
p
;
int
i
;
if
(
pLib
->
vMap
==
NULL
)
pLib
->
vMap
=
Vec_IntStartFull
(
Abc_NamObjNumMax
(
pLib
->
pManName
)
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
Rtl_NtkOrderWires
(
p
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
Rtl_LibUpdateInstances
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern
int
Rtl_NtkCountSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
);
int
Rtl_NtkCountWireRange
(
Rtl_Ntk_t
*
p
,
int
NameId
)
{
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
Width
=
Rtl_WireWidth
(
p
,
Wire
);
return
Width
;
}
int
Rtl_NtkCountSliceRange
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
)
{
return
pSlice
[
1
]
-
pSlice
[
2
]
+
1
;
}
int
Rtl_NtkCountConcatRange
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
)
{
int
i
,
nBits
=
0
;
for
(
i
=
1
;
i
<=
pConcat
[
0
];
i
++
)
nBits
+=
Rtl_NtkCountSignalRange
(
p
,
pConcat
[
i
]
);
return
nBits
;
}
int
Rtl_NtkCountSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
)
{
if
(
Rtl_SigIsNone
(
Sig
)
)
return
Rtl_NtkCountWireRange
(
p
,
Sig
>>
2
);
if
(
Rtl_SigIsSlice
(
Sig
)
)
return
Rtl_NtkCountSliceRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
)
);
if
(
Rtl_SigIsConcat
(
Sig
)
)
return
Rtl_NtkCountConcatRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
)
);
if
(
Rtl_SigIsConst
(
Sig
)
)
assert
(
0
);
return
ABC_INFINITY
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern
int
Rtl_NtkCheckSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
);
int
Rtl_NtkCheckWireRange
(
Rtl_Ntk_t
*
p
,
int
NameId
,
int
Left
,
int
Right
)
{
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
First
=
Rtl_WireBitStart
(
p
,
Wire
);
int
Width
=
Rtl_WireWidth
(
p
,
Wire
),
i
;
Left
=
Left
==
-
1
?
Width
-
1
:
Left
;
Right
=
Right
==
-
1
?
0
:
Right
;
assert
(
Right
<=
Left
&&
Right
>=
0
);
for
(
i
=
Right
;
i
<=
Left
;
i
++
)
if
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
i
)
==
-
1
)
return
0
;
return
1
;
}
int
Rtl_NtkCheckSliceRange
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
)
{
return
Rtl_NtkCheckWireRange
(
p
,
pSlice
[
0
],
pSlice
[
1
],
pSlice
[
2
]
);
}
int
Rtl_NtkCheckConcatRange
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
)
{
int
i
;
for
(
i
=
1
;
i
<=
pConcat
[
0
];
i
++
)
if
(
!
Rtl_NtkCheckSignalRange
(
p
,
pConcat
[
i
]
)
)
return
0
;
return
1
;
}
int
Rtl_NtkCheckSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
)
{
if
(
Rtl_SigIsNone
(
Sig
)
)
return
Rtl_NtkCheckWireRange
(
p
,
Sig
>>
2
,
-
1
,
-
1
);
else
if
(
Rtl_SigIsConst
(
Sig
)
)
return
1
;
else
if
(
Rtl_SigIsSlice
(
Sig
)
)
return
Rtl_NtkCheckSliceRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsConcat
(
Sig
)
)
return
Rtl_NtkCheckConcatRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
)
);
else
assert
(
0
);
return
-
1
;
}
extern
void
Rtl_NtkSetSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
,
int
Value
);
void
Rtl_NtkSetWireRange
(
Rtl_Ntk_t
*
p
,
int
NameId
,
int
Left
,
int
Right
,
int
Value
)
{
//char * pName = Rtl_NtkStr( p, NameId );
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
First
=
Rtl_WireBitStart
(
p
,
Wire
);
int
Width
=
Rtl_WireWidth
(
p
,
Wire
),
i
;
Left
=
Left
==
-
1
?
Width
-
1
:
Left
;
Right
=
Right
==
-
1
?
0
:
Right
;
assert
(
Right
<=
Left
&&
Right
>=
0
);
for
(
i
=
Right
;
i
<=
Left
;
i
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
i
)
==
-
1
);
Vec_IntWriteEntry
(
&
p
->
vLits
,
First
+
i
,
Value
);
}
//printf( "Finished setting wire %s\n", Rtl_NtkStr(p, NameId) );
}
void
Rtl_NtkSetSliceRange
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
,
int
Value
)
{
Rtl_NtkSetWireRange
(
p
,
pSlice
[
0
],
pSlice
[
1
],
pSlice
[
2
],
Value
);
}
void
Rtl_NtkSetConcatRange
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
,
int
Value
)
{
int
i
;
for
(
i
=
1
;
i
<=
pConcat
[
0
];
i
++
)
Rtl_NtkSetSignalRange
(
p
,
pConcat
[
i
],
Value
);
}
void
Rtl_NtkSetSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
,
int
Value
)
{
if
(
Rtl_SigIsNone
(
Sig
)
)
Rtl_NtkSetWireRange
(
p
,
Sig
>>
2
,
-
1
,
-
1
,
Value
);
else
if
(
Rtl_SigIsSlice
(
Sig
)
)
Rtl_NtkSetSliceRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
),
Value
);
else
if
(
Rtl_SigIsConcat
(
Sig
)
)
Rtl_NtkSetConcatRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
),
Value
);
else
if
(
Rtl_SigIsConst
(
Sig
)
)
assert
(
0
);
}
void
Rtl_NtkInitInputs
(
Rtl_Ntk_t
*
p
)
{
int
b
,
i
;
for
(
i
=
0
;
i
<
p
->
nInputs
;
i
++
)
{
int
First
=
Rtl_WireBitStart
(
p
,
i
);
int
Width
=
Rtl_WireWidth
(
p
,
i
);
for
(
b
=
0
;
b
<
Width
;
b
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
==
-
1
);
Vec_IntWriteEntry
(
&
p
->
vLits
,
First
+
b
,
Vec_IntSize
(
&
p
->
vOrder
)
);
}
Vec_IntPush
(
&
p
->
vOrder
,
i
);
//printf( "Finished setting input %s\n", Rtl_WireNameStr(p, i) );
}
}
Vec_Int_t
*
Rtl_NtkCollectOutputs
(
Rtl_Ntk_t
*
p
)
{
//char * pNtkName = Rtl_NtkName(p);
int
b
,
i
;
Vec_Int_t
*
vRes
=
Vec_IntAlloc
(
100
);
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
//char * pName = Rtl_WireNameStr(p, p->nInputs + i);
int
First
=
Rtl_WireBitStart
(
p
,
p
->
nInputs
+
i
);
int
Width
=
Rtl_WireWidth
(
p
,
p
->
nInputs
+
i
);
for
(
b
=
0
;
b
<
Width
;
b
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
!=
-
1
);
Vec_IntPush
(
vRes
,
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
);
}
}
return
vRes
;
}
int
Rtl_NtkReviewCells
(
Rtl_Ntk_t
*
p
)
{
int
i
,
k
,
Par
,
Val
,
*
pCell
,
RetValue
=
0
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
{
if
(
pCell
[
7
]
)
continue
;
Rtl_CellForEachInput
(
p
,
pCell
,
Par
,
Val
,
k
)
if
(
!
Rtl_NtkCheckSignalRange
(
p
,
Val
)
)
break
;
if
(
k
<
Rtl_CellInputNum
(
pCell
)
)
continue
;
Rtl_CellForEachOutput
(
p
,
pCell
,
Par
,
Val
,
k
)
Rtl_NtkSetSignalRange
(
p
,
Val
,
Vec_IntSize
(
&
p
->
vOrder
)
);
Vec_IntPush
(
&
p
->
vOrder
,
p
->
nInputs
+
i
);
pCell
[
7
]
=
1
;
RetValue
=
1
;
//printf( "Setting cell %s as propagated.\n", Rtl_CellNameStr(p, pCell) );
}
return
RetValue
;
}
int
Rtl_NtkReviewConnections
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pCon
,
RetValue
=
0
;
Rtl_NtkForEachCon
(
p
,
pCon
,
i
)
{
int
Status0
=
Rtl_NtkCheckSignalRange
(
p
,
pCon
[
0
]
);
int
Status1
=
Rtl_NtkCheckSignalRange
(
p
,
pCon
[
1
]
);
if
(
Status0
==
Status1
)
continue
;
if
(
!
Status0
&&
Status1
)
ABC_SWAP
(
int
,
pCon
[
0
],
pCon
[
1
]
)
Rtl_NtkSetSignalRange
(
p
,
pCon
[
1
],
Vec_IntSize
(
&
p
->
vOrder
)
);
Vec_IntPush
(
&
p
->
vOrder
,
p
->
nInputs
+
Rtl_NtkCellNum
(
p
)
+
i
);
RetValue
=
1
;
}
return
RetValue
;
}
void
Rtl_NtkPrintCellOrder
(
Rtl_Ntk_t
*
p
)
{
int
i
,
iCell
;
Vec_IntForEachEntry
(
&
p
->
vOrder
,
iCell
,
i
)
{
printf
(
"%4d : "
,
i
);
printf
(
"Cell %4d "
,
iCell
);
if
(
iCell
<
p
->
nInputs
)
printf
(
"Type Input "
);
else
if
(
iCell
<
p
->
nInputs
+
Rtl_NtkCellNum
(
p
)
)
{
int
*
pCell
=
Rtl_NtkCell
(
p
,
iCell
-
p
->
nInputs
);
printf
(
"Type %4d "
,
Rtl_CellType
(
pCell
)
);
printf
(
"%16s "
,
Rtl_CellTypeStr
(
p
,
pCell
)
);
printf
(
"%16s "
,
Rtl_CellNameStr
(
p
,
pCell
)
);
}
else
printf
(
"Type Connection "
);
printf
(
"
\n
"
);
}
}
void
Rtl_NtkPrintUnusedCells
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pCell
;
printf
(
"
\n
*** Printing unused cells:
\n
"
);
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
{
if
(
pCell
[
7
]
)
continue
;
printf
(
"Unused cell %s %s
\n
"
,
Rtl_CellTypeStr
(
p
,
pCell
),
Rtl_CellNameStr
(
p
,
pCell
)
);
}
printf
(
"
\n
"
);
}
void
Rtl_NtkOrderCells
(
Rtl_Ntk_t
*
p
)
{
Vec_Int_t
*
vRes
;
int
nBits
=
Rtl_NtkRangeWires
(
p
);
Vec_IntFill
(
&
p
->
vLits
,
nBits
,
-
1
);
Vec_IntClear
(
&
p
->
vOrder
);
Vec_IntGrow
(
&
p
->
vOrder
,
Rtl_NtkObjNum
(
p
)
);
Rtl_NtkInitInputs
(
p
);
Rtl_NtkMapWires
(
p
,
0
);
//Vec_IntPrint(&p->vLits);
Rtl_NtkReviewConnections
(
p
);
while
(
Rtl_NtkReviewCells
(
p
)
|
Rtl_NtkReviewConnections
(
p
)
);
Rtl_NtkMapWires
(
p
,
1
);
vRes
=
Rtl_NtkCollectOutputs
(
p
);
Vec_IntFree
(
vRes
);
//Rtl_NtkPrintCellOrder( p );
}
void
Rtl_LibOrderCells
(
Rtl_Lib_t
*
pLib
)
{
Rtl_Ntk_t
*
p
;
int
i
;
if
(
pLib
->
vMap
==
NULL
)
pLib
->
vMap
=
Vec_IntStartFull
(
Abc_NamObjNumMax
(
pLib
->
pManName
)
);
assert
(
Vec_IntSize
(
pLib
->
vMap
)
==
Abc_NamObjNumMax
(
pLib
->
pManName
)
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
Rtl_NtkOrderCells
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Rtl_TokenUnspace
(
char
*
p
)
{
int
i
,
Length
=
strlen
(
p
),
Quote
=
0
;
for
(
i
=
0
;
i
<
Length
;
i
++
)
if
(
p
[
i
]
==
'\"'
)
Quote
^=
1
;
else
if
(
Quote
&&
p
[
i
]
==
' '
)
p
[
i
]
=
'\"'
;
}
void
Rtl_TokenRespace
(
char
*
p
)
{
int
i
,
Length
=
strlen
(
p
);
assert
(
p
[
0
]
==
'\"'
&&
p
[
Length
-
1
]
==
'\"'
);
for
(
i
=
1
;
i
<
Length
-
1
;
i
++
)
if
(
p
[
i
]
==
'\"'
)
p
[
i
]
=
' '
;
}
Vec_Int_t
*
Rtl_NtkReadFile
(
char
*
pFileName
,
Abc_Nam_t
*
p
)
{
Vec_Int_t
*
vTokens
;
char
*
pTemp
,
Buffer
[
MAX_LINE
];
FILE
*
pFile
=
fopen
(
pFileName
,
"rb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Cannot open file
\"
%s
\"
for reading.
\n
"
,
pFileName
);
return
NULL
;
}
Abc_NamStrFindOrAdd
(
p
,
"module"
,
NULL
);
assert
(
Abc_NamObjNumMax
(
p
)
==
2
);
vTokens
=
Vec_IntAlloc
(
1000
);
while
(
fgets
(
Buffer
,
MAX_LINE
,
pFile
)
!=
NULL
)
{
if
(
Buffer
[
0
]
==
'#'
)
continue
;
Rtl_TokenUnspace
(
Buffer
);
pTemp
=
strtok
(
Buffer
,
"
\t\r\n
"
);
if
(
pTemp
==
NULL
)
continue
;
while
(
pTemp
)
{
if
(
*
pTemp
==
'\"'
)
Rtl_TokenRespace
(
pTemp
);
Vec_IntPush
(
vTokens
,
Abc_NamStrFindOrAdd
(
p
,
pTemp
,
NULL
)
);
pTemp
=
strtok
(
NULL
,
"
\t\r\n
"
);
}
Vec_IntPush
(
vTokens
,
-
1
);
}
fclose
(
pFile
);
return
vTokens
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern
void
Rtl_NtkPrintSig
(
Rtl_Ntk_t
*
p
,
int
Sig
);
void
Rtl_NtkPrintConst
(
Rtl_Ntk_t
*
p
,
int
*
pConst
)
{
int
i
;
if
(
pConst
[
0
]
==
-
1
)
{
fprintf
(
Rtl_NtkFile
(
p
),
" %d"
,
pConst
[
1
]
);
return
;
}
fprintf
(
Rtl_NtkFile
(
p
),
" %d
\'
"
,
pConst
[
0
]
);
for
(
i
=
pConst
[
0
]
-
1
;
i
>=
0
;
i
--
)
fprintf
(
Rtl_NtkFile
(
p
),
"%d"
,
Abc_InfoHasBit
(
pConst
+
1
,
i
)
);
}
void
Rtl_NtkPrintSlice
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
)
{
fprintf
(
Rtl_NtkFile
(
p
),
" %s"
,
Rtl_NtkStr
(
p
,
pSlice
[
0
])
);
if
(
pSlice
[
1
]
==
pSlice
[
2
]
)
fprintf
(
Rtl_NtkFile
(
p
),
" [%d]"
,
pSlice
[
1
]
);
else
fprintf
(
Rtl_NtkFile
(
p
),
" [%d:%d]"
,
pSlice
[
1
],
pSlice
[
2
]
);
}
void
Rtl_NtkPrintConcat
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
)
{
int
i
;
fprintf
(
Rtl_NtkFile
(
p
),
" {"
);
for
(
i
=
1
;
i
<=
pConcat
[
0
];
i
++
)
Rtl_NtkPrintSig
(
p
,
pConcat
[
i
]
);
fprintf
(
Rtl_NtkFile
(
p
),
" }"
);
}
void
Rtl_NtkPrintSig
(
Rtl_Ntk_t
*
p
,
int
Sig
)
{
if
(
Rtl_SigIsNone
(
Sig
)
)
fprintf
(
Rtl_NtkFile
(
p
),
" %s"
,
Rtl_NtkStr
(
p
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsConst
(
Sig
)
)
Rtl_NtkPrintConst
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConsts
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsSlice
(
Sig
)
)
Rtl_NtkPrintSlice
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsConcat
(
Sig
)
)
Rtl_NtkPrintConcat
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
)
);
else
assert
(
0
);
}
void
Rtl_NtkPrintWire
(
Rtl_Ntk_t
*
p
,
int
*
pWire
)
{
fprintf
(
Rtl_NtkFile
(
p
),
" wire"
);
if
(
pWire
[
1
]
!=
1
)
fprintf
(
Rtl_NtkFile
(
p
),
" width %d"
,
pWire
[
1
]
);
if
(
pWire
[
2
]
!=
0
)
fprintf
(
Rtl_NtkFile
(
p
),
" offset %d"
,
pWire
[
2
]
);
if
(
pWire
[
0
]
&
8
)
fprintf
(
Rtl_NtkFile
(
p
),
" upto"
);
if
(
pWire
[
0
]
&
1
)
fprintf
(
Rtl_NtkFile
(
p
),
" input %d"
,
pWire
[
3
]
);
if
(
pWire
[
0
]
&
2
)
fprintf
(
Rtl_NtkFile
(
p
),
" output %d"
,
pWire
[
3
]
);
if
(
pWire
[
0
]
&
4
)
fprintf
(
Rtl_NtkFile
(
p
),
" signed"
);
fprintf
(
Rtl_NtkFile
(
p
),
" %s
\n
"
,
Rtl_NtkStr
(
p
,
pWire
[
0
]
>>
4
)
);
}
void
Rtl_NtkPrintCell
(
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
int
i
,
Par
,
Val
;
Rtl_CellForEachAttr
(
p
,
pCell
,
Par
,
Val
,
i
)
fprintf
(
Rtl_NtkFile
(
p
),
" attribute %s %s
\n
"
,
Rtl_NtkStr
(
p
,
Par
),
Rtl_NtkStr
(
p
,
Val
)
);
fprintf
(
Rtl_NtkFile
(
p
),
" cell %s %s
\n
"
,
Rtl_NtkStr
(
p
,
Rtl_CellType
(
pCell
)),
Rtl_NtkStr
(
p
,
pCell
[
1
])
);
Rtl_CellForEachParam
(
p
,
pCell
,
Par
,
Val
,
i
)
fprintf
(
Rtl_NtkFile
(
p
),
" parameter"
),
Rtl_NtkPrintSig
(
p
,
Par
),
Rtl_NtkPrintSig
(
p
,
Val
),
printf
(
"
\n
"
);
Rtl_CellForEachConnect
(
p
,
pCell
,
Par
,
Val
,
i
)
fprintf
(
Rtl_NtkFile
(
p
),
" connect"
),
Rtl_NtkPrintSig
(
p
,
Par
),
Rtl_NtkPrintSig
(
p
,
Val
),
printf
(
"
\n
"
);
fprintf
(
Rtl_NtkFile
(
p
),
" end
\n
"
);
}
void
Rtl_NtkPrintConnection
(
Rtl_Ntk_t
*
p
,
int
*
pCon
)
{
fprintf
(
Rtl_NtkFile
(
p
),
" connect"
);
Rtl_NtkPrintSig
(
p
,
pCon
[
0
]
);
Rtl_NtkPrintSig
(
p
,
pCon
[
1
]
);
fprintf
(
Rtl_NtkFile
(
p
),
"
\n
"
);
}
void
Rtl_NtkPrint
(
Rtl_Ntk_t
*
p
)
{
int
i
,
Par
,
Val
,
*
pWire
,
*
pCell
,
*
pCon
;
fprintf
(
Rtl_NtkFile
(
p
),
"
\n
"
);
Rtl_NtkForEachAttr
(
p
,
Par
,
Val
,
i
)
fprintf
(
Rtl_NtkFile
(
p
),
"attribute %s %s
\n
"
,
Rtl_NtkStr
(
p
,
Par
),
Rtl_NtkStr
(
p
,
Val
)
);
fprintf
(
Rtl_NtkFile
(
p
),
"module %s
\n
"
,
Rtl_NtkName
(
p
)
);
Rtl_NtkForEachWire
(
p
,
pWire
,
i
)
Rtl_NtkPrintWire
(
p
,
pWire
);
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
Rtl_NtkPrintCell
(
p
,
pCell
);
Rtl_NtkForEachCon
(
p
,
pCon
,
i
)
Rtl_NtkPrintConnection
(
p
,
pCon
);
fprintf
(
Rtl_NtkFile
(
p
),
"end
\n
"
);
}
void
Rtl_LibPrint
(
char
*
pFileName
,
Rtl_Lib_t
*
p
)
{
p
->
pFile
=
pFileName
?
fopen
(
pFileName
,
"wb"
)
:
stdout
;
if
(
p
->
pFile
==
NULL
)
{
printf
(
"Cannot open output file
\"
%s
\"
.
\n
"
,
pFileName
);
return
;
}
else
{
Rtl_Ntk_t
*
pNtk
;
int
i
;
fprintf
(
p
->
pFile
,
"
\n
"
);
fprintf
(
p
->
pFile
,
"# Generated by ABC on %s
\n
"
,
Extra_TimeStamp
()
);
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
Rtl_NtkPrint
(
pNtk
);
if
(
p
->
pFile
!=
stdout
)
fclose
(
p
->
pFile
);
p
->
pFile
=
NULL
;
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern
int
Rtl_NtkReadSig
(
Rtl_Ntk_t
*
p
,
int
*
pPos
);
int
Rtl_NtkReadConst
(
Rtl_Ntk_t
*
p
,
char
*
pConst
)
{
Vec_Int_t
*
vConst
=
&
p
->
pLib
->
vConsts
;
int
RetVal
=
Vec_IntSize
(
vConst
);
int
Width
=
atoi
(
pConst
);
assert
(
pConst
[
0
]
>=
'0'
&&
pConst
[
0
]
<=
'9'
);
if
(
strstr
(
pConst
,
"
\'
"
)
)
{
int
Length
=
strlen
(
pConst
);
int
nWords
=
(
Width
+
31
)
/
32
;
int
i
,
*
pArray
;
Vec_IntPush
(
vConst
,
Width
);
Vec_IntFillExtra
(
vConst
,
Vec_IntSize
(
vConst
)
+
nWords
,
0
);
pArray
=
Vec_IntEntryP
(
vConst
,
RetVal
+
1
);
for
(
i
=
Length
-
1
;
i
>=
Length
-
Width
;
i
--
)
if
(
pConst
[
i
]
==
'1'
)
Abc_InfoSetBit
(
pArray
,
Length
-
1
-
i
);
}
else
{
Vec_IntPush
(
vConst
,
-
1
);
Vec_IntPush
(
vConst
,
Width
);
}
return
(
RetVal
<<
2
)
|
1
;
}
int
Rtl_NtkReadSlice
(
Rtl_Ntk_t
*
p
,
char
*
pSlice
,
int
NameId
)
{
Vec_Int_t
*
vSlice
=
&
p
->
pLib
->
vSlices
;
int
RetVal
=
Vec_IntSize
(
vSlice
);
int
Left
=
atoi
(
pSlice
+
1
);
char
*
pTwo
=
strstr
(
pSlice
,
":"
);
int
Right
=
pTwo
?
atoi
(
pTwo
+
1
)
:
Left
;
assert
(
pSlice
[
0
]
==
'['
&&
pSlice
[
strlen
(
pSlice
)
-
1
]
==
']'
);
Vec_IntPush
(
vSlice
,
NameId
);
Vec_IntPush
(
vSlice
,
Left
);
Vec_IntPush
(
vSlice
,
Right
);
return
(
RetVal
<<
2
)
|
2
;
}
int
Rtl_NtkReadConcat
(
Rtl_Ntk_t
*
p
,
int
*
pPos
)
{
Vec_Int_t
*
vConcat
=
&
p
->
pLib
->
vConcats
;
int
RetVal
=
Vec_IntSize
(
vConcat
);
char
*
pTok
;
Vec_IntPush
(
vConcat
,
ABC_INFINITY
);
do
{
int
Sig
=
Rtl_NtkReadSig
(
p
,
pPos
);
Vec_IntPush
(
vConcat
,
Sig
);
pTok
=
Rtl_NtkTokStr
(
p
,
*
pPos
);
}
while
(
pTok
[
0
]
!=
'}'
);
Vec_IntWriteEntry
(
vConcat
,
RetVal
,
Vec_IntSize
(
vConcat
)
-
RetVal
-
1
);
assert
(
pTok
[
0
]
==
'}'
);
(
*
pPos
)
++
;
return
(
RetVal
<<
2
)
|
3
;
}
int
Rtl_NtkReadSig
(
Rtl_Ntk_t
*
p
,
int
*
pPos
)
{
int
NameId
=
Rtl_NtkTokId
(
p
,
*
pPos
);
char
*
pSig
=
Rtl_NtkTokStr
(
p
,
(
*
pPos
)
++
);
if
(
pSig
[
0
]
>=
'0'
&&
pSig
[
0
]
<=
'9'
)
return
Rtl_NtkReadConst
(
p
,
pSig
);
if
(
pSig
[
0
]
==
'{'
)
return
Rtl_NtkReadConcat
(
p
,
pPos
);
else
{
char
*
pNext
=
Rtl_NtkTokStr
(
p
,
*
pPos
);
if
(
pNext
&&
pNext
[
0
]
==
'['
)
{
(
*
pPos
)
++
;
return
Rtl_NtkReadSlice
(
p
,
pNext
,
NameId
);
}
else
return
NameId
<<
2
;
}
}
int
Rtl_NtkReadWire
(
Rtl_Ntk_t
*
p
,
int
iPos
)
{
int
i
,
Entry
,
Prev
=
-
1
;
int
Width
=
1
,
Upto
=
0
,
Offset
=
0
,
Out
=
0
,
In
=
0
,
Number
=
0
,
Signed
=
0
;
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
-
1
,
RTL_WIRE
)
);
Vec_IntClear
(
&
p
->
pLib
->
vAttrTemp
);
Vec_IntForEachEntryStart
(
p
->
pLib
->
vTokens
,
Entry
,
i
,
iPos
)
{
char
*
pTok
=
Rtl_NtkTokStr
(
p
,
i
);
if
(
Entry
==
-
1
)
break
;
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_WIDTH
)
)
Width
=
atoi
(
Rtl_NtkTokStr
(
p
,
++
i
)
);
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_OFFSET
)
)
Offset
=
atoi
(
Rtl_NtkTokStr
(
p
,
++
i
)
);
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_INPUT
)
)
Number
=
atoi
(
Rtl_NtkTokStr
(
p
,
++
i
)
),
In
=
1
,
p
->
nInputs
++
;
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_OUTPUT
)
)
Number
=
atoi
(
Rtl_NtkTokStr
(
p
,
++
i
)
),
Out
=
1
,
p
->
nOutputs
++
;
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_SIGNED
)
)
Signed
=
1
;
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_UPTO
)
)
Upto
=
1
;
Prev
=
Entry
;
}
// add WIRE_NUM=5 entries
Vec_IntPush
(
&
p
->
vWires
,
(
Prev
<<
4
)
|
(
Upto
<<
3
)
|
(
Signed
<<
2
)
|
(
Out
<<
1
)
|
(
In
<<
0
)
);
Vec_IntPush
(
&
p
->
vWires
,
Width
);
Vec_IntPush
(
&
p
->
vWires
,
Offset
);
Vec_IntPush
(
&
p
->
vWires
,
Number
);
Vec_IntPush
(
&
p
->
vWires
,
-
1
);
assert
(
Rtl_NtkPosCheck
(
p
,
i
,
RTL_NONE
)
);
return
i
;
}
int
Rtl_NtkReadAttribute
(
Rtl_Ntk_t
*
p
,
int
iPos
)
{
//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
//char * pTok2 = Rtl_NtkTokStr(p, iPos);
//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
-
1
,
RTL_ATTRIBUTE
)
);
Vec_IntPush
(
&
p
->
pLib
->
vAttrTemp
,
Rtl_NtkTokId
(
p
,
iPos
++
)
);
Vec_IntPush
(
&
p
->
pLib
->
vAttrTemp
,
Rtl_NtkTokId
(
p
,
iPos
++
)
);
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
,
RTL_NONE
)
);
return
iPos
;
}
int
Rtl_NtkReadAttribute2
(
Rtl_Lib_t
*
p
,
int
iPos
)
{
//char * pTok1 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos-1));
//char * pTok2 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos) );
//char * pTok3 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos+1));
assert
(
Vec_IntEntry
(
p
->
vTokens
,
iPos
-
1
)
==
p
->
pMap
[
RTL_ATTRIBUTE
]
);
Vec_IntPush
(
&
p
->
vAttrTemp
,
Vec_IntEntry
(
p
->
vTokens
,
iPos
++
)
);
Vec_IntPush
(
&
p
->
vAttrTemp
,
Vec_IntEntry
(
p
->
vTokens
,
iPos
++
)
);
assert
(
Vec_IntEntry
(
p
->
vTokens
,
iPos
)
==
p
->
pMap
[
RTL_NONE
]
);
return
iPos
;
}
int
Rtl_NtkReadConnect
(
Rtl_Ntk_t
*
p
,
int
iPos
)
{
//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
//char * pTok2 = Rtl_NtkTokStr(p, iPos);
//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
-
1
,
RTL_CONNECT
)
);
Vec_IntPush
(
&
p
->
vConns
,
Rtl_NtkReadSig
(
p
,
&
iPos
)
);
Vec_IntPush
(
&
p
->
vConns
,
Rtl_NtkReadSig
(
p
,
&
iPos
)
);
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
,
RTL_NONE
)
);
return
iPos
;
}
int
Rtl_NtkReadCell
(
Rtl_Ntk_t
*
p
,
int
iPos
)
{
Vec_Int_t
*
vAttrs
=
&
p
->
pLib
->
vAttrTemp
;
int
iPosPars
,
iPosCons
,
Par
,
Val
,
i
,
Entry
;
assert
(
Rtl_NtkPosCheck
(
p
,
iPos
-
1
,
RTL_CELL
)
);
Vec_IntPush
(
&
p
->
vCells
,
Vec_IntSize
(
&
p
->
vStore
)
);
Vec_IntPush
(
&
p
->
vStore
,
Rtl_NtkTokId
(
p
,
iPos
++
)
);
// 0
Vec_IntPush
(
&
p
->
vStore
,
Rtl_NtkTokId
(
p
,
iPos
++
)
);
// 1
Vec_IntPush
(
&
p
->
vStore
,
-
1
);
Vec_IntPush
(
&
p
->
vStore
,
-
1
);
assert
(
Vec_IntSize
(
vAttrs
)
%
2
==
0
);
Vec_IntPush
(
&
p
->
vStore
,
Vec_IntSize
(
vAttrs
)
/
2
);
iPosPars
=
Vec_IntSize
(
&
p
->
vStore
);
Vec_IntPush
(
&
p
->
vStore
,
0
);
// 5
iPosCons
=
Vec_IntSize
(
&
p
->
vStore
);
Vec_IntPush
(
&
p
->
vStore
,
0
);
// 6
Vec_IntPush
(
&
p
->
vStore
,
0
);
// 7
assert
(
Vec_IntSize
(
&
p
->
vStore
)
==
Vec_IntEntryLast
(
&
p
->
vCells
)
+
CELL_NUM
);
Vec_IntAppend
(
&
p
->
vStore
,
vAttrs
);
Vec_IntClear
(
vAttrs
);
Vec_IntForEachEntryStart
(
p
->
pLib
->
vTokens
,
Entry
,
i
,
iPos
)
{
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_END
)
)
break
;
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_PARAMETER
)
||
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_CONNECT
)
)
{
int
iPosCount
=
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_PARAMETER
)
?
iPosPars
:
iPosCons
;
Vec_IntAddToEntry
(
&
p
->
vStore
,
iPosCount
,
1
);
i
++
;
Par
=
Rtl_NtkReadSig
(
p
,
&
i
);
Val
=
Rtl_NtkReadSig
(
p
,
&
i
);
Vec_IntPushTwo
(
&
p
->
vStore
,
Par
,
Val
);
}
assert
(
Rtl_NtkPosCheck
(
p
,
i
,
RTL_NONE
)
);
}
assert
(
Rtl_NtkPosCheck
(
p
,
i
,
RTL_END
)
);
i
++
;
assert
(
Rtl_NtkPosCheck
(
p
,
i
,
RTL_NONE
)
);
return
i
;
}
int
Wln_ReadMatchEnd
(
Rtl_Ntk_t
*
p
,
int
Mod
)
{
int
i
,
Entry
,
Count
=
0
;
Vec_IntForEachEntryStart
(
p
->
pLib
->
vTokens
,
Entry
,
i
,
Mod
)
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_CELL
)
)
Count
++
;
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_END
)
)
{
if
(
Count
==
0
)
return
i
;
Count
--
;
}
assert
(
0
);
return
-
1
;
}
int
Rtl_NtkReadNtk
(
Rtl_Lib_t
*
pLib
,
int
Mod
)
{
Rtl_Ntk_t
*
p
=
Rtl_NtkAlloc
(
pLib
);
Vec_Int_t
*
vAttrs
=
&
p
->
pLib
->
vAttrTemp
;
int
End
=
Wln_ReadMatchEnd
(
p
,
Mod
),
i
,
Entry
;
assert
(
Rtl_NtkPosCheck
(
p
,
Mod
-
1
,
RTL_MODULE
)
);
assert
(
Rtl_NtkPosCheck
(
p
,
End
,
RTL_END
)
);
p
->
NameId
=
Rtl_NtkTokId
(
p
,
Mod
);
p
->
Slice0
=
Vec_IntSize
(
&
pLib
->
vSlices
);
Vec_IntAppend
(
&
p
->
vAttrs
,
vAttrs
);
Vec_IntClear
(
vAttrs
);
Vec_IntForEachEntryStartStop
(
pLib
->
vTokens
,
Entry
,
i
,
Mod
,
End
)
{
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_WIRE
)
)
i
=
Rtl_NtkReadWire
(
p
,
i
+
1
);
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_ATTRIBUTE
)
)
i
=
Rtl_NtkReadAttribute
(
p
,
i
+
1
);
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_CELL
)
)
i
=
Rtl_NtkReadCell
(
p
,
i
+
1
);
else
if
(
Rtl_NtkTokCheck
(
p
,
Entry
,
RTL_CONNECT
)
)
i
=
Rtl_NtkReadConnect
(
p
,
i
+
1
);
}
p
->
Slice1
=
Vec_IntSize
(
&
pLib
->
vSlices
);
assert
(
Vec_IntSize
(
&
p
->
vWires
)
%
WIRE_NUM
==
0
);
return
End
;
}
void
Rtl_NtkReportUndefs
(
Rtl_Ntk_t
*
p
)
{
Vec_Int_t
*
vNames
,
*
vCounts
;
int
i
,
iName
,
*
pCell
,
nUndef
=
0
;
vNames
=
Vec_IntAlloc
(
10
);
vCounts
=
Vec_IntAlloc
(
10
);
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
if
(
Rtl_CellModule
(
pCell
)
==
ABC_INFINITY
-
1
)
{
iName
=
Vec_IntFind
(
vNames
,
Rtl_CellType
(
pCell
));
if
(
iName
==
-
1
)
{
iName
=
Vec_IntSize
(
vNames
);
Vec_IntPush
(
vNames
,
Rtl_CellType
(
pCell
)
);
Vec_IntPush
(
vCounts
,
0
);
}
Vec_IntAddToEntry
(
vCounts
,
iName
,
1
);
}
Vec_IntForEachEntry
(
vNames
,
iName
,
i
)
printf
(
" %s (%d)"
,
Rtl_NtkStr
(
p
,
iName
),
Vec_IntEntry
(
vCounts
,
i
)
);
printf
(
"
\n
"
);
Vec_IntFree
(
vNames
);
Vec_IntFree
(
vCounts
);
}
int
Rtl_NtkSetParents
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pCell
,
nUndef
=
0
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
{
pCell
[
2
]
=
Rtl_NtkReadType
(
p
,
Rtl_CellType
(
pCell
)
);
if
(
Rtl_CellModule
(
pCell
)
==
ABC_INFINITY
-
1
)
nUndef
++
;
else
pCell
[
3
]
=
Rtl_CellModule
(
pCell
)
<
ABC_INFINITY
?
pCell
[
6
]
-
1
:
Rtl_NtkModule
(
p
,
Rtl_CellModule
(
pCell
)
-
ABC_INFINITY
)
->
nInputs
;
}
if
(
!
nUndef
)
return
0
;
printf
(
"Module
\"
%s
\"
has %d blackbox instances: "
,
Rtl_NtkName
(
p
),
nUndef
);
Rtl_NtkReportUndefs
(
p
);
return
nUndef
;
}
void
Rtl_LibSetParents
(
Rtl_Lib_t
*
p
)
{
Rtl_Ntk_t
*
pNtk
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
Rtl_NtkSetParents
(
pNtk
);
}
void
Rtl_LibReorderModules_rec
(
Rtl_Ntk_t
*
p
,
Vec_Ptr_t
*
vNew
)
{
int
i
,
*
pCell
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
{
Rtl_Ntk_t
*
pMod
=
Rtl_CellNtk
(
p
,
pCell
);
if
(
pMod
&&
pMod
->
iCopy
==
-
1
)
Rtl_LibReorderModules_rec
(
pMod
,
vNew
);
}
assert
(
p
->
iCopy
==
-
1
);
p
->
iCopy
=
Vec_PtrSize
(
vNew
);
Vec_PtrPush
(
vNew
,
p
);
}
void
Rtl_NtkUpdateBoxes
(
Rtl_Ntk_t
*
p
)
{
int
i
,
*
pCell
;
Rtl_NtkForEachCell
(
p
,
pCell
,
i
)
{
Rtl_Ntk_t
*
pMod
=
Rtl_CellNtk
(
p
,
pCell
);
if
(
pMod
)
pCell
[
2
]
=
ABC_INFINITY
+
pMod
->
iCopy
;
}
}
void
Rtl_LibUpdateBoxes
(
Rtl_Lib_t
*
p
)
{
Rtl_Ntk_t
*
pNtk
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
Rtl_NtkUpdateBoxes
(
pNtk
);
}
void
Rtl_LibReorderModules
(
Rtl_Lib_t
*
p
)
{
Vec_Ptr_t
*
vNew
=
Vec_PtrAlloc
(
Vec_PtrSize
(
p
->
vNtks
)
);
Rtl_Ntk_t
*
pNtk
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
pNtk
->
iCopy
=
-
1
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
p
->
vNtks
,
pNtk
,
i
)
if
(
pNtk
->
iCopy
==
-
1
)
Rtl_LibReorderModules_rec
(
pNtk
,
vNew
);
assert
(
Vec_PtrSize
(
p
->
vNtks
)
==
Vec_PtrSize
(
vNew
)
);
Rtl_LibUpdateBoxes
(
p
);
Vec_PtrClear
(
p
->
vNtks
);
Vec_PtrAppend
(
p
->
vNtks
,
vNew
);
Vec_PtrFree
(
vNew
);
}
Rtl_Lib_t
*
Rtl_LibReadFile
(
char
*
pFileName
,
char
*
pFileSpec
)
{
Rtl_Lib_t
*
p
=
Rtl_LibAlloc
();
int
i
,
Entry
;
p
->
pSpec
=
Abc_UtilStrsav
(
pFileSpec
);
p
->
pManName
=
Abc_NamStart
(
1000
,
50
);
p
->
vTokens
=
Rtl_NtkReadFile
(
pFileName
,
p
->
pManName
);
Rtl_LibDeriveMap
(
p
);
Vec_IntClear
(
&
p
->
vAttrTemp
);
Vec_IntForEachEntry
(
p
->
vTokens
,
Entry
,
i
)
if
(
Entry
==
p
->
pMap
[
RTL_MODULE
]
)
i
=
Rtl_NtkReadNtk
(
p
,
i
+
1
);
else
if
(
Entry
==
p
->
pMap
[
RTL_ATTRIBUTE
]
)
i
=
Rtl_NtkReadAttribute2
(
p
,
i
+
1
);
Rtl_LibSetParents
(
p
);
Rtl_LibReorderModules
(
p
);
return
p
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern
void
Rtl_NtkCollectSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
);
void
Rtl_NtkCollectWireRange
(
Rtl_Ntk_t
*
p
,
int
NameId
,
int
Left
,
int
Right
)
{
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
First
=
Rtl_WireBitStart
(
p
,
Wire
);
int
Width
=
Rtl_WireWidth
(
p
,
Wire
),
i
;
Left
=
Left
==
-
1
?
Width
-
1
:
Left
;
Right
=
Right
==
-
1
?
0
:
Right
;
assert
(
Right
>=
0
&&
Right
<=
Left
);
for
(
i
=
Right
;
i
<=
Left
;
i
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
i
)
!=
-
1
);
Vec_IntPush
(
&
p
->
vBitTemp
,
Vec_IntEntry
(
&
p
->
vLits
,
First
+
i
)
);
}
}
void
Rtl_NtkCollectConstRange
(
Rtl_Ntk_t
*
p
,
int
*
pConst
)
{
int
i
,
nLimit
=
pConst
[
0
];
if
(
nLimit
==
-
1
)
nLimit
=
32
;
//assert( pConst[0] > 0 );
for
(
i
=
0
;
i
<
nLimit
;
i
++
)
Vec_IntPush
(
&
p
->
vBitTemp
,
Abc_InfoHasBit
(
pConst
+
1
,
i
)
);
}
void
Rtl_NtkCollectSliceRange
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
)
{
Rtl_NtkCollectWireRange
(
p
,
pSlice
[
0
],
pSlice
[
1
],
pSlice
[
2
]
);
}
void
Rtl_NtkCollectConcatRange
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
)
{
int
i
;
for
(
i
=
pConcat
[
0
];
i
>=
1
;
i
--
)
Rtl_NtkCollectSignalRange
(
p
,
pConcat
[
i
]
);
}
void
Rtl_NtkCollectSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
)
{
if
(
Rtl_SigIsNone
(
Sig
)
)
Rtl_NtkCollectWireRange
(
p
,
Sig
>>
2
,
-
1
,
-
1
);
else
if
(
Rtl_SigIsConst
(
Sig
)
)
Rtl_NtkCollectConstRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConsts
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsSlice
(
Sig
)
)
Rtl_NtkCollectSliceRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
)
);
else
if
(
Rtl_SigIsConcat
(
Sig
)
)
Rtl_NtkCollectConcatRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
)
);
else
assert
(
0
);
}
extern
int
Rtl_NtkInsertSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
,
int
*
pLits
,
int
nLits
);
int
Rtl_NtkInsertWireRange
(
Rtl_Ntk_t
*
p
,
int
NameId
,
int
Left
,
int
Right
,
int
*
pLits
,
int
nLits
)
{
//char * pName = Rtl_NtkStr( p, NameId );
int
Wire
=
Rtl_WireMapNameToId
(
p
,
NameId
);
int
First
=
Rtl_WireBitStart
(
p
,
Wire
);
int
Width
=
Rtl_WireWidth
(
p
,
Wire
),
i
,
k
=
0
;
Left
=
Left
==
-
1
?
Width
-
1
:
Left
;
Right
=
Right
==
-
1
?
0
:
Right
;
assert
(
Right
>=
0
&&
Right
<=
Left
);
for
(
i
=
Right
;
i
<=
Left
;
i
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
i
)
==
-
1
);
Vec_IntWriteEntry
(
&
p
->
vLits
,
First
+
i
,
pLits
[
k
++
]
);
}
assert
(
k
<=
nLits
);
return
k
;
}
int
Rtl_NtkInsertSliceRange
(
Rtl_Ntk_t
*
p
,
int
*
pSlice
,
int
*
pLits
,
int
nLits
)
{
return
Rtl_NtkInsertWireRange
(
p
,
pSlice
[
0
],
pSlice
[
1
],
pSlice
[
2
],
pLits
,
nLits
);
}
int
Rtl_NtkInsertConcatRange
(
Rtl_Ntk_t
*
p
,
int
*
pConcat
,
int
*
pLits
,
int
nLits
)
{
int
i
,
k
=
0
;
for
(
i
=
1
;
i
<=
pConcat
[
0
];
i
++
)
k
+=
Rtl_NtkInsertSignalRange
(
p
,
pConcat
[
i
],
pLits
+
k
,
nLits
-
k
);
assert
(
k
<=
nLits
);
return
k
;
}
int
Rtl_NtkInsertSignalRange
(
Rtl_Ntk_t
*
p
,
int
Sig
,
int
*
pLits
,
int
nLits
)
{
int
nBits
=
ABC_INFINITY
;
if
(
Rtl_SigIsNone
(
Sig
)
)
nBits
=
Rtl_NtkInsertWireRange
(
p
,
Sig
>>
2
,
-
1
,
-
1
,
pLits
,
nLits
);
if
(
Rtl_SigIsSlice
(
Sig
)
)
nBits
=
Rtl_NtkInsertSliceRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vSlices
,
Sig
>>
2
),
pLits
,
nLits
);
if
(
Rtl_SigIsConcat
(
Sig
)
)
nBits
=
Rtl_NtkInsertConcatRange
(
p
,
Vec_IntEntryP
(
&
p
->
pLib
->
vConcats
,
Sig
>>
2
),
pLits
,
nLits
);
if
(
Rtl_SigIsConst
(
Sig
)
)
assert
(
0
);
assert
(
nBits
==
nLits
);
return
nBits
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Rtl_NtkBlastInputs
(
Gia_Man_t
*
pNew
,
Rtl_Ntk_t
*
p
)
{
int
b
,
i
;
for
(
i
=
0
;
i
<
p
->
nInputs
;
i
++
)
{
int
First
=
Rtl_WireBitStart
(
p
,
i
);
int
Width
=
Rtl_WireWidth
(
p
,
i
);
for
(
b
=
0
;
b
<
Width
;
b
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
==
-
1
);
Vec_IntWriteEntry
(
&
p
->
vLits
,
First
+
b
,
Gia_ManAppendCi
(
pNew
)
);
}
}
}
void
Rtl_NtkBlastOutputs
(
Gia_Man_t
*
pNew
,
Rtl_Ntk_t
*
p
)
{
int
b
,
i
;
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
int
First
=
Rtl_WireBitStart
(
p
,
p
->
nInputs
+
i
);
int
Width
=
Rtl_WireWidth
(
p
,
p
->
nInputs
+
i
);
for
(
b
=
0
;
b
<
Width
;
b
++
)
{
assert
(
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
!=
-
1
);
Gia_ManAppendCo
(
pNew
,
Vec_IntEntry
(
&
p
->
vLits
,
First
+
b
)
);
}
}
}
void
Rtl_NtkBlastConnect
(
Gia_Man_t
*
pNew
,
Rtl_Ntk_t
*
p
,
int
*
pCon
)
{
int
nBits
;
Vec_IntClear
(
&
p
->
vBitTemp
);
Rtl_NtkCollectSignalRange
(
p
,
pCon
[
0
]
);
nBits
=
Rtl_NtkInsertSignalRange
(
p
,
pCon
[
1
],
Vec_IntArray
(
&
p
->
vBitTemp
),
Vec_IntSize
(
&
p
->
vBitTemp
)
);
assert
(
nBits
==
Vec_IntSize
(
&
p
->
vBitTemp
)
);
//printf( "Finished blasting connection (Value = %d).\n", Vec_IntEntry(&p->vBitTemp, 0) );
}
void
Rtl_NtkBlastHierarchy
(
Gia_Man_t
*
pNew
,
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
extern
Gia_Man_t
*
Rtl_NtkBlast
(
Rtl_Ntk_t
*
p
);
extern
void
Gia_ManDupRebuild
(
Gia_Man_t
*
pNew
,
Gia_Man_t
*
p
,
Vec_Int_t
*
vLits
);
Rtl_Ntk_t
*
pModel
=
Rtl_NtkModule
(
p
,
Rtl_CellModule
(
pCell
)
-
ABC_INFINITY
);
int
k
,
Par
,
Val
,
nBits
=
0
;
Vec_IntClear
(
&
p
->
vBitTemp
);
Rtl_CellForEachInput
(
p
,
pCell
,
Par
,
Val
,
k
)
Rtl_NtkCollectSignalRange
(
p
,
Val
);
// if ( pModel->pGia == NULL )
// pModel->pGia = Rtl_NtkBlast( pModel );
assert
(
pModel
->
pGia
);
Gia_ManDupRebuild
(
pNew
,
pModel
->
pGia
,
&
p
->
vBitTemp
);
Rtl_CellForEachOutput
(
p
,
pCell
,
Par
,
Val
,
k
)
nBits
+=
Rtl_NtkInsertSignalRange
(
p
,
Val
,
Vec_IntArray
(
&
p
->
vBitTemp
)
+
nBits
,
Vec_IntSize
(
&
p
->
vBitTemp
)
-
nBits
);
assert
(
nBits
==
Vec_IntSize
(
&
p
->
vBitTemp
)
);
}
int
Rtl_NtkCellParamValue
(
Rtl_Ntk_t
*
p
,
int
*
pCell
,
char
*
pParam
)
{
int
ParamId
=
Rtl_NtkStrId
(
p
,
pParam
);
int
i
,
Par
,
Val
,
ValOut
=
ABC_INFINITY
,
*
pConst
;
// p->pLib->pFile = stdout;
// Rtl_CellForEachParam( p, pCell, Par, Val, i )
// fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
Rtl_CellForEachParam
(
p
,
pCell
,
Par
,
Val
,
i
)
if
(
(
Par
>>
2
)
==
ParamId
)
{
assert
(
Rtl_SigIsConst
(
Val
)
);
pConst
=
Vec_IntEntryP
(
&
p
->
pLib
->
vConsts
,
Val
>>
2
);
assert
(
pConst
[
0
]
<
32
);
ValOut
=
pConst
[
1
];
}
return
ValOut
;
}
void
Rtl_NtkBlastOperator
(
Gia_Man_t
*
pNew
,
Rtl_Ntk_t
*
p
,
int
*
pCell
)
{
extern
void
Rtl_NtkBlastNode
(
Gia_Man_t
*
pNew
,
int
Type
,
int
nIns
,
Vec_Int_t
*
vDatas
,
int
nRange
,
int
fSign0
,
int
fSign1
);
Vec_Int_t
*
vRes
=
&
p
->
pLib
->
vTemp
[
3
];
int
i
,
Par
,
Val
,
ValOut
=
-
1
,
nBits
=
0
,
nRange
=
-
1
;
int
fSign0
=
Rtl_NtkCellParamValue
(
p
,
pCell
,
"
\\
A_SIGNED"
);
int
fSign1
=
Rtl_NtkCellParamValue
(
p
,
pCell
,
"
\\
B_SIGNED"
);
Rtl_CellForEachOutput
(
p
,
pCell
,
Par
,
ValOut
,
i
)
nRange
=
Rtl_NtkCountSignalRange
(
p
,
ValOut
);
assert
(
nRange
>
0
);
for
(
i
=
0
;
i
<
TEMP_NUM
;
i
++
)
Vec_IntClear
(
&
p
->
pLib
->
vTemp
[
i
]
);
//printf( "Starting blasting cell %s.\n", Rtl_CellNameStr(p, pCell) );
Rtl_CellForEachInput
(
p
,
pCell
,
Par
,
Val
,
i
)
{
Vec_IntClear
(
&
p
->
vBitTemp
);
Rtl_NtkCollectSignalRange
(
p
,
Val
);
Vec_IntAppend
(
&
p
->
pLib
->
vTemp
[
i
],
&
p
->
vBitTemp
);
}
Rtl_NtkBlastNode
(
pNew
,
Rtl_CellModule
(
pCell
),
Rtl_CellInputNum
(
pCell
),
p
->
pLib
->
vTemp
,
nRange
,
fSign0
,
fSign1
);
assert
(
Vec_IntSize
(
vRes
)
>
0
);
nBits
=
Rtl_NtkInsertSignalRange
(
p
,
ValOut
,
Vec_IntArray
(
vRes
)
+
nBits
,
Vec_IntSize
(
vRes
)
-
nBits
);
assert
(
nBits
==
Vec_IntSize
(
vRes
)
);
//printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) );
}
Gia_Man_t
*
Rtl_NtkBlast
(
Rtl_Ntk_t
*
p
)
{
Gia_Man_t
*
pTemp
,
*
pNew
=
Gia_ManStart
(
1000
);
int
i
,
iObj
,
*
pCell
,
nBits
=
Rtl_NtkRangeWires
(
p
);
char
Buffer
[
100
];
static
int
counter
=
0
;
Vec_IntFill
(
&
p
->
vLits
,
nBits
,
-
1
);
Rtl_NtkMapWires
(
p
,
0
);
Rtl_NtkBlastInputs
(
pNew
,
p
);
Gia_ManHashAlloc
(
pNew
);
Vec_IntForEachEntry
(
&
p
->
vOrder
,
iObj
,
i
)
{
iObj
-=
Rtl_NtkInputNum
(
p
);
if
(
iObj
<
0
)
continue
;
if
(
iObj
>=
Rtl_NtkCellNum
(
p
)
)
{
Rtl_NtkBlastConnect
(
pNew
,
p
,
Rtl_NtkCon
(
p
,
iObj
-
Rtl_NtkCellNum
(
p
))
);
continue
;
}
pCell
=
Rtl_NtkCell
(
p
,
iObj
);
if
(
Rtl_CellModule
(
pCell
)
>=
ABC_INFINITY
)
Rtl_NtkBlastHierarchy
(
pNew
,
p
,
pCell
);
else
if
(
Rtl_CellModule
(
pCell
)
<
ABC_OPER_LAST
)
Rtl_NtkBlastOperator
(
pNew
,
p
,
pCell
);
else
printf
(
"Cannot blast black box %s in module %s.
\n
"
,
Rtl_NtkStr
(
p
,
Rtl_CellType
(
pCell
)),
Rtl_NtkName
(
p
)
);
}
Gia_ManHashStop
(
pNew
);
Rtl_NtkBlastOutputs
(
pNew
,
p
);
Rtl_NtkMapWires
(
p
,
1
);
pNew
=
Gia_ManCleanup
(
pTemp
=
pNew
);
Gia_ManStop
(
pTemp
);
sprintf
(
Buffer
,
"temp%d.aig"
,
counter
++
);
//sprintf( Buffer, "temp%d.aig", counter );
Gia_AigerWrite
(
pNew
,
Buffer
,
0
,
0
,
0
);
printf
(
"Dumpted blasted AIG into file
\"
%s
\"
for module
\"
%s
\"
.
\n
"
,
Buffer
,
Rtl_NtkName
(
p
)
);
Gia_ManPrintStats
(
pNew
,
NULL
);
return
pNew
;
}
void
Rtl_LibBlast
(
Rtl_Lib_t
*
pLib
)
{
Rtl_Ntk_t
*
p
;
int
i
;
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
if
(
p
->
pGia
==
NULL
)
p
->
pGia
=
Rtl_NtkBlast
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Rtl_LibPreprocess
(
Rtl_Lib_t
*
pLib
)
{
abctime
clk
=
Abc_Clock
();
Rtl_Ntk_t
*
p1
,
*
p2
,
*
p
;
int
i
,
k
,
Status
,
fFound
=
0
;
printf
(
"Performing preprocessing for verification.
\n
"
);
// find similar modules
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p1
,
i
)
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p2
,
k
)
{
if
(
i
>=
k
)
continue
;
if
(
Gia_ManCiNum
(
p1
->
pGia
)
!=
Gia_ManCiNum
(
p2
->
pGia
)
||
Gia_ManCoNum
(
p1
->
pGia
)
!=
Gia_ManCoNum
(
p2
->
pGia
)
)
continue
;
// two similar modules
Status
=
Cec_ManVerifyTwo
(
p1
->
pGia
,
p2
->
pGia
,
0
);
if
(
Status
!=
1
)
continue
;
printf
(
"Proved equivalent modules: %s == %s
\n
"
,
Rtl_NtkName
(
p1
),
Rtl_NtkName
(
p2
)
);
// inline
if
(
Gia_ManAndNum
(
p1
->
pGia
)
>
Gia_ManAndNum
(
p2
->
pGia
)
)
ABC_SWAP
(
Gia_Man_t
*
,
p1
->
pGia
,
p2
->
pGia
);
assert
(
Gia_ManAndNum
(
p1
->
pGia
)
<=
Gia_ManAndNum
(
p2
->
pGia
)
);
Gia_ManStopP
(
&
p2
->
pGia
);
p2
->
pGia
=
Gia_ManDup
(
p1
->
pGia
);
fFound
=
1
;
goto
finish
;
}
finish:
if
(
fFound
==
0
)
printf
(
"Preprocessing not succeded.
\n
"
);
Abc_PrintTime
(
1
,
"Preprocessing time"
,
Abc_Clock
()
-
clk
);
// blast AIGs again
Vec_PtrForEachEntry
(
Rtl_Ntk_t
*
,
pLib
->
vNtks
,
p
,
i
)
if
(
p
!=
p1
&&
p
!=
p2
)
Gia_ManStopP
(
&
p
->
pGia
);
Rtl_LibBlast
(
pLib
);
}
void
Rtl_LibSolve
(
Rtl_Lib_t
*
pLib
)
{
abctime
clk
=
Abc_Clock
();
int
Status
;
Rtl_Ntk_t
*
pTop
=
Rtl_LibTop
(
pLib
);
Gia_Man_t
*
pCopy
=
Gia_ManDup
(
pTop
->
pGia
);
Gia_ManInvertPos
(
pCopy
);
Gia_ManAppendCo
(
pCopy
,
0
);
Status
=
Cec_ManVerifySimple
(
pCopy
);
Gia_ManStop
(
pCopy
);
if
(
Status
==
1
)
printf
(
"Verification problem solved! "
);
else
printf
(
"Verification problem is NOT solved! "
);
Abc_PrintTime
(
1
,
"Time"
,
Abc_Clock
()
-
clk
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/base/wln/wlnRtl.c
View file @
79f04c66
...
@@ -37,21 +37,6 @@ ABC_NAMESPACE_IMPL_START
...
@@ -37,21 +37,6 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Wln_Ntk_t
*
Wln_ReadRtl
(
char
*
pFileName
)
{
return
NULL
;
}
/**Function*************************************************************
/**Function*************************************************************
...
@@ -96,28 +81,31 @@ int Wln_ConvertToRtl( char * pCommand, char * pFileTemp )
...
@@ -96,28 +81,31 @@ int Wln_ConvertToRtl( char * pCommand, char * pFileTemp )
fclose
(
pFile
);
fclose
(
pFile
);
return
1
;
return
1
;
}
}
Wln_Ntk_t
*
Wln_ReadSystemVerilog
(
char
*
pFileName
,
char
*
pTopModul
e
,
int
fVerbose
)
Rtl_Lib_t
*
Wln_ReadSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fCollaps
e
,
int
fVerbose
)
{
{
Wln_Ntk
_t
*
pNtk
=
NULL
;
Rtl_Lib
_t
*
pNtk
=
NULL
;
char
Command
[
1000
];
char
Command
[
1000
];
char
*
pFileTemp
=
"_temp_.rtlil"
;
char
*
pFileTemp
=
"_temp_.rtlil"
;
int
fSVlog
=
strstr
(
pFileName
,
".sv"
)
!=
NULL
;
int
fSVlog
=
strstr
(
pFileName
,
".sv"
)
!=
NULL
;
sprintf
(
Command
,
"%s -qp
\"
read_verilog %s%s; hierarchy %s%s; flatten; proc; write_rtlil %s
\"
"
,
if
(
strstr
(
pFileName
,
".rtl"
)
)
return
Rtl_LibReadFile
(
pFileName
,
pFileName
);
sprintf
(
Command
,
"%s -qp
\"
read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s
\"
"
,
Wln_GetYosysName
(),
fSVlog
?
"-sv "
:
""
,
pFileName
,
Wln_GetYosysName
(),
fSVlog
?
"-sv "
:
""
,
pFileName
,
pTopModule
?
"-top "
:
"-auto-top"
,
pTopModule
?
pTopModule
:
""
,
pFileTemp
);
pTopModule
?
"-top "
:
"-auto-top"
,
pTopModule
?
pTopModule
:
""
,
fCollapse
?
"flatten; "
:
""
,
pFileTemp
);
if
(
fVerbose
)
if
(
fVerbose
)
printf
(
"%s
\n
"
,
Command
);
printf
(
"%s
\n
"
,
Command
);
if
(
!
Wln_ConvertToRtl
(
Command
,
pFileTemp
)
)
if
(
!
Wln_ConvertToRtl
(
Command
,
pFileTemp
)
)
{
return
NULL
;
return
NULL
;
}
pNtk
=
Rtl_LibReadFile
(
pFileTemp
,
pFileName
);
pNtk
=
Wln_ReadRtl
(
pFileTemp
);
if
(
pNtk
==
NULL
)
if
(
pNtk
==
NULL
)
{
{
printf
(
"Dumped the design into file
\"
%s
\"
.
\n
"
,
pFileTemp
);
printf
(
"Dumped the design into file
\"
%s
\"
.
\n
"
,
pFileTemp
);
return
NULL
;
return
NULL
;
}
}
unlink
(
pFileTemp
);
//
unlink( pFileTemp );
return
pNtk
;
return
pNtk
;
}
}
Gia_Man_t
*
Wln_BlastSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fSkipStrash
,
int
fInvert
,
int
fTechMap
,
int
fVerbose
)
Gia_Man_t
*
Wln_BlastSystemVerilog
(
char
*
pFileName
,
char
*
pTopModule
,
int
fSkipStrash
,
int
fInvert
,
int
fTechMap
,
int
fVerbose
)
...
@@ -125,10 +113,16 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk
...
@@ -125,10 +113,16 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk
Gia_Man_t
*
pGia
=
NULL
;
Gia_Man_t
*
pGia
=
NULL
;
char
Command
[
1000
];
char
Command
[
1000
];
char
*
pFileTemp
=
"_temp_.aig"
;
char
*
pFileTemp
=
"_temp_.aig"
;
int
fRtlil
=
strstr
(
pFileName
,
".rtl"
)
!=
NULL
;
int
fSVlog
=
strstr
(
pFileName
,
".sv"
)
!=
NULL
;
int
fSVlog
=
strstr
(
pFileName
,
".sv"
)
!=
NULL
;
sprintf
(
Command
,
"%s -qp
\"
read_verilog %s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s
\"
"
,
sprintf
(
Command
,
"%s -qp
\"
%s%s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s
\"
"
,
Wln_GetYosysName
(),
fSVlog
?
"-sv "
:
""
,
pFileName
,
Wln_GetYosysName
(),
pTopModule
?
"-top "
:
"-auto-top"
,
pTopModule
?
pTopModule
:
""
,
fTechMap
?
"techmap; setundef -zero; "
:
""
,
pFileTemp
);
fRtlil
?
"read_rtlil"
:
"read_verilog"
,
fSVlog
?
" -sv "
:
" "
,
pFileName
,
pTopModule
?
"-top "
:
"-auto-top"
,
pTopModule
?
pTopModule
:
""
,
fTechMap
?
"techmap; setundef -zero; "
:
""
,
pFileTemp
);
if
(
fVerbose
)
if
(
fVerbose
)
printf
(
"%s
\n
"
,
Command
);
printf
(
"%s
\n
"
,
Command
);
if
(
!
Wln_ConvertToRtl
(
Command
,
pFileTemp
)
)
if
(
!
Wln_ConvertToRtl
(
Command
,
pFileTemp
)
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment