基於FPGA的光纖數據傳輸
項目簡述
在這次的實驗中我們主要學習SFP接口的使用,該接口是高速接口主要是使用GTP接口來完成的。本次項目的簡述爲,一塊FPGA開發板通過光纖發送遞增數據,另一塊FPGA開發板通過光纖接收數據並且驗證數據的正確性。本次實驗所用到的軟硬件環境如下:
1、VIVIADO 2019.1軟件開發環境
2、米聯客MA7035FA開發板
3、米聯客MZ7015開發板
Aurora 8B10B的調用
我們接下來將對Aurora 8B10B IP進行講解
1、傳輸數據的位寬,這裏選擇4Byte,也就是說IP的用戶接口數據爲32位寬
2、GTP接口的串行傳輸速率,GTP幾口最大傳輸6.25Gbps,這裏我們直接選擇最大速率傳輸
3、Aurora 8B10B IP的GTP底層接口時鐘,這個與FPGA開發板的GTP時鐘有關,我使用的這兩款開發板都是125MHz,所以我們這裏選擇125MHz
4、Aurora 8B10B IP的初始化時鐘,我們選擇50MHz
5、DRP時鐘,我們在程序中沒有用到DRP有關的操作,這裏也給成50MHz
6、選擇該Aurora 8B10B IP的通信模式,這裏選擇雙工通信
7、數據傳輸的用戶接口,我們這裏使用簡單的AXI4-stream數據接口
8、這裏我們的數據使用小端模式。
大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;這和我們的閱讀習慣一致。
小端模式,是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低。
1、這個按照GTP口的順序進行選擇,該款FPGA一共4對GTP接口,從左下角逆時針循環時0,1,2,3。具體選擇哪一個看FPGA開發板上面的GTP接口使用的第幾對。
1、這裏我們只使用1個IP核,不使用示例工程,所以我們選擇第一個
2、我們這個IP核的初始化時鐘是單端信號,參考時鐘是雙端時鐘,進行相應的選擇。
Aurora 8B10B接口的描述
接下來我們對我們使用的Aurora 8B10B接口進行簡單的描述。
aurora_8b10b_0 your_instance_name (
.s_axi_tx_tdata (s_axi_tx_tdata ), // input wire [31 : 0] s_axi_tx_tdata
.s_axi_tx_tvalid (s_axi_tx_tvalid ), // input wire s_axi_tx_tvalid
.s_axi_tx_tready (s_axi_tx_tready ), // output wire s_axi_tx_tready
.m_axi_rx_tdata (m_axi_rx_tdata ), // output wire [31 : 0] m_axi_rx_tdata
.m_axi_rx_tvalid (m_axi_rx_tvalid ), // output wire m_axi_rx_tvalid
.hard_err (hard_err ), // output wire hard_err
.soft_err (soft_err ), // output wire soft_err
.channel_up (channel_up ), // output wire channel_up
.lane_up (lane_up ), // output wire [0 : 0] lane_up
.txp (txp ), // output wire [0 : 0] txp
.txn (txn ), // output wire [0 : 0] txn
.reset (reset ), // input wire reset
.gt_reset (gt_reset ), // input wire gt_reset
.loopback (loopback ), // input wire [2 : 0] loopback
.rxp (rxp ), // input wire [0 : 0] rxp
.rxn (rxn ), // input wire [0 : 0] rxn
.drpclk_in (drpclk_in ), // input wire drpclk_in
.drpaddr_in (drpaddr_in ),// input wire [8 : 0] drpaddr_in
.drpen_in (drpen_in ), // input wire drpen_in
.drpdi_in (drpdi_in ), // input wire [15 : 0] drpdi_in
.drprdy_out (drprdy_out ),// output wire drprdy_out
.drpdo_out (drpdo_out ), // output wire [15 : 0] drpdo_out
.drpwe_in (drpwe_in ), // input wire drpwe_in
.power_down (power_down ),// input wire power_down
.tx_lock (tx_lock ), // output wire tx_lock
.tx_resetdone_out (tx_resetdone_out ), // output wire tx_resetdone_out
.rx_resetdone_out (rx_resetdone_out ), // output wire rx_resetdone_out
.link_reset_out (link_reset_out ), // output wire link_reset_out
.init_clk_in (init_clk_in ), // input wire init_clk_in
.user_clk_out (user_clk_out ), // output wire user_clk_out
.pll_not_locked_out (pll_not_locked_out ), // output wire pll_not_locked_out
.sys_reset_out (sys_reset_out ), // output wire sys_reset_out
.gt_refclk1_p (gt_refclk1_p ), // input wire gt_refclk1_p
.gt_refclk1_n (gt_refclk1_n ), // input wire gt_refclk1_n
.sync_clk_out (sync_clk_out ), // output wire sync_clk_out
.gt_reset_out (gt_reset_out ), // output wire gt_reset_out
.gt_refclk1_out (gt_refclk1_out ), // output wire gt_refclk1_out
.gt0_pll0refclklost_out (gt0_pll0refclklost_out ), // output wire gt0_pll0refclklost_out
.quad1_common_lock_out (quad1_common_lock_out ), // output wire quad1_common_lock_out
.gt0_pll0outclk_out (gt0_pll0outclk_out ), // output wire gt0_pll0outclk_out
.gt0_pll1outclk_out (gt0_pll1outclk_out ), // output wire gt0_pll1outclk_out
.gt0_pll0outrefclk_out (gt0_pll0outrefclk_out ), // output wire gt0_pll0outrefclk_out
.gt0_pll1outrefclk_out (gt0_pll1outrefclk_out ) // output wire gt0_pll1outrefclk_out
);
1、s_axi_tx_tdata、s_axi_tx_tvalid、s_axi_tx_tready、m_axi_rx_tdata、
m_axi_rx_tvalid信號:AXI4-stream協議的信號,具體的時序要求可以查找一下該協議特別容易理解,如果同學們對這個協議不熟悉,一定要學完這個協議繼續學習。
2、hard_err 、soft_err信號:Aurora 8B10B IP硬件、軟件出錯的提示信號。
3、channel_up 、lane_up信號:兩個Aurora 8B10B IP的初始化完成信號,只有將兩個信號拉高之後,我們纔可以進行進一步的操作。
4、txp、txn信號:GTP的寫差分接口,也就是我們綁引腳的接口。
5、reset、gt_reset信號:分別是Aurora 8B10B IP與GTP接口的復位信號,高有效,通常先復位reset再復位gt_reset,高電平復位。這裏需要注意的是Aurora 8B10B IP在正常使用前一定要復位一段時間。
6、loopback信號:環回[2:0]端口在收發機的正常工作和不同的環回模式之間進行選擇,這裏我們默認爲 0。
7、rxp、rxn信號: GTP的讀差分接口,也是我們綁引腳的接口。
8、drpclk_in、drpaddr_in、drpen_in、drpdi_in、drprdy_out、drpdo_out、drpwe_in信號:DRP相關信號,與資源分配相關一般用不到,時鐘連接定製IP時選擇的50MHz時鐘,其餘的信號輸入寫0輸出忽視即可。
9、power_down信號:掉電信號,1表示IP掉電,正常工作的情況下該位是0信號。
10、init_clk_in信號:Aurora 8B10B IP的初始化時鐘信號。
11、user_clk_out信號:用戶操作的時鐘信號也就是前面AXI4-stream信號的時鐘信號,所有的數據操作都是在這個時鐘域裏面完成的。
其餘的輸出我們這裏用不到也就不進行詳細的詳解,感興趣的同學可以查閱技術手冊。
光纖項目的代碼設計
MZ7015開發板工程
gtp_top模塊:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : gtp_top.v
// Create Time : 2019-12-01 14:20:41
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module gtp_top(
input GTPQ0_P ,
input GTPQ0_N ,
output wire txp ,
output wire txn ,
input rxp ,
input rxn ,
input sclk ,
output wire sfp_tx_disable
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [31:0] s_axi_tx_tdata ;
reg s_axi_tx_tvalid ;
wire s_axi_tx_tready ;
wire [31:0] m_axi_rx_tdata ;
wire m_axi_rx_tvalid ;
wire hard_err ;
wire soft_err ;
wire channel_up ;
wire lane_up ;
reg reset ;
reg gt_reset ;
wire [ 3:0] loopback ;
wire drpclk_in ;
wire [ 8:0] drpaddr_in ;
wire drpen_in ;
wire [15:0] drpdi_in ;
wire drprdy_out ;
wire [15:0] drpdo_out ;
wire drpwe_in ;
wire power_down ;
wire tx_lock ;
wire tx_resetdone_out ;
wire rx_resetdone_out ;
wire link_reset_out ;
wire init_clk_in ;
wire user_clk_out ;
wire pll_not_locked_out ;
wire sys_reset_out ;
wire sync_clk_out ;
wire gt_reset_out ;
wire gt_refclk1_out ;
wire gt0_pll0refclklost_out;
wire quad1_common_lock_out;
wire gt0_pll0outclk_out ;
wire gt0_pll1outclk_out ;
wire gt0_pll0outrefclk_out;
wire gt0_pll1outrefclk_out;
wire locked ;
reg [10:0] gt_reset_cnt ;
reg start_flag ;
reg [31:0] data_cnt ;
reg [11:0] err_cnt ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign drpaddr_in = 9'b000;
assign drpen_in = 1'b0;
assign drpdi_in = 16'd0;
assign drpwe_in = 1'b0;
assign loopback = 3'b000;
assign power_down = ~locked;
assign sfp_tx_disable = 1'b0;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
gt_reset <= 1'b0;
else if(gt_reset_cnt >= 'd500)
gt_reset <= 1'b0;
else if(gt_reset_cnt == 'd100)
gt_reset <= 1'b1;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
gt_reset_cnt <= 11'd0;
else if(gt_reset_cnt[10] == 1'b1)
gt_reset_cnt <= gt_reset_cnt;
else
gt_reset_cnt <= gt_reset_cnt + 1'b1;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
reset <= 1'b1;
else if(gt_reset_cnt >= 'd200)
reset <= 1'b0;
else
reset <= 1'b1;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
start_flag <= 1'b0;
else if(channel_up==1'b1 && lane_up==1'b1)
start_flag <= 1'b1;
else
start_flag <= 1'b0;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
s_axi_tx_tdata <= 32'd0;
else if(s_axi_tx_tvalid==1'b1 && s_axi_tx_tready==1'b1 && start_flag==1'b1)
s_axi_tx_tdata <= s_axi_tx_tdata + 1'b1;
else
s_axi_tx_tdata <= s_axi_tx_tdata;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
s_axi_tx_tvalid <= 1'b0;
else if(start_flag==1'b1)
s_axi_tx_tvalid <= 1'b1;
else
s_axi_tx_tvalid <= 1'b0;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
data_cnt <= 'd0;
else if(m_axi_rx_tvalid == 1'b1)
data_cnt <= data_cnt + 1'b1;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
err_cnt <= 'd0;
else if(m_axi_rx_tvalid==1'b1 && data_cnt!=m_axi_rx_tdata)
err_cnt <= err_cnt + 1'b1;
clk_wiz_0 clk_wiz_0_inst(
// Clock out ports
.clk_out1 (drpclk_in ),
.clk_out2 (init_clk_in ),
.locked (locked ),
.clk_in1 (sclk )
);
aurora_8b10b_0 aurora_8b10b_0_inst (
.s_axi_tx_tdata (s_axi_tx_tdata ), // input wire [0 : 31] s_axi_tx_tdata
.s_axi_tx_tvalid (s_axi_tx_tvalid ), // input wire s_axi_tx_tvalid
.s_axi_tx_tready (s_axi_tx_tready ), // output wire s_axi_tx_tready
.m_axi_rx_tdata (m_axi_rx_tdata ), // output wire [0 : 31] m_axi_rx_tdata
.m_axi_rx_tvalid (m_axi_rx_tvalid ), // output wire m_axi_rx_tvalid
.hard_err (hard_err ), // output wire hard_err
.soft_err (soft_err ), // output wire soft_err
.channel_up (channel_up ), // output wire channel_up
.lane_up (lane_up ), // output wire [0 : 0] lane_up
.txp (txp ), // output wire [0 : 0] txp
.txn (txn ), // output wire [0 : 0] txn
.reset (reset ), // input wire reset
.gt_reset (gt_reset ), // input wire gt_reset
.loopback (loopback ), // input wire [2 : 0] loopback
.rxp (rxp ), // input wire [0 : 0] rxp
.rxn (rxn ), // input wire [0 : 0] rxn
.drpclk_in (drpclk_in ), // input wire drpclk_in
.drpaddr_in (drpaddr_in ), // input wire [8 : 0] drpaddr_in
.drpen_in (drpen_in ), // input wire drpen_in
.drpdi_in (drpdi_in ), // input wire [15 : 0] drpdi_in
.drprdy_out (drprdy_out ), // output wire drprdy_out
.drpdo_out (drpdo_out ), // output wire [15 : 0] drpdo_out
.drpwe_in (drpwe_in ), // input wire drpwe_in
.power_down (power_down ), // input wire power_down
.tx_lock (tx_lock ), // output wire tx_lock
.tx_resetdone_out (tx_resetdone_out ), // output wire tx_resetdone_out
.rx_resetdone_out (rx_resetdone_out ), // output wire rx_resetdone_out
.link_reset_out (link_reset_out ), // output wire link_reset_out
.init_clk_in (init_clk_in ), // input wire init_clk_in
.user_clk_out (user_clk_out ), // output wire user_clk_out
.pll_not_locked_out (pll_not_locked_out ), // output wire pll_not_locked_out
.sys_reset_out (sys_reset_out ), // output wire sys_reset_out
.gt_refclk1_p (GTPQ0_P ), // input wire gt_refclk1_p
.gt_refclk1_n (GTPQ0_N ), // input wire gt_refclk1_n
.sync_clk_out (sync_clk_out ), // output wire sync_clk_out
.gt_reset_out (gt_reset_out ), // output wire gt_reset_out
.gt_refclk1_out (gt_refclk1_out ), // output wire gt_refclk1_out
.gt0_pll0refclklost_out (gt0_pll0refclklost_out ), // output wire gt0_pll0refclklost_out
.quad1_common_lock_out (quad1_common_lock_out ), // output wire quad1_common_lock_out
.gt0_pll0outclk_out (gt0_pll0outclk_out ), // output wire gt0_pll0outclk_out
.gt0_pll1outclk_out (gt0_pll1outclk_out ), // output wire gt0_pll1outclk_out
.gt0_pll0outrefclk_out (gt0_pll0outrefclk_out ), // output wire gt0_pll0outrefclk_out
.gt0_pll1outrefclk_out (gt0_pll1outrefclk_out ) // output wire gt0_pll1outrefclk_out
);
//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/
ila_0 ila_0_inst (
.clk (user_clk_out ), // input wire clk
.probe0 (s_axi_tx_tdata ), // input wire [31:0] probe0
.probe1 (s_axi_tx_tvalid ), // input wire [0:0] probe1
.probe2 (s_axi_tx_tready ), // input wire [0:0] probe2
.probe3 (m_axi_rx_tdata ), // input wire [31:0] probe3
.probe4 (m_axi_rx_tvalid ), // input wire [0:0] probe4
.probe5 (channel_up ), // input wire [0:0] probe5
.probe6 (lane_up ), // input wire [0:0] probe6
.probe7 (data_cnt ), // input wire [0:0] probe5
.probe8 (err_cnt ) // input wire [0:0] probe6
);
endmodule
上面的代碼並不複雜,只需要詳細的讀一下具體的代碼,相信大家可以學會這個接口的使用,因爲我們在程序中主要利用了aurora_8b10b IP核,大大減少了設計的複雜度。但是需要注意的是,我們定製IP與前面我們介紹的有所出入,因爲具體的開發板的不同
MZ7015開發板測試代碼
測試代碼如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/11/30 20:11:24
// Design Name:
// Module Name: gtp_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module gtp_tb;
wire GTPQ0_P ;
wire GTPQ0_N ;
reg sclk ;
reg GTPQ ;
wire txp ;
wire txn ;
wire rxp ;
wire rxn ;
initial begin
sclk = 1'b0;
GTPQ = 1'b0;
end
always #5 sclk = ~sclk;
always #4 GTPQ = ~GTPQ;
assign rxp = txp;
assign rxn = txn;
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW") // Specify the output slew rate
) OBUFDS_inst (
.O(GTPQ0_P), // Diff_p output (connect directly to top-level port)
.OB(GTPQ0_N), // Diff_n output (connect directly to top-level port)
.I(GTPQ) // Buffer input
);
gtp_top gtp_top_inst(
.GTPQ0_P (GTPQ0_P ),
.GTPQ0_N (GTPQ0_N ),
.txp (txp ),
.txn (txn ),
.rxp (rxp ),
.rxn (rxn ),
.sclk (sclk )
);
endmodule
/*
module gtp_tb();
reg clk_m;//50Mhz
reg gtq0;
wire gtq0_n,gtq0_p;
wire txp,txn,rxn,rxp;
initial begin
clk_m = 0;
gtq0 =0;
end
always #5 clk_m = ~clk_m;
always #4 gtq0 = ~gtq0;
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW") // Specify the output slew rate
) OBUFDS_inst (
.O(gtq0_p), // Diff_p output (connect directly to top-level port)
.OB(gtq0_n), // Diff_n output (connect directly to top-level port)
.I(gtq0) // Buffer input
);
assign rxp=txp;
assign rxn=txn;
gtp_top top_aurora_inst(
.GTPQ0_N (gtq0_n),
.GTPQ0_P (gtq0_p),
.txp (txp),
.txn (txn),
.rxp (rxp),
.rxn (rxn),
.sclk (clk_m)
);
endmodule
*/
MA7035FA開發板代碼
該工程的主要代碼如下:
gtp_top模塊
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : gtp_top.v
// Create Time : 2019-12-01 14:20:31
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module gtp_top(
input GTPQ0_P ,
input GTPQ0_N ,
output wire txp ,
output wire txn ,
input rxp ,
input rxn ,
input sclk ,
output wire sfp_tx_disable
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire [31:0] s_axi_tx_tdata ;
reg s_axi_tx_tvalid ;
wire s_axi_tx_tready ;
wire [31:0] m_axi_rx_tdata ;
wire m_axi_rx_tvalid ;
wire hard_err ;
wire soft_err ;
wire channel_up ;
wire lane_up ;
reg reset ;
reg gt_reset ;
wire [ 3:0] loopback ;
wire drpclk_in ;
wire [ 8:0] drpaddr_in ;
wire drpen_in ;
wire [15:0] drpdi_in ;
wire drprdy_out ;
wire [15:0] drpdo_out ;
wire drpwe_in ;
wire power_down ;
wire tx_lock ;
wire tx_resetdone_out ;
wire rx_resetdone_out ;
wire link_reset_out ;
wire init_clk_in ;
wire user_clk_out ;
wire pll_not_locked_out ;
wire sys_reset_out ;
wire sync_clk_out ;
wire gt_reset_out ;
wire gt_refclk1_out ;
wire gt0_pll0refclklost_out;
wire quad1_common_lock_out;
wire gt0_pll0outclk_out ;
wire gt0_pll1outclk_out ;
wire gt0_pll0outrefclk_out;
wire gt0_pll1outrefclk_out;
wire locked ;
reg [10:0] gt_reset_cnt ;
reg start_flag ;
wire [11:0] data_count ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign drpaddr_in = 9'b000;
assign drpen_in = 1'b0;
assign drpdi_in = 16'd0;
assign drpwe_in = 1'b0;
assign loopback = 3'b000;
assign power_down = ~locked;
assign sfp_tx_disable = 1'b0;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
gt_reset <= 1'b0;
else if(gt_reset_cnt >= 'd500)
gt_reset <= 1'b0;
else if(gt_reset_cnt == 'd100)
gt_reset <= 1'b1;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
gt_reset_cnt <= 11'd0;
else if(gt_reset_cnt[10] == 1'b1)
gt_reset_cnt <= gt_reset_cnt;
else
gt_reset_cnt <= gt_reset_cnt + 1'b1;
always @(posedge init_clk_in or negedge locked)
if(locked == 1'b0)
reset <= 1'b1;
else if(gt_reset_cnt >= 'd200)
reset <= 1'b0;
else
reset <= 1'b1;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
start_flag <= 1'b0;
else if(channel_up==1'b1 && lane_up==1'b1)
start_flag <= 1'b1;
else
start_flag <= 1'b0;
always @(posedge user_clk_out or negedge locked)
if(locked == 1'b0)
s_axi_tx_tvalid <= 1'b0;
else if(data_count >= 'd500)
s_axi_tx_tvalid <= 1'b1;
else if(data_count <= 'd10)
s_axi_tx_tvalid <= 1'b0;
else
s_axi_tx_tvalid <= s_axi_tx_tvalid;
fifo_generator_0 fifo_generator_0_inst (
.clk (user_clk_out ), // input wire clk
.srst (~locked ), // input wire srst
.din (m_axi_rx_tdata ), // input wire [31 : 0] din
.wr_en (m_axi_rx_tvalid ), // input wire wr_en
.rd_en (s_axi_tx_tvalid && s_axi_tx_tready), // input wire rd_en
.dout (s_axi_tx_tdata ), // output wire [31 : 0] dout
.full ( ), // output wire full
.empty ( ), // output wire empty
.data_count (data_count ) // output wire [11 : 0] data_count
);
clk_wiz_0 clk_wiz_0_inst(
// Clock out ports
.clk_out1 (drpclk_in ),
.clk_out2 (init_clk_in ),
.locked (locked ),
.clk_in1 (sclk )
);
aurora_8b10b_0 aurora_8b10b_0_inst (
.s_axi_tx_tdata (s_axi_tx_tdata ), // input wire [0 : 31] s_axi_tx_tdata
.s_axi_tx_tvalid (s_axi_tx_tvalid ), // input wire s_axi_tx_tvalid
.s_axi_tx_tready (s_axi_tx_tready ), // output wire s_axi_tx_tready
.m_axi_rx_tdata (m_axi_rx_tdata ), // output wire [0 : 31] m_axi_rx_tdata
.m_axi_rx_tvalid (m_axi_rx_tvalid ), // output wire m_axi_rx_tvalid
.hard_err (hard_err ), // output wire hard_err
.soft_err (soft_err ), // output wire soft_err
.channel_up (channel_up ), // output wire channel_up
.lane_up (lane_up ), // output wire [0 : 0] lane_up
.txp (txp ), // output wire [0 : 0] txp
.txn (txn ), // output wire [0 : 0] txn
.reset (reset ), // input wire reset
.gt_reset (gt_reset ), // input wire gt_reset
.loopback (loopback ), // input wire [2 : 0] loopback
.rxp (rxp ), // input wire [0 : 0] rxp
.rxn (rxn ), // input wire [0 : 0] rxn
.drpclk_in (drpclk_in ), // input wire drpclk_in
.drpaddr_in (drpaddr_in ), // input wire [8 : 0] drpaddr_in
.drpen_in (drpen_in ), // input wire drpen_in
.drpdi_in (drpdi_in ), // input wire [15 : 0] drpdi_in
.drprdy_out (drprdy_out ), // output wire drprdy_out
.drpdo_out (drpdo_out ), // output wire [15 : 0] drpdo_out
.drpwe_in (drpwe_in ), // input wire drpwe_in
.power_down (power_down ), // input wire power_down
.tx_lock (tx_lock ), // output wire tx_lock
.tx_resetdone_out (tx_resetdone_out ), // output wire tx_resetdone_out
.rx_resetdone_out (rx_resetdone_out ), // output wire rx_resetdone_out
.link_reset_out (link_reset_out ), // output wire link_reset_out
.init_clk_in (init_clk_in ), // input wire init_clk_in
.user_clk_out (user_clk_out ), // output wire user_clk_out
.pll_not_locked_out (pll_not_locked_out ), // output wire pll_not_locked_out
.sys_reset_out (sys_reset_out ), // output wire sys_reset_out
.gt_refclk1_p (GTPQ0_P ), // input wire gt_refclk1_p
.gt_refclk1_n (GTPQ0_N ), // input wire gt_refclk1_n
.sync_clk_out (sync_clk_out ), // output wire sync_clk_out
.gt_reset_out (gt_reset_out ), // output wire gt_reset_out
.gt_refclk1_out (gt_refclk1_out ), // output wire gt_refclk1_out
.gt0_pll0refclklost_out (gt0_pll0refclklost_out ), // output wire gt0_pll0refclklost_out
.quad1_common_lock_out (quad1_common_lock_out ), // output wire quad1_common_lock_out
.gt0_pll0outclk_out (gt0_pll0outclk_out ), // output wire gt0_pll0outclk_out
.gt0_pll1outclk_out (gt0_pll1outclk_out ), // output wire gt0_pll1outclk_out
.gt0_pll0outrefclk_out (gt0_pll0outrefclk_out ), // output wire gt0_pll0outrefclk_out
.gt0_pll1outrefclk_out (gt0_pll1outrefclk_out ) // output wire gt0_pll1outrefclk_out
);
endmodule
這裏因爲這個比較簡單,我們便不再給出相應的測試文件,想寫的同學可以試着書寫。
仿真結果
這裏給出我們MZ7015開發板的仿真結果如下:
從圖中可以看出,誤碼的個數爲零,所以證明了我們設計的準確性。
下板結果
由於在家的硬件條件不夠我們沒辦法進行下板測試,但是這個項目我們在學校的時候已經下板測試過了誤碼爲零,從而證明了我們實驗的正確性。
總結
創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。(txt文件、圖片文件在羣中)對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣: