Changes to "read_jsonc".

This commit is contained in:
Alan Mishchenko 2025-12-24 17:45:00 -08:00
parent 58023c97b7
commit 60f52cc082
2 changed files with 502 additions and 44 deletions

View File

@ -1890,7 +1890,8 @@ usage:
***********************************************************************/
int IoCommandReadJsonc( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern int Jsonc_ReadTest( char * pFileName );
extern Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName );
Abc_Ntk_t * pNtk;
char * pFileName;
FILE * pFile;
int c;
@ -1920,7 +1921,11 @@ int IoCommandReadJsonc( Abc_Frame_t * pAbc, int argc, char ** argv )
}
fclose( pFile );
Jsonc_ReadTest( pFileName );
pNtk = Jsonc_ReadNetwork( pFileName );
if ( pNtk == NULL )
return 1;
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
Abc_FrameClearVerifStatus( pAbc );
return 0;
usage:
@ -4607,4 +4612,3 @@ usage:
ABC_NAMESPACE_IMPL_END

View File

@ -21,12 +21,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "ioAbc.h"
#include "base/abc/abc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"
#include "ioAbc.h"
ABC_NAMESPACE_IMPL_START
@ -45,38 +47,50 @@ typedef enum {
} json_type_t;
// Core structure: stores offset and length in the original string
typedef struct {
uint32_t offset; // Offset in the JSON string
uint32_t length; // Length of this value
json_type_t type; // Type of JSON value
typedef struct json_value_t_ {
uint32_t offset; // Offset in the JSON string
uint32_t length; // Length of this value
json_type_t type; // Type of JSON value
uint32_t container; // Index of the container if this is an object/array
} json_value_t;
// Key-value pair for objects
typedef struct {
json_value_t key; // Key (always a string)
json_value_t value; // Associated value
typedef struct json_pair_t_ {
json_value_t key; // Key (always a string)
json_value_t value; // Associated value
} json_pair_t;
// Dynamic array for storing pairs (objects) or values (arrays)
typedef struct {
typedef struct json_container_t_ {
union {
json_pair_t *pairs; // For objects
json_value_t *values; // For arrays
} data;
uint32_t count; // Number of elements
uint32_t capacity; // Allocated capacity
uint32_t count; // Number of elements
uint32_t capacity; // Allocated capacity
} json_container_t;
// Main JSON structure
typedef struct {
char *str; // The original JSON string
uint32_t str_len; // Length of the string
json_value_t root; // Root element
json_container_t *containers; // Array of containers
uint32_t container_count; // Number of containers
uint32_t container_capacity; // Allocated capacity
typedef struct json_t_ {
char *str; // The original JSON string
uint32_t str_len; // Length of the string
json_value_t root; // Root element
json_container_t *containers; // Array of containers
uint32_t container_count; // Number of containers
uint32_t container_capacity; // Allocated capacity
} json_t;
// Creation / destruction
json_t * json_create(void);
void json_destroy(json_t *json);
bool json_load_file(json_t *json, const char *filename);
// Debug/printing helpers
void json_print(json_t *json, FILE *fp);
void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool format);
void json_print_string(json_t *json, json_value_t val, FILE *fp);
void json_debug_value(json_t *json, json_value_t val, int indent);
// Function prototypes
json_t* json_create(void);
void json_destroy(json_t *json);
@ -93,6 +107,12 @@ void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool
void json_print_string(json_t *json, json_value_t val, FILE *fp);
void json_debug_value(json_t *json, json_value_t val, int indent);
extern Abc_Ntk_t * Abc_NtkFromMiniMapping( int * pArray );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// Create a new JSON structure
json_t* json_create(void) {
json_t *json = (json_t*)calloc(1, sizeof(json_t));
@ -185,6 +205,7 @@ json_container_t* json_add_container(json_t *json) {
// Parse a JSON string
json_value_t json_parse_string(json_t *json, uint32_t *pos) {
json_value_t val = {0};
val.container = UINT32_MAX;
val.type = JSON_STRING;
val.offset = *pos;
@ -203,6 +224,7 @@ json_value_t json_parse_string(json_t *json, uint32_t *pos) {
// Parse a JSON number
json_value_t json_parse_number(json_t *json, uint32_t *pos) {
json_value_t val = {0};
val.container = UINT32_MAX;
val.type = JSON_NUMBER;
val.offset = *pos;
@ -223,6 +245,7 @@ json_value_t json_parse_number(json_t *json, uint32_t *pos) {
// Parse a JSON object
json_value_t json_parse_object(json_t *json, uint32_t *pos) {
json_value_t val = {0};
val.container = UINT32_MAX;
val.type = JSON_OBJECT;
val.offset = *pos;
@ -230,6 +253,8 @@ json_value_t json_parse_object(json_t *json, uint32_t *pos) {
json_container_t *container = json_add_container(json);
if (!container) return val;
val.container = json->container_count - 1;
container = json->containers + val.container;
container->capacity = 8;
container->data.pairs = (json_pair_t*)calloc(container->capacity, sizeof(json_pair_t));
@ -249,6 +274,7 @@ json_value_t json_parse_object(json_t *json, uint32_t *pos) {
json_value_t value = json_parse_value(json, pos);
// Add pair to container
container = json->containers + val.container;
if (container->count >= container->capacity) {
uint32_t new_capacity = container->capacity * 2;
json_pair_t *new_pairs = (json_pair_t*)realloc(
@ -278,6 +304,7 @@ json_value_t json_parse_object(json_t *json, uint32_t *pos) {
// Parse a JSON array
json_value_t json_parse_array(json_t *json, uint32_t *pos) {
json_value_t val = {0};
val.container = UINT32_MAX;
val.type = JSON_ARRAY;
val.offset = *pos;
@ -285,6 +312,8 @@ json_value_t json_parse_array(json_t *json, uint32_t *pos) {
json_container_t *container = json_add_container(json);
if (!container) return val;
val.container = json->container_count - 1;
container = json->containers + val.container;
container->capacity = 8;
container->data.values = (json_value_t*)calloc(container->capacity, sizeof(json_value_t));
@ -297,6 +326,7 @@ json_value_t json_parse_array(json_t *json, uint32_t *pos) {
json_value_t value = json_parse_value(json, pos);
// Add value to container
container = json->containers + val.container;
if (container->count >= container->capacity) {
uint32_t new_capacity = container->capacity * 2;
json_value_t *new_values = (json_value_t*)realloc(
@ -325,6 +355,7 @@ json_value_t json_parse_array(json_t *json, uint32_t *pos) {
// Parse any JSON value
json_value_t json_parse_value(json_t *json, uint32_t *pos) {
json_value_t val = {0};
val.container = UINT32_MAX;
json_skip_whitespace(json->str, pos, json->str_len);
@ -342,18 +373,21 @@ json_value_t json_parse_value(json_t *json, uint32_t *pos) {
val.type = JSON_NULL;
val.offset = *pos;
val.length = 4;
val.container = UINT32_MAX;
*pos += 4;
return val;
} else if (c == 't') {
val.type = JSON_BOOL;
val.offset = *pos;
val.length = 4;
val.container = UINT32_MAX;
*pos += 4;
return val;
} else if (c == 'f') {
val.type = JSON_BOOL;
val.offset = *pos;
val.length = 5;
val.container = UINT32_MAX;
*pos += 5;
return val;
} else if ((c >= '0' && c <= '9') || c == '-') {
@ -397,6 +431,7 @@ bool json_load_file(json_t *json, const char *filename) {
json->str[file_size] = '\0';
json->str_len = (uint32_t)file_size;
json->container_count = 0;
// Parse JSON
uint32_t pos = 0;
@ -442,24 +477,8 @@ void json_print_string(json_t *json, json_value_t val, FILE *fp) {
fputc('"', fp);
}
// Find the container index for a given value
static int find_container_index(json_t *json, json_value_t val) {
static int last_container = 0;
// Check if it's an object or array
if (val.type == JSON_OBJECT || val.type == JSON_ARRAY) {
int index = last_container++;
if (index < json->container_count) {
return index;
}
}
return -1;
}
// Print a JSON value recursively
void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool format) {
static int container_index = 0;
switch (val.type) {
case JSON_NULL:
fprintf(fp, "null");
@ -486,8 +505,8 @@ void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool
case JSON_ARRAY: {
fputc('[', fp);
if (container_index < json->container_count) {
json_container_t *container = &json->containers[container_index++];
if (val.container < json->container_count) {
json_container_t *container = &json->containers[val.container];
for (uint32_t i = 0; i < container->count; i++) {
if (format) {
@ -516,8 +535,8 @@ void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool
case JSON_OBJECT: {
fputc('{', fp);
if (container_index < json->container_count) {
json_container_t *container = &json->containers[container_index++];
if (val.container < json->container_count) {
json_container_t *container = &json->containers[val.container];
for (uint32_t i = 0; i < container->count; i++) {
if (format) {
@ -549,7 +568,6 @@ void json_print_value(json_t *json, json_value_t val, FILE *fp, int indent, bool
// Print the entire JSON to a file
void json_print(json_t *json, FILE *fp) {
// Reset the static container index in json_print_value
json_print_value(json, json->root, fp, 0, true);
fprintf(fp, "\n");
}
@ -722,7 +740,6 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
fprintf( pFile, " }%s\n", Mio_PinReadNext(pPin) ? "," : "" );
}
fprintf( pFile, " }\n" );
//fprintf( pFile, " ]\n" );
fprintf( pFile, " }%s\n", ++Counter == Total ? "" : "," );
}
Abc_NtkForEachPo( p, pObj, i )
@ -749,6 +766,443 @@ void Jsonc_WriteTest( Abc_Ntk_t * p, char * pFileName )
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static json_container_t * Jsonc_GetContainer( json_t * pJson, json_value_t value )
{
if ( value.container == UINT32_MAX )
return NULL;
if ( value.container >= pJson->container_count )
return NULL;
return pJson->containers + value.container;
}
static int Jsonc_StringEqual( json_t * pJson, json_value_t value, const char * pStr )
{
uint32_t Len;
if ( value.type != JSON_STRING || value.length < 2 )
return 0;
Len = value.length - 2;
return strlen(pStr) == Len && strncmp( pJson->str + value.offset + 1, pStr, Len ) == 0;
}
static char * Jsonc_StringDup( json_t * pJson, json_value_t value )
{
char * pRes;
uint32_t i, Len;
if ( value.type != JSON_STRING || value.length < 2 )
return NULL;
Len = value.length - 2;
pRes = ABC_ALLOC( char, Len + 1 );
for ( i = 0; i < Len; i++ )
{
char c = pJson->str[value.offset + 1 + i];
if ( c == '\\' && i + 1 < Len )
{
i++;
c = pJson->str[value.offset + 1 + i];
}
pRes[i] = c;
}
pRes[Len] = '\0';
return pRes;
}
static int Jsonc_ParseInt( json_t * pJson, json_value_t value, int * pResult )
{
char * pBuffer, * pEnd;
uint32_t Len;
long Temp;
if ( value.type != JSON_NUMBER )
return 0;
Len = value.length;
pBuffer = ABC_ALLOC( char, Len + 1 );
memcpy( pBuffer, pJson->str + value.offset, Len );
pBuffer[Len] = '\0';
Temp = strtol( pBuffer, &pEnd, 10 );
ABC_FREE( pBuffer );
if ( pEnd == NULL || pEnd == pBuffer )
return 0;
*pResult = (int)Temp;
return 1;
}
static json_value_t * Jsonc_ObjectLookup( json_t * pJson, json_value_t object, const char * pKey )
{
json_container_t * pCont;
uint32_t i;
if ( object.type != JSON_OBJECT )
return NULL;
pCont = Jsonc_GetContainer( pJson, object );
if ( pCont == NULL )
return NULL;
for ( i = 0; i < pCont->count; i++ )
if ( Jsonc_StringEqual( pJson, pCont->data.pairs[i].key, pKey ) )
return &pCont->data.pairs[i].value;
return NULL;
}
static Vec_Int_t * Jsonc_NameCounts( Vec_Ptr_t * vBases, Vec_Int_t ** pvBaseIds )
{
Abc_Nam_t * pNames;
Vec_Int_t * vCounts, * vBaseIds;
char * pBase;
int i, Id;
pNames = Abc_NamStart( Vec_PtrSize(vBases) + 1, 24 );
vCounts = Vec_IntAlloc( Vec_PtrSize(vBases) + 1 );
vBaseIds = Vec_IntAlloc( Vec_PtrSize(vBases) + 1 );
Vec_IntFillExtra( vCounts, 1, 0 );
Vec_PtrForEachEntry( char *, vBases, pBase, i )
{
int fFound;
Id = Abc_NamStrFindOrAdd( pNames, pBase, &fFound );
Vec_IntFillExtra( vCounts, Id + 1, 0 );
Vec_IntAddToEntry( vCounts, Id, 1 );
Vec_IntPush( vBaseIds, Id );
}
Abc_NamDeref( pNames );
*pvBaseIds = vBaseIds;
return vCounts;
}
static void Jsonc_AppendName( Vec_Str_t * vNames, const char * pBase, int Bit, int fUseBit )
{
int nSize = (int)strlen(pBase ? pBase : "") + 32;
char * pBuffer = ABC_ALLOC( char, nSize );
if ( fUseBit )
snprintf( pBuffer, nSize, "%s[%d]", pBase ? pBase : "", Bit );
else
snprintf( pBuffer, nSize, "%s", pBase ? pBase : "" );
Vec_StrPrintStr( vNames, pBuffer );
Vec_StrPush( vNames, '\0' );
ABC_FREE( pBuffer );
}
static void Jsonc_AppendPortNames( Vec_Str_t * vNames, Vec_Ptr_t * vBases, Vec_Int_t * vBits )
{
Vec_Int_t * vCounts, * vBaseIds;
char * pBase;
int i, Bit, Count;
vCounts = Jsonc_NameCounts( vBases, &vBaseIds );
Vec_PtrForEachEntry( char *, vBases, pBase, i )
{
Bit = Vec_IntEntry( vBits, i );
Count = Vec_IntEntry( vCounts, Vec_IntEntry( vBaseIds, i ) );
Jsonc_AppendName( vNames, pBase, Bit, Bit != 0 || Count > 1 );
}
Vec_IntFree( vCounts );
Vec_IntFree( vBaseIds );
}
static Vec_Int_t * Jsonc_ConvertToMiniMapping( json_t * pJson, Mio_Library_t * pLib, char ** ppDesignName )
{
Vec_Ptr_t * vPiBases = NULL, * vPoBases = NULL;
Vec_Int_t * vPiBits = NULL, * vPoBits = NULL;
Vec_Int_t * vNodeMap = NULL, * vGateIdx = NULL, * vPoIdx = NULL;
Vec_Int_t * vMapping = NULL, * vPoDrivers = NULL;
Vec_Str_t * vNames = NULL;
json_container_t * pNodes;
json_value_t * pTemp;
char * pBase;
int i, k, nCis = 0, nNodes = 0, nCos = 0;
int fSuccess = 0;
if ( ppDesignName )
*ppDesignName = NULL;
if ( pLib == NULL )
{
printf( "Genlib library is not available.\n" );
return NULL;
}
if ( pJson->root.type != JSON_OBJECT )
{
printf( "JSONC root should be an object.\n" );
return NULL;
}
pTemp = Jsonc_ObjectLookup( pJson, pJson->root, "name" );
if ( pTemp && ppDesignName && pTemp->type == JSON_STRING )
*ppDesignName = Jsonc_StringDup( pJson, *pTemp );
pTemp = Jsonc_ObjectLookup( pJson, pJson->root, "nodes" );
if ( pTemp == NULL || pTemp->type != JSON_ARRAY )
{
printf( "JSONC file is missing top-level \"nodes\" array.\n" );
return NULL;
}
pNodes = Jsonc_GetContainer( pJson, *pTemp );
if ( pNodes == NULL )
{
printf( "Internal JSONC structure is incomplete.\n" );
return NULL;
}
vNodeMap = Vec_IntStartFull( pNodes->count );
vGateIdx = Vec_IntAlloc( pNodes->count );
vPoIdx = Vec_IntAlloc( pNodes->count );
vPiBases = Vec_PtrAlloc( pNodes->count );
vPiBits = Vec_IntAlloc( pNodes->count );
vPoBases = Vec_PtrAlloc( pNodes->count );
vPoBits = Vec_IntAlloc( pNodes->count );
// first pass: collect object types and names
for ( i = 0; i < (int)pNodes->count; i++ )
{
json_value_t Node = pNodes->data.values[i];
json_value_t * pType = Jsonc_ObjectLookup( pJson, Node, "type" );
json_value_t * pName = Jsonc_ObjectLookup( pJson, Node, "name" );
json_value_t * pBit = Jsonc_ObjectLookup( pJson, Node, "bit" );
int Bit = 0;
if ( pType == NULL || pType->type != JSON_STRING )
{
printf( "Node %d does not have a valid \"type\" field.\n", i );
goto cleanup;
}
if ( pBit && !Jsonc_ParseInt( pJson, *pBit, &Bit ) )
{
printf( "Node %d has an invalid \"bit\" field.\n", i );
goto cleanup;
}
if ( Jsonc_StringEqual( pJson, *pType, "pi" ) )
{
Vec_IntWriteEntry( vNodeMap, i, nCis++ );
pBase = Jsonc_StringDup( pJson, pName ? *pName : *pType );
if ( pBase == NULL )
{
printf( "Primary input %d is missing a name.\n", i );
goto cleanup;
}
Vec_PtrPush( vPiBases, pBase );
Vec_IntPush( vPiBits, Bit );
}
else if ( Jsonc_StringEqual( pJson, *pType, "instance" ) )
{
Vec_IntPush( vGateIdx, i );
nNodes++;
}
else if ( Jsonc_StringEqual( pJson, *pType, "PO" ) || Jsonc_StringEqual( pJson, *pType, "po" ) )
{
Vec_IntPush( vPoIdx, i );
nCos++;
pBase = Jsonc_StringDup( pJson, pName ? *pName : *pType );
if ( pBase == NULL )
{
printf( "Primary output %d is missing a name.\n", i );
goto cleanup;
}
Vec_PtrPush( vPoBases, pBase );
Vec_IntPush( vPoBits, Bit );
}
else
{
printf( "Node %d has unsupported type.\n", i );
goto cleanup;
}
}
// assign IDs to internal nodes
for ( i = 0; i < Vec_IntSize(vGateIdx); i++ )
Vec_IntWriteEntry( vNodeMap, Vec_IntEntry(vGateIdx, i), nCis + i );
// allocate storage for mapping
vMapping = Vec_IntAlloc( 4 + nNodes * 4 + nCos + 10 );
vNames = Vec_StrAlloc( 1024 );
vPoDrivers = Vec_IntAlloc( nCos );
Vec_IntPush( vMapping, nCis );
Vec_IntPush( vMapping, nCos );
Vec_IntPush( vMapping, nNodes );
Vec_IntPush( vMapping, 0 ); // flops
// second pass: build nodes and POs
for ( i = 0; i < (int)pNodes->count; i++ )
{
json_value_t Node = pNodes->data.values[i];
json_value_t * pType = Jsonc_ObjectLookup( pJson, Node, "type" );
if ( Jsonc_StringEqual( pJson, *pType, "instance" ) )
{
json_value_t * pGateName = Jsonc_ObjectLookup( pJson, Node, "name" );
json_value_t * pFanins = Jsonc_ObjectLookup( pJson, Node, "fanins" );
json_container_t * pFanObj;
Mio_Gate_t * pGate;
Mio_Pin_t * pPin;
char * pGateStr;
if ( pGateName == NULL || pGateName->type != JSON_STRING )
{
printf( "Gate node %d is missing a name.\n", i );
goto cleanup;
}
pGateStr = Jsonc_StringDup( pJson, *pGateName );
if ( pGateStr == NULL )
{
printf( "Gate node %d has an invalid name.\n", i );
goto cleanup;
}
pGate = Mio_LibraryReadGateByName( pLib, pGateStr, NULL );
if ( pGate == NULL )
{
printf( "Gate \"%s\" is not found in the current library.\n", pGateStr );
ABC_FREE( pGateStr );
goto cleanup;
}
if ( pFanins == NULL || pFanins->type != JSON_OBJECT )
{
printf( "Gate \"%s\" is missing \"fanins\" description.\n", pGateStr );
ABC_FREE( pGateStr );
goto cleanup;
}
pFanObj = Jsonc_GetContainer( pJson, *pFanins );
if ( pFanObj == NULL )
{
printf( "Gate \"%s\" has incomplete fanin information.\n", pGateStr );
ABC_FREE( pGateStr );
goto cleanup;
}
Vec_IntPush( vMapping, Mio_GateReadPinNum(pGate) );
for ( pPin = Mio_GateReadPins(pGate), k = 0; pPin; pPin = Mio_PinReadNext(pPin), k++ )
{
json_value_t * pPinInfo = Jsonc_ObjectLookup( pJson, *pFanins, Mio_PinReadName(pPin) );
json_value_t * pNodeLit;
int NodeId, MapId;
if ( pPinInfo == NULL || pPinInfo->type != JSON_OBJECT )
{
printf( "Gate \"%s\" is missing connection for pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
ABC_FREE( pGateStr );
goto cleanup;
}
pNodeLit = Jsonc_ObjectLookup( pJson, *pPinInfo, "node" );
if ( pNodeLit == NULL || !Jsonc_ParseInt( pJson, *pNodeLit, &NodeId ) )
{
printf( "Gate \"%s\" has invalid node reference on pin \"%s\".\n", pGateStr, Mio_PinReadName(pPin) );
ABC_FREE( pGateStr );
goto cleanup;
}
if ( NodeId < 0 || NodeId >= Vec_IntSize(vNodeMap) )
{
printf( "Gate \"%s\" references out-of-range node %d.\n", pGateStr, NodeId );
ABC_FREE( pGateStr );
goto cleanup;
}
MapId = Vec_IntEntry( vNodeMap, NodeId );
if ( MapId < 0 )
{
printf( "Gate \"%s\" refers to unsupported node %d.\n", pGateStr, NodeId );
ABC_FREE( pGateStr );
goto cleanup;
}
Vec_IntPush( vMapping, MapId );
}
Vec_StrPrintStr( vNames, pGateStr );
Vec_StrPush( vNames, '\0' );
ABC_FREE( pGateStr );
}
else if ( Jsonc_StringEqual( pJson, *pType, "PO" ) || Jsonc_StringEqual( pJson, *pType, "po" ) )
{
json_value_t * pFanin = Jsonc_ObjectLookup( pJson, Node, "fanin" );
json_value_t * pNodeId = pFanin ? Jsonc_ObjectLookup( pJson, *pFanin, "node" ) : NULL;
int NodeId, MapId;
if ( pNodeId == NULL || !Jsonc_ParseInt( pJson, *pNodeId, &NodeId ) )
{
printf( "Primary output %d is missing driver information.\n", Vec_IntSize(vPoDrivers) );
goto cleanup;
}
if ( NodeId < 0 || NodeId >= Vec_IntSize(vNodeMap) )
{
printf( "Primary output %d refers to out-of-range node %d.\n", Vec_IntSize(vPoDrivers), NodeId );
goto cleanup;
}
MapId = Vec_IntEntry( vNodeMap, NodeId );
if ( MapId < 0 )
{
printf( "Primary output %d points to unsupported node %d.\n", Vec_IntSize(vPoDrivers), NodeId );
goto cleanup;
}
Vec_IntPush( vPoDrivers, MapId );
}
}
if ( Vec_IntSize(vPoDrivers) != nCos )
{
printf( "JSONC file declares %d POs but %d drivers were found.\n", nCos, Vec_IntSize(vPoDrivers) );
goto cleanup;
}
// append CO drivers
Vec_IntForEachEntry( vPoDrivers, k, i )
Vec_IntPush( vMapping, k );
// append gate / CI / CO names
Jsonc_AppendPortNames( vNames, vPiBases, vPiBits );
Jsonc_AppendPortNames( vNames, vPoBases, vPoBits );
// align to 4 bytes and append strings as ints
{
int nExtra = (4 - Vec_StrSize(vNames) % 4) % 4;
int nWords, * pBuffer;
for ( i = 0; i < nExtra; i++ )
Vec_StrPush( vNames, '\0' );
nWords = Vec_StrSize(vNames) / 4;
pBuffer = (int *)Vec_StrArray( vNames );
for ( i = 0; i < nWords; i++ )
Vec_IntPush( vMapping, pBuffer[i] );
}
fSuccess = 1;
cleanup:
if ( fSuccess == 0 && ppDesignName && *ppDesignName )
ABC_FREE( *ppDesignName );
Vec_IntFreeP( &vPoDrivers );
Vec_IntFreeP( &vNodeMap );
Vec_IntFreeP( &vGateIdx );
Vec_IntFreeP( &vPoIdx );
Vec_IntFreeP( &vPiBits );
Vec_IntFreeP( &vPoBits );
if ( vNames )
Vec_StrFree( vNames );
if ( vPiBases )
{
Vec_PtrForEachEntry( char *, vPiBases, pBase, i )
ABC_FREE( pBase );
Vec_PtrFree( vPiBases );
}
if ( vPoBases )
{
Vec_PtrForEachEntry( char *, vPoBases, pBase, i )
ABC_FREE( pBase );
Vec_PtrFree( vPoBases );
}
if ( fSuccess == 0 && vMapping )
{
Vec_IntFree( vMapping );
vMapping = NULL;
}
return vMapping;
}
Abc_Ntk_t * Jsonc_ReadNetwork( char * pFileName )
{
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
Vec_Int_t * vMapping;
Abc_Ntk_t * pNtk;
char * pDesignName = NULL;
json_t * pJson = json_create();
if ( pJson == NULL )
{
printf( "Failed to allocate JSONC parser.\n" );
return NULL;
}
if ( !json_load_file( pJson, pFileName ) )
{
printf( "Failed to load JSONC file \"%s\".\n", pFileName );
json_destroy( pJson );
return NULL;
}
vMapping = Jsonc_ConvertToMiniMapping( pJson, pLib, &pDesignName );
json_destroy( pJson );
if ( vMapping == NULL )
return NULL;
pNtk = Abc_NtkFromMiniMapping( Vec_IntArray(vMapping) );
Vec_IntFree( vMapping );
if ( pNtk == NULL )
{
ABC_FREE( pDesignName );
return NULL;
}
ABC_FREE( pNtk->pName );
pNtk->pName = pDesignName ? pDesignName : Extra_FileNameGeneric( pFileName );
ABC_FREE( pNtk->pSpec );
pNtk->pSpec = Abc_UtilStrsav( pFileName );
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////