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

📄 svf2vme.c

📁 在嵌入式系统中对Lattice CPLD软件升级时所需的VME文件生成所需源代码。将一个链上的不同厂家的CPLD产生的SVF文件转换成VME文件
💻 C
📖 第 1 页 / 共 5 页
字号:
* 													*
* numbits:          is the number of bits of data need to convert.		*
* HexString:        is the data string to convert.					*
* end:              is to tell if the semicolon is encountered following	*
*                   the close ')'.    							*
* options:          0 = data are not save. e.g. smask data				*
*                   1 = save selectively. e.g. mask data 				*
*                   2 = compress data. e.g. SDR TDI TDO only. SIR never.	*
*                   3 = save selectively and compressed.				*
*													*
* This routine will return a string of given number of bits. 			*
*													*
******************************************************************************/

short int  ConvertFromHexString(long int numbits, char *data_buf, char *end, char keep, int sdr)
{  
	int          charcount;           /* counts during pass over the string */
	int          dataIdx;             /* cursor into dataarray[]        */
	int          i, j;                   /* hex value extract from the char         */
	int first = 1;
	char           cur_char;
	unsigned char  char_val;
	short int             rcode = 0;
	char                  *work_buf = NULL;          /*working memory*/
	
	charcount = dataIdx = 0;  
	*end = 0;
	
	if ( keep ) {
		if ( ( work_buf = ( char * ) malloc( numbits / 4 + 2 ) ) == NULL ) {
			return OUT_OF_MEMORY;
		}
	}
  
	/*search for the open bracket then close bracket*/
	while ( rcode == 0 ) {
		/*read next string if necessary*/
        rcode = Token( " (" );
		
		if ( !strcmp( SVF_string, "SHR" ) ||
			 !strcmp( SVF_string, "SHL" ) ) {
			
			strcpy( shiftdirection, SVF_string );
			rcode = Token( " (" );
	
			shiftsize = atoi( SVF_string );
			rcode = Token( " (" );
			rcode = Token( " (" );
	
			globalBitArrayCounter--;
		}
		else if ( !strcmp( SVF_string, "VAR" ) ) {
			data_buf[ 0 ] = VAR;
			Token( " (" );
			return ( rcode );
		}
		else if ( globalBitArrayCounter && strcmp( SVF_string, ")" ) && sdr && first ) {
			globalBitArrayCounter--;
			first = 0;
			/*the variable 'first' assures that globalBitArrayCounter gets*/
			/*decremented only once*/
		}

		for ( i = 0; i < (int) strlen( SVF_string ); i++ )
		{
            if ( ( cur_char = SVF_string[ i ] ) == ')' ) {
				break;  /*end of current stream*/
			}

            if ( (keep) && ( isxdigit( cur_char ) ) ) { 
                work_buf[ charcount++ ] = cur_char;
			}
		}

        if ( cur_char == ')' ) {
			break;   /*done with the current row*/
		}
	}
	
	/*data_buf now contains the entire hex string. reverse it and convert it to binary*/
	if (keep) {   
		if ( charcount * 4 < numbits ) {
			dataIdx = numbits / 4;
			for ( i = charcount-1; i >= 0; i-- ) { /*push data forward*/
				work_buf[ dataIdx-- ] = work_buf[ i ];
			}
			
			while ( dataIdx >= 0 ) {
				work_buf[ dataIdx-- ] = '0'; /*fill the lower data with 0*/
			}
			charcount = numbits / 4 + 1;
		}
		
		dataIdx = 0;
		j = 0;
		
		for ( i = charcount - 1; i >= 0; i-- ) {
			char_val = ( unsigned char ) CharToHex( work_buf[ i ] );
			if ( j % 2 == 0 ) {
				data_buf[ dataIdx ] = 0x00;
				data_buf[ dataIdx ] |= ( unsigned char )( reverse( char_val ) << 4 );
			}
			else 
			{
				data_buf[ dataIdx ] |= ( unsigned char ) reverse( char_val );
				dataIdx++;
			}
			j++;
		}
	}
	
	if (work_buf != NULL) {
		free(work_buf);
	}

	return rcode;
}

/***********************************************************************
*
* convertToispSTREAM()
* converts SVF ASCII data stream to Bin stream
*
* 
************************************************************************/
short int convertToispSTREAM(long int numbits, unsigned char *data_buf, char options, int a_iLoop )
{
	int foundFF = 0;
	int FFcount;
	int bytes;
	int i;
	int j;
	char opt;
	char mode;
	unsigned char cur_char;
	unsigned char compr_char = 0x00;
	
	if ( numbits % 8 ) {
		bytes = numbits / 8 + 1;
	}
	else {
		bytes = numbits / 8;
	}
	opt = options;
	j = 0;
	mode = 0;

	if ( ( data_buf[ 0 ] == VAR ) && ( a_iLoop == 0 ) && ( iLoopVMEOption ) ) {
		write( VAR );
		return 0;
	}

	/* Determine the compression mode recommended */
	if ( options >= Minimize ) {
		mode = ( char ) compressToispSTREAM( bytes, data_buf, &opt );
		if (opt == NoSave) {
			return OK;
		}

		if ( mode == 1 ) {
			compr_char = 0x00;
		}
		else if ( mode == 2 ) {
			compr_char = 0xFF;
		}
		
		write( mode );   
		if ( ( mode >= 3 ) && ( mode % 2 ) ) {
			/* For compress by nibble, if mode is odd, inc it to fit byte boundary */
			mode++;  
		}
	}
	if ( opt ) {  
		foundFF = FFcount = 0;
		for ( i = 0; i < bytes; i++ ) {
			/* Turn off the store when enough nibbles are stored */
			if ( ( mode >= 3 ) && ( i >= mode / 2 ) ) {
				opt = NoSave;
			}
			
			cur_char = data_buf[ i ];
			if ( ( opt >= Minimize ) && ( foundFF ) && ( cur_char == compr_char ) ) {
				/* 0xFF again */
				FFcount++;
			}

			else if ( ( opt >= Minimize ) && ( foundFF ) ) {
				/* More than 1 and last 0xFF found */
				ConvNumber( FFcount );

				/* Number of 0xFF bytes */  
				foundFF = FFcount = 0;
				if ( cur_char == compr_char ) {
					foundFF = 1;
				}
				write( cur_char );
			}
			else if ( ( opt >= Minimize ) && ( cur_char == compr_char ) && ( mode < 3 ) && ( mode != -93 ) ) {
				foundFF = 1;    
				write( cur_char );
			}
			else if ( opt ) {
				write( cur_char );
			}
		}
	}

	if ( foundFF ) {
		/* More than 1 and last 0xFF found */
		if ( cur_char == compr_char ) {
			/* Last nibble also is key */
			FFcount++;
		}

		/* Number of 0xFF or 0x00 bytes */
		ConvNumber( FFcount );
	}

	return 0;
}

/***********************************************************************
*
* compressispSTREAM()
* This is to analyze the incoming stream to determine if compression is
* feasible:
* Return  0=> No Compression is recommended.
*         1=> Compression by 0x00.
*         2=> Compression by 0xFF.
*       >=3=> compression by nibble count. 
*             Example: given stream 012301230123 
*             Return value should be 4 since the stream can be compressed
*             as 012302. 
* 
************************************************************************/
short int compressToispSTREAM( int bytes, unsigned char * data_buf, char * options )
{	
	int ori_bytes;
	int i;
	int j;
	int k;
	int m;
	int bits;
	int foundFF;
	int table[ 16];
	int bytetable[ 256 ];
	int bytecount;
	int occurance;
	int rcode;
	int comprkey;
	int count00 = 0;
	int countff = 0;
	unsigned char key;
	unsigned char FFcount = 0;
	unsigned char cur_char;
	unsigned char compr_char;
	unsigned char xch;
	
	ori_bytes = bytes;
	rcode = 0;

	/* If length is less than 3 bytes, don't waste time to compress */
	if (bytes < 3) {
		*options = Store;
		return 0x00;
	}
	
	/* Intitialize the lookup table */
	for ( i = 0; i < 16; i++ ) {
		table[ i ] = 0;   
	}
	for ( i = 0; i < 256; i++ ) {
		bytetable[ i ] = 0;  
	}
	
	/* Build the data occurance frequency table */
	for ( i = 0; i < bytes; i++ ) {
		table[ ( int ) ( data_buf[ i ] >> 4 ) ] += 1;    /* Check the high nibble */
		table[ ( int ) ( data_buf[ i ] & 0x0F ) ] += 1;   /* Check the low nibble */
		if ( data_buf[ i ] == 0x00 ) {
			count00++;
		}
		if ( data_buf[ i ] == 0xFF ) {
			countff++;
		}
	}

	/* Perform compression dry run to see if saving is compress by 0x00 and 0xFF */
	if ( count00 > countff ) {
		compr_char = 0x00;
	}
	else {
		compr_char = 0xFF;
	}
	
	foundFF = FFcount = 0;
	bytecount = 0;
	cur_char = 0x00;
	for ( i = 0; i < bytes; i++ ) {
		cur_char = data_buf[ i ];
		if ( ( foundFF ) && ( cur_char == compr_char ) && ( FFcount < 0xFF ) ) {
			/* 0xFF again */
			FFcount++;
		}
		else if ( foundFF ) {
			/* More than 1 and last 0xFF found */
			bytecount++;
			foundFF = FFcount = 0;
			if ( cur_char == compr_char ) {
				foundFF = 1; 
			}
			bytecount++;
		}
		else if ( cur_char == compr_char ) {
			foundFF = 1;    
			bytecount++;
		}
		else 
		{
			bytecount++;
		}

		bytetable[ ( int ) cur_char ] += 1;
	}      
	
	j = bytetable[ 0 ];
	key = 0;
	for ( i = 0; i < 256; i++ ) {
		if ( bytetable[ i ] > j ) {
			j = bytetable[ i ]; 
			key = i;
		}
	}

	/* Calculate the bytes needed to perform compression using the highest occurance byte as the key */
	comprkey =( ( ( bytes - j ) * ( 8 + 1 ) + j ) / 8 ) + 1;
	if ( bytecount < bytes ) { 
		/* Compress by 0xFF or 0x00 recommended */
		if ( compr_char == 0x00 ) {
			rcode = 1;
		}
		else {
			rcode = 2;
		}
	}
    else {
		/* Try multiple nibble alternative */
		occurance = 0;
		
		/* Find the lowest number of occurance */
		for ( i = 0; i < 16; i++ ) {
			if ( table[ i] > 0 ) {
				if ( occurance == 0 ) {
					occurance = table[ i ];
				}
				else if ( table[ i ] < occurance ) {
					occurance = table[ i ];
				}
			}
		}
		
		/* The number of nibbles as the key */
		bits = bytes * 2 / occurance;
		
		for ( i = 1; i < occurance; i++ ) {
			/* Check if the stream can be mapped into keys */
			for ( j = 0; j < bits; j++ ) {
				/* The next first nibble of the key */
				m = j + i * bits;
				if ( ( 0x0F & ( data_buf[ j / 2 ] >> 4 * ( 1 - j % 2 ) ) ) != ( 0x0F & ( data_buf[ m / 2 ] >> 4 * ( 1 - m % 2 ) ) ) ) {
					/* No compression possible */
					*options = Store;
					rcode = 0;
					break;
				}
			}
		}

		if ( ( *options == Store ) || ( occurance == 1 ) ) {
			rcode = 0x00;
		}
		else {
			/* tnt 10/19/02: if the number of nibbles is the same 
							size as the orginal number of bytes, then 
							do not compress.  This is done to fix the 
							problem with 5512VE part */
			if ( bits == ori_bytes ) {
				*options = Store;
				rcode = 0x00;
			}

⌨️ 快捷键说明

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