- `timescale 1ns / 1ps
- module rst_ctrl(
- input wire clk ,
- input wire start_en ,
- output wire reset ,// 系统复位
- output wire gt_reset // 收发器复位
- );
- //parameter define
- parameter GT_RESET_START = 128 ;
- parameter GT_RESET_END = 384 ;
- parameter RESET_MAX = GT_RESET_END + GT_RESET_START;
- //reg define
- reg reset_r ;
- reg gt_reset_r ;
- reg reset_busy =0;//复位忙指示信号
- reg [1:0] start_flag_dly =0;//复位使能信号延时
- reg [10:0] cnt_rst =0;//用于产生复位信号的计数器
- //wire define
- assign reset = reset_r ;
- assign gt_reset = gt_reset_r;
- //起始信号边沿
- wire link_up_n = !start_flag_dly[1]&&start_flag_dly[0];
- //start_flag_dly
- always @(posedge clk) begin
- start_flag_dly <= {start_flag_dly[0], start_en};
- end
- //复位忙指示信号
- always @(posedge clk) begin
- if(link_up_n==1) begin
- reset_busy <= 1;
- end
- else if(cnt_rst== RESET_MAX - 1)begin
- reset_busy <= 0;
- end
- end
- //复位计数器
- always @(posedge clk) begin
- if (reset_busy == 'd1) begin
- if(reset_busy == 'd1 && (cnt_rst == RESET_MAX - 1))
- cnt_rst <= 'd0;
- else
- cnt_rst <= cnt_rst + 1'b1;
- end
- else begin
- cnt_rst <= 'd0;
- end
- end
- //gt_reset
- always @(posedge clk) begin
- if (reset_busy == 'd1) begin
- if(cnt_rst == GT_RESET_START - 1) begin
- gt_reset_r <= 1'b1;
- end
- else if (cnt_rst == GT_RESET_END - 1|| cnt_rst == 0 ) begin
- gt_reset_r <= 1'b0;
- end
- else begin
- gt_reset_r <= gt_reset_r;
- end
- end
- else begin
- gt_reset_r <= 1'b0;
- end
- end
- //reset
- always @(posedge clk) begin
- if (reset_busy == 'd1) begin
- reset_r <= 1'b1;
- end
- else begin
- reset_r <= 1'b0;
- end
- end
- endmodule
发送模块
发送部分就是简单的模拟AXI总线协议进行发送,这里指定了几个参数,方便后期移植修改,同时又例化了一个ILA IP用于检测上板时数据正确性。
- `timescale 1ns / 1ps
- module Aurora_Tx #(
- parameter DATA_WIDTH = 32, // DATA bus width
- parameter TKEEP_WIDTH = DATA_WIDTH/8, // TKEEP width
- parameter STREAM_LEN = 1024 ,
- parameter REG_MAX_BURST = 15
- )
- (
- input wire clk ,
- input wire rst ,
- output wire [0 : DATA_WIDTH-1] s_axi_tx_tdata ,
- output wire [0 : TKEEP_WIDTH-1] s_axi_tx_tkeep ,
- output wire s_axi_tx_tlast ,
- output wire s_axi_tx_tvalid ,
- input wire s_axi_tx_tready
- );
- //reg define
- reg [0:DATA_WIDTH-1] axi_tx_tdata ;
- reg axi_tx_tlast ;
- reg axi_tx_tvalid ;
- reg [REG_MAX_BURST:0] cnt_data ;
- //wire define
- wire cnt_data_tlast ;
- assign s_axi_tx_tdata = axi_tx_tdata;
- assign s_axi_tx_tkeep = 4'hF ;
- assign s_axi_tx_tlast = axi_tx_tlast;
- assign s_axi_tx_tvalid = axi_tx_tvalid;
- assign cnt_data_tlast = (s_axi_tx_tready==1) && (axi_tx_tvalid==1) && (cnt_data == STREAM_LEN - 1);
- //cnt_data
- always @(posedge clk) begin
- if(rst==1)begin
- cnt_data <= 'd0;
- end
- else if ((s_axi_tx_tready==1) && (axi_tx_tvalid==1)) begin
- if(cnt_data_tlast==1)
- cnt_data <= 'd0;
- else
- cnt_data <= cnt_data + 1'b1;
- end
- end
- //axi_tx_tlast
- always @(*) begin
- axi_tx_tlast = cnt_data_tlast;
- end
- //axi_tx_tvalid
- always @(posedge clk) begin
- if(rst==1)begin
- axi_tx_tvalid <= 1'b0;
- end
- else if (cnt_data_tlast == 1'b1) begin
- axi_tx_tvalid <= 1'b0;
- end
- else if (axi_tx_tvalid == 1'b0 && s_axi_tx_tready == 1'b1) begin
- axi_tx_tvalid <= 1'b1;
- end
- end
- //axi_tx_tdata
- always @(*) begin
- axi_tx_tdata = cnt_data;
- end
- wire [63:0] probe0;
- assign probe0 = {
- s_axi_tx_tdata ,//32
- s_axi_tx_tkeep ,//4
- s_axi_tx_tlast ,//1
- s_axi_tx_tvalid ,//1
- s_axi_tx_tready ,//1
- cnt_data //16
- };
- ila_0 u_tx (
- .clk(clk), // input wire clk
- .probe0(probe0) // input wire [63:0] probe0
- );
- endmodule
接收模块
接收部分就是简单的模拟AXI总线协议接收数据,这里也指定了几个参数,方便后期移植修改,同时又例化了一个ILA IP用于检测上板时数据正确性。
- module Aurora_Rx #(
- parameter DATA_WIDTH = 32, // DATA bus width
- parameter TKEEP_WIDTH = DATA_WIDTH/8, // TKEEP width
- parameter STREAM_LEN = 1024 ,
- parameter REG_MAX_BURST = 15
- )(
- input wire clk ,
- input wire rst ,
- input wire [0 : DATA_WIDTH-1] m_axi_rx_tdata ,
- input wire [0 : TKEEP_WIDTH-1] m_axi_rx_tkeep ,
- input wire m_axi_rx_tlast ,
- input wire m_axi_rx_tvalid
- );
- //reg define
- reg [REG_MAX_BURST:0] cnt_burst ;
- reg error_r ;
- always @(posedge clk) begin
- if(rst==1)begin
- cnt_burst <= 'd0;
- end
- else if (m_axi_rx_tvalid == 1) begin
- if(m_axi_rx_tvalid == 1 && cnt_burst == STREAM_LEN - 1)
- cnt_burst <= 'd0;
- else
- cnt_burst <= cnt_burst + 1'b1;
- end
- end
- //check
- always @(posedge clk) begin
- if(rst==1)begin
- error_r <= 'd0;
- end
- else if (m_axi_rx_tvalid==1 && (m_axi_rx_tdata != cnt_burst)) begin
- error_r <= 1'b1;
- end
- end
- wire [63:0] probe0;
- assign probe0 = {
- m_axi_rx_tdata ,
- m_axi_rx_tkeep ,
- m_axi_rx_tlast ,
- m_axi_rx_tvalid ,
- error_r ,
- cnt_burst
- };
- ila_0 u_rx (
- .clk(clk), // input wire clk
- .probe0(probe0) // input wire [63:0] probe0
- );
- endmodule
顶层连接
根据前面绘制的框图连接上述各个模块,例化了一个VIO IP进行检测和控制复位。
- `timescale 1ns / 1ps
- module Aurora_Top(
- //clock---------------------------------
- input clk_in, //系统钟
- input gt_refclk116_p , //差分参考钟
- input gt_refclk116_n , //差分参考钟
- //Serial I/O----------------------------
- input rxp ,
- input rxn ,
- output txp ,
- output txn ,
- //--------------------------------------
- output tx_dis ,
- output led_link_up
- );
- //==========================================
- //wire define
- wire start;
- //------------------------------SEND--------------------------------------------
- // AXI TX Interface
- wire [0 : 31] s_axi_tx_tdata ;
- wire [0 : 3] s_axi_tx_tkeep ;
- wire s_axi_tx_tlast ;
- wire s_axi_tx_tvalid ;
- wire s_axi_tx_tready ;
- //------------------------------RECEIVE-----------------------------------------
- // AXI RX Interface
- wire [0 : 31] m_axi_rx_tdata ;
- wire [0 : 3] m_axi_rx_tkeep ;
- wire m_axi_rx_tlast ;
- wire m_axi_rx_tvalid ;
- //------------------------------SYSTEM------------------------------------------
- // reset IO,test
- wire reset;
- wire gt_reset;
- wire [2 : 0] loopback;
- //------------------------------clock-------------------------------------------
- // GT Reference Clock Interface
- wire gt_refclk1_p;
- wire gt_refclk1_n;
- wire init_clk_in ;
- wire user_clk_out;
- wire sync_clk_out;
- wire gt_refclk1_out;
- //--------------------------------drp-------------------------------------------
- //drp Interface
- wire drpclk_in ;
- //-----------------------------Status Detection--------------------------------
- // Error Detection Interface
- wire hard_err ;
- wire soft_err ;
- wire frame_err;
- // Status link
- wire channel_up;
- wire lane_up;
- wire sys_reset_out;
- //==========================================
- //wire assign
- assign tx_dis = 0;
- assign gt_refclk116_p =gt_refclk1_p;
- assign gt_refclk116_n =gt_refclk1_n;
- assign led_link_up = channel_up & lane_up;
- assign init_clk_in = clk_in;
- assign drpclk_in = clk_in;
- wire sys_rst = ~(channel_up & lane_up & (~sys_reset_out));
-
- rst_ctrl u_rst_ctrl(
- .clk ( init_clk_in ),
- .start_en ( start ),
- .reset ( reset ),
- .gt_reset ( gt_reset )
- );
- Aurora_Tx u_Aurora_Tx(
- .clk ( user_clk_out ),
- .rst ( start ),
- .s_axi_tx_tdata ( s_axi_tx_tdata ),
- .s_axi_tx_tkeep ( s_axi_tx_tkeep ),
- .s_axi_tx_tlast ( s_axi_tx_tlast ),
- .s_axi_tx_tvalid ( s_axi_tx_tvalid ),
- .s_axi_tx_tready ( s_axi_tx_tready )
- );
- Aurora_Rx u_Aurora_Rx(
- .clk ( user_clk_out ),
- .rst ( start ),
- .m_axi_rx_tdata ( m_axi_rx_tdata ),
- .m_axi_rx_tkeep ( m_axi_rx_tkeep ),
- .m_axi_rx_tlast ( m_axi_rx_tlast ),
- .m_axi_rx_tvalid ( m_axi_rx_tvalid )
- );
- aurora_8b10b_0 u_aurora(
- //------------------------------SEND--------------------------------------------
- // AXI TX Interface
- .s_axi_tx_tdata (s_axi_tx_tdata ), // input wire [0 : 31] s_axi_tx_tdata
- .s_axi_tx_tkeep (s_axi_tx_tkeep ), // input wire [0 : 3] s_axi_tx_tkeep
- .s_axi_tx_tlast (s_axi_tx_tlast ), // input wire s_axi_tx_tlast
- .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
- //------------------------------RECEIVE-----------------------------------------
- // AXI RX Interface
- .m_axi_rx_tdata (m_axi_rx_tdata ), // output wire [0 : 31] m_axi_rx_tdata
- .m_axi_rx_tkeep (m_axi_rx_tkeep ), // output wire [0 : 3] m_axi_rx_tkeep
- .m_axi_rx_tlast (m_axi_rx_tlast ), // output wire m_axi_rx_tlast
- .m_axi_rx_tvalid(m_axi_rx_tvalid), // output wire m_axi_rx_tvalid
- //------------------------------SYSTEM------------------------------------------
- // reset IO,test
- .reset(reset), // input wire reset
- .gt_reset(gt_reset), // input wire gt_reset
- .loopback(loopback), // input wire [2 : 0] loopback
- //--------------------------------Serial I/O------------------------------------
- .txp(txp), // output wire [0 : 0] txp
- .txn(txn), // output wire [0 : 0] txn
- .rxp(rxp), // input wire [0 : 0] rxp
- .rxn(rxn), // input wire [0 : 0] rxn
- //------------------------------clock-------------------------------------------
- // GT Reference Clock Interface
- .gt_refclk1_p(gt_refclk1_p), // input wire gt_refclk1_p
- .gt_refclk1_n(gt_refclk1_n), // input wire gt_refclk1_n
- .init_clk_in(init_clk_in), // input wire init_clk_in
- //--------------------------------drp-------------------------------------------
- //drp Interface
- .drpclk_in(drpclk_in), // input wire drpclk_in
- .drpaddr_in(0), // input wire [8 : 0] drpaddr_in
- .drpen_in(0), // input wire drpen_in
- .drpdi_in(0), // input wire [15 : 0] drpdi_in
- .drprdy_out(), // output wire drprdy_out
- .drpdo_out(), // output wire [15 : 0] drpdo_out
- .drpwe_in(0), // input wire drpwe_in
- //-----------------------------Status Detection--------------------------------
- // Error Detection Interface
- .hard_err (hard_err ), // output wire hard_err
- .soft_err (soft_err ), // output wire soft_err
- .frame_err(frame_err), // output wire frame_err
- // Status
- .power_down(0), // input wire power_down
- .channel_up(channel_up), // output wire channel_up
- .lane_up(lane_up), // output wire [0 : 0] lane_up
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- .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
- .pll_not_locked_out(pll_not_locked_out), // output wire pll_not_locked_out
- //reset_out
- .gt_reset_out(gt_reset_out), // output wire gt_reset_out
- .link_reset_out(link_reset_out), // output wire link_reset_out
- .sys_reset_out(sys_reset_out), // output wire sys_reset_out
- //clk_out
- .user_clk_out(user_clk_out), // output wire user_clk_out
- .sync_clk_out(), // output wire sync_clk_out
- .gt_refclk1_out(), // output wire gt_refclk1_out
- //qplllock_out
- .gt0_qplllock_out(), // output wire gt0_qplllock_out
- .gt0_qpllrefclklost_out(), // output wire gt0_qpllrefclklost_out
- .gt_qpllclk_quad2_out(), // output wire gt_qpllclk_quad2_out
- .gt_qpllrefclk_quad2_out() // output wire gt_qpllrefclk_quad2_out
- );
-
- vio_0 Status_dect (
- .clk(user_clk_out), // input wire clk
- .probe_in0(hard_err), // input wire [0 : 0] probe_in0
- .probe_in1(soft_err), // input wire [0 : 0] probe_in1
- .probe_in2(frame_err), // input wire [0 : 0] probe_in2
- .probe_in3(channel_up), // input wire [0 : 0] probe_in3
- .probe_in4(lane_up), // input wire [0 : 0] probe_in4
- .probe_out0(loopback), // output wire [2 : 0] probe_out0
- .probe_out1(start) // output wire [0 : 0] probe_out1
- );
- endmodule
下板测试
设置loopback的默认值为0,或者不为0的先设置为0,然后设置为0 ,然后设置模式为近端回环测试,1或2都可。则可以看到channel_up和lane_up都拉高,连接建立。start信号拉高复位,然后置零可去发送接收的窗口观察信号收发是否正确。
发送部分的ILA窗口抓取到数据正常发送,同时满足AXI的协议。
接收部分的ILA窗口抓取到数据正常接收,同时满足AXI的协议,error指示信号常为低,证明数据传输正常,链路稳定。