文章目录
- 前言
- 一、AXI_Stream数据产生模块
- 二、上板效果
- 总结
前言
上一篇内容我们已经详细介绍了基于aurora8b10b IP核的设计,本文将基于此进一步完善并且进行上板验证。
设计思路及代码思路参考FPGA奇哥系列网课
一、AXI_Stream数据产生模块
AXIS协议是非常简单的,看过之前的AXI_FULL协议应该会很容易理解。
该模块有以下需要注意的点:
- 主机VALID信号一定是要主动拉高的,不可以以从机READY信号作为拉高判断的条件。
- 对于last信号的产生和计数器的清零,一定是要在握手成功的前提下进行判断,因为要避免从机莫名其妙拉低的情况,例如,我们要发送100个数据,计数器需要在99时候清零,如果READY在98的时候是高,那么计数器会顺利计数到99,而READY恰好99时候变为为0,如果不加w_active这个握手成功的限制条件,计数器会在此时清零,而我们第100个数据也就丢失了,对于LAST信号更加严重,因为从机压根就接收不到LAST信号了。
else if(w_active && r_send_cnt == P_SEND_LEN - 1)
r_send_cnt <= 'd0;
else if(w_active && r_send_cnt == P_SEND_LEN - 2)
rm_axi_tx_tlast <= 'd1;
module user_data_gen(
input i_clk ,
input i_rst ,
output [31:0] m_axi_tx_tdata ,
output [3 :0] m_axi_tx_tkeep ,
output m_axi_tx_tlast ,
output m_axi_tx_tvalid ,
input m_axi_tx_tready ,
input [31:0] s_axi_rx_tdata ,
input [3 :0] s_axi_rx_tkeep ,
input s_axi_rx_tlast ,
input s_axi_rx_tvalid
);
localparam P_SEND_LEN = 100 ;
reg [31:0] rm_axi_tx_tdata ;
reg [3 :0] rm_axi_tx_tkeep ;
reg rm_axi_tx_tlast ;
reg rm_axi_tx_tvalid ;
reg [15:0] r_cnt ;
reg [15:0] r_send_cnt ;
wire w_start ;
wire w_active ;
assign w_start = r_cnt == 100 ;
assign w_active = m_axi_tx_tvalid & m_axi_tx_tready ;
assign m_axi_tx_tdata = rm_axi_tx_tdata ;
assign m_axi_tx_tkeep = rm_axi_tx_tkeep ;
assign m_axi_tx_tlast = rm_axi_tx_tlast ;
assign m_axi_tx_tvalid = rm_axi_tx_tvalid ;
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_cnt <= 'd0;
else if(rm_axi_tx_tlast)
r_cnt <= 'd0;
else if(r_cnt == 100)
r_cnt <= r_cnt;
else
r_cnt <= r_cnt + 1;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_send_cnt <= 'd0;
else if(w_active && r_send_cnt == P_SEND_LEN - 1)
r_send_cnt <= 'd0;
else if(w_active)
r_send_cnt <= r_send_cnt + 1;
else
r_send_cnt <= r_send_cnt;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
rm_axi_tx_tvalid <= 'd0;
else if(w_active && r_send_cnt == P_SEND_LEN - 1)
rm_axi_tx_tvalid <= 'd0;
else if(w_start)
rm_axi_tx_tvalid <= 'd1;
else
rm_axi_tx_tvalid <= rm_axi_tx_tvalid;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
rm_axi_tx_tlast <= 'd0;
else if(w_active && r_send_cnt == P_SEND_LEN - 2)
rm_axi_tx_tlast <= 'd1;
else
rm_axi_tx_tlast <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
rm_axi_tx_tdata <= 'd0;
else if(rm_axi_tx_tlast)
rm_axi_tx_tdata <= 'd0;
else if(w_active)
rm_axi_tx_tdata <= rm_axi_tx_tdata + 1;
else
rm_axi_tx_tdata <= rm_axi_tx_tdata;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
rm_axi_tx_tkeep <= 4'b1111;
else
rm_axi_tx_tkeep <= 4'b1111;
end
endmodule
二、上板效果
这就没啥好说的了,一收一发,没有任何问题。
总结
完整工程可参考:https://github.com/shun6-6/AURORA8B10B