verilog 仿真工程应用-生成coe/mif 文件

原文网站: verilog 仿真工程应用-生成coe/mif 文件 – 芯片天地

在使用xilinx 芯片时, 我们会使用到xilinx 公司提供的IP 核, 比如rom , 单端口ram, 双端口ram等等。 在这些存储器件中,有时我们希望预存储一些数据(对存储单沿进行初始化)。这时,我们就会需要coe文件了。 另外,如果使用altera 公司的fpga, 同样也会遇到这样的问题。虽然quartus 本身就提供一种方法制作mif文件,但本文中,我们可以利用verilog 仿真文件制作自己所需要的coe文件或者mif 文件。

在我们学习verilog 仿真时,不但能对我们的fpga 工程进行仿真, 同时,也可以利用我们所学习的verilog 仿真知识(文件操作)制作一些文件。

利用静态数组方式,生成coe,mif文件

在整个仿真工程中, 用户需要修改一下几个参数:

  • localparam INPUT_DATA_RADIX = 16; // 16, 10 , 2
  • localparam INPUT_DATA_WID = 8;
  • localparam INPUT_DATA_DEEP = 256;

INPUT_DATA_RADIX 是用来确定输出文件格式的(16进制,10进制,2进制), 是用户告诉仿真工程,输出什么样的格式的coe,mif 文件。

INPUT_DATA_WID 是用来确定输入, 输出文件的数据宽度。

INPUT_DATA_DEEP 是告诉仿真工程,最终输出文件有多少个数据。

reg [INPUT_DATA_WID - 1:0] input_data [0:INPUT_DATA_DEEP - 1]; 
integer i; 
initial begin 
    for(i = 0; i < INPUT_DATA_DEEP; i = i + 1) 
    begin 
        input_data = i; 
    end 
end

这里是用户自定义的静态数组,用户可以根据自己的需要更改input_data 数组里面的内容。这里我们只是简单的提供一个例子,方便大家使用。

仿真代码如下:

例1

`timescale 1ns / 1ps
module sim_top(
);
// ====================== user parameter setting =======================

localparam  INPUT_DATA_RADIX    = 16;   // 16,  10 , 2
localparam  INPUT_DATA_WID      = 8;
localparam  INPUT_DATA_DEEP     = 256;

// data need to convert
reg [INPUT_DATA_WID - 1:0] input_data [0:INPUT_DATA_DEEP - 1];

integer i;
initial
begin
    for(i = 0; i < INPUT_DATA_DEEP; i = i + 1)
    begin
        input_data = i;
    end
end

// =====================================================================
reg stop_flag = 0;
            
localparam FILE_COE = "../../../test.coe";
localparam FILE_MIF = "../../../test.mif";
integer n;
integer fd_coe;
integer fd_mif;

initial begin
    n = 0;
    fd_coe = $fopen(FILE_COE, "w");
    if(fd_coe == 0)
    begin
        $display("$open coe file failed") ;
        $stop;
    end
    
    
    $display("\n ============= coe file opened... ============= ") ;
// =====================================================================
// coe file    
    $fwrite(fd_coe,"memory_initialization_radix = %0d;\n",INPUT_DATA_RADIX);
    $fwrite(fd_coe,"memory_initialization_vector = ");
    #10;

    for (n = 0; n < INPUT_DATA_DEEP; n = n + 1)
    begin
        if( INPUT_DATA_RADIX == 16)
            $fwrite(fd_coe,"\n%h", input_data[n]);
        if( INPUT_DATA_RADIX == 2)
            $fwrite(fd_coe,"\n%b", input_data[n]);
        
        #10;
    end
    
    $fwrite(fd_coe,";");
    #10;
    $fclose(fd_coe) ;
    $display("\n ============= coe file closed... ============= ") ;
// =====================================================================


// =====================================================================
// mif file    
    $display("\n ============= mif file opened... ============= ") ;
    fd_mif = $fopen(FILE_MIF, "w");
    if(fd_mif == 0)
    begin
        $display("$open mif file failed") ;
        $stop;
    end
    
    $fwrite(fd_mif,"WIDTH=%0d;\n",INPUT_DATA_WID);
    $fwrite(fd_mif,"DEPTH=%0d;\n\n",INPUT_DATA_DEEP);
    
    $fwrite(fd_mif,"ADDRESS_RADIX=UNS;\n");
    if( INPUT_DATA_RADIX == 16)
        $fwrite(fd_mif,"DATA_RADIX=HEX;\n\n");
    if( INPUT_DATA_RADIX == 10)
        $fwrite(fd_mif,"DATA_RADIX=DEC;\n\n");
    if( INPUT_DATA_RADIX == 2)
        $fwrite(fd_mif,"DATA_RADIX=BIN;\n\n");

    $fwrite(fd_mif,"CONTENT BEGIN\n");
    #10;

    for (n = 0; n < INPUT_DATA_DEEP; n = n + 1)
    begin
        if( INPUT_DATA_RADIX == 16)
            $fwrite(fd_mif,"%0d : %h;\n", n, input_data[n]);
        if( INPUT_DATA_RADIX == 10)
            $fwrite(fd_mif,"%0d : %0d;\n", n, input_data[n]);
        if( INPUT_DATA_RADIX == 2)
            $fwrite(fd_mif,"%0d : %b;\n", n, input_data[n]);
        
        #10;
    end
    $fwrite(fd_mif,"END;\n");
    #10;
    
    $fclose(fd_mif) ;
    $display("\n ============= mif file closed... ============= ") ;
// =====================================================================
    stop_flag = 1;
    #100;
    $stop;
end

    
endmodule

利用现有的文件,生成coe,mif文件

有时,我们会利用其他工程或者软件的输出结果, 作为coe,mif 文件的输入。这时,就需要打开文本、2进制的文件,读取这些文件的内容, 利用仿真工程生成相应的coe,mif文件。

例2

文本输入文件如下(test.txt):

01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
10
11
12

注:INPUT_DATA_RADIX  = 16 时,文本文件中必须使用0-9 a-f 来表示; INPUT_DATA_RADIX  = 10 时,文本文件中必须使用0-9 表示; INPUT_DATA_RADIX  = 2 时,文本文件中必须使用0-1 来表示。

例如当INPUT_DATA_RADIX  = 2 ,INPUT_DATA_WID = 8 时,文本文件必须是:

01010011

01111001

二进制输入文件(test.bin)

`timescale 1ns / 1ps
module sim_top(
);
// ====================== user parameter setting =======================

localparam  INPUT_DATA_RADIX    = 16;   // 16,  10 , 2
localparam  INPUT_DATA_WID      = 8;
localparam  INPUT_DATA_DEEP     = 256;

// data need to convert
reg [INPUT_DATA_WID - 1:0] input_data [0:INPUT_DATA_DEEP - 1];

integer i;
initial
begin
    for(i = 0; i < INPUT_DATA_DEEP; i = i + 1)
    begin
        input_data = i;
    end
end

// =====================================================================
reg stop_flag = 0;
            
localparam FILE_COE = "../../../test.coe";
localparam FILE_MIF = "../../../test.mif";

localparam DATA_TXT = "../../../test.txt";
localparam DATA_BIN = "../../../test.bin";

integer n;
integer fd_coe;
integer fd_mif;
integer fd_txt;
integer fd_bin;

reg [7:0] mem;
reg [7:0] mem_array[0:3];

initial begin
    n = 0;
    fd_coe = $fopen(FILE_COE, "w");
    if(fd_coe == 0)
    begin
        $display("$open coe file failed") ;
        $stop;
    end
    
    fd_txt = $fopen(DATA_TXT, "r");
    if(fd_txt == 0)
    begin
        $display("$open txt file failed") ;
        $stop;
    end
    
    $display("\n ============= coe file opened... ============= ") ;
// =====================================================================
// coe file    
    $fwrite(fd_coe,"memory_initialization_radix = %0d;\n",INPUT_DATA_RADIX);
    $fwrite(fd_coe,"memory_initialization_vector = \n");
    #10;

    while ($feof(fd_txt) != 1)
    begin
        $fgets(mem,fd_txt);
        if( INPUT_DATA_RADIX == 16)
            $fwrite(fd_coe,"%s", mem);
        if( INPUT_DATA_RADIX == 10)
            $fwrite(fd_coe,"%s", mem);
        if( INPUT_DATA_RADIX == 2)
            $fwrite(fd_coe,"%s", mem);
        
        #10;
    end
    
    $fwrite(fd_coe,";");
    #10;
    $fclose(fd_coe) ;
    $display("\n ============= coe file closed... ============= ") ;
// =====================================================================


// =====================================================================
// mif file    
    $display("\n ============= mif file opened... ============= ") ;
    fd_mif = $fopen(FILE_MIF, "w");
    if(fd_mif == 0)
    begin
        $display("$open mif file failed") ;
        $stop;
    end
    
    fd_bin = $fopen(DATA_BIN, "rb");
    if(fd_bin == 0)
    begin
        $display("$open bin file failed") ;
        $stop;
    end
    
    $fwrite(fd_mif,"WIDTH=%0d;\n",INPUT_DATA_WID);
    $fwrite(fd_mif,"DEPTH=%0d;\n\n",INPUT_DATA_DEEP);
    
    $fwrite(fd_mif,"ADDRESS_RADIX=UNS;\n");
    if( INPUT_DATA_RADIX == 16)
        $fwrite(fd_mif,"DATA_RADIX=HEX;\n\n");
    if( INPUT_DATA_RADIX == 10)
        $fwrite(fd_mif,"DATA_RADIX=DEC;\n\n");
    if( INPUT_DATA_RADIX == 2)
        $fwrite(fd_mif,"DATA_RADIX=BIN;\n\n");

    $fwrite(fd_mif,"CONTENT BEGIN\n");
    #10;

    $fread(mem, fd_bin);
    #10;

    while ($feof(fd_bin) != 1)
    begin
//        $fread(mem_array, fd_bin, 0, 4);
        if( INPUT_DATA_RADIX == 16)
//            $fwrite(fd_mif,"%0d : %02h%02h%02h%02h;\n", n, mem_array[0],mem_array[1],mem_array[2],mem_array[3]);
            $fwrite(fd_mif,"%0d : %02h;\n", n, mem);
        if( INPUT_DATA_RADIX == 10)
            $fwrite(fd_mif,"%0d : %0d;\n", n, mem);
        if( INPUT_DATA_RADIX == 2)
            $fwrite(fd_mif,"%0d : %08b;\n", n, mem);

        n = n + 1;
        $fread(mem, fd_bin);
        #10;
    end
    
    if( n < INPUT_DATA_DEEP);
        $fwrite(fd_mif,"[%0d..%0d] : 0;\n", n, INPUT_DATA_DEEP - 1);
    
    $fwrite(fd_mif,"END;\n");
    #10;
    
    $fclose(fd_mif) ;
    $display("\n ============= mif file closed... ============= ") ;
// =====================================================================
    stop_flag = 1;
    #100;
    $stop;
end
    
endmodule

仿真输出的test.coe文件如下:

memory_initialization_radix = 16;
memory_initialization_vector = 
01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
10
11
12 ;

仿真输出的test.mif 文件如下:

WIDTH=8;
DEPTH=256;

ADDRESS_RADIX=UNS;
DATA_RADIX=HEX;

CONTENT BEGIN
0 : 00;
1 : 01;
2 : 02;
3 : 03;
4 : 04;
5 : 05;
6 : 06;
7 : 07;
8 : 08;
9 : 09;
10 : 0a;
11 : 0b;
12 : 0c;
13 : 0d;
14 : 0e;
15 : 0f;
16 : 10;
17 : 11;
18 : 12;
19 : 13;
20 : 14;
21 : 15;
22 : 16;
23 : 17;
24 : 18;
25 : 19;
26 : 1a;
27 : 1b;
28 : 1c;
29 : 1d;
30 : 1e;
31 : 1f;
32 : 20;
33 : 21;
34 : 22;
35 : 23;
36 : 24;
37 : 25;
38 : 26;
39 : 27;
40 : 28;
41 : 29;
42 : 2a;
43 : 2b;
44 : 2c;
45 : 2d;
46 : 2e;
47 : 2f;
[48..255] : 0;
END;

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值