基于GTX的64B66B编码的自定义接收模块(高速收发器二十二)

  点击进入高速收发器系列文章导航界面


1、自定义PHY顶层模块

  前文设计了64B66B自定义PHY的发送模块,本文完成自定义PHY剩余的模块的设计,整体设计框图如下所示。

  其中phy_tx是自定义PHY的发送数据模块,scrambler是加扰模块,rx_slipbit是接收端手动对齐模块,descrambler是解扰模块,phy_rx是自定义PHY的接收数据模块。其中加扰和解扰直接使用官方示例工程的模块。

在这里插入图片描述

图1 整体设计框图

  当接收数据同步完成之后,接收数据模块才会解码接收的数据,转换成axi_stream流数据输出给用户。

  PHY顶层模块的参考代码如下所示:

    //例化PHY接收对齐模块phy_rx_slipbit u_phy_rx_slipbit(.rx_clk     ( rx_clk        ),//系统时钟信号;.rx_rst	    ( rst           ),//系统复位信号,高电平有效;.header     ( rx_header     ),//头部2位数据,等于2'b01或者2'b10时有效;.header_vld ( rx_header_vld ),//头部数据有效指示信号,高电平有效;.slipbit    ( rx_slipbit    ),//滑块信号,高电平有效;.sync       ( sync          ) //同步成功指示信号,高电平有效;);//解扰模块;descrambler u_descrambler_0(.clk		        ( rx_clk            ),//系统时钟信号;.rst 	            ( rx_rst            ),//系统复位信号,高电平有效;.rx_header_i        ( rx_header         ),//2位的同步头数据,不需要进行解扰;.rx_header_vld_i    ( rx_header_vld     ),//同步头有效指示信号,高电平有效;.rx_data_i          ( rx_data           ),//需要解码的接收数据;.rx_data_vld_i      ( rx_data_vld       ),//接收数据有效指示信号;.rx_header_o        ( rx_header_de      ),//2位的同步头数据,不需要进行解扰;.rx_header_vld_o    ( rx_header_vld_de  ),//同步头有效指示信号,高电平有效;.rx_data_o          ( rx_data_de        ),//解扰后的输出数据;.rx_data_vld_o      ( rx_data_vld_de    ) //解扰后的输出数据有效指示信号;);//例化PHY接收模块;phy_rx  u_phy_rx(.rx_clk		    ( rx_clk	        ),//系统时钟信号;.rx_rst	        ( rx_rst	        ),//系统复位信号,高电平有效;.sync           ( sync              ),//同步成功指示信号,高电平有效;.rx_data        ( rx_data_de        ),//GTX的接收数据信号;.rx_data_vld    ( rx_data_vld_de    ),//GTX的接收数据有效指示信号;.rx_header      ( rx_header_de      ),//GTX的接收头部数据信号;.rx_header_vld  ( rx_header_vld_de  ),//GTX的接收头部数据有效指示信号;.m_axi_data     ( m_axi_data        ),//数据信号;.m_axi_keep     ( m_axi_keep        ),//数据掩码信号;.m_axi_last     ( m_axi_last        ),//一帧数据的结束数据;.m_axi_valid    ( m_axi_valid       ) //数据有效指示信号;);//例化PHY发送模块;phy_tx u_phy_tx(.tx_clk         ( tx_clk        ),//系统时钟信号;.tx_rst         ( tx_rst        ),//系统复位信号,高电平有效;.s_axi_valid    ( s_axi_valid   ),//数据有效指示信号,高电平有效;.s_axi_last     ( s_axi_last    ),//帧结束指示信号,高电平有效;.s_axi_data     ( s_axi_data    ),//数据信号;.s_axi_keep     ( s_axi_keep    ),//数据掩码信号;.s_axi_ready    ( s_axi_ready   ),//接收数据应答信号;.tx_data        ( tx_data_0       ),//GTX需要发送的数据;.tx_header      ( tx_header_0     ),//GTX需要发送的头部数据;.tx_sequence    ( tx_sequence_0   ) //GTX外部计数器;);//通道0的加扰模块;scrambler u_scrambler_0(.clk		        ( tx_clk            ),//系统时钟信号;.rst 	            ( tx_rst            ),//系统复位信号,高电平有效;.tx_header_i        ( tx_header_0       ),//2位的同步头数据,不需要进行加扰;.tx_sequence_i      ( tx_sequence_0     ),//外部计数器;.tx_data_i          ( tx_data_0         ),//需要加码的接收数据;.tx_header_o        ( tx_header         ),//2位的同步头数据,不需要进行接扰;.tx_sequence_o      ( tx_sequence       ),//外部计数器;.tx_data_o          ( tx_data           ) //加扰后的输出数据;);

2、接收端同步模块设计

  该模块通过接收到的同步头(rx_headr)的状态去拉高slipbit,调节串并转换的起始位置,达到接收数据对齐的目的。

  当接收通道复位完成之后,开始检测接收到的同步头(rx_headr)的状态,如果rx_headr不等于2’b01或者2’b10,则表示接收的数据没有对齐,把slipbit信号拉高一个时钟,等待32个时钟周期后,再次检测rx_headr的状态,直到连续64个时钟rx_headr均为2’b01或者2’b10时,表示同步完成。

  上述是官方示例工程接收端同步数据的思路,以这个方式设计模块或者直接使用官方示例工程的同步模块,在实际上板测试时,可能会存在一些问题。

  我在设计该模块时,还增加了一个条件,正常情况下,一帧数据应该只有在帧头和帧尾才会存在控制位,其余时间全是数据位。

  因此rx_headr应该不会连续三个时钟为2‘b10,因此如果检测到连续三个时钟均为2’b10,则认为同步失败,需要继续拉高slipbit来调整串并转换的起始位置。

  下面是该模块的具体设计,首先是端口信号,sync为高电平表示接收的数据同步完成,之后接收数据模块才能正常工作。计数器cnt用于计数连续检测正确数据的个数,计数器计数到最大值时,表示同步完成。

    //该计数器用于记录连续检测正确数据的个数,达到指定个数时表示同步成功;always@(posedge rx_clk)beginif(rx_rst)begin//cnt <= 'd0;endelse if(slipbit)begin//通过滑块信号进行同步时,表示检测到错误数据,计数器清零。cnt <= 'd0;endelse if(add_cnt)beginif(end_cnt)cnt <= 'd0;elsecnt <= cnt + 'd1;endend//头部数据有效且是控制帧或者数据帧且不处于同步过程中;assign add_cnt = (header_vld && ((header == 2'b01) || (header == 2'b10)) && (~slipbit_flag));assign end_cnt = add_cnt && cnt == SH_CNT_MAX - 1;//连续采集指定个正确的数据;

  当不处于同步调整状态,且接收的有效同步头是错误时,表示同步失败,拉高slipbit调整串并转换的起始位置。

    //当头部数据有效指示信号位高电平且头部是错误数据并且不处于同步过程中时,表示检测的数据有误。assign header_invld = (header_vld && (header != 2'b01) && (header != 2'b10) && (~slipbit_flag));//当采集数据有误时,将滑块信号拉高,进行校准;always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;slipbit <= 1'b0;endelse begin//当检测的信号有错误且此时并没有进行校正时有效;slipbit <= ((~slipbit) && (header_invld || syc_error));endend

  每次slipbit拉高之后,需要等待32个时钟之后,才能进行下次检测,因此需要一个计数器slipbit_cnt来计数这个状态slipbit_flag。

    //正在校准的指示信号,初始值位0,当滑块信号位高电平时开始计数,当计数器计数结束时拉低;always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;slipbit_flag <= 1'b0;endelse if(end_slipbit_cnt)begin//当计数器拉高时有效;slipbit_flag <= 1'b0;endelse if(slipbit)begin//滑块信号有效时拉高;slipbit_flag <= 1'b1;endend//记录滑块信号拉高后的一段时间,这段时间内IP会对采集位置进行调整,期间不需要判断输出头部数据的正确性;always@(posedge rx_clk)beginif(rx_rst)begin//slipbit_cnt <= 'd0;endelse if(add_slipbit_cnt)beginif(end_slipbit_cnt)slipbit_cnt <= 'd0;elseslipbit_cnt <= slipbit_cnt + 'd1;endendassign add_slipbit_cnt = (slipbit || slipbit_flag);//当滑块信号或者指示信号有效时计数;assign end_slipbit_cnt = add_slipbit_cnt && slipbit_cnt == SLIPBIT_GAP - 1;//当计数到指定时钟个数时清零;

  生成同步完成指示信号sync,当slipbit为高电平时,表示在调节同步的位置,此时sync为低电平。当计数器cnt计数结束时,表示同步完成,此时sync拉高。

    //生成同步完成指示信号。always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;sync <= 1'b0;endelse if(slipbit)begin//当滑块信号位高电平时,表示检测到错误数据,表示当前数据没有同步成功;sync <= 1'b0;endelse if(end_cnt)begin//当连续检测到指定个正确数据时,表示同步成功;sync <= 1'b1;endend

  最后将输入信号通过两组移位寄存器暂存,如果同步后的有效同步头rx_headr连续三个时钟均为2’b10,则表示同步失败,将sync_error拉高,会重新调整同步位置。

    //将头部数据和头部数据有效指示信号延迟两个时钟。always@(posedge rx_clk)begin{header_r[1],header_r[0]} <= {header_r[0],header};header_vld_r <= {header_vld_r[0],header_vld};end//检测头部数据,防止出现连续的2'b10,从而导致同步错误。always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;syc_error <= 1'b0;endelse begin//当不处于同步调整状态下时,连续三个时钟检测到头部数据为2'b10时拉高,表示接收的同步数据错误,需要继续调整同步。syc_error <= (~slipbit_flag) && (header == 2'b10) && (header_r[0] == 2'b10) && (header_r[1] == 2'b10) && header_vld && (&header_vld_r);endend

3、接收数据模块设计

  64B66B编码的接收模块设计逻辑很简单,只需要从指定起始位和停止位之间解析出数据输出到用户的axi_stream端口即可。

  首先是端口信号列表,包含解扰后的输入数据、同步头、同步完成指示信号SYNC,还有输出给用户的axi_stream主机端口信号,因为模块内部不包含FIFO等缓冲结果,因此不需要从机提供应答信号,直接将解析的数据输出。

  通过一组移位寄存器将输入信号暂存,便于后续逻辑使用。当接收端的数据同步完成,同步头为2’b10且接收第一个数据的第一个字节数据为8’h78时,sof_flag拉高表示检测到帧头。

    //当检测到帧头时拉高,其余时间为低电平。always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;sof_flag <= 1'b0;endelse if(sync)begin//检测到帧头时拉高;sof_flag <= (rx_header_vld && (rx_header == 2'b10) && rx_data_vld && (rx_data[7:0] == 8'h78));endend

  而帧尾有8种情况,当eof_flag拉高时,表示检测到帧尾,同时需要记录帧尾包含几个字节的有效数据,与输出给用户的尾端数据掩码信号有关。

  Rx_flag为高电平表示正在接收一帧数据,当检测到帧头时拉高,输出用户最后一帧的最后一个数据时拉低,其余时间保持不变。

    //接收数据标志信号,初始值为0,当检测到起始帧时拉高,检测到结束帧时拉低;always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;rx_flag <= 1'b0;endelse if(m_axi_last)begin//当一帧数据接收完成时拉低;rx_flag <= 1'b0;endelse if(sof_flag)begin//当检测到帧头时拉高;rx_flag <= 1'b1;endend

  然后是生成用户数据,由于停止位的最低字节不是数据,因此在拼接时需要舍弃。因为GTX的数据是小端对齐的,而输出给用户的数据采用大端对齐,因此输出的数据需要将高低字节数据转换。

//生成用户数据信号;always@(posedge rx_clk)beginif(rx_rst)begin//初始值为0;m_axi_data_r <= 'd0;endelse if(eof_flag)beginm_axi_data_r <= {rx_data_r[0][15:8],rx_data_r[1][63:8]};endelse if(eof_flag_r)beginm_axi_data_r <= {rx_data_r[0][15:0],rx_data_r[1][63:16]};endelse if(rx_flag)beginm_axi_data_r <= {rx_data_r[0][7:0],rx_data_r[1][63:8]};endend//将输出数据大小端翻转;assign m_axi_data = {m_axi_data_r[7:0],m_axi_data_r[15:8],m_axi_data_r[23:16],m_axi_data_r[31:24],m_axi_data_r[39:32],m_axi_data_r[47:40],m_axi_data_r[55:48],m_axi_data_r[63:56]};

  之后生成用户数据掩码,初始值8’hff,表示所有数据均有效。根据帧尾的有效字节数确定尾端掩码的数值,比如帧尾有1字节有效数据时,则用户数据的尾端所有字节的数据均有效,为8’hff,其余七种情况需要全部考虑。

  该模块的设计到此结束,用户在设计时只需要注意帧尾有效字节数,与尾端掩码的对应关系即可,其余设计都比较简单。

4、仿真PHY顶层模块

  加扰和解扰模块使用官方示例工程相关模块,但在模块内部添加了对其他信号的延时设计,确保数据对齐,加扰和解扰模块参考代码如下所示。

  加扰模块参考代码:

//--###############################################################################################
//--#
//--# File Name		: scrambler
//--# Designer		: 数字站
//--# Tool			: Vivado 2021.1
//--# Design Date	: 2024.4.3
//--# Description	: 通过x^58+x^39+1对接收数据进行加扰。
//--# Version		: 0.0
//--# Coding scheme	: GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
module scrambler #(parameter   TX_DATA_WIDTH           =   64		         //需要加扰的数据位宽;
)(input									clk		        ,//系统时钟信号;input									rst 	        ,//系统复位信号,高电平有效;input       [1 : 0]                     tx_header_i     ,//2位的同步头数据,不需要进行加扰;input       [6 : 0]                     tx_sequence_i   ,//外部计数器;input       [TX_DATA_WIDTH - 1 : 0]     tx_data_i       ,//需要加码的接收数据;output  reg [1 : 0]                     tx_header_o     ,//2位的同步头数据,不需要进行接扰;output  reg [6 : 0]                     tx_sequence_o   ,//外部计数器;output  reg [TX_DATA_WIDTH - 1 : 0]     tx_data_o        //加扰后的输出数据;
);integer                                 i               ;reg         [57 : 0]                    poly            ;reg         [57 : 0]                    scrambler       ;reg         [TX_DATA_WIDTH - 1 : 0]     tempData        ;reg                                     xorBit          ;always@(scrambler,tx_data_i)beginpoly = scrambler;for(i=0 ; i<=(TX_DATA_WIDTH-1) ; i=i+1)beginxorBit = tx_data_i[i] ^ poly[38] ^ poly[57];poly = {poly[56:0],xorBit};tempData[i] = xorBit;endend//加扰输出数据;always@(posedge clk)beginif (rst)begintx_data_o <= 'h0;scrambler <= 58'h155_5555_5555_5555;endelse if(tx_sequence_i)begintx_data_o <= tempData;scrambler <= poly;endend//加码数据相对于其他信号延迟一个时钟,为了对齐,把其他信号延迟一个时钟后输出。always@(posedge clk)begintx_header_o <= tx_header_i;tx_sequence_o <= tx_sequence_i;endendmodule

  解扰模块参考代码:

//--###############################################################################################
//--#
//--# File Name		: descrambler
//--# Designer		: 数字站
//--# Tool			: Vivado 2021.1
//--# Design Date	: 2024.4.3
//--# Description	: 通过x^58+x^39+1对接收数据进行解扰。
//--# Version		: 0.0
//--# Coding scheme	: GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
module descrambler #(parameter   RX_DATA_WIDTH           =   64		         //需要解扰的数据位宽;
)(input									clk		        ,//系统时钟信号;input									rst 	        ,//系统复位信号,高电平有效;input       [1 : 0]                     rx_header_i     ,//2位的同步头数据,不需要进行解扰;input                                   rx_header_vld_i ,//同步头有效指示信号,高电平有效;input       [RX_DATA_WIDTH - 1 : 0]     rx_data_i       ,//需要解码的接收数据;input                                   rx_data_vld_i   ,//接收数据有效指示信号;output  reg [1 : 0]                     rx_header_o     ,//2位的同步头数据,不需要进行解扰;output  reg                             rx_header_vld_o ,//同步头有效指示信号,高电平有效;output  reg [RX_DATA_WIDTH - 1 : 0]     rx_data_o       ,//解扰后的输出数据;output  reg                             rx_data_vld_o    //解扰后的输出数据有效指示信号;
);integer                                 i               ;reg         [57 : 0]                    descrambler     ;reg         [57 : 0]                    poly            ;reg         [RX_DATA_WIDTH - 1 : 0]     tempData        ;reg                                     xorBit          ;//解扰运算;always@(descrambler,rx_data_i)beginpoly = descrambler;for(i=0;i<=(RX_DATA_WIDTH-1);i=i+1)beginxorBit = rx_data_i[i] ^ poly[38] ^ poly[57];poly = {poly[56:0],rx_data_i[i]};tempData[i] = xorBit;endend//解扰将数据输出;always@(posedge clk)beginif(rst)beginrx_data_o <= 'h0;descrambler <= 58'h155_5555_5555_5555;endelse if(rx_data_vld_i)beginrx_data_o <= tempData;descrambler <= poly;endend//解码数据相对于其他信号延迟一个时钟,为了对齐,把其他信号延迟一个时钟后输出。always@(posedge clk)beginrx_header_o <= rx_header_i;rx_header_vld_o <= rx_header_vld_i;rx_data_vld_o <= rx_data_vld_i;endendmodule

  自定义PHY顶层模块的仿真激励代码如下所示:

//--###############################################################################################
//--#
//--# File Name		: tb_phy_module
//--# Designer		: 数字站
//--# Tool			: Vivado 2021.1
//--# Design Date	: 2024.4.07
//--# Description	: TestBench
//--# Version		: 0.0
//--# Coding scheme	: GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
`timescale 1 ns/1 ns
module tb_phy_module();localparam	CYCLE		= 	10		        ;//系统时钟周期,单位ns,默认10ns;localparam	RST_TIME	= 	10		        ;//系统复位持续时间,默认10个系统时钟周期;localparam  TX_KEEP     =   8'b1111_1100    ;//发送最后一个数据的有效位数,大端对齐;reg			                clk             ;//系统时钟,默认100MHz;reg			                rst_n           ;//系统复位,默认低电平有效;reg         [4 : 0]         send_value      ;reg                         s_axi_valid     ;//数据有效指示信号,高电平有效;reg                         s_axi_last      ;//帧结束指示信号,高电平有效;reg         [63 : 0]        s_axi_data      ;//数据信号;reg         [7 : 0]         s_axi_keep      ;//数据掩码信号;wire                        rx_data_vld     ;//GTX的接收数据有效指示信号;wire                        rx_header_vld   ;//GTX的接收头部数据有效指示信号;wire                        rx_slipbit      ;//滑块信号,高电平有效;wire        [63 : 0]        tx_data         ;//GTX需要发送的数据;wire        [1 : 0]         tx_header       ;//GTX需要发送的头部数据;wire        [6 : 0]         tx_sequence     ;//GTX外部计数器;wire                        s_axi_ready     ;//接收数据应答信号;assign rx_data_vld = (tx_sequence != 32);assign rx_header_vld = rx_data_vld;phy_module u_phy_module(.rst            ( ~rst_n        ),.rx_clk		    ( clk		    ),//系统时钟信号;.rx_rst	        ( ~rst_n	    ),//系统复位信号,高电平有效;.rx_data        ( tx_data       ),//GTX的接收数据信号;.rx_data_vld    ( rx_data_vld   ),//GTX的接收数据有效指示信号;.rx_header      ( tx_header     ),//GTX的接收头部数据信号;.rx_header_vld  ( rx_header_vld ),//GTX的接收头部数据有效指示信号;.rx_slipbit     ( rx_slipbit    ),//滑块信号,高电平有效;.tx_clk         ( clk           ),//系统时钟信号;.tx_rst         ( ~rst_n        ),//系统复位信号,高电平有效;.tx_data        ( tx_data       ),//GTX需要发送的数据;.tx_header      ( tx_header     ),//GTX需要发送的头部数据;.tx_sequence    ( tx_sequence   ),//GTX外部计数器;.s_axi_valid    ( s_axi_valid   ),//数据有效指示信号,高电平有效;.s_axi_last     ( s_axi_last    ),//帧结束指示信号,高电平有效;.s_axi_data     ( s_axi_data    ),//数据信号;.s_axi_keep     ( s_axi_keep    ),//数据掩码信号;.s_axi_ready    ( s_axi_ready   ),//接收数据应答信号;.m_axi_data     (               ),//数据信号;.m_axi_keep     (               ),//数据掩码信号;.m_axi_last     (               ),//一帧数据的结束数据;.m_axi_valid    (               ) //数据有效指示信号;);//生成周期为CYCLE数值的系统时钟;initial beginclk = 0;forever #(CYCLE/2) clk = ~clk;end//生成复位信号;initial beginrst_n = 1;#2;rst_n = 0;//开始时复位10个时钟;#(RST_TIME*CYCLE);rst_n = 1;end//生成输入信号din;initial begins_axi_data  = 64'd0;s_axi_keep  = 8'd0;s_axi_last  = 1'd0;s_axi_valid = 1'd0;wait(rst_n);//等待复位完成;repeat(10) @(posedge clk);phy_tx_task(5);repeat(100) @(posedge clk);repeat(5) beginphy_tx_task(5);end@(posedge s_axi_ready);end//发送数据的任务;task phy_tx_task(input	[7 : 0]		len);begin : phy_tx_task_0integer i;s_axi_data  <= 64'd0;s_axi_keep  <= 8'hff;s_axi_last  <= 1'd0;s_axi_valid <= 1'd0;send_value <= 5'd1;@(posedge clk);wait(s_axi_ready);@(posedge clk);for(i=0 ; i<len ; i=i+1)begins_axi_data <= {{send_value[4:0],3'd0},{send_value[4:0],3'd1},{send_value[4:0],3'd2},{send_value[4:0],3'd3},{send_value[4:0],3'd4},{send_value[4:0],3'd5},{send_value[4:0],3'd6},{send_value[4:0],3'd7}};if(i == len - 1)begins_axi_last <= 1'b1;s_axi_keep <= TX_KEEP;endelse begins_axi_last <= 1'b0;s_axi_keep <= 8'hff;ends_axi_valid <= 1'b1;send_value <= send_value + 1;@(posedge clk);ends_axi_data  <= 64'd0;s_axi_keep  <= 8'hff;s_axi_last  <= 1'd0;s_axi_valid <= 1'd0;@(posedge clk);endendtaskendmodule

  将用户发送数据的尾端掩码设置为8’hc0,抓到发送数据和接收数据的时序如下图所示,一帧数据最后一个有效数据是8’h29,收发一致,证明发送数据、接收数据、加扰、解扰的逻辑设计均没有问题。

在这里插入图片描述

图2 自定义PHY的仿真时序

  将尾端数据掩码信号修改为8’hf0,对应的仿真时序如下图所示。接收和发送的最后一个有效字节数据均为8’h2b,表示收发数据均正确。

在这里插入图片描述

图3 自定义PHY仿真时序

  将发送数据的尾端掩码修改为8’hfc,对应的仿真时序如下图所示,接收和发送数据帧的最后一个有效字节数据均为2’h2d,表示收发数据时序均正确。

在这里插入图片描述

图4 自定义phy仿真时序

  其余情况有兴趣的可以自行仿真,在设计时对所有情况都做过仿真。因为本文并没有加入高速收发器进行联调,所以其余情况就不全部列出了。下文将所有模块联合并上板,到时候在将全部情况进行仿真。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/380305.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多口适配器,给您的生活增添便利

随着科技的快速发展&#xff0c;我们的生活已离不开各种各样的电子设备&#xff0c;智能手机、平板电脑、智能手表、无线耳机……它们共同构建了我们丰富多彩的数字生活。然而&#xff0c;面对众多设备的充电需求&#xff0c;传统的单一充电口已难以满足现代人的使用习惯。在这…

使用JWT双令牌机制进行接口请求鉴权

在前后端分离的开发过程中&#xff0c;前端发起请求&#xff0c;调用后端接口&#xff0c;后端在接收请求时&#xff0c;首先需要对收到的请求鉴权&#xff0c;在这种情况先我们可以采用JWT机制来鉴权。 JWT有两种机制&#xff0c;单令牌机制和双令牌机制。 单令牌机制服务端…

IDEA的详细设置

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …

《绝区零》是一款什么类型的游戏,Mac电脑怎么玩《绝区零》苹果电脑玩游戏怎么样

米哈游的《绝区零》最近在网上爆火呀&#xff0c;不过很多人都想知道mac电脑能不能玩《绝区零》&#xff0c;今天麦麦就给大家介绍一下《绝区零》是一款什么样的游戏&#xff0c;Mac电脑怎么玩《绝区零》。 一、《绝区零》是一款什么样的游戏 《绝区零》是由上海米哈游自主研发…

常见排序算法总结

文章目录 比较排序冒泡排序选择排序插入排序归并排序快速排序堆排序希尔排序 非比较排序&#xff08;桶排序&#xff09;计数排序基数排序 比较排序 冒泡排序 嵌套循环&#xff0c;每次内层循环执行时&#xff0c;数组的每两个元素交换&#xff0c;将一个最大/小的数排到数组…

技术成神之路:设计模式(八)责任链模式

介绍 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许多个对象依次处理请求&#xff0c;避免请求的发送者和接收者之间的显式耦合。该模式通过将多个可能处理请求的对象连接成一条链&#xff0c;并沿着这条链传递请求…

达梦数据库 DISQL连接数据库与执行SQL、脚本的方法

DISQL连接数据库与执行SQL、脚本的方法 1.DISQL介绍2.DISQL连接数据库的方法2.1 本地连接2.2 远程连接2.3 CONN连接 3.执行SQL、脚本的方法3.1 通过DISQL登录后在字符界面3.2 启动DISQL时运行脚本3.3 进入DISQL后&#xff0c;通过start命令运行脚本3.4 使用EDIT命令编辑脚本 1.…

ubuntu 24 PXE Server (bios+uefi) 批量部署系统

pxe server 前言 PXE&#xff08;Preboot eXecution Environment&#xff0c;预启动执行环境&#xff09;是一种网络启动协议&#xff0c;允许计算机通过网络启动而不是使用本地硬盘。PXE服务器是实现这一功能的服务器&#xff0c;它提供了启动镜像和引导加载程序&#xff0c;…

解决npm install(‘proxy‘ config is set properly. See: ‘npm help config‘)失败问题

摘要 重装电脑系统后&#xff0c;使用npm install初始化项目依赖失败了&#xff0c;错误提示&#xff1a;‘proxy’ config is set properly…&#xff0c;具体的错误提示如下图所示&#xff1a; 解决方案 经过报错信息查询解决办法&#xff0c;最终找到了两个比较好的方案&a…

git commit报错: pre-commit hook failed (add --no-verify to bypass)

原因&#xff1a; 在提交前做代码风格检查&#xff0c;若检查不通过&#xff0c;则提交失败 解决方案&#xff1a;进入项目的.git>hooks目录&#xff0c;找到pre-commit文件&#xff0c;删除即可

【银河麒麟服务器操作系统】java进程oom现象分析及处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问麒麟软件产品专区&#xff1a;https://product.kylinos.cn 现象描述 某服务器系统升级内核至4.19.90-25.22.v2101版本后仍会触发oom导致java进程被kill。 现象分析 oom现象分析 系统messages日志分析&#xff0c;故…

python--实验15 数据分析与可视化

目录 知识点 1 数据分析概述 1.1流程 1.2定义 1.3数据分析常用工具 2 科学计算 2.1numpy 2.1.1定义 2.1.2创建数组的方式 2.1.3np.random的随机数函数 3 数据可视化 3.1定义 3.2基本思想 3.3Matplotlib库 3.3.1模块 4 数据分析 4.1Pandas 4.2数据结构 4.3基…

html+canvas 实现签名功能-手机触摸

手机上的效果图 需要注意&#xff0c;手机触摸和鼠标不是一个事件&#xff0c;不能通用&#xff0c;上一篇是关于使用鼠标的样例 相关代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewpo…

Large Language Model系列之一:语言模型与表征学习(Language Models and Representation Learning)

语言模型与表征学习&#xff08;Language Models and Representation Learning&#xff09; 1 语言模型 N-Gram模型 from collections import defaultdictsentences [The swift fox jumps over the lazy dog.,The swift river flows under the ancient bridge.,The swift br…

Java关于JDBC的理解

JDBC Java Database Connectivity&#xff1a;意为Java数据库连接。是Java提供的一组独立于任何数据库管理系统的API。Java提供接口规范&#xff0c;由各个数据库厂商提供接口的实现&#xff0c;厂商提供的实现类封装成jar文件&#xff0c;也就是我们俗称的数据库驱动jar包。我…

PyTorch张量数值计算

文章目录 1、张量基本运算2、阿达玛积3、点积运算4、指定运算设备⭐5、解决在GPU运行PyTorch的问题 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&am…

LDR6020:重塑iPad一体式有线键盘体验的创新力量

在移动办公与娱乐日益融合的时代&#xff0c;iPad凭借其强大的性能和便携性&#xff0c;成为了众多用户不可或缺的生产力工具。然而&#xff0c;为了进一步提升iPad的使用体验&#xff0c;一款高效、便捷的键盘成为了不可或缺的配件。今天&#xff0c;我们要介绍的&#xff0c;…

云计算复习--虚拟化技术

文章目录 虚拟化技术定义与原理虚拟机监视器&#xff08;VMM&#xff09;虚拟化技术服务器虚拟化存储虚拟化网络虚拟化应用虚拟化 关键技术新型虚拟化技术发展进展作业 虚拟化技术定义与原理 定义&#xff1a;虚拟化技术是一种将计算机物理实体&#xff08;如服务器、存储设备…

【BUG】已解决:OSError: [Errno 22] Invalid argument

已解决&#xff1a;OSError: [Errno 22] Invalid argument 目录 已解决&#xff1a;OSError: [Errno 22] Invalid argument 【常见模块错误】 错误原因&#xff1a; 解决方法如下&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&…

利用AI辅助制作ppt封面

如何利用AI辅助制作一个炫酷的PPT封面 标题使用镂空字背景替换为动态视频 标题使用镂空字 1.首先&#xff0c;新建一个空白的ppt页面&#xff0c;插入一张你认为符合主题的图片&#xff0c;占满整个可视页面。 2.其次&#xff0c;插入一个矩形&#xff0c;右键选择设置形状格式…