赞
踩
每层都嵌套在上层的数据字段
以太网帧长: 64B~1518B
IP层
ARP层
UDP层
ICMP层
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) begin if(i_rst) begin ri_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 begin ri_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) begin if(i_rst) r_target_mac <= P_TARTGET_MAC; else if(i_target_mac_valid) r_target_mac <= i_target_mac; else r_target_mac <= r_target_mac; end //valid后,输入源mac地址锁存 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_source_mac <= P_SOURCE_MAC ; else if(i_source_mac_valid) r_source_mac <= i_source_mac; else r_source_mac <= r_source_mac; end //GMII接口输入有效 // r_rec_cnt 为 6 停一个周期 接收SFD // 继续 + 1 always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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) begin if(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@(*) begin case(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) r_rec_5d_cnt <= 'd0; else if(ri_GMII_valid_5d) r_rec_5d_cnt <= r_rec_5d_cnt + 1; else r_rec_5d_cnt <= 'd0; end //正常信号的下降沿 有效为0 //延迟5个周期 计数为 21 有效为1 always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) r_crc_en_1d <= 'd0; else r_crc_en_1d <= r_crc_en; end //获取外部输入的CRC结果 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_crc_result <= 'd0; else if(ri_GMII_valid) r_crc_result <= {ri_GMII_data,r_crc_result[31:8]}; else r_crc_result <= r_crc_result; end //CRC使能下降沿 CRC有效 always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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; end endmodule
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) begin if(i_rst) r_target_mac <= P_TARTGET_MAC; else if(i_target_mac_valid) r_target_mac <= i_target_mac; else r_target_mac <= r_target_mac; end //锁存 源mac always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_source_mac <= P_SOURCE_MAC ; else if(i_source_mac_valid) r_source_mac <= i_source_mac; else r_source_mac <= r_source_mac; end //锁存输入的 发送mac帧信息 always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ri_send_type <= 'd0; ri_send_len <= 'd0; ri_send_data <= 'd0; ri_send_valid <= 'd0; end else if(i_send_valid) begin ri_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 begin ri_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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) begin ri_send_valid_1d <= 'd0; r_mac_data_valid_1d <= 'd0; end else begin ri_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) begin if(i_rst) begin ri_udp_valid <= 'd0 ; ro_GMII_valid_1d <= 'd0; end else begin ri_udp_valid <= i_udp_valid; ro_GMII_valid_1d <= ro_GMII_valid; end end always@(posedge i_clk,posedge i_rst) begin if(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; end endmodule
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) begin if(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) begin if(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) begin if(i_rst) begin ri_mac_data <= 'd0; ri_mac_last <= 'd0; ri_mac_valid <= 'd0; ri_mac_data_1d <= 'd0; ri_mac_valid_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; ri_mac_valid_1d <= ri_mac_valid; end end //mac端口有效 ip计数器+1 always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) begin ro_udp_len <= 'd0; ro_icmp_len <= 'd0; end else begin ro_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) begin if(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) begin if(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) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end endmodule
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) begin if(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) begin if(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) begin if(i_rst) begin ri_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) begin ri_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 begin ri_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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) begin ro_mac_type <= 'd0; end else begin ro_mac_type <= 16'h0800; end end //ARP always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ro_arp_seek_ip <= P_ST_TARGET_IP; ro_arp_seek_valid <= 'd0; end else if(ri_send_valid && !ri_send_valid_1d) begin ro_arp_seek_ip <= r_target_ip; ro_arp_seek_valid <= 'd1; end else begin ro_arp_seek_ip <= ro_arp_seek_ip; ro_arp_seek_valid <= 'd0; end end endmodule
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) begin if(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) begin if(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) begin if(i_rst) begin ri_ip_len <= 0; ri_ip_data <= 0; ri_ip_last <= 0; ri_ip_valid <= 0; end else if(i_ip_valid) begin ri_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 begin ri_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) begin if(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) begin if(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) begin if(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) begin if(i_rst) ro_udp_last <= 'd0; else if(r_udp_cnt == ri_ip_len - 2) ro_udp_last <= 'd1; else ro_udp_last <= 'd0; end endmodule
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) begin if(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) begin if(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) begin if(i_rst) begin ri_send_data <= 'd0; ri_send_last <= 'd0; ri_send_valid <= 'd0; end else begin ri_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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(i_rst) r_fifo_udp_empty <= 'd0; else r_fifo_udp_empty <= w_fifo_udp_empty; end //组帧输出 always@(posedge i_clk,posedge i_rst) begin if(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 end endmodule
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) begin if(i_rst) begin ri_icmp_len <= 'd0; ri_icmp_data <= 'd0; ri_icmp_last <= 'd0; ri_icmp_valid <= 'd0; end else begin ri_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) begin if(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) begin if(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) begin if(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) begin if(i_rst) ro_trig_reply <= 'd0; else if(r_icmp_cnt == 7 && r_type == 8) ro_trig_reply <= 'd1; else ro_trig_reply <= 'd0; end endmodule
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) begin if(i_rst) begin ri_trig_reply <= 'd0; ri_trig_seq <= 'd0; end else begin ri_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) begin if(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) begin if(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) begin if(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 end endmodule
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) begin if(i_rst) begin ri_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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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) begin if(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; end endmodule
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) begin if(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) begin if(i_rst) ro_seek_ip <= 'd0; else ro_seek_ip <= ri_source_ip; end //输入目的有效 获得目的ip always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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) begin if(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) begin if(i_rst) begin ri_trig_reply <= 'd0; ri_active_send <= 'd0; end else begin ri_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) begin if(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) begin if(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) begin if(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) begin if(i_rst) ri_reply_mac <= 'd0; else ri_reply_mac <= i_reply_mac; end //组帧输出 always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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) begin if(i_rst) ro_mac_last <= 'd0; else if(r_mac_cnt == P_LEN - 2) ro_mac_last <= 'd1; else ro_mac_last <= 'd0; end endmodule
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) begin if(i_rst) r_st_current <= P_ST_IDLE; else r_st_current <= r_st_next; end always@(*) begin case(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 end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_seek_ip <= 'd0; else if(i_seek_valid) r_seek_ip <= i_seek_ip; else r_seek_ip <= r_seek_ip; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_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 begin r_updata_ip <= r_updata_ip ; r_updata_mac <= r_updata_mac; end end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ri_seek_valid <= 'd0; ri_updata_valid <= 'd0; end else begin ri_seek_valid <= i_seek_valid ; ri_updata_valid <= i_updata_valid; end end always@(posedge i_clk,posedge i_rst) begin if(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) begin r_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) begin r_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) begin r_ram_ip_en <= 'd1; r_ram_ip_we <= 'd1; r_ram_ip_addr <= r_up_data_addr; end else begin r_ram_ip_en <= 'd0; r_ram_ip_we <= 'd0; r_ram_ip_addr <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(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) begin r_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) begin r_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) begin r_ram_mac_en <= 'd1; r_ram_mac_we <= 'd0; r_ram_mac_addr <= r_access_addr; end else begin r_ram_mac_en <= 'd0; r_ram_mac_we <= 'd0; r_ram_mac_addr <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_ram_ip_end_1d <= 'd0; else r_ram_ip_end_1d <= r_ram_ip_end; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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
要双端口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) begin if(i_rst) begin ri_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 begin ri_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 end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_ram_en_A <= 'd0; r_ram_we_A <= 'd0; r_ram_din_A <= 'd0; end else if(ri_per_valid) begin r_ram_en_A <= 'd1; r_ram_we_A <= 'd1; r_ram_din_A <= ri_per_data; end else begin r_ram_en_A <= 'd0; r_ram_we_A <= 'd0; r_ram_din_A <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ri_per_valid_1d <= 'd0; else ri_per_valid_1d <= ri_per_valid; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; // end always@(posedge i_clk,posedge i_rst) begin if(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; else r_data_len <= r_data_len; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; else r_fifo_rd_en <= 'd0; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_rd_en_1d <= 'd0; else r_fifo_rd_en_1d <= r_fifo_rd_en; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_out_run_1d <= 'd0; else r_out_run_1d <= r_out_run; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_ram_en_B <= 'd0; r_ram_we_B <= 'd0; end else if(r_out_run && !r_out_run_1d) begin r_ram_en_B <= 'd1; r_ram_we_B <= 'd0; end else if(r_out_run) begin r_ram_en_B <= 'd1; r_ram_we_B <= 'd0; end else begin r_ram_en_B <= 'd0; r_ram_we_B <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_ram_en_B_1d <= 'd0; else r_ram_en_B_1d <= r_ram_en_B; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_post_valid <= 'd0; else ro_post_valid <= r_ram_en_B_1d; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end endmodule
类型是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) begin if(i_rst) begin ro_ip_data <= 'd0; ro_ip_last <= 'd0; ro_ip_valid <= 'd0; end else if(i_type == 16'h0800) begin ro_ip_data <= i_data ; ro_ip_last <= i_last ; ro_ip_valid <= i_valid; end else begin ro_ip_data <= 'd0; ro_ip_last <= 'd0; ro_ip_valid <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ro_arp_data <= 'd0; ro_arp_last <= 'd0; ro_arp_valid <= 'd0; end else if(i_type == 16'h0806) begin ro_arp_data <= i_data ; ro_arp_last <= i_last ; ro_arp_valid <= i_valid; end else begin ro_arp_data <= 'd0; ro_arp_last <= 'd0; ro_arp_valid <= 'd0; end end endmodule
两个数据流都加个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) begin if(i_rst) begin ri_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 begin ri_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 end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_fifo_A_rden_1d <= 'd0 ; r_fifo_B_rden_1d <= 'd0 ; end else begin r_fifo_A_rden_1d <= r_fifo_A_rden; r_fifo_B_rden_1d <= r_fifo_B_rden; end end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_valid <= 'd0; else ro_valid <= r_fifo_rd[0]; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_last <= 'd0; else if(!w_rd_en & r_rd_en) ro_last <= 'd1; else ro_last <= 'd0; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_rd <= 'd0; else r_fifo_rd <= {r_fifo_rd[0],(r_fifo_A_rden | r_fifo_B_rden)}; end always@(posedge i_clk,posedge i_rst) begin if(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) begin if(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; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_rden_A_pos <= 'd0; r_rden_B_pos <= 'd0; end else begin r_rden_A_pos <= w_rden_A_pos ; r_rden_B_pos <= w_rden_B_pos ; end end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ro_type <= 'd0; ro_len <= 'd0; end else if(r_arbiter == 1 && r_rden_A_pos) begin ro_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) begin ro_type <= w_B_type_len[31:16]; ro_len <= w_B_type_len[15:0]; end else begin ro_type <= ro_type; ro_len <= ro_len ; end end endmodule
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
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
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
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
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
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 交流
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。