UDP--DDR--SFP,FPGA实现之模块梳理及AXI读写DDR读写上板测试
模块梳理介绍
在之前的几篇文章中,笔者详细介绍了整个项目的框架结构以及部分关键模块的实现细节。这些模块包括UDP协议栈、UDP指令监测、数据跨时钟域处理、DDR读写控制、内存读取控制以及DDR AXI控制器等。这些模块共同构成了项目的基础架构,每个模块都经过精心设计和实现,以确保系统的稳定性和高效性。
鉴于后续的GT收发器功能模块配置相对简单,而之前的模块已经形成了一定的体系规模,笔者现在将对这些模块进行功能联调,以实现全面的仿真测试。功能联调是确保各个模块能够协同工作的重要步骤,通过仿真测试可以验证模块之间的接口是否匹配,数据传输是否准确,以及整体系统是否能够按照预期运行。
而对于UDP协议栈的仿真,由于在之前的专栏已经较为详尽,在本章节中,便不再进行仿真,而是直接模拟UDP数据的发送,对于MIG核笔者同样不进行仿真,考虑到移植仿真文件比较麻烦,不如在验证AXI的正确性后,直接进行上板验证。
模块整体结构代码
module k7325t_top(input i_sysclk ,/*sfp*/input i_gtrefclk_p ,input i_gtrefclk_n ,output o_gt_tx_p ,output o_gt_tx_n ,input i_gt_rx_p ,input i_gt_rx_n ,output [1 :0] o_sfp_disable ,input i_rxc ,input [3 :0] i_rxd ,input i_rx_ctl ,output o_txc ,output [3 :0] o_txd ,output o_tx_ctl ,output phy_rst ,/*ddr*/output [14:0] ddr3_addr ,output [2 :0] ddr3_ba ,output ddr3_cas_n ,output [0 :0] ddr3_ck_n ,output [0 :0] ddr3_ck_p ,output [0 :0] ddr3_cke ,output ddr3_ras_n ,output ddr3_reset_n ,output ddr3_we_n ,inout [31:0] ddr3_dq ,inout [3 :0] ddr3_dqs_n ,inout [3 :0] ddr3_dqs_p ,output [0 :0] ddr3_cs_n ,output [3 :0] ddr3_dm ,output [0 :0] ddr3_odt );
wire w_udp_clk ;
wire w_udp_rst ;
wire w_sfp_clk ;
wire w_sfp_rst ;
wire [15:0] w_udp_len ;
wire [7 :0] w_udp_data ;
wire w_udp_last ;
wire w_udp_valid ;
wire [31:0] w_send_data ;
wire w_send_valid ;
assign phy_rst = 1'b1;
wire w_sys_clk ;
wire w_ddr_clk ;
wire w_locked ;
wire w_ui_clk ;
wire w_ui_rst ;
wire [1 :0] w_op_cmd ;
wire [29:0] w_op_waddr ;
wire [29:0] w_op_raddr ;
wire w_op_valid ;
wire w_op_ready ;
wire [31:0] w_write_data ;
wire w_write_valid ;
wire [31:0] w_read_data ;
wire w_read_valid ;wire w_read_cmd ;
wire [7 :0] w_store_udp_data ;
wire w_store_udp_valid;
wire w_store_done ;
wire w_raddr_clear ;
wire w_sync_clear ;
wire [15:0] w_store_size ;
wire w_read_back ;
wire [31:0] w_sfp_data ;
wire w_sfp_valid ;/*生成全局时钟*/
clk_gen clk_gen_u0(.clk_out2 (w_ddr_clk ),.clk_out1 (w_sys_clk ),.locked (w_locked ),.clk_in1 (i_sysclk ));/*UDP协议栈*/
udp_module udp_module_u0(.i_rxc (i_rxc ),.i_rxd (i_rxd ),.i_rx_ctl (i_rx_ctl ),.o_txc (o_txc ),.o_txd (o_txd ),.o_tx_ctl (o_tx_ctl ),.o_udp_clk (w_udp_clk ),.o_udp_rst (w_udp_rst ),.o_rec_len (w_udp_len ),.o_rec_data (w_udp_data ),.o_rec_last (w_udp_last ),.o_rec_valid (w_udp_valid )
);/*指令监测,输出监测后数据*/
udp_cmd_check udp_cmd_check_u0(.i_clk (w_udp_clk ),.i_rst (w_udp_rst ),.i_udp_data (w_udp_data ),.i_udp_valid (w_udp_valid ),.o_udp_data (w_store_udp_data ),.o_udp_valid (w_store_udp_valid ),.o_store_done (w_store_done ),.o_raddr_clear (w_raddr_clear ));/*跨时钟域处理,1Byte-->4Bytes,udp-->ddr*/
ASYNC_BUF_DDR ASYNC_BUF_DDR_U0(.i_udp_clk (w_udp_clk ),.i_udp_rst (w_udp_rst ),.i_ui_clk (w_ui_clk ),.i_ui_rst (w_ui_rst ),.i_udp_data (w_store_udp_data ),.i_udp_valid (w_store_udp_valid ),.o_send_data (w_send_data ),.o_send_valid (w_send_valid ));/*读取地址清除信号跨时钟*/
sync_s2f sync_s2f_u0(.i_clk_slow (w_udp_clk ),.i_signal (w_raddr_clear ),.i_clk_fast (w_ui_clk ),.o_sync (w_sync_clear )
);/*内存读取控制器*/
read_memory_ctrl read_memory_ctrl_u0(.i_ui_clk (w_ui_clk ),.i_ui_rst (w_ui_rst ),.i_sfp_clk (w_sfp_clk ),.i_sfp_rst (w_sfp_rst ),.i_store_done (w_store_done ),.i_store_size (w_store_size ),.i_raddr_clear (w_sync_clear ),.o_read_back (w_read_back ),.o_read_cmd (w_read_cmd ),.i_read_data (w_read_data ),.i_read_valid (w_read_valid ),.o_sfp_data (w_sfp_data ),.o_sfp_valid (w_sfp_valid ));/*ddr读写控制器*/
ddr_rw_control ddr_rw_control_u0(.i_ui_clk (w_ui_clk ),.i_ui_rst (w_ui_rst ),.i_send_data (w_send_data ),.i_send_valid (w_send_valid ),.i_read_cmd (w_read_cmd ),.i_raddr_clear (w_sync_clear ),.i_read_back (w_read_back ),.o_store_size (w_store_size ),.o_op_cmd (w_op_cmd ),.o_op_waddr (w_op_waddr ),.o_op_raddr (w_op_raddr ),.o_op_valid (w_op_valid ),.i_op_ready (w_op_ready ),.o_write_data (w_write_data ),.o_write_valid (w_write_valid ),.i_read_data (w_read_data ),.i_read_valid (w_read_valid ));/*ddr axi读写驱动*/
ddr_top ddr_top_u0(.i_ddr_clk (w_ddr_clk ),.i_ddr_rstn (w_locked ),.ddr3_addr (ddr3_addr ),.ddr3_ba (ddr3_ba ),.ddr3_cas_n (ddr3_cas_n ),.ddr3_ck_n (ddr3_ck_n ),.ddr3_ck_p (ddr3_ck_p ),.ddr3_cke (ddr3_cke ),.ddr3_ras_n (ddr3_ras_n ),.ddr3_reset_n (ddr3_reset_n ),.ddr3_we_n (ddr3_we_n ),.ddr3_dq (ddr3_dq ),.ddr3_dqs_n (ddr3_dqs_n ),.ddr3_dqs_p (ddr3_dqs_p ),.ddr3_cs_n (ddr3_cs_n ),.ddr3_dm (ddr3_dm ),.ddr3_odt (ddr3_odt ),.ui_clk (w_ui_clk ),.ui_clk_sync_rst (w_ui_rst ),.i_op_cmd (w_op_cmd ),.i_op_waddr (w_op_waddr ),.i_op_raddr (w_op_raddr ),.i_op_valid (w_op_valid ),.o_op_ready (w_op_ready ),.i_write_data (w_write_data ),.i_write_valid (w_write_valid ),.o_read_data (w_read_data ),.o_read_valid (w_read_valid ));/*光纤传输器*/
gt_one_top gt_one_top_u0(.i_sysclk (w_sys_clk ),.i_gtrefclk_p (i_gtrefclk_p ),.i_gtrefclk_n (i_gtrefclk_n ),.o_gt_tx_p (o_gt_tx_p ),.o_gt_tx_n (o_gt_tx_n ),.i_gt_rx_p (i_gt_rx_p ),.i_gt_rx_n (i_gt_rx_n ),.o_sfp_disable (o_sfp_disable ),.o_sfp_txclk (w_sfp_clk ),.o_sfp_txrst (w_sfp_rst ),.i_send_data (w_sfp_data ),.i_send_valid (w_sfp_valid ));
整体模块仿真(不包含GT收发器部分)
那么接下来便进行仿真流程的梳理
- 模拟UDP接收到500K数据,在数据文件下发前,发送擦除指令,在数据文件下发后,发送传输完成指令
- UDP指令监测模块对输入的UDP模拟数据做解析,解析出指令或是数据
- 数据跨时钟模块接收指令监测模块输出的数据,进行位宽转换和跨时钟处理
- 单次输出1K数据到DDR读写控制模块,DDR读写控制模块传输数据至DDR_AXI控制器
- DDR_AXI控制器转译OP总线指令,转换为AXI总线,进行文件数据写入
- 内存读取控制模块监测文件传输完成指令,控制DDR读写控制模块,进行文件循环读取
- 仿真激励代码如下
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/05/09 09:32:42
// Design Name:
// Module Name: tb_module
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module tb_module();reg i_udp_clk = 1'b0;
reg i_udp_rst = 1'b0;
reg i_ui_clk = 1'b0;
reg i_ui_rst = 1'b0;
reg i_sfp_clk = 1'b0;
reg i_sfp_rst = 1'b0;
reg [7 :0] i_udp_data = 8'd0;
reg i_udp_valid = 1'd0;
reg i_rcmd = 1'b0;
wire [7 :0] w_store_udp_data ;
wire w_store_udp_valid ;
wire w_store_done ;
wire w_raddr_clear ;
wire w_sync_clear ;
wire w_read_cmd ;
reg [31:0] r_read_data = 32'd0;
reg r_read_valid = 1'd0 ;
wire [31:0] w_sfp_data ;
wire w_sfp_valid ;
wire [31:0] w_send_data ;
wire w_send_valid ;
wire [1 :0] w_op_cmd ;
wire [29:0] w_op_waddr ;
wire [29:0] w_op_raddr ;
wire w_op_valid ;
wire [31:0] w_write_data ;
wire w_write_valid ;
wire [15:0] w_store_size ;integer i = 0;
integer j = 0;
always #4 i_udp_clk = ~i_udp_clk;
always #2.5 i_ui_clk = ~i_ui_clk ;
always #2 i_sfp_clk = ~i_sfp_clk;
initial begini_udp_rst = 1;i_sfp_rst = 1;i_ui_rst = 1;#100@(i_sfp_clk) begini_udp_rst <= 1'b0;i_sfp_rst <= 1'b0;i_ui_rst <= 1'b0;end#100/*传输擦除指令*/@(posedge i_udp_clk)udp_cmd(64'HD5D5D5D5_FCFCFCFC);/*传输200KB*/@(posedge i_udp_clk)for(i = 0;i < 300; i = i + 1) begin@(posedge i_udp_clk)udp_send(1024);#500@(posedge i_udp_clk);end/*传输完成指令*/@(posedge i_udp_clk)udp_cmd(64'HA5A5A5A5_BCBCBCBC);
end/*指令监测,输出监测后数据*/
udp_cmd_check udp_cmd_check_u0(.i_clk (i_udp_clk ),.i_rst (i_udp_rst ),.i_udp_data (i_udp_data ),.i_udp_valid (i_udp_valid ),.o_udp_data (w_store_udp_data ),.o_udp_valid (w_store_udp_valid ),.o_store_done (w_store_done ),.o_raddr_clear (w_raddr_clear ));/*跨时钟域处理,1Byte-->4Bytes,udp-->ddr*/
ASYNC_BUF_DDR ASYNC_BUF_DDR_U0(.i_udp_clk (i_udp_clk ),.i_udp_rst (i_udp_rst ),.i_ui_clk (i_ui_clk ),.i_ui_rst (i_ui_rst ),.i_udp_data (w_store_udp_data ),.i_udp_valid (w_store_udp_valid ),.o_send_data (w_send_data ),.o_send_valid (w_send_valid ));/*读取地址清除信号跨时钟*/
sync_s2f sync_s2f_u0(.i_clk_slow (i_udp_clk ),.i_signal (w_raddr_clear ),.i_clk_fast (i_ui_clk ),.o_sync (w_sync_clear )
);ddr_rw_control ddr_rw_control_u0(.i_ui_clk (i_ui_clk ),.i_ui_rst (i_ui_rst ),.i_send_data (w_send_data ),.i_send_valid (w_send_valid ),.i_read_cmd (i_rcmd ),.i_raddr_clear (w_sync_clear ),.i_read_back (1'b0 ),.o_store_size (w_store_size ),.o_op_cmd (w_op_cmd ),.o_op_waddr (w_op_waddr ),.o_op_raddr (w_op_raddr ),.o_op_valid (w_op_valid ),.i_op_ready (1'b1 ),.o_write_data (w_write_data ),.o_write_valid (w_write_valid ),.i_read_data (32'd0 ),.i_read_valid (1'b0 ));always @(posedge i_ui_clk) beginif (w_read_cmd) beginddr_data(256);end
end/*内存读取控制器*/
read_memory_ctrl read_memory_ctrl_u0(.i_ui_clk (i_ui_clk ),.i_ui_rst (i_ui_rst ),.i_sfp_clk (i_sfp_clk ),.i_sfp_rst (i_sfp_rst ),.i_store_done (w_store_done ),.i_store_size (w_store_size ),.i_raddr_clear (w_sync_clear ),.o_read_cmd (w_read_cmd ),.i_read_data (r_read_data ),.i_read_valid (r_read_valid ),.o_sfp_data (w_sfp_data ),.o_sfp_valid (w_sfp_valid ));task udp_send(input [15:0] byte_len);begin : datainteger i;i_udp_data = 8'd0;i_udp_valid = 1'd0;@(posedge i_udp_clk);for(i = 0;i < byte_len ;i = i + 1)begini_udp_data <= i_udp_data + 1'b1;i_udp_valid <= 1'b1;@(posedge i_udp_clk);endi_udp_data <= 8'd0;i_udp_valid <= 1'd0;
end
endtasktask udp_cmd(input [63:0] i_cmd);begin : cmdinteger i;i_udp_data = 8'd0;i_udp_valid = 1'd0;@(posedge i_udp_clk);for(i = 0;i < 8 ;i = i + 1)begini_udp_data <= i_cmd[63:56];i_cmd <= {i_cmd[55:0],8'h0};i_udp_valid <= 1'b1;@(posedge i_udp_clk);endi_udp_data <= 8'd0;i_udp_valid <= 1'd0;
end
endtasktask ddr_data(input [15:0] byte_len);begin : ddrinteger i;r_read_data = 32'd0;r_read_valid = 1 'd0;@(posedge i_ui_clk);for(i = 0;i < 256 ;i = i + 1)beginr_read_data <= r_read_data + 1'b1;r_read_valid <= 1'b1;@(posedge i_ui_clk);endr_read_data = 32'd0;r_read_valid = 1 'd0;
end
endtaskendmodule
上述测试流程实际是对之前文章的测试进行了总结,所以在此,便不进行贴图展示结果了。
接下来,将进行AXI读写DDR的上板测试,如下所示,是笔者写的一个DDR模块顶层代码,实际是,将AXI读写DDR的控制器的op总线部分交互变为一与个可控模块进行交互,通过vio控制可控模块进行数据总线输出,读写DDR。
AXI接口的MIG核读写DDR上板测试
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/25 15:17:48
// Design Name:
// Module Name: ddr_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module ddr_top(// input i_ddr_clk ,// input i_ddr_rstn ,input i_sysclk ,output [14:0] ddr3_addr ,output [2 :0] ddr3_ba ,output ddr3_cas_n ,output [0 :0] ddr3_ck_n ,output [0 :0] ddr3_ck_p ,output [0 :0] ddr3_cke ,output ddr3_ras_n ,output ddr3_reset_n ,output ddr3_we_n ,inout [31:0] ddr3_dq ,inout [3 :0] ddr3_dqs_n ,inout [3 :0] ddr3_dqs_p ,output [0 :0] ddr3_cs_n ,output [3 :0] ddr3_dm ,output [0 :0] ddr3_odt // output ui_clk ,// output ui_clk_sync_rst ,// input [1 :0] i_op_cmd ,// input [29:0] i_op_waddr ,// input [29:0] i_op_raddr ,// input i_op_valid ,// output o_op_ready ,// input [31:0] i_write_data ,// input i_write_valid ,// output [31:0] o_read_data ,// output o_read_valid );(*mark_debug = "true"*)wire init_calib_complete ;
wire w_ui_clk_sync_rst ;
wire [3 :0] M_AXI_AWID ;
(*mark_debug = "true"*)wire [29:0] M_AXI_AWADDR ;
(*mark_debug = "true"*)wire [7 :0] M_AXI_AWLEN ;
wire [2 :0] M_AXI_AWSIZE ;
wire [1 :0] M_AXI_AWBURST ;
wire [0 :0] M_AXI_AWLOCK ;
wire [3 :0] M_AXI_AWCACHE ;
wire [2 :0] M_AXI_AWPROT ;
wire [3 :0] M_AXI_AWQOS ;
(*mark_debug = "true"*)wire M_AXI_AWVALID ;
(*mark_debug = "true"*)wire M_AXI_AWREADY ;
(*mark_debug = "true"*)wire [31:0] M_AXI_WDATA ;
(*mark_debug = "true"*)wire [3 :0] M_AXI_WSTRB ;
(*mark_debug = "true"*)wire M_AXI_WLAST ;
(*mark_debug = "true"*)wire M_AXI_WVALID ;
wire M_AXI_WREADY ;
wire [3 :0] M_AXI_BID ;
wire [1 :0] M_AXI_BRESP ;
wire M_AXI_BVALID ;
wire M_AXI_BREADY ;
wire [3 :0] M_AXI_ARID ;
(*mark_debug = "true"*)wire [29:0] M_AXI_ARADDR ;
(*mark_debug = "true"*)wire [7 :0] M_AXI_ARLEN ;
wire [2 :0] M_AXI_ARSIZE ;
wire [1 :0] M_AXI_ARBURST ;
wire [0 :0] M_AXI_ARLOCK ;
wire [3 :0] M_AXI_ARCACHE ;
wire [2 :0] M_AXI_ARPROT ;
wire [3 :0] M_AXI_ARQOS ;
(*mark_debug = "true"*)wire M_AXI_ARVALID ;
(*mark_debug = "true"*)wire M_AXI_ARREADY ;
wire [3 :0] M_AXI_RID ;
(*mark_debug = "true"*)wire [31:0] M_AXI_RDATA ;
(*mark_debug = "true"*)wire [1 :0] M_AXI_RRESP ;
(*mark_debug = "true"*)wire M_AXI_RLAST ;
(*mark_debug = "true"*)wire M_AXI_RVALID ;
wire M_AXI_RREADY ;wire [0 :0] M_AXI_AWUSER ;
wire [0 :0] M_AXI_WUSER ;
wire [0 :0] M_AXI_BUSER ;
wire [0 :0] M_AXI_ARUSER ;
wire [0 :0] M_AXI_RUSER ;
wire w_ddr_clk ;
wire w_locked ;
wire [1 :0] w_op_cmd ;
wire [29:0] w_op_waddr ;
wire [29:0] w_op_raddr ;
wire w_op_valid ;
wire w_op_ready ;
wire [31:0] w_write_data ;
wire w_write_valid ;
wire [31:0] w_read_data ;
wire w_read_valid ;
/*生成全局时钟*/
clk_gen clk_gen_u0(.clk_out2 (w_ddr_clk ),.clk_out1 ( ),.locked (w_locked ),.clk_in1 (i_sysclk ));
wire ui_clk ;
// assign ui_clk_sync_rst = w_ui_clk_sync_rst;wire i_wcmd ;
wire i_rcmd ;
vio_0 vio_0_u0 (.clk (ui_clk),.probe_out0 (i_wcmd),.probe_out1 (i_rcmd)
);rw_fsm_gen rw_fsm_gen_u0(.i_clk (ui_clk ),.i_rst (w_ui_clk_sync_rst ),.i_wcmd (i_wcmd ),.i_rcmd (i_rcmd ),.o_can_cmd (),.o_op_cmd (w_op_cmd ),.o_op_waddr (w_op_waddr ),.o_op_raddr (w_op_raddr ),.o_op_valid (w_op_valid ),.i_op_ready (w_op_ready ),.o_write_data (w_write_data ),.o_write_valid (w_write_valid ),.i_read_data (w_read_data ),.i_read_valid (w_read_valid ));ddr_axi_rw#(.C_M_TARGET_SLAVE_BASE_ADDR (32'h00000000 ),.C_M_AXI_BURST_LEN (256 ),.C_M_AXI_ID_WIDTH (3 ),.C_M_AXI_ADDR_WIDTH (30 ),.C_M_AXI_DATA_WIDTH (32 ),.C_M_AXI_AWUSER_WIDTH (1 ),.C_M_AXI_ARUSER_WIDTH (1 ),.C_M_AXI_WUSER_WIDTH (1 ),.C_M_AXI_RUSER_WIDTH (1 ),.C_M_AXI_BUSER_WIDTH (1 )
)ddr_axi_rw_u0(.init_calib_complete (init_calib_complete),.i_op_cmd (w_op_cmd ),.i_op_waddr (w_op_waddr ),.i_op_raddr (w_op_raddr ),.i_op_valid (w_op_valid ),.o_op_ready (w_op_ready ),.i_write_data (w_write_data ),.i_write_valid (w_write_valid ),.o_read_data (w_read_data ),.o_read_valid (w_read_valid ),.M_AXI_ACLK (ui_clk ),.M_AXI_ARESETN (~w_ui_clk_sync_rst ),.M_AXI_AWID (M_AXI_AWID ),.M_AXI_AWADDR (M_AXI_AWADDR ),.M_AXI_AWLEN (M_AXI_AWLEN ),.M_AXI_AWSIZE (M_AXI_AWSIZE ),.M_AXI_AWBURST (M_AXI_AWBURST ),.M_AXI_AWLOCK (M_AXI_AWLOCK ),.M_AXI_AWCACHE (M_AXI_AWCACHE ),.M_AXI_AWPROT (M_AXI_AWPROT ),.M_AXI_AWQOS (M_AXI_AWQOS ),.M_AXI_AWUSER (M_AXI_AWUSER ),.M_AXI_AWVALID (M_AXI_AWVALID ),.M_AXI_AWREADY (M_AXI_AWREADY ),.M_AXI_WDATA (M_AXI_WDATA ),.M_AXI_WSTRB (M_AXI_WSTRB ),.M_AXI_WLAST (M_AXI_WLAST ),.M_AXI_WUSER (M_AXI_WUSER ),.M_AXI_WVALID (M_AXI_WVALID ),.M_AXI_WREADY (M_AXI_WREADY ),.M_AXI_BID (M_AXI_BID ),.M_AXI_BRESP (M_AXI_BRESP ),.M_AXI_BUSER (M_AXI_BUSER ),.M_AXI_BVALID (M_AXI_BVALID ),.M_AXI_BREADY (M_AXI_BREADY ), .M_AXI_ARID (M_AXI_ARID ),.M_AXI_ARADDR (M_AXI_ARADDR ),.M_AXI_ARLEN (M_AXI_ARLEN ),.M_AXI_ARSIZE (M_AXI_ARSIZE ),.M_AXI_ARBURST (M_AXI_ARBURST ),.M_AXI_ARLOCK (M_AXI_ARLOCK ),.M_AXI_ARCACHE (M_AXI_ARCACHE ),.M_AXI_ARPROT (M_AXI_ARPROT ),.M_AXI_ARQOS (M_AXI_ARQOS ),.M_AXI_ARUSER (M_AXI_ARUSER ),.M_AXI_ARVALID (M_AXI_ARVALID ),.M_AXI_ARREADY (M_AXI_ARREADY ),.M_AXI_RID (M_AXI_RID ),.M_AXI_RDATA (M_AXI_RDATA ),.M_AXI_RRESP (M_AXI_RRESP ),.M_AXI_RLAST (M_AXI_RLAST ),.M_AXI_RUSER (M_AXI_RUSER ),.M_AXI_RVALID (M_AXI_RVALID ),.M_AXI_RREADY (M_AXI_RREADY ) );mig_7series_0 u_mig_axi (.ddr3_addr (ddr3_addr ), // output [14:0] ddr3_addr.ddr3_ba (ddr3_ba ), // output [2:0] ddr3_ba.ddr3_cas_n (ddr3_cas_n ), // output ddr3_cas_n.ddr3_ck_n (ddr3_ck_n ), // output [0:0] ddr3_ck_n.ddr3_ck_p (ddr3_ck_p ), // output [0:0] ddr3_ck_p.ddr3_cke (ddr3_cke ), // output [0:0] ddr3_cke.ddr3_ras_n (ddr3_ras_n ), // output ddr3_ras_n.ddr3_reset_n (ddr3_reset_n ), // output ddr3_reset_n.ddr3_we_n (ddr3_we_n ), // output ddr3_we_n.ddr3_dq (ddr3_dq ), // inout [31:0] ddr3_dq.ddr3_dqs_n (ddr3_dqs_n ), // inout [3:0] ddr3_dqs_n.ddr3_dqs_p (ddr3_dqs_p ), // inout [3:0] ddr3_dqs_p.ddr3_cs_n (ddr3_cs_n ), // output [0:0] ddr3_cs_n.ddr3_dm (ddr3_dm ), // output [3:0] ddr3_dm.ddr3_odt (ddr3_odt ), // output [0:0] ddr3_odt// Application interface ports .ui_clk (ui_clk ), // output ui_clk.ui_clk_sync_rst (w_ui_clk_sync_rst ), // output ui_clk_sync_rst.init_calib_complete (init_calib_complete ), // output init_calib_complete.mmcm_locked ( ), // output mmcm_locked.app_sr_req (0 ), // input app_sr_req.app_ref_req (0 ), // input app_ref_req.app_zq_req (0 ), // input app_zq_req.app_sr_active ( ), // output app_sr_active.app_ref_ack ( ), // output app_ref_ack.app_zq_ack ( ), // output app_zq_ack.aresetn (~ui_clk_sync_rst ), // input aresetn.s_axi_awid (M_AXI_AWID ), // input [3:0] s_axi_awid.s_axi_awaddr (M_AXI_AWADDR ), // input [29:0] s_axi_awaddr.s_axi_awlen (M_AXI_AWLEN ), // input [7:0] s_axi_awlen.s_axi_awsize (M_AXI_AWSIZE ), // input [2:0] s_axi_awsize.s_axi_awburst (M_AXI_AWBURST ), // input [1:0] s_axi_awburst.s_axi_awlock (M_AXI_AWLOCK ), // input [0:0] s_axi_awlock.s_axi_awcache (M_AXI_AWCACHE ), // input [3:0] s_axi_awcache.s_axi_awprot (M_AXI_AWPROT ), // input [2:0] s_axi_awprot.s_axi_awqos (M_AXI_AWQOS ), // input [3:0] s_axi_awqos.s_axi_awvalid (M_AXI_AWVALID ), // input s_axi_awvalid.s_axi_awready (M_AXI_AWREADY ), // output s_axi_awready.s_axi_wdata (M_AXI_WDATA ), // input [255:0] s_axi_wdata.s_axi_wstrb (M_AXI_WSTRB ), // input [31:0] s_axi_wstrb.s_axi_wlast (M_AXI_WLAST ), // input s_axi_wlast.s_axi_wvalid (M_AXI_WVALID ), // input s_axi_wvalid.s_axi_wready (M_AXI_WREADY ), // output s_axi_wready.s_axi_bid (M_AXI_BID ), // output [3:0] s_axi_bid.s_axi_bresp (M_AXI_BRESP ), // output [1:0] s_axi_bresp.s_axi_bvalid (M_AXI_BVALID ), // output s_axi_bvalid.s_axi_bready (M_AXI_BREADY ), // input s_axi_bready.s_axi_arid (M_AXI_ARID ), // input [3:0] s_axi_arid.s_axi_araddr (M_AXI_ARADDR ), // input [29:0] s_axi_araddr.s_axi_arlen (M_AXI_ARLEN ), // input [7:0] s_axi_arlen.s_axi_arsize (M_AXI_ARSIZE ), // input [2:0] s_axi_arsize.s_axi_arburst (M_AXI_ARBURST ), // input [1:0] s_axi_arburst.s_axi_arlock (M_AXI_ARLOCK ), // input [0:0] s_axi_arlock.s_axi_arcache (M_AXI_ARCACHE ), // input [3:0] s_axi_arcache.s_axi_arprot (M_AXI_ARPROT ), // input [2:0] s_axi_arprot.s_axi_arqos (M_AXI_ARQOS ), // input [3:0] s_axi_arqos.s_axi_arvalid (M_AXI_ARVALID ), // input s_axi_arvalid.s_axi_arready (M_AXI_ARREADY ), // output s_axi_arready.s_axi_rid (M_AXI_RID ), // output [3:0] s_axi_rid.s_axi_rdata (M_AXI_RDATA ), // output [255:0] s_axi_rdata.s_axi_rresp (M_AXI_RRESP ), // output [1:0] s_axi_rresp.s_axi_rlast (M_AXI_RLAST ), // output s_axi_rlast.s_axi_rvalid (M_AXI_RVALID ), // output s_axi_rvalid.s_axi_rready (M_AXI_RREADY ), // input s_axi_rready.sys_clk_i (w_ddr_clk ),.clk_ref_i (w_ddr_clk ),.sys_rst (w_locked ) // input sys_rst 低有效
);
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/25 15:57:46
// Design Name:
// Module Name: rw_fsm_gen
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module rw_fsm_gen(input i_clk ,input i_rst ,input i_wcmd ,input i_rcmd ,output o_can_cmd ,output [1 :0] o_op_cmd ,output [29:0] o_op_waddr ,output [29:0] o_op_raddr ,output o_op_valid ,input i_op_ready ,output [31:0] o_write_data ,output o_write_valid ,input [31:0] i_read_data ,input i_read_valid);reg ri_wcmd ;
reg ri_rcmd ;
reg [1 :0] ro_op_cmd ;
reg [29:0] ro_op_waddr ;
reg [29:0] ro_op_raddr ;
reg ro_op_valid ;
reg ri_op_ready ;
reg [31:0] ro_write_data ;
reg ro_write_valid ;
reg [15:0] r_write_cnt ;
wire wcmd_pos ;
wire rcmd_pos ;localparam P_WADDR = 4*256 ;
localparam P_RADDR = 4*256 ;assign wcmd_pos = ~ri_wcmd & i_wcmd ;
assign rcmd_pos = ~ri_rcmd & i_rcmd ;
assign o_op_cmd = ro_op_cmd ;
assign o_op_waddr = ro_op_waddr ;
assign o_op_raddr = ro_op_raddr ;
assign o_op_valid = ro_op_valid ;
assign o_write_data = ro_write_data ;
assign o_write_valid = ro_write_valid ;
assign o_can_cmd = ~ro_write_valid & ~ i_read_valid;always @(posedge i_clk,posedge i_rst) beginif(i_rst) beginri_wcmd <= 1'b0;ri_rcmd <= 1'b0;ri_op_ready <= 1'b0;endelse beginri_wcmd <= i_wcmd;ri_rcmd <= i_rcmd;ri_op_ready <= i_op_ready;end
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)ro_op_cmd <= 2'b00;else if(wcmd_pos)ro_op_cmd <= 2'b01;else if(rcmd_pos)ro_op_cmd <= 2'b10;else if(ro_op_valid && ri_op_ready)ro_op_cmd <= 2'b00;
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)ro_op_valid <= 1'b0;else if(ro_op_valid && ri_op_ready)ro_op_valid <= 1'b0;else if(~ro_op_valid && wcmd_pos)ro_op_valid <= 1'b1;else if(~ro_op_valid && rcmd_pos)ro_op_valid <= 1'b1;
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)ro_op_waddr <= 'd0;else if(ro_op_valid && ri_op_ready && ro_op_cmd == 2'b01)ro_op_waddr <= ro_op_waddr + P_WADDR;
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)ro_op_raddr <= 'd0;else if(ro_op_valid && ri_op_ready && ro_op_cmd == 2'b10)ro_op_raddr <= ro_op_raddr + P_RADDR;
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst) beginro_write_data <= 32'd0;ro_write_valid <= 1'b0 ;endelse if(r_write_cnt == 'd4095) beginro_write_data <= 32'd0;ro_write_valid <= 1'b0 ;endelse if((~ro_op_valid && wcmd_pos) || ro_write_valid) beginro_write_data <= ro_write_data + 1'b1;ro_write_valid <= 1'b1;end
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst) r_write_cnt <= 16'd0;else if(r_write_cnt == 'd4095)r_write_cnt <= 16'd0;else if(ro_write_valid)r_write_cnt <= r_write_cnt + 1'b1;
endendmodule
接下来,笔者便进行上板测试
由下图可知,MIG核成功实现对DDR的初始化,init信号为高
首先通过vio进行两次写数据测试,vio控制输出逻辑为0~1的电平跳变,而代码中通过捕获上升沿,实现读或写指令的输出,写测试如下图所示:
图中展示的是第二次突发长度为256的写测试,注意写地址
AXI总线的地址最小操控单元为Byte,而笔者读写数据的位宽为4Byte,4*256 = 1Kbyte;对应地址即为0x0400,那么第二次写的地址即为0x0400,地址正确。
接下来进行读测试 ,以0地址为起始地址,突发长度256,读到的数据为1~256,与写入数据对应。
进行第二次读,读到的数据为257~512,与写入数据对应
经过上述仿真与上板测试,可以看出从UDP到DDR这条线路已经是ok的,接下来将进行GT收发器的使用讲解,关于本节代码的问题,以及优化意见,欢迎大家在评论区指出,如果想要对应工程进行学习,欢迎大家私信。
相关文章:
UDP--DDR--SFP,FPGA实现之模块梳理及AXI读写DDR读写上板测试
模块梳理介绍 在之前的几篇文章中,笔者详细介绍了整个项目的框架结构以及部分关键模块的实现细节。这些模块包括UDP协议栈、UDP指令监测、数据跨时钟域处理、DDR读写控制、内存读取控制以及DDR AXI控制器等。这些模块共同构成了项目的基础架构,每个模块…...
Slidev集成Chart.js:专业数据可视化演示文稿优化指南
引言:为何选择在Slidev中集成Chart.js? 在现代演示文稿中,高效的数据可视化对于清晰传达复杂信息至关重要。Slidev是一款灵活的开源演示文稿工具,基于Web技术构建,但在高级数据可视化方面存在一定局限。本文旨在提供一…...
动态规划(3)学习方法论:构建思维模型
引言 动态规划是算法领域中一个强大而优雅的解题方法,但对于许多学习者来说,它也是最难以掌握的算法范式之一。与贪心算法或分治法等直观的算法相比,动态规划往往需要更抽象的思维和更系统的学习方法。在前两篇文章中,我们介绍了动态规划的基础概念、原理以及问题建模与状…...
NDS3211HV单路H.264/HEVC/HD视频编码器
1产品概述 NDS3211HV单路高清编码器是一款功能强大的音/视频编码设备,支持2组立体声,同时还支持CC(CVBS)字幕。支持多种音频编码方式。该设备配备了多种音/视频输入接口:HD-SDI数字视频输入、HDMI高清输入(支持CC)、A…...
GO语言语法---if语句
文章目录 1. 基本语法1.1 单分支1.2 双分支1.3 多分支 2. Go特有的if语句特性2.1 条件前可以包含初始化语句2.2 条件表达式不需要括号2.3 必须使用大括号2.4 判断语句所在行数控制 Go语言的if语句用于条件判断,与其他C风格语言类似,但有一些独特的语法特…...
单细胞转录组(4)Cell Ranger
使用 Cell Ranger 分析单细胞数据 1. 数据转换 BCL2FASTQ 在进行单细胞数据分析之前,需要将 Illumina 测序仪生成的 BCL 格式数据转换为 FASTQ 格式。这一步通常使用 bcl2fastq 软件完成。 1.1 安装 bcl2fastq bcl2fastq 是 Illumina 提供的软件,用于…...
Python爬虫-爬取百度指数之人群兴趣分布数据,进行数据分析
前言 本文是该专栏的第56篇,后面会持续分享python爬虫干货知识,记得关注。 在本专栏之前的文章《Python爬虫-爬取百度指数之需求图谱近一年数据》中,笔者有详细介绍过爬取需求图谱的数据教程。 而本文,笔者将再以百度指数为例子,基于Python爬虫获取指定关键词的人群“兴…...
使用Python和Selenium打造一个全网页截图工具
无论是归档网站、测试页面设计,还是为报告记录网页内容,一个可靠的截图工具都能大大提升效率。本文将介绍如何使用Python、Selenium和wxPython构建一个用户友好的网页截图工具。该工具能在浏览器中显示网页,自动平滑滚动到底部以触发懒加载内…...
自动化脚本开发:Python调用云手机API实现TikTok批量内容发布
在2025年的技术生态下,通过Python实现TikTok批量内容发布的自动化脚本开发需结合云手机API调用、TikTok开放接口及智能调度算法。以下是基于最新技术实践的系统化开发方案: 一、云手机环境配置与API对接 云手机平台选择与API接入 推荐使用比特云手机或丁…...
React Hooks 必须在组件最顶层调用的原因解析
文章目录 前言一、Hooks 的基本概念二、Hooks 的调用规则三、为什么 Hooks 必须在最顶层调用?1. 维护 Hooks 的调用顺序2. 闭包与状态关联3. 实现细节:Hook 的链表结构 四、违反规则的后果五、如何正确使用 Hooks六、示例:正确与错误的用法对…...
西门子 Teamcenter13 Eclipse RCP 开发 1.2 工具栏 开关按钮
西门子 Teamcenter13 Eclipse RCP 开发 1.2 工具栏 开关按钮 1 配置文件2 插件控制3 命令框架 位置locationURI备注菜单栏menu:org.eclipse.ui.main.menu添加到传统菜单工具栏toolbar:org.eclipse.ui.main.toolbar添加到工具栏 style 值含义显示效果push普通按钮(默…...
5.27本日总结
一、英语 复习list2list29 二、数学 学习14讲部分内容 三、408 学习计组1.2内容 四、总结 高数和计网明天结束当前章节,计网内容学完之后主要学习计组和操作系统 五、明日计划 英语:复习lsit3list28,完成07年第二篇阅读 数学&#…...
【持续更新中】架构面试知识学习总结
1.分库分表出现冗余数据: ☆分库分表方法:水平和垂直(业务场景,数据关联性。逻辑要调查清楚) 垂直:将一个表(库)按照列的业务相关性进行拆分,把经常一起使用的列放在一张表(库)&…...
文字溢出省略号显示
一、 单行文字溢出、省略号显示 二、 多行文字溢出,省略号显示 有较大的兼容性问题,适用于Webkit为内核的浏览器软件,或者移动端的(大部分也是webkit) 此效果建议后端人员开发 三、图片底侧空白缝隙的修复技巧&#…...
力扣-283-移动零
1.题目描述 2.题目链接 283. 移动零 - 力扣(LeetCode) 3.题目代码 class Solution {public void moveZeroes(int[] nums) {int dest-1;int cur0;while(cur<nums.length){if(nums[cur]0){cur;}else if(nums[cur]!0){swap(nums,cur,dest1);cur;dest…...
【001】RenPy打包安卓apk 流程源码级别分析
1. 入口在下图 2. SDK版本及代码入口 (renpy-8.3.7-sdk) 由于SDK一直在升级,本文采用 标题中的版本进行分析,整体逻辑变化不太大。 实际执行逻辑是调用的rapt 2.1 点击按钮实际执行逻辑 def AndroidIfState(state, needed, acti…...
机器学习-人与机器生数据的区分模型测试-数据处理 - 续
这里继续 机器学习-人与机器生数据的区分模型测试-数据处理1的内容 查看数据 中1的情况 #查看数据1的分布情况 one_ratio_list [] for col in data.columns:if col city or col target or col city2: # 跳过第一列continueelse:one_ratio data[col].mean() # 计算1值占…...
计算机视觉与深度学习 | Python实现EMD-VMD-LSTM时间序列预测(完整源码和数据)
EMD-VMD-LSTM 一、完整代码实现二、代码结构解析三、关键参数说明四、性能优化建议五、工业部署方案以下是用Python实现EMD-VMD-LSTM时间序列预测的完整代码,结合经验模态分解(EMD)、变分模态分解(VMD)与LSTM深度学习模型,适用于复杂非平稳信号的预测任务。代码包含数据生…...
数据结构与算法——双向链表
双向链表 定义链表分类双向链表:带头双向循环链表 初始化打印尾插头插尾删头删查找在pos(指定位置)之后插入结点在pos(指定位置)之前插入结点删除pos(指定位置)的结点销毁顺序表与链表的分析 定义 链表分类 单向和双向 带头和不带头 带头是指存在一个头结点&…...
.NET 中管理 Web API 文档的两种方式
前言 在 .NET 开发中管理 Web API 文档是确保 API 易用性、可维护性和一致性的关键。今天大姚给大家分享两种在 .NET 中管理 Web API 文档的方式,希望可以帮助到有需要的同学。 Swashbuckle Swashbuckle.AspNetCore 是一个流行的 .NET 库,它使得在 AS…...
混合学习:Bagging与Boosting的深度解析与实践指南
引言 在机器学习的世界里,模型的性能优化一直是研究的核心问题。无论是分类任务还是回归任务,我们都希望模型能够在新的数据上表现出色,即具有良好的泛化能力。然而,实际应用中常常遇到模型过拟合(高方差)…...
基于大疆Mini 3无人机和指定软件工具链的完整3D建模工作
基于大疆Mini 3无人机和指定软件工具链的完整3D建模工作流程关键步骤: 1. 无人机航拍准备 • 设备检查:确保大疆 Mini 3 电量充足,相机设置为 RAW 格式(便于后期调色),关闭自动白平衡。 • 飞行规划&…...
开源项目实战学习之YOLO11:12.1 ultralytics-models-sam-blocks.py源码
👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-__init__.py2.sam-modules-blocks.pybl…...
3D个人简历网站 5.天空、鸟、飞机
1.显示天空 models下新建文件Sky.jsx Sky.jsx // 从 React 库中导入 useRef 钩子,用于创建可变的 ref 对象 import { useRef } from "react"; // 从 react-three/drei 库中导入 useGLTF 钩子,用于加载 GLTF 格式的 3D 模型 import { useGLT…...
蓝桥杯-不完整的算式
问题描述 小蓝在黑板上写了一个形如 AopBCAopBC 的算式,其中 AA、BB、CC 都是非负整数,opop 是 、-、*、/、-、*、/(整除)四种运算之一。不过 AA、opop、BB、CC 这四部分有一部分被不小心的同学擦掉了。 给出这个不完整的算式&a…...
【Python 算法零基础 3.递推】
压抑与痛苦,那些辗转反侧的夜,终会让我们更加强大 —— 25.5.16 一、递推的概念 递推 —— 递推最通俗的理解就是数列,递推和数列的关系就好比 算法 和 数据结构 的关系,数列有点像数据结构中的线性表(可以是顺序表,也…...
计算机视觉与深度学习 | Matlab实现EMD-LSTM和LSTM时间序列预测对比(完整源码和数据)
EMD-LSTM与LSTM 一、数据生成与预处理二、经验模态分解(EMD)三、数据预处理四、模型构建与训练1. 单一LSTM模型2. EMD-LSTM混合模型五、预测与结果对比1. 单一LSTM预测2. EMD-LSTM预测3. 性能评估六、结果可视化七、完整代码说明八、典型输出结果九、改进方向以下是用MATLAB实…...
【爬虫】DrissionPage-6
官方文档: https://www.drissionpage.cn/browser_control/visit https://www.drissionpage.cn/browser_control/page_operation 1. Tab 对象概述 Tab 对象 是 DrissionPage 中用于控制浏览器标签页的主要单位。每个 Tab 对象对应一个浏览器标签页,负责执行各种网页…...
C/C++实践(十)C语言冒泡排序深度解析:发展历史、技术方法与应用场景
一、发展历史 冒泡排序(Bubble Sort)作为计算机科学领域最基础的排序算法之一,其历史可追溯至计算机编程的早期阶段。尽管具体起源时间难以考证,但它在20世纪50年代至60年代间被广泛讨论和应用。冒泡排序的名称来源于其独特的排序…...
git提交库常用词
新功能 feat修改BUG fix文档修改 docs格式修改 style重构 refactor性能提升 perf测试 test构建系统 build对CI配置文件修改 ci修改构建流程、或增加依赖库、工具 chore回滚版本 revert...
结构化思考力_第一章_明确理念打基础
接收信息的3个步骤 1. 梳理:观点、理由、事实和数据; 2. 画3这的结构图 3. 一句话概括 可套用固定格式。在——的基础上,从——、——、——N个方面,说明了————。 一句话概括主要内容的前提是,一定是结构非常…...
【C语言练习】046. 编写插入排序算法
046. 编写插入排序算法 046. 编写插入排序算法C语言实现插入排序代码说明示例运行输入:输出:插入排序的特点一、插入排序的适用场景二、C语言代码示例及分步讲解代码实现代码解析三、示例执行过程四、性能分析五、总结046. 编写插入排序算法 插入排序(Insertion Sort)是一…...
Kotlin与机器学习实战:Android端集成TensorFlow Lite全指南
本文将手把手教你如何在Android应用中集成TensorFlow Lite模型,实现端侧机器学习推理能力。我们以图像分类场景为例,提供可直接运行的完整代码示例。 环境准备 1. 开发环境要求 Android Studio Arctic Fox以上版本AGP 7.0Kotlin 1.6Minimum SDK 21 2.…...
【Linux笔记】nfs网络文件系统与autofs(nfsdata、autofs、autofs.conf、auto.master)
一、nfs概念 NFS(Network File System,网络文件系统) 是一种由 Sun Microsystems 于1984年开发的分布式文件系统协议,允许用户通过网络访问远程计算机上的文件,就像访问本地文件一样。它广泛应用于 Unix/Linux 系统&a…...
Redis持久化机制详解:保障数据安全的关键策略
在现代应用开发中,Redis作为高性能的内存数据库被广泛使用。然而,内存的易失性特性使得持久化成为Redis设计中的关键环节。本文将全面剖析Redis的持久化机制,包括RDB、AOF以及混合持久化模式,帮助开发者根据业务需求选择最适合的持…...
经典算法 求C(N, K) % mod,保证mod是质数
求C(N, K) % mod,保证mod是质数 问题描述 给你三个整数N,K,mod保证mod是一个质数,求组合数C(N, K) % mod。 输入描述 输入有多组,输入第一行为两个整数T,mod。接下来2 - T 1行,每行输入N, K。 输出描…...
NY309NY318美光科技颗粒NY319NY320
NY309NY318美光科技颗粒NY319NY320 技术解析:架构创新与性能突围 美光科技的NY系列颗粒(如NY309、NY318、NY319、NY320)延续了其在存储技术领域的创新基因。以NY319为例,其采用16层BiCS3 3D NAND工艺,通过浮栅&#…...
Buildroot 移植MiniGUI: 编写简单示例(基于君正X2000)
概述 上一篇文章: Buildroot 移植MiniGUI, 在编译打包完文件系统后, 编写一个Demo进一步验证MiniGUI的功能. 目标平台: 键值CPUX2000架构mips内存128MB存储256MBLCD600*1024 MiniGUI 的三种运行模式 在编写第一个 MiniGUI 程序之前,需要了解如下事实࿱…...
flutter长列表 ListView、GridView、SingleChildScrollView、CustomScrollView区别
组件名称用途/适合场景是否懒加载支持列表结构用法复杂度SingleChildScrollView适用于内容数量不大、不重复的页面(如表单、静态内容)❌ 否❌ 否⭐⭐ListView适用于垂直方向的长列表,自动滚动;适合展示大量数据✅ 支持✅ 是⭐⭐Li…...
OpenCV透视变换
概念 OpenCV 透视变换是将图像从一个视平面投影到另一个视平面的过程,也叫投影映射 ,属于空间立体三维变换。它基于透视原理,通过 33 的变换矩阵作用于图像像素坐标来实现映射转换 ,能模拟人眼或相机镜头观看三维空间物体时的透视…...
Node.js 实战四:数据库集成最佳实践
你写了个登录接口,用上了 JWT;然后,产品来了句: “用户数据能分页查吗?能关联公司信息吗?我们这边还有多语言字段…” 你发现:SQL 写得越来越长,关联越来越绕,字段越来越…...
【JDBC】JDBC概述、历史版本及特征
1_JDBC概述 什么是JDBC JDBC(Java DataBase Connectivity, Java数据库连接) ,是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成 有了JDBC,程序员只需用JDBC API写一个程序…...
redis的pipline使用结合线程池优化实战
文章目录 代码讲解与事务 (MULTI/EXEC) 的区别在你这段代码里的价值可能的坑实战建议 代码 /*** 批量根据用户 ID 查询用户信息** param findUsersByIdsReqDTO* return*/Overridepublic Response<List<FindUserByIdRspDTO>> findByIds(FindUsersByIdsReqDTO findUs…...
【RabbitMQ】整合 SpringBoot,实现工作队列、发布/订阅、路由和通配符模式
文章目录 工作队列模式引入依赖配置声明生产者代码消费者代码 发布/订阅模式引入依赖声明生产者代码发送消息 消费者代码运行程序 路由模式声明生产者代码消费者代码运行程序 通配符模式声明生产者代码消费者代码运行程序 工作队列模式 引入依赖 我们在创建 SpringBoot 项目的…...
MySQL初阶:sql事务和索引
索引(index) 可以类似理解为一本书的目录,一个表可以有多个索引。 索引的意义和代价 在MySQL中使用select进行查询时会经过: 1.先遍历表 2.将条件带入每行记录中进行判断,看是否符合 3.不符合就跳过 但当表中的…...
使用教程:8x16模拟开关阵列可级联XY脚双向导通自动化接线
以下通过点亮LED进行基本使用流程演示,实际可以连接复杂外设(SPI、CAN、ADC等) 单模块使用 RX、TX、5V和GND接到串口模块;X5接5V;Y2接LED;LED-接GND 串口模块插上电脑后,LED没有亮;因为此时模…...
很啰嗦,再次总结 DOM
DOM (文档对象模型) 详解 一、DOM 基础概念 1. 定义与作用 DOM(Document Object Model)即文档对象模型,是一种用于 HTML 和 XML 文档的编程接口。它将文档解析为一个由节点和对象组成的树状结构,允许程序和脚本动态访问、修改文…...
文件读取漏洞路径与防御总结
文件读取漏洞路径与防御总结 文件读取漏洞允许攻击者通过路径遍历等手段访问未授权的文件。以下是Linux和Windows系统中常见敏感路径的归纳及防御建议: Linux 系统常见敏感路径 系统关键文件: /etc/passwd:用户账户信息(可被用来…...
电池的充放电电流中C的含义
充电电池的充放电电流标注为 -0.2C、1C、2C 等参数时,其含义与电池的容量和充放电速率直接相关。以下是详细解释: 1. 什么是 “C” 值? • C 是电池的 额定容量(Capacity) 的缩写,单位为 Ah(安时…...
文章记单词 | 第91篇(六级)
一,单词释义 stride /straɪd/- v. 大步走;跨越;迈进 /n. 大步;进展;步幅diplomatic /ˌdɪpləˈmtɪk/- adj. 外交的;有手腕的conquer /ˈkɒŋkə(r)/- v. 征服;战胜;克服geogra…...