设备:zynq7100;
开发环境:window
vivado版本:2021.1
一、aurora ip核的使用-回环测试
1.1 IP核的配置
GT Refclk :GT参考时钟,这里我所用的时钟是100MHZ。
Lane Rate : 链路数据传输速率Gbps,这里我使用10Gbps。
INIT clk :初始化时钟,我使用的100MHZ。
GT DRP clk:用户时钟,保持默认
user_clk:即数据的时钟,接受和发射数据的时钟,计算公式如下:
例如:10Gbps的64B66
user_clk = 10*1000 / 64 = 156.25Mhz
Dataflow Mode:数据流模式:选择全双工
Interface:接口类型:Framing类型
little Ednian support:小端数据(小端:[15:0] 大端:[0:15])
Lanes:通道数,这里我只使用了一个通道,其余选项保持默认。
Shared Logic:设置IP的逻辑放置的位置
In core:在IP核内:support、复位、时钟等逻辑在ip内
In example design:在例子中,逻辑都在ip外
这里我选择的是在ip内,由于我没有差分初始化信号,所以我使能了Single Ended INT CLK。
1.2 IP的使用
GT_DIFF_REFCLK1:初始化时钟,绑定晶振时钟即可。
GT_SERIAL_RX:GT的接受端口,绑定外部引脚即可。
channel_up以及lane_up:建链信号,高有效,这里我相与接到led灯上,当灯亮时表示建链成功。
hard_err以及soft_err:传输错误信号,高有效,这里我相与接到led灯上,当灯亮时表示建链传输过程中出现错误。
gt_rxcdrovrden_in以及powder_down: 给到常值0;
reset_pb以及pma_init:这俩分别是aurora全局复位和硬件资源复位的控制信号,如果作为控制使用约束至开关或按钮,但是!如果不做控制,也一定要给到常值0,不能悬空不接,否则aurora模块无法正常工作。
loopback[2:0]:设置aurora的回环模式,默认给到000,按照手册里的来就行。
最后的bd图,如下图所示:
由图片可以看到IP的调用十分的简单,其中我自己加了一个数据生成模块,用于两个板子之间的通信数据的传输。发送接受数据截图:可以看到收发的数据是正常的。
二、aurora读写DDR测试
由于aurora ip核输出的的数据是stream流数据,而ddr我设置的是axi4-full协议格式的,所以要写一个流数据转full协议的模块。
首先是写模块:
module axi_write #
(
parameter integer ADDR_WIDTH = 32 ,
parameter integer DATA_WIDTH = 64 ,
parameter integer AW_LIN = 64 //1-256
)
(
//写入数据
input S_WR_aclk ,
input S_WR_aresetn ,
input wire [DATA_WIDTH-1:0] S_WR_tdata ,
input S_WR_tvalid ,
input S_WR_tlast ,
output S_WR_tready ,
//AXI总线
input wire m_axi_aclk ,
input wire m_axi_aresetn ,
output wire m_axi_awid ,
output wire [ADDR_WIDTH-1 : 0] m_axi_awaddr ,
output wire [7 : 0] m_axi_awlen ,
output wire [2 : 0] m_axi_awsize ,
output wire [1 : 0] m_axi_awburst ,
output wire m_axi_awlock ,
output wire [3 : 0] m_axi_awcache ,
output wire [2 : 0] m_axi_awprot ,
output wire [3 : 0] m_axi_awqos ,
output wire m_axi_awvalid ,
input wire m_axi_awready ,
output wire [DATA_WIDTH-1 : 0] m_axi_wdata ,
output wire [DATA_WIDTH/8-1 : 0] m_axi_wstrb ,
output wire m_axi_wlast ,
output wire m_axi_wvalid ,
input wire m_axi_wready ,
input wire m_axi_bid ,
input wire [1 : 0] m_axi_bresp ,
input wire m_axi_bvalid ,
output wire m_axi_bready
);
//状态跳转。
always @ (posedge i_clk, negedge i_rst_n) begin : W_FMS1
if (~i_rst_n)
c_state <= 0;
else
c_state <= n_state;
end
//状态跳转条件 FSM32
always @ (*) begin : W_FMS2
case (c_state)
WR_IDLE : begin
if (i_valid)
n_state = WR_ADDR;
else
n_state = WR_IDLE;
end
WR_ADDR : begin
if (aw_ready)
n_state = WR_DATA;
else
n_state = WR_ADDR;
end
WR_DATA : begin
if (number_cnt == aw_len - 1&& w_ready && w_valid)
n_state = WR_LAST;
else
n_state = WR_DATA;
end
WR_LAST : begin
if (w_ready && w_valid && w_last)
n_state = WR_STOP;
else
n_state = WR_LAST;
end
WR_STOP : begin
n_state = WR_IDLE;
end
default : n_state = 'bx ;
endcase
end
//状态执行的操作 FSM33
always @ (posedge i_clk, negedge i_rst_n) begin : W_FMS3
if (~i_rst_n)
begin
w_data <= 0;
w_valid <= 0;
w_last <= 0;
w_strb <= 0;
aw_addr <= 0;
aw_len <= 0;
aw_size <= 0;
aw_burst <= 0;
aw_valid <= 0;
aw_addr_cnt <= 32'h00000000;
end
else
case (n_state)
WR_ADDR : begin
w_strb <= wstrb ;
aw_size <= awsize ;
aw_burst <= 2'd1 ;
aw_len <= AW_LIN - 1 ;
aw_valid <= 1 ;
aw_addr <= aw_addr_cnt ;
end
WR_DATA : begin
aw_valid <= 0;
if (i_valid)
begin
if (w_ready)
begin
w_valid <= 1;
w_data <= i_data;
end
else
begin
w_data <= w_data;
end
end
else
begin
w_valid <= 0;
w_data <= w_data;
end
end
WR_LAST : begin
if (i_valid)
begin
w_valid <= 1;
w_last <= 1;
w_data <= i_data;
end
else
begin
w_valid <= 0;
w_data <= w_data;
end
end
WR_STOP : begin
w_last <= 0 ;
w_valid <= 0 ;
if (aw_addr_cnt >= 32'h1000)
aw_addr_cnt <= 32'h0000_0000;
else
aw_addr_cnt <= aw_addr_cnt + (AW_LIN*DATA_WIDTH/8);
end
default : ;
endcase
end
//此处省略。
读模块:
module axi_read #
(
parameter integer ADDR_WIDTH = 32 ,
parameter integer DATA_WIDTH = 64 ,
parameter integer AR_LIN = 64
)
(
//读脉冲信号
input i_wr_done ,
//读出数据
input M_RD_aclk ,
input M_RD_aresetn ,
output wire M_RD_tlast ,
output wire M_RD_tvalid ,
output wire [DATA_WIDTH-1:0] M_RD_tdata ,
input wire M_RD_tready ,
//AXI总线
input wire m_axi_aclk ,
input wire m_axi_aresetn ,
output wire m_axi_arid ,
output wire [ADDR_WIDTH-1 : 0] m_axi_araddr ,
output wire [7 : 0] m_axi_arlen ,
output wire [2 : 0] m_axi_arsize ,
output wire [1 : 0] m_axi_arburst ,
output wire m_axi_arlock ,
output wire [3 : 0] m_axi_arcache ,
output wire [2 : 0] m_axi_arprot ,
output wire [3 : 0] m_axi_arqos ,
output wire m_axi_arvalid ,
input wire m_axi_arready ,
input wire m_axi_rid ,
input wire [DATA_WIDTH-1 : 0] m_axi_rdata ,
input wire [1 : 0] m_axi_rresp ,
input wire m_axi_rlast ,
input wire m_axi_rvalid ,
output wire m_axi_rready
);
//状态转换 FSM31
always @ (posedge i_clk, negedge i_rst_n) begin : R_FMS1
if (~i_rst_n)
c_state <= WAIT_RD;
else
c_state <= n_state;
end
//状态跳转条件 FSM32
always @ (*) begin : R_FMS2
case (c_state)
WAIT_RD : begin
if (i_wr_done_reg6 == 1/*i_wr_done == 1*/) //检测到写完成
n_state = RD_ADDR;
else
n_state = WAIT_RD;
end
RD_ADDR : begin
if (ar_ready)
n_state = RD_DATA;
else
n_state = RD_ADDR;
end
RD_DATA : begin
if (num_rd_cnt == ar_len - 1&& o_valid && i_ready)
n_state = RD_LAST;
else
n_state = RD_DATA;
end
RD_LAST : begin
if (o_valid && i_ready)
n_state = RD_STOP;
else
n_state = RD_LAST;
end
RD_STOP : begin
n_state = WAIT_RD;
end
default : begin
n_state = 0;
end
endcase
end
//状态执行的操作 FSM33
always @ (posedge i_clk, negedge i_rst_n) begin : R_FMS3
if (~i_rst_n)
begin
ar_addr <= 0;
ar_len <= 0;
ar_burst <= 0;
ar_size <= 0;
ar_valid <= 0;
o_data <= 0;
o_last <= 0;
o_valid <= 0;
rd_addr_buff <= 32'h0000_0000;
end
else
case (n_state)
WAIT_RD : begin
ar_valid <= 0;
end
RD_ADDR : begin
ar_valid <= 1 ;
ar_addr <= rd_addr_buff ;
ar_len <= AR_LIN - 1 ;
ar_burst <= 2'd1 ;
ar_size <= arsize ;
end
RD_DATA : begin
ar_valid <= 0;
if (r_valid)
begin
o_valid <= 1;
if (i_ready)
o_data <= r_data;
else
o_data <= o_data;
end
else
begin
o_data <= o_data;
o_valid <= 0;
end
end
RD_LAST : begin
o_last <= 1;
if (r_valid && i_ready)
begin
o_data <= r_data;
o_valid <= 1;
end
else
begin
o_data <= o_data;
o_valid <= 0;
end
end
RD_STOP : begin
o_last <= 0;
o_valid <= 0;
if (rd_addr_buff >= 32'h1000)
rd_addr_buff <= 32'h0000_0000;
else
rd_addr_buff <= rd_addr_buff + AR_LIN*(DATA_WIDTH/8);
end
endcase
end
读写模块仿真波形图:
写模块仿真波形图
读模块仿真波形图:
从波形图可以看出,读写模块的功能是正常的,下面就是在bd中将他们几个组合起来。
框图如下:
下到板子中,可以看到读写的数据是一样的。
是产生数据的波形图。
ila抓取的波形图:
整个工程就大功告成了,过几天更新xdma读写ddr,最后完成xdma <---->aurora的回环。