关于验证Verification IP,举个例子看看

专业解释:
VIP(Verfication IP)代码确认与验证技术,是预先验证过的内建验证结构,提供了完整的、灵活的应用机制,可以方便地插入到基于仿真的确认测试中,可以大大提高验证可重用性和验证效率。VIP是一种验证模型,并提供一套全面测试环境,帮助设计者和验证者确认其设计功能的正确性,可用于各个层次的仿真验证。通常,VIP是基于标准协议的,如:AMBA、PCIE、USB、Ethernet等。VIP中包括很多验证部件IP,这些IP都严格遵循这些标准协议、已经被验证过,通常包括:产生testbench所必须的基础部件、检查机制以及产生单独协议的程序,这些程序通常是一个BFM(Bus Functional Models)。

通俗解释:
vip可以实现数据 → 通信协议的转换,把想发的数据输入给vip(如读文件的方式),vip会输出符合相应通信协议的数据,可直接用来作为相应模块的输入信号。
vip也可以用来验证输出数据是否符合相应通信协议的时序,且输出的数据是否正确(与文件数据对比)。

本文设计的模块即实现了数据 → AXI Stream 输出 的转换。
————————————————————————————————————
C++程序:

C++程序用于产生存储数据的.bin文件,文件中第一个32bit数据为文件中全部有效数据的总字节数,其后的数据为按顺序排列的有效数据。

#include <iostream>

using namespace std;

#define N 32

int main()
{
    /* write file */
    FILE* fp;

    unsigned int byte_cnt=0;
    unsigned int data[N];//sizeof(unsigned int) == 4 bytes

    fp = fopen("test_axis.bin", "wb");
    fseek(fp, sizeof(byte_cnt), SEEK_CUR);//指针从当前位置向后移动 sizeof(byte_cnt) 个字节 ,留作之后再写入

    for(int i=0;i<N;i++)
    {
        data[i] = i;
    }

    fwrite(data, sizeof(unsigned int), N, fp);
    byte_cnt += N * sizeof(unsigned int);
    cout<<byte_cnt<<" bytes have been written in file."<<endl;

    fwrite(data, sizeof(unsigned int), N, fp);
    byte_cnt += N * sizeof(unsigned int);
    cout<<byte_cnt<<" bytes have been  written in file."<<endl;


    //向前移动会把前面的数据覆盖
    fseek(fp, -(byte_cnt + sizeof(byte_cnt)), SEEK_CUR);//指针从当前位置向前移动 (byte_cnt + sizeof(byte_cnt)) 个字节
    fwrite(&byte_cnt, sizeof(byte_cnt), 1, fp);//在前面写入总共的字节数,此时,指针从当前位置向后移动 sizeof(byte_cnt) 个字节
    fseek(fp, (byte_cnt + sizeof(int)), SEEK_CUR);//指针还原
    byte_cnt = 0;

    fclose(fp);


    /* read file */
    FILE* fp_r;
    unsigned int rd_data[N*2+1];//sizeof(unsigned int) == 4 bytes
    fp_r = fopen("test_axis.bin", "rb");
    fread(rd_data, sizeof(unsigned int) , N*2+1, fp_r);
    fclose(fp_r);

    printf("\n");
    for(int i=0;i<N*2+1;i++)
    {
        printf("rd_data[%d] = %d\n", i, rd_data[i]);
    }
    printf("\n");

    return 0;
}

 vip程序:

`timescale 1ns / 1ns
//
// Company:
// Engineer:
//
// Create Date: 11/09/2020
// Author Name: Sniper
// Module Name: axis_driver
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//

module axis_driver
#(
	parameter WIDTH = 32
)
(
    input           clk,
    input           rst_n,
    input           start,
    output reg      m_axis_tvalid,
    input           m_axis_tready,
    output reg [WIDTH-1:0] m_axis_tdata,
    output reg      m_axis_tlast,
    input [16*8-1:0]    id,
    input [128*8-1:0]   filename
);

integer 		   file;

reg [7:0] 		   state;
reg [31:0] 		   transfer_byte_cnt;
reg [31:0] 		   sum_byte_num;
reg [WIDTH-1:0]    file_data;

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
	begin
		state <= 0;
		transfer_byte_cnt <= 0;
		m_axis_tvalid <= 0;
		m_axis_tlast <= 0;
		m_axis_tdata <= 0;
	end
	else
	begin
		case(state)
		0://init
		begin
			file = $fopen(filename,"rb");
			state <= state + 1;
			if(!file)
				$error("Failed to open %s",filename);
		end
		1://wait for start pulse
        begin
			if(start)//start==1 only 1 clk period
			begin
				$fread(sum_byte_num,file);//first 32bit data is sum_byte_num
				sum_byte_num = {<<8{sum_byte_num}};//convert the sequence of byte
				$fread(file_data,file);
				file_data = {<<8{file_data}};

                m_axis_tdata <= file_data;
                transfer_byte_cnt <= transfer_byte_cnt + (WIDTH/8);

                m_axis_tvalid <= 1;
                state <= state + 1;
			end
        end
        2://transfer
        begin
            if(m_axis_tvalid & m_axis_tready)//handshake
            begin
                $fread(file_data,file);
                file_data = {<<8{file_data}};

                m_axis_tdata <= file_data;
                transfer_byte_cnt <= transfer_byte_cnt + (WIDTH/8);

                m_axis_tvalid <= 1;
                if(transfer_byte_cnt == sum_byte_num - (WIDTH/8))
                begin
                    m_axis_tlast <= 1;
                    state <= state + 1;
                end
            end
        end
        3://reset
        begin
            m_axis_tvalid <= 0;
            m_axis_tlast <= 0;
            m_axis_tdata <= 0;

			$fclose(file);
            sum_byte_num = 0;
            transfer_byte_cnt <= 0;
            state <= 0;
        end
		endcase
	end
end

endmodule

vip_tb:

`timescale 1ns / 1ns
//
// Company:
// Engineer:
//
// Create Date: 11/09/2020
// Author Name: Sniper
// Module Name: tb_axis_driver
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//

module tb_axis_driver;

//parameter
parameter WIDTH = 32;


//input
reg clk;
reg rst_n;
reg start;
reg m_axis_tready;
reg [16*8-1:0] id;
reg [128*8-1:0] filename;


//output
wire m_axis_tvalid;
wire [WIDTH-1:0] m_axis_tdata;
wire m_axis_tlast;



initial
begin
    clk = 0;
    rst_n = 0;
    start = 0;
    m_axis_tready = 1;
    id[16*8-1:0] = "AXIS_DRIVER_0";
    filename[128*8-1:0] = "test_axis.bin";

	#100;
    rst_n = 1;

    #100;
    @(posedge clk)
        start <= 1;
    @(posedge clk)
        start <= 0;

    #1000;
    @(posedge clk)
        start <= 1;
    @(posedge clk)
        start <= 0;

    #1000;
    @(posedge clk)
        start <= 1;
    @(posedge clk)
        start <= 0;


end

//clock
always #5 clk = ~clk;



//DUT
axis_driver 
#(
    .WIDTH(WIDTH)
)
DUT
(
    .clk(clk),
    .rst_n(rst_n),
    .start(start),
    .m_axis_tvalid(m_axis_tvalid),
    .m_axis_tready(m_axis_tready),
    .m_axis_tdata(m_axis_tdata),
    .m_axis_tlast(m_axis_tlast),
    .id(id),
    .filename(filename)
);

initial
begin
  $dumpfile("curve.vcd");
  $dumpvars(0,DUT);
end

initial #10000 $finish;

endmodule

仿真结果:

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值