• 将二进制文件生成主要厂商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!
    ");
    		printf("
    Usage: bin2fpga.exe Depth InputFile
    ");
    		return 0;
    	}
    	else {
    
    		FileIn = fopen(*(argv + 2), "rb");
    		if (FileIn == NULL){
    			printf("File does not exist!
    ");
    			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!
    ");
    			return 0;
    		}
    		
    		// For altera fpga mif file
    		FileOut = fopen("./altera.mif", "w");
    		
    		if (FileOut == NULL) {
    			printf("Output File Create Error!
    ");
    			return 0;
    		}
    		
    		fprintf(FileOut, "DEPTH = %d;
    WIDTH = 32;
    ADDRESS_RADIX = DEC;
    DATA_RADIX = HEX;
    CONTENT
    BEGIN
    ", 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, ";
    ");
    			address++;
    		}
    		
    		fprintf(FileOut, "[%d..%d]: 0;
    ", address, maxaddr - 1);
    		
    		fprintf(FileOut, "
    
    END;
    ");
    		
    		fclose(FileOut);
    		
    		// For xilinx fpga mif file
    		FileOut = fopen("./xilinx.mif", "w");
    		
    		if (FileOut == NULL) {
    			printf("Output File Create Error!
    ");
    			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, "
    ");
    		}
    		
    		fclose(FileOut);
    		
    		// For xilinx fpga coe file
    		FileOut = fopen("./xilinx.coe", "w");
    		
    		if (FileOut == NULL) {
    			printf("Output File Create Error!
    ");
    			return 0;
    		}
    		
    		fprintf(FileOut, "MEMORY_INITIALIZATION_RADIX=16;
    MEMORY_INITIALIZATION_VECTOR=
    ");
    
    		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, ",
    ");
    		}
    		
    		fseek(FileOut, -2L, SEEK_END);
    		fprintf(FileOut, ";
    ");
    		
    		fclose(FileOut);
    
    		// Generic verilog readmemh file
    		FileOut = fopen("./readmemh.txt", "w");
    		
    		if (FileOut == NULL) {
    			printf("Output File Create Error!
    ");
    			return 0;
    		}
    		
    		address = 0x0;
    		fseek(FileIn, 0L, SEEK_SET);
    		fread(buf, FileLen, 1, FileIn);
    			
    		for (i = 0; i < FileLen; i += 4) {
    			fprintf(FileOut, "@%08x
    ", 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, "
    ");
    			address++;
    		}
    		
    		free(buf);
    		fclose(FileIn);
    		fclose(FileOut);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    TypeScript--变量
    TypeScript--Hello
    前端跨域的方式
    内存泄漏与垃圾回收机制
    前端拷贝
    React生命周期16版本
    Redux三大原则
    IE6常见CSS解析Bug及hack
    Redux的应用
    vue-router-基础
  • 原文地址:https://www.cnblogs.com/lyuyangly/p/4852627.html
Copyright © 2020-2023  润新知