From 37e0f58473b0ce7dc9015285cc7a7e163799d3c1 Mon Sep 17 00:00:00 2001 From: Ludovic Jacomme Date: Sun, 23 May 2004 14:20:32 +0000 Subject: [PATCH] - New small tool that can be helpfull to convert pat files to equivalent PWL spice commands --- alliance/src/pat2spi/Makefile.am | 1 + alliance/src/pat2spi/configure.in | 35 ++ alliance/src/pat2spi/man1/Makefile.am | 2 + alliance/src/pat2spi/man1/pat2spi.1 | 37 ++ alliance/src/pat2spi/src/Makefile.am | 11 + alliance/src/pat2spi/src/pat2spi.c | 558 ++++++++++++++++++++++++++ alliance/src/pat2spi/src/pat2spi.h | 65 +++ 7 files changed, 709 insertions(+) create mode 100644 alliance/src/pat2spi/Makefile.am create mode 100644 alliance/src/pat2spi/configure.in create mode 100644 alliance/src/pat2spi/man1/Makefile.am create mode 100644 alliance/src/pat2spi/man1/pat2spi.1 create mode 100644 alliance/src/pat2spi/src/Makefile.am create mode 100644 alliance/src/pat2spi/src/pat2spi.c create mode 100644 alliance/src/pat2spi/src/pat2spi.h diff --git a/alliance/src/pat2spi/Makefile.am b/alliance/src/pat2spi/Makefile.am new file mode 100644 index 00000000..5fcaa0d3 --- /dev/null +++ b/alliance/src/pat2spi/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src man1 diff --git a/alliance/src/pat2spi/configure.in b/alliance/src/pat2spi/configure.in new file mode 100644 index 00000000..ce049458 --- /dev/null +++ b/alliance/src/pat2spi/configure.in @@ -0,0 +1,35 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/pat2spi.c) + +PAT2SPI_MAJOR_VERSION=1 +PAT2SPI_MINOR_VERSION=1 +PAT2SPI_VERSION=$PAT2SPI_MAJOR_VERSION.$PAT2SPI_MINOR_VERSION + +AC_SUBST(PAT2SPI_MAJOR_VERSION) +AC_SUBST(PAT2SPI_MINOR_VERSION) +AC_SUBST(PAT2SPI_VERSION) + +# For automake. +VERSION=$PAT2SPI_VERSION +PACKAGE=pat2spi + +dnl Initialize automake stuff +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +dnl Checks for programs. +AC_PROG_CC +AM_PROG_LEX +AC_PROG_YACC +AM_PROG_LIBTOOL +AC_PROG_MAKE_SET + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +man1/Makefile +src/Makefile +]) diff --git a/alliance/src/pat2spi/man1/Makefile.am b/alliance/src/pat2spi/man1/Makefile.am new file mode 100644 index 00000000..6585b8d3 --- /dev/null +++ b/alliance/src/pat2spi/man1/Makefile.am @@ -0,0 +1,2 @@ +man_MANS = pat2spi.1 +EXTRA_DIST = $(man_MANS) diff --git a/alliance/src/pat2spi/man1/pat2spi.1 b/alliance/src/pat2spi/man1/pat2spi.1 new file mode 100644 index 00000000..1a02b6e5 --- /dev/null +++ b/alliance/src/pat2spi/man1/pat2spi.1 @@ -0,0 +1,37 @@ +.TH PAT2SPI 1 "May 23, 2004" "ASIM/LIP6" "CAO\-VLSI Reference Manual" +.SH NAME +.PP +\fIpat2spi\fP, PAT ALLIANCE format translator to Spice PWL format + +.so man1/alc_origin.1 +.SH SYNOPSIS +.PP +\fBpat2spi\fP +[ +.I -slope natural_value +] +.I In_filename +.I Out_filename + +.SH DESCRIPTION +.PP +\fBpat2spi\fP is a translator from ALLIANCE pattern format (\fI".pat"\fP) +to spice PWL format (\fI".spi"\fP). An optional slope parameter can be used to specify +the slope value in pico second. + +.SH EXAMPLE +.br +Converts adder4.pat using PWL commands and generates the file spice_pattern.spi +(that could be used in a SPICE testbench for example). + +.PP +.ti 7 +pat2spi -slope 100 adder4 spice_pattern + +.SH SEE ALSO +.PP +asimut(1), pat(5) + + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/pat2spi/src/Makefile.am b/alliance/src/pat2spi/src/Makefile.am new file mode 100644 index 00000000..e238ea0d --- /dev/null +++ b/alliance/src/pat2spi/src/Makefile.am @@ -0,0 +1,11 @@ +## Process this file with automake to produce Makefile.in + +bin_PROGRAMS = pat2spi + +AM_CFLAGS = @ALLIANCE_CFLAGS@ + +pat2spi_LDADD = @ALLIANCE_LIBS@ \ + -lPpt -lPhl -lPat -lAut -lMut + + +pat2spi_SOURCES = pat2spi.c pat2spi.h diff --git a/alliance/src/pat2spi/src/pat2spi.c b/alliance/src/pat2spi/src/pat2spi.c new file mode 100644 index 00000000..f3be066b --- /dev/null +++ b/alliance/src/pat2spi/src/pat2spi.c @@ -0,0 +1,558 @@ +/*------------------------------------------------------------\ +| | +| Tool : PAT2SPI | +| | +| File : pat2spi.c | +| | +| Authors : Jacomme Ludovic | +| | +| Date : 10.08.02 | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Include Files | +| | +\------------------------------------------------------------*/ + +# include +# include +# include +# include +# include +# include "mut.h" +# include "aut.h" +# include "pat.h" +# include "ppt.h" + +# include "pat2spi.h" + +/*------------------------------------------------------------\ +| | +| Constants | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Types | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Variables | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| pat_addpatfig | +| | +\------------------------------------------------------------*/ + +patfig_list *pat_addpatfig( paseq_list *Sequence ) +{ + patfig_list *FigurePat; + char **ModeArray; + char **NameArray; + char *FormatArray; + long *WidthArray; + char *ScanBuffer; + + char Buffer[ 4096 ]; + char Name [ 512 ]; + char Format; + int Left; + int Right; + char *Direction; + char *Mode; + + long NumberIO; + long NumberBit; + long IndexBit; + + char TimeUnit; + unsigned long TimeScale; + unsigned long TimeDelta; + unsigned long Delta; + unsigned long TimeCurrent; + unsigned long TimeNext; + char TimeAllZero; + + paiol_list *ScanIol; + pagrp_list *ScanGrp; + papat_list *ScanPaPat; + + FigurePat = (patfig_list *)autallocblock( sizeof( patfig_list ) ); + + NumberBit = Sequence->IOLNBR; + ScanGrp = Sequence->PAGRP; + + ScanIol = Sequence->PAIOL; + + NameArray = (char **)autallocblock( sizeof( char * ) * NumberBit ); + FormatArray = (char *)autallocblock( sizeof( char ) * NumberBit ); + ModeArray = (char **)autallocblock( sizeof( char * ) * NumberBit ); + WidthArray = (long *)autallocblock( sizeof( long ) * NumberBit ); + + NumberIO = 0; + IndexBit = 0; + + while ( ScanIol != (paiol_list *)0 ) + { + switch ( ScanIol->MODE) + { + case 'I': Mode = "in"; + break; + case 'O': + case 'B': + case 'Z': Mode = "out"; + break; + case 'R': Mode = "register"; + break; + case 'T': Mode = "inout"; + break; + case 'S': + case 'W': + case 'X': + case 'U': Mode = "signal"; + break; + } + + Format = ScanIol->FORMAT; + +# ifdef DEBUG + if ( ScanGrp != (pagrp_list *)0 ) + { + fprintf( stdout, "ScanGrp %s %d %d %d\n", + ScanGrp->NAME, ScanGrp->FINDEX, ScanGrp->LENGTH, ScanGrp->FLAG ); + } +# endif + + if ( ( ScanGrp != (pagrp_list *)0 ) && + ( IndexBit == ScanGrp->FINDEX ) ) + { + if ( Format == 'B' ) Format = 'X'; + /* + if ( ScanIol->FORMAT != 'B' ) + */ + { + if ( ! ScanGrp->FLAG ) + { + sscanf( ScanIol->NAME, "%s %d", Name, &Left ); + + ScanIol += ScanGrp->LENGTH - 1; + IndexBit += ScanGrp->LENGTH; + + sscanf( ScanIol->NAME, "%s %d", Name, &Right ); + + if ( Left < Right ) Direction = "to"; + else Direction = "downto"; + + sprintf( Buffer, "%s (%d %s %d) %c", Name, Left, Direction, Right, Format ); + +# ifdef DEBUG + fprintf( stdout, "ICI %s\n", Buffer ); +# endif + ScanIol = ScanIol->NEXT; + } + else + { +# ifdef DEBUG + fprintf( stdout, "NAME %s\n", ScanGrp->NAME ); +# endif + + ScanBuffer = Buffer; + strcpy( ScanBuffer, ScanGrp->NAME ); + ScanBuffer += strlen( ScanBuffer ); + strcpy( ScanBuffer, " (" ); + ScanBuffer += 2; + + for ( Left = 0; Left < ScanGrp->LENGTH; Left++ ) + { +# ifdef DEBUG + fprintf( stdout, "IOLNAME %s\n", ScanIol->NAME ); +# endif + strcpy( ScanBuffer, ScanIol->NAME ); + ScanBuffer += strlen( ScanBuffer ); + + if ( Left != (ScanGrp->LENGTH - 1) ) + { + strcpy( ScanBuffer, ", " ); + ScanBuffer += 2; + } + + ScanIol = ScanIol->NEXT; + } + + strcpy( ScanBuffer, ")" ); + IndexBit += ScanGrp->LENGTH; +# ifdef DEBUG + fprintf( stdout, "Buffer %s\n", Buffer ); +# endif + } + + NameArray [ NumberIO ] = autnamealloc( Buffer ); + ModeArray [ NumberIO ] = autnamealloc( Mode ); + FormatArray[ NumberIO ] = Format; + WidthArray [ NumberIO ] = ScanGrp->LENGTH; + NumberIO = NumberIO + 1; + + ScanGrp = ScanGrp->NEXT; + + continue; + } + } + + NameArray [ NumberIO ] = ScanIol->NAME; + FormatArray[ NumberIO ] = Format; + ModeArray [ NumberIO ] = autnamealloc( Mode ); + WidthArray [ NumberIO ] = 1; + NumberIO = NumberIO + 1; + + ScanIol = ScanIol->NEXT; + IndexBit = IndexBit + 1; + } + + FigurePat->NAME = Sequence->NAME; + FigurePat->SEQUENCE = Sequence; + FigurePat->IO_NUMBER_BIT = NumberBit; + FigurePat->IO_NUMBER = NumberIO; + FigurePat->IO_NAME_ARRAY = NameArray; + FigurePat->IO_MODE_ARRAY = ModeArray; + FigurePat->IO_FORMAT_ARRAY = FormatArray; + FigurePat->IO_WIDTH_ARRAY = WidthArray; + + switch ( Sequence->TIME_UNIT & PAT_SEQ__TIMEUNIT ) + { + case PAT_TU__FS : TimeScale = 1000000000; + TimeUnit = PAT_TU__US; + break; + case PAT_TU__PS : TimeScale = 1000000000; + TimeUnit = PAT_TU__MS; + break; + case PAT_TU__NS : TimeScale = 1000000; + TimeUnit = PAT_TU__MS; + break; + case PAT_TU__US : TimeScale = 1000; + TimeUnit = PAT_TU__MS; + break; + default : TimeScale = 1; + TimeUnit = Sequence->TIME_UNIT; + break; + } + + TimeDelta = 0; + +# ifdef DEBUG + fprintf( stdout, "PAT_TIMEUNIT %d\n", PAT_TIMEUNIT ); +# endif + + if ( ( Sequence->TIME_UNIT & PAT_SEQ__TIMEUNIT ) != PAT_TU__VU ) + { + for ( ScanPaPat = Sequence->CURPAT; + ScanPaPat != (papat_list *)0; + ScanPaPat = ScanPaPat->NEXT ) + { +# ifdef DEBUG + fprintf( stdout, "%ld\n", ScanPaPat->TIME ); +# endif + if ( ScanPaPat->TIME != 0 ) TimeAllZero = 0; + + if ( ScanPaPat->NEXT != (papat_list *)0 ) + { + Delta = ScanPaPat->NEXT->TIME - ScanPaPat->TIME; + + if ( ( TimeDelta == 0 ) || + ( TimeDelta > Delta ) ) + { + TimeDelta = Delta; + } + } + + while ( ( TimeScale != 1 ) && + ( ( ScanPaPat->TIME % TimeScale ) != 0 ) ) + { + TimeScale /= 1000; + TimeUnit--; + } + } + + TimeDelta /= TimeScale; + + if ( TimeDelta == 0 ) TimeDelta = 1; + } + else + { + TimeUnit = Sequence->TIME_UNIT; + TimeScale = 1; + TimeDelta = 1; + } + +# ifdef DEBUG + fprintf( stdout, "TIME_UNIT %ld\n", TimeUnit ); + fprintf( stdout, "TIME_SCALE %ld\n", TimeScale ); + fprintf( stdout, "TIME_DELTA %ld\n", TimeDelta ); +# endif + + FigurePat->TIME_UNIT = TimeUnit; + FigurePat->TIME_SCALE = TimeScale; + FigurePat->TIME_DELTA = TimeDelta; + + return( FigurePat ); +} + +/*------------------------------------------------------------\ +| | +| P2Sloadpatfig | +| | +\------------------------------------------------------------*/ + +patfig_list *P2Sloadpatfig( char *FileName ) +{ + paseq_list *Sequence; + + Sequence = pat_lodpaseq( FileName, (paseq_list *)0, 0, 0 ); + + if ( Sequence == (paseq_list *)0 ) + { + autexit( 1 ); + } + + return( pat_addpatfig( Sequence ) ); +} + +/*------------------------------------------------------------\ +| | +| P2Sgetvectorname | +| | +\------------------------------------------------------------*/ + +static char *P2Sgetvectorname( char *name ) +{ + char *new_name; + char *blank; + unsigned int length; + unsigned int pos_blank; + + if ( name != (char *)0 ) + { + blank = strchr( name, ' ' ); + if ( blank != (char *)0 ) + { + length = strlen( name ); + pos_blank = blank - name; + new_name = (char *)mbkalloc( (length + 2) * sizeof(char) ); + strcpy(new_name, name); + new_name[ pos_blank ] = '['; + new_name[ length ] = ']'; + new_name[ length + 1] = '\0'; + + name = namealloc( new_name ); + mbkfree( new_name ); + } + } + + return( name ); +} + +/*------------------------------------------------------------\ +| | +| P2Sdrivepatfig | +| | +\------------------------------------------------------------*/ + +void P2Sdrivepatfig( patfig_list *PatFigure, char *FileName, long Slope ) +{ + paseq_list *PaSeq; + papat_list *PaPat; + paevt_list *PaEvt; + paiol_list *PaIol; + char CurrentEvent; + char NextEvent; + char Event; + char FirstTime; + long NumberBit; + long CurrentBit; + char *TimeUnitName; + char *IolName; + FILE *File; + + unsigned long CurrentTime; + unsigned long NextTime; + + NumberBit = PatFigure->IO_NUMBER_BIT; + PaSeq = PatFigure->SEQUENCE; + + File = mbkfopen( FileName, "spi", "w" ); + + if ( File == (FILE *)0 ) + { + fprintf( stdout, "Unable to open output file %s.spi\n", FileName ); + autexit( 1 ); + } + + CurrentBit = 0; + + switch ( PaSeq->TIME_UNIT & PAT_SEQ__TIMEUNIT ) + { + case PAT_TU__FS : TimeUnitName = "FS"; + break; + case PAT_TU__PS : TimeUnitName = "PS"; + break; + case PAT_TU__NS : TimeUnitName = "NS"; + break; + case PAT_TU__US : TimeUnitName = "US"; + break; + default : TimeUnitName = "NS"; + break; + } + + for ( CurrentBit = 0; CurrentBit < NumberBit; CurrentBit++ ) + { + NextEvent = '*'; + CurrentEvent = '*'; + FirstTime = 1; + + PaIol = &PaSeq->PAIOL[ CurrentBit ]; + + if ( ( PaIol->MODE != 'I' ) && + ( PaIol->MODE != 'T' ) ) continue; + + IolName = P2Sgetvectorname( PaIol->NAME ); + + if ( isvss( IolName ) || + isvdd( IolName ) ) continue; + + for ( PaPat = PaSeq->CURPAT; + PaPat != (papat_list *)0; + PaPat = PaPat->NEXT ) + { + CurrentTime = PaPat->TIME; + + if ( PaPat->NEXT != (papat_list *)0 ) + { + NextTime = PaPat->NEXT->TIME; + } + else + { + NextTime = CurrentTime + Slope; + } + + if ( ! FirstTime ) + { + CurrentEvent = NextEvent; + } + + for ( PaEvt = PaPat->PAEVT; + PaEvt != (paevt_list *)0; + PaEvt = PaEvt->NEXT ) + { + if ( PaEvt->INDEX != CurrentBit ) continue; + + Event = PaEvt->USRVAL; + + if ( Event == '-' ) Event = '0'; + else + if ( Event == '+' ) Event = '1'; + + NextEvent = Event; break; + } + + if ( FirstTime ) + { + FirstTime = 0; + CurrentEvent = NextEvent; + + fprintf( File, "vinput%ld %s 0 PWL (\n", CurrentBit, IolName ); + fprintf( File, "+ %ld%s %s %ld%s %s\n", + CurrentTime , TimeUnitName, + (( CurrentEvent == '0' ) ? "LOW" : "HIGH"), + CurrentTime + Slope, TimeUnitName, + (( CurrentEvent == '0' ) ? "LOW" : "HIGH") ); + + } + else + if ( PaEvt != (paevt_list *)0 ) + { + fprintf( File, "+ %ld%s %s %ld%s %s\n", + CurrentTime , TimeUnitName, + (( CurrentEvent == '0' ) ? "LOW" : "HIGH"), + CurrentTime + Slope, TimeUnitName, + (( NextEvent == '0' ) ? "LOW" : "HIGH") ); + } + } + + if ( ! FirstTime ) + { + fprintf( File, "+ )\n\n" ); + } + } + + fclose( File ); + + fprintf( stdout, "\t o final time %ld ps\n", CurrentTime ); +} + +/*------------------------------------------------------------\ +| | +| main | +| | +\------------------------------------------------------------*/ + +void P2Ssyntax() +{ + fprintf( stdout, "\tSyntax: pat2spi [-slope natural] in_file out_file\n" ); + autexit( 1 ); +} + +int main( int argc, char **argv ) +{ + patfig_list *PatFigure; + char *InputName; + char *OutputName; + long Slope; + long Number; + + mbkenv(); + + InputName = (char *)0; + OutputName = (char *)0; + Slope = -1; + + alliancebanner ("pat2spi", "1.0", "PAT Format Translator", "2002", ALLIANCE_VERSION); + + if ( argc < 3 ) P2Ssyntax(); + + for ( Number = 1; + Number < argc; + Number++ ) + { + if ( ! strcmp( argv[ Number ], "-slope" )) + { + Slope = atol( argv[ ++Number ] ); + if ( Slope <= 0 ) P2Ssyntax(); + } + else + if ( InputName == (char *)0 ) InputName = argv[ Number ]; + else + if ( OutputName == (char *)0 ) OutputName = argv[ Number ]; + else + P2Ssyntax(); + } + + fprintf( stdout, "\t--> Loading pat file %s\n", InputName ); + PatFigure = P2Sloadpatfig( InputName ); + + if ( Slope == -1 ) + { + fprintf( stdout, "\t o Use a default slope of 1000 ps\n" ); + } + else + { + fprintf( stdout, "\t o Use a user slope of %ld ps\n", Slope ); + } + + fprintf( stdout, "\t--> Driving spi file %s\n", OutputName ); + P2Sdrivepatfig( PatFigure, OutputName, Slope ); + + return( 0 ); +} diff --git a/alliance/src/pat2spi/src/pat2spi.h b/alliance/src/pat2spi/src/pat2spi.h new file mode 100644 index 00000000..ef96e4d4 --- /dev/null +++ b/alliance/src/pat2spi/src/pat2spi.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------\ +| | +| Tool : Pat2Spi | +| | +| File : pat2spi.h | +| | +| Authors : Jacomme Ludovic | +| | +| Date : 10.08.02 | +| | +\------------------------------------------------------------*/ + +# ifndef PAT2SPI_H +# define PAT2SPI_H + +/*------------------------------------------------------------\ +| | +| Constants | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Macros | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Types | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Pattern Figure | +| | +\------------------------------------------------------------*/ + + typedef struct patfig_list + { + struct patfig_list *NEXT; + char *NAME; + char **IO_NAME_ARRAY; + char **IO_MODE_ARRAY; + char *IO_FORMAT_ARRAY; + long *IO_WIDTH_ARRAY; + long IO_NUMBER; + long IO_NUMBER_BIT; + paseq_list *SEQUENCE; + unsigned long TIME_SCALE; + unsigned long TIME_DELTA; + char TIME_UNIT; + + } patfig_list; + +/*------------------------------------------------------------\ +| | +| Variables | +| | +\------------------------------------------------------------*/ +/*------------------------------------------------------------\ +| | +| Functions | +| | +\------------------------------------------------------------*/ + +# endif