首页 > 其他 > 详细

Verilog读取HEX文件初始化ROM

时间:2015-12-16 00:22:11      阅读:1140      评论:0      收藏:0      [点我收藏+]

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] q

);

?

parameter filename="F:/project/cpu/code/ModelSim/04_ROMInitTest/src/ROM.hex";

?

reg[ 7:0] char_1st;

reg[15:0] address; // Rom address

reg[ 7:0] len; // bytes of one line in the hex file

reg[ 7:0] dat;

reg[7:0] sum; // intel hex file verification

?

reg[ 640:1] errstr;

?

reg[7:0] rom[0:4095];

?

reg CanRead;

?

integer i,fp,code;

?

always@(posedge clk)

if(!rst_n)begin

char_1st = 0;

address =0;

len =0;

dat =0;

sum =0;

CanRead =1;

?

fp=$fopen(filename,"r");

?

if(fp==0)begin

$display($time,"ERROR: Hex File %s cann‘t be open!",filename);

$stop; // stop when no such file

end

else begin

$display($time,"Message: Hex File %s open succese!",filename);

end

?

if($ferror(fp,errstr))begin

$display("%s",errstr);

$display($time,"ERROR: Hex File %s error",filename);

$stop;

end

?

while(CanRead)

begin

//first byte should be ":"

char_1st=$fgetc(fp);

?

if(char_1st=="\n")begin //if it is blank line read next char

char_1st=$fgetc(fp);

end

else if(char_1st!=":")begin // every line begin with ":"

//if one line is not start with ":" this file maybe not a hex file

$display($time,"Error: The 1st char isn‘t [:]Hex File convert end! ");

CanRead = 0;

end

else begin

//the second and third byte means how many data in this line

code=$fscanf(fp,"%2x",len);

if(len==0)begin

$display($time,"Message:Initial Rom Finish!");

CanRead = 0;

end

else begin

sum=len;

code=$fscanf(fp,"%4x",address);

sum=sum+address;

sum=sum+(address>>8); // unsigned sum

?

code=$fscanf(fp,"%2x",dat); // data type

sum=sum+dat;

for(i=0;i<len;i=i+1)begin

code=$fscanf(fp,"%2x",dat);

sum=sum+dat;

rom[address]=dat; // ram read data from file

address=address+1;

end

code=$fscanf(fp,"%2x\n",dat); // check data

sum=sum+dat;

?

if(sum!=0)begin

$display("Error:verification code is not zero!");

CanRead = 0;

end

end

end

end

end

else begin

q<=rom[addr];

end

?

endmodule

测试文件

ROM_t.v

?

module Rom_t;

?

reg clk;

reg rst_n;

reg[15:0] addr;

wire[7:0] q;

?

ROM U_rom(

clk,

rst_n,

addr,

q

);

?

always #1 clk=~clk;

?

initial begin

clk<=0;

rst_n<=1;

#5 rst_n<=0;

#5 rst_n<=1;

end

?

always@(posedge clk)

if(!rst_n)begin

addr<=0;

end

else begin

addr<=addr+1;

end

?

endmodule

?

测试所用HEX是Keil编译一段C语言代码后生成的十六进制文件。用STC-ISP打开如下图(可以用任意一个HEX文件继续后续实验)

?

技术分享

?

以上3个文件(ROM.v,Rom_t.v,ROM.hex)放在\04_ROMInitTest\src目录下,代码中会从这个目录打开ROM.hex文件。

?

Modelsim中启动仿真,结果如下图

?

技术分享

?

控制台输出如下内容:

技术分享

上面的时序图中可见clk的上升沿中有2次都检测到rst_n为0,所以上面的初始化代码会执行2次。

?

附上网上一段关于HEX和mif文件相关的资料:

?

hex文件又叫intel hex文件

Intel HEX由任意数量的十六进制记录组成。每个记录包含5个域,它们按以下格式排列:
:llaaaatt[dd...]cc
每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数字。每一个域由至少两个十六进制编码数字组成,

它们构成一个字节,就像以下描述的那样:
: 每个Intel HEX记录都由冒号开头.
ll 是数据长度域,它代表记录当中数据字节(dd)的数量.
aaaa 是地址域,它代表记录当中数据的起始地址.
tt 是代表HEX记录类型的域,它可能是以下数据当中的一个:
00 – 数据记录
01 – 文件结束记录
02 – 扩展段地址记录
04 – 扩展线性地址记录
dd 是数据域,它代表一个字节的数据.一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域(ll)中指

定的数字相符.
cc 是校验和域,它表示这个记录的校验和.校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模

进行以下补足.

数据记录
Intel HEX文件由任意数量以回车换行符结束的数据记录组成.数据记录外观如下:
:10246200464C5549442050524F46494C4500464C33
其中:
10 是这个记录当中数据字节的数量.
2462 是数据将被下载到存储器当中的地址.
00 是记录类型(数据记录)
464C…464C是数据.
33 是这个记录的校验和.

mif文件比起hex文件就要"单纯"许多 因为她没有最后的坑爹的校验和 所以生成起来比较容易

mif文件的格式范例如下

WIDTH=128;
DEPTH=4096;

ADDRESS_RADIX=HEX; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//十进制为DEC?
DATA_RADIX=HEX; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //二进制为BIN

CONTENT BEGIN
0000 : 000000000000000000000000FFFFFFF0;
0001 : 000000000000000000000000FFFFFFF1;
0002 : 000000000000000000000000FFFFFFF2;
0003 : 000000000000000000000000FFFFFFF3;

.............................................................................

..............................................................................

END;

Verilog读取HEX文件初始化ROM

原文:http://www.cnblogs.com/nf466568905/p/5049864.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!