0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FPGA設(shè)計(jì)案例:數(shù)據(jù)緩存模塊設(shè)計(jì)與驗(yàn)證實(shí)驗(yàn)

電子設(shè)計(jì) ? 來(lái)源:csdn ? 作者:沒(méi)落騎士 ? 2020-12-28 13:06 ? 次閱讀

本文設(shè)計(jì)思想采用明德?lián)P至簡(jiǎn)設(shè)計(jì)法。上一篇博文中定制了自定義MAC IP的結(jié)構(gòu),在用戶側(cè)需要位寬轉(zhuǎn)換及數(shù)據(jù)緩存。本文以TX方向?yàn)槔?,設(shè)計(jì)并驗(yàn)證發(fā)送緩存模塊。這里定義該模塊可緩存4個(gè)最大長(zhǎng)度數(shù)據(jù)包,用戶根據(jù)需求改動(dòng)即可。

該模塊核心是利用異步FIFO進(jìn)行跨時(shí)鐘域處理,位寬轉(zhuǎn)換由VerilogHDL實(shí)現(xiàn)。需要注意的是用戶數(shù)據(jù)包位寬32bit,因此包尾可能有無(wú)效字節(jié),而轉(zhuǎn)換為8bit位寬數(shù)據(jù)幀后是要丟棄無(wú)效字節(jié)的。內(nèi)部邏輯非常簡(jiǎn)單,直接上代碼:
`timescale 1ns / 1ps

// Description: MAC IP TX方向用戶數(shù)據(jù)緩存及位寬轉(zhuǎn)換模塊
// 整體功能:將TX方向用戶32bit位寬的數(shù)據(jù)包轉(zhuǎn)換成8bit位寬數(shù)據(jù)包
//用戶側(cè)時(shí)鐘100MHZ,MAC側(cè)125MHZ
//緩存深度:保證能緩存4個(gè)最長(zhǎng)數(shù)據(jù)包,TX方向用戶數(shù)據(jù)包包括
//目的MAC地址 源MAC地址 類型/長(zhǎng)度 數(shù)據(jù) 最長(zhǎng)1514byte

module tx_buffer#(parameter DATA_W = 32)//位寬不能改動(dòng)
(

//全局信號(hào)
input rst_n,//保證拉低三個(gè)時(shí)鐘周期,否則FIF可能不會(huì)正確復(fù)位

//用戶側(cè)信號(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側(cè)信號(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;

/****************************************寫側(cè)*************************************************/
always @(posedge user_clk or negedge rst_n)begin
if(rst_n==1'b0)begin
wr_en end
else if(rdy)
wr_en end

always @(posedge user_clk or negedge rst_n)begin
if(rst_n==1'b0)begin
fifo_din end
else begin//[35] din_sop [34] din_eop [33:32] din_mod [31:0] din
fifo_din end
end

assign rdy = wr_data_count

/****************************************讀側(cè)*************************************************/

always @(posedge eth_tx_clk or negedge rst_n) begin
if (rst_n==0) begin
rd_cnt end
else if(add_rd_cnt) begin
if(end_rd_cnt)
rd_cnt else
rd_cnt 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 end
else if(add_rd_cnt)begin
dout end
end

always @(posedge eth_tx_clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_vld end
else if(add_rd_cnt && ((rd_cnt dout_vld end
else
dout_vld end

always @(posedge eth_tx_clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_sop end
else if(add_rd_cnt && rd_cnt == 0 && fifo_dout[35])begin
dout_sop end
else
dout_sop end

always @(posedge eth_tx_clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_eop end
else if(add_rd_cnt && rd_cnt == 3 - fifo_dout[33:32] && fifo_dout[34])begin
dout_eop end
else
dout_eop end

/******************************FIFO復(fù)位邏輯****************************************/
assign rst = !rst_n || rst_flag;

always @(posedge user_clk or negedge rst_n)begin
if(!rst_n)begin
rst_flag end
else if(end_rst_cnt)
rst_flag end

always @(posedge user_clk or negedge rst_n) begin
if (rst_n==0) begin
rst_cnt end
else if(add_rst_cnt) begin
if(end_rst_cnt)
rst_cnt else
rst_cnt end
end
assign add_rst_cnt = (rst_flag);
assign end_rst_cnt = add_rst_cnt && rst_cnt == (3)-1 ;

//FIFO位寬32bit 一幀數(shù)據(jù)最長(zhǎng)1514byte,即379個(gè)16bit數(shù)據(jù)
//FIFO深度:379*4 = 1516 需要2048
//異步FIFO例化
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

接下來(lái)是驗(yàn)證部分,也就是本文的重點(diǎn)。以下的testbench包含了最基本的測(cè)試思想:發(fā)送測(cè)試激勵(lì)給UUT,將UUT輸出與黃金參考值進(jìn)行比較,通過(guò)記分牌輸出比較結(jié)果。
`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))//位寬不能改動(dòng)
dut
(

//全局信號(hào)
.rst_n (rst_n) ,//保證拉低三個(gè)時(shí)鐘周期,否則FIF可能不會(huì)正確復(fù)位
.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í)鐘******************************************/
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
/***********************************復(fù)位邏輯******************************************/
initial begin
rst_n = 1;
#1;
rst_n = 0;
#(RST_TIM*USER_CLK_CYC);
rst_n = 1;
end

/***********************************輸入激勵(lì)******************************************/
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

/***********************************輸出緩存與檢測(cè)******************************************/
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 /n");
#SIM_TIM;
if(err_flag)
$fdisplay(fid,"Check is failed/n");
else
$fdisplay(fid,"Check is successful/n");
$fdisplay(fid," Testing is finished /n");
$fclose(fid);
$stop;
end

/***********************************子任務(wù)******************************************/
//包生成子任務(wù)
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 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

//包檢測(cè)子任務(wù)
task packet_check;
integer k;
integer num,packet_len;
begin
num = 1;
$fdisplay(fid,"%dth:Packet checking.../n",chk_time);
packet_len = 4*len[chk_time]-mod[chk_time];
if(j != packet_len)begin
$fdisplay(fid,"Length of the packet is wrong./n");
err_flag = 1;
disable packet_check;
end

for(k=0;k
if(k%4 == 3)begin
if(dout_buf[k] != num)begin
$fdisplay(fid,"Data of the packet is wrong!/n");
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!/n");
err_flag = 1;
end
end
chk_time = chk_time + 1;
end
endtask

endmodule

tx_buffer_tb

可見(jiàn)主要是task編寫及文件讀寫操作幫了大忙,如果都用眼睛看波形來(lái)驗(yàn)證設(shè)計(jì)正確性,真的是要搞到眼瞎。為保證測(cè)試完備性,測(cè)試包生成task可通過(guò)輸入接口產(chǎn)生不同長(zhǎng)度和無(wú)效字節(jié)數(shù)的遞增數(shù)據(jù)包。testbench中每檢測(cè)到輸出包尾指示信號(hào)eop即調(diào)用packet_check task對(duì)數(shù)值進(jìn)行檢測(cè)。本文的testbench結(jié)構(gòu)較具通用性,可以用來(lái)驗(yàn)證任意對(duì)數(shù)據(jù)包進(jìn)行處理的邏輯單元。

之前Modelsim獨(dú)立仿真帶有IP核的Vivado工程時(shí)經(jīng)常報(bào)錯(cuò),只好使用Vivado自帶的仿真工具。一直很頭痛這個(gè)問(wèn)題,這次終于有了進(jìn)展!首先按照常規(guī)流程使用Vivado調(diào)用Modelsim進(jìn)行行為仿真,啟動(dòng)后會(huì)在工程目錄下產(chǎn)生些有用的文件,幫助我們脫離Vivado進(jìn)行獨(dú)立仿真。

在新建Modelsim工程時(shí),在紅框內(nèi)選擇Vivado工程中
.sim -> sim_1 -> behav下的modelsim.ini文件。之后添加文件包括:待測(cè)試設(shè)計(jì)文件、testbench以及IP核可綜合文件。第三個(gè)文件在
.srcs -> sources_1 -> ip -> -> synth下。

o4YBAF9uIlCAEUzAAACig9pDNm4320.png

現(xiàn)在可以順利啟動(dòng)仿真了。我們來(lái)看下仿真結(jié)果:

文件中信息打印情況:

從波形和打印信息的結(jié)果來(lái)看,基本可以證明數(shù)據(jù)緩存及位寬轉(zhuǎn)換模塊邏輯功能無(wú)誤。為充分驗(yàn)證要進(jìn)一步給出覆蓋率較高的測(cè)試數(shù)據(jù)集,后期通過(guò)編寫do文件批量仿真實(shí)現(xiàn)。在FPGAIC設(shè)計(jì)中,驗(yàn)證占據(jù)大半開(kāi)發(fā)周期,可見(jiàn)VerilogHDL的非綜合子集也是至關(guān)重要的,今后會(huì)多總結(jié)高效的驗(yàn)證方法!

編輯:hfy


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1624

    文章

    21573

    瀏覽量

    600688
  • 數(shù)據(jù)緩存
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    7034
  • VerilogHDL
    +關(guān)注

    關(guān)注

    2

    文章

    39

    瀏覽量

    19062
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【紫光同創(chuàng)盤古PGX-Nano教程】——(盤古PGX-Nano開(kāi)發(fā)板/PG2L50H_MBG324第二章)按鍵消抖實(shí)驗(yàn)例程

    logos2 系列 28nm 工藝的 FPGA(PG2L50H_MBG324)。集成下載器芯片,極大的便利 了用戶的使用。 板卡搭載一顆容量為 2MB 的 SRAM 用于數(shù)據(jù)緩存,DAC 芯片用于
    發(fā)表于 04-28 17:57

    基于FPGA開(kāi)發(fā)板的GPS模擬器數(shù)據(jù)采集驗(yàn)證

    必須將GPS模擬器的數(shù)據(jù)通過(guò)FPGA開(kāi)發(fā)板進(jìn)行短時(shí)間的采集,至少能用于matlab算法上的捕獲驗(yàn)證,這個(gè)采集時(shí)間至少要幾ms。
    發(fā)表于 04-25 10:31 ?684次閱讀
    基于<b class='flag-5'>FPGA</b>開(kāi)發(fā)板的GPS模擬器<b class='flag-5'>數(shù)據(jù)</b>采集<b class='flag-5'>驗(yàn)證</b>

    fpga原型驗(yàn)證平臺(tái)與硬件仿真器的區(qū)別

    FPGA原型驗(yàn)證平臺(tái)與硬件仿真器在芯片設(shè)計(jì)和驗(yàn)證過(guò)程中各自發(fā)揮著獨(dú)特的作用,它們之間存在明顯的區(qū)別。
    的頭像 發(fā)表于 03-15 15:07 ?953次閱讀

    fpga原型驗(yàn)證流程

    FPGA原型驗(yàn)證流程是確保FPGA(現(xiàn)場(chǎng)可編程門陣列)設(shè)計(jì)正確性和功能性的關(guān)鍵步驟。它涵蓋了從設(shè)計(jì)實(shí)現(xiàn)到功能驗(yàn)證的整個(gè)過(guò)程,是FPGA開(kāi)發(fā)流
    的頭像 發(fā)表于 03-15 15:05 ?1319次閱讀

    fpga驗(yàn)證和測(cè)試的區(qū)別

    FPGA驗(yàn)證和測(cè)試在芯片設(shè)計(jì)和開(kāi)發(fā)過(guò)程中都扮演著重要的角色,但它們各自有著不同的側(cè)重點(diǎn)和應(yīng)用場(chǎng)景。
    的頭像 發(fā)表于 03-15 15:03 ?928次閱讀

    fpga驗(yàn)證和uvm驗(yàn)證的區(qū)別

    FPGA驗(yàn)證和UVM驗(yàn)證在芯片設(shè)計(jì)和驗(yàn)證過(guò)程中都扮演著重要的角色,但它們之間存在明顯的區(qū)別。
    的頭像 發(fā)表于 03-15 15:00 ?1319次閱讀

    FPGA資源與AISC對(duì)應(yīng)關(guān)系

    邏輯功能。 存儲(chǔ)塊(Block RAM):用于數(shù)據(jù)緩存和存儲(chǔ)。 數(shù)字信號(hào)處理模塊(DSP Blocks):用于高效地執(zhí)行數(shù)字信號(hào)處理任務(wù)。 輸入/輸出模塊(I/O Blocks):用于
    發(fā)表于 02-22 09:52

    原型平臺(tái)是做什么的?proFPGA驗(yàn)證環(huán)境介紹

    proFPGA是mentor的FPGA原型驗(yàn)證平臺(tái),當(dāng)然mentor被西門子收購(gòu)之后,現(xiàn)在叫西門子EDA。
    的頭像 發(fā)表于 01-22 09:21 ?1232次閱讀
    原型平臺(tái)是做什么的?pro<b class='flag-5'>FPGA</b><b class='flag-5'>驗(yàn)證</b>環(huán)境介紹

    什么是FPGA原型驗(yàn)證?FPGA原型設(shè)計(jì)的好處是什么?

    FPGA原型設(shè)計(jì)是一種成熟的技術(shù),用于通過(guò)將RTL移植到現(xiàn)場(chǎng)可編程門陣列(FPGA)來(lái)驗(yàn)證專門應(yīng)用的集成電路(ASIC),專用標(biāo)準(zhǔn)產(chǎn)品(ASSP)和片上系統(tǒng)(SoC)的功能和性能。
    發(fā)表于 01-12 16:13 ?1046次閱讀

    labview怎么清除串口緩存數(shù)據(jù)

    LabVIEW 是一款功能強(qiáng)大的圖形化編程軟件,常用于控制、監(jiān)測(cè)和數(shù)據(jù)采集等應(yīng)用。當(dāng)我們使用串口進(jìn)行數(shù)據(jù)通信時(shí),有時(shí)會(huì)遇到串口緩存數(shù)據(jù)無(wú)法及時(shí)清除或清除不徹底的情況。解決這個(gè)問(wèn)題的方
    的頭像 發(fā)表于 01-08 11:30 ?3216次閱讀

    靈動(dòng)微電子汽車芯片測(cè)試驗(yàn)證實(shí)驗(yàn)室通過(guò)國(guó)家CNAS認(rèn)證

    近日,上海靈動(dòng)微電子股份有限公司(以下簡(jiǎn)稱“靈動(dòng)微電子”)的汽車芯片測(cè)試驗(yàn)證實(shí)驗(yàn)室(以下簡(jiǎn)稱“車規(guī)實(shí)驗(yàn)室”)已順利通過(guò)中國(guó)合格評(píng)定國(guó)家認(rèn)可委員會(huì)(CNAS)的嚴(yán)格評(píng)審,正式獲授能力認(rèn)可證書。
    的頭像 發(fā)表于 12-28 17:08 ?1088次閱讀
    靈動(dòng)微電子汽車芯片測(cè)試<b class='flag-5'>驗(yàn)證實(shí)驗(yàn)</b>室通過(guò)國(guó)家CNAS認(rèn)證

    Redis緩存預(yù)熱+緩存雪崩+緩存擊穿+緩存穿透要點(diǎn)簡(jiǎn)析

    緩存預(yù)熱就是系統(tǒng)上線后,提前將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)。
    的頭像 發(fā)表于 12-25 09:41 ?785次閱讀
    Redis<b class='flag-5'>緩存</b>預(yù)熱+<b class='flag-5'>緩存</b>雪崩+<b class='flag-5'>緩存</b>擊穿+<b class='flag-5'>緩存</b>穿透要點(diǎn)簡(jiǎn)析

    mybatis一級(jí)緩存和二級(jí)緩存的原理

    MyBatis是一種輕量級(jí)的持久化框架,它提供了一級(jí)緩存和二級(jí)緩存的機(jī)制來(lái)優(yōu)化數(shù)據(jù)庫(kù)操作性能。一級(jí)緩存是默認(rèn)開(kāi)啟的,而二級(jí)緩存需要手動(dòng)配置啟
    的頭像 發(fā)表于 12-03 11:55 ?1006次閱讀

    阿里達(dá)摩院裁撤量子實(shí)驗(yàn)證實(shí)!

    據(jù)阿里達(dá)摩院證實(shí),他們已經(jīng)決定裁撤量子實(shí)驗(yàn)室,并將實(shí)驗(yàn)室及儀器設(shè)備捐贈(zèng)給浙江大學(xué)。這一舉措的目的是為了促進(jìn)量子科技的協(xié)同發(fā)展,并將捐贈(zèng)的實(shí)驗(yàn)室和設(shè)備開(kāi)放給浙江大學(xué)及其他高校和科研機(jī)構(gòu)使
    的頭像 發(fā)表于 11-28 18:20 ?1037次閱讀

    Socket緩存如何影響TCP的性能

    白。下面我們就構(gòu)建起一個(gè)簡(jiǎn)單的實(shí)驗(yàn)環(huán)境,在兩臺(tái)虛擬機(jī)之間探究一下Socket緩存究竟如何影響TCP的性能?對(duì)分析過(guò)程不感興趣的可以直接看最后的結(jié)論。 影響Socket緩存的參數(shù) 首先,我們要先來(lái)列出Linux中可以影響Socke
    的頭像 發(fā)表于 11-09 10:13 ?531次閱讀