本文主要是介绍基于FPGA的UDP协议栈设计第六章_仲裁模块设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 前言:
- 一、模块设计
- 1、模块接口
- 2、实现方式
- 总结:
前言:
仲裁模块设计,解决当IP层同时收到UDP层和ICMP层数据以及MAC层同时收到ARP层和IP层数据时候的仲裁问题
一、模块设计
1、模块接口
设计代码为本人参考FPGA奇哥系列网课自行编写
端口A相较于端口B有更高的优先级
module Data_2to1_arbiter#(parameter P_INTERVAL_LEN = 10
)(input i_clk ,input i_rst ,input [7 :0] i_data_a ,input i_valid_a ,input i_last_a ,input [15:0] i_len_a ,input [15:0] i_type_a ,input [7 :0] i_data_b ,input i_valid_b ,input i_last_b ,input [15:0] i_len_b ,input [15:0] i_type_b ,output o_nxt_frame_stop ,output [7 :0] o_data ,output o_valid ,output o_last ,output [15:0] o_len ,output [15:0] o_type
);
2、实现方式
通过FIFO实现仲裁过程:
ARP报文和ICMP报文具有更高的优先级,因为他们往往很久才会传输一次。
FIFO_8x256 FIFO_8x256_port_a (.clk (i_clk ), .din (ri_data_a ), .wr_en (ri_valid_a ), .rd_en (r_fifo_rden_a ), .dout (w_fifo_douta ), .full (w_fifo_fulla ), .empty (w_fifo_emptya )
);FIFO_32x16 FIFO_32x16_port_a (.clk (i_clk ), .din ({ri_type_a,ri_len_a} ), .wr_en (w_valid_a_pos ), .rd_en (w_fifo_rden_a_pos ), .dout (w_fifo_douta_type_len ), .full (), .empty ()
);FIFO_8x256 FIFO_8x256_port_b (.clk (i_clk ), .din (ri_data_b ), .wr_en (ri_valid_b ), .rd_en (r_fifo_rden_b ), .dout (w_fifo_doutb ), .full (w_fifo_fullb ), .empty (w_fifo_emptyb )
);FIFO_32x16 FIFO_32x16_port_b (.clk (i_clk ), .din ({ri_type_b,ri_len_b} ), .wr_en (w_valid_b_pos ), .rd_en (w_fifo_rden_b_pos ), .dout (w_fifo_doutb_type_len ), .full (), .empty ()
);
一共有四个FIFO模块,分别用来存储端口A和端口B的数据和类型长度信息,输入的数据进入相应的FIFO当中,对应的类型和长度信息也存入FIFO,在if-else当中FIFO_a(存优先级高的报文,ICMP或ARP)的响应优先级更高,通过判断FIFO是否为空进行相应仲裁。
//每次发完数据仲裁信号归零,当仲裁信号为0时候才会响应下一次
always @(posedge i_clk or posedge i_rst)beginif(i_rst)r_arbiter <= 'd0;else if(ro_last)r_arbiter <= 'd0;else if(!w_fifo_emptya && r_arbiter == 0 && r_interval_cnt == P_INTERVAL_LEN)r_arbiter <= 'd1;else if(!w_fifo_emptyb && r_arbiter == 0 && r_interval_cnt == P_INTERVAL_LEN)r_arbiter <= 'd2;elser_arbiter <= r_arbiter;
end
总结:
完整代码参考GitHub:https://github.com/shun6-6/Tri_Eth_UDP_pro_stack
这篇关于基于FPGA的UDP协议栈设计第六章_仲裁模块设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!