⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨


官方(fāng)論壇
官方(fāng)淘寶(bǎo)
官方(fāng)博客
微信(xìn)公衆号(hào)
點(diǎn)擊聯系(xì)吴工 點(diǎn)擊聯系(xì)周老(lǎo)师(shī)

【文(wén)章(zhāng)】FPGA千(qiān)兆(zhào)以(yǐ)太网(wǎng)MAC設計(jì)

發(fà)布(bù)时(shí)間(jiān):2021-06-26   作者(zhě):admin 浏覽量(liàng):

本(běn)文(wén)摘自(zì)网(wǎng)絡班陳同(tóng)学博客:https://www.cnblogs.com/moluoqishi/p/9751652.html

本(běn)文(wén)設計(jì)思(sī)想(xiǎng)采用(yòng)明(míng)德揚至(zhì)簡設計(jì)法。上(shàng)一(yī)篇(piān)博文(wén)中(zhōng)定(dìng)制了(le)自(zì)定(dìng)義MAC IP的(de)結構,在(zài)用(yòng)戶側需要(yào)位宽(kuān)轉(zhuǎn)換及(jí)數據(jù)緩存。本(běn)文(wén)以(yǐ)TX方(fāng)向(xiàng)为(wèi)例,設計(jì)并验(yàn)證發(fà)送緩存模块(kuài)。这(zhè)里(lǐ)定(dìng)義該模块(kuài)可(kě)緩存4个(gè)最(zuì)大长度(dù)數據(jù)包(bāo),用(yòng)戶根(gēn)據(jù)需求改動(dòng)即可(kě)。

該模块(kuài)核心(xīn)是(shì)利用(yòng)异(yì)步FIFO進(jìn)行跨时(shí)鐘(zhōng)域处理,位宽(kuān)轉(zhuǎn)換由(yóu)VerilogHDL实現(xiàn)。需要(yào)注意(yì)的(de)是(shì)用(yòng)戶數據(jù)包(bāo)位宽(kuān)32bit,因(yīn)此(cǐ)包(bāo)尾可(kě)能(néng)有(yǒu)无效字(zì)节(jié),而(ér)轉(zhuǎn)換为(wèi)8bit位宽(kuān)數據(jù)幀後(hòu)是(shì)要(yào)丢棄无效字(zì)节(jié)的(de)。內(nèi)部(bù)邏輯非(fēi)常簡單,直(zhí)接上(shàng)代(dài)碼:

`timescale 1ns / 1ps

 

// Description: MAC IP TX方(fāng)向(xiàng)用(yòng)戶數據(jù)緩存及(jí)位宽(kuān)轉(zhuǎn)換模块(kuài)

// 整體(tǐ)功能(néng):将TX方(fāng)向(xiàng)用(yòng)戶32bit位宽(kuān)的(de)數據(jù)包(bāo)轉(zhuǎn)換成(chéng)8bit位宽(kuān)數據(jù)包(bāo)

//用(yòng)戶側时(shí)鐘(zhōng)100MHZMAC125MHZ

//緩存深度(dù):保證能(néng)緩存4个(gè)最(zuì)长數據(jù)包(bāo),TX方(fāng)向(xiàng)用(yòng)戶數據(jù)包(bāo)包(bāo)括

//目的(de)MAC地(dì)址  源MAC地(dì)址 類(lèi)型/长度(dù) 數據(jù) 最(zuì)长1514byte

 

 

module tx_buffer#(parameter DATA_W = 32)//位宽(kuān)不(bù)能(néng)改動(dòng)

(

    

    //全(quán)局(jú)信(xìn)号(hào)

    input                         rst_n,//保證拉低三(sān)个(gè)时(shí)鐘(zhōng)周期(qī),否則FIF可(kě)能(néng)不(bù)会(huì)正(zhèng)确複位

 

    //用(yòng)戶側信(xìn)号(hào)

    input                         user_clk,

    input         [DATA_W-1:0]     din,

    input                         din_vld,

    input                         din_sop,

    input                         din_eop,

    input         [2-1:0]         din_mod,

    output                         rdy,

 

    //MAC側信(xìn)号(hào)

    input                         eth_tx_clk,

    output reg     [8-1:0]         dout,

    output reg                     dout_sop,

    output reg                     dout_eop,

    output reg                     dout_vld

    );

 

 

    reg wr_en = 0;

    reg [DATA_W+4-1:0] fifo_din = 0;

    reg [ (2-1):0]  rd_cnt = 0     ;

    wire        add_rd_cnt ;

    wire        end_rd_cnt ;

    wire rd_en;

    wire [DATA_W+4-1:0] fifo_dout;

    wire rst;

    reg [ (2-1):0]  rst_cnt =0    ;

    wire        add_rst_cnt ;

    wire        end_rst_cnt ;

    reg rst_flag = 0;

    wire [11 : 0] wr_data_count;

    wire empty;

    wire full;

 

/****************************************写側*************************************************/

always  @(posedge user_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        wr_en <= 0;

    end

    else if(rdy)

        wr_en <= din_vld;

end

 

always  @(posedge user_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        fifo_din <= 0;

    end

    else begin//[35] din_sop    [34] din_eop    [33:32] din_mod    [31:0] din

        fifo_din <= {din_sop,din_eop,din_mod,din};

    end

end

 

assign rdy = wr_data_count <= 1516 && !rst && !rst_flag && !full;

 

/****************************************读(dú)側*************************************************/

 

always @(posedge eth_tx_clk or negedge rst_n) begin

    if (rst_n==0) begin

        rd_cnt <= 0;

    end

    else if(add_rd_cnt) begin

        if(end_rd_cnt)

            rd_cnt <= 0;

        else

            rd_cnt <= rd_cnt+1 ;

   end

end

assign add_rd_cnt = (!empty);

assign end_rd_cnt = add_rd_cnt  && rd_cnt == (4)-1 ;

 

assign rd_en = end_rd_cnt;

 

always  @(posedge eth_tx_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        dout <= 0;

    end

    else if(add_rd_cnt)begin

        dout <= fifo_dout[DATA_W-1-rd_cnt*8 -:8];

    end

end

 

always  @(posedge eth_tx_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        dout_vld <= 0;

    end

    else if(add_rd_cnt && ((rd_cnt <= 3 - fifo_dout[33:32] && fifo_dout[34]) || !fifo_dout[34]))begin

        dout_vld <= 1;

    end

    else

        dout_vld <= 0;

end

 

always  @(posedge eth_tx_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        dout_sop <= 0;

    end

    else if(add_rd_cnt && rd_cnt == 0 && fifo_dout[35])begin

        dout_sop <= 1;

    end

    else

        dout_sop <= 0 ;

end

 

always  @(posedge eth_tx_clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        dout_eop <= 0;

    end

    else if(add_rd_cnt && rd_cnt == 3 - fifo_dout[33:32] && fifo_dout[34])begin

        dout_eop <= 1;

    end

    else

        dout_eop <= 0;

end

 

 

/******************************FIFO複位邏輯****************************************/

assign rst = !rst_n || rst_flag;

 

always  @(posedge user_clk or negedge rst_n)begin

    if(!rst_n)begin

        rst_flag <= 1;

    end

    else if(end_rst_cnt)

        rst_flag <= 0;

end

 

always @(posedge user_clk or negedge rst_n) begin

    if (rst_n==0) begin

        rst_cnt <= 0;

    end

    else if(add_rst_cnt) begin

        if(end_rst_cnt)

            rst_cnt <= 0;

        else

            rst_cnt <= rst_cnt+1 ;

   end

end

assign add_rst_cnt = (rst_flag);

assign end_rst_cnt = add_rst_cnt  && rst_cnt == (3)-1 ;

 

 

 

    //FIFO位宽(kuān)32bit 一(yī)幀數據(jù)最(zuì)长1514byte,即379个(gè)16bit數據(jù)

    //FIFO深度(dù):379*4 = 1516  需要(yào)2048

    //异(yì)步FIFO例化(huà)

    fifo_generator_0 fifo (

  .rst(rst),        // input wire rst

  .wr_clk(user_clk),  // input wire wr_clk   100MHZ

  .rd_clk(eth_tx_clk),  // input wire rd_clk  125MHZ

  .din(fifo_din),        // input wire [33 : 0] din

  .wr_en(wr_en),    // input wire wr_en

  .rd_en(rd_en),    // input wire rd_en

  .dout(fifo_dout),      // output wire [33 : 0] dout

  .full(full),      // output wire full

  .empty(empty),    // output wire empty

  .wr_data_count(wr_data_count)  // output wire [11 : 0] wr_data_count

);

 

endmodule

 

tx_buffer

接下(xià)来(lái)是(shì)验(yàn)證部(bù)分(fēn),也(yě)就(jiù)是(shì)本(běn)文(wén)的(de)重(zhòng)點(diǎn)。以(yǐ)下(xià)的(de)testbench包(bāo)含了(le)最(zuì)基本(běn)的(de)测試思(sī)想(xiǎng):發(fà)送测試激勵給(gěi)UUT,将UUT輸出(chū)與(yǔ)黃金(jīn)參考值進(jìn)行比較,通(tòng)过(guò)記(jì)分(fēn)牌(pái)輸出(chū)比較結果(guǒ)。

`timescale 1ns / 1ps

 

module tx_buffer_tb( );

 

parameter USER_CLK_CYC = 10,

          ETH_CLK_CYC = 8,

          RST_TIM = 3;

          

parameter SIM_TIM = 10_000;

 

reg user_clk;

reg rst_n;

reg [32-1:0] din;

reg din_vld,din_sop,din_eop;

reg [2-1:0] din_mod;

wire rdy;

reg eth_tx_clk;

wire [8-1:0] dout;

wire dout_sop,dout_eop,dout_vld;

reg [8-1:0] dout_buf [0:1024-1];

reg [16-1:0] len [0:100-1];

reg [2-1:0] mod [0:100-1];

reg err_flag = 0;

 

tx_buffer#(.DATA_W(32))//位宽(kuān)不(bù)能(néng)改動(dòng)

dut

(

    

    //全(quán)局(jú)信(xìn)号(hào)

   .rst_n      (rst_n) ,//保證拉低三(sān)个(gè)时(shí)鐘(zhōng)周期(qī),否則FIF可(kě)能(néng)不(bù)会(huì)正(zhèng)确複位

   .user_clk   (user_clk) ,

   .din        (din) ,

   .din_vld    (din_vld) ,

   .din_sop    (din_sop) ,

   .din_eop    (din_eop) ,

   .din_mod    (din_mod) ,

   .rdy        (rdy) ,

   .eth_tx_clk (eth_tx_clk) ,

   .dout       (dout) ,

   .dout_sop   (dout_sop) ,

   .dout_eop   (dout_eop) ,

   .dout_vld   (dout_vld)

    );

    

/***********************************时(shí)鐘(zhōng)******************************************/

    initial begin

        user_clk = 1;

        forever #(USER_CLK_CYC/2) user_clk = ~user_clk;

    end

 

    initial begin

        eth_tx_clk = 1;

        forever #(ETH_CLK_CYC/2) eth_tx_clk = ~eth_tx_clk;

    end

/***********************************複位邏輯******************************************/

    initial begin

        rst_n = 1;

        #1;

        rst_n = 0;

        #(RST_TIM*USER_CLK_CYC);

        rst_n = 1;

    end

    

/***********************************輸入(rù)激勵******************************************/

integer gen_time = 0;

    initial begin

        #1;

        packet_initial;

        #(RST_TIM*USER_CLK_CYC);

        packet_gen(20,2);

        #(USER_CLK_CYC*10);

        packet_gen(30,1);

    end

    

/***********************************輸出(chū)緩存與(yǔ)檢测******************************************/    

integer j = 0;

integer chk_time = 0;

    initial begin

        forever begin

            @(posedge eth_tx_clk)

            if(dout_vld)begin    

                if(dout_sop)begin

                    dout_buf[0] = dout;

                    j = 1;

                end

                else if(dout_eop)begin

                    dout_buf[j] = dout;

                    j = j+1;

                    packet_check;

                end

                else begin

                    dout_buf[j] = dout;

                    j = j+1;

                end

            end

        end

    end

    

/***********************************score board******************************************/

integer fid;

    initial begin

        fid = $fopen("test.txt");

        $fdisplay(fid,"                 Start testing                       ");

        #SIM_TIM;

        if(err_flag)

            $fdisplay(fid,"Check is failed ");

        else

            $fdisplay(fid,"Check is successful ");

        $fdisplay(fid,"                 Testing is finished                 ");

        $fclose(fid);

        $stop;

    end

 

/***********************************子任务******************************************/    

//包(bāo)生(shēng)成(chéng)子任务

    task packet_gen;

        input [16-1:0] length;

        input [2-1:0] invalid_byte;

        integer i;

        begin

            len[gen_time] = length;

            mod[gen_time] = invalid_byte;

            

            for(i = 1;i<=length;i=i+1)begin

                if(rdy == 1)begin

                    din_vld = 1;

                    if(i==1)

                        din_sop = 1;

                    else if(i == length)begin

                        din_eop = 1;

                        din_mod = invalid_byte;

                    end

                    else begin

                        din_sop = 0;

                        din_eop = 0;

                        din_mod = 0;

                    end

                    din = i ;

                end

                

                else begin

                    din_sop = din_sop;

                    din_eop = din_eop;

                    din_vld = 0;

                    din_mod = din_mod;

                    din = din;

                    i = i - 1;

                end

                

                #(USER_CLK_CYC*1);

            end

            packet_initial;

            gen_time = gen_time + 1;

        end

    endtask

    

    task packet_initial;

        begin

            din_sop = 0;

            din_eop = 0;

            din_vld = 0;

            din = 0;

            din_mod = 0;

        end

    endtask

 

//包(bāo)檢测子任务

    task packet_check;

        integer k;

        integer num,packet_len;

        begin

            num = 1;

            $fdisplay(fid,"%dth:Packet checking... ",chk_time);

            packet_len = 4*len[chk_time]-mod[chk_time];

            if(j != packet_len)begin

                $fdisplay(fid,"Length of the packet is wrong. ");

                err_flag = 1;

                disable packet_check;

            end

            

            for(k=0;k<packet_len;k=k+1)begin

                if(k%4 == 3)begin

                    if(dout_buf[k] != num)begin

                        $fdisplay(fid,"Data of the packet is wrong! ");

                        err_flag = 1;

                    end

                    num = num+1;

                end    

                else if(dout_buf[k] != 0)begin

                    $fdisplay(fid,"Data of the packet is wrong,it should be zero! ");

                    err_flag = 1;

                end

            end

            chk_time = chk_time + 1;

        end

    endtask

    

endmodule

 

tx_buffer_tb

可(kě)見(jiàn)主(zhǔ)要(yào)是(shì)task編写及(jí)文(wén)件(jiàn)读(dú)写操作幫了(le)大忙,如(rú)果(guǒ)都用(yòng)眼(yǎn)睛看(kàn)波(bō)形来(lái)验(yàn)證設計(jì)正(zhèng)确性(xìng),真(zhēn)的(de)是(shì)要(yào)搞到(dào)眼(yǎn)瞎。为(wèi)保證测試完備性(xìng),测試包(bāo)生(shēng)成(chéng)task可(kě)通(tòng)过(guò)輸入(rù)接口(kǒu)産生(shēng)不(bù)同(tóng)长度(dù)和(hé)无效字(zì)节(jié)數的(de)遞增數據(jù)包(bāo)。testbench中(zhōng)每檢测到(dào)輸出(chū)包(bāo)尾指示信(xìn)号(hào)eop即調用(yòng)packet_check task对(duì)數值進(jìn)行檢测。本(běn)文(wén)的(de)testbench結構較具通(tòng)用(yòng)性(xìng),可(kě)以(yǐ)用(yòng)来(lái)验(yàn)證任意(yì)对(duì)數據(jù)包(bāo)進(jìn)行处理的(de)邏輯單元(yuán)。

之前(qián)Modelsim独立仿真(zhēn)带(dài)有(yǒu)IP核的(de)Vivado工程时(shí)經(jīng)常報錯,只(zhī)好(hǎo)使用(yòng)Vivado自(zì)带(dài)的(de)仿真(zhēn)工具。一(yī)直(zhí)很头(tóu)痛这(zhè)个(gè)問(wèn)題(tí),这(zhè)次(cì)終(zhōng)于(yú)有(yǒu)了(le)進(jìn)展(zhǎn)!首先(xiān)按照常規流程使用(yòng)Vivado調用(yòng)Modelsim進(jìn)行行为(wèi)仿真(zhēn),啟動(dòng)後(hòu)会(huì)在(zài)工程目录(lù)下(xià)産生(shēng)些有(yǒu)用(yòng)的(de)文(wén)件(jiàn),幫助我(wǒ)们(men)脫離Vivado進(jìn)行独立仿真(zhēn)。


在(zài)新建Modelsim工程时(shí),在(zài)紅(hóng)框內(nèi)選擇Vivado工程中(zhōng)<project>.sim -> sim_1 -> behav下(xià)的(de)modelsim.ini文(wén)件(jiàn)。之後(hòu)添加文(wén)件(jiàn)包(bāo)括:待测試設計(jì)文(wén)件(jiàn)、testbench以(yǐ)及(jí)IP核可(kě)綜合文(wén)件(jiàn)。第(dì)三(sān)个(gè)文(wén)件(jiàn)在(zài)<project>.srcs -> sources_1 -> ip -> <ip_name> -> synth下(xià)。


現(xiàn)在(zài)可(kě)以(yǐ)順利啟動(dòng)仿真(zhēn)了(le)。我(wǒ)们(men)来(lái)看(kàn)下(xià)仿真(zhēn)結果(guǒ):



文(wén)件(jiàn)中(zhōng)信(xìn)息打(dǎ)印(yìn)情(qíng)況:



從波(bō)形和(hé)打(dǎ)印(yìn)信(xìn)息的(de)結果(guǒ)来(lái)看(kàn),基本(běn)可(kě)以(yǐ)證明(míng)數據(jù)緩存及(jí)位宽(kuān)轉(zhuǎn)換模块(kuài)邏輯功能(néng)无誤。为(wèi)充分(fēn)验(yàn)證要(yào)進(jìn)一(yī)步給(gěi)出(chū)覆蓋率較高(gāo)的(de)测試數據(jù)集,後(hòu)期(qī)通(tòng)过(guò)編写do文(wén)件(jiàn)批量(liàng)仿真(zhēn)实現(xiàn)。在(zài)FPGA或(huò)IC設計(jì)中(zhōng),验(yàn)證占據(jù)大半開(kāi)發(fà)周期(qī),可(kě)見(jiàn)VerilogHDL的(de)非(fēi)綜合子集也(yě)是(shì)至(zhì)關(guān)重(zhòng)要(yào)的(de),今後(hòu)会(huì)多(duō)總(zǒng)結高(gāo)效的(de)验(yàn)證方(fāng)法!





上(shàng)一(yī)篇(piān):沒(méi)有(yǒu)了(le)
   拓展(zhǎn)閱读(dú)
⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨