FPGA——以太网设计(1)基本模块
- 1. 协议解析
- (1)MAC层
- (2)IP层 和 ARP层
- (3)UDP层 和 ICMP层
- 2.1 MAC接收模块
- 2.2 MAC发送模块
- 3.1 IP接收模块
- 3.2 IP发送模块
- 4.1 UDP接收模块
- 4.2 UDP发送模块
- 5.1 ICMP接收模块
- 5.2 ICMP发送模块
- 6.1 ARP接收模块
- 6.2 ARP发送模块
- 6.3 ARP表模块
- 7 CRC数据对比模块
- 8 MAC下ARP和IP数据分流模块
- 9 数据流仲裁模块
- 模块收发组合
- 1 MAC层收发
- 2 ARP层收发
- 2 IP层收发
- 3 ICMP层收发
- 3 UDP层收发
- UDP协议栈
1. 协议解析
每层都嵌套在上层的数据字段
(1)MAC层
以太网帧长: 64B~1518B
(2)IP层 和 ARP层
IP层
ARP层
(3)UDP层 和 ICMP层
UDP层
ICMP层
2.1 MAC接收模块
module MAC_rx#(parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_CRC_CHECK = 1
)(input i_clk ,input i_rst ,/*--------info port--------*/ input [47:0] i_target_mac ,input i_target_mac_valid ,input [47:0] i_source_mac ,input i_source_mac_valid ,/*--------data port--------*/output [15:0] o_post_type ,output [7 :0] o_post_data ,output o_post_last ,output o_post_valid ,output [47:0] o_rec_src_mac ,output o_rec_src_valid ,output o_crc_error , output o_crc_valid , /*--------GMII port--------*/input [7 :0] i_GMII_data ,input i_GMII_valid
);
/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg ro_post_last ;
reg ro_post_valid ;
reg [47:0] ro_rec_src_mac ;
reg ro_rec_src_valid ;
reg ro_crc_error ;
reg [7 :0] ri_GMII_data ;
reg ri_GMII_valid ;
reg [7 :0] ri_GMII_data_1d ;
reg ri_GMII_valid_1d ;
reg [7 :0] ri_GMII_data_2d ;
reg ri_GMII_valid_2d ;
reg [7 :0] ri_GMII_data_3d ;
reg ri_GMII_valid_3d ;
reg [7 :0] ri_GMII_data_4d ;
reg ri_GMII_valid_4d ;
reg [7 :0] ri_GMII_data_5d ;
reg ri_GMII_valid_5d ;
reg [47:0] r_target_mac ;
reg [47:0] r_source_mac ;
reg [47:0] r_rec_mac ;
reg r_rec_mac_access ;
reg [15:0] r_rec_cnt ;
reg r_headr_check ;
reg r_header_access ;
reg [15:0] r_rec_type ;//0x0800-IP 0X0806-ARP
reg r_crc_rst ;
reg r_crc_en ;
reg r_crc_en_1d ;
reg [15:0] r_rec_5d_cnt ;
reg [31:0] r_crc_result ;
reg ro_crc_valid ;/***************wire******************/
wire [31:0] w_crc_result ;/***************component*************/
CRC32_D8 CRC32_D8_u0(.i_clk (i_clk ),.i_rst (r_crc_rst ),.i_en (r_crc_en ),.i_data (ri_GMII_data_5d ),.o_crc (w_crc_result )
);
/***************assign****************/
assign o_post_type = r_rec_type ;
assign o_post_data = ri_GMII_data_5d ;
assign o_post_last = ro_post_last ;
assign o_post_valid = ro_post_valid ;
assign o_rec_src_mac = ro_rec_src_mac ;
assign o_rec_src_valid = ro_rec_src_valid ;
assign o_crc_error = ro_crc_error ;
assign o_crc_valid = ro_crc_valid ;
/***************always****************///数据打5拍,为了对齐信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_GMII_data <= 'd0;ri_GMII_valid <= 'd0;ri_GMII_data_1d <= 'd0;ri_GMII_valid_1d <= 'd0;ri_GMII_data_2d <= 'd0;ri_GMII_valid_2d <= 'd0;ri_GMII_data_3d <= 'd0;ri_GMII_valid_3d <= 'd0;ri_GMII_data_4d <= 'd0;ri_GMII_valid_4d <= 'd0;end else beginri_GMII_data <= i_GMII_data ;ri_GMII_valid <= i_GMII_valid;ri_GMII_data_1d <= ri_GMII_data ;ri_GMII_valid_1d <= ri_GMII_valid;ri_GMII_data_2d <= ri_GMII_data_1d ;ri_GMII_valid_2d <= ri_GMII_valid_1d;ri_GMII_data_3d <= ri_GMII_data_2d ;ri_GMII_valid_3d <= ri_GMII_valid_2d;ri_GMII_data_4d <= ri_GMII_data_3d ;ri_GMII_valid_4d <= ri_GMII_valid_3d;ri_GMII_data_5d <= ri_GMII_data_4d ;ri_GMII_valid_5d <= ri_GMII_valid_4d;end
end
//valid后,输入目标mac地址锁存
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_mac <= P_TARTGET_MAC;else if(i_target_mac_valid)r_target_mac <= i_target_mac;elser_target_mac <= r_target_mac;
end//valid后,输入源mac地址锁存
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_mac <= P_SOURCE_MAC ;else if(i_source_mac_valid)r_source_mac <= i_source_mac;elser_source_mac <= r_source_mac;
end//GMII接口输入有效
// r_rec_cnt 为 6 停一个周期 接收SFD
// 继续 + 1
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rec_cnt <= 'd0;else if(ri_GMII_valid && r_rec_cnt == 6 && ri_GMII_data == 8'h55)r_rec_cnt <= r_rec_cnt;else if(ri_GMII_valid)r_rec_cnt <= r_rec_cnt + 1;else r_rec_cnt <= 'd0;
end// r_rec_cnt 7 ~ 12 存好收到目的的MAC地址
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rec_mac <= 'd0;else if(ri_GMII_valid && r_rec_cnt >= 7 && r_rec_cnt <= 12)r_rec_mac <= {r_rec_mac[39:0],ri_GMII_data};else r_rec_mac <= r_rec_mac;
end// r_rec_cnt 13 检测收到目的mac与自身mac是否相等
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rec_mac_access <= 'd0;else if(r_rec_cnt == 13 && r_rec_mac != r_source_mac)r_rec_mac_access <= 'd0;else if(r_rec_cnt == 13 && (r_rec_mac == r_source_mac || &r_rec_mac))r_rec_mac_access <= 'd1;else r_rec_mac_access <= r_rec_mac_access;
end
//r_rec_cnt 0~6 检验前导码 是否为55 再6 检测SFD 是否为D5
always@(*)
begincase(r_rec_cnt)0,1,2,3,4,5 :r_headr_check <= ri_GMII_data == 8'h55 ? 'd1 : 'd0;6 :r_headr_check <= ri_GMII_data == 8'hD5 || ri_GMII_data == 8'h55 ? 'd1 : 'd0;default :r_headr_check <= 'd1;endcase
end//头没有问题,就通过信号不拉低
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_header_access <= 'd1;else if(!ri_GMII_valid)r_header_access <= 'd1;else if(ri_GMII_valid && r_rec_cnt >= 0 && r_rec_cnt <= 6 && !r_headr_check)r_header_access <= 'd0;else r_header_access <= r_header_access;
end// r_rec_cnt 13~ 18 源MAC地址接收
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_rec_src_mac <= 'd0;else if(ri_GMII_valid && r_rec_cnt >= 13 && r_rec_cnt <= 18)ro_rec_src_mac <= {ro_rec_src_mac[39:0],ri_GMII_data};else ro_rec_src_mac <= ro_rec_src_mac;
end// r_rec_cnt 19 源MAC地址接收有效
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_rec_src_valid <= 'd0;else if(r_rec_cnt == 19)ro_rec_src_valid <= 'd1;else ro_rec_src_valid <= ro_rec_src_valid;
end//r_rec_cnt 19 ~ 20 接收类型
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rec_type <= 'd0;else if(ri_GMII_valid && r_rec_cnt >= 19 && r_rec_cnt <= 20)r_rec_type <= {r_rec_type[7:0],ri_GMII_data};else r_rec_type <= r_rec_type;
end //延迟5个周期的 GMII 有效 r_rec_5d_cnt + 1
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rec_5d_cnt <= 'd0; else if(ri_GMII_valid_5d)r_rec_5d_cnt <= r_rec_5d_cnt + 1;elser_rec_5d_cnt <= 'd0;
end
//正常信号的下降沿 有效为0
//延迟5个周期 计数为 21 有效为1
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_valid <= 'd0;else if(ro_post_last)ro_post_valid <= 'd0;else if(r_rec_5d_cnt == 21)ro_post_valid <= 'd1;else ro_post_valid <= ro_post_valid;
end//GMII有效信号下降沿 输出 ro_post_last
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_last <= 'd0;else if(!i_GMII_valid && ri_GMII_valid)ro_post_last <= 'd1;else ro_post_last <= 'd0;
end// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// ro_arp_valid <= 'd0;
// else if(!ri_GMII_valid && ri_GMII_data_1d)
// ro_arp_valid <= 'd0;
// else if(r_rec_type == 16'h0806 && r_rec_5d_cnt == 20)
// ro_arp_valid <= 'd1;
// else
// ro_arp_valid <= ro_ip_valid;
// end// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// ro_arp_last <= 'd0;
// else if(!i_GMII_valid && ri_GMII_valid && r_rec_type == 16'h0806)
// ro_arp_last <= 'd1;
// else
// ro_arp_last <= 'd0;
// end//CRC使能信号 来 CRC模块数据复位信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_rst <= 'd1;else if(r_rec_5d_cnt == 7)r_crc_rst <= 'd0;else if(!r_crc_en && r_crc_en_1d)r_crc_rst <= 'd1;else r_crc_rst <= r_crc_rst;
end// GMII有效的下降沿 关闭crc校验使能
//
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_en <= 'd0;else if(!ri_GMII_valid && ri_GMII_data_1d)r_crc_en <= 'd0;else if(r_rec_5d_cnt == 7)r_crc_en <= 'd1;else r_crc_en <= r_crc_en;
end//CRC使能信号打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_en_1d <= 'd0;else r_crc_en_1d <= r_crc_en;
end//获取外部输入的CRC结果
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_result <= 'd0;else if(ri_GMII_valid)r_crc_result <= {ri_GMII_data,r_crc_result[31:8]};elser_crc_result <= r_crc_result;
end//CRC使能下降沿 CRC有效
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_crc_valid <= 'd0;else if(!r_crc_en && r_crc_en_1d)ro_crc_valid <= 'd1;else ro_crc_valid <= 'd0;
end//CRC校验 error
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_crc_error <= 'd0;else if(!P_CRC_CHECK)ro_crc_error <= 'd0;else if(!r_crc_en && r_crc_en_1d && r_crc_result != w_crc_result)ro_crc_error <= 'd1;else ro_crc_error <= 'd0;
endendmodule
2.2 MAC发送模块
module MAC_tx#(parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_CRC_CHECK = 1
)(input i_clk ,input i_rst ,/*--------info port--------*/ input [47:0] i_target_mac ,input i_target_mac_valid ,input [47:0] i_source_mac ,input i_source_mac_valid ,/*--------data port--------*/input i_udp_valid ,output o_udp_ready ,input [15:0] i_send_type ,input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,/*--------GMII port--------*/output [7 :0] o_GMII_data ,output o_GMII_valid
);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] ri_send_type ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_valid ;
reg ri_send_valid_1d ;
reg [7 :0] ro_GMII_data ;
reg ro_GMII_valid ;
reg ro_GMII_valid_1d ;
reg [47:0] r_target_mac ;
reg [47:0] r_source_mac ;
reg r_fifo_mac_rd_en ;
reg [15:0] r_mac_pkg_cnt ;
reg [7 :0] r_mac_data ;
reg r_mac_data_valid ;
reg r_mac_data_valid_1d ;
reg [15:0] r_mac_data_cnt ;
reg r_crc_rst ;
reg r_crc_en ;
reg [1 :0] r_crc_out_cnt ;
reg r_crc_out_cnt_1d ;
reg [15:0] r_gap_lat ;
reg r_gap_lock ;
reg [15:0] r_gap_cnt ;
reg ri_udp_valid ;
reg ro_udp_ready ;/***************wire******************/
wire [7 :0] w_fifo_mac_dout ;
wire w_fifo_mac_full ;
wire w_fifo_mac_empty ;
wire w_send_valid_pos ;
wire w_send_valid_neg ;
wire [31:0] w_crc_result ;/***************component*************/
FIFO_MAC_8X64 FIFO_MAC_8X64_U0 (.clk (i_clk ), // input wire clk.din (ri_send_data ), // input wire [7 : 0] din.wr_en (ri_send_valid ), // input wire wr_en.rd_en (r_fifo_mac_rd_en ), // input wire rd_en.dout (w_fifo_mac_dout ), // output wire [7 : 0] dout.full (w_fifo_mac_full ), // output wire full.empty (w_fifo_mac_empty ) // output wire empty
);CRC32_D8 CRC32_D8_u0(.i_clk (i_clk ),.i_rst (r_crc_rst ),.i_en (r_crc_en ),.i_data (r_mac_data ),.o_crc (w_crc_result )
);/***************assign****************/
assign o_GMII_data = ro_GMII_data ;
assign o_GMII_valid = ro_GMII_valid ;
assign w_send_valid_pos = ri_send_valid & !ri_send_valid_1d;
assign w_send_valid_neg = !ri_send_valid & ri_send_valid_1d;
assign o_udp_ready = ro_udp_ready ;/***************always****************/
//锁存 目的mac
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_mac <= P_TARTGET_MAC;else if(i_target_mac_valid)r_target_mac <= i_target_mac;elser_target_mac <= r_target_mac;
end
//锁存 源mac
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_mac <= P_SOURCE_MAC ;else if(i_source_mac_valid)r_source_mac <= i_source_mac;elser_source_mac <= r_source_mac;
end//锁存输入的 发送mac帧信息
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_send_type <= 'd0;ri_send_len <= 'd0;ri_send_data <= 'd0;ri_send_valid <= 'd0;end else if(i_send_valid) beginri_send_type <= i_send_type ;ri_send_len <= i_send_len ;ri_send_data <= i_send_data ;ri_send_valid <= i_send_valid;end else beginri_send_type <= ri_send_type ;ri_send_len <= ri_send_len ;ri_send_data <= 'd0 ;ri_send_valid <= 'd0;end
end//mac帧的计数器
//CRC校验输出完成 停止
//输入信号有效上升沿开始 计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_pkg_cnt <= 'd0;else if(r_crc_out_cnt == 3)r_mac_pkg_cnt <= 'd0;else if(w_send_valid_pos || r_mac_pkg_cnt)r_mac_pkg_cnt <= r_mac_pkg_cnt + 1;else r_mac_pkg_cnt <= r_mac_pkg_cnt;
end//组mac帧 : 前导码 + SFD + 目的mac + 源mac
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_data <= 'd0;else case(r_mac_pkg_cnt)0,1,2,3,4,5,6 :r_mac_data <= 8'h55;7 :r_mac_data <= 8'hd5;8 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[47:40];9 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[39:32];10 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[31:24];11 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[23:16];12 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[15: 8];13 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[7 : 0];14 :r_mac_data <= r_source_mac[47:40];15 :r_mac_data <= r_source_mac[39:32];16 :r_mac_data <= r_source_mac[31:24];17 :r_mac_data <= r_source_mac[23:16];18 :r_mac_data <= r_source_mac[15: 8];19 :r_mac_data <= r_source_mac[7 : 0];20 :r_mac_data <= ri_send_type[15: 8];21 :r_mac_data <= ri_send_type[7 : 0];default :r_mac_data <= w_fifo_mac_dout;endcase
end//mac有效信号
// mac数据计数到值 关闭
//发送有效上升沿 开启
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_data_valid <= 'd0;else if(r_mac_data_cnt == ri_send_len + 1)r_mac_data_valid <= 'd0;else if(w_send_valid_pos)r_mac_data_valid <= 'd1;else r_mac_data_valid <= r_mac_data_valid;
end//mac总数计数器
//到设置长度清零
//fifo读使能 开启计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_data_cnt <= 'd0;else if(r_mac_data_cnt == ri_send_len + 1)r_mac_data_cnt <= 'd0;else if(r_fifo_mac_rd_en | r_mac_data_cnt)r_mac_data_cnt <= r_mac_data_cnt + 1;else r_mac_data_cnt <= r_mac_data_cnt;
end//mac帧的计数器 到20 开启读fifo使能
//到mac总数关闭
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_mac_rd_en <= 'd0;else if(r_mac_data_cnt == ri_send_len - 1)r_fifo_mac_rd_en <= 'd0;else if(r_mac_pkg_cnt == 20)r_fifo_mac_rd_en <= 'd1;else r_fifo_mac_rd_en <= r_fifo_mac_rd_en;
end//CRC校验复位
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_rst <= 'd1;else if(r_mac_pkg_cnt == 8 )r_crc_rst <= 'd0;else if(r_crc_out_cnt == 3)r_crc_rst <= 'd1;else r_crc_rst <= r_crc_rst;
end//CRC校验使能,mac帧计时器为 8时 开启
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_en <= 'd0;else if(r_mac_data_cnt == ri_send_len + 1)r_crc_en <= 'd0;else if(r_mac_pkg_cnt == 8 )r_crc_en <= 'd1;else r_crc_en <= r_crc_en;
end// r_crc_out_cnt 数据有效下降沿开启计数 等于3清零
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_out_cnt <= 'd0;else if(r_crc_out_cnt == 3) r_crc_out_cnt <= 'd0;else if((!r_mac_data_valid && r_mac_data_valid_1d) || r_crc_out_cnt)r_crc_out_cnt <= r_crc_out_cnt + 1;else r_crc_out_cnt <= r_crc_out_cnt;
end//输出mac帧数据
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_GMII_data <= 'd0;else if(r_mac_data_valid)ro_GMII_data <= r_mac_data;else case(r_crc_out_cnt)0 :ro_GMII_data <= w_crc_result[7 : 0];1 :ro_GMII_data <= w_crc_result[15: 8];2 :ro_GMII_data <= w_crc_result[23:16];3 :ro_GMII_data <= w_crc_result[31:24];default :ro_GMII_data <= 'd0;endcase
end // r_crc_out_cnt_1d
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_crc_out_cnt_1d <= 'd0;else if(r_crc_out_cnt == 3)r_crc_out_cnt_1d <= 'd1;else r_crc_out_cnt_1d <= 'd0;
end//数据有效的时候 GMII输出有效
//只有在CRC结束,r_crc_out_cnt_1d 拉高的时候,GMII输出无效
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_GMII_valid <= 'd0;else if(r_crc_out_cnt_1d)ro_GMII_valid <= 'd0;else if(r_mac_data_valid)ro_GMII_valid <= 'd1;else ro_GMII_valid <= ro_GMII_valid;
end
//信号打拍 获得上升沿
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_send_valid_1d <= 'd0;r_mac_data_valid_1d <= 'd0;end else beginri_send_valid_1d <= ri_send_valid ;r_mac_data_valid_1d <= r_mac_data_valid;end
end
/*-------------------UDP------------------------*/
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_udp_valid <= 'd0 ;ro_GMII_valid_1d <= 'd0;end else beginri_udp_valid <= i_udp_valid;ro_GMII_valid_1d <= ro_GMII_valid;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_udp_ready <= 'd1;else if(i_udp_valid)ro_udp_ready <= 'd0;else if( r_mac_data_cnt == ri_send_len - 1)ro_udp_ready <= 'd1;else ro_udp_ready <= ro_udp_ready;
endendmodule
3.1 IP接收模块
module IP_rx#(parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(input i_clk ,input i_rst ,/*--------info port --------*/input [31:0] i_target_ip ,input i_target_valid ,input [31:0] i_source_ip ,input i_source_valid ,/*--------data port--------*/output [15:0] o_udp_len ,output [7 :0] o_udp_data ,output o_udp_last ,output o_udp_valid ,output [15:0] o_icmp_len ,output [7 :0] o_icmp_data ,output o_icmp_last ,output o_icmp_valid ,output [31:0] o_source_ip ,output o_source_ip_valid ,/*--------mac port--------*/input [7 :0] i_mac_data ,input i_mac_last ,input i_mac_valid);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [31:0] r_target_ip ;
reg [31:0] r_source_ip ;
reg [7 :0] ri_mac_data ;
reg [7 :0] ri_mac_data_1d ;
reg ri_mac_last ;
reg ri_mac_valid ;
reg ri_mac_valid_1d ;
reg [15:0] ro_udp_len ;
reg ro_udp_last ;
reg ro_udp_valid ;
reg [15:0] ro_icmp_len ;
reg ro_icmp_last ;
reg ro_icmp_valid ;
reg [15:0] r_ip_len ;
reg [7 :0] r_ip_type ;
reg [31:0] r_ip_source ;
reg [31:0] r_ip_target ;
reg [15:0] r_ip_cnt ;
reg ro_source_ip_valid ;/***************wire******************//***************component*************//***************assign****************/
assign o_udp_data = ri_mac_data_1d ;
assign o_icmp_data = ri_mac_data_1d ;
assign o_udp_len = ro_udp_len ;
assign o_udp_last = ro_udp_last ;
assign o_udp_valid = ro_udp_valid ;
assign o_icmp_len = ro_icmp_len ;
assign o_icmp_last = ro_icmp_last ;
assign o_icmp_valid = ro_icmp_valid ;
assign o_source_ip = r_ip_source ;
assign o_source_ip_valid = ro_source_ip_valid;
/***************always****************/
//目的ip有效信号 锁存 目的ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_ip <= P_ST_TARGET_IP;else if(i_target_valid)r_target_ip <= i_target_ip;else r_target_ip <= r_target_ip;
end//源ip效信号 锁存 源ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_ip <= P_ST_SOURCE_IP;else if(i_source_valid)r_source_ip <= i_source_ip;else r_source_ip <= r_source_ip;
end//信号和数据打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_mac_data <= 'd0;ri_mac_last <= 'd0;ri_mac_valid <= 'd0;ri_mac_data_1d <= 'd0;ri_mac_valid_1d <= 'd0;end else beginri_mac_data <= i_mac_data ;ri_mac_last <= i_mac_last ;ri_mac_valid <= i_mac_valid;ri_mac_data_1d <= ri_mac_data;ri_mac_valid_1d <= ri_mac_valid;end
end//mac端口有效 ip计数器+1
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_cnt <= 'd0;else if(ri_mac_valid)r_ip_cnt <= r_ip_cnt + 1;else r_ip_cnt <= 'd0;
end// 2 3 字节数据为ip报文总长度
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_len <= 'd0;else if(r_ip_cnt >= 2 && r_ip_cnt <= 3)r_ip_len <= {r_ip_len[7:0],ri_mac_data};else r_ip_len <= r_ip_len;
end//第9字节 ip 协议类型
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_type <= 'd0;else if(r_ip_cnt == 9)r_ip_type <= ri_mac_data;else r_ip_type <= r_ip_type;
end//第12 13 14 15字节 ip源地址
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_source <= 'd0;else if(r_ip_cnt >= 12 && r_ip_cnt <= 15)r_ip_source <= {r_ip_source[23:0],ri_mac_data};else r_ip_source <= r_ip_source;
end
//输出ip源地址有效
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_source_ip_valid <= 'd0;else if(r_ip_cnt == 15)ro_source_ip_valid <= 'd1;else ro_source_ip_valid <= 'd0;
end//第16 17 18 19字节 ip目的地址
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_target <= 'd0;else if(r_ip_cnt >= 16 && r_ip_cnt <= 19)r_ip_target <= {r_ip_target[23:0],ri_mac_data};else r_ip_target <= r_ip_target;
end//计算UDP 或者 ICMP 的数据长度
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_udp_len <= 'd0;ro_icmp_len <= 'd0;end else beginro_udp_len <= r_ip_len - 20;ro_icmp_len <= r_ip_len - 20;end
end// 第20字节 检测是目的和源IP是否正确
//检测协议类型 UDP还是ICMP
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_udp_valid <= 'd0;else if(!ri_mac_valid && ri_mac_valid_1d)ro_udp_valid <= 'd0;else if(r_ip_cnt == 20 && r_ip_target == r_source_ip && r_ip_type == 17)ro_udp_valid <= 'd1;else ro_udp_valid <= ro_udp_valid;
end
//ICMP 同上
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_icmp_valid <= 'd0;else if(!ri_mac_valid && ri_mac_valid_1d)ro_icmp_valid <= 'd0;else if(r_ip_cnt == 20 && r_ip_target == r_source_ip && r_ip_type == 1)ro_icmp_valid <= 'd1;else ro_icmp_valid <= ro_icmp_valid;
end//i_mac_valid 信号的下降沿 拉高 last信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_udp_last <= 'd0;else if(!i_mac_valid && ri_mac_valid && r_ip_type == 17)ro_udp_last <= 'd1;else ro_udp_last <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_icmp_last <= 'd0;else if(!i_mac_valid && ri_mac_valid && r_ip_type == 1)ro_icmp_last <= 'd1;else ro_icmp_last <= 'd0;
endendmodule
3.2 IP发送模块
module IP_tx#(parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(input i_clk ,input i_rst ,/*--------info port --------*/input [31:0] i_target_ip ,input i_target_valid ,input [31:0] i_source_ip ,input i_source_valid ,/*--------data port--------*/input [7 :0] i_send_type ,input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,output [31:0] o_arp_seek_ip ,output o_arp_seek_valid ,/*--------mac port--------*/output [15:0] o_mac_type ,output [15:0] o_mac_len ,output [7 :0] o_mac_data ,output o_mac_last ,output o_mac_valid );/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [31:0] r_target_ip ;
reg [31:0] r_source_ip ;
reg [7 :0] ri_send_type ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_last ;
reg ri_send_valid ;
reg ri_send_valid_1d ;
reg r_fifo_ip_rd_en ;
reg [7 :0] r_ip_data ;
reg [7 :0] r_ip_valid ;
reg [15:0] r_ip_data_cnt ;
reg [15:0] r_ip_message ;
reg [31:0] r_ip_check ;
reg [15:0] ro_mac_type ;
reg ro_mac_last ;
reg [31:0] ro_arp_seek_ip ;
reg ro_arp_seek_valid ;/***************wire******************/
wire [31:0] w_fifo_ip_dout ;
wire w_fifo_ip_full ;
wire w_fifo_ip_empty ;/***************component*************/
//把要发送的数据存进FIFO,要发送时读出来
FIFO_MAC_8X64 FIFO_IP_8X64_U0 (.clk (i_clk ), // input wire clk.din (ri_send_data ), // input wire [7 : 0] din.wr_en (ri_send_valid ), // input wire wr_en.rd_en (r_fifo_ip_rd_en ), // input wire rd_en.dout (w_fifo_ip_dout ), // output wire [7 : 0] dout.full (w_fifo_ip_full ), // output wire full.empty (w_fifo_ip_empty ) // output wire empty
);/***************assign****************/
assign o_mac_data = r_ip_data ;
assign o_mac_valid = r_ip_valid ;
assign o_mac_len = ri_send_len;
assign o_mac_type = ro_mac_type;
assign o_mac_last = ro_mac_last;
assign o_arp_seek_ip = ro_arp_seek_ip ;
assign o_arp_seek_valid = ro_arp_seek_valid;
/***************always****************/
//目的地址有效 锁存
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_ip <= P_ST_TARGET_IP;else if(i_target_valid)r_target_ip <= i_target_ip;else r_target_ip <= r_target_ip;
end//源地址有效 锁存
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_ip <= P_ST_SOURCE_IP;else if(i_source_valid)r_source_ip <= i_source_ip;else r_source_ip <= r_source_ip;
end//锁存 类型和数据等信息 ip报文长度 为 UDP报文 + 20
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_send_type <= 'd0;ri_send_len <= 'd0;ri_send_data <= 'd0;ri_send_last <= 'd0;ri_send_valid <= 'd0;end else if(i_send_valid) beginri_send_type <= i_send_type ;ri_send_len <= i_send_len + 20;ri_send_data <= i_send_data ;ri_send_last <= i_send_last ;ri_send_valid <= i_send_valid ;end else beginri_send_type <= ri_send_type ;ri_send_len <= ri_send_len ;ri_send_data <= ri_send_data ;ri_send_last <= 'd0;ri_send_valid <= 'd0;end
end // r_ip_data_cnt 计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_data_cnt <= 'd0;else if(r_ip_data_cnt == ri_send_len - 1)r_ip_data_cnt <= 'd0;else if(ri_send_valid || r_ip_data_cnt)r_ip_data_cnt <= r_ip_data_cnt + 1;else r_ip_data_cnt <= r_ip_data_cnt;
end// ip报文的个数 计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_message <= 'd0;else if(o_mac_last)r_ip_message <= r_ip_message + 1;else r_ip_message <= r_ip_message;
end//进行首部校验和
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_check <= 'd0;else if(ri_send_valid && r_ip_data_cnt == 0)r_ip_check <= 16'h4500 + ri_send_len + r_ip_message + 16'h4000 + {8'd64,ri_send_type} + r_source_ip[31:16] +r_source_ip[15:0] + r_target_ip[31:16] + r_target_ip[15:0];else if(r_ip_data_cnt == 1)r_ip_check <= r_ip_check[31:16] + r_ip_check[15:0];else if(r_ip_data_cnt == 2)r_ip_check <= r_ip_check[31:16] + r_ip_check[15:0];else if(r_ip_data_cnt == 3)r_ip_check <= ~r_ip_check;else r_ip_check <= r_ip_check;
end//打拍生成边沿
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_send_valid_1d <= 'd0;else ri_send_valid_1d <= ri_send_valid;
end//发送有效信号上升沿 ip帧有效拉高
// mac帧结束信号拉高,ip帧有效拉低
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_valid <= 'd0;else if(ro_mac_last)r_ip_valid <= 'd0;else if(ri_send_valid && !ri_send_valid_1d)r_ip_valid <= 'd1;else r_ip_valid <= r_ip_valid;
end
//组帧输出
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_data <= 'd0;else case(r_ip_data_cnt)0 : r_ip_data <= {4'b0100,4'b0101}; //版本+首部长度1 : r_ip_data <= 'd0; //服务类型2 : r_ip_data <= ri_send_len[15:8]; //总长度的高8位3 : r_ip_data <= ri_send_len[7 :0]; //总长度的低8位4 : r_ip_data <= r_ip_message[15:8]; //报文标识的高8位5 : r_ip_data <= r_ip_message[7 :0]; //报文标识的低8位6 : r_ip_data <= {3'b010,5'b00000}; //标志+片偏移7 : r_ip_data <= 'd0; //片偏移8 : r_ip_data <= 'd64; //生存时间9 : r_ip_data <= ri_send_type; //协议类型10 : r_ip_data <= r_ip_check[15:8];11 : r_ip_data <= r_ip_check[7 :0];12 : r_ip_data <= r_source_ip[31:24];13 : r_ip_data <= r_source_ip[23:16];14 : r_ip_data <= r_source_ip[15:8];15 : r_ip_data <= r_source_ip[7 :0];16 : r_ip_data <= r_target_ip[31:24];17 : r_ip_data <= r_target_ip[23:16];18 : r_ip_data <= r_target_ip[15:8];19 : r_ip_data <= r_target_ip[7 :0];default : r_ip_data <= w_fifo_ip_dout;endcase
end// ip帧 计数到18 从FIFO中读取数据
// mac帧结束信号拉高,不读了
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_ip_rd_en <= 'd0;else if(ro_mac_last)r_fifo_ip_rd_en <= 'd0;else if(r_ip_data_cnt == 18)r_fifo_ip_rd_en <= 'd1;else r_fifo_ip_rd_en <= r_fifo_ip_rd_en;
end//ip帧计数器计到最大 mac 帧结束了
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_mac_last <= 'd0;else if(r_ip_data_cnt == ri_send_len - 1)ro_mac_last <= 'd1;else ro_mac_last <= 'd0;
end//输出mac层的报文类型
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_mac_type <= 'd0;end else beginro_mac_type <= 16'h0800;end
end //ARP
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_arp_seek_ip <= P_ST_TARGET_IP;ro_arp_seek_valid <= 'd0;end else if(ri_send_valid && !ri_send_valid_1d) beginro_arp_seek_ip <= r_target_ip;ro_arp_seek_valid <= 'd1;end else beginro_arp_seek_ip <= ro_arp_seek_ip;ro_arp_seek_valid <= 'd0;end
end
endmodule
4.1 UDP接收模块
module UDP_rx#(parameter P_TARGET_PORT = 16'h8080 ,P_SOURCE_PORT = 16'h8080
)(input i_clk ,input i_rst ,/*--------info port-------*/input [15:0] i_target_port ,input i_target_valid ,input [15:0] i_source_port ,input i_source_valid ,/*--------data port--------*/output [15:0] o_udp_len ,output [7 :0] o_udp_data ,output o_udp_last ,output o_udp_valid ,/*--------ip port--------*/input [15:0] i_ip_len ,input [7 :0] i_ip_data ,input i_ip_last ,input i_ip_valid
);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] r_target_port ;
reg [15:0] r_source_port ;
reg [15:0] ri_ip_len ;
reg [7 :0] ri_ip_data ;
reg ri_ip_last ;
reg ri_ip_valid ;
reg [15:0] ro_udp_len ;
reg ro_udp_last ;
reg ro_udp_valid ;
reg [15:0] r_udp_cnt ;/***************wire******************//***************component*************//***************assign****************/
assign o_udp_len = ro_udp_len ;
assign o_udp_data = ri_ip_data ;
assign o_udp_last = ro_udp_last ;
assign o_udp_valid = ro_udp_valid ;
/***************always****************/
//锁存 目标端口
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_port <= 'd0;else if(i_target_valid) r_target_port <= i_target_port;else r_target_port <= r_target_port;
end//锁存 源端口
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_port <= 'd0;else if(i_source_valid) r_source_port <= i_source_port;else r_source_port <= r_source_port;
end//ip有效信号 锁存ip的信息
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_ip_len <= 0;ri_ip_data <= 0;ri_ip_last <= 0;ri_ip_valid <= 0;end else if(i_ip_valid) beginri_ip_len <= i_ip_len ;ri_ip_data <= i_ip_data ;ri_ip_last <= i_ip_last ;ri_ip_valid <= i_ip_valid;end else beginri_ip_len <= ri_ip_len ;ri_ip_data <= 'd0 ;ri_ip_last <= 'd0 ;ri_ip_valid <= 'd0;end
end//ip有效信号,r_udp_cnt + 1
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_udp_cnt <= 'd0;else if(ri_ip_valid)r_udp_cnt <= r_udp_cnt + 1;else r_udp_cnt <= 'd0;
end
//UDP帧的长度 为 IP帧长度 - 8
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_udp_len <= 'd0;else ro_udp_len <= ri_ip_len - 8;
end//UDP接收到第7位 拉高UDP有效,跟数据一起出来
//UDP发送到长度-1 时,拉低有效信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_udp_valid <= 'd0;else if(r_udp_cnt == ri_ip_len - 1)ro_udp_valid <= 'd0;else if(r_udp_cnt == 7)ro_udp_valid <= 'd1;else ro_udp_valid <= ro_udp_valid;
end
//拉高last结束信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) ro_udp_last <= 'd0;else if(r_udp_cnt == ri_ip_len - 2)ro_udp_last <= 'd1;else ro_udp_last <= 'd0;
endendmodule
4.2 UDP发送模块
module UDP_tx#(parameter P_TARGET_PORT = 16'h8080 ,P_SOURCE_PORT = 16'h8080
)(input i_clk ,input i_rst ,/*--------info port-------*/input [15:0] i_target_port ,input i_target_valid ,input [15:0] i_source_port ,input i_source_valid ,/*--------data port--------*/input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,/*--------ip port--------*/output [15:0] o_ip_len ,output [7 :0] o_ip_data ,output o_ip_last ,output o_ip_valid
);/***************function**************//***************parameter*************/
localparam P_ST_MIN_LEN = 18 + 8;/***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] r_target_port ;
reg [15:0] r_source_port ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_last ;
reg ri_send_valid ;
reg [15:0] ro_ip_len ;
reg [7 :0] ro_ip_data ;
reg ro_ip_last ;
reg ro_ip_valid ;
reg r_fifo_udp_rd_en;
reg [15:0] r_udp_cnt ;
reg r_fifo_udp_empty;/***************wire******************/
wire [7:0] w_fifo_udp_dout ;
wire w_fifo_udp_full ;
wire w_fifo_udp_empty; /***************component*************/
//要写的数据存进FIFO
FIFO_MAC_8X64 FIFO_UDP_8X64_U0 (.clk (i_clk ), // input wire clk.din (ri_send_data ), // input wire [7 : 0] din.wr_en (ri_send_valid ), // input wire wr_en.rd_en (r_fifo_udp_rd_en ), // input wire rd_en.dout (w_fifo_udp_dout ), // output wire [7 : 0] dout.full (w_fifo_udp_full ), // output wire full.empty (w_fifo_udp_empty ) // output wire empty
);/***************assign****************/
assign o_ip_len = ro_ip_len ;
assign o_ip_data = ro_ip_data ;
assign o_ip_last = ro_ip_last ;
assign o_ip_valid = ro_ip_valid ;/***************always****************/
//锁存 目的端口
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_port <= P_TARGET_PORT;else if(i_target_valid) r_target_port <= i_target_port;else r_target_port <= r_target_port;
end//锁存 源端口
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_source_port <= P_SOURCE_PORT;else if(i_source_valid) r_source_port <= i_source_port;else r_source_port <= r_source_port;
end//锁存输入的IP数据
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_send_data <= 'd0;ri_send_last <= 'd0;ri_send_valid <= 'd0;end else beginri_send_data <= i_send_data ;ri_send_last <= i_send_last ;ri_send_valid <= i_send_valid;end
end//锁存输入的数据长度
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_send_len <= 'd0;else if(i_send_valid) ri_send_len <= i_send_len ;else ri_send_len <= ri_send_len;
end//发送UDP数据长度小于18 并且已经完成18+8 的UDP帧 ,后计数器清空
//大于18 ,正常发完
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) r_udp_cnt <= 'd0;else if(ri_send_len < 18 && r_udp_cnt == P_ST_MIN_LEN - 1)r_udp_cnt <= 'd0;else if(ri_send_len >= 18 && r_udp_cnt == (ri_send_len + 8) - 1)r_udp_cnt <= 'd0;else if(ri_send_valid || r_udp_cnt)r_udp_cnt <= r_udp_cnt + 1;else r_udp_cnt <= r_udp_cnt;
end//如果数据长度小于18 就默认18
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_ip_len <= 'd0;else if(ri_send_len < 18)ro_ip_len <= 18;else ro_ip_len <= ri_send_len + 8;
end//如果收到ip_last信号,ip有效拉低
//收到输入有效信号,ip有效拉高
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_ip_valid <= 'd0;else if(ro_ip_last)ro_ip_valid <= 'd0;else if(ri_send_valid)ro_ip_valid <= 'd1;else ro_ip_valid <= ro_ip_valid;
end
//UDP发完后,拉高ip_last信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_ip_last <= 'd0;else if(ri_send_len < 18 && r_udp_cnt == P_ST_MIN_LEN - 1)ro_ip_last <= 'd1;else if(ri_send_len >= 18 && r_udp_cnt == (ri_send_len + 8) - 1)ro_ip_last <= 'd1;else ro_ip_last <= 'd0;
end//输出完8字节 UDP帧的头 FIFO读使能打开
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_udp_rd_en <= 'd0;else if(r_udp_cnt == (ri_send_len + 8) - 1)r_fifo_udp_rd_en <= 'd0;else if(r_udp_cnt == 6)r_fifo_udp_rd_en <= 'd1;else r_fifo_udp_rd_en <= r_fifo_udp_rd_en;
end//空信号打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_udp_empty <= 'd0;else r_fifo_udp_empty <= w_fifo_udp_empty;
end//组帧输出
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_ip_data <= 'd0;else case(r_udp_cnt)0 : ro_ip_data <= r_source_port[15:8];1 : ro_ip_data <= r_source_port[7 :0];2 : ro_ip_data <= r_target_port[15:8];3 : ro_ip_data <= r_target_port[7 :0];4 : ro_ip_data <= ro_ip_len[15:8];5 : ro_ip_data <= ro_ip_len[7 :0];6 : ro_ip_data <= 'd0;7 : ro_ip_data <= 'd0;default : ro_ip_data <= !r_fifo_udp_empty ? w_fifo_udp_dout : 'd0;endcase
endendmodule
5.1 ICMP接收模块
module ICMP_rx(input i_clk ,input i_rst ,/*--------rec port--------*/input [15:0] i_icmp_len ,input [7 :0] i_icmp_data ,input i_icmp_last ,input i_icmp_valid , /*--------send port--------*/output o_trig_reply ,output [15:0] o_trig_seq
);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] ri_icmp_len ;
reg [7 :0] ri_icmp_data ;
reg ri_icmp_last ;
reg ri_icmp_valid ;
reg ro_trig_reply ;
reg [15:0] r_icmp_cnt ;
reg [7 :0] r_type ;
reg [15:0] ro_trig_seq ;/***************wire******************//***************component*************//***************assign****************/
assign o_trig_reply = ro_trig_reply ;
assign o_trig_seq = ro_trig_seq ;/***************always****************/
//输入信号打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_icmp_len <= 'd0;ri_icmp_data <= 'd0;ri_icmp_last <= 'd0;ri_icmp_valid <= 'd0;end else beginri_icmp_len <= i_icmp_len ;ri_icmp_data <= i_icmp_data ;ri_icmp_last <= i_icmp_last ;ri_icmp_valid <= i_icmp_valid;end
end//开始计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_icmp_cnt <= 'd0;else if(ri_icmp_valid)r_icmp_cnt <= r_icmp_cnt + 1;else r_icmp_cnt <= 'd0;
end//存下icmp类型
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_type <= 'd0;else if(ri_icmp_valid && r_icmp_cnt == 0)r_type <= ri_icmp_data;else r_type <= r_type;
end//ICMP帧的 序号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_trig_seq <= 'd0;else if(r_icmp_cnt >=6 && r_icmp_cnt <= 7)ro_trig_seq <= {ro_trig_seq[7 :0],ri_icmp_data};else ro_trig_seq <= ro_trig_seq;
end//类型为8 计数8个 拉高序号的回复信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_trig_reply <= 'd0;else if(r_icmp_cnt == 7 && r_type == 8)ro_trig_reply <= 'd1;else ro_trig_reply <= 'd0;
endendmodule
5.2 ICMP发送模块
module ICMP_tx(input i_clk ,input i_rst ,input i_trig_reply ,input [15:0] i_trig_seq ,output [15:0] o_icmp_len ,output [7 :0] o_icmp_data ,output o_icmp_last ,output o_icmp_valid
);/***************function**************//***************parameter*************/
localparam P_LEN = 40 ;
/***************port******************/ /***************mechine***************//***************reg*******************/
reg ri_trig_reply ;
reg [15:0] ri_trig_seq ;
reg [15:0] ro_icmp_len ;
reg [7 :0] ro_icmp_data ;
reg ro_icmp_last ;
reg ro_icmp_valid ;
reg [15:0] r_icmp_cnt ;
reg [31:0] r_icmp_check ;
reg [7 :0] r_check_cnt ;/***************wire******************//***************component*************//***************assign****************/
assign o_icmp_len = ro_icmp_len ;
assign o_icmp_data = ro_icmp_data ;
assign o_icmp_last = ro_icmp_last ;
assign o_icmp_valid = ro_icmp_valid;
/***************always****************/
//序号值 和 信号 打一拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_trig_reply <= 'd0;ri_trig_seq <= 'd0;end else beginri_trig_reply <= i_trig_reply;ri_trig_seq <= i_trig_seq;end
end//r_check_cnt 在 ri_trig_reply拉高后 +1
//r_icmp_cnt 计数完,r_check_cnt清空
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_check_cnt <= 'd0;else if(r_icmp_cnt == P_LEN - 1)r_check_cnt <= 'd0;else if(r_check_cnt == 3)r_check_cnt <= r_check_cnt + 1;else if(ri_trig_reply | r_check_cnt)r_check_cnt <= r_check_cnt + 1;else r_check_cnt <= r_check_cnt;
end//ICMP的校验和 和IP层的首部校验和一样
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_icmp_check <= 'd0;else if(r_check_cnt == 0)r_icmp_check <= 16'h0001 + ri_trig_seq;else if(r_check_cnt == 1)r_icmp_check <= r_icmp_check[31:16] + r_icmp_check[15:0];else if(r_check_cnt == 2)r_icmp_check <= r_icmp_check[31:16] + r_icmp_check[15:0];else if(r_check_cnt == 3)r_icmp_check <= ~r_icmp_check;else r_icmp_check <= r_icmp_check;
end//校验完成后 开始组帧计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_icmp_cnt <= 'd0;else if(r_icmp_cnt == P_LEN - 1)r_icmp_cnt <= 'd0;else if(r_check_cnt == 3 || r_icmp_cnt)r_icmp_cnt <= r_icmp_cnt + 1;else r_icmp_cnt <= r_icmp_cnt;
end
//ICMP的长度 输出
always@(posedge i_clk,posedge i_rst)
begin if(i_rst)ro_icmp_len <= 'd0;else ro_icmp_len <= P_LEN;
end
//校验完成输出 ICMP帧,使能拉高
always@(posedge i_clk,posedge i_rst)
begin if(i_rst)ro_icmp_valid <= 'd0;else if(r_icmp_cnt == P_LEN - 1)ro_icmp_valid <= 'd0;else if(r_check_cnt == 3)ro_icmp_valid <= 'd1;else ro_icmp_valid <= ro_icmp_valid;
end//输出结束信号
always@(posedge i_clk,posedge i_rst)
begin if(i_rst)ro_icmp_last <= 'd0;else if(r_icmp_cnt == P_LEN - 2)ro_icmp_last <= 'd1;else ro_icmp_last <= 'd0;
end//组帧
always@(posedge i_clk,posedge i_rst)
begin if(i_rst)ro_icmp_data <= 'd0;else case(r_icmp_cnt)0 :ro_icmp_data <= 'd0;1 :ro_icmp_data <= 'd0;2 :ro_icmp_data <= r_icmp_check[15:8];3 :ro_icmp_data <= r_icmp_check[7 :0];4 :ro_icmp_data <= 8'h00;5 :ro_icmp_data <= 8'h01;6 :ro_icmp_data <= ri_trig_seq[15:8];7 :ro_icmp_data <= ri_trig_seq[7 :0];default :ro_icmp_data <= 'd0;endcase
endendmodule
6.1 ARP接收模块
module ARP_rx#(parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(input i_clk ,input i_rst ,input [31:0] i_source_ip ,input i_s_ip_valid ,/*--------info port--------*/output [47:0] o_target_mac ,output [31:0] o_target_ip ,output o_target_valid ,output o_tirg_reply ,/*--------MAC port--------*/input [7 :0] i_mac_data ,input i_mac_last ,input i_mac_valid
);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [47:0] ro_target_mac ;
reg [31:0] ro_target_ip ;
reg ro_target_valid ;
reg [7 :0] ri_mac_data ;
reg [7 :0] ri_mac_data_1d ;
reg ri_mac_last ;
reg ri_mac_valid ;
reg [15:0] r_mac_cnt ;
reg [15:0] r_arp_op ;
reg ro_tirg_reply ;
reg [31:0] ri_source_ip ; /***************wire******************//***************component*************//***************assign****************/
assign o_target_mac = ro_target_mac ;
assign o_target_ip = ro_target_ip ;
assign o_tirg_reply = ro_tirg_reply ;
assign o_target_valid = ro_target_valid;/***************always****************/
//打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_mac_data <= 'd0;ri_mac_last <= 'd0;ri_mac_valid <= 'd0;ri_mac_data_1d <= 'd0;end else begin ri_mac_data <= i_mac_data ;ri_mac_last <= i_mac_last ;ri_mac_valid <= i_mac_valid;ri_mac_data_1d <= ri_mac_data;end
end//源ip 锁存
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_source_ip <= P_SOURCE_IP;else if(i_s_ip_valid)ri_source_ip <= i_source_ip;else ri_source_ip <= ri_source_ip;
end//mac计数器
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_cnt <= 'd0;else if(ri_mac_valid) r_mac_cnt <= r_mac_cnt + 1;else r_mac_cnt <= 'd0;
end//获得ARP的操作类型
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_arp_op <= 'd0;else if(r_mac_cnt >= 6 && r_mac_cnt <= 7)r_arp_op <= {r_arp_op[7 :0],ri_mac_data};else r_arp_op <= r_arp_op;
end//获得目的mac
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_target_mac <= 'd0;else if(r_mac_cnt >= 8 && r_mac_cnt <= 13 && (r_arp_op == 1 || r_arp_op == 2))ro_target_mac <= {ro_target_mac[39:0],ri_mac_data};else ro_target_mac <= ro_target_mac;
end//获得目的ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_target_ip <= 'd0;else if(r_mac_cnt >= 14 && r_mac_cnt <= 17 && (r_arp_op == 1 || r_arp_op == 2))ro_target_ip <= {ro_target_ip[23:0],ri_mac_data};else ro_target_ip <= ro_target_ip;
end//计数到17 拉高有效信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) ro_target_valid <= 'd0;else if(r_mac_cnt == 17) ro_target_valid <= 'd1;else ro_target_valid <= 'd0;
end//计数到18 类型为1 请求
//回复信号触发信号 拉高
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_tirg_reply <= 'd0;else if(r_mac_cnt == 18 && r_arp_op == 1)ro_tirg_reply <= 'd1;else ro_tirg_reply <= 'd0;
endendmodule
6.2 ARP发送模块
module ARP_tx#(parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(input i_clk ,input i_rst ,input [31:0] i_target_ip ,input i_target_valid ,input [47:0] i_source_mac ,input i_s_mac_valid ,input [31:0] i_source_ip ,input i_s_ip_valid ,input [47:0] i_reply_mac ,output [31:0] o_seek_ip ,output o_seek_valid ,input i_trig_reply ,input i_active_send ,output [7 :0] o_mac_data ,output o_mac_last ,output o_mac_valid
);/***************function**************//***************parameter*************/
localparam P_LEN = 46 ;/***************port******************/ /***************mechine***************//***************reg*******************/
reg [31:0] r_target_ip ;
reg ri_trig_reply ;
reg ri_active_send ;
reg [7 :0] ro_mac_data ;
reg ro_mac_last ;
reg ro_mac_valid ;
reg [15:0] r_mac_cnt ;
reg [15:0] r_arp_op ;
reg [47:0] ri_source_mac ;
reg [31:0] ri_source_ip ;
reg [31:0] ro_seek_ip ;
reg ro_seek_valid ;
reg [47:0] ri_reply_mac ;
reg [15:0] r_arp_cnt ;/***************wire******************/
wire w_act ;/***************component*************//***************assign****************/
assign o_mac_data = ro_mac_data ;
assign o_mac_last = ro_mac_last ;
assign o_mac_valid = ro_mac_valid ;
assign o_seek_ip = ro_seek_ip ;
assign o_seek_valid = ro_seek_valid ;
assign w_act = r_arp_cnt == 10;/***************always****************///主动ARP和被动ARP 触发有效
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) ro_seek_valid <= 'd0;else if(i_trig_reply | i_active_send)ro_seek_valid <= 'd1;else ro_seek_valid <= 'd0;
end//输出 源ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_seek_ip <= 'd0;else ro_seek_ip <= ri_source_ip;
end//输入目的有效 获得目的ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_target_ip <= P_TARGET_IP;else if(i_target_valid)r_target_ip <= i_target_ip;else r_target_ip <= r_target_ip;
end//输入mac有效,获得源mac
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_source_mac <= P_SOURCE_MAC;else if(i_s_mac_valid)ri_source_mac <= i_source_mac;else ri_source_mac <= ri_source_mac;
end//输入ip有效,获得源ip
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_source_ip <= P_SOURCE_IP;else if(i_s_ip_valid)ri_source_ip <= i_source_ip;else ri_source_ip <= ri_source_ip;
end// 被动触发 和主动触发信号打拍
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_trig_reply <= 'd0;ri_active_send <= 'd0;end else beginri_trig_reply <= i_trig_reply ;ri_active_send <= i_active_send | w_act;end
end//r_arp_cnt计数器 0 到 11
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_arp_cnt <= 'd0;else if(r_arp_cnt < 11)r_arp_cnt <= r_arp_cnt + 1;else r_arp_cnt <= r_arp_cnt;
end//打拍后的触发信号,控制开始mac帧计数
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_mac_cnt <= 'd0;else if(r_mac_cnt == P_LEN - 1)r_mac_cnt <= 'd0;else if(ri_trig_reply || ri_active_send || r_mac_cnt) r_mac_cnt <= r_mac_cnt + 1;else r_mac_cnt <= r_mac_cnt;
end//打拍后的触发信号,控制回复类型值
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_arp_op <= 'd0;else if(ri_trig_reply)r_arp_op <= 'd2;else if(ri_active_send)r_arp_op <= 'd1;else r_arp_op <= r_arp_op;
end//得到mac帧 用于回复
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_reply_mac <= 'd0;else ri_reply_mac <= i_reply_mac;
end //组帧输出
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_mac_data <= 'd0;else case(r_mac_cnt)0 :ro_mac_data <= 'd0;1 :ro_mac_data <= 'd1;2 :ro_mac_data <= 8'h08;3 :ro_mac_data <= 8'h00;4 :ro_mac_data <= 'd6;5 :ro_mac_data <= 'd4;6 :ro_mac_data <= r_arp_op[15:8];7 :ro_mac_data <= r_arp_op[7 :0];8 :ro_mac_data <= ri_source_mac[47:40];9 :ro_mac_data <= ri_source_mac[39:32];10 :ro_mac_data <= ri_source_mac[31:24];11 :ro_mac_data <= ri_source_mac[23:16];12 :ro_mac_data <= ri_source_mac[15: 8];13 :ro_mac_data <= ri_source_mac[7 : 0];14 :ro_mac_data <= ri_source_ip[31:24];15 :ro_mac_data <= ri_source_ip[23:16];16 :ro_mac_data <= ri_source_ip[15: 8];17 :ro_mac_data <= ri_source_ip[7 : 0];18 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[47:40] : 8'h00;19 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[39:32] : 8'h00;20 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[31:24] : 8'h00; 21 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[23:16] : 8'h00;22 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[15: 8] : 8'h00;23 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[7 : 0] : 8'h00;24 :ro_mac_data <= r_target_ip[31:24];25 :ro_mac_data <= r_target_ip[23:16];26 :ro_mac_data <= r_target_ip[15: 8];27 :ro_mac_data <= r_target_ip[7 : 0];default :ro_mac_data <= 'd0;endcase
end//到长度就拉低有效信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_mac_valid <= 'd0;else if(r_mac_cnt == P_LEN - 1)ro_mac_valid <= 'd0;else if(ri_trig_reply || ri_active_send )ro_mac_valid <= 'd1;else ro_mac_valid <= ro_mac_valid;
end //产生last信号
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_mac_last <= 'd0;else if(r_mac_cnt == P_LEN - 2)ro_mac_last <= 'd1;else ro_mac_last <= 'd0;
endendmodule
6.3 ARP表模块
module ARP_Table(input i_clk ,input i_rst ,input [31:0] i_seek_ip ,input i_seek_valid ,input [31:0] i_updata_ip ,input [47:0] i_updata_mac ,input i_updata_valid ,output [47:0] o_active_mac ,output o_active_valid
); /***************function**************//***************parameter*************/
localparam P_ST_IDLE = 0 ,P_ST_SEEK = 1 ,P_ST_UPDATA_S = 2 ,P_ST_UPDATA = 3 ,P_ST_MAC = 4 ;/***************port******************/ /***************mechine***************/
reg [7 :0] r_st_current ;
reg [7 :0] r_st_next ;/***************reg*******************/
reg [31:0] r_seek_ip ;
reg [31:0] r_updata_ip ;
reg [47:0] r_updata_mac ;
reg [47:0] ro_active_mac ;
reg ro_active_valid ;
reg ri_seek_valid ;
reg ri_updata_valid ;
reg r_ram_ip_en ;
reg r_ram_ip_we ;
reg [2 :0] r_ram_ip_addr ;
reg r_ram_ip_dv ;
reg r_ram_mac_en ;
reg r_ram_mac_we ;
reg [2 :0] r_ram_mac_addr ;
reg r_ram_mac_dv ;
reg r_ip_access ;
reg [2 :0] r_access_addr ;
reg r_ram_ip_end ;
reg r_ram_ip_end_1d ;
reg r_updata_acc ;
reg [2 :0] r_up_data_addr ;/***************wire******************/
wire [31:0] w_ram_ip_dout ;
wire [47:0] w_ram_mac_dout ;
wire w_seek_v_pos ;
wire w_seek_v_neg ;
wire w_updata_v_pos ;
wire w_updata_v_neg ;
wire r_ram_ip_end_neg;/***************component*************/
RAM_IP RAM_IP_U0 (.clka (i_clk ),.ena (r_ram_ip_en ),.wea (r_ram_ip_we ),.addra (r_ram_ip_addr ),.dina (r_updata_ip ),.douta (w_ram_ip_dout )
);RAM_MAC RAM_MAC_U0 (.clka (i_clk ), .ena (r_ram_mac_en ), .wea (r_ram_mac_we ), .addra (r_ram_mac_addr ), .dina (r_updata_mac ), .douta (w_ram_mac_dout )
);
/***************assign****************/
assign o_active_mac = ro_active_mac ;
assign o_active_valid = ro_active_valid ;
assign w_seek_v_pos = i_seek_valid & !ri_seek_valid;
assign w_seek_v_neg = !i_seek_valid & ri_seek_valid;
assign w_updata_v_pos = i_updata_valid & !ri_updata_valid;
assign w_updata_v_neg = !i_updata_valid & ri_updata_valid;
assign r_ram_ip_end_neg = r_ram_ip_end & !r_ram_ip_end_1d;/***************always****************/
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_st_current <= P_ST_IDLE;else r_st_current <= r_st_next;
endalways@(*)
begincase(r_st_current)P_ST_IDLE :r_st_next = w_seek_v_pos ? P_ST_SEEK : i_updata_valid ? P_ST_UPDATA_S : P_ST_IDLE;P_ST_SEEK :r_st_next = r_ip_access || (r_ram_ip_end_neg && !r_ip_access)? P_ST_MAC : P_ST_SEEK;P_ST_UPDATA_S :r_st_next = r_updata_acc ? P_ST_IDLE : (r_ram_ip_end_neg && !r_updata_acc) ? P_ST_UPDATA : P_ST_UPDATA_S;P_ST_UPDATA :r_st_next = P_ST_IDLE;P_ST_MAC :r_st_next = P_ST_IDLE;default :r_st_next = P_ST_IDLE;endcase
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_seek_ip <= 'd0;else if(i_seek_valid)r_seek_ip <= i_seek_ip;else r_seek_ip <= r_seek_ip;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginr_updata_ip <= 'd0;r_updata_mac <= 'd0;end else if(i_updata_valid) begin r_updata_ip <= i_updata_ip ;r_updata_mac <= i_updata_mac;end else beginr_updata_ip <= r_updata_ip ;r_updata_mac <= r_updata_mac;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_seek_valid <= 'd0;ri_updata_valid <= 'd0;end else beginri_seek_valid <= i_seek_valid ;ri_updata_valid <= i_updata_valid;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) begin r_ram_ip_en <= 'd0;r_ram_ip_we <= 'd0;r_ram_ip_addr <= 'd0; end else if(r_st_current == P_ST_SEEK && !r_ram_ip_end) beginr_ram_ip_en <= 'd1;r_ram_ip_we <= 'd0;if(r_ram_ip_en) r_ram_ip_addr <= r_ram_ip_addr + 1;else r_ram_ip_addr <= 'd0;end else if(r_st_current == P_ST_UPDATA_S && !r_ram_ip_end) beginr_ram_ip_en <= 'd1;r_ram_ip_we <= 'd0;if(r_ram_ip_en) r_ram_ip_addr <= r_ram_ip_addr + 1;else r_ram_ip_addr <= 'd0;end else if(r_st_current == P_ST_UPDATA) beginr_ram_ip_en <= 'd1;r_ram_ip_we <= 'd1;r_ram_ip_addr <= r_up_data_addr;end else beginr_ram_ip_en <= 'd0;r_ram_ip_we <= 'd0;r_ram_ip_addr <= 'd0;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) begin r_ram_mac_en <= 'd0;r_ram_mac_we <= 'd0;r_ram_mac_addr <= 'd0; end else if(r_st_current == P_ST_UPDATA_S && !r_ram_ip_end) beginr_ram_mac_en <= 'd1;r_ram_mac_we <= 'd0;r_ram_mac_addr <= r_ram_mac_addr + 1;end else if(r_st_current == P_ST_UPDATA) beginr_ram_mac_en <= 'd1;r_ram_mac_we <= 'd1;r_ram_mac_addr <= r_up_data_addr;end else if(r_ram_ip_dv && w_ram_ip_dout == r_seek_ip) beginr_ram_mac_en <= 'd1;r_ram_mac_we <= 'd0;r_ram_mac_addr <= r_access_addr;end else beginr_ram_mac_en <= 'd0;r_ram_mac_we <= 'd0;r_ram_mac_addr <= 'd0;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_ip_end <= 'd0;else if(r_st_current == P_ST_IDLE)r_ram_ip_end <= 'd0;else if(r_st_current == P_ST_SEEK && r_ram_ip_addr == 7)r_ram_ip_end <= 'd1;else if(r_st_current == P_ST_UPDATA_S && r_ram_ip_addr == 7)r_ram_ip_end <= 'd1;else r_ram_ip_end <= r_ram_ip_end;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_ip_end_1d <= 'd0;elser_ram_ip_end_1d <= r_ram_ip_end;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_ip_dv <= 'd0;else if(r_ram_ip_en && !r_ram_ip_we && !r_ip_access)r_ram_ip_dv <= 'd1;else r_ram_ip_dv <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ip_access <= 'd0;else if(r_st_current == P_ST_IDLE)r_ip_access <= 'd0;else if(r_ram_ip_dv && w_ram_ip_dout == r_seek_ip)r_ip_access <= 'd1;else r_ip_access <= r_ip_access;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_access_addr <= 'd0;else if(r_st_current == P_ST_IDLE)r_access_addr <= 'd0;else if(r_ram_ip_dv && !r_ip_access)r_access_addr <= r_access_addr + 1;else r_access_addr <= r_access_addr;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_updata_acc <= 'd0;else if(r_ram_ip_dv && w_ram_ip_dout == r_updata_ip && w_ram_mac_dout == r_updata_mac)r_updata_acc <= 'd1;else r_updata_acc <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_up_data_addr <= 'd0;else if(r_st_current == P_ST_UPDATA)r_up_data_addr <= r_up_data_addr + 1;else r_up_data_addr <= r_up_data_addr;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_active_mac <= 48'd0;else if(r_st_current == P_ST_MAC && r_ip_access)ro_active_mac <= w_ram_mac_dout;else ro_active_mac <= 48'hffffffffffff;
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_active_valid <= 'd0;else if(r_st_current == P_ST_MAC)ro_active_valid <= 'd1;else ro_active_valid <= 'd0;
end
endmodule
7 CRC数据对比模块
要双端口ram读写缓存帧的数据和FIFO配合存储帧长度和类型
module CRC_Data_Pro(input i_clk ,input i_rst ,input [15:0] i_per_type ,input [7 :0] i_per_data ,input i_per_last ,input i_per_valid ,input i_per_crc_error ,input i_per_crc_valid ,output [15:0] o_post_type ,output [7 :0] o_post_data ,output o_post_last ,output o_post_valid
);/***************function**************//***************parameter*************/
localparam P_FRAME_GAP = 12 ;/***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] ri_per_type ;
reg [7 :0] ri_per_data ;
reg ri_per_last ;
reg ri_per_valid ;
reg ri_per_valid_1d ;
reg ri_per_crc_error ;
reg ri_per_crc_valid ;
reg [7 :0] ro_post_data ;
reg ro_post_last ;
reg ro_post_valid ;
reg r_ram_en_A ;
reg r_ram_we_A ;
reg [11:0] r_ram_addr_A ;
reg [7 :0] r_ram_din_A ;
reg r_ram_en_B ;
reg r_ram_en_B_1d ;
reg r_ram_we_B ;
reg [11:0] r_ram_addr_B ;
reg [10:0] r_data_len ;
reg [10:0] r_data_len_o ;
reg r_fifo_rd_en ;
reg r_fifo_rd_en_1d ;
reg r_fifo_wr_en ;
reg r_out_run ;
reg r_out_run_1d ;
reg [10:0] r_fifo_dout ;
reg [15:0] r_gap_cnt ;
reg [15:0] ro_post_type ;
reg ri_per_last_1d ;/***************wire******************/
wire [7 :0] w_ram_dout_B ;
wire [10:0] w_fifo_dout ;
wire w_fifo_empty ;
wire w_fifo_full ;
wire [15:0] w_fifo_type ;/***************component*************/
RAM_8x1500_TrueDual RAM_8x1500_TrueDual_u0 (//修改为8X3000 .clka (i_clk ),.ena (r_ram_en_A ),.wea (r_ram_we_A ),.addra (r_ram_addr_A ),.dina (r_ram_din_A ),.douta (),.clkb (i_clk ),.enb (r_ram_en_B ),.web (r_ram_we_B ),.addrb (r_ram_addr_B ),.dinb (0 ),.doutb (w_ram_dout_B )
);FIFO_11X64 FIFO_11X64_U0 (.clk (i_clk ),.din (r_data_len ),.wr_en (r_fifo_wr_en ),.rd_en (r_fifo_rd_en ),.dout (w_fifo_dout ),.full (w_fifo_full ),.empty (w_fifo_empty )
);FIFO_16X64 FIFO_16X64_U1 (.clk (i_clk ),.din (ri_per_type ),.wr_en (r_fifo_wr_en ),.rd_en (r_fifo_rd_en ),.dout (w_fifo_type ),.full (),.empty ()
);/***************assign****************/
assign o_post_data = ro_post_data ;
assign o_post_last = ro_post_last ;
assign o_post_valid = ro_post_valid;
assign o_post_type = ro_post_type;/***************always****************/
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_per_data <= 'd0;ri_per_last <= 'd0;ri_per_valid <= 'd0;ri_per_type <= 'd0;ri_per_crc_error <= 'd0;ri_per_crc_valid <= 'd0;end else beginri_per_data <= i_per_data ;ri_per_last <= i_per_last ;ri_per_valid <= i_per_valid ;ri_per_type <= i_per_type ;ri_per_crc_error <= i_per_crc_error;ri_per_crc_valid <= i_per_crc_valid;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginr_ram_en_A <= 'd0; r_ram_we_A <= 'd0; r_ram_din_A <= 'd0;end else if(ri_per_valid) beginr_ram_en_A <= 'd1;r_ram_we_A <= 'd1;r_ram_din_A <= ri_per_data;end else beginr_ram_en_A <= 'd0;r_ram_we_A <= 'd0;r_ram_din_A <= 'd0;end
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_per_valid_1d <= 'd0;elseri_per_valid_1d <= ri_per_valid;
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_addr_A <= 'd0;else if(ri_per_crc_valid && ri_per_crc_error)r_ram_addr_A <= r_ram_addr_A - r_data_len;else if(r_ram_addr_A == 2999)r_ram_addr_A <= 'd0;else if(ri_per_valid && !ri_per_valid_1d)r_ram_addr_A <= r_ram_addr_A;else if(ri_per_valid | ri_per_valid_1d)r_ram_addr_A <= r_ram_addr_A + 1;else r_ram_addr_A <= r_ram_addr_A;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ri_per_last_1d <= 'd0;else ri_per_last_1d <= ri_per_last;
end// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// r_data_len <= 'd0;
// else if(ri_per_last_1d)
// r_data_len <= r_ram_addr_A;
// else
// r_data_len <= r_data_len;
// endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_data_len <= 'd0;else if(r_fifo_wr_en)r_data_len <= 'd0;else if(ri_per_valid)r_data_len <= r_data_len + 1;elser_data_len <= r_data_len;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_wr_en <= 'd0;else if(ri_per_crc_valid && !ri_per_crc_error && !r_fifo_wr_en)r_fifo_wr_en <= 'd1;else r_fifo_wr_en <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_rd_en <= 'd0;else if(!w_fifo_empty && !r_out_run && !r_fifo_rd_en && r_gap_cnt == P_FRAME_GAP - 4)r_fifo_rd_en <= 'd1;elser_fifo_rd_en <= 'd0;
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_rd_en_1d <= 'd0;else r_fifo_rd_en_1d <= r_fifo_rd_en;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_dout <= 'd0;else if(r_fifo_rd_en_1d) r_fifo_dout <= w_fifo_dout;else r_fifo_dout <= r_fifo_dout;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_out_run <= 'd0;else if(r_data_len_o == r_fifo_dout - 1)r_out_run <= 'd0;else if(!r_fifo_rd_en && r_fifo_rd_en_1d)r_out_run <= 'd1;else r_out_run <= r_out_run;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_data_len_o <= 'd0;else if(r_data_len_o == r_fifo_dout - 1)r_data_len_o <= 'd0;else if(r_out_run)r_data_len_o <= r_data_len_o + 1;else r_data_len_o <= r_data_len_o;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_out_run_1d <= 'd0;elser_out_run_1d <= r_out_run;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginr_ram_en_B <= 'd0; r_ram_we_B <= 'd0; end else if(r_out_run && !r_out_run_1d) beginr_ram_en_B <= 'd1; r_ram_we_B <= 'd0; end else if(r_out_run) beginr_ram_en_B <= 'd1; r_ram_we_B <= 'd0; end else beginr_ram_en_B <= 'd0; r_ram_we_B <= 'd0; end
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_addr_B <= 'd0;else if(r_ram_addr_B == 2999) r_ram_addr_B <= 'd0;else if(r_out_run && !r_out_run_1d)r_ram_addr_B <= r_ram_addr_B;else if(r_out_run | r_out_run_1d)r_ram_addr_B <= r_ram_addr_B + 1;else r_ram_addr_B <= r_ram_addr_B;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_data <= 'd0;else if(r_ram_en_B_1d)ro_post_data <= w_ram_dout_B;else ro_post_data <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_type <= 'd0;else if(r_fifo_rd_en_1d)ro_post_type <= w_fifo_type;else ro_post_type <= ro_post_type;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_ram_en_B_1d <= 'd0;else r_ram_en_B_1d <= r_ram_en_B;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_valid <= 'd0;else ro_post_valid <= r_ram_en_B_1d;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_post_last <= 'd0;else if(!r_ram_en_B && r_ram_en_B_1d)ro_post_last <= 'd1;else ro_post_last <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_gap_cnt <= 'd1;else if(r_fifo_rd_en)r_gap_cnt <= 'd0;else if(r_gap_cnt == P_FRAME_GAP - 4)r_gap_cnt <= r_gap_cnt;else if(ro_post_last | r_gap_cnt)r_gap_cnt <= r_gap_cnt + 1;else r_gap_cnt <= r_gap_cnt;
endendmodule
8 MAC下ARP和IP数据分流模块
类型是0800就是IP 0806就是ARP,进行分流操作
module mac_arp_ip_mux(input i_clk ,input i_rst ,input [15:0] i_type ,input [7 :0] i_data ,input i_last ,input i_valid ,output [7 :0] o_ip_data ,output o_ip_last ,output o_ip_valid ,output [7 :0] o_arp_data ,output o_arp_last ,output o_arp_valid
);reg [7 :0] ro_ip_data ;
reg ro_ip_last ;
reg ro_ip_valid ;
reg [7 :0] ro_arp_data ;
reg ro_arp_last ;
reg ro_arp_valid ;assign o_ip_data = ro_ip_data ;
assign o_ip_last = ro_ip_last ;
assign o_ip_valid = ro_ip_valid ;
assign o_arp_data = ro_arp_data ;
assign o_arp_last = ro_arp_last ;
assign o_arp_valid = ro_arp_valid ;always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_ip_data <= 'd0;ro_ip_last <= 'd0;ro_ip_valid <= 'd0;end else if(i_type == 16'h0800) beginro_ip_data <= i_data ;ro_ip_last <= i_last ;ro_ip_valid <= i_valid;end else beginro_ip_data <= 'd0;ro_ip_last <= 'd0;ro_ip_valid <= 'd0;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_arp_data <= 'd0;ro_arp_last <= 'd0;ro_arp_valid <= 'd0;end else if(i_type == 16'h0806) beginro_arp_data <= i_data ;ro_arp_last <= i_last ;ro_arp_valid <= i_valid;end else beginro_arp_data <= 'd0;ro_arp_last <= 'd0;ro_arp_valid <= 'd0;end
endendmodule
9 数据流仲裁模块
两个数据流都加个FIFO,以帧为单位,先输出A,A输出完成后再输出B。还要进行流控:要切换通道输出时,要先把现在这个通道的FIFO数据输出完,才能来新通道的输入,保证多次操作之后FIFO不会溢出。
module Data_2to1(input i_clk ,input i_rst ,input [15:0] i_type_A ,input [15:0] i_len_A ,input [7 :0] i_data_A ,input i_last_A ,input i_valid_A ,output o_next_frame_stop ,input [15:0] i_type_B ,input [15:0] i_len_B ,input [7 :0] i_data_B ,input i_last_B ,input i_valid_B ,output [15:0] o_type ,output [15:0] o_len ,output [7 :0] o_data ,output o_last ,output o_valid
);/***************function**************//***************parameter*************//***************port******************/ /***************mechine***************//***************reg*******************/
reg [15:0] ri_type_A ;
reg [15:0] ri_len_A ;
reg [7 :0] ri_data_A ;
reg ri_last_A ;
reg ri_valid_A ;
reg ri_valid_A_1d ;
reg [15:0] ri_type_B ;
reg [15:0] ri_len_B ;
reg [7 :0] ri_data_B ;
reg ri_last_B ;
reg ri_valid_B ;
reg ri_valid_B_1d ;
reg [7 :0] ro_data ;
reg ro_last ;
reg ro_valid ;
reg r_fifo_A_rden ;
reg r_fifo_B_rden ;
reg r_fifo_A_rden_1d;
reg r_fifo_B_rden_1d;
reg [1 :0] r_fifo_rd ;
reg [1:0] r_arbiter ;
reg [15:0] r_rd_cnt ;
reg r_rd_en ;
reg ro_next_frame_stop ;
reg [15:0] ro_type ;
reg [15:0] ro_len ;
reg r_rden_A_pos ;
reg r_rden_B_pos ;
reg [7 :0] r_cnt ;/***************wire******************/
wire [7 :0] w_fifo_A_dout ;
wire w_fifo_A_full ;
wire w_fifo_A_empty ;
wire [7 :0] w_fifo_B_dout ;
wire w_fifo_B_full ;
wire w_fifo_B_empty ;
wire w_rd_en ;
wire w_valid_A_pos ;
wire w_valid_B_pos ;
wire w_rden_A_pos ;
wire w_rden_B_pos ;
wire [31:0] w_A_type_len ;
wire [31:0] w_B_type_len ;/***************component*************/
FIFO_8X256 FIFO_8X256_U0_A (.clk (i_clk ), .din (ri_data_A ), .wr_en (ri_valid_A ), .rd_en (r_fifo_A_rden ), .dout (w_fifo_A_dout ), .full (w_fifo_A_full ), .empty (w_fifo_A_empty )
);FIFO_32X16 FIFO_32X16_A (.clk (i_clk ), .din ({ri_type_A,ri_len_A} ), .wr_en (w_valid_A_pos ), .rd_en (w_rden_A_pos ), .dout (w_A_type_len ), .full (),.empty ()
);FIFO_8X256 FIFO_8X256_U0_B (.clk (i_clk ), .din (ri_data_B ), .wr_en (ri_valid_B ), .rd_en (r_fifo_B_rden ), .dout (w_fifo_B_dout ), .full (w_fifo_B_full ), .empty (w_fifo_B_empty )
);FIFO_32X16 FIFO_32X16_B (.clk (i_clk ),.din ({ri_type_B,ri_len_B} ),.wr_en (w_valid_B_pos ),.rd_en (w_rden_B_pos ),.dout (w_B_type_len ),.full (), .empty ()
);/***************assign****************/
assign o_data = ro_data ;
assign o_last = ro_last ;
assign o_valid = ro_valid ;
assign w_rd_en = r_fifo_A_rden | r_fifo_B_rden;
assign o_next_frame_stop = ro_next_frame_stop;
assign w_valid_A_pos = ri_valid_A & !ri_valid_A_1d;
assign w_valid_B_pos = ri_valid_B & !ri_valid_B_1d;
assign w_rden_A_pos = r_fifo_A_rden & !r_fifo_A_rden_1d;
assign w_rden_B_pos = r_fifo_B_rden & !r_fifo_B_rden_1d;
assign o_type = ro_type;
assign o_len = ro_len ;/***************always****************/
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginri_type_A <= 'd0;ri_len_A <= 'd0;ri_data_A <= 'd0;ri_last_A <= 'd0;ri_valid_A <= 'd0;ri_type_B <= 'd0;ri_len_B <= 'd0;ri_data_B <= 'd0;ri_last_B <= 'd0;ri_valid_B <= 'd0;ri_valid_A_1d <= 'd0;ri_valid_B_1d <= 'd0;end else beginri_type_A <= i_type_A ;ri_len_A <= i_len_A ;ri_data_A <= i_data_A ;ri_last_A <= i_last_A ;ri_valid_A <= i_valid_A ;ri_type_B <= i_type_B ;ri_len_B <= i_len_B ;ri_data_B <= i_data_B ;ri_last_B <= i_last_B ;ri_valid_B <= i_valid_B ;ri_valid_A_1d <= ri_valid_A;ri_valid_B_1d <= ri_valid_B;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginr_fifo_A_rden_1d <= 'd0 ;r_fifo_B_rden_1d <= 'd0 ;end else beginr_fifo_A_rden_1d <= r_fifo_A_rden;r_fifo_B_rden_1d <= r_fifo_B_rden;end
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_cnt <= 'd0;else if(r_arbiter)r_cnt <= 'd0;else if(r_cnt == 8)r_cnt <= r_cnt;else if(r_arbiter == 0)r_cnt <= r_cnt + 1;else r_cnt <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_arbiter <= 'd0;else if(ro_last)r_arbiter <= 'd0;else if(!w_fifo_A_empty && r_arbiter == 0 && r_cnt == 8)r_arbiter <= 'd1;else if(!w_fifo_B_empty && r_arbiter == 0 && r_cnt == 8)r_arbiter <= 'd2;else r_arbiter <= r_arbiter;
end always@(posedge i_clk,posedge i_rst)
beginif(i_rst) ro_data <= 'd0;else if(r_arbiter == 1) ro_data <= w_fifo_A_dout;else if(r_arbiter == 2) ro_data <= w_fifo_B_dout;else ro_data <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_valid <= 'd0;else ro_valid <= r_fifo_rd[0];
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_last <= 'd0;else if(!w_rd_en & r_rd_en)ro_last <= 'd1;else ro_last <= 'd0;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_A_rden <= 'd0;else if(r_arbiter == 1 && r_rd_cnt == ri_len_A - 1)r_fifo_A_rden <= 'd0;else if(r_arbiter == 1 && !w_fifo_A_empty && !ro_valid)r_fifo_A_rden <= 'd1;else r_fifo_A_rden <= r_fifo_A_rden;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_B_rden <= 'd0;else if(r_arbiter == 2 && r_rd_cnt == ri_len_B - 1)r_fifo_B_rden <= 'd0;else if(r_arbiter == 2 && !w_fifo_B_empty && !ro_valid)r_fifo_B_rden <= 'd1;else r_fifo_B_rden <= r_fifo_B_rden;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rd_cnt <= 'd0;else if(r_arbiter == 1 && r_rd_cnt == ri_len_A - 1)r_rd_cnt <= 'd0;else if(r_arbiter == 2 && r_rd_cnt == ri_len_B - 1)r_rd_cnt <= 'd0;else if(r_fifo_A_rden | r_fifo_B_rden)r_rd_cnt <= r_rd_cnt + 1;else r_rd_cnt <= r_rd_cnt;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_fifo_rd <= 'd0;else r_fifo_rd <= {r_fifo_rd[0],(r_fifo_A_rden | r_fifo_B_rden)};
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst)r_rd_en <= 'd0;else r_rd_en <= w_rd_en;
end//流控的过程
//1. A的数据来了,但是B还有帧还没发完,先输出stop信号。
//2. stop时,会A先发打断,完成然后把B的帧发了。
//3. A是空的,B也是空的,并且还在stop状态,此时拉低stop信号,正常输出
always@(posedge i_clk,posedge i_rst)
beginif(i_rst)ro_next_frame_stop <= 'd0;else if(ro_next_frame_stop && r_arbiter == 2 && w_fifo_B_empty)ro_next_frame_stop <= 'd0;else if(r_arbiter == 1 && !w_fifo_B_empty)ro_next_frame_stop <= 'd1;else ro_next_frame_stop <= ro_next_frame_stop;
endalways@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginr_rden_A_pos <= 'd0;r_rden_B_pos <= 'd0;end else beginr_rden_A_pos <= w_rden_A_pos ;r_rden_B_pos <= w_rden_B_pos ;end
end
always@(posedge i_clk,posedge i_rst)
beginif(i_rst) beginro_type <= 'd0;ro_len <= 'd0;end else if(r_arbiter == 1 && r_rden_A_pos) beginro_type <= w_A_type_len[31:16];ro_len <= w_A_type_len[15:0];end else if(r_arbiter == 2 && r_rden_B_pos) beginro_type <= w_B_type_len[31:16];ro_len <= w_B_type_len[15:0];end else beginro_type <= ro_type;ro_len <= ro_len ;end
endendmodule
模块收发组合
1 MAC层收发
module Ethernet_MAC#(parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},P_CRC_CHECK = 1
)(input i_clk ,input i_rst ,/*--------info port--------*/ input [47:0] i_target_mac ,input i_target_mac_valid ,input [47:0] i_source_mac ,input i_source_mac_valid ,/*--------data port--------*/input i_udp_valid ,output o_udp_ready ,input [15:0] i_send_type ,input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,output [7 :0] o_ip_data ,output o_ip_last ,output o_ip_valid ,output [7 :0] o_arp_data ,output o_arp_last ,output o_arp_valid ,output [47:0] o_rec_src_mac ,output o_rec_src_valid ,output o_crc_error , output o_crc_valid , /*--------GMII port--------*/output [7 :0] o_GMII_data ,output o_GMII_valid ,input [7 :0] i_GMII_data ,input i_GMII_valid
);(* mark_debug = "true" *)wire [15:0] w_post_type ;
(* mark_debug = "true" *)wire [7 :0] w_post_data ;
(* mark_debug = "true" *)wire w_post_last ;
(* mark_debug = "true" *)wire w_post_valid ;
(* mark_debug = "true" *)wire [15:0] w_crc_post_type ;
(* mark_debug = "true" *)wire [7 :0] w_crc_post_data ;
(* mark_debug = "true" *)wire w_crc_post_last ;
(* mark_debug = "true" *)wire w_crc_post_valid ;
(* mark_debug = "true" *)wire w_crc_error ;
(* mark_debug = "true" *)wire w_crc_valid ; assign o_crc_error = w_crc_error ;
assign o_crc_valid = w_crc_valid ; MAC_tx#(.P_TARTGET_MAC (P_TARTGET_MAC),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_CRC_CHECK (P_CRC_CHECK )
)
MAC_tx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_mac (i_target_mac ),.i_target_mac_valid (i_target_mac_valid),.i_source_mac (i_source_mac ),.i_source_mac_valid (i_source_mac_valid),.i_udp_valid (i_udp_valid ),.o_udp_ready (o_udp_ready ),.i_send_type (i_send_type ),.i_send_len (i_send_len ),.i_send_data (i_send_data ),.i_send_last (i_send_last ),.i_send_valid (i_send_valid ),.o_GMII_data (o_GMII_data ),.o_GMII_valid (o_GMII_valid )
);mac_arp_ip_mux mac_arp_ip_mux_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_type (w_crc_post_type ),.i_data (w_crc_post_data ),.i_last (w_crc_post_last ),.i_valid (w_crc_post_valid ),.o_ip_data (o_ip_data ),.o_ip_last (o_ip_last ),.o_ip_valid (o_ip_valid ),.o_arp_data (o_arp_data ),.o_arp_last (o_arp_last ),.o_arp_valid (o_arp_valid )
);CRC_Data_Pro CRC_Data_Pro_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_per_type (w_post_type ),.i_per_data (w_post_data ),.i_per_last (w_post_last ),.i_per_valid (w_post_valid ),.i_per_crc_error (w_crc_error ),.i_per_crc_valid (w_crc_valid ),.o_post_type (w_crc_post_type ),.o_post_data (w_crc_post_data ),.o_post_last (w_crc_post_last ),.o_post_valid (w_crc_post_valid )
);MAC_rx#(.P_TARTGET_MAC (P_TARTGET_MAC ),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_CRC_CHECK (P_CRC_CHECK )
)
MAC_rx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_mac (i_target_mac ),.i_target_mac_valid (i_target_mac_valid),.i_source_mac (i_source_mac ),.i_source_mac_valid (i_source_mac_valid),.o_post_type (w_post_type ),.o_post_data (w_post_data ),.o_post_last (w_post_last ),.o_post_valid (w_post_valid ),.o_rec_src_mac (o_rec_src_mac ),.o_rec_src_valid (o_rec_src_valid ),.o_crc_error (w_crc_error ), .o_crc_valid (w_crc_valid ), .i_GMII_data (i_GMII_data ),.i_GMII_valid (i_GMII_valid )
);endmodule
2 ARP层收发
module Ethernet_ARP#(parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(input i_clk ,input i_rst ,input [31:0] i_source_ip ,input i_s_ip_valid ,input [47:0] i_source_mac ,input i_s_mac_valid ,input [31:0] i_target_ip ,input i_target_valid , input [31:0] i_seek_ip ,input i_seek_valid ,output [47:0] o_rec_target_mac ,output o_rec_target_valid ,output [7 :0] o_mac_data ,output o_mac_last ,output o_mac_valid ,input [7 :0] i_mac_data ,input i_mac_last ,input i_mac_valid
);wire w_trig_reply ;
wire [47:0] w_rec_target_mac ;
wire [31:0] w_target_ip ;
wire w_rec_target_valid ;
wire [31:0] w_arp_seek_ip ;
wire w_arp_seek_valid ;ARP_tx#(.P_TARGET_IP (P_TARGET_IP ),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_SOURCE_IP (P_SOURCE_IP )
)
ARP_tx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_ip (i_target_ip ),.i_target_valid (i_target_valid ),.i_source_mac (i_source_mac ),.i_s_mac_valid (i_s_mac_valid ),.i_source_ip (i_source_ip ),.i_s_ip_valid (i_s_ip_valid ),.i_reply_mac (w_rec_target_mac ),.i_trig_reply (w_trig_reply ),.i_active_send (0),.o_seek_ip (w_arp_seek_ip ),.o_seek_valid (w_arp_seek_valid),.o_mac_data (o_mac_data ),.o_mac_last (o_mac_last ),.o_mac_valid (o_mac_valid )
);ARP_Table ARP_Table_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_seek_ip (i_seek_ip ),.i_seek_valid (i_seek_valid ),.i_updata_ip (w_target_ip ),.i_updata_mac (w_rec_target_mac ),.i_updata_valid (w_rec_target_valid ),.o_active_mac (o_rec_target_mac ),.o_active_valid (o_rec_target_valid )
); ARP_rx#(.P_TARGET_IP (P_TARGET_IP ),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_SOURCE_IP (P_SOURCE_IP )
)
ARP_rx_U0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_source_ip (i_source_ip ),.i_s_ip_valid (i_s_ip_valid ),.o_target_mac (w_rec_target_mac ),.o_target_ip (w_target_ip ),.o_target_valid (w_rec_target_valid ),.o_tirg_reply (w_trig_reply ),.i_mac_data (i_mac_data ),.i_mac_last (i_mac_last ),.i_mac_valid (i_mac_valid )
);endmodule
2 IP层收发
module Ethernet_IP#(parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(input i_clk ,input i_rst ,/*--------info port --------*/input [31:0] i_target_ip ,input i_target_valid ,input [31:0] i_source_ip ,input i_source_valid ,/*--------data port--------*/input [7 :0] i_send_type ,input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,output [15:0] o_udp_len ,output [7 :0] o_udp_data ,output o_udp_last ,output o_udp_valid ,output [15:0] o_icmp_len ,output [7 :0] o_icmp_data ,output o_icmp_last ,output o_icmp_valid ,output [31:0] o_source_ip ,output o_source_ip_valid ,/*--------arp port--------*/output [31:0] o_arp_seek_ip ,output o_arp_seek_valid ,/*--------mac port--------*/output [15:0] o_mac_type ,output [15:0] o_mac_len ,output [7 :0] o_mac_data ,output o_mac_last ,output o_mac_valid ,input [7 :0] i_mac_data ,input i_mac_last ,input i_mac_valid );IP_tx#(.P_ST_TARGET_IP (P_ST_TARGET_IP ),.P_ST_SOURCE_IP (P_ST_SOURCE_IP )
)
IP_tx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_ip (i_target_ip ),.i_target_valid (i_target_valid ),.i_source_ip (i_source_ip ),.i_source_valid (i_source_valid ),.i_send_type (i_send_type ),.i_send_len (i_send_len ),.i_send_data (i_send_data ),.i_send_last (i_send_last ),.i_send_valid (i_send_valid ),.o_arp_seek_ip (o_arp_seek_ip ),.o_arp_seek_valid (o_arp_seek_valid ),.o_mac_type (o_mac_type ),.o_mac_len (o_mac_len ),.o_mac_data (o_mac_data ),.o_mac_last (o_mac_last ),.o_mac_valid (o_mac_valid )
);IP_rx#(.P_ST_TARGET_IP (P_ST_TARGET_IP ), .P_ST_SOURCE_IP (P_ST_SOURCE_IP )
)
IP_rx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_ip (i_target_ip ),.i_target_valid (i_target_valid ),.i_source_ip (i_source_ip ),.i_source_valid (i_source_valid ),.o_udp_len (o_udp_len ),.o_udp_data (o_udp_data ),.o_udp_last (o_udp_last ),.o_udp_valid (o_udp_valid ),.o_icmp_len (o_icmp_len ),.o_icmp_data (o_icmp_data ),.o_icmp_last (o_icmp_last ),.o_icmp_valid (o_icmp_valid ),.o_source_ip (o_source_ip ),.o_source_ip_valid (o_source_ip_valid ),.i_mac_data (i_mac_data ),.i_mac_last (i_mac_last ),.i_mac_valid (i_mac_valid ) );endmodule
3 ICMP层收发
module Ethernet_ICMP(input i_clk ,input i_rst ,input [15:0] i_icmp_len ,input [7 :0] i_icmp_data ,input i_icmp_last ,input i_icmp_valid , output [15:0] o_icmp_len ,output [7 :0] o_icmp_data ,output o_icmp_last ,output o_icmp_valid
);wire w_trig_reply ;
wire [31:0] w_trig_seq ; ICMP_tx ICMP_tx_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_trig_reply (w_trig_reply ),.i_trig_seq (w_trig_seq ),.o_icmp_len (o_icmp_len ),.o_icmp_data (o_icmp_data ),.o_icmp_last (o_icmp_last ),.o_icmp_valid (o_icmp_valid )
);ICMP_rx ICMP_rx_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_icmp_len (i_icmp_len ),.i_icmp_data (i_icmp_data ),.i_icmp_last (i_icmp_last ),.i_icmp_valid (i_icmp_valid ), .o_trig_reply (w_trig_reply ),.o_trig_seq (w_trig_seq )
);endmodule
3 UDP层收发
module Ethernet_UDP#(parameter P_TARGET_PORT = 16'h8080 ,P_SOURCE_PORT = 16'h8080
)(input i_clk ,input i_rst ,/*--------info port-------*/input [15:0] i_target_port ,input i_target_valid ,input [15:0] i_source_port ,input i_source_valid ,/*--------data port--------*/input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,output [15:0] o_udp_len ,output [7 :0] o_udp_data ,output o_udp_last ,output o_udp_valid ,/*--------ip port--------*/output [15:0] o_ip_len ,output [7 :0] o_ip_data ,output o_ip_last ,output o_ip_valid ,input [15:0] i_ip_len ,input [7 :0] i_ip_data ,input i_ip_last ,input i_ip_valid
);UDP_tx#(.P_TARGET_PORT (P_TARGET_PORT),.P_SOURCE_PORT (P_SOURCE_PORT)
)
UDP_tx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_port (i_target_port ),.i_target_valid (i_target_valid ),.i_source_port (i_source_port ),.i_source_valid (i_source_valid ),.i_send_len (i_send_len ),.i_send_data (i_send_data ),.i_send_last (i_send_last ),.i_send_valid (i_send_valid ),.o_ip_len (o_ip_len ),.o_ip_data (o_ip_data ),.o_ip_last (o_ip_last ),.o_ip_valid (o_ip_valid )
);UDP_rx#(.P_TARGET_PORT (P_TARGET_PORT),.P_SOURCE_PORT (P_SOURCE_PORT)
)
UDP_rx_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_port (i_target_port ),.i_target_valid (i_target_valid ),.i_source_port (i_source_port ),.i_source_valid (i_source_valid ),.o_udp_len (o_udp_len ),.o_udp_data (o_udp_data ),.o_udp_last (o_udp_last ),.o_udp_valid (o_udp_valid ),.i_ip_len (i_ip_len ),.i_ip_data (i_ip_data ),.i_ip_last (i_ip_last ),.i_ip_valid (i_ip_valid )
);
endmodule
UDP协议栈
module UDP_Stack_Module#(parameter P_TARGET_PORT = 16'h8080 ,P_SOURCE_PORT = 16'h8080 ,P_TARGET_IP = {8'd192,8'd168,8'd1,8'd0} ,P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1} ,P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00} ,P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00} ,P_CRC_CHEKC = 1
)(input i_clk ,input i_rst ,/*--------info port-------*/ input [15:0] i_target_port ,input i_target_port_valid ,input [15:0] i_source_port ,input i_source_port_valid ,input [31:0] i_target_ip ,input i_target_ip_valid ,input [31:0] i_source_ip ,input i_source_ip_valid ,input [47:0] i_target_mac ,input i_target_mac_valid ,input [47:0] i_source_mac ,input i_source_mac_valid ,/*--------data port--------*/input [15:0] i_send_len ,input [7 :0] i_send_data ,input i_send_last ,input i_send_valid ,output o_send_ready ,output [15:0] o_rec_len ,output [7 :0] o_rec_data ,output o_rec_last ,output o_rec_valid ,output [31:0] o_source_ip ,output o_source_ip_valid ,output [47:0] o_rec_src_mac ,output o_rec_src_valid ,output o_crc_error , output o_crc_valid , /*--------GMII port--------*/output [7 :0] o_GMII_data ,output o_GMII_valid ,input [7 :0] i_GMII_data ,input i_GMII_valid
);wire w_udp_ready ;
wire w_ip_next_frame_stop ;
wire w_udp_next_frame_stop ;
wire [15:0] w_udp2ip_len ;
wire [7 :0] w_udp2ip_data ;
wire w_udp2ip_last ;
wire w_udp2ip_valid ;
(* mark_debug = "true" *)wire [15:0] w_ip2udp_len ;
(* mark_debug = "true" *)wire [7 :0] w_ip2udp_data ;
(* mark_debug = "true" *)wire w_ip2udp_last ;
(* mark_debug = "true" *)wire w_ip2udp_valid ; wire [15:0] w_icmp_rec_len ;
wire [7 :0] w_icmp_rec_data ;
wire w_icmp_rec_last ;
wire w_icmp_rec_valid ;
wire [15:0] w_icmp_send_len ;
wire [7 :0] w_icmp_send_data ;
wire w_icmp_send_last ;
wire w_icmp_send_valid ;wire [15:0] w_icmp_udp_type ;
wire [15:0] w_icmp_udp_len ;
wire [7 :0] w_icmp_udp_data ;
wire w_icmp_udp_last ;
wire w_icmp_udp_valid ;wire [47:0] w_arp_rec_target_mac ;
wire w_arp_rec_target_valid ;wire [7 :0] w_arp2mac_data ;
wire w_arp2mac_last ;
wire w_arp2mac_valid ;
wire [7 :0] w_mac2arp_data ;
wire w_mac2arp_last ;
wire w_mac2arp_valid ;wire [15:0] w_ip2mac_type ;
wire [15:0] w_ip2mac_len ;
wire [7 :0] w_ip2mac_data ;
wire w_ip2mac_last ;
wire w_ip2mac_valid ;
(* mark_debug = "true" *)wire [7 :0] w_mac2ip_data ;
(* mark_debug = "true" *)wire w_mac2ip_last ;
(* mark_debug = "true" *)wire w_mac2ip_valid ;wire [15:0] w_ip_icmp_2_mac_type ;
wire [15:0] w_ip_icmp_2_mac_len ;
wire [7 :0] w_ip_icmp_2_mac_data ;
wire w_ip_icmp_2_mac_last ;
wire w_ip_icmp_2_mac_valid ;wire [31:0] w_arp_seek_ip ;
wire w_arp_seek_valid ;wire w_send_ready ;
reg ro_send_ready ;
reg [7 :0] r_ready_cnt ;
reg ri_send_valid ;assign o_send_ready = w_send_ready;
assign w_send_ready = ~w_ip_next_frame_stop & ~w_udp_next_frame_stop & w_udp_ready;Ethernet_UDP#(.P_TARGET_PORT (P_TARGET_PORT ),.P_SOURCE_PORT (P_SOURCE_PORT )
)
Ethernet_UDP_u0
( .i_clk (i_clk ),.i_rst (i_rst ),.i_target_port (i_target_port ),.i_target_valid (i_target_port_valid),.i_source_port (i_source_port ),.i_source_valid (i_source_port_valid),.i_send_len (i_send_len ),.i_send_data (i_send_data ),.i_send_last (i_send_last ),.i_send_valid (i_send_valid ),.o_udp_len (o_rec_len ),.o_udp_data (o_rec_data ),.o_udp_last (o_rec_last ),.o_udp_valid (o_rec_valid ),.o_ip_len (w_udp2ip_len ),.o_ip_data (w_udp2ip_data ),.o_ip_last (w_udp2ip_last ),.o_ip_valid (w_udp2ip_valid ),.i_ip_len (w_ip2udp_len ),.i_ip_data (w_ip2udp_data ),.i_ip_last (w_ip2udp_last ),.i_ip_valid (w_ip2udp_valid )
);Ethernet_ICMP Ethernet_ICMP_u0(.i_clk (i_clk ),.i_rst (i_rst ),.i_icmp_len (w_icmp_rec_len ),.i_icmp_data (w_icmp_rec_data ),.i_icmp_last (w_icmp_rec_last ),.i_icmp_valid (w_icmp_rec_valid ), .o_icmp_len (w_icmp_send_len ),.o_icmp_data (w_icmp_send_data ),.o_icmp_last (w_icmp_send_last ),.o_icmp_valid (w_icmp_send_valid )
);Data_2to1 Data_2to1_ICMP_UDP(.i_clk (i_clk ),.i_rst (i_rst ),.i_type_A (17 ),.i_len_A (w_udp2ip_len ),.i_data_A (w_udp2ip_data ),.i_last_A (w_udp2ip_last ),.i_valid_A (w_udp2ip_valid ),.o_next_frame_stop (w_udp_next_frame_stop),.i_type_B (1 ),.i_len_B (w_icmp_send_len ),.i_data_B (w_icmp_send_data ),.i_last_B (w_icmp_send_last ),.i_valid_B (w_icmp_send_valid ),.o_type (w_icmp_udp_type ),.o_len (w_icmp_udp_len ),.o_data (w_icmp_udp_data ),.o_last (w_icmp_udp_last ),.o_valid (w_icmp_udp_valid )
);Ethernet_ARP#(.P_TARGET_IP (P_TARGET_IP ),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_SOURCE_IP (P_SOURCE_IP )
)
Ethernet_ARP_u0
( .i_clk (i_clk ),.i_rst (i_rst ),.i_source_ip (i_source_ip ),.i_s_ip_valid (i_source_ip_valid ),.i_source_mac (i_source_mac ),.i_s_mac_valid (i_source_mac_valid ),.i_target_ip (i_target_ip ),.i_target_valid (i_target_ip_valid ), .i_seek_ip (w_arp_seek_ip ),.i_seek_valid (w_arp_seek_valid ),.o_rec_target_mac (w_arp_rec_target_mac ),.o_rec_target_valid (w_arp_rec_target_valid ),.o_mac_data (w_arp2mac_data ),.o_mac_last (w_arp2mac_last ),.o_mac_valid (w_arp2mac_valid ),.i_mac_data (w_mac2arp_data ),.i_mac_last (w_mac2arp_last ),.i_mac_valid (w_mac2arp_valid )
);Ethernet_IP#(.P_ST_TARGET_IP (P_TARGET_IP ),.P_ST_SOURCE_IP (P_SOURCE_IP )
)
Ethernet_IP_u0
(.i_clk (i_clk ),.i_rst (i_rst ),.i_target_ip (i_target_ip ),.i_target_valid (i_target_ip_valid ),.i_source_ip (i_source_ip ),.i_source_valid (i_source_ip_valid ),.i_send_type (w_icmp_udp_type[7 :0] ),.i_send_len (w_icmp_udp_len ),.i_send_data (w_icmp_udp_data ),.i_send_last (w_icmp_udp_last ),.i_send_valid (w_icmp_udp_valid ),.o_udp_len (w_ip2udp_len ),.o_udp_data (w_ip2udp_data ),.o_udp_last (w_ip2udp_last ),.o_udp_valid (w_ip2udp_valid ),.o_icmp_len (w_icmp_rec_len ),.o_icmp_data (w_icmp_rec_data ),.o_icmp_last (w_icmp_rec_last ),.o_icmp_valid (w_icmp_rec_valid ),.o_source_ip (o_source_ip ),.o_source_ip_valid (o_source_ip_valid ),.o_arp_seek_ip (w_arp_seek_ip ),.o_arp_seek_valid (w_arp_seek_valid ),.o_mac_type (w_ip2mac_type ),.o_mac_len (w_ip2mac_len ),.o_mac_data (w_ip2mac_data ),.o_mac_last (w_ip2mac_last ),.o_mac_valid (w_ip2mac_valid ),.i_mac_data (w_mac2ip_data ),.i_mac_last (w_mac2ip_last ),.i_mac_valid (w_mac2ip_valid ) );Data_2to1 Data_2to1_ARP_IP(.i_clk (i_clk ),.i_rst (i_rst ),.i_type_A (16'h0806 ),.i_len_A (50 ),.i_data_A (w_arp2mac_data ),.i_last_A (w_arp2mac_last ),.i_valid_A (w_arp2mac_valid ),.o_next_frame_stop (w_ip_next_frame_stop),.i_type_B (w_ip2mac_type ),.i_len_B (w_ip2mac_len ),.i_data_B (w_ip2mac_data ),.i_last_B (w_ip2mac_last ),.i_valid_B (w_ip2mac_valid ),.o_type (w_ip_icmp_2_mac_type ),.o_len (w_ip_icmp_2_mac_len ),.o_data (w_ip_icmp_2_mac_data ),.o_last (w_ip_icmp_2_mac_last ),.o_valid (w_ip_icmp_2_mac_valid )
);Ethernet_MAC#(.P_TARTGET_MAC (P_TARTGET_MAC ),.P_SOURCE_MAC (P_SOURCE_MAC ),.P_CRC_CHECK (P_CRC_CHEKC )
)
Ethernet_MAC_u0
( .i_clk (i_clk ),.i_rst (i_rst ),.i_target_mac (w_arp_rec_target_mac ),.i_target_mac_valid (w_arp_rec_target_valid ),.i_source_mac (i_source_mac ),.i_source_mac_valid (i_source_mac_valid ),.i_udp_valid (i_send_valid ),.o_udp_ready (w_udp_ready ),.i_send_type (w_ip_icmp_2_mac_type ),.i_send_len (w_ip_icmp_2_mac_len ),.i_send_data (w_ip_icmp_2_mac_data ),.i_send_last (w_ip_icmp_2_mac_last ),.i_send_valid (w_ip_icmp_2_mac_valid ),.o_ip_data (w_mac2ip_data ),.o_ip_last (w_mac2ip_last ),.o_ip_valid (w_mac2ip_valid ),.o_arp_data (w_mac2arp_data ),.o_arp_last (w_mac2arp_last ),.o_arp_valid (w_mac2arp_valid ),.o_rec_src_mac (o_rec_src_mac ),.o_rec_src_valid (o_rec_src_valid ),.o_crc_error (o_crc_error ), .o_crc_valid (o_crc_valid ), .o_GMII_data (o_GMII_data ),.o_GMII_valid (o_GMII_valid ),.i_GMII_data (i_GMII_data ),.i_GMII_valid (i_GMII_valid )
);endmodule
有问题可以加企鹅群 658476482 交流