我们拿到可执行的程序大部分是二进制的,如何在verilog中运行?
首先注意:Verilog中使用的Hex与intelhex格式不同!
转化过程:
(1)首先将二进制用工具bin2mif.c转化成verilog的Hex文件,当然先用gcc编译bin2mif.c,然后运行改程序就行,程序源码在文档后面附上。
(2)然后注意:转化的十六进制文件是否是你的verilog需要的对齐格式,有的vcs需要4字节对齐,有的是32字节对齐。还要注意大小端!
/* * bin2mif/hex converter * * Copyright (C) 2011 zengjun <zengjun<AT>opencpu.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * USAGE: * bin2mif.exe main.bin main.mif 32 (QuartusII memory initialize file) * bin2mif.exe main.bin main.hex 8 (VerilogHDL $readmemh(filename,registers) file) * */ #include "stdio.h" #define LOWER(x) (((x)>='A' && (x)<='Z')?(((x)-'A')+'a'):(x)) typedef enum { f_quartus, f_ieeeverilog, f_invalid } filetype_t; int main(int argc,char *argv[]) { FILE *fr = NULL; FILE *fw = NULL; int size = 0; int i = 0; int ch = 0; filetype_t ftype = f_invalid; int len = 0; int bus_width = 0; if (argc == 4) { fr = fopen(argv[1],"rb"); if (fr != NULL) { fseek(fr,0,SEEK_END); size = ftell(fr); fseek(fr,0,SEEK_SET); len = strlen(argv[2]); if (len > strlen(".mif")) { if (argv[2][len-4] == '.' && LOWER(argv[2][len-3]) == 'm' && LOWER(argv[2][len-2]) == 'i' && LOWER(argv[2][len-1]) == 'f') { ftype = f_quartus; } if (argv[2][len-4] == '.' && LOWER(argv[2][len-3]) == 'h' && LOWER(argv[2][len-2]) == 'e' && LOWER(argv[2][len-1]) == 'x') { ftype = f_ieeeverilog; } } if (ftype != f_invalid) fw = fopen(argv[2],"wb"); else { printf("invalid output file type.\n"); return -1; } if (fw == NULL) { printf("open %s failed.\n",argv[2]); return -2; } } else { printf("open %s failed.\n",argv[1]); return -3; } /* check bus width */ bus_width = atoi(argv[3]); if (ftype == f_quartus) { switch (bus_width) { case 8: case 16: case 32: /* right,nothing to do */ break; default: printf("bus_width = %d invalid,only 8,16 and 32 supported.\n",bus_width); return -4; } } else if (ftype == f_ieeeverilog) { switch (bus_width) { case 8: /* right,nothing to do */ break; default: printf("bus_width = %d invalid,only 8 supported.\n",bus_width); return -5; } } if (fw != NULL) { if (ftype == f_quartus) { if (bus_width == 8) { fprintf(fw,"%% CREATED BY OPENCPU.COM %%\r\n\r\nDEPTH = %d;\r\nWIDTH = 8;\r\nADDRESS_RADIX = DEC;\r\nDATA_RADIX = HEX;\r\n\r\nCONTENT\r\nBEGIN\r\n",size); for (i=0; i<size; i++) { fprintf(fw,"\t%6d\t:\t",i); fseek(fr,i,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x;\r\n",ch); } fprintf(fw,"END;\r\n"); } else if (bus_width == 16) { fprintf(fw,"%% CREATED BY OPENCPU.COM %%\r\n\r\nDEPTH = %d;\r\nWIDTH = 16;\r\nADDRESS_RADIX = DEC;\r\nDATA_RADIX = HEX;\r\n\r\nCONTENT\r\nBEGIN\r\n",size >> 1); for (i=0; i<size; i+=2) { fprintf(fw,"\t%6d\t:\t",i >> 1); fseek(fr,i+1,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x",ch); fseek(fr,i,SEEK_SET); fread(&ch,1+0,1,fr); fprintf(fw,"%02x",ch); fprintf(fw,";\r\n"); } fprintf(fw,"END;\r\n"); } else if (bus_width == 32) { fprintf(fw,"%% CREATED BY OPENCPU.COM %%\r\n\r\nDEPTH = %d;\r\nWIDTH = 32;\r\nADDRESS_RADIX = DEC;\r\nDATA_RADIX = HEX;\r\n\r\nCONTENT\r\nBEGIN\r\n",size >> 2); for (i=0; i<size; i+=4) { fprintf(fw,"\t%6d\t:\t",i >> 2); fseek(fr,i+3,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x",ch); fseek(fr,i+2,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x",ch); fseek(fr,i+1,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x",ch); fseek(fr,i+0,SEEK_SET); fread(&ch,1,1,fr); fprintf(fw,"%02x",ch); fprintf(fw,";\r\n"); } fprintf(fw,"END;\r\n"); } } else if (ftype == f_ieeeverilog) { for (i=0; i<size; i++) { fseek(fr,i,SEEK_SET); fread(&ch,1,1,fr); if (i % 16 == 15) { if (i == size -1) fprintf(fw,"%02x",ch); else fprintf(fw,"%02x\r\n",ch); } else fprintf(fw,"%02x ",ch); } } } if (fr != NULL) fclose(fr); if (fw != NULL) fclose(fw); } else { printf("USAGE:\r\n%s main.bin main.mif 32\t(QuartusII memory initialize file)\r\n%s main.bin main.hex 8 \t(VerilogHDL $readmemh(filename,registers) file)\r\n\r\nCREATED BY OPENCPU.COM\r\n",argv[0],argv[0]); return -6; } return 0; }(3)如果大小端和对齐方式不符合,需要写脚本转化下,那个简单。