实验室有一块米联客出的Kintex-7的板子,被我用来做毕业设计,其中使用到了千兆以太网的外设,于是打算使用米联客自己教程中所使用的协议栈来开发千兆以太网通信,接着就接触到了米联客的教程udp_stack.dcp。
//如果帮到你,一定要点赞收藏哦!//
0 使用背景
博主在很多设计部分参考了官方资料的udp_tx_speed工程,包括tri-mode ethernet IP, async/package FIFO的设置都与此同步,在此默认哥老倌们都已经配置好了。
1 协议栈介绍
1.1 结构拓扑
下图为udp_stack.dcp的结构,事实上博主只使用了数据发送回路。本来想把receive_buffer这一部分去掉的,后来发现,这部分用来接收反馈数据/反馈信号的,如果去掉,udp_stack.dcp就没法正常工作。
1.2 接口描述
下图中是udp_stack.dcp的接口定义
在这些接口的连接中,除了app_tx_XXX博主是引出来自己写控制逻辑外,其余的都参照tx_speed教程中的连接方式了。
1.3 逻辑控制
下图是米联客给的时序图,所以主要任务即为控制app层的app_tx_XXX信号,让协议栈为我们打工!实现千兆以太网通信。
说到这儿,有人就要问了:“合着逻辑控制都是用嘴吹的,没法白嫖是吧?”
这就奉上自己写的代码,里面用了三段式Moore状态机来控制,已经过验证,该逻辑控制可行。
module TOP_CTRL(
input clk_15_625,
input clk_25,
input clk_200,
input rst_n,
input udp_tx_ready,
input app_tx_ack,
input locked,
input dst_ip_unreachable,
output phy_rst_o,
output reg app_tx_request,
output reg app_tx_data_valid,
output reg [63:0] app_tx_data,
output reg [7:0] app_tx_data_keep,
output reg app_tx_data_last,
// output reg [15:0] package_length,
output reg [3:0] state
);
//reg definition
reg [15:0] delay_cnt;
reg [3:0] send_counter = 0;
// reg [3:0] state;
reg [4:0] next_state;
//wire definition
//parameter definition
parameter idle_state = 0;
parameter request_state = 1;
parameter transmit_state = 2;
parameter delay_state = 3;
//phy_rst_o output defintion
assign phy_rst_o = (delay_cnt == 10'd100)? 1'b1 : 1'b0;
always @(posedge clk_25) begin
if(!locked)
delay_cnt <= 10'd0;
else begin
if(delay_cnt == 10'd100)
delay_cnt <= delay_cnt;
else
delay_cnt <= delay_cnt + 1'b1;
end
end
//The first stage of the state machine
always@(posedge clk_15_625 or negedge rst_n)
begin
if(!rst_n)
state <= idle_state;
else
state <= next_state;
end
//The second stage of state machine
always@(negedge clk_15_625 or negedge rst_n)
begin
if(!rst_n)
begin
next_state <= idle_state;
end
else
begin
case(state)
idle_state:
begin
if(udp_tx_ready)
next_state <= request_state;
else
next_state <= idle_state;
end
request_state:
begin
if(app_tx_ack)
next_state <= transmit_state;
else if(dst_ip_unreachable)
next_state <= idle_state;
else
next_state <= next_state;
end
transmit_state:
begin
if(send_counter < 8)
next_state <= next_state;
else
next_state <= delay_state;
end
delay_state:
begin
//Delay logic
next_state <= idle_state;
// else
// next_state <= delay_state;
end
default:
next_state <= idle_state;
endcase
end
end
//The third stage of state machine
always@(posedge clk_15_625 or negedge rst_n)
begin
if(!rst_n)
begin
app_tx_data_valid <= 1'b0;
app_tx_request <= 1'b0;
app_tx_data <= 64'd0;
app_tx_data_last <= 1'b0;
app_tx_data_keep <= 8'hff;
send_counter <= 4'd0;
// package_length <= 16'd8;
end
else
begin
case(state)
idle_state:
begin
app_tx_data = 64'h0;
app_tx_request <= 1'b0;
app_tx_data_valid <= 1'b0;
end
request_state:
begin
app_tx_data_valid <= 1'b0;
app_tx_request <= 1'b1;
end
transmit_state:
begin
app_tx_request <= 1'b0;
app_tx_data_valid <= 1'b1;
app_tx_data <= 64'h1122334455667788;
if(send_counter == 4'd7)
begin
app_tx_data_keep <= 8'hff;
app_tx_data_last <= 1'b1;
end
else
begin
app_tx_data_keep <= 8'hff;
end
send_counter <= send_counter + 1'b1;
end
delay_state:
begin
app_tx_data_valid <= 1'b0;
app_tx_data <= 64'h0;
app_tx_data_keep <= 8'hff;
send_counter <= 4'd0;
app_tx_data_last <= 1'b0;
end
default:
begin
app_tx_data <= 64'h0;
end
endcase
end
end
endmodule
白嫖的时候要记得点赞收藏,不然以后找不到回来的路。(阅完即删^V^)
2 调试工具
博主在开发过程中使用了两个工具:
1.Vivado自带的Behavior simulation
2.烧写到板子,然后用chipscope/ila观察波形,值得一提的是,在仿真过程中udp_stack.dcp不能参与仿真,必须得要udp_stack.v! 那咋办嘛?难道要劳资花钱买源代码???
不用担心,博主给出了解决方案:
米联客含协议栈.dcp的工程仿真教程
注意:
0# 实际implementation 的时候又需要删除udp_stack.v
1# 起初调试过程中,发现udp_stack的发送回路和接受回路都可以通,但是无论如何udp_tx_ack也不能拉高,我勒个去,排查了几天,最后把自己写的三段式状态机替换了才知道原来问题出在时钟源,我的状态机控制那里是整个工程的,包括了千兆网口和其余的一些模块,因而使用的是默认的200MHz时钟源clk_200,但实际上udp_stack中控制关键引脚时应该使用的时钟时clk_15_625。
3 总结
值得一提的是,米联客推出千兆以太网解决方案,总体来说还是比较好的,但是目前时序约束貌似还没有改进,即使是官方例程也是不满足时序要求的
如果有没描述清楚的问题,欢迎大家留言讨论;
//如果帮到你,一定要点赞收藏哦!//文章来源:https://www.toymoban.com/news/detail-598219.html
参考资料
[1] 03米联客2020版FPGA课程(UDP以太网通信篇).pdf
[2] 01_udp_rgmii_1g\02_udp_txspeed_rgmii参考工程文章来源地址https://www.toymoban.com/news/detail-598219.html
到了这里,关于米联客udp_stack以太网协议栈使用教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!