转化过程:
(1)首先将二进制用工具bin2mif.c转化成verilog的Hex文件,当然先用gcc编译bin2mif.c,然后运行改程序就行,程序源码在文档后面附上。
(2)然后注意:转化的十六进制文件是否是你的verilog需要的对齐格式,有的vcs需要4字节对齐,有的是32字节对齐。
还要注意大小端!
* bin2mif/hex converter
* 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);
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)如果大小端和对齐方式不符合,需要写脚本转化下,那个简单。
Verilog
使用$readmemb .txt对非IP核的ROM/RAM的初始化
对于直接调用rom/ram的ip核使用mif
文件
核
hex
文件
将其初始化操作还是很简单的。这里讲自己编写简易的rom,使用txt
文件
对它初始化。
直接上模型代码:
module rom(data,addr,read);
output [7:0] data;
input [3:0] addr;
input read;
reg [7:0] memory [13'h1fff:0];
wire [7:0]
今天一个上午的时间,都被这个问题所困扰,在网上查询
十六进制
文件
的一般格式,都是这么说的,
文件
由一条条的记录组成,每条记录都有固定的几个部分组成。具体的格式如下::10008000AF5F67F0602703E0322CFA92007780C361:1000900089001C6B7EA7CA9200FE10D2AA00477D81:0B00A00080FA92006F3600C3A00076CB
ROM.v代码
这个模块设计的关键是在复位信号中执行初始化代码,读取指定位置的
HEX
文件
中的数据初始化rom,然后在其他时钟沿时刻输出地址所指的数据。
//read
hex
file to initial ROM or RAM
module ROM(
input clk,
input rst_n,
input[15:0] addr,
output reg[7:0] ...
HEX
文件
和BIN
文件
是我们经常碰到的2种
文件
格式。因为自己也是新手,所以一直对这两个
文件
懵懵懂懂,不甚了解,最近在做STM32单片机的IAP更新,其中要考虑
HEX
文件
和BIN
文件
,所以需要学习下这两种
文件
。下面是最近的我的了解,如有不对地方还请指正。
1.IP核的基本概念
IP(Intellectual Property)即知识产权。在半导体产业将IP核定义为“用于ASIC或FPGA中的预先设计好的电路功能模块”。简而言之,IP即电路功能模块。
在数字电路中,将常用的且比较复杂的功能模块设计成参数可修改的模块,方便用户直接调用。
2.IP核的分类
HDL语言形式---软核;网表形式---固核;版图形式---硬核;
3.IP核的典型应用
ROM-IP核简介:
ROM是只读存储器(Rea...
二进制
转化为
十六进制
目标:对话框里有两个编辑框和一个转换按钮。一个编辑框用于接收用户的输入,当单击转换按钮时,另一个编辑框用于输出转换后的
十六进制
数。实现方法:1、首先为这两个编辑框分别绑定变量m_szBinary和m_sz
Hex
。2、添加转换函数OnBtoHConvert()。具体代码如下:void CBtoHDlg::OnBtoHConvert(){UpdateData
二进制
转换成BCD的原理与
verilog
实现 --加3左移
FPGA中的lcd显示、串口收发等应用会涉及到
二进制
和BCD码之间的转换,常见的有3种方法:除法取模运算、查找表、加3左移。 大位宽下,取模除法运算耗费大量lut资源,查找表也不方便,常用一种加3左移的方法。
加3左移相当于左移后再加6,基本过程有很多人描述过了,可以参考下面的博客,其过程介绍得很清楚。
https://www.cnblogs.com/SummerSunnyDay/p/5013835.html
我这里着重补充一下为什么通过这种有条
系统任务$readmemh读取
十六进制
文件
。$readmemh的作用是将
文件
中的数据一次性的读入某个数组中,然后可以依次从数组中取出单个的数据进行处理。读取的内容只包括空白位置(空格、换行、制表格)、注释行、
十六进制
的数字。语法结构中的起始地址与终止地址可省略。【语法结构】:$readmemh("
文件
名", 存储器名,起始地址,终止地址);【实例150】://从input
文件
夹下读取16...