在testbench從文件讀入激勵


在驗證verilog邏輯模塊功能時候,我們可以從文件中讀入激勵,便於大規模的驗證。文件中的數據我們可以用c++編寫程序產生。

第一種讀入文件的方法是用系統函數:$readmemb, readmemh, 第一個函數是讀入二進制的字符串,第二個是讀入16進制的字符串。

我們准備兩個文本文件x1.txt

1111
1010
1110
0001

y1.txt

1101
0101
1010
0001

我們驗證一個四位的加法器

加法器verilog代碼如下:

module adder4(cout, sum, ina, inb, cin,clk);
output [3:0] sum;
output cout;
input [3:0] ina, inb;
input cin,clk;
reg[3:0] tempa, tempb, sum;
reg cout;
reg tempc;

always @(posedge clk)
begin
	tempa = ina;
	tempb = inb;
	tempc = cin;
end

always @(posedge clk)
begin
 {cout, sum} = tempa+ tempb + tempc;
end
endmodule

testbench代碼如下,我們用readmemb函數讀入激勵,並在for循環中賦值給ina,inb

`timescale 1ns/1ns
 `include "adder4.v"

module adder_rw_tb;
reg[3:0] ina,inb;
reg cin;
reg clk = 0;
 wire[3:0] sum;
 wire cout;
reg[3:0] inam[0:3];
reg[3:0] inbm[0:3];
 integer i;
 always #10 clk =~ clk;

initial
 begin
     $readmemb("x1.txt",inam);
     $readmemb("y1.txt",inbm);
     for(i=0;i<4;i=i+1)
     begin
          #20 ina = inam[i];
              inb = inbm[i];
     end
 end

initial
 begin
     cin=0;
     repeat(2)
     #200 cin = {$random} % 16;
 end

adder4 adder4_0(
            .clk(clk),
            .sum(sum),
            .cout(cout),
            .ina(ina),
            .inb(inb),
            .cin(cin)
        );
 initial
 begin
     $monitor($time,,,"%b + %b + %b = {%b,%b}", ina, inb, cin,cout,sum);
     #400 $finish;
 end

initial
 begin
      $dumpfile("dump.vcd");
      $dumpvars;
 end
endmodule


用vcs編譯后,run simv

Contains Synopsys proprietary information.
Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 21 19:34 2018
                    0  xxxx + xxxx + 0 = {x,xxxx}
                   20  1111 + 1101 + 0 = {x,xxxx}
                   30  1111 + 1101 + 0 = {1,1100}
                   40  1010 + 0101 + 0 = {1,1100}
                   50  1010 + 0101 + 0 = {0,1111}
                   60  1110 + 1010 + 0 = {0,1111}
                   70  1110 + 1010 + 0 = {1,1000}
                   80  0001 + 0001 + 0 = {1,1000}
                   90  0001 + 0001 + 0 = {0,0010}
$finish called from file "adder_rw_tb.v", line 44.
$finish at simulation time                  400
            V C S   S i m u l a t i o n   R e p o r t

在verdi中裝入dump.vcd,波形如下:

image


修改testbench代碼,用fdisplay把輸出寫到文件里面。


`timescale 1ns/1ns
`include "adder4.v"

module adder_rw_tb;
reg[3:0] ina,inb;
reg cin;
reg clk = 0;
 wire[3:0] sum;
 wire cout;
reg[3:0] inam[0:3];
reg[3:0] inbm[0:3];
 integer i;
 integer fd;
 always #10 clk =~ clk;

initial
 begin
     $readmemb("x1.txt",inam);
     $readmemb("y1.txt",inbm);
     fd = $fopen("z1.txt");
     for(i=1;i<4;i=i+1)
     begin
          #20 ina = inam[i];
              inb = inbm[i];
          $fdisplay(fd,"%b %b %b %b",ina, inb,sum,cout);
     end
     #20
     $fdisplay(fd,"%b %b %b %b",ina, inb,sum,cout);
     $fclose(fd);
 end

initial
 begin
     cin=0;
     repeat(2)
     #200 cin = {$random} % 16;
 end

adder4 adder4_0(
            .clk(clk),
            .sum(sum),
            .cout(cout),
            .ina(ina),
            .inb(inb),
            .cin(cin)
        );
 initial
 begin
     $monitor($time,,,"%b + %b + %b = {%b,%b}", ina, inb, cin,cout,sum);
     #400 $finish;
 end

initial
 begin
      $dumpfile("dump.vcd");
      $dumpvars;
 end
endmodule

編譯執行程序后,可以得到z1.txt

1111 1101 xxxx x
1010 0101 1100 1
1110 1010 1111 0
0001 0001 1000 1
0001 0001 0010 0

我們也可以把兩個輸入數據合在一個文件xy.txt里面,

1111 1101
1010 0101
1110 1010
0001 0001

用fscanf來讀入激勵數據,代碼如下:

`timescale 1ns/1ns
 `include "adder4.v"

module adder_rw_tb;
reg[3:0] ina,inb;
reg cin;
reg clk = 0;
 wire[3:0] sum;
 wire cout;
reg[3:0] inam[0:3];
reg[3:0] inbm[0:3];
 integer i;
 integer fd,fd_r;
 always #10 clk =~ clk;

initial
 begin
     fd_r = $fopen("xy.txt","r");
     fd = $fopen("z.txt","w");
     for(i=0;i<4;i=i+1)
     begin
          #20
          $fscanf(fd_r, "%d %d",ina,inb);
          $fwrite(fd,"%b %b %b %b\n",ina, inb,sum,cout);
     end
     #20
     $fwrite(fd,"%b %b %b %b\n",ina, inb,sum,cout);
     $fclose(fd);
 end

initial
 begin
     cin=0;
     repeat(2)
     #200 cin = {$random} % 16;
 end

adder4 adder4_0(
            .clk(clk),
            .sum(sum),
            .cout(cout),
            .ina(ina),
            .inb(inb),
            .cin(cin)
        );
initial
begin
    $monitor($time,,,"%b + %b + %b = {%b,%b}", ina, inb, cin,cout,sum);
     #400 $finish;
 end

initial
 begin
      $dumpfile("dump.vcd");
      $dumpvars;
 end
 endmodule


Chronologic VCS simulator copyright 1991-2017
Contains Synopsys proprietary information.
Compiler version M-2017.03-SP2-11; Runtime version M-2017.03-SP2-11;  Dec 21 20:13 2018
                    0  xxxx + xxxx + 0 = {x,xxxx}
                   20  0111 + 1101 + 0 = {x,xxxx}
                   30  0111 + 1101 + 0 = {1,0100}
                   40  0010 + 0101 + 0 = {1,0100}
                   50  0010 + 0101 + 0 = {0,0111}
                   60  0110 + 0010 + 0 = {0,0111}
                   70  0110 + 0010 + 0 = {0,1000}
                   80  0001 + 0001 + 0 = {0,1000}
                   90  0001 + 0001 + 0 = {0,0010}

寫入z.txt數據為:

0111 1101 xxxx x
0010 0101 0100 1
0110 0010 0111 0
0001 0001 1000 0
0001 0001 0010 0







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM