在驗證verilog邏輯模塊功能時候,我們可以從文件中讀入激勵,便於大規模的驗證。文件中的數據我們可以用c++編寫程式產生。第一種讀入文件的方法是用系統函數:$readmemb, readmemh, 第一個函數是讀入二進位的字元串,第二個是讀入16進位的字元串。我們準備兩個文本文件x1.txt111... ...
在驗證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,波形如下:
修改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