⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svf2vme.c

📁 在嵌入式系统中对Lattice CPLD软件升级时所需的VME文件生成所需源代码。将一个链上的不同厂家的CPLD产生的SVF文件转换成VME文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************
*       Copyright, 2000-2003 Lattice Semiconductor Corp.                *
*                               SVF2VME.c                               *
*       This Program Converts An SVF File From ASCII Source Form Into   *
*       Binary Form To Reduce Size And To Improve Processing Time.      *
*                                                                       *
*       The conversion is done by converting Token into 8 bits Code.    *
*       The 8 bits Token are always followed by 16 bits field.          * 
*       Some 8 bits Token has data field follows the 16 bits field.     *
*       SDI MASK is not supported due to its rare appearence on ISP     *
*       application.                                                    *
*       The data field follows the SDR token are compressed when 0x00   *
*       or 0xFF bytes are detected. The compression is done by replacing*
*       0xFF, 0xFF, 0xFF by 0xFF, 0x02 etc.                             *
*       Single level Huffman encoding scheme is used to compress the    *
*       data and compare with the result produced above. The winner is  *
*       is used to compress the data.                                   *
*       Compression is done on row by row bases.                        *
*       The RUNTEST Token is followed by a 16 bits field express in     *
*       uS if the most significant bit is 0, in mS if the most          *
*       significant bit is 1.                                           *
*       The FREQUENCY Token is followed by a 16 bits field express in   *
*       KHZ if the most significant bit is 0, in MHZ if the most        *
*       significant bit is 1.                                           *
*                                                                       *
* Note: This program must be compiled as a 32 bits application if the   *
*       SVF file is known to contain more than more than 64000 bits     *
*       in a single scan.                                               *
* The VME filetype code is __VME1.0                                     *
* Howard Tang  08/08/98  Convert from svfdvr.c                          * 
* Howard Tang  02/02/00  Update per new marketing requirement for market*
*                        launch of ispVM Embedded.                      *
* Howard Tang  05/30/00  Accept no space between TDx and (, xMASK and ( *
* Howard Tang  09/27/00  Replace tap with blank for simpler processing  *
*                        Accept STATE RESET IDLE IRPAUSE DRPAUSE        *
*                        multiple state construct.                      *
* Howard Tang  12/19/00  If the last char is already a \n, then read    *
*                        a new line.                                    *
* Howard Tang  01/02/01  Fix the splitting long SDR data stream problem.*                       
* Howard Tang  04/26/01  Support Non zero HIR, HDR, TIR and TDR.        *
* Howard Tang  08/28/01  Change to VME1.1 format:                       *
*                         - The number is cascaded.                     *
*                         - Turn on/off the SDR cascading when force    *
*                           splitting occur.                            *
*                         - Add support to FLOW opcode which shall      *
*                           alter from the continue while pass to       *
*                           stop if pass.                               *
* Howard Tang  10/02/01  Minimize file size by using repeat looping     *
*                        feature.                                       *
* tnt		   12/03/01  Added SECUREHEAP opcode to maintain file       *
*                        integrity when inserting the heapsize          *
* tnt          12/03/01  Added switch to indicate foreign devices       *
* tnt           1/07/01  Change to VME2.0								*
* tnt			9/30/02	 Update to accept other vendor names.  If       *
*						 the vendor is not Altera or Xilinx, then       *
*						 default to Lattice.							*
* tnt		   10/19/02  Added fix to compressToIspStream for 5512VE    *
* tnt		   10/21/02  Support frequency option at command line       *
* tnt		   4/7/03    Change version number to VME 2.0.1. Note:      *
*						 the internal version number will still be 2.0  *
*						 in order for the decoder to accept files       *
*						 generated with this version.                   *
*                        Changes include:								*
*                        1) In STATECom function, if a long state is    *
*							given, return failure.                      *
*                        2) Change the variables MaxSize and scan_len   *
*                           to unsigned long for easier porting to      *
*                           16-bit.										*
* 4/28/03 Update to v2.1.  v2.1 supports Continue If Fail (USERCODE     *
*         Verification).  Also updated the command line syntax and      *
*         usage.                                                        *
* 2/11/04	Update to v2.1.1.  Remove IEEE 1532 support.                *
*                                                                       *
*************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include "vmopcode.h"
#include "svf2loopsvf.h"
#include "Utilities.h"
#include "UESVerify.h"
#include "SVF2VME.h"

FILE *fp, *fpw;
unsigned char  buffer[strmax];   /*memory to store a string temporary          */
unsigned char  *SVF_string;   /*pointer to current token string*/
unsigned int allocateFlag;  /*variable to determine if we allocate memory for numBitArray*/
long int frequency = 0;
int svfline = 0;            /*keeps the svfline number read*/
int *numBitArray = NULL;			/*keeps track of the bits in repeat loops */
int globalBitArrayCounter = 0;  /*counter used in numBitArray*/
int headIR = 0, tailIR = 0, headDR = 0, tailDR = 0;
int CurEndDR = DRPAUSE, CurEndIR = IRPAUSE;
long int MaxSize = 0;            /*the maximum row size of all the SVF files*/
char pass=0;                /*to keep track of the passes of the current attempt*/

/* Variables used in programming foreign devices */
int vendor = 0;
unsigned char* SDRMask = NULL;
unsigned char* SIRMask = NULL;
int previousSIRbits = 0;
int previousSDRbits = 0;

static struct stableState 
{
	char * text;
	int state;
} stableStates[ StableStateMax ] = {
	{ "RESET", RESET },
	{ "IDLE", IDLE },
	{ "IRPAUSE", IRPAUSE },
	{ "DRPAUSE", DRPAUSE }
};

static struct scanToken 
{
	char *text;
	int token;
} scanTokens[] = 
{
 /*opcode share with ispVM and SVF2VME */
 {";", ENDDATA},
 {"SIR", SIR},{"SDR", SDR},
 {"TDI", TDI},{"TDO", TDO},{"MASK", MASK},
 {"STATE", STATE},
 {"TCK", TCK,}, {"WAIT", WAIT},
 {"XSDR", XSDR},{"XTDI", XTDI},{"XTDO", XTDO},  /*opcode for ispVM only*/
 {"ENDDR", ENDDR},
 {"ENDIR", ENDIR},
 {"HIR", HIR},{"TIR", TIR},{"HDR", HDR},{"TDR", TDR},
 {"MEM", MEM},                                /*opcode for ispVM only*/
  /*opcode exist only in SVF files and is for SVF2VME only*/
 {"RUNTEST", RUNTEST},
 {"ENDSTATE", ENDSTATE},
 {"TRST", TRST},
 {"FREQUENCY", FREQUENCY},
 {"SEC", SEC},
 {"SMASK", SMASK},
 {"MAXIMUM", MAX},
 {"ON", ON},{"OFF", OFF},
 {"SETFLOW",SETFLOW},{"RESETFLOW",RESETFLOW},
 {"REPEAT",REPEAT},{"ENDLOOP",ENDLOOP},
 {"(", LEFTPAREN}, 
 /* 05/27/03 Nguyen added to support Dynamic IO */
 {"DMASK",DMASK},
 {"VUES", VUES}
};

int ScanTokenMax = sizeof( scanTokens ) / sizeof( scanTokens[ 0 ] );

/* 3 scan nodes is reserved:
   0 is for SIR, 1 is for SDR and 2 is to store previous SDR */ 
/* 4/26/2001 ht Add 1 scan nodes to store the HIR,TIR,HDR and TDR info */
struct scanNode 
{
 long int numbits;
 unsigned char *tdi;
 unsigned char *tdo;
 unsigned char *mask;
 /* 05/27/03 Nguyen added to support Dynamic IO */
 unsigned char *dmask;

} scanNodes[4] = {{0, NULL, NULL, NULL, NULL },
{0, NULL, NULL, NULL, NULL },
{0, NULL, NULL, NULL, NULL },
{0, NULL, NULL, NULL, NULL },
};

CFG * cfgChain = NULL;

/* Variables used in looping */
extern int iLoopVMEOption;
extern int shiftsize;
extern int iLoopIndex;
extern int totalbytecount;
extern int ** Repeat;
extern int * PatternNumArray;
extern int ** SDRValueArray;
extern int heapsize;
extern unsigned int inRepeat;

/*************************************************************************
*                                                                        *
*              Convert Number to VME format                              *
*                                                                        *
* A large number is converted into cascading of bytes                    *
* If the most significant bit of a byte is 0, then                       *
* it is the last byte to form the number.                                *
* Input:                                                                 *
* number-----the decimal number to be converted                          *
* fpw------write the converted number into it                            *
* Return:                                                                *
* the number of bytes the number is converted into.                      *       
*                                                                        *
*************************************************************************/
int ConvNumber( long int number )
{
	int byte_cnt = 0;
	while ( number > 0x007F ) {
		byte_cnt++;
        write( ( number & 0x007F ) + 0x0080 );
        number = number >> 7;
	}
	
	write( ( unsigned char ) number );
	byte_cnt++;
	return( byte_cnt );
}
        


/*************************************************************************
* Token()                                                                *
* return a token when it is called. Comments are discarded.              *
* To make the parser more flexible, space is inserted between the        *
* following delimiters. If there are space there already, additional     *
* space is added which will be discarded when strtok is used.            *
* ';'                                                                    *
* Var:                                                                   *
* global fp--the current svfplus file pointer.                           *
*        buffer--the temporary storage of the string                     *
* out    SVF_string--the token obtained.                                 *
* return 1 when EOF else 0.                                              *
**************************************************************************/
int Token( const char * delimiters )
{
	int i, j, length;
	if ( ( SVF_string == NULL ) || ( ( SVF_string = strtok( NULL, delimiters ) ) == NULL ) ||
		  ( SVF_string[ 0 ] == '!' ) || ( SVF_string[ 0 ] == '/' ) ||
		  ( SVF_string[ 0 ] == '\n' )  /*12/19/00 ht read a new line*/ ) {
		do {
			if ( fgets( buffer, strmax, fp ) == NULL ) {
				return ( 1 );
			}
			
			length = strlen( buffer ) + 1;
			if ( length > 2 ) {
				for ( i = 0; i < length; i++ ) {
					switch ( buffer[ i ] ) {
					case '\t': 
						/* Replace tab with space */
						buffer[ i ] = ' '; /*9/27/00 ht*/
						break;
					case '\r': 
						/* Replace carriage return with space */
						buffer[ i ] = ' ';
						break;
					case ';' :
					case '(' :
					case ')' :
						for ( j = length + 2; j > i + 2; j-- ) {
							buffer[ j ] = buffer[ j - 2 ];
						}
						buffer[ j-- ] = ' ';   /*space at i + 2*/
						buffer[ j-- ] = buffer[ i ]; /*shift left 1*/
						buffer[ i ] = ' ';     /*space at i*/
						length += 2;        /*real length*/
						i += 2;             /*2 space added*/
						break;
					default :
						break;
					}
				}
			}
			
			SVF_string = strtok( buffer, delimiters ); /* Get the first token */
			svfline++;  /* Update the line number */
		} while ( ( SVF_string == NULL ) || ( SVF_string[ 0 ] == '!' ) ||
				  ( SVF_string[ 0 ] == '/' ) || ( SVF_string[ 0 ] == '\r' ) );  /* Ignore comments */
    }
	
	return( 0 );  /* Not yet end of file */
}


/*************************************************************************
* ispsvf_convert()                                                       *
* Read the svf file line by line and convert line by line into a token   *
* based ispSTREAM file:                                                  *
* FIELD:  token  :size    :   data                                       *
* WIDTH:  8 bits :16 bits :   variable(in binary)                        *
* 8/28/01 define options:                                                *
*          bit 0: no compress is 0, comression is 1.                     *
*          bit 1: stop if fail is 0, stop if pass is 1.                  *
*************************************************************************/
short int ispsvf_convert( int chips, CFG * chain, char * vmefilename, char options )
{
	short int  i, j, rcode = 0;
	int device;
	char filler = 0;
	long int scan_len;
	int arrayCounter;
	char opcode;
	unsigned char *dataptr;
	int numOfRepeats = 0;
	int *heapSizeArray = 0;
	char* ispJTAG;
	int temp;
	char xchar;
	
	static struct header 
	{
		unsigned char types;
		int           value;
	} headers[ 4 ] = { { TDR, 0 }, { TIR, 0 }, { HDR, 0 }, { HIR, 0 } };
	
	if ( ( fpw = fopen( vmefilename, "wb" ) ) == NULL ) {
		return FILE_NOT_FOUND;
	}
	
	ispJTAG = "__VME2.0";
	fprintf( fpw, ispJTAG );   /*ispJTAG filetype*/
	totalbytecount += strlen( ispJTAG );
	
	if ( options & 0x01 ) {
		write( 0xF1 ); /*F1: the Full VME File */
	}
	else  {
		write( 0xF2 ); /*F2: the compress VME File */
	}
	
	write( MEM );     /*the memory size token*/
	ConvNumber( MaxSize );
	
	/* if looping VME */
	if (iLoopVMEOption) {
		/* Count the total number of loops for all devices*/
		for (i = 0; i < iLoopIndex; i++) {
			for (j= 0; j < PatternNumArray[i]; j++) {
				numOfRepeats += Repeat[i][j];
			}
		}
		
		/* allocate space to store the size (in bytes) of each iLoopVMEOption */
		if (numOfRepeats) {
			heapSizeArray = (int*)calloc(numOfRepeats, sizeof(int));
			numOfRepeats = 0 ;
		}
	}
	
	for (device = 0; device < chips; device++) {
		rcode = 0;
		iLoopIndex = device; 

		/* set vendor */
		write(VENDOR);
		if (!stricmp(chain[device].Vendor, "lattice")) {
			vendor = LATTICE;
			write(LATTICE);
		}
		else if (!stricmp(chain[device].Vendor, "altera")) {
			vendor = ALTERA;
			write(ALTERA);
		}
		else if (!stricmp(chain[device].Vendor, "xilinx")) {
			vendor = XILINX;
			write(XILINX);
		}
		
		if (stricmp(chain[device].name, "SVF") == 0) {    
			if ((fp = fopen(chain[device].Svffile, "r")) == NULL) {
				return FILE_NOT_FOUND;
			}
			
			/*get the frequency setting in the structure*/
			if (strchr(chain[device].Frequency, 'k'))   /*frequency specified in KHZ*/
				frequency = atoi(chain[device].Frequency);
			else if (strchr(chain[device].Frequency, 'm')) /*frequency specified in MHZ*/
				frequency =(atoi(chain[device].Frequency))*1000; /*convert to KHZ*/
			else 
				frequency = 0;    /*it is default into 1MHZ*/
			
			if (chips > 1) {
				/* Multiple devices chain found */
				for (i = 0; i < 4; i++) {
					headers[i].value = 0;
				}

				for (i = 0; i < device; i++) {
					/*calculate the Trailer stream*/
					headers[0].value += 1;
					headers[1].value += chain[i].inst;
				}

				for (i = device + 1; i < chips; i++) {
					/*calculate the Header stream*/
					headers[2].value += 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -