SDRAM学习笔记(MT48LC16M16A2,w9812g6kh)

news2024/10/6 4:04:41

一、基本知识

SDRAM : 即同步动态随机存储器(Synchronous Dynamic Random Access Memory), 同步是指其时钟频率与对应控制器(CPU/FPGA)的系统时钟频率相同,并且内部命令 的发送与数据传输都是以该时钟为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机指数据的读取和写入可以随机指定地址,而不是必须按照严格的线性次序变化。

SDRAM 使用电容的电荷存储特性存储数据,而 SRAM使用CMOS晶体管存储数据,这决定了SDRAM的运行功耗要远远低于SRAM。由于使用晶体管存储数据,要能够正确的存储一位数据,需要最少6个晶体管。因此,从芯片面积上来说,单片SRAM芯片的容量不可能做到很高。

通常情况下,SDRAM 是拥有四个 BANK 的动态刷新存储器,存储器工作在 3.3V 的电 压下,拥有一个同步接口,SDRAM 的所有信号都在时钟信号的上升沿被寄存。对于 SDRAM 的读写是以突发的方式进行的,对 sdram 的获取(读或者写)是从一个指定的地址开始,并按照编程好的数量(长度)的地址,以编程好的数据顺序读写数据。

存取原理:先通过行地址打开行地址线,后通过列地址线打开列地址,便实现把电容与数据线连通,实现读/写操作。

   打开行地址需要tRCD时间,后才能打开列地址。tRCD可查手册,计算需要多少个对应频率的时钟的延迟,进行设计。

   打开列地址后,如果是读操作,需要CL(CAS READ LATENCY)个时钟周期才会出数据,如果是写操作,则数据需要同时送出,不用CL。

  不同型号的sdram:命令、时序参数有区别

二、型号MT48LC16M16A2的sdram

引脚:

对于sdram的控制,通过CS_N、RAS_N、CAS_N、WE_N四个引脚来控制,故记这四个引脚组成的状态为控制命令cmd。

通过这个表来设置cmd。

1.时序设计

控制sdram只需要结合时序图和命令表,通过线性序列机和状态机来设计就可以。

1.上电初始化:通过计数器使sdram处于nop状态 不少于100us后,发出一个precharge命令,经过tRP时间(一直处于nop,下同),发出一个autorefresh命令,经过tRFC时间,再autorefresh一次,经过tRFC时间,便可发出load mode register命令配置模式寄存器。

模式寄存器设置规则如下:

2.读/写命令:

       器件手册给出了包括读/写在内的多种命令的时序图,根据时序图进行设计即可,比如常用的:

2.代码设计

       类似IIC协议和SPI协议,依旧是状态机加线性序列机的形式来是实现。最底层用状态机实现每种状态需要的操作,中间层用线性序列机实现一个完整的读/写/其他操作需要经过几种状态的跳转。故先定义状态和命令cmd。

       注意,设计时仍然需要注意时钟问题,给sdram的时钟是在上升沿读取数据,所以输出的数据在上升沿应该是稳定的,具体可以通过设计与读写两个时钟的移相来实现。

module sdram_driver(
	input clk ,
	input rst_n ,
	
	input write_sig ,
	input read_sig ,
	input initial_sig ,
	input [12:0]write_addr ,
	input [1:0]write_bank ,
	input [12:0]read_addr ,
	input [1:0]read_bank ,
	
	output reg [3:0]cmd ,
	output reg [1:0]bank ,
	output reg [12:0]addr ,
	output reg [11:0]mode ,
	output reg cke_ctrl ,
	output reg [1:0]dqm_ctrl ,
	output reg initial_done ,
	output reg [15:0]read_data ,
	output reg trans_done ,
	inout [15:0]DQ 
);

//状态参数
localparam nop1 = 					4'b1000 ; //空闲态:禁止命令
localparam nop2 = 					4'b0111 ; //空闲态:空命令
localparam active = 					4'b0011 ; //选bank与行
localparam read = 					4'b0101 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam write = 					4'b0100 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam burst_terminate = 		4'b0110 ; //突发中止
localparam precharge = 				4'b0010 ; //关闭行,预充电
localparam refresh = 				4'b0001 ; //刷新
localparam load_mode_register =	4'b0000 ; //a0 - a11 tmrd


// mode register
localparam M9_BL_mode = 1'b0 ; //length
localparam M9_SL_mode = 1'b1 ; //single
localparam M87_SO_mode = 2'b00 ; 
localparam M654_CAS_2 = 3'b010 ;//CL
localparam M654_CAS_3 = 3'b011 ;//CL
localparam M3_seq = 1'b0 ;
localparam M3_intl = 1'b1 ;
localparam M210_BL_1 = 3'b000 ;//be able to replace single read/write (M9)
localparam M210_BL_2 = 3'b001 ;
localparam M210_BL_4 = 3'b010 ;
localparam M210_BL_8 = 3'b011 ;
localparam M210_BL_full = 3'b111 ;

// read with auto precharge ?
localparam auto_precharge = 1 ;
wire rd_with_auto , wr_with_auto ;
assign rd_with_auto = auto_precharge ;
assign wr_with_auto = auto_precharge ;

reg [15:0]cmd_cnt ;
always@( posedge clk or negedge rst_n )	
if(!rst_n)
	begin
		cmd_cnt 		<= 0 ;
		cmd 			<= nop2 ;
		bank			<= 0 ;
		addr			<= 0 ;
		mode			<= 0 ;
		cke_ctrl		<= 0 ;
		dqm_ctrl		<= 0 ;	
		trans_done 	<= 0 ;
		initial_done<= 0 ;
		read_data   <= 0 ;
	end
else if(initial_sig)
	begin
		cmd_cnt <= cmd_cnt + 1 ;
		case(cmd_cnt)
			1:cmd <= nop2 ;//delay > 100 us
			10005: begin cke_ctrl <= 1 ;  end
			10010: begin cmd <= precharge ; addr[10] = 1 ;  end //precharge all banks : tRP >= 20ns (2T)
			10011: begin cmd <= nop2 ; end
			10015: begin cmd <= refresh ; cke_ctrl <= 1 ; end //auto refresh : >= 2T(RFC) ; T(RFC) >= 66ns    1T(auto)(256Mb) = 8192
			10016: begin cmd <= nop2 ; end
			10026: begin cmd <= refresh ; cke_ctrl <= 1 ; end // 
			10027: begin cmd <= nop2 ; end						  // 
			10040: begin cmd <= load_mode_register ; bank <= 0 ; mode <= { 2'b00 , M9_BL_mode , M87_SO_mode , M654_CAS_3 , M3_seq , M210_BL_4 } ;end //set mode :t(mrd) = 2t(ck) = 2*6 = 12 ns
			10041: begin cmd <= nop2 ; end
			10045: begin initial_done <= 1 ;  end
			10046: begin cmd_cnt <= 0 ; end
			default:cmd <= nop2 ;	
		endcase
	end
else if(initial_done)
	begin
		if(write_sig)
			begin
				if(wr_with_auto)
					begin
						cmd_cnt <= cmd_cnt + 1 ;
						case(cmd_cnt)
							1:begin cmd <= active ; bank <= write_bank ; addr <= write_addr ; end
							4:begin cmd <= write ; bank <= write_bank ; addr <= {write_addr[12:11],1'b1,write_addr[9:0]}; end
							10:begin trans_done <= 1 ; cmd_cnt <= 0 ;end
							default:cmd<=nop2;
						endcase
					end
				else if(~wr_with_auto)
					begin
						cmd_cnt <= cmd_cnt + 1 ;
						case(cmd_cnt)
							1:begin cmd <= active ; bank <= write_bank ; addr <= write_addr ; end
							4:begin cmd <= write ; bank <= write_bank ; addr <= {write_addr[12:11],1'b1,write_addr[9:0]}; end
							9:begin cmd <= precharge ; addr[10] = 1 ;end
							12:begin trans_done <= 1 ; cmd_cnt <= 0 ;end
							default:cmd<=nop2;
						endcase
					end		
			end
		else if(read_sig)
			begin
				if( rd_with_auto )
					begin
						cmd_cnt <= cmd_cnt + 1 ;
						case(cmd_cnt)
							1:begin cmd <= active ; bank <= read_bank ; addr <= read_addr ;  end
							4:begin cmd <= read ; bank <= read_bank ; addr <= {read_addr[12:11],1'b1,read_addr[9:0]}; end //addr10 control auto charge
							9:begin read_data <= DQ ; end
							10:begin read_data <= DQ ; end
							11:begin read_data <= DQ ; end
							12:begin read_data <= DQ ; end
							13:begin trans_done<= 1 ; cmd_cnt <= 0 ; end
							default:begin cmd <= nop2 ;read_data <= DQ ;end
						endcase
					end
				else if( ~rd_with_auto )
					begin
					cmd_cnt <= cmd_cnt + 1 ;
						case(cmd_cnt)
							1:begin cmd <= active ; bank <= read_bank ; addr <= read_addr ;  end
							4:begin cmd <= read ; bank <= read_bank ; addr <= {read_addr[12:11],1'b0,read_addr[9:0]}; end //addr10: control auto charge
							9:begin read_data <= DQ ; end
							10:begin read_data <= DQ ; end
							11:begin read_data <= DQ ; cmd <= precharge ; addr[10] = 1 ; end //precharge
							12:begin read_data <= DQ ;  end
							14:begin trans_done<= 1 ; cmd_cnt <= 0 ; end
							default:cmd <= nop2 ;
						endcase
					end
			end
		else
			begin
				cmd <= nop2 ;
				cmd_cnt <= 0 ;
				trans_done<= 0 ;
			end
	end
else
	begin
		cmd_cnt <= 0 ;
	end

	


endmodule
//-75 100MHz CL = 2 setup = 1.5 hold = 0.8 上升沿读写数据//
// 100MHz : T = 10ns //
// tRP >= 20ns ; T(RFC) >= 66ns ; t(mrd) = 12 ns
// 这里实现 普通的写和读 ;有特殊要求的根据手册进行cmd修改即可
 
module sdram_ctrl(
	input fpga_clk ,
	input rst_n ,
	
	input write_sig ,
	input read_sig ,
	input [12:0]write_addr ,
	input [1:0]write_bank ,
	input [15:0]write_data ,
	input [12:0]read_addr ,
	input [1:0]read_bank , 
	
	output trans_done ,
	output [15:0]read_data ,
	output sclk ,
	output  CKE ,
	output  CS_N ,
	output  RAS_N ,
	output  CAS_N ,
	output  WE_N ,
	output  [1:0]DQM ,//高电平时屏蔽
	output  [12:0]SA ,//A12 - A0
	output  [1:0]BA ,
	inout [15:0]DQ
);

wire clk_100m;
wire clk_100m_90shift ;
pll pll_inst(
	.inclk0(fpga_clk),
	.c0(clk_100m),
	.c1(clk_100m_90shift)
	);
assign sclk = clk_100m_90shift ;

//read / write signal catch
reg write_sig_reg ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)
	write_sig_reg <= 0 ;
else
	write_sig_reg <= write_sig ;

reg read_sig_reg ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)
	read_sig_reg <= 0 ;
else 
	read_sig_reg <= read_sig ;
	
reg write_signal ;
reg read_signal ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)
	write_signal <= 0 ;
else if( write_sig & (!write_sig_reg ) )
	write_signal <= 1 ;
else if(trans_done)
	write_signal <= 0 ;
	
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)
	read_signal <= 0 ;
else if( read_sig & (!read_sig_reg ) )
	read_signal <= 1 ;
else if(trans_done)
	read_signal <= 0 ;	

// initial sdram
reg [5:0]initial_cnt ;
wire initial_done ;
always@(posedge clk_100m or negedge rst_n)
if(!rst_n)
	initial_cnt <= 0 ;
else if( initial_cnt < 50 )
	initial_cnt <= initial_cnt + 1 ;
else
	initial_cnt <= initial_cnt ;

reg initial_sig ;
always@(posedge clk_100m or negedge rst_n)	
if(!rst_n)
	initial_sig <= 0 ;
else if(initial_cnt == 48)
	initial_sig <= 1 ;
else if(initial_done)
	initial_sig <= 0 ;
	
	
wire [3:0]cmd ;
wire [1:0]bank ;
wire [12:0]addr ;
wire [11:0]mode ;
wire cke_ctrl ;
wire [1:0]dqm_ctrl ;
sdram_driver sdram_driver_inst(
	.clk(clk_100m) ,
	.rst_n(rst_n) ,
	
	.write_sig(write_signal) ,
	.read_sig(read_signal) ,
	.initial_sig(initial_sig),
	.write_addr(write_addr) ,
	.write_bank(write_bank) ,
	.read_addr(read_addr) ,
	.read_bank(read_bank) ,
	
	.cmd(cmd) ,
	.bank(bank) ,
	.addr(addr) ,
	.mode(mode) ,
	.cke_ctrl(cke_ctrl) ,
	.dqm_ctrl(dqm_ctrl) ,
	.initial_done(initial_done),
	.read_data(read_data) ,
	.trans_done(trans_done) ,
	.DQ(DQ)
);	
	
sdram_underlying_logic sdram_underlying_logic_inst(
	.clk(clk_100m) ,
	.rst_n(rst_n) ,
	
	.mode(mode),//A11 -A0
	.cmd(cmd) ,
	.cke_ctrl(cke_ctrl) ,
	.bank(bank) ,
	.addr(addr) ,
	.write_data(write_data) ,
	.dqm_ctrl(dqm_ctrl),
	

	.CKE(CKE) ,
	.CS_N(CS_N) ,
	.RAS_N(RAS_N) ,
	.CAS_N(CAS_N) ,
	.WE_N(WE_N) ,
	.DQM(DQM) ,//高电平时屏蔽
	.SA(SA) ,//A12 - A0
	.BA(BA) ,
	.DQ(DQ)
);

	
endmodule
module sdram_underlying_logic(
	input clk ,
	input rst_n ,
	
	input [11:0]mode,//A11 -A0
	input [3:0]cmd ,
	input cke_ctrl ,
	input [1:0]bank ,
	input [12:0]addr ,
	input [15:0]write_data ,
	input [1:0]dqm_ctrl,
	
	output reg CKE ,
	output reg CS_N ,
	output reg RAS_N ,
	output reg CAS_N ,
	output reg WE_N ,
	output reg[1:0]DQM ,//高电平时屏蔽
	output reg[12:0]SA ,//A12 - A0
	output reg [1:0]BA ,
	inout [15:0]DQ
);

reg DQ_ctrl ;
reg [15:0]DQ_out ;
assign DQ = (DQ_ctrl ? DQ_out : 16'hzzzz) ;///

//状态参数
localparam nop1 = 					10'b1000000000 ; //空闲态:禁止命令
localparam nop2 = 					10'b0100000000 ; //空闲态:空命令
localparam active = 					10'b0010000000 ; //选bank与行
localparam read = 					10'b0001000000 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam write = 					10'b0000100000 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam burst_terminate = 		10'b0000010000 ; //突发中止
localparam precharge = 				10'b0000001000 ; //关闭行,预充电
localparam auto_refresh = 			10'b0000000100 ; //自动刷新
localparam self_refresh = 			10'b0000000010 ; //自刷新
localparam load_mode_register =	10'b0000000001 ; //加载模式寄存器

reg [9:0]state ;//状态机
always@(posedge clk or negedge rst_n)
if(!rst_n)
	state <= nop2 ;
else if( cmd[3] )
	state <= nop1 ;
else if( cmd == 4'b0111 )
	state <= nop2 ;
else if( cmd == 4'b0011 )
	state <= active ;
else if( cmd == 4'b0101 )
	state <= read ;
else if( cmd == 4'b0100 )
	state <= write ;
else if( cmd == 4'b0110 )
	state <= burst_terminate ;
else if( cmd == 4'b0010 )
	state <= precharge ;
else if( cmd == 4'b0001 )
	begin
		if(cke_ctrl)
			state <= auto_refresh ;
		else
			state <= self_refresh ;
	end
else if( cmd == 4'b0000 )
	state <= load_mode_register ;
	
	
reg [7:0]state_cnt ;
always@(posedge clk or negedge rst_n)
if(!rst_n)
	begin
		state_cnt <= 0 ;
		CKE <= 1 ;
		CS_N <= 1 ;
		RAS_N <= 1 ;
		CAS_N <= 1 ;
		WE_N <= 1 ;
		BA <= 0 ;
		SA <= 0 ;
		DQM <= 0 ;
		DQ_ctrl <= 1 ;//获取数据线的控制权
		DQ_out <= 0 ;
	end
else 
	begin
		case(state)
			nop1 : begin CS_N <= 1 ;  end
			nop2 : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 1 ; WE_N <= 1 ; DQ_out <= write_data ;end
			active: begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 1 ; WE_N <= 1 ; SA <= addr ; BA <= bank ;end		
			read : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 0 ; WE_N <= 1 ; SA <= addr ; BA <= bank ; DQM <= dqm_ctrl ; DQ_ctrl <= 0 ; end
			write : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 0 ; WE_N <= 0 ; SA <= addr ; BA <= bank ; DQM <= dqm_ctrl ; DQ_out <= write_data ;end
			precharge : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 1 ; WE_N <= 0 ; SA[10] <= addr[10] ; BA <= bank ;DQ_ctrl <= 1 ; end//sa[10] = 1 :对所有bank预充电 ; sa[10] = 0 : 对ba1 ba0 选中的bank预充电
			auto_refresh : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 1 ; CKE <= 1 ; end
			self_refresh : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 1 ; CKE <= 0 ; end
			load_mode_register : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 0 ; SA <= { 1'b0 , mode } ; end
			default:;
		endcase
	end




endmodule
`timescale 1ns/1ns 
module sdram_ctrl_tb();

reg fpga_clk ;
reg rst_n ;
reg write_sig ;
reg read_sig ;
reg [12:0]write_addr ;
reg [1:0] write_bank ;
reg [15:0]write_data ;
reg [12:0]read_addr ;
reg [1:0] read_bank ; 

wire sclk ;
wire CKE ;
wire CS_N ;
wire RAS_N ;
wire CAS_N ;
wire WE_N ;
wire [1:0]DQM ;//高电平时屏蔽
wire [12:0]SA ;//A12 - A0
wire [1:0]BA ;
wire [15:0]DQ;
wire [15:0]read_data;
wire trans_done;
wire [3:0]cmd_state ;
sdram_ctrl sdram_ctrl_inst(
	.fpga_clk(fpga_clk) ,
	.rst_n(rst_n) ,
	
	.write_sig(write_sig) ,
	.read_sig(read_sig) ,
	.write_addr(write_addr) ,
	.write_bank(write_bank) ,
	.write_data(write_data) ,
	.read_addr(read_addr) ,
	.read_bank(read_bank) , 
	
	.trans_done(trans_done) ,
	.read_data(read_data) ,
	.sclk(sclk) ,
	.CKE(CKE) ,
	.CS_N(CS_N) ,
	.RAS_N(RAS_N) ,
	.CAS_N(CAS_N) ,
	.WE_N(WE_N) ,
	.DQM(DQM) ,
	.SA(SA) ,
	.BA(BA) ,
	.DQ(DQ)
);

mt48lc16m16a2 mt48lc16m16a2_inst(
	.Dq(DQ),
	.Addr(SA),
	.Ba(BA),
	.Clk(sclk),
	.Cke(CKE),
	.Cs_n(CS_N),
	.Ras_n(RAS_N),
	.Cas_n(CAS_N),
	.We_n(WE_N),
	.Dqm(DQM)
);

pulldown(DQ[15]);
pulldown(DQ[14]);
pulldown(DQ[13]);
pulldown(DQ[12]);
pulldown(DQ[11]);
pulldown(DQ[10]);
pulldown(DQ[9]);
pulldown(DQ[8]);
pulldown(DQ[7]);
pulldown(DQ[6]);
pulldown(DQ[5]);
pulldown(DQ[4]);
pulldown(DQ[3]);
pulldown(DQ[2]);
pulldown(DQ[1]);
pulldown(DQ[0]);
assign cmd_state = {CS_N,RAS_N,CAS_N,WE_N} ;

initial fpga_clk = 0 ;
always #10 fpga_clk = !fpga_clk ;
initial begin
	rst_n = 0 ;
	write_sig = 0 ;
	read_sig = 0 ;
	write_addr = 0 ;
	write_bank = 0 ;
	write_data = 0 ;
	read_addr  = 0 ;
	read_bank  = 0 ;
	#201 ;
	rst_n = 1 ;
	#102000;
	#200 ;
	write_addr = 13'd2 ;
	write_bank = 2'd1;
	write_data = 16'h5a5a ;
	write_sig = 1;
	#70;
	write_data = 16'h5a5b ;
	#10;
	write_data = 16'h5a5c ;
	#10;
	write_data = 16'h5a5d ;
	#200 ;
	write_sig = 0;
	#5000;
	read_addr = 13'd2 ;
	read_bank = 2'd1;
	read_sig = 1 ;
	#200 ;
	read_sig = 0 ;
	#10000;
	$stop ;
	
end



endmodule

3.仿真

1.上点初始化

2.写数据(带自动预充电)

3.读数据(带自动预充电)

读出来的数据,DQ的最后一个数据只有7.6ns,不知道是什么原因。

但是移相适当仍然可以读取。

接下来对AC609板载的SDRAM:w9812g6kh进行设计,并进行板级验证。

三、型号w9812g6kh的sdram

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python中if __name__ == ‘__main__‘,__init__和self 的解析

一、 if __name__ __main__ if __name__ __main__的意思是&#xff1a; 当.py文件被直接运行时&#xff0c;if __name__ __main__之下的代码块将被运行&#xff1b; 当.py文件以模块形式被导入时&#xff0c;if __name__ __main__之下的代码块不被运行。 1.1、一个 xxx.p…

面试题复盘-2023/10/20

目录 笔试题面试题&#xff08;未完待续&#xff09; 笔试题 一.多选题 A:map的key是const,不可更改 B:STL中的快速排序比一般的快速排序速度更快&#xff0c;是因为中值排序法 C:list的插入效率是O(1) D:vector的容量只能增大不能减小 解析&#xff1a; B: STL中的sort函数的…

Python教程总结版

目录 1. chr()和ord()的用法 2. input()——读取数据的转换 2.1 int(),float(),list() 数据转换 2.2 split()函数处理多个输入值 2.3 map()强制转换 1. chr()和ord()的用法 for i in range(65, 91): print(chr(i), end) # 控制台输出&#xff1a;ABCDEFGHIJKLMNOPQRSTUV…

关于高并发你必须知道的几个概念

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录高并发必须知道的几个概念&#xff0c;如有出入还望指正。 关注公众…

墨西哥专线港口通航情况

随着全球贸易的不断发展&#xff0c;墨西哥作为拉美地区的重要国家&#xff0c;其港口通航状况对于国际贸易具有重要意义。本文将从墨西哥专线港口的通航现状、通航瓶颈以及未来发展趋势等方面进行分析&#xff0c;以期为墨西哥港口的发展提供一些参考。 一、墨西哥专线港口的通…

使用Linux JumpServer 堡垒机进行远程访问

文章目录 前言1. 安装Jump server2. 本地访问jump server3. 安装 cpolar内网穿透软件4. 配置Jump server公网访问地址5. 公网远程访问Jump server6. 固定Jump server公网地址 前言 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpS…

有什么不起眼,却很挣钱的副业?

说两个真人真事儿&#xff1a; 1、我有一个表妹,去年生完孩子后,开始在家做视频剪辑工作。 主要是剪辑一些古装剧、家庭剧等视频,然后发布到抖音和快手等短视频平台。 她会把视频剪辑成一集一集的,先发布片段进行推广,如果用户觉得剧情吸引就提示他们可以付费购买全集。 我表妹…

JS:获取当前时间、计算2个时间的相差天数

前言 本文将介绍在js中对时间的一些操作&#xff0c;包括&#xff1a;获取当前的年、月、日&#xff1b;获取指定格式的时间&#xff1b;2个时间的相差天数等 基本操作 在js种可以使用特定的函数&#xff0c;获取当前的年、月、日等时间 date .getYear(); //获取当前年份(2…

动画云渲染要多少钱?云渲染怎么使用?

其实动画云渲染的具体费用会根据所使用的平台、渲染模式、渲染时间等因素而有所不同&#xff0c;具体还是要看你所使用的云渲染平台。下面我们以炫云云渲染为例&#xff0c;告诉你动画云渲染需要多少钱。 炫云云渲染是第一家实现一键云渲染的平台&#xff0c;是最早的一批云渲染…

公司给了个CheckStyle,还给公司一片红润

项目总监在管理项目时&#xff0c;会担心技术人员开发代码不规范的问题。如果人员少口头述说一下就好了。但是人员大呢?比如50人的大团队&#xff0c;如果一个一个去说那肯定不可能。所以就需要借助工具checkstyle了。checkstyle的介绍如下&#xff1a; “CheckStyle是SourceF…

腾讯联手警方重拳出击 《绝地求生》外挂首案告破

12月13日&#xff0c;闲游盒腾讯公司联手无锡江阴警方破获一起利用《绝地求生》游戏外挂非法谋利的重大案件&#xff0c;3名核心涉案犯罪嫌疑人全部落网&#xff0c;并对犯罪事实供认不讳。这是腾讯宣布获得《绝地求生》国服独家代理权以来&#xff0c;破获的首起《绝地求生》外…

整数转罗马数字-----题解报告

题目&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 直接按照题目模拟过程即可 public String intToRoman(int num) {int []a{1000,900,500,400,100,90,50,40,10,9,5,4,1};String []b{"M","CM","D",&quo…

全志R528代码编译和烧录以及测试

代表编译 代码存在如下目录中:/home/workspace/tina-r528-v1.2 这里输入如下指令进行编译: su root source build/envsetup.sh lunch r528_evb2-tina make & packroottina-virtual-machine:/home/workspace/tina-r528-v1.2# source build/envsetup.sh Setup env done! …

最小生成树专题2 最小生成树-Kruskal算法

题目&#xff1a; 样例1&#xff1a; 输入 4 5 0 1 3 0 2 2 0 3 3 2 3 1 1 2 1 输出 4 样例2&#xff1a; 输入 3 1 0 1 1 输出 -1 思路&#xff1a; 由题意&#xff0c;我们看一下数据&#xff0c;可以知道&#xff0c;朴素版的 最小生成树&#xff0c;是使用 二维数组存储…

【python入门篇】条件表达式、循环(5)

这一章节讲python的条件表达式和循环放在一起来说&#xff0c;条件语句是通过判断条件是否成立&#xff0c;根据条件表达式的结果做出决策&#xff0c;控制不同代码块的执行。循环是一种重复执行某段代码的结构,通常被用于遍历或处理一组数据,或者重复执行一些代码直到满足某个…

设计模式:状态模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《备忘录模式》 下一篇《访问者模式》 简介&#xff1a; 状态模式&#xff0c;它是一种对象行为型模式&#xff0c;它允许一个对象在其内部状态改变时改变它的行为。这种模式可以让一个对象的行为随着状态的改…

Docker安装及镜像源修改

Docker安装及镜像源修改 一、docker安装1、yum 包更新到最新2、安装需要的软件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外两个是devicemapper驱动依赖的3、 设置yum源4、 安装docker&#xff0c;出现输入的界面都按 y5、 查看docker版本&#xff0c;…

2023年中国商用洗碗机产量、需求量、市场规模及行业前景分析[图]

商用洗碗机是餐厅、食堂、中央厨房、酒店等应用场景中不可或缺的洁净消毒设备。商用洗碗机一般用于商用目的&#xff0c;随着消费者对食品卫生日渐重视&#xff0c;中国商用洗碗机市场得到了快速发展。商用洗碗机分类洗碗机有多种形式按洗涤方式分&#xff0c;有喷淋式、叶轮式…

AI 数字人短视频变现及引流,轻松掌握流量密码

项目介绍 AI 数字人短视频就是利用 AI 数字人工具 &#xff0c;生成模仿真人的口播视频 &#xff0c;进行涨粉变现。常见的领域有情感 、 创业 、 育儿 、 书单等 &#xff0c;同一个视频可以发布到各大平台 &#xff0c;实现一 鱼多吃。 创业就卖思维类书籍 &#xff0c;育儿…

Android setText()错误

android.content.res.Resources$NotFoundException: String resource ID #0x0at android.content.res.Resources.getText(Resources.java:415)at android.widget.TextView.setText(TextView.java:6375) 出现场景&#xff1a;在RecycleView的 Override public void onBindViewHo…