将二进制文件生成主要厂商FPGA初始化文件程序

  不管是RISC-V, MIPS, Nios II, MicroBlaze, MSP430, 8051, OpenRISC, OpenSPARC, LEON2/LEON3等等软核处理器,在FPGA上实现的时候我们通常需要一部分片上RAM存储bootloader,可以使用gcc的objcopy把bootloader的text, exception vector, rodata, data or bss等你需要的内容copy出来,可以通过-O binary生成二进制文件,可以通过-j .section提取你要的section,当然也可以通过--gap-fill 0x00 参数指定默认各sections之间空白填充的数据。通过以下C程序可以生成符合Altera (Intel)、Xilinx和Verilog中$readmemh调用的内存初始化数据。可以根据不同处理器的大小端字节序做修改,下面的程序为小端序设计。

/*
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *  
 *	copyright @ Lyu Yang
 */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
	int i, j, FileLen = 0, address = 0, maxaddr;
	FILE * FileIn, * FileOut;

	if (argc != 3) {
		printf("Arguments Error!\n");
		printf("\nUsage: bin2fpga.exe Depth InputFile\n");
		return 0;
	}
	else {

		FileIn = fopen(*(argv + 2), "rb");
		if (FileIn == NULL){
			printf("File does not exist!\n");
			return 0;
		}

		fseek(FileIn, 0L, SEEK_END);
		FileLen = ftell(FileIn);
		maxaddr = atoi(*(argv + 1));
		
		unsigned char * buf = (unsigned char*)malloc(sizeof(char)* FileLen);
		if(buf == NULL) {
			printf("Memory Allocate Error!\n");
			return 0;
		}
		
		// For altera fpga mif file
		FileOut = fopen("./altera.mif", "w");
		
		if (FileOut == NULL) {
			printf("Output File Create Error!\n");
			return 0;
		}
		
		fprintf(FileOut, "DEPTH = %d;\nWIDTH = 32;\nADDRESS_RADIX = DEC;\nDATA_RADIX = HEX;\nCONTENT\nBEGIN\n", maxaddr);

		fseek(FileIn, 0L, SEEK_SET);
		fread(buf, FileLen, 1, FileIn);
			
		for (i = 0; i < FileLen; i += 4) {
			fprintf(FileOut, "%d: ", address);
			
			fprintf(FileOut, "%02x", buf[i + 3]);
			fprintf(FileOut, "%02x", buf[i + 2]);
			fprintf(FileOut, "%02x", buf[i + 1]);
			fprintf(FileOut, "%02x", buf[i + 0]);
			
			fprintf(FileOut, ";\n");
			address++;
		}
		
		fprintf(FileOut, "[%d..%d]: 0;\n", address, maxaddr - 1);
		
		fprintf(FileOut, "\n\nEND;\n");
		
		fclose(FileOut);
		
		// For xilinx fpga mif file
		FileOut = fopen("./xilinx.mif", "w");
		
		if (FileOut == NULL) {
			printf("Output File Create Error!\n");
			return 0;
		}
		
		fseek(FileIn, 0L, SEEK_SET);
		fread(buf, FileLen, 1, FileIn);
			
		for (i = 0; i < FileLen; i += 4) {
			unsigned int word = *((unsigned int*)(buf + i));
			int x = 32;
			while(x--)
				fprintf(FileOut, "%c", (word >> x & 0x1) + '0');
			
			fprintf(FileOut, "\n");
		}
		
		fclose(FileOut);
		
		// For xilinx fpga coe file
		FileOut = fopen("./xilinx.coe", "w");
		
		if (FileOut == NULL) {
			printf("Output File Create Error!\n");
			return 0;
		}
		
		fprintf(FileOut, "MEMORY_INITIALIZATION_RADIX=16;\nMEMORY_INITIALIZATION_VECTOR=\n");

		fseek(FileIn, 0L, SEEK_SET);
		fread(buf, FileLen, 1, FileIn);
			
		for (i = 0; i < FileLen; i += 4) {		
			fprintf(FileOut, "%02x", buf[i + 3]);
			fprintf(FileOut, "%02x", buf[i + 2]);
			fprintf(FileOut, "%02x", buf[i + 1]);
			fprintf(FileOut, "%02x", buf[i + 0]);
			
			fprintf(FileOut, ",\n");
		}
		
		fseek(FileOut, -2L, SEEK_END);
		fprintf(FileOut, ";\n");
		
		fclose(FileOut);

		// Generic verilog readmemh file
		FileOut = fopen("./readmemh.txt", "w");
		
		if (FileOut == NULL) {
			printf("Output File Create Error!\n");
			return 0;
		}
		
		address = 0x0;
		fseek(FileIn, 0L, SEEK_SET);
		fread(buf, FileLen, 1, FileIn);
			
		for (i = 0; i < FileLen; i += 4) {
			fprintf(FileOut, "@%08x\n", address);
			
			fprintf(FileOut, "%02x", buf[i + 3]);
			fprintf(FileOut, "%02x", buf[i + 2]);
			fprintf(FileOut, "%02x", buf[i + 1]);
			fprintf(FileOut, "%02x", buf[i + 0]);
			
			fprintf(FileOut, "\n");
			address++;
		}
		
		free(buf);
		fclose(FileIn);
		fclose(FileOut);
	}
	
	return 0;
}

 

posted @ 2015-10-02 19:53  BH5HSV  阅读(624)  评论(0编辑  收藏  举报