OpenCores
URL https://opencores.org/ocsvn/common/common/trunk

Subversion Repositories common

[/] [common/] [trunk/] [220_convert_hex2ver_pli.c] - Rev 48

Compare with Previous | Blame | View Log

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "veriuser.h"
#include "acc_user.h"
 
#define TRUE 1 
#define FALSE 0 
#define MAX_BUFFER_SZ	2048
#define MAX_NAME_SZ		128
#define OUT_FILE_EXT 	".ver"
#define COLON			':'
#define OFFSET		  	9
#define H10		  		0x10L
#define AWORD			8
#define WORDS_PER_LINE	8
#define MASK15 			0x000000FFL
#define EXT_STR 		".ver"
 
typedef enum {
	OK 		= 0,
	WARNING = 1,
	ERROR 	= 2
}STATUS;
static int line_no = 0;
/********************************************************************
 * char* trimAlteraExt(char* oldName, char* newName)
 * oldName : original file name.
 * newName : new file name which doesnt have file extension.
 *
 * This function trims the file extension
 * Looks for first "." and trims the file name afterwords.
********************************************************************/
 
char* trimAlteraExt(oldName, newName)
char* oldName;
char* newName;
{
    char tempStr[MAX_BUFFER_SZ];
    char* tempPtr=NULL;
 
    newName[0]='\0';
    if(oldName[0]=='\0')
        return NULL;
    strcpy(tempStr, oldName);
    if(tempPtr = strstr(tempStr, "."))
    {
        *tempPtr = '\0';
    }
    strcpy(newName, tempStr);
    return newName;
}
 
/****************************************************************/
int display_msg(status, str, data_file)
STATUS status;
char *str;
char *data_file;
{
	switch(status)
	{
		case WARNING:
			 printf("WARNING: %s, %s\n\n", data_file, str);
			break;
		case ERROR:
			 printf("ERROR:%s, line %d, %s\n\n", data_file, line_no, str);
			break;
		default:
			break;
	}
	return(TRUE);
}
/****************************************************************
  char *ltrim(str)                                                     
  char *str;                                                           
  Deletes leading blanks in string 'str'                             
****************************************************************/               
char *ltrim(str)
char *str;
{  
   	int i = 0,j = 0;
 
	/* Illeagal application. Returns NULL. */
   	if (str == 0) return(0);  
   	/* Deletes leading blanks */
   	while (*(str + i) == ' ' || *(str + i) == '\n' || *(str + i) == '\t' || *(str + i) == '\b') i++;
   	for (; *(str + i) != '\0'; i++,j++) *(str + j) = *(str + i); 
	/* Appends a NULL character to the end of the string */
   	*(str + j) = '\0';  
 
	return(str);
}
 
/****************************************************************
 * Function: write_ver_data
 * Description: This function ensures that each char (in hex)
 * 		represents a nibble of the data.
 * For example if (width<5) we need to output only 1 char hex. 
****************************************************************/      
void write_ver_data(ofp, width, data)
FILE *ofp;
int width;
char *data;
{
  int num_nibbles;
  int num_hex;
 
  num_nibbles = (width%4?(width/4 + 1):width/4);
  num_hex = num_nibbles/2;
 
  while (num_hex--)
  {
    fprintf(ofp, "%c%c", data[0], data[1]);
    data +=2;
  }
  /* NB: we skip the leading '0' in data[0]. */
  if (num_nibbles&1) fprintf(ofp, "%c", data[1]);
}
 
/****************************************************************
Function: write_data
Description: Write ROM data in the verilog format so that
	it can be read using readmemh(infile, rom)
Format:	example data format for the 8 bit data
		@1
		01 02 03 04 05 06 07 08
		@a
		0a 0b 0c      
****************************************************************/      
int write_data(ofp, nn, aaaa, off_addr, dddd, width)
FILE *ofp;
long nn, aaaa, off_addr;
char *dddd;
int width;
{
	int count, i;
    char data[MAX_BUFFER_SZ +1];
	int num_hexs, nibbles ;
 
 
	if((width % AWORD) == 0)
	{
		num_hexs = width/AWORD;
	}
	else
	{
		num_hexs = (width/AWORD) + 1;
	}
 
	fprintf(ofp, "@%x\n", aaaa + off_addr);
 
	nibbles  = num_hexs*2;
	count = 1;
	while(nn > 0)
	{
		if(nn >= num_hexs)
		{
			strncpy(data, dddd, nibbles);
			data[nibbles] = '\0';
		}
		else
		{
			for(i = 0; i < (num_hexs - nn); i++)
			{
				sprintf(data + i*2, "%s", "00");
			}
			strcat(data + (num_hexs - nn), dddd);
		}	
		write_ver_data(ofp, width, data);
		if(count < WORDS_PER_LINE)
		{
			count ++;
		}
		else
		{
			fprintf(ofp, "\n");
			count = 1;
		}
		dddd = dddd + nibbles;
		nn -= num_hexs;
	}
	if(count > 1)
		fprintf(ofp, "\n");
 
 
}
/****************************************************************/
/* Convert Intel-hex format data to verilog format data 		*/
/* 	Intel-hex format 	:nnaaaaattddddcc 						*/
/****************************************************************/
convert_hex2ver()
{
    char buffer[MAX_BUFFER_SZ +1]; 
	char out_file[MAX_NAME_SZ +1];
	char init_filename[MAX_NAME_SZ +1];
    char dddd[MAX_BUFFER_SZ +1];
	char *in_file, *out_str;
 
	FILE *ifp, *ofp;
	int i ;
	int done = FALSE;
	int first_rec = FALSE;
	int last_rec = FALSE;
	int width ;
	long off_addr, nn, aaaa, tt, cc, aah, aal, dd, sum ;
	handle wrk;
	static s_setval_value user_s = {accStringVal};
	static s_setval_delay delay ;
 
	off_addr= nn= aaaa= tt= cc= aah= aal= dd= sum = 0;
 
	in_file = (char *)tf_getcstringp(1);
	width = tf_getp(2);
	trimAlteraExt(in_file, out_file);
	strcat(out_file, OUT_FILE_EXT);
    if ((ifp = fopen(in_file, "r")) == NULL)
    {
       	printf("cannot read %s\n", in_file);
       	fclose(ifp);
		return;
    }
    if ((ofp = fopen(out_file, "w")) == NULL)
    {
       	printf("cannot write %s\n", out_file);
       	fclose(ofp);
		return;
    }
	while(!done)
	{
      	if(fgets(buffer, MAX_BUFFER_SZ, ifp) == NULL)
		{
			if(!first_rec)
				done = display_msg(WARNING, "Intel-hex data file is empty.", in_file);
			else if(!last_rec)
				done = display_msg(ERROR, "Missing the last record.", in_file);
		}
		else if(strlen(ltrim(buffer)) == 0)
		{
			line_no++;
		}
		else if(buffer && (buffer[0] == COLON))
		{
			line_no++;
			first_rec = TRUE;
		   	sscanf(buffer+1,"%02x%04x%02x", &nn, &aaaa, &tt);
			if((tt == 2) && (nn != 2) )
			{
				done = display_msg(ERROR, "Invalid data record.", in_file);
			}
			else
			{
		   	sscanf(buffer+3,"%02x%02x", &aah, &aal);
			sum = nn + aah + aal + tt ;
			for(i = 0; i < nn; i++)
			{
				sscanf(buffer+OFFSET+i*2, "%02x", &dd);
				sprintf(dddd+i*2, "%02x", dd);
				sum += dd;
			}
   			sscanf(buffer+OFFSET+i*2, "%02x\n", &cc);
 
   			switch(tt) {
   				case 0x00: /* normal_record */
					first_rec = TRUE;
					if(((~sum + 1)& MASK15) == cc)
					{
						write_data(ofp, nn, aaaa, off_addr, dddd,width);
						off_addr = 0;
					}
					else
					{
						done = display_msg(ERROR, "Invalid checksum.", in_file);
					}
   				break;
   				case 0x01: /* last record */
					last_rec = TRUE;
					if(((~sum+1)&MASK15) != cc)
					{
						display_msg(ERROR, "Invalid checksum.", in_file);
					}
					done = TRUE;
   				break;
   				case 0x02: /* address base record */
		   			sscanf(dddd,"%x\n", &off_addr);
					if(((~sum +1)& MASK15) == cc)
					{
						off_addr *=  H10;
					}
   					else
					{
						done = display_msg(ERROR, "Invalid checksum.", in_file);
					}
   				break;
   				default:
   					done = display_msg(ERROR, "Unknown record type.", in_file);
   				break;
		    } /* switch */
			}
		}
		else
		{
			line_no++;
			display_msg(ERROR, "Invalid INTEL HEX record", in_file);
			done = TRUE;
		}
  	}
  	fclose(ifp);
  	fclose(ofp);
	/* append EXT_STR to the input string and pass it back in arg 1 */
	delay.model = accNoDelay;
	wrk = acc_handle_tfarg(3);
	trimAlteraExt(in_file, init_filename);
	strcat(init_filename, EXT_STR);
	user_s.value.str = init_filename;
	acc_set_value(wrk, &user_s, &delay);
 
	return(0);
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.