XILINX原语之——xpm_fifo_sync(灵活设置位宽、深度)

调用xpm_fifo_sync原语和使用FIFO IP盒基本一致。使用xpm_fifo_sync优势:可以在代码中更改数据位宽和深度,不用再重新生成FIFO IP核。

原语打开方法:

将引脚设置成和调用FIFO IP一致,例化后:

module 	SYNC_FIFO#(
	parameter 				READ_MODE	= 	"fwft",	//"std"- standard read mode;"fwft"- First-Word-Fall-Through read mode
	parameter 	integer 	DATA_WIDTH	= 	32,		//1 to 4096
	parameter 	integer 	DATA_DEPTH	= 	2048,	//16 to 4194304
	parameter 	integer 	READ_LATENCY= 	0		//0 to 100  "fwft":0; "std":1 
)(
	input 	wire 								clk,
	input 	wire 								rst,
	input 	wire [DATA_WIDTH-1 : 0] 			din,
	input 	wire 								wr_en,
	input 	wire	 							rd_en,
	output 	wire [DATA_WIDTH-1 : 0] 			dout,
	output 	wire 								full,
	output 	wire 								empty,
	output 	wire [$clog2(DATA_DEPTH) : 0] 		data_count
);

	wire	[$clog2(DATA_DEPTH) : 0] 		rd_data_count;
	wire	[$clog2(DATA_DEPTH) : 0] 		wr_data_count;
	assign									data_count=	wr_data_count;
	
	
	wire		sync_rst;
	xpm_cdc_sync_rst #(
		.DEST_SYNC_FF	(3			),   
		.INIT			(1			),           						
		.INIT_SYNC_FF	(0			),   
		.SIM_ASSERT_CHK	(0			)  
	)
	u_sync_rst(
		.dest_rst		(sync_rst	),					
		.dest_clk		(clk		),
		.src_rst		(rst		)   
	);
	
	xpm_fifo_sync #(
		.DOUT_RESET_VALUE("0"),    // String
		.ECC_MODE("no_ecc"),       // String
		.FIFO_MEMORY_TYPE("block"), // String"auto", "block", "distributed", or "ultra";
		.FIFO_READ_LATENCY(READ_LATENCY),// DECIMAL 0 to 100
		.FIFO_WRITE_DEPTH(DATA_DEPTH),   // DECIMAL 16 to 4194304
		.FULL_RESET_VALUE(0),      // DECIMAL 
		.PROG_EMPTY_THRESH(10),    // DECIMAL
		.PROG_FULL_THRESH(10),     // DECIMAL
		.RD_DATA_COUNT_WIDTH($clog2(DATA_DEPTH)+1),   // DECIMAL 1 to 23
		.READ_DATA_WIDTH(DATA_WIDTH),      // DECIMAL
		.READ_MODE(READ_MODE),         // String//"std"- standard read mode;"fwft"- First-Word-Fall-Through read mode
		.SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
		.USE_ADV_FEATURES("0707"), // String
		.WAKEUP_TIME(0),           // DECIMAL
		.WRITE_DATA_WIDTH(DATA_WIDTH),     // DECIMAL
		.WR_DATA_COUNT_WIDTH($clog2(DATA_DEPTH)+1)    // DECIMAL 1 to 23
   )
   u_xpm_fifo_sync(
////OUTPUT
		.almost_empty		(),                                       
		.almost_full		(),                                         
		.data_valid			(),                                          
		.dbiterr			(),             
		.dout				(dout		),                   
		.empty				(empty		),                 
		.full				(full		),                   
		.overflow			(),           
		.prog_empty			(),                                          
		.prog_full			(),         
		.rd_data_count		(rd_data_count), 
		.rd_rst_busy		(),     
		.sbiterr			(),             
		.underflow			(),         
		.wr_ack				(),               
		.wr_data_count		(wr_data_count), 
		.wr_rst_busy		(),                                         
//INPUT
		.din				(din		),                     
		.injectdbiterr		(0			), 
		.injectsbiterr		(0			), 
		.rd_en				(rd_en		),                 
		.rst				(sync_rst	),                     
		.sleep				(0			),                 
		.wr_clk				(clk		),               
		.wr_en				(wr_en		)                  
   );
endmodule

同时使用IP生成一个FIFO进行仿真对比。

一、"fwft"模式(First-Word-Fall-Through read mode)

生成的FIFO IP同样设置为fwft模式,仿真代码如下:

`timescale 1ns / 1ps

module tb_syncfifo();
	parameter 				READ_MODE	= 	"fwft";//"std"- standard read mode;"fwft"- First-Word-Fall-Through read mode
	parameter 	integer 	DATA_WIDTH	= 	32;
	parameter 	integer 	DATA_DEPTH	= 	2048;

	reg 								clk;
	reg 								rst;
	reg [DATA_WIDTH-1 : 0] 				din;
	reg 								wr_en;
	reg	 								rd_en;
	wire [DATA_WIDTH-1 : 0] 			dout;
	wire 								full;
	wire 								empty;
	wire [$clog2(DATA_DEPTH) : 0] 		data_count;


	wire [31 : 0] 						dout_IP;
	wire 								full_IP;
	wire 								empty_IP;
	wire [11 : 0] 						data_count_IP;	
	SYNC_FIFO#(
		.READ_MODE				(READ_MODE),
		.DATA_WIDTH				(DATA_WIDTH),
		.DATA_DEPTH				(DATA_DEPTH),
		.READ_LATENCY			(0			)
	)u_scfifo(
		.clk					(clk		),
		.rst					(rst		),
		.din					(din		),
		.wr_en					(wr_en		),
		.rd_en					(rd_en		),
		.dout					(dout		),
		.full					(full		),
		.empty					(empty		),
		.data_count    			(data_count)
	);


	wire		sync_rst;
	xpm_cdc_sync_rst #(
		.DEST_SYNC_FF	(3			),   
		.INIT			(1			),           						
		.INIT_SYNC_FF	(0			),   
		.SIM_ASSERT_CHK	(0			)  
	)
	u_sync_rst(
		.dest_rst		(sync_rst	),					
		.dest_clk		(clk		),
		.src_rst		(rst		)   
	);
	
	SCFIFO_32W_2048D		u_IP_fifo(
		.clk					(clk		),
		.srst					(sync_rst	),
		.din					(din		),
		.wr_en					(wr_en		),
		.rd_en					(rd_en		),
		.dout					(dout_IP	),
		.full					(full_IP	),
		.empty					(empty_IP	),
		.data_count    			(data_count_IP)
	);

initial begin
	clk<=0;
	rst<=1;
#2000
	rst<=0;
end

	
	always #5 clk<=!clk;

	reg		[31:0]		cnt;
	always @(posedge clk or posedge rst)
	begin
		if (rst) begin
			cnt		<= 0;
		end else begin
			if(cnt>=6000)
				cnt<=0;
			else
				cnt<=cnt+1;
		end
	end
	always @(*)
	begin
		if (rst) begin
			wr_en		<= 0;
		end else begin
			if(cnt>200&&cnt<3000 && full==0)begin
				wr_en		<= 1;
			end else
				wr_en		<= 0;
		end
	end


	always @(posedge clk or posedge rst)
	begin
		if (rst) begin
			din<=0;
		end else begin
			if(cnt>200&&cnt<3000 && full==0)begin
				din			<=din+1;
			end
		end
	end
	
	always @(*)
	begin
		if (rst) begin
			rd_en		<= 0;
		end else begin
			if(cnt>3000 && empty==0)begin
				rd_en		<= 1;
			end else
				rd_en		<= 0;
		end
	end

endmodule

仿真波形如下:

1、写FIFO

FIFO空信号(empty):调用XPM原语和使用IP核一致,都在写入数据后延迟3个周期拉低;

FIFO计数信号(count):调用XPM原语计数延迟2个周期(与手册一致),调用IP核计数延迟1个周期。

FIFO满信号(full):调用XPM原语和使用IP核一致,都在写入2048+2个数据后拉高;

2、读FIFO

FIFO满信号(full):调用XPM原语和使用IP核一致,都在读取数据后1个时钟周期后拉低;

FIFO计数信号(count):调用XPM原语计数延迟2个周期,调用IP核计数延迟1个周期。

FIFO输出信号(dout): 调用XPM原语和使用IP核一致,rd_en使能时输出数据,无时钟延迟。

FIFO空信号(empty):调用XPM原语和使用IP核一致,都在读完数据后1个周期拉高;

二、"std"模式(standard read mode)

生成的FIFO IP同样设置为STD模式,仿真代码如下:

`timescale 1ns / 1ps

module tb_syncfifo_std();
	parameter 				READ_MODE	= 	"std";//"std"- standard read mode;"fwft"- First-Word-Fall-Through read mode
	parameter 	integer 	DATA_WIDTH	= 	32;
	parameter 	integer 	DATA_DEPTH	= 	2048;

	reg 								clk;
	reg 								rst;
	reg [DATA_WIDTH-1 : 0] 				din;
	reg 								wr_en;
	reg	 								rd_en;
	wire [DATA_WIDTH-1 : 0] 			dout;
	wire 								full;
	wire 								empty;
	wire [$clog2(DATA_DEPTH) : 0] 		data_count;


	wire [31 : 0] 						dout_IP;
	wire 								full_IP;
	wire 								empty_IP;
	wire [10 : 0] 						data_count_IP;	
	SYNC_FIFO#(
		.READ_MODE				(READ_MODE),
		.DATA_WIDTH				(DATA_WIDTH),
		.DATA_DEPTH				(DATA_DEPTH),
		.READ_LATENCY			(1			)
	)u_scfifo(
		.clk					(clk		),
		.rst					(rst		),
		.din					(din		),
		.wr_en					(wr_en		),
		.rd_en					(rd_en		),
		.dout					(dout		),
		.full					(full		),
		.empty					(empty		),
		.data_count    			(data_count)
	);
	
	wire		sync_rst;
	xpm_cdc_sync_rst #(
		.DEST_SYNC_FF	(3			),   
		.INIT			(1			),           						
		.INIT_SYNC_FF	(0			),   
		.SIM_ASSERT_CHK	(0			)  
	)
	u_sync_rst(
		.dest_rst		(sync_rst	),					
		.dest_clk		(clk		),
		.src_rst		(rst		)   
	);
	
	SCFIFO_32W_2048D_STD		u_IP_fifo(
		.clk					(clk		),
		.srst					(sync_rst	),
		.din					(din		),
		.wr_en					(wr_en		),
		.rd_en					(rd_en		),
		.dout					(dout_IP	),
		.full					(full_IP	),
		.empty					(empty_IP	),
		.data_count    			(data_count_IP)
	);


initial begin
	clk<=0;
	rst<=1;
#2000
	rst<=0;
end
	
	always #5 clk<=!clk;

	reg		[31:0]		cnt;
	always @(posedge clk or posedge rst)
	begin
		if (rst) begin
			cnt		<= 0;
		end else begin
			if(cnt>=6000)
				cnt<=0;
			else
				cnt<=cnt+1;
		end
	end
	always @(*)
	begin
		if (rst) begin
			wr_en		<= 0;
		end else begin
			if(cnt>200&&cnt<3000 && full==0)begin
				wr_en		<= 1;
			end else
				wr_en		<= 0;
		end
	end


	always @(posedge clk or posedge rst)
	begin
		if (rst) begin
			din<=0;
		end else begin
			if(cnt>200&&cnt<3000 && full==0)begin
				din			<=din+1;
			end
		end
	end
	
	always @(*)
	begin
		if (rst) begin
			rd_en		<= 0;
		end else begin
			if(cnt>3000 && empty==0)begin
				rd_en		<= 1;
			end else
				rd_en		<= 0;
		end
	end

endmodule

1、写FIFO

FIFO空信号(empty):调用XPM原语和使用IP核一致,都在写入数据后1个周期拉低;

FIFO计数信号(count):调用XPM原语计数延迟2个周期(与手册一致),调用IP核计数延迟1个周期。

FIFO满信号(full):调用XPM原语和使用IP核一致,都在写入2048个数据后拉高;

2、读FIFO

FIFO满信号(full):调用XPM原语和使用IP核一致,都在读取数据后1个时钟周期后拉低;

FIFO计数信号(count):调用XPM原语计数延迟2个周期,调用IP核计数延迟1个周期。

FIFO输出信号(dout): 调用XPM原语和使用IP核一致,rd_en使能后下一个时钟周期输出数据,1个时钟周期延迟。

FIFO空信号(empty):调用XPM原语和使用IP核一致,都在读完2048个数据后1个周期拉高;

分析一下这段代码:`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: Gpixel CN // Engineer: // // Create Date: 2020/11/12 09:26:04 // Design Name: // Module Name: Serdes // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module Serdes( input ClkRx_Bit, input Clk_Stream, input Rst_Stream, input DataRx_p, input DataRx_n, output reg Stream_Valid, output reg [11 :0] Stream_Data, input [1 :0] BitMode, input BitToggle, input BitSlip, input Cmd_Align, output Ack_Align, input IODelayTapMan, input [4 :0] IODelayTapDataMan, output [4 :0] IODelayTapDataOut, output [4 :0] edge_s ); wire DataRx_IBUFDS; wire DataRx_IDELAYE2; wire [1 :0] DataRx_IDDR; reg [1 :0] DataRx_IDDR_d; reg [1 :0] DataRx; reg BitSlip_d = 1'b0; reg BitSlip_d2 = 1'b0; wire BitSlip_RE; reg src_BitSlip_RE = 1'b0; reg BitSlip_RE_q = 1'b0; reg BitSlip_Ack = 1'b0; reg BitSlip_Ack_q = 1'b0; reg BitToggle_d = 1'b0; reg BitToggle_d2 = 1'b0; wire BitToggleFlag; reg src_BitToggleFlag = 1'b0; reg [1 :0] BitMode_q = 2'b10; wire [4 :0] IODelayTapDataIn; wire [4 :0] IODelayTapDataAuto; reg StreamFifo_Rd = 1'b0; wire StreamFifo_Valid; wire StreamFifo_Empty; wire [11 :0] StreamFifo_Data; reg [2 :0] ShiftCnt = 3'd0; reg [11 :0] ShiftDataRx; reg [11 :0] DataRxPar_i = 12'd0; reg [11 :0] DataRxPar_i_d = 12'd0; //(*ASYNC_REG = "TRUE"*) reg [11 :0] DataRxBitEnable; reg [11 :0] Stream_Data_Align; reg [11 :0] Stream_Data_i; reg Stream_Valid_i; reg [2 :0] LoadParallelCnt = 3'd6; reg LoadParallel = 1'b0; reg LoadParallel_d = 1'b0; assign IODelayTapDataIn = (IODelayTapMan == 1'b1)? IODelayTapDataMan : IODelayTapDataAuto; //***********************************************************************************************// IBUFDS #( .DIFF_TERM("TRUE"), // Differential Termination .IBUF_LOW_PWR("FALSE"), // Low power="TRUE", Highest performance="FALSE" .IOSTANDARD("LVDS_25") // Specify the input I/O standard ) IBUFDS_inst ( .O(DataRx_IBUFDS), // Buffer output .I(DataRx_p), // Diff_p buffer input (connect directly to top-level port) .IB(DataRx_n) // Diff_n buffer input (connect directly to top-level port) ); // (* IODELAY_GROUP = <iodelay_group_TL> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(0), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(400.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst ( .CNTVALUEOUT(IODelayTapDataOut), // 5-bit output: Counter value output .DATAOUT(DataRx_IDELAYE2), // 1-bit output: Delayed data output .C(Clk_Stream), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(IODelayTapDataIn), // 5-bit input: Counter value input .DATAIN(), // 1-bit input: Internal delay data input .IDATAIN(DataRx_IBUFDS), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b1), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED" --<Q1><Q1> "SAME_EDGE_PIPELINED" --<Q1><Q1> "SAME_EDGE" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 --<Q2><Q2> --<Q2><Q2> .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst ( .Q1(DataRx_IDDR[0]), // 1-bit output for positive edge of clock .Q2(DataRx_IDDR[1]), // 1-bit output for negative edge of clock .C(ClkRx_Bit), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(DataRx_IDELAYE2), // 1-bit DDR data input .R(Rst_Stream), // 1-bit reset .S(1'b0) // 1-bit set ); //***********************************************************************************************// always@(posedge ClkRx_Bit) begin BitMode_q <= BitMode; case(BitMode_q) 2'b00: begin LoadParallelCnt = 3'd4; DataRxBitEnable = 12'b111111110000; end 2'b01: begin LoadParallelCnt = 3'd5; DataRxBitEnable = 12'b111111111100; end 2'b10: begin LoadParallelCnt = 3'd6; DataRxBitEnable = 12'b111111111111; end default: begin LoadParallelCnt = 3'd6; DataRxBitEnable = 12'b111111111111; end endcase end //--------------------------------------------------------------------------// always@(posedge ClkRx_Bit) begin DataRx_IDDR_d <= DataRx_IDDR; if (BitToggleFlag == 1'b0) begin DataRx <= {DataRx_IDDR[0],DataRx_IDDR[1]}; end else begin DataRx <= {DataRx_IDDR_d[1],DataRx_IDDR[0]}; end end //--------------------------------------------------------------------------// always@(posedge ClkRx_Bit) begin ShiftDataRx <= {DataRx[0],DataRx[1],ShiftDataRx[11:2]}; LoadParallel_d <= LoadParallel; DataRxPar_i_d <= DataRxPar_i; if (BitSlip_RE == 1'b1) begin ShiftCnt <= ShiftCnt; LoadParallel <= 1'b0; end else begin if (ShiftCnt == LoadParallelCnt - 1'b1) begin ShiftCnt <= 3'd0; LoadParallel <= 1'b1; DataRxPar_i <= ShiftDataRx & DataRxBitEnable; end else begin ShiftCnt <= ShiftCnt + 3'd1; LoadParallel <= 1'b0; end end end //--------------------------------------------------------------------------// fifo_serdes_w16_d16 inst_fifo_serdes_w16_d16( .rst (Rst_Stream ), .wr_clk (ClkRx_Bit ), .rd_clk (Clk_Stream ), .din (DataRxPar_i_d ), .wr_en (LoadParallel_d ), .rd_en (StreamFifo_Rd ), .dout (StreamFifo_Data ), .full ( ), .empty (StreamFifo_Empty ), .valid (StreamFifo_Valid ) ); //--------------------------------------------------------------------------// always@(posedge Clk_Stream) begin if(StreamFifo_Empty == 1'b0) begin StreamFifo_Rd <= 1'b1; end else begin StreamFifo_Rd <= 1'b0; end case(BitMode) 2'b00: begin Stream_Data_i <= {4'b0000,StreamFifo_Data[11:4]}; end 2'b01: begin Stream_Data_i <= {2'b00,StreamFifo_Data[11:2]}; end 2'b10: begin Stream_Data_i <= StreamFifo_Data; end default: begin Stream_Data_i <= StreamFifo_Data; end endcase Stream_Valid_i <= StreamFifo_Valid; Stream_Valid <= Stream_Valid_i; Stream_Data <= Stream_Data_i; end //--------------------------------------------------------------------------// always@(posedge Clk_Stream) begin BitToggle_d <= BitToggle; BitToggle_d2 <= BitToggle_d; if ((BitToggle_d == 1'b1)&&(BitToggle_d2 == 1'b0)) begin src_BitToggleFlag <= ~src_BitToggleFlag; end BitSlip_d <= BitSlip; BitSlip_d2 <= BitSlip_d; if ((BitSlip_d == 1'b1)&&( BitSlip_d2 == 1'b0)) begin src_BitSlip_RE <= 1'b1; end else begin src_BitSlip_RE <= 1'b0; end end xpm_cdc_pulse #( .DEST_SYNC_FF(4), // DECIMAL; range: 2-10 .INIT_SYNC_FF(0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values .REG_OUTPUT(1), // DECIMAL; 0=disable registered output, 1=enable registered output .RST_USED(0), // DECIMAL; 0=no reset, 1=implement reset .SIM_ASSERT_CHK(0) // DECIMAL; 0=disable simulation messages, 1=enable simulation messages ) xpm_cdc_pulse_inst ( .dest_pulse(BitSlip_RE), // 1-bit output: Outputs a pulse the size of one dest_clk period when a pulse // transfer is correctly initiated on src_pulse input. This output is // combinatorial unless REG_OUTPUT is set to 1. .dest_clk(ClkRx_Bit), // 1-bit input: Destination clock. .dest_rst(), // 1-bit input: optional; required when RST_USED = 1 .src_clk(Clk_Stream), // 1-bit input: Source clock. .src_pulse(src_BitSlip_RE), // 1-bit input: Rising edge of this signal initiates a pulse transfer to the // destination clock domain. The minimum gap between each pulse transfer must be // at the minimum 2*(larger(src_clk period, dest_clk period)). This is measured // between the falling edge of a src_pulse to the rising edge of the next // src_pulse. This minimum gap will guarantee that each rising edge of src_pulse // will generate a pulse the size of one dest_clk period in the destination // clock domain. When RST_USED = 1, pulse transfers will not be guaranteed while // src_rst and/or dest_rst are asserted. .src_rst() // 1-bit input: optional; required when RST_USED = 1 ); //--------------------------------------------------------------------------// xpm_cdc_single #( .DEST_SYNC_FF(4), // DECIMAL; range: 2-10 .INIT_SYNC_FF(0), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values .SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages .SRC_INPUT_REG(1) // DECIMAL; 0=do not register input, 1=register input ) xpm_cdc_single_inst ( .dest_out(BitToggleFlag), // 1-bit output: src_in synchronized to the destination clock domain. This output is // registered. .dest_clk(ClkRx_Bit), // 1-bit input: Clock signal for the destination clock domain. .src_clk(Clk_Stream), // 1-bit input: optional; required when SRC_INPUT_REG = 1 .src_in(src_BitToggleFlag) // 1-bit input: Input signal to be synchronized to dest_clk domain. ); //--------------------------------------------------------------------------// BitAlign inst_BitAlign( .Clk (Clk_Stream), .Reset (Rst_Stream), .data_par (Stream_Data_i), .Cmd_Bit_Align (Cmd_Align), .Ack_Bit_Align (Ack_Align), .edge_s (edge_s), .loc_eye_sam (), .idelay_valuein (IODelayTapDataAuto) ); endmodule
最新发布
07-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值