以太网ICMP协议(ping指令)——FPGA学习笔记25
--素材来源原子哥
一、IP协议
1、IP简介
IP是Internet Protocol(网际互连协议)的缩写。IP 协议是 TCP/IP 协议簇中的核心协议,它为上层协议提供无状态、无连接、不可靠的服务。IP 协议规定了数据传输时的基本单元和格式 。
IP协议是 OSI 参考模型中网络层的重要成员,与 ICMP协议及 IGMP 协议共同构成OSI 参考模型模型中的网络层 。
2、OSI参考模型
3、IP协议格式
4、IP包详细格式
前 20 个字节和紧跟其后的可选字段是 IP 数据报的首部,前 20 个字节是固定的,后面可选字段是可有可无的,首部的每一行以 32 位(4 个字节)为单位。每个字节传输规则为由比特最高位到最低位的顺序逐一进行发送, 4 字节的 32bit 值按照以下次序传输:首先 7-0bit,其次 15-8 bit,然后 23-16bit,最后是 31-24bit。
版本: 4 位 IP 版本号(Version),这个值设置为二进制的 0100 时表示 IPv4,设置为 0110 时表示 IPv6,目前使用比较多的 IP 协议版本号是 4。
首部长度: 4 位首部长度(IHL, Internet Header Length),表示 IP 首部一共有多少个 32 位(4 个字节) 。在没有可选字段时, IP 首部长度为 20 个字节, 因此首部长度的值为 5。
服务类型: 8 位服务类型(TOS, Type of service),该字段被划分成两个子字段: 3 位优先级字段(现在已经基本忽略掉了)和 4 位 TOS 字段,最后一位固定为 0。服务类型为 0 时表示一般服务。
总长度: 16 位 IP 数据报总长度(Total Length),包括 IP 首部和 IP 数据部分,以字节为单位。我们利用 IP 首部长度和 IP 数据报总长度,就可以知道 IP 数据报中数据内容的起始位置和长度。由于该字段长16bit,所以 IP 数据报最长可达 65535 字节。尽管理论上可以传输长达 65535 字节的 IP 数据报,但实际上还要考虑网络的最大承载能力等因素。
标识字段: 16 位标识(Identification)字段,用来标识主机发送的每一份数据报。通常每发送一份报文它的值就会加 1。
标志字段: 3 位标志(Flags)字段,第 1 位为保留位;第 2 位表示禁止分片(1 表示不分片 0:允许分片);第 3 位标识更多分片(除了数据报的最后一个分片外,其它分片都为 1)。
片偏移: 13 位片偏移(Fragment Offset),在接收方进行数据报重组时用来标识分片的顺序。
生存时间: 8 位生存时间字段, TTL(Time To Live)域防止丢失的数据包在无休止的传播,一般被设置为 64 或者 128。
协议: 8 位协议(Protocol)类型,表示此数据报所携带上层数据使用的协议类型, ICMP 为 1, TCP 为6, UDP 为 17。
首部校验和: 16 位首部校验和(Header Checksum),该字段只校验数据报的首部,不包含数据部分;校验 IP 数据报头部是否被破坏、篡改和丢失等。
源 IP 地址: 32 位源 IP 地址(Source Address),即发送端的 IP 地址, 如 192.168.1.123。
目的 IP 地址: 32 位目的 IP 地址(Destination Address),即接收端的 IP 地址, 如 192.168.1.102。
可选字段: 是数据报中的一个可变长度的可选信息,选项字段以 32bit 为界,不足时插入值为 0 的填充字节,保证 IP 首部始终是 32bit 的整数倍(一般为0)
5、IP首部校验和
0x4500 + 0x003C + 0x0000 + 0x4000 + 0x4001 + 0x0000(计算时强制置0) + 0xc0a8
+ 0x010a + 0xc0a8 + 0x0166 = 0x248FD
进位拿出来与低位相加。
0x0002 + 0x48FD = 0x000048FF(此种情况并未出现进位)
0x0000+ 0x48FF= 0x48FF(此种情况并未出现进位)
check_sum = ~0x48FF(按位取反)= 0xb700
对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位)
二、ICMP协议
1、简介
ICMP是Internet Control Message Protocol的缩写,即互联网控制消息协议。它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,使网络管理者可以对所发生的问题作出诊断,然后采取适当的措施解决问题。
2、ICMP协议包格式
(1)查询报文
常用类型有:类型 0,代码 0:表示回显应答(ping 应答)。 类型 8,代码 0:表示回显请求(ping 请求)。 类型 11,代码 0:超时; 类型 3,代码 0:网络不可达; 类型 3,代码 1:主机不可达; 类型 5,代码 0:重定向。
代码(code):占用了 8 bit 位,根据 ICMP 差错报文的类型,进一步分析错误的原因,代码值不同对应的错误也不同,例如:类型为 11 且代码为 0,表示数据传输过程中超时了,超时的具体原因是 TTL 值为 0,数据报被丢弃。
校验和(checksum):占用了 16 bit 位, 校验的方法同上述 IP 首部校验和的方法一致。 数据发送到目的地后需要对 ICMP 数据报文做一个校验,用于检查数据报文是否有错误。
标识符(Identifier):占用了 16 bit 位,对于每一个发送的数据报进行标识。
序列号(Sequence number):占用了 16 bit 位,对于发送的每一个数据报文进行编号,比如:发送的第一个数据报序列号为 1,第二个序列号为 2。
数据(Data):要发送的 ICMP 数据。
3、常用ICMP报文类型
三、程序设计
目标:电脑ping开发板实现开发板应答
1、整体框图:
2、ICMP编写:
(1)icmp_rx
前导码+帧起始界定符->以太网帧头->IP 首部->ICMP 首->ICMP 数据(有效数据) ->接收结束
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/12/26 15:41:37
// Design Name:
// Module Name: icmp_rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module icmp_rx(input clk ,input rst_n ,input gmii_rx_dv ,input [ 7:0] gmii_rxd ,output reg rec_pkt_done , //以太网单包数据接收完成信号output reg rec_en , //以太网接收数据使能信号 ---fifo_enoutput reg [ 7:0] rec_data , //以太网接收数据 ---fifo_dataoutput reg [15:0] rec_byte_num , //以太网接收有效字数 bitoutput reg [15:0] icmp_id , //ICMP标识符output reg [15:0] icmp_seq , //ICMP序列号output reg [31:0] reply_checksum //接收数据校验
);//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48'h00_11_22_33_44_55;
//开发板IP地址 192.168.1.10
parameter BOARD_IP = {8'd192,8'd168,8'd1,8'd10}; //状态机状态定义
localparam st_idle = 7'b000_0001 ; //初始状态,等待接收前导码
localparam st_preamble = 7'b000_0010 ; //接收前导码状态
localparam st_eth_head = 7'b000_0100 ; //接收以太网帧头
localparam st_ip_head = 7'b000_1000 ; //接收IP首部
localparam st_icmp_head = 7'b001_0000 ; //接收ICMP首部
localparam st_rx_data = 7'b010_0000 ; //接收有效数据
localparam st_rx_end = 7'b100_0000 ; //接收结束//以太网类型定义
localparam ETH_TYPE = 16'h0800 ; //以太网协议类型 IP协议
localparam ICMP_TYPE = 8'd1 ; //ICMP协议类型//ICMP报文类型:回显请求
localparam ECHO_REQUEST = 8'h08 ; reg [6 :0] cur_state ; //当前状态
reg [6 :0] next_state ; //下一状态
reg skip_en ; //状态跳转信号
reg error_en ; //状态错误信号
reg [4 :0] cnt ; //状态数据计数器
reg [47:0] des_mac ; //目的MAC
reg [15:0] eth_type ; //以太网类型
reg [5 :0] ip_head_byte_num ; //IP首部长度
reg [15:0] total_length ; //接收数据字节长度
reg [15:0] icmp_data_length ; //有效数据长度
reg [31:0] des_ip ; //目的IP
reg [7 :0] icmp_type ; //ICMP报文类型:用于标识错误类型的差错报文或者查询类型的报告报文
reg [7 :0] icmp_code ; //ICMP报文代码:根据ICMP差错报文的类型,进一步分析错误的原因,代码值不同对应的错误也不同//例如:类型为11且代码为0,表示数据传输过程中超时了,超时的具体原因是TTL值为0,数据报被丢弃。
reg [15:0] icmp_checksum ; //接收校验和:数据发送到目的地后需要对ICMP数据报文做一个校验,用于检查数据报文是否有错误
reg [1 :0] rec_en_cnt ; //8bit转32bit计数器
reg [15:0] icmp_rx_cnt ; //接收数据计数
reg [7 :0] icmp_rx_data_d0 ;
reg [31:0] reply_checksum_add ;//(三段式状态机)同步时序描述状态转移
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincur_state <= st_idle ;end else begincur_state <= next_state ;end
end//
always @(*) beginif (!rst_n) beginnext_state = st_idle ;end else begincase (cur_state)st_idle :begin //等待接收前导码if (skip_en) beginnext_state = st_preamble ;end else beginnext_state = st_idle ; endendst_preamble :begin //接收前导码if (skip_en ) beginnext_state = st_eth_head ;end else if(error_en)beginnext_state = st_rx_end ;endelse beginnext_state = st_preamble ;endendst_eth_head :begin //接收以太网帧头if (skip_en ) beginnext_state = st_ip_head ;end else if(error_en)beginnext_state = st_rx_end ;endelse beginnext_state = st_eth_head ;endendst_ip_head :begin //接收IP首部if (skip_en ) beginnext_state = st_icmp_head;end else if(error_en)beginnext_state = st_rx_end ;endelse beginnext_state = st_ip_head ;endendst_icmp_head :begin //接收ICMP首部if (skip_en ) beginnext_state = st_rx_data ;end else if(error_en)beginnext_state = st_rx_end ;endelse beginnext_state = st_icmp_head;endendst_rx_data :begin //接收有效数据if (skip_en ) beginnext_state = st_rx_end ;end else beginnext_state = st_rx_data ;endendst_rx_end :begin //接收结束if (skip_en ) beginnext_state = st_idle ;end else beginnext_state = st_rx_end ;endenddefault: next_state = st_idle ;endcaseend
end//
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginskip_en <= 1'b0 ;error_en <= 1'b0 ;cnt <= 5'd0 ;des_mac <= 48'd0 ;eth_type <= 16'd0 ;des_ip <= 32'd0 ;ip_head_byte_num <= 6'd0 ;total_length <= 16'd0 ;icmp_type <= 8'd0 ;icmp_code <= 8'd0 ;icmp_checksum <= 16'd0 ;icmp_id <= 16'd0 ;icmp_seq <= 16'd0 ;icmp_rx_data_d0 <= 8'd0 ;reply_checksum <= 32'd0 ; //累加reply_checksum_add <= 32'd0 ;icmp_rx_cnt <= 16'd0 ;icmp_data_length <= 16'd0 ;rec_en_cnt <= 2'd0 ;rec_en <= 1'b0 ;rec_data <= 32'd0 ;rec_pkt_done <= 1'b0 ;rec_byte_num <= 16'd0 ;end else beginskip_en <= 1'b0;error_en <= 1'b0;rec_pkt_done <= 1'b0; //以太网单包数据接收完成信号case (cur_state)st_idle :begin //等待接收前导码if ((gmii_rx_dv == 1'b1) && (gmii_rxd == 8'h55)) beginskip_en <= 1'b1;end else beginskip_en <= 1'b0;endendst_preamble :begin //接收前导码if (gmii_rx_dv == 1'b1) begincnt <= cnt + 1'b1;if ((cnt < 5'd6 ) && (gmii_rxd != 8'h55)) beginerror_en <= 1'b1;endelse if (cnt == 5'd6) begincnt <= 5'd0;if (gmii_rxd == 8'hd5) beginskip_en <= 1'b1;error_en <= 1'b0;end else beginskip_en <= 1'b0;error_en <= 1'b1;endend else beginskip_en <= skip_en ;error_en <= error_en;endend else beginskip_en <= 1'b0;error_en <= 1'b1;endendst_eth_head :begin //接收以太网帧头if (gmii_rx_dv == 1'b1) begincnt <= cnt + 1'b1;if (cnt < 5'd6) begindes_mac <= {des_mac[39:0],gmii_rxd};end else if( cnt == 5'd12)begineth_type[15:8] <= gmii_rxd;endelse if (cnt == 5'd13) begineth_type[ 7:0] <= gmii_rxd;cnt <= 5'd0;if (((des_mac == BOARD_MAC)||(des_mac == 48'hff_ff_ff_ff_ff_ff))&&(eth_type[15:8] == ETH_TYPE[15:8])&&(gmii_rxd == ETH_TYPE[7:0])) beginskip_en <= 1'b1;error_en <= 1'b0;end else beginskip_en <= 1'b0;error_en <= 1'b1;endend else beginskip_en <= skip_en ;error_en <= error_en ;endend else beginskip_en <= 1'b0;error_en <= 1'b1;endendst_ip_head :begin //接收IP首部if (gmii_rx_dv == 1'b1) begincnt <= cnt + 1'b1;if (cnt == 5'd0) beginip_head_byte_num <= {gmii_rxd[3:0],2'd0};end else if (cnt == 5'd2) begintotal_length[15:8] <= gmii_rxd ;endelse if (cnt == 5'd3) begintotal_length[7:0] <= gmii_rxd ;endelse if (cnt == 5'd4) begin //有效数据字节长度,(IP首部20个字节,icmp首部8个字节,所以减去28)icmp_data_length <= total_length - 16'd28; endelse if (cnt == 5'd9) beginif (gmii_rxd != ICMP_TYPE) begin //如果当前接收的数据不是ICMP协议,停止解析数据 error_en <= 1'b1 ;skip_en <= 1'b0 ;cnt <= 5'd0 ;end else beginerror_en <= 1'b0 ;skip_en <= skip_en ;endend else if ((cnt >= 5'd16)&&(cnt <= 5'd18)) begindes_ip <= {des_ip[23:0],gmii_rxd};endelse if (cnt == 5'd19) begindes_ip <= {des_ip[23:0],gmii_rxd};if ({des_ip[23:0],gmii_rxd} == BOARD_IP) beginskip_en <= 1'b1;error_en <= 1'b0;cnt <= 5'd0;end else beginskip_en <= 1'b0;error_en <= 1'b1;cnt <= 5'd0;endend else beginskip_en <= skip_en ;error_en <= error_en ;endend else beginskip_en <= 1'b0;error_en <= 1'b1;end endst_icmp_head :begin //接收ICMP首部if (gmii_rx_dv == 1'b1) begincnt <= cnt + 1 'b1;if (cnt == 5'd0) beginicmp_type <= gmii_rxd ;end else if (cnt == 5'd1) beginicmp_code <= gmii_rxd ;endelse if ((cnt == 5'd2)||(cnt == 5'd3)) beginicmp_checksum <= {icmp_checksum[7:0],gmii_rxd} ;endelse if ((cnt == 5'd4)||(cnt == 5'd5)) beginicmp_id <= {icmp_id[7:0],gmii_rxd} ;endelse if (cnt == 5'd6) beginicmp_seq[15:8] <= gmii_rxd ;end else if (cnt == 5'd7) beginicmp_seq[7:0] <= gmii_rxd ;if (icmp_type == ECHO_REQUEST) beginskip_en <= 1'b1;error_en <= 1'b0;cnt <= 5'd0;end else beginskip_en <= 1'b0;error_en <= 1'b1; cnt <= 5'd0;endendelse beginskip_en <= skip_en ;error_en <= error_en ;cnt <= cnt ;endend else beginskip_en <= 1'b0;error_en <= 1'b1; cnt <= 5'd0;endendst_rx_data :begin //接收有效数据if (gmii_rx_dv == 1'b1) beginrec_en_cnt <= rec_en_cnt + 1'b1 ;icmp_rx_cnt <= icmp_rx_cnt + 1'b1 ;rec_data <= gmii_rxd ; //以太网接收数据rec_en <= 1'b1 ;if (icmp_rx_cnt == icmp_data_length - 1'b1) beginicmp_rx_data_d0 <= 8'd0;if (icmp_data_length[0] == 1'b1) begin //奇数reply_checksum_add <= {8'h0,gmii_rxd} + reply_checksum_add ;end else begin //偶数reply_checksum_add <= {icmp_rx_data_d0,gmii_rxd} + reply_checksum_add ;endend else if (icmp_rx_cnt < icmp_data_length) beginicmp_rx_data_d0 <= gmii_rxd ;icmp_rx_cnt <= icmp_rx_cnt + 1'b1 ;if (icmp_rx_cnt[0] == 1'b1) beginreply_checksum_add <= {icmp_rx_data_d0,gmii_rxd} + reply_checksum_add ;end else beginreply_checksum_add <= reply_checksum_add ;endendelse beginerror_en <= 1'b1;endif (icmp_rx_cnt == icmp_data_length - 1'b1) beginskip_en <= 1'b1;error_en <= 1'b0;rec_en_cnt <= 2'd0;rec_pkt_done <= 1'b1;rec_byte_num <= icmp_data_length ; end else beginskip_en <= 1'b0;error_en <= 1'b1;rec_en_cnt <= 2'd0;rec_pkt_done <= 1'b1;rec_byte_num <= icmp_data_length ; endend else beginerror_en <= 1'b1;endendst_rx_end :begin //接收结束rec_en <= 1'b0;if ((gmii_rx_dv == 1'b0)&&(skip_en == 1'b0)) beginreply_checksum <= reply_checksum_add ;skip_en <= 1'b1 ;reply_checksum_add <= 32'd0 ;end else beginreply_checksum <= reply_checksum ;skip_en <= skip_en ;reply_checksum_add <= reply_checksum_add ;endenddefault: error_en = 1'b1 ; endcase end
endendmodule
(2)icmp_tx
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/12/28 20:19:55
// Design Name:
// Module Name: icmp_tx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module icmp_tx( input clk , //时钟信号input rst_n , //复位信号,低电平有效input [31:0] reply_checksum , //ICMP数据部分校验和input [15:0] icmp_id , //ICMP标识符input [15:0] icmp_seq , //ICMP序列号input tx_start_en , //以太网开始发送信号input [ 7:0] tx_data , //以太网待发送数据input [15:0] tx_byte_num , //以太网发送的有效字节数input [47:0] des_mac , //发送的目标MAC地址input [31:0] des_ip , //发送的目标IP地址input [31:0] crc_data , //CRC校验数据input [7:0] crc_next , //CRC下次校验完成数据output reg tx_done , //以太网发送完成信号output reg tx_req , //读数据请求信号output reg gmii_tx_en , //GMII输出数据有效信号output reg [7:0] gmii_txd , //GMII输出数据output reg crc_en , //CRC开始校验使能output reg crc_clr //CRC数据复位信号
);//parameter define
//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48'h00_11_22_33_44_55;
//开发板IP地址 192.168.1.10
parameter BOARD_IP = {8'd192,8'd168,8'd1,8'd10};
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter DES_MAC = 48'hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.102
parameter DES_IP = {8'd192,8'd168,8'd1,8'd102};//状态机状态定义
localparam st_idle = 8'b0000_0001 ; //初始状态,等待开始发送信号
localparam st_check_sum = 8'b0000_0010 ; //IP首部校验和
localparam st_check_icmp = 8'b0000_0100 ; //ICMP首部+数据校验
localparam st_preamble = 8'b0000_1000 ; //发送前导码+帧起始界定符
localparam st_eth_head = 8'b0001_0000 ; //发送以太网帧头
localparam st_ip_head = 8'b0010_0000 ; //发送IP首部+ICMP首部
localparam st_tx_data = 8'b0100_0000 ; //发送数据
localparam st_crc = 8'b1000_0000 ; //发送CRC校验值//以太网类型定义
localparam ETH_TYPE = 16'h0800 ; //以太网协议类型 IP协议//以太网数据最小46个字节,IP首部20个字节+ICMP首部8个字节
//所以数据至少46-20-8=18个字节
localparam MIN_DATA_NUM = 16'd18 ;//parameter define
//ICMP报文类型:回显应答
parameter ECHO_REPLY = 8'h00 ;reg [7:0] cur_state ;//当前状态
reg [7:0] next_state ;//下一状态
reg start_en_d0 ;//
reg start_en_d1 ;//
reg start_en_d2 ;//
reg [15:0] tx_data_num ;//发送数据长度
reg [15:0] total_num ;//总长度
reg trig_tx_en ;//使能触发信号
reg skip_en ;//状态跳转信号
reg [4:0] cnt ;//发送数据计数器
reg [31:0] check_buffer ;//IP首部校验和
reg [31:0] check_buffer_icmp ;//ICMP首部校验和
reg [7:0] preamble [7:0] ;//前导码
reg [7:0] eth_head [13:0] ;//以太网首部
reg [31:0] ip_head [6:0] ;//IP首部 + ICMP首部
reg [1:0] tx_bit_sel ;//bit计数器
reg tx_done_t ;//发送完成标志
reg [15:0] data_cnt ;//发送数据计数器
reg [4:0] real_add_cnt ;//多发送数据计数器wire [15:0] real_tx_data_num ; //发送有效长度
wire pos_start_en ; //触发信号上升沿assign pos_start_en = (~start_en_d2) & start_en_d1;
assign real_tx_data_num = (tx_data_num >= MIN_DATA_NUM) ? tx_data_num : MIN_DATA_NUM;//采tx_start_en的上升沿
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginstart_en_d0 <= 1'b0;start_en_d1 <= 1'b0;start_en_d2 <= 1'b0;end else beginstart_en_d0 <= tx_start_en;start_en_d1 <= start_en_d0;start_en_d2 <= start_en_d1;end
end //寄存数据有效字节
always @(posedge clk or negedge rst_n) beginif(!rst_n) begintx_data_num <= 16'd0;total_num <= 16'd0;endelse beginif(pos_start_en && cur_state==st_idle) begin//数据长度tx_data_num <= tx_byte_num;//IP长度:有效数据+IP首部长度(20bytes)+ICMP首部长度(8bytes)total_num <= tx_byte_num + 16'd28;end else begintx_data_num <= tx_data_num ;total_num <= total_num ;endend
end//触发发送信号
always @(posedge clk or negedge rst_n) beginif(!rst_n) begintrig_tx_en <= 1'b0;endelse begintrig_tx_en <= pos_start_en;end
end//(三段式状态机)同步时序描述状态转移
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincur_state <= st_idle ;end else begincur_state <= next_state ;end
end//
always @(*) beginnext_state = st_idle;case(cur_state)st_idle : begin //等待发送数据if(skip_en)next_state = st_check_sum;elsenext_state = st_idle;end st_check_sum: begin //IP首部校验if(skip_en)next_state = st_check_icmp;elsenext_state = st_check_sum;end st_check_icmp: begin //ICMP首部校验if(skip_en)next_state = st_preamble;elsenext_state = st_check_icmp;end st_preamble : begin //发送前导码+帧起始界定符if(skip_en)next_state = st_eth_head;elsenext_state = st_preamble;endst_eth_head : begin //发送以太网首部if(skip_en)next_state = st_ip_head;elsenext_state = st_eth_head;end st_ip_head : begin //发送IP首部+icmp首部if(skip_en)next_state = st_tx_data;elsenext_state = st_ip_head;endst_tx_data : begin //发送数据if(skip_en)next_state = st_crc;elsenext_state = st_tx_data;endst_crc: begin //发送CRC校验值if(skip_en)next_state = st_idle;elsenext_state = st_crc;enddefault : next_state = st_idle;endcase
end//
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginskip_en <= 1'b0 ; cnt <= 5'd0 ;check_buffer <= 32'd0 ;check_buffer_icmp <= 32'd0 ;ip_head[1][31:16] <= 16'd0 ;tx_bit_sel <= 2'b0 ;crc_en <= 1'b0 ;gmii_tx_en <= 1'b0 ;gmii_txd <= 8'd0 ;tx_req <= 1'b0 ;tx_done_t <= 1'b0 ; data_cnt <= 16'd0 ;real_add_cnt <= 5'd0 ;//初始化数组 //前导码 7个8'h55 + 1个8'hd5preamble[0] <= 8'h55;preamble[1] <= 8'h55;preamble[2] <= 8'h55;preamble[3] <= 8'h55;preamble[4] <= 8'h55;preamble[5] <= 8'h55;preamble[6] <= 8'h55;preamble[7] <= 8'hd5;//目的MAC地址 //目的MAC地址 ff_ff_ff_ff_ff_ffeth_head[0] <= DES_MAC[47:40];eth_head[1] <= DES_MAC[39:32];eth_head[2] <= DES_MAC[31:24];eth_head[3] <= DES_MAC[23:16];eth_head[4] <= DES_MAC[15:8];eth_head[5] <= DES_MAC[7:0];//源MAC地址 //开发板MAC地址 00-11-22-33-44-55eth_head[6] <= BOARD_MAC[47:40];eth_head[7] <= BOARD_MAC[39:32];eth_head[8] <= BOARD_MAC[31:24];eth_head[9] <= BOARD_MAC[23:16];eth_head[10] <= BOARD_MAC[15:8];eth_head[11] <= BOARD_MAC[7:0];//以太网类型 //0800 IP协议eth_head[12] <= ETH_TYPE[15:8];eth_head[13] <= ETH_TYPE[7:0];end else beginskip_en <= 1'b0 ;crc_en <= 1'b0 ;gmii_tx_en <= 1'b0 ;tx_done_t <= 1'b0 ;case (cur_state)st_idle :beginif (trig_tx_en) beginskip_en <= 1'b1; //版本号:4 首部长度:5(单位:32bit,20byte/4=5)ip_head[0] <= {8'h45,8'h00,total_num};//16位标识,每次发送累加1 ip_head[1][31:16] <= ip_head[1][31:16] + 1'b1;//bit[15:13]: 010表示不分片ip_head[1][15:0] <= 16'h4000;//8'h80:表示生存时间//8'd01:1代表ICMP,2代表IGMP,6代表TCP,17代表UDPip_head[2] <= {8'h80,8'd01,16'h0000};//源IP地址 ip_head[3] <= BOARD_IP;//目的IP地址if (des_ip != 32'd0) beginip_head[4] <= des_ip ;end else beginip_head[4] <= DES_IP ;end// 8位icmp TYPE ,8位 icmp CODE ip_head[5][31:16] <= {ECHO_REPLY,8'h00};//16位identifier 16位sequenceip_head[6] <= {icmp_id,icmp_seq};//更新MAC地址if (des_mac != 48'd0) begin//目的MAC地址eth_head[0] <= des_mac[47:40] ;eth_head[1] <= des_mac[39:32] ;eth_head[2] <= des_mac[31:24] ;eth_head[3] <= des_mac[23:16] ;eth_head[4] <= des_mac[15:8] ;eth_head[5] <= des_mac[7:0] ;end end endst_check_sum :begin //IP首部校验cnt <= cnt + 1'b1;if (cnt == 5'd0) begincheck_buffer <= ip_head[0][31:16] + ip_head[0][15:0]+ ip_head[1][31:16] + ip_head[1][15:0]+ ip_head[2][31:16] + ip_head[2][15:0]+ ip_head[3][31:16] + ip_head[3][15:0]+ ip_head[4][31:16] + ip_head[4][15:0];end else if (cnt == 5'd1) begin //可能出现进位,累加一次check_buffer <= check_buffer[31:16] + check_buffer[15:0];endelse if (cnt == 5'd2) begin //可能再次出现进位,累加一次check_buffer <= check_buffer[31:16] + check_buffer[15:0];end else if (cnt == 5'd3) beginskip_en <= 1'b1 ;cnt <= 5'd0 ;ip_head[2][15:0] <= ~check_buffer[15:0] ;endelse begincheck_buffer <= check_buffer;endendst_check_icmp :begin //ICMP首部+数据校验cnt <= cnt + 1'b1 ; if (cnt == 5'd0) begincheck_buffer_icmp <= ip_head[5][31:16] + ip_head[6][31:16] + ip_head[6][15:0]+ reply_checksum;end else if(cnt == 5'd1) begin //可能出现进位,累加一次check_buffer_icmp <= check_buffer_icmp[31:16] + check_buffer_icmp[15:0];endelse if(cnt == 5'd2) begin //可能再次出现进位,累加一次check_buffer_icmp <= check_buffer_icmp[31:16] + check_buffer_icmp[15:0];endelse if(cnt == 5'd3) begin //按位取反skip_en <= 1'b1;cnt <= 5'd0;// ICMP:16位校验和ip_head[5][15:0] <= ~check_buffer_icmp[15:0];end else begincheck_buffer_icmp <= check_buffer_icmp;endendst_preamble :begin //发送前导码+帧起始界定符gmii_tx_en <= 1'b1 ;gmii_txd <= preamble[cnt];if (cnt == 5'd7) beginskip_en <= 1'b1 ; cnt <= 5'd0 ;end else begincnt <= cnt + 1'b1 ;endendst_eth_head :begin //发送以太网首部gmii_tx_en <= 1'b1 ; crc_en <= 1'b1 ;gmii_txd <= eth_head[cnt] ;if (cnt == 5'd13) beginskip_en <= 1'b1 ;cnt <= 5'd0 ;end else begincnt <= cnt + 1'b1 ;endendst_ip_head :begin //发送IP+ICMP首部gmii_tx_en <= 1'b1 ; crc_en <= 1'b1 ;tx_bit_sel <= tx_bit_sel + 1'b1 ;if (tx_bit_sel == 2'd0) begingmii_txd <= ip_head[cnt][31:24] ;end else if (tx_bit_sel == 2'd1) begingmii_txd <= ip_head[cnt][23:16] ;end else if (tx_bit_sel == 2'd2) begingmii_txd <= ip_head[cnt][15:8] ;if(cnt == 5'd6)begintx_req <= 1'b1 ;endendelse if (tx_bit_sel == 2'd3) begin gmii_txd <= ip_head[cnt][7:0] ;if (cnt == 5'd6) begin //提前读请求数据,等待数据有效时发送skip_en <= 1'b1 ;cnt <= 5'd0 ;end else begincnt <= cnt + 1'b1 ; endendelse begingmii_txd <= gmii_txd ; endendst_tx_data :begin //发送数据gmii_tx_en <= 1'b1 ; crc_en <= 1'b1 ;tx_bit_sel <= 2'd0 ;gmii_txd <= tx_data ;if (data_cnt < tx_data_num - 1'b1) begindata_cnt <= data_cnt + 1'b1 ;end else if (data_cnt == tx_data_num - 1'b1) begin//如果发送的有效数据少于18个字节,在后面填补充位//补充的值为最后一次发送的有效数据if (data_cnt + real_add_cnt < real_tx_data_num - 1'b1) beginreal_add_cnt <= real_add_cnt + 1'b1 ;end else beginskip_en <= 1'b1 ;data_cnt <= 16'd0 ;real_add_cnt <= 5'd0 ; endendelse begindata_cnt <= data_cnt ;endif (data_cnt == tx_data_num - 2'd2) begintx_req <= 1'b0 ;end else begintx_req <= tx_req ;endendst_crc :begingmii_tx_en <= 1'b1;tx_bit_sel <= tx_bit_sel + 3'd1;tx_req <= 1'b0; if(tx_bit_sel == 3'd0)gmii_txd <= {~crc_next[0], ~crc_next[1], ~crc_next[2],~crc_next[3],~crc_next[4], ~crc_next[5], ~crc_next[6],~crc_next[7]};else if(tx_bit_sel == 3'd1)gmii_txd <= {~crc_data[16], ~crc_data[17], ~crc_data[18],~crc_data[19],~crc_data[20], ~crc_data[21], ~crc_data[22],~crc_data[23]};else if(tx_bit_sel == 3'd2) begingmii_txd <= {~crc_data[8], ~crc_data[9], ~crc_data[10],~crc_data[11],~crc_data[12], ~crc_data[13], ~crc_data[14],~crc_data[15]};endelse if(tx_bit_sel == 3'd3) begingmii_txd <= {~crc_data[0], ~crc_data[1], ~crc_data[2],~crc_data[3],~crc_data[4], ~crc_data[5], ~crc_data[6],~crc_data[7]};tx_done_t <= 1'b1;skip_en <= 1'b1;endelse;enddefault: ;endcase end
end//发送完成信号及crc值复位信号
always @(posedge clk or negedge rst_n) beginif(!rst_n) begintx_done <= 1'b0;crc_clr <= 1'b0;endelse begintx_done <= tx_done_t;crc_clr <= tx_done_t;end
endendmodule
(3)icmp
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/12/29 15:29:13
// Design Name:
// Module Name: icmp
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module icmp(input sys_clk , //ila系统时钟input rst_n , //复位信号,低电平有效//GMII接口 input gmii_rx_clk , //GMII接收数据时钟input gmii_rx_dv , //GMII输入数据有效信号input [7:0] gmii_rxd , //GMII输入数据input gmii_tx_clk , //GMII发送数据时钟output gmii_tx_en , //GMII输出数据有效信号output [7:0] gmii_txd , //GMII输出数据 //用户接口 output rec_pkt_done , //以太网单包数据接收完成信号output rec_en , //以太网接收的数据使能信号 output [ 7:0] rec_data , //以太网接收的数据 output [15:0] rec_byte_num , //以太网接收的有效字节数 单位:byteinput tx_start_en , //以太网开始发送信号input [ 7:0] tx_data , //以太网待发送数据 input [15:0] tx_byte_num , //以太网发送的有效字节数 单位:byteinput [47:0] des_mac , //发送的目标MAC地址input [31:0] des_ip , //发送的目标IP地址output tx_done , //以太网发送完成信号output tx_req //读数据请求信号
);//parameter define
//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48'h00_11_22_33_44_55;
//开发板IP地址 192.168.1.10
parameter BOARD_IP = {8'd192,8'd168,8'd1,8'd10};
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter DES_MAC = 48'hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.102
parameter DES_IP = {8'd192,8'd168,8'd1,8'd102};wire crc_en ; //CRC开始校验使能
wire crc_clr ; //CRC数据复位信号
wire [7:0] crc_d8 ; //输入待校验8位数据wire [31:0] crc_data ; //CRC校验数据
wire [31:0] crc_next ; //CRC下次校验完成数据wire [15:0] icmp_id ; //ICMP标识符:对于每一个发送的数据报进行标识
wire [15:0] icmp_seq ; //ICMP序列号:对于发送的每一个数据报文进行编号//比如:发送的第一个数据报序列号为1,第二个序列号为2
wire [31:0] reply_checksum ; //接收的icmp数据部分校验和assign crc_d8 = gmii_txd ;icmp_rx #(.BOARD_MAC (BOARD_MAC ) , //参数例化.BOARD_IP (BOARD_IP ) )
u_icmp_rx(.clk (gmii_rx_clk ) ,.rst_n (rst_n ) ,.gmii_rx_dv (gmii_rx_dv ) , //GMII输入数据有效信号.gmii_rxd (gmii_rxd ) , //GMII输入数据.rec_pkt_done (rec_pkt_done ) , //以太网单包数据接收完成信号.rec_en (rec_en ) , //以太网接收数据使能信号 ---fifo_en.rec_data (rec_data ) , //以太网接收数据 ---fifo_data.rec_byte_num (rec_byte_num ) , //以太网接收有效字数 bit.icmp_id (icmp_id ) , //ICMP标识符.icmp_seq (icmp_seq ) , //ICMP序列号.reply_checksum (reply_checksum ) //接收数据校验
);icmp_tx#( .BOARD_MAC (BOARD_MAC ) , //参数例化.BOARD_IP (BOARD_IP ) ,.DES_MAC (DES_MAC ) ,.DES_IP (DES_IP ) )
u_icmp_tx( //input.clk (gmii_tx_clk ) , //时钟信号.rst_n (rst_n ) , //复位信号,低电平有效.reply_checksum (reply_checksum ) , //ICMP数据部分校验和.icmp_id (icmp_id ) , //ICMP标识符.icmp_seq (icmp_seq ) , //ICMP序列号.tx_start_en (tx_start_en ) , //以太网开始发送信号.tx_data (tx_data ) , //以太网待发送数据.tx_byte_num (tx_byte_num ) , //以太网发送的有效字节数.des_mac (des_mac ) , //发送的目标MAC地址.des_ip (des_ip ) , //发送的目标IP地址.crc_data (crc_data ) , //CRC校验数据.crc_next (crc_next ) , //CRC下次校验完成数据//output.tx_done (tx_done ) , //以太网发送完成信号.tx_req (tx_req ) , //读数据请求信号.gmii_tx_en (gmii_tx_en ) , //GMII输出数据有效信号.gmii_txd (gmii_txd ) , //GMII输出数据.crc_en (crc_en ) , //CRC开始校验使能.crc_clr (crc_clr ) //CRC数据复位信号
);crc32_d8 u_crc32_d8(.clk (gmii_tx_clk ) , //时钟信号.rst_n (rst_n ) , //复位信号,低电平有效.data (crc_d8 ) , //输入待校验8位数据.crc_en (crc_en ) , //crc使能,开始校验标志.crc_clr (crc_clr ) , //crc数据复位信号 .crc_data (crc_data ) , //CRC校验数据.crc_next (crc_next ) //CRC下次校验完成数据
);endmodule
3、整体代码框架
四、下载测试
五、工程源码、项目移植请后台私信
相关文章:
以太网ICMP协议(ping指令)——FPGA学习笔记25
--素材来源原子哥 一、IP协议 1、IP简介 IP是Internet Protocol(网际互连协议)的缩写。IP 协议是 TCP/IP 协议簇中的核心协议,它为上层协议提供无状态、无连接、不可靠的服务。IP 协议规定了数据传输时的基本单元和格式 。 IP协议是 OSI 参考模型中网络层…...
ESP32自动下载电路分享
下面是一个ESP32系列或者ESP8266等电路的一个自动下载电路 在ESP32等模块需要烧写程序的时候,需要通过将EN引脚更改为低电平并将IO0引脚设置为低电平来切换到烧写模式。 有时候也会采用先将IO接到一个按键上,按住按键拉低IO0的同时重新上电的方式进入烧写…...
数据结构(ing)
学习内容 指针 指针的定义: 指针是一种变量,它的值为另一个变量的地址,即内存地址。 指针在内存中也是要占据位置的。 指针类型: 指针的值用来存储内存地址,指针的类型表示该地址所指向的数据类型并告诉编译器如何解…...
STM32-笔记32-ESP8266作为服务端
esp8266作为服务器的时候,这时候网络助手以客户端的模式连接到esp8266,其中IP地址写的是esp8266作为服务器时的IP地址,可以使用ATCIFSR查询esp8266的ip地址,端口号默认写333。 当esp8266作为服务器的时候,需要完成哪些…...
[Day 12]904.水果成篮
今天给带来的题目是滑动窗口的另一种题目,之前我们讲了滑动窗口题目中长度最小的子数组,今天这个题目实际上是求长度最长的子数组 题目描述:力扣链接 904.水果成篮 你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整…...
检查字符是否相同
给你一个字符串 s ,如果 s 是一个 好 字符串,请你返回 true ,否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 ,那么我们称字符串 s 是 好 字符串。 输入:s "abacbc" 输出:t…...
专家混合(MoE)大语言模型:免费的嵌入模型新宠
专家混合(MoE)大语言模型:免费的嵌入模型新宠 今天,我们深入探讨一种备受瞩目的架构——专家混合(Mixture-of-Experts,MoE)大语言模型,它在嵌入模型领域展现出了独特的魅力。 一、M…...
CSS3 框大小
CSS3 框大小 CSS3 是网页设计和开发中不可或缺的一部分,它为开发者提供了更多样化、更灵活的样式和布局选择。在 CSS3 中,框大小(Box Sizing)是一个重要的概念,它决定了元素内容的宽度和高度以及元素整体的大小。本文将详细介绍 CSS3 框大小的概念、用法以及最佳实践。 …...
Vue动态控制disabled属性
参考:https://blog.csdn.net/guhanfengdu/article/details/126082781 在Vue中disabled:的值是受布尔值影响的,false为关闭禁用,true为开启禁用效果。 结果就是true会让按钮禁用 相反false会让按钮重新可以使用 那如果想要通过id属性值来判断是否禁用…...
Python入门教程 —— 列表
1.列表的基本使用 列表的介绍 前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢? 定义100个变量,每个变量存放一个学生的姓名可行吗?有更好的办法吗? 列表 列表的格式 定义列的格式:[元素1, 元素2, 元素3, ..., 元素n] 变量tmp的类型…...
CSS2笔记
一、CSS基础 1.CSS简介 2.CSS的编写位置 2.1 行内样式 2.2 内部样式 2.3 外部样式 3.样式表的优先级 4.CSS语法规范 5.CSS代码风格 二、CSS选择器 1.CSS基本选择器 通配选择器元素选择器类选择器id选择器 1.1 通配选择器 1.2 元素选择器 1.3 类选择器 1.4 ID选择器 1.5 基…...
对一个双向链表,从尾部遍历找到第一个值为x的点,将node p插入这个点之前,如果找不到,则插在末尾。使用C语言实现
以下是一个用C语言实现的双向链表(Doubly Linked List)插入操作的代码。该代码从尾部遍历找到第一个值为x的节点,并在其前插入新节点p,或者在未找到时将其插入链表末尾。 #include <stdio.h> #include <stdlib.h>// 定…...
C语言string函数库补充之strstr
这次讲解一个函数strstr 它的功能是在一个字符串(称为“主字符串”)中查找另一个字符串(称为“子字符串”)的第一个出现位置。如果找到了子字符串,strstr 函数会返回一个指向子字符串在主字符串中首次出现位置的指针&…...
SpringBoot整合Mapstruct转换器使用教程(提供Gitee源码)
前言:MapStruct 主要是为了简化 Java 应用程序中不同对象之间(特别是 DTO(Data Transfer Object)、VO(Value Object)、BO(Business Object)和数据库实体类等)数据转换的过程。 目录 一、什么是Mapstruct 二、导入Maven依赖 三、创建数据模型 四、创建Mapper接口 …...
vue cli更新遇到的问题(vue -V查询版本号不变的问题)
1.镜像地址选择 npm会去默认的registry远程仓库中下载指定内容 该过程可能十分缓慢 因此我们可以切换默认仓库为镜像地址 npm config set registry https://registry.npmmirror.com 通过该指令可以从最新的镜像地址下载指定内容(镜像地址可能会有变 有变请重新查询) 2.下载 …...
CSP初赛知识学习计划
CSP初赛知识学习计划 学习目标 在20天内系统掌握CSP初赛所需的计算机基础知识、编程概念、数据结构、算法等内容,为初赛取得优异成绩奠定坚实基础。 资料收集 整理的CSP知识点文档。相关教材,如《信息学奥赛一本通》等。在线编程学习平台,…...
Python 中常见的数据结构之二推导式
Python 中常见的数据结构之二推导式 使用推异式列表推导式字典推导式集合推导式 使用推异式 推导式是一种从已存在的序列中快速构建列表(list)、集合(set) 和 字典(dictionary)方式。Python 支持 3 种不同类型的推导式: 列表推导式;字典推导式…...
java.lang.Error: FFmpegKit failed to start on brand:
如果你使用FFmpegKit的时候遇到了这个问题: java.lang.Error: FFmpegKit failed to start on brand: Xiaomi, model: MI 8, device: dipper, api level: 29, abis: arm64-v8a armeabi-v7a armeabi, 32bit abis: armeabi-v7a armeabi, 64bit abis: arm64-v8a.at c…...
Gateway服务网关
一、初识Gateway服务网关 1.为什么需要网关? 在微服务中,各个模块之间的调用,也可以称其为远程调用!但是,如果是外部(用户)对微服务进行访问时,发的请求能不加处理的直接访问微服务…...
windows终端conda activate命令行不显示环境名
问题: 始终不显示环境名 解决 首先需要配置conda的环境变量 确保conda --version能显示版本 然后对cmd进行初始化,如果用的是vscode中的终端,那需要对powershell进行初始化 Windows CMD conda init cmd.exeWindows PowerShell conda …...
【网络】ARP表、MAC表、路由表
ARP表 网络设备存储IP-MAC映射关系的表,便于快速查找和转发数据包 ARP协议工作原理 ARP(Address Resolution Protocol),地址解析协议,能够将网络层的IP地址解析为数据链路层的MAC地址。 1.主机在自己的ARP缓冲区中建立…...
5.1 冒泡排序与选择排序
5.1 冒泡排序与选择排序 在计算机科学中,排序算法是最基础且最常用的算法之一。在这个部分,我们将探讨两种基础的排序算法:冒泡排序和选择排序。 冒泡排序 冒泡排序是一种简单的排序算法。它的基本思想是通过重复地遍历需要排序的序列&…...
vip与haproxy构建nginx高可用集群传递客户端真实ip
问题 系统使用了vip与haproxy实现高可用以及对nginx进行负载均衡,但是发现在上游的应用服务无法拿到客户端的请求ip地址,拿到的是主haproxy机器的ip,以下是nginx与haproxy的缩减配置: location ~* ^/(xx|xx) {proxy_pass http:/…...
049_小驰私房菜_MTK Camera debug,通过adb 命令读写Camera sensor寄存器地址的值
一、读取/写入 某个寄存器地址的值 设备先adb root 1)读取寄存器地址的值 /proc/driver # echo "0x0a34" > camsensor && dmesg |grep -i a34 2)往寄存器地址写值 /proc/driver # echo "0x3304 0x66” > camsensor && dmesg |grep -…...
《深入浅出HTTPS》读书笔记(24):椭圆曲线密码学
《深入浅出HTTPS》读书笔记(24):椭圆曲线密码学 为了保证DH的密钥对不被破解,提升安全性的主要手段就是增加密钥对的长度,但是长度越长,性能越低。 为了解决性能问题,需要…...
MIPI_DPU 综合(DPU+MIPI+Demosaic+VDMA 通路)
目录 1. 简介 2. 创建 Platform 2.1 Block Design 2.1.1 DPU PFM Lite 2.1.2 DPU prj 2.1.3 DPU MIPI Platform 2.2 pin 约束 2.2.1 GPIO 约束 2.2.2 IIC 约束 2.1.3 DPHY 约束 3. 报错总结 3.1 AXI_M 必须顺序引用 3.2 DPU 地址分配错误 4. Design Example 4.…...
开源模型应用落地-qwen2-7b-instruct-LoRA微调-Axolotl-单机多卡-RTX 4090双卡(七)
一、前言 本篇文章将使用Axolotl去高效微调QWen2系列模型,通过阅读本文,您将能够更好地掌握这些关键技术,理解其中的关键技术要点,并应用于自己的项目中。 二、术语介绍 2.1. LoRA微调 LoRA (Low-Rank Adaptation) 用于微调大型语言模型 (LLM)。 是一种有效的自适应策略,…...
电商项目-基于ElasticSearch实现商品搜索功能(一)
一、根据关键字查询商品 (1) shangcheng_service_search项目创建SearchService接口 public interface SearchService { /*** 全文检索* param paramMap 查询参数* return*/public Map search(Map<String, String> paramMap) throws Exception; }(2) shangcheng_serv…...
Kafka集群部署与安装
一、什么是Kafka Kafka是一个Pub-Sub的消息系统,无论是发布还是订阅,都须指定Topic。 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者大规模的网站中的所有动作流数据 二、JMS:Java Message Service Java消息服…...
基于深度学习的视觉检测小项目(二) 环境和框架搭建
一、环境和框架要求 SAM的环境要求: Python>3.7 PyTorch>1.7 torchvision>0.8 YOLO V8的环境要求:YOLO集成在ultralytics库中,ultralytics库的环境要求: Python>3.7 PyTorch>1.10.0 1、确定pytorch版本…...
JS (node) 的 ACM 模式 + debug方法 (01背包为例)
文章目录 JS 的 ACM 模式输入处理 JS dubug (01背包为例)动态输入在本地通过 Node.js 运行和调试 硬编码 Hard CodingVS Code JS 的 ACM 模式 在 JavaScript 中,ACM 模式一般通过 Node.js 的 readline 模块实现。 输入处理 使用 readline 模块监听输入。 将每行输…...
USB射频微波功率计的功能与优势-盛铂科技
USB射频功率计是一种用于测量射频信号(RF)功率的仪器,它通过USB接口与计算机或其他设备连接,以便于进行数据采集、处理和显示。 主要功能 功率测量:能够测量射频信号的功率,通常以毫瓦(mW&…...
基于单片机的公交车报站系统设计
引言:单片机应用实践是电类相关专业一门必修的专业技术基础课,其教学目的就是为了使学生能深入了解模拟电路、数字电路、EDA 技术、传感器、单片机原理及其相关接口的综合应用技术,为此我们选了一个典型的实践题目- 公交车报站系统设计&#…...
软考教材重点内容 信息安全工程师 第 12 章网络安全审计技术原理与应用
12.1.1 网络安全审计概念 网络安全审计是指对网络信息系统的安全相关活动信息进行获取、记录、存储、分析和利用的工作。网络安全审计的作用在于建立“事后”安全保障措施,保存网络安全事件及行为信息,为网络安全事件分析提供线索及证据,以便…...
Spring IOC
什么是spring 以前没有spring的时候,我们需要得到一个对象,都是自己主动去new一个对象,然后通过set方法给对象注入属性,但是这种动作其实是一个重复的动作,所以spring提供ioc的容器解决方案,在容器启动的时…...
Jmeter进阶篇(31)解决java.net.BindException: Address already in use: connect报错
📚前言 近期雪雪妹妹在使用Jmeter执行压测的时候,发现了一个非常让她头疼的问题,她使用20并发跑,正确率可以达到100%,但是一旦使用200并发,就会出现大量的报错,报错内容如下: java.net.BindException: Address already in use: connectat java.net.DualStackPlainSo…...
组会 | DenseNet
目录 1 研究背景1.1 提出的动机1.2 同期的模型 2 网络模型2.1 模型架构2.2 模块与参数2.3 瓶颈层和压缩率2.4 小结 3 实验结果4 优点与缺点4.1 DenseNet 的优点4.2 DenseNet 的缺点 前言:本博客仅为组会总结,如有谬误,请不吝指出…...
深入解析-正则表达式
学习正则,我们到底要学什么? 正则表达式(RegEx)是一种强大的文本匹配工具,广泛应用于数据验证、文本搜索、替换和解析等领域。学习正则表达式,我们不仅要掌握其语法规则,还需要学会如何高效地利…...
12306分流抢票软件 bypass v1.16.43 绿色版(春节自动抢票工具)
软件介绍 12306Bypass分流抢票软件,易操作强大的12306抢票软件,全程自动抢票,云识别验证码打码,多线程秒单、稳定捡漏,支持抢候补票、抢到票自动付款,支持多天、多车次、多席别、多乘客、短信提醒等功能。…...
Arduino UNO 驱动1.8 TFT屏幕显示中文
背景 最近入手了一块1.8寸的tft屏幕,通过学习文档,已经掌握了接线,显示英文、数字、矩形区域、划线、画点等操作, 但是想显示中文的时候操作比较复杂。 问题 1、arduino uno 驱动这款屏幕目前使的是自带的<TFT.h> 库操作…...
vue路由模式面试题
vue路由模式 1.路由的模式有哪些?有什么区别? history和hash模式 区别: 1.表现的形态不同: 在地址栏url中:hash模式中带有**#**号,history没有 2.请求错误时表现不同: 在hash模式中,对于404地址请求时,不会进行请求 但是在history模式中,对于404请求时,仍然会进行请求…...
计算机的错误计算(二百零一)
摘要 用两个大模型计算 ,结果保留 10位有效数字。实验表明,两个大模型的输出均只有1位正确数字;并它们几乎相同:仅最后1位数字不同。 例1. 计算 , 结果保留 10位有效数字。 下面是与一个数学解题器的对话。 以上为与一个数学解…...
WandB使用笔记
最近看代码,发现代码中有wandb有关的内容,搜索了一下发现是一个模型训练工具,然后学习了一下,这里记录一下使用过程,方便以后查阅。 WandB使用笔记 登录WandB 并 创建团队安装 WandB 并 登录模型训练过程跟踪模型版本管…...
TTL 传输中过期问题定位
问题: 工作环境中有一个acap的环境,ac的wan口ip是192.168.186.195/24,ac上lan上有vlan205,其ip子接口地址192.168.205.1/24,ac采用非nat模式,而是路由模式,在上级路由器上有192.168.205.0/24指向…...
spring mvc源码学习笔记之五
pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...
Java 数据库连接 - Sqlite
Java 数据库连接 - Sqlite PS: 1. 连接依赖库:[sqlite-jdbc-xxx.jar](https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc)(根据连接的数据库版本选择) 2. 支持一次连接执行多次sql语句; 3. 仅本地连接;使用说明: publ…...
【Rust自学】10.2. 泛型
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 题外话:泛型的概念非常非常非常重要!!!整个第10章全都是Rust的重难点!…...
鸿蒙MPChart图表自定义(六)在图表中绘制游标
在鸿蒙开发中,MPChart 是一个非常强大的图表库,它可以帮助我们创建各种精美的图表。今天,我们将继续探索鸿蒙MPChart的自定义功能,重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…...
PHP在做api开发中,RSA加密签名算法如何使用 ?
RSA 加密是什么 RSA(Rivest-Shamir-Adleman)是最早的公钥密码系统之一,广泛用于安全数据传输。3 位数学家 Rivest、Shamir 和 Adleman 的名字来命名的。 是非对称加密的一种 这种算法非常可靠,密钥越长,它就越难破解。…...
PHP+Redis的基本操作方法
一、Redis连接与认证 二、String操作 三、Hash操作 四、List操作 五、Set操作 六、Zset操作 一、Redis连接与认证 $redis new Redis(); //连接参数:ip、端口、连接超时时间,连接成功返回true,否则返回false $ret $redis->connec…...