mirror of https://github.com/YosysHQ/abc.git
Updates to NDR format (bug fixes).
This commit is contained in:
parent
f23ea8e33f
commit
aa313189c4
|
|
@ -194,6 +194,7 @@ static inline char * Abc_OperName( int Type )
|
|||
if ( Type == ABC_OPER_ARI_ADD ) return "+";
|
||||
if ( Type == ABC_OPER_ARI_SUB ) return "-";
|
||||
if ( Type == ABC_OPER_ARI_MUL ) return "*";
|
||||
if ( Type == ABC_OPER_ARI_SMUL ) return "*";
|
||||
if ( Type == ABC_OPER_ARI_DIV ) return "/";
|
||||
if ( Type == ABC_OPER_ARI_REM ) return "%";
|
||||
if ( Type == ABC_OPER_ARI_MOD ) return "mod";
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ ABC_NAMESPACE_HEADER_START
|
|||
Object inputs are name IDs of the driving nets; object outputs are name IDs of the driven nets.
|
||||
|
||||
The design is initialized using procedure Ndr_Create(), which takes the design name as an argument.
|
||||
A module in the design is initialized using procedure Ndr_AddModule(), which take the design and
|
||||
A module in the design is initialized using procedure Ndr_AddModule(), which takes the design and
|
||||
the module name as arguments. Objects are added to a module in any order using procedure Ndr_AddObject().
|
||||
|
||||
Primary input and primary output objects should be explicitly created, as shown in the examples below.
|
||||
|
||||
Instances of known operators listed in file "abcOper.h" are assumed to have one output. The only known
|
||||
issue due to this restriction concerns an adder, which produces a sum and a carry-out. To make sure the
|
||||
issue due to this restriction concerns the adder, which produces the sum and the carry-out. To make sure the
|
||||
adder instance has only one output, the carry-out has to be concatenated with the sum before the adder
|
||||
instance is created in the NDR format.
|
||||
|
||||
|
|
@ -68,17 +68,16 @@ ABC_NAMESPACE_HEADER_START
|
|||
Bit-slice and concatenation operators should be represented as separate objects.
|
||||
|
||||
If the ordering of inputs/outputs/flops of a module is not provided as a separate record in NDR format,
|
||||
their ordering is determined by the order of their appearance of their records in the body of the module.
|
||||
their ordering is determined by the order of their appearance in the NDR description of the module.
|
||||
|
||||
If left limit and right limit of a range are equal, it is assumed that the range contains one bit
|
||||
If range limits and signedness are all 0, it is assumed that it is the bit-width is equal to 1.
|
||||
If left limit and right limit of a bit-range are equal, it is assumed that the range contains one bit
|
||||
|
||||
Word-level constants are represented as char-strings given in the same way as they would appear in a Verilog
|
||||
file. For example, the 16-bit constant 10 is represented as a string "4'b1010" and is given as an argument
|
||||
(char * pFunction) to the procedure Ndr_AddObject().
|
||||
|
||||
Currently two types of flops are supported: a simple flop with implicit clock with two fanins (data and init)
|
||||
and a complex flop with 7 fanins (clock, data, reset, set, enable, async, init), as shown in the examples below.
|
||||
Currently two types of flops are supported: a simple flop with implicit clock and two fanins (data and init)
|
||||
and a complex flop with 8 fanins (clock, data, reset, set, enable, async, sre, init), as shown in the examples below.
|
||||
|
||||
The initial value of a flop is represented by input "init", which can be driven by a constant or by a primary
|
||||
input of the module. If it is a primary input, is it assumed that the flop is not initialized. If the input
|
||||
|
|
@ -322,6 +321,7 @@ static inline int Ndr_DataObjNum( Ndr_Data_t * p, int Mod )
|
|||
static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames )
|
||||
{
|
||||
Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
|
||||
Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
|
||||
int Obj, nArray, * pArray, fFirst = 1;
|
||||
|
||||
fprintf( pFile, "\nmodule %s (\n ", pNames[Ndr_ObjReadEntry(p, Mod, NDR_NAME)] );
|
||||
|
|
@ -348,16 +348,20 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
|
|||
fprintf( pFile, " output " );
|
||||
Ndr_ObjWriteRange( p, Obj, pFile, 1 );
|
||||
fprintf( pFile, " %s;\n", Ndr_ObjReadInName(p, Obj, pNames) );
|
||||
Vec_IntPush( vOuts, Ndr_ObjReadBody(p, Obj, NDR_INPUT) );
|
||||
}
|
||||
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
Ndr_ModForEachNode( p, Mod, Obj )
|
||||
{
|
||||
if ( Vec_IntFind(vOuts, Ndr_ObjReadBody(p, Obj, NDR_OUTPUT)) >= 0 )
|
||||
continue;
|
||||
fprintf( pFile, " wire " );
|
||||
Ndr_ObjWriteRange( p, Obj, pFile, 1 );
|
||||
fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) );
|
||||
}
|
||||
Vec_IntFree( vOuts );
|
||||
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
|
|
@ -403,7 +407,8 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
|
|||
fprintf( pFile, ".set(%s), ", pNames[pArray[3]] );
|
||||
fprintf( pFile, ".enable(%s), ", pNames[pArray[4]] );
|
||||
fprintf( pFile, ".async(%s), ", pNames[pArray[5]] );
|
||||
fprintf( pFile, ".init(%s) ", pNames[pArray[6]] );
|
||||
fprintf( pFile, ".sre(%s), ", pNames[pArray[6]] );
|
||||
fprintf( pFile, ".init(%s) ", pNames[pArray[7]] );
|
||||
fprintf( pFile, ");\n" );
|
||||
continue;
|
||||
}
|
||||
|
|
@ -900,25 +905,26 @@ static inline void Ndr_ModuleTestMemory()
|
|||
// This testing procedure creates and writes into a Verilog file
|
||||
// the following design composed of one word-level flop
|
||||
|
||||
// module flop ( input [3:0] data, input clk, input reset, input set, input enable, input async, input [3:0] init, output [3:0] q );
|
||||
// ABC_DFFRSE reg1 ( .d(data), .clk(clk), .reset(reset), .set(set), .enable(enable), .async(async), .init(init), .q(q) ) ;
|
||||
// module flop ( input [3:0] data, input clk, input reset, input set, input enable, input async, input sre, input [3:0] init, output [3:0] q );
|
||||
// ABC_DFFRSE reg1 ( .d(data), .clk(clk), .reset(reset), .set(set), .enable(enable), .async(async), .sre(sre), .init(init), .q(q) ) ;
|
||||
// endmodule
|
||||
|
||||
static inline void Ndr_ModuleTestFlop()
|
||||
{
|
||||
// map name IDs into char strings
|
||||
char * ppNames[10] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "init", "q" };
|
||||
char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
|
||||
// name IDs
|
||||
int NameIdData = 2;
|
||||
int NameIdClk = 3;
|
||||
int NameIdReset = 4;
|
||||
int NameIdSet = 5;
|
||||
int NameIdEnable = 6;
|
||||
int NameIdAsync = 7;
|
||||
int NameIdInit = 8;
|
||||
int NameIdQ = 9;
|
||||
int NameIdData = 2;
|
||||
int NameIdClk = 3;
|
||||
int NameIdReset = 4;
|
||||
int NameIdSet = 5;
|
||||
int NameIdEnable = 6;
|
||||
int NameIdAsync = 7;
|
||||
int NameIdSre = 8;
|
||||
int NameIdInit = 9;
|
||||
int NameIdQ = 10;
|
||||
// array of fanins of node s
|
||||
int Fanins[7] = { NameIdData, NameIdClk, NameIdReset, NameIdSet, NameIdEnable, NameIdAsync, NameIdInit };
|
||||
int Fanins[8] = { NameIdData, NameIdClk, NameIdReset, NameIdSet, NameIdEnable, NameIdAsync, NameIdSre, NameIdInit };
|
||||
|
||||
// create a new module
|
||||
void * pDesign = Ndr_Create( 1 );
|
||||
|
|
@ -932,9 +938,10 @@ static inline void Ndr_ModuleTestFlop()
|
|||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdSet, NULL );
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdEnable, NULL );
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdAsync, NULL );
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdSre, NULL );
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdInit, NULL );
|
||||
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_DFFRSE, 0, 3, 0, 0, 7, Fanins, 1, &NameIdQ, NULL );
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_DFFRSE, 0, 3, 0, 0, 8, Fanins, 1, &NameIdQ, NULL );
|
||||
|
||||
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL );
|
||||
|
||||
|
|
|
|||
|
|
@ -397,13 +397,6 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
|
|||
ABC_SWAP( int, Vec_IntEntryP(vFanins, 1)[0], Vec_IntEntryP(vFanins, 2)[0] );
|
||||
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
|
||||
Wlc_ObjSetNameId( pNtk, iObj, NameId );
|
||||
if ( Type == ABC_OPER_ARI_SMUL )
|
||||
{
|
||||
pObj = Wlc_NtkObj(pNtk, iObj);
|
||||
assert( Wlc_ObjFaninNum(pObj) == 2 );
|
||||
Wlc_ObjFanin0(pNtk, pObj)->Signed = 1;
|
||||
Wlc_ObjFanin1(pNtk, pObj)->Signed = 1;
|
||||
}
|
||||
}
|
||||
// mark primary outputs
|
||||
Ndr_ModForEachPo( p, Mod, Obj )
|
||||
|
|
@ -426,6 +419,12 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
|
|||
int * pFanins = Wlc_ObjFanins(pObj);
|
||||
for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
|
||||
pFanins[k] = Vec_IntEntry(vName2Obj, pFanins[k]);
|
||||
if ( Wlc_ObjType(pObj) == WLC_OBJ_ARI_MULTI )
|
||||
{
|
||||
assert( Wlc_ObjFaninNum(pObj) == 2 );
|
||||
Wlc_ObjFanin0(pNtk, pObj)->Signed = 1;
|
||||
Wlc_ObjFanin1(pNtk, pObj)->Signed = 1;
|
||||
}
|
||||
}
|
||||
if ( pNtk->vInits )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
|
|||
fprintf( pFile, " " );
|
||||
fprintf( pFile, "%s (", pObj->Type == WLC_OBJ_READ ? "ABC_READ" : "ABC_WRITE" );
|
||||
Wlc_ObjForEachFanin( pObj, iFanin, k )
|
||||
fprintf( pFile, " .%s(%s)", k==0 ? "mem_in" : (k==1 ? "addr": "data"), Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s),", k==0 ? "mem_in" : (k==1 ? "addr": "data"), Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s) ) ;\n", pObj->Type == WLC_OBJ_READ ? "data" : "mem_out", Wlc_ObjName(p, i) );
|
||||
continue;
|
||||
}
|
||||
|
|
@ -276,19 +276,19 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
|
|||
fprintf( pFile, " " );
|
||||
fprintf( pFile, "%s_%d (", pObj->Type == WLC_OBJ_READ ? "CPL_MEM_READ" : "CPL_MEM_WRITE", Depth );
|
||||
Wlc_ObjForEachFanin( pObj, iFanin, k )
|
||||
fprintf( pFile, " .%s(%s)", k==0 ? "mem_data_in" : (k==1 ? "addr_in": "data_in"), Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s),", k==0 ? "mem_data_in" : (k==1 ? "addr_in": "data_in"), Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s) ) ;\n", "data_out", Wlc_ObjName(p, i) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( pObj->Type == WLC_OBJ_FF )
|
||||
{
|
||||
char * pInNames[7] = {"d", "clk", "reset", "set", "enable", "async", "init"};
|
||||
char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"};
|
||||
fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) );
|
||||
fprintf( pFile, " " );
|
||||
fprintf( pFile, "%s (", "ABC_DFFRSE" );
|
||||
Wlc_ObjForEachFanin( pObj, iFanin, k )
|
||||
fprintf( pFile, " .%s(%s)", pInNames[k], Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) );
|
||||
fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, i) );
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue