1、读文件到memory的操作
假设仿真的时候,某个变量需要输入一堆数据,能想到的具体应用就是做协议解析的时候。以往的做法是把数据提前存入ROM中,从ROM 中读取数据,但是这样操作得添加控制ROM的代码,还浪费了一些资源,不太适合仿真。看到有读文件的操作,就尝试一下。
//============= 顶层设计模块===================//
module top(
input I_clk ,
input I_rst ,
input [07:0] I_data ,
output reg [07:0] O_data
);
always @ (posedge I_clk or posedge I_rst)
begin
if (I_rst)
begin
O_data <= 0;
end
else
begin
O_data <= I_data;
end
end
endmodule
//============= 仿真测试模块===================//
module tb_top(
);
reg I_clk ;
reg I_rst ;
reg [07:0] I_data ;
wire[07:0] O_data ;
reg [07:0] I_data_t ;
top u_top(
. I_clk (I_clk ) ,
. I_rst (I_rst ) ,
. I_data (I_data ) ,
. O_data (O_data )
);
integer i;
reg [7:0] memorydata [0:8];
always # 2 I_clk = ~ I_clk;
initial begin
I_clk = 0;
I_rst = 1;
i = 0;
I_data_t = 0;
# 200
I_rst = 0;
$readmemh("C:/Users/Lenovo/Desktop/tmp/test/project_1/usedata.txt",memorydata); //readmemh输入文件格式16进制
repeat (6) begin
# 40 ;
I_data_t = memorydata [i] ;
i = i + 1;
end
end
always @ (I_clk) //这个always 模块,应该把所有的输出都遍历到,这样输出数据和时钟完全对齐,避免出现仿真时候打拍没有延迟的情况
begin
I_data <= I_data_t
end
endmodule
txt 文件如下:
仿真结果如下:
2、 写文件操作
试过几种网上说的方法,就这个试通了。在verilog程序中添加相对应的代码即可
reg [7:0] i =0;
always @ (posedge clk)
begin
if (!rst_n)
i <=0;
else if (i<255)
i <= i+1;
else
i<= 255;
end
//需要说明,%d输出的是十进制数据, %h输出的是十六进制数据 如果,rom_data_I是 wire signed[8:0]rom_data_I; //声明过的,定义为有符号数,则在txt文件中保存的就是有符号数,否则,默认为无符号数。
integer w_file;
initial w_file = $fopen("data_out_1.txt");
always @(i)
begin
$fdisplay(w_file,"%d",rom_data_I); // %d 10进制输出
if(i == 8'd254) //共写入254个数据
$stop;
end
说明: 操作发现txt 一直没有数据,检查代码也没错,最后发现,是要把modelsim/vivado 自带仿真软件关闭以后,数据才能存入到 txt 文件里