Hi Beal,
I picked out the parts of the s2ibis code that does this merging. It'll work
for data files generated for the following types of spice:
"HSpice",
"PSpice",
"SPICE2",
"Spice3",
"Spectre"
I've added a spice type called "dummy" if you just have files with data and
nothing else.
(The first line of the input files should be empty)
if you are using spice other than these you need to add the following to the
code to take care of it:
1. spiceNameString : your spice name(does not run it so just
something
different from those already
there)
2. dataEndMarker : When to stop reading the data in the file.
3. VIDataBeginMarker: Where to start reading from the file for actual
data points.
4. VIDataConversionString: What format will the data be in(check the code
for examples)
The format to use it right now is:
combine <spiceType> <typFl> <minFl> <maxFl> <opFl>
Copy the two files in a dir and say make(in any Unix platform) on windows
just compile the combine.c
Please let me know if there are any problems.
regards,
presi
-----
Syed Huq wrote:
> Hi,
>
> Yes it can be done with Xemacs. It's called 'Rectangle Operations' and I
> think you could try the following key bindings:
>
> ^x r k, ^x r y, ^x r d
>
> emacs or Xemacs is a GNU editor(plus more)found on all Linux systems as
> well as UNIX.
>
> Regards,
> Syed
> Cisco Systems, Inc.
>
> > From beal@lisbon.eng.hou.compaq.com Tue Dec 8 08:06:46 1998
> > X-SMAP-Received-From: outside
> > Date: Tue, 8 Dec 98 09:16 CST
> > From: beal@lisbon.eng.hou.compaq.com (Weston Beal)
> > To: ibis-users@vhdl.org
> > Subject: curve merging
> >
> > Dear Users,
> >
> > I have two IBIS files which represent the min and max cases of a
> > model. One file has the min characteristics in the typ column and the
> > other has the max characteristics in the typ column. I would like to
> > merge them into one file in standard (typ, min, max) IBIS format. Does
> > anyone have a utility to do this which they can share?
> >
> > Thanks,
> > Weston Beal
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cahn's Axiom: "When all else fails, read the instructions." R.Sanjeev Home... ~~~~~~~~~ hppt://members.tripod.com/~r_sanjeev e-mail: presi@india.ti.com snail-mail: 20, Karnan Street, Murugesha Naicken Nagar, Kodambakkam, Chennai-24. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# makefile for mergeIBIS
#
##############################################################################
# Compilation and linking using GNU tools
#
CC = gcc
CFLAGS = -g
##############################################################################
PROGRAM = mergeIBIS
SRCS = mergeIBIS.c
ALL = $(SRCS)
OBJS =$(SRCS:.c=.o)
$(PROGRAM): $(OBJS)
$(CC) -o $(PROGRAM) $(CFLAGS) $(OBJS)
clean :
rm $(OBJS) $(PROGRAM)
depend :
makedepend -- $(CFLAGS) $(SRCS)
# DO NOT DELETE THIS LINE -- make depend depends on it.
/********************************************************************
* Parts from s2ibis2 that came from:
* North Carolina State University
* Electronics Research Laboratory
*
* Modified by: Sanjeev Ranganathan
* Indian Institute of Technology Madras
* VLSI Design Laboratory.
* e-mail: presi@oyster.ee.iitm.ernet.in
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/*
* ARGUMENT LABELS
*
* These are used to label function arguments.
*
* IN indicates that the argument data is read only by the function, and
* not written.
*
* INOUT indicates that the argument data is read and written by the
* function.
*
* OUT indicates that the argument data is written by the function,
* without reference to its previous value.
*
* INOUT and OUT apply only to pointer arguments, since there is no
* direct pass-by-reference mechanism in C.
*/
#define IN
#define OUT
#define INOUT
#define SHARED
/* MAX TABLE size :used as initial value*/
#define MAX_TAB_SIZE 600
/* Basic data Structures required a minTypMax table and its size */
typedef struct {
double typ, /* typical value */
min, /* minimum value */
max; /* maximum value */
} ibisTypMinMax_t, *ibisTypMinMax_Pt;
typedef struct VIentryDef {
double v;
ibisTypMinMax_t i;
} ibisVItableEntry_t, *ibisVItableEntry_Pt;
typedef struct {
int size;
ibisVItableEntry_Pt
VIs;
} ibisVItable_t, *ibisVItable_Pt;
/* The Kind of Spices that it can support */
char *spiceNameString[] =
{
"HSpice",
"PSpice",
"SPICE2",
"Spice3",
"Spectre",
"dummy"
};
/* The number of these */
#define NUM_SUPP_SPICE 6
/* It uses the following as the data begin marker i.e. these are present in
* the line before the data is actually displayed */
char *VIDataBeginMarker[] =
{
"transfer",
"DC TRANSFER",
"X",
"Index",
"Values",
"\n"
};
/* Stops reading with this */
char *dataEndMarker[] =
{
"job",
"",
"Y",
"CPU",
"",
"eof"
};
/* The data is assumed to be %le and is read as that */
char *VIDataConversionString[] =
{
"%le %le \n",
"%le %le \n",
"%le %le \n",
"%*d %le %le \n",
"%*d %le %*le %le \n",
"%le %le \n"
};
/* Maps the given input name to an integer corresponding to that name */
int
find_spice_type(char *spName)
{
int i;
for (i=0;i<NUM_SUPP_SPICE;i++)
if (!strcmp(spName,spiceNameString[i]))
return(i);
return(0);
}
/* reads the typ min max files and generates the data-structure */
int
getSpiceVIData( IN ibisVItable_Pt VIData_P,
IN int tableSize,
IN int spiceType,
IN char *spiceOutFile,
IN char *command )
{
FILE *outFile_P = NULL;
char lineBuffer[256];
double tempData[300][2];
int rowIndex = 1,i = 0;
if ( ( outFile_P = fopen( spiceOutFile, "r" ) ) == NULL )
{
fprintf( stderr, "Unable to open file %s for reading.\n",
spiceOutFile );
return( 1 );
}
/*------------------------------------------------------------------------
*
* Read lines until we hit the data begin marker or EOF. If it's EOF,
* return an error.
*
*-----------------------------------------------------------------------*/
while ( ( fgets( lineBuffer, 256, outFile_P ) != NULL ) &&
( strstr( lineBuffer, VIDataBeginMarker[spiceType] ) == NULL ) );
if ( strstr( lineBuffer, VIDataBeginMarker[spiceType] ) == NULL )
{
fprintf( stderr, "Data begin marker %s not found ",
VIDataBeginMarker[spiceType] );
fprintf( stderr, "in output file %s.\n", spiceOutFile );
return( 1 );
}
/*------------------------------------------------------------------------
*
* We're now at the line before the start of the VI data.
* Read lines until we get the correct number of columns.
*
*-----------------------------------------------------------------------*/
while ( ( fgets( lineBuffer, 256, outFile_P ) != NULL ) &&
( sscanf( lineBuffer, VIDataConversionString[spiceType],
&tempData[0][0], &tempData[0][1] ) != 2 ) );
if ( feof( outFile_P ) )
{
fprintf( stderr, "s2ibis2: No data in file %s\n", spiceOutFile );
return( 1 );
}
tempData[0][1] = -tempData[0][1];
/*------------------------------------------------------------------------
*
* Now we read until we see the end-of-data marker or the end-of-file
* marker. We include the data from any read that returns the correct
* number of columns read. If we don't have an end-of-data marker for
* this particular flavor of Spice, we just read to the end-of-file maker.
*
*-----------------------------------------------------------------------*/
if ( dataEndMarker[spiceType] == NULL )
{
while ( ( fgets( lineBuffer, 256, outFile_P ) != NULL ) )
if ( sscanf(lineBuffer, VIDataConversionString[spiceType],
&tempData[rowIndex][0], &tempData[rowIndex][1]) == 2 )
{
tempData[rowIndex][1] = -tempData[rowIndex][1];
rowIndex++;
}
}
else
{
while ( ( fgets( lineBuffer, 256, outFile_P ) != NULL ) &&
( strstr( lineBuffer, dataEndMarker[spiceType] ) == NULL ) )
if ( sscanf(lineBuffer, VIDataConversionString[spiceType],
&tempData[rowIndex][0], &tempData[rowIndex][1]) == 2 )
{
tempData[rowIndex][1] = -tempData[rowIndex][1];
rowIndex++;
}
}
fclose( outFile_P );
rowIndex--;
if ( rowIndex > tableSize )
{
fprintf( stderr, "s2ibis2: Spice job returned too many data points.\n" );
fprintf( stderr, " May have to truncate table...\n" );
}
/*------------------------------------------------------------------------
*
* Now we transfer the data to the correct place, depending on the value
* of command.
*
*-----------------------------------------------------------------------*/
if ( !( strcmp( command, "typ" ) ) )
{
VIData_P->size = rowIndex + 1;
/** Some way to create the size equivalent for the rowindex **/
if( (VIData_P->VIs = (ibisVItableEntry_Pt) \
malloc(sizeof(ibisVItableEntry_t) * VIData_P->size) ) == NULL)
{
printf("Out of memory");
return(1);
}
for ( i = 0; i <= rowIndex; i++ )
{
VIData_P->VIs[i].v = tempData[i][0];
VIData_P->VIs[i].i.typ = tempData[i][1];
}
}
else if ( !( strcmp( command, "min" ) ) )
for ( i = 0; i <= rowIndex; i++ )
VIData_P->VIs[i].i.min = tempData[i][1];
else
for ( i = 0; i <= rowIndex; i++ )
VIData_P->VIs[i].i.max = tempData[i][1];
return( 0 );
}
/* Does the final write into the Outfile of the Data Structure generated
* earlier by getSpiceVIData function */
int writeSpiceVIData(IN char* Outfile, IN ibisVItable_Pt VIData_P)
{
FILE * outFile_P;
int j = 0;
if ( ( outFile_P = fopen( Outfile, "w" ) ) == NULL )
{
fprintf( stderr, "Unable to open file %s for writing.\n",
outFile_P );
perror( "s2ibis2");
return( 1 );
}
printf("%s Generated by program\n",Outfile);
fprintf(outFile_P,"| Voltage\t I(typ)\t I(min)\t I(max)\n");
for(j = 0 ;j < VIData_P->size;j++)
fprintf(outFile_P,"%le %le %le %le\n",VIData_P->VIs[j].v, \
VIData_P->VIs[j].i.typ, \
VIData_P->VIs[j].i.min,VIData_P->VIs[j].i.max);
fclose(outFile_P);
}
int
main(int argc,char* argv[])
{
/* Take the input and call get Spice VI Data in proper order
to get all the data required and then print quietly */
ibisVItable_Pt VIData_P ;
int spiceType;
if (argc<2)
{
printf("Usage %s <spiceType> <typFl> <minFl> <maxFl> <opFl>\n",argv[0]);
return(1);
}
spiceType = find_spice_type(argv[1]);
getSpiceVIData(VIData_P,MAX_TAB_SIZE,spiceType,argv[2],"typ");
getSpiceVIData(VIData_P,VIData_P->size,spiceType,argv[3],"min");
getSpiceVIData(VIData_P,VIData_P->size,spiceType,argv[4],"max");
writeSpiceVIData(argv[5],VIData_P);
}
Received on Fri Dec 11 00:11:44 1998
This archive was generated by hypermail 2.1.8 : Fri Jun 03 2011 - 09:53:46 PDT