【DFT】MBIST (1) MBIST基础

该部分内容主要是 数字系统测试和可测试性设计(纳瓦比著_北京:机械工业出版社)一书中第九章中存储器测试部分的内容,算是作为 MBIST 入门。

1. 存储器测试

688 442 718

存储器包括易失性和非易失性存储器。

易失性存储器为RAM(随机存取存储器),它可以是静态或动态存储器(SRAM和 DRAM )。SRAM在通电时保留其存储值,而DRAM需要刷新。

非易失性存储器分为ROM(只读存储器)、PROM(可编程ROM ),EPROM(可擦除PROM )、UVPROM ( UV可擦除PROM )、EEPROM(电可擦除PROM ))和闪存存储器。

作为系统的一部分,存储器通常是存储的核心,它们可以用作可编程装置的一部分,也可以是独立的存储器芯片。无论存储器的类型、容量、结构如何,它们都是由许多带有时序逻辑的存储单元组成。Scan chain 可以利用组合测试方法的优点来把时序电路转变成组合电路。不幸的是,由于硬件的开销,我们不能在存储器上也做到这一点。如过将存储器作为能够达到由109个存储器单元组成的时序电路,并再测试这种测试电路的21G个状态的想法是绝对不可能成功的。

尽管有这些困难,存储器测试工作还是要进行的,而且也是无法回避的。由于每个系统都会以一种或者其他形式使用存储器,系统的功能是否正常在很大程度上取决于其存储器

在最近几年,特别是在如今SoC上有超过80%的芯片面积都被各种形式的存储器占用之时,此问题已经变得更加重要。

2. 存储器结构

存储器具有许多形式和容量,我们不能将它们分开处理。然而,由于它们有着共同的读写寻址结构,所以可以按照以下相同原则进行测试。这里简单介绍SRAM的结构(MBIST也主要是针对SRAM的吧,后续需要再确定一下)。

图11-1显示了一个存储器阵列的基本结构,它由 n x m 个单元排列在一个 n x m 的阵列中。存储器的硬件由存储单元阵列解码行和列地址的解码器读取/写入处理逻辑处理存储器阵列输入和输出的逻辑模块构成。

阵列中存储单元的准确排布依赖于芯片上的空间限制,与存储器字的长度和地址空间无关。

在这里插入图片描述

IO逻辑模块包括模拟读出放大器和用来从存储器阵列输出的数据中做选择,或将数据写入阵列中的逻辑单元

单个存储单元硬件结构在很大程度上依赖于存储器的类型。图11-2显示了一个SRAM和DRAM单元。

在这里插入图片描述

虽然可以使用传统测试技术测试所有的 IO 逻辑和单元,但我们并没有这么做。部分原因是如果这样做会使部分待测部件成为模拟器件(例如单元的IO逻辑和阵列),测试它们需要比我们的数字测试技术更为复杂的模拟技术。然而,如果将存储器模块作为一个整体的话,可以预见到在正确测试技术和适当故障模型的辅助下将可探测到周边逻辑单元及阵列的故障

3. 存储器故障模型

一个存储器模块包括模拟和数字部分。什么方法可以让存储器的测试比一个 n × m 模拟单元的测试更简单呢,那就是使用数字的周边逻辑作为接口测试存储器单元。然而,需要测试的大多数存储器单元的硬件都无法轻易地映射到逻辑固定故障模型之中。

此外,由于单元数量以及每个单元可能会具有的结构故障,构建存储器故障模型,尝试逐一测试此等故障(正如在逻辑测试中所做的那样)需要大量的资源。

所以,存储器测试的解决方案只能是使用功能性故障模型而不是构造性的并考虑同一时间内所有周边逻辑和存储器阵列的相关故障。

为了证明存储器的功能正常,存储器测试必须进行存储器单元阵列的读写操作测试。虽然此功能测试以阵列自身为主要目标,但我们也期盼使用相同的测试可测出周边逻辑内的故障

例如,需要考虑的事项有:由行解码器逻辑造成的故障,SRAM单元的字线(Word Line,WL)(见图11-2)固定于0(见图11-1 )。在此字线寻址的单元内写一个值(例如 0),然后试图读取它,这将导致读回以前的值,而不是新值0。

首先,这是一个存储单元的功能性测试,由于我们正在测试它的存储功能,它也应该执行这些操作。此外,本次测试的失败可以检测到驱动BL以及来自单元的BL线的IO逻辑功能故障。存储器故障模型描述如下。

3.1 固定故障(SAF)

固定存储器功能故障是一些使目标单元永久存储于其内的1或0的情况
—A cell is stuck-at-1 or 0; <∀/1> denotes a stuck-at-1 and <∀/0> denotes a stuck-at-0

为了测试此故障,应写入0,再将其读回,然后对1再做同样的事情。如果在这两种情况下,能读回相同的值,则可以认为该单元存储值固定在该值处。

3.2 转换故障(TF)

如果一个单元可以从 v ‾ \overline{v} v 变更为 v ‾ \overline{v} v,但周围没有其他方式,那么则说明存储值无法将 v ‾ \overline{v} v转换为 v。**转换故障(TF)**可以是1或0转换故障。

A cell fails to transit; it can be <↑/0> or <↓ /1>

3.3 耦合故障(CF)

由于邻接单元,许多单元共享字线和位线,将其写入一个单元可能导致另一个单元出现相同值

由于无法从存储器外部获知存储器阵列的组织,我们无法说出哪些单元共享位线,哪些单元共享字线,因此,在这两种单元的类型中均可出现连接耦合故障(Coupling Fault,CF )

如要测试CF,需在所有单元中写0,然后在一个存储单元写1。除了已经具有1值的单元外,读取所有其他单元值,检查其是否为1。另外,对相反值也要采取此流程。

其他CF类型有反向、幂和k单元耦合。

反向耦合(CFin, Inversion Couple Fault)是指当写入一个值到一个存储单元时,该值将反转另一个存储单元值。
A transition in one cell inverts the content of another。

当一个特定转换(0到1或1到0)将耦合单元转变为一个特定值( 0 或 1 )即为幂耦合(CFid, Idempotent Couple Fault )
A transition in one cell forces a constant value (1 or 0) into another; that is, <↑;1/0>, <↑;0/1>, <↓;1/0>, or <↓;0/1>.

k 单元耦合的当两个或两个以上单元间出现CF, k 在此情况下为参与的单元数。

3.4 桥接和状态耦合故障

两个或两个以上位线短接在一起就造成了桥接故障(Bridge Fault,BF )。根据短路后面的逻辑,短路表现值为两个单元的与/或逻辑。固定故障检测了一些桥接故障。

除了所致短路仅会影响一个单元、其他单元不受影响之外,状态耦合故障类似于BF。

4. 功能测试方法

本节解释了一些存储单元可能会互相影响对方的功能效应。这样就能够轻易地理解,**如果想完整和详尽地测试存储器阵列,必须在读取所有其他单元之时,将0和1读/写入每个单元以观察其他单元是否受到影响。**显然,详尽地执行此过程会导致测试时间变长。尽管有很多存储器测试方法能支持这个彻底的测试,但还有一些其他的尝试将测试复杂性以及时间降至 O(N) 的方法,其中N是存储器总位数(近似值)。

4.1 March 测试算法

March测试就是一个 О(N) 复杂性测试。

March测试是:当以第一存储器位置开始写入1(或0)时,这些位置会保留其1(或0)写入值,因此,看起来1(或0)像是从位置0一直步进至存储器中最后的位置。
(进行下个单元之前,施加 March 测试矢量到存储器的每个单元,这意味着如果施加特殊矢量到一个单元,那么必须将它施加到所有单元。这是通过增加存储器地址顺序 ( 从 0 到 n-1 ) 或降低地址顺序进行的)

一开始,我们是以一般存储器 March 测试类别的存储器测试算法来解释 March C 测试的。March-C 在每一个存储器位置以 0 开始(所有N1位)。然后,我们开始从位置 0 以升序排序的方法读取并检查 0 实际上在不在那里,对每个已经检查了的位置写入 1 。因此 1 的步进是以升序排列的,持续检查和写入 1 直到我们读取到存储器的最后一位。这时,所有的存储器位都包含1。现在反转这一过程,对我们以递减顺序读取 1,并将每次读取的位置写为0。在反向过程中,从位置 N-1 处以递减顺序步进。然后重复同样的测试,在所有 N 位置上以 1 开始测试。

大多数 March 测试的方法可以像上述 March-C 段落那样来解释。然而,为了便于理解,Van de Goor 设计出一个记法,其中的一个子集示如图 11-3 所示,此符号简单地指出了测试步骤,从中可以很容易地看出确定一个测试步骤顺序的读/写的数量。
在这里插入图片描述

4.2 March-C 算法

使用图 11-3 的记法,March-C 存储器测试算法如下描述:

在这里插入图片描述
本次测试的具体步骤如下,上述表达式或者下述的步骤显示了March -C 使用了 10 个读/写操作,其顺序为 10N。

March-C 的测试步骤:
在这里插入图片描述

4.3 MATS+ 算法

MATS 是 Modified Algorithm Test Sequence 的缩写,MAST+ 是另一种存储器测试算法。该算法比 March-C 算法简单一些,能够检测的故障也较少。

MATS+ 可以表示如下:
在这里插入图片描述
MATS+ 步骤如下:
在这里插入图片描述

4.4 其他的 March 测试

在这里插入图片描述
参考资料:

  1. Knaizuk[AU3] J Jr,Hartmann CRP (1977)An optimal algorithm for testing stuck-at faults in Random AccessMemories.IEEE Trans Comput C-26(11):1141-1144
  2. Nair R (1979) Comments on an optimal algorithm for testing stuck-at faults in Random-Access Memories. IEEEBTrans Comput C-28(3):258-261
  3. Abadir MS,Reghbati JK (1983) Functional testing of Semiconductor Random Access Memories. ACM ComputSurv 15(3):175-198
  4. Winegarden S, Pannell D (1981)Paragons for memory test. In: Proceedings of the International Test Conference,Oct.1981, pp. 44 48
  5. van de Goor AJ(1991) Testing semiconductor memories: theory and practice. Wiley, Chichester, UK.
  6. Marinescu M (1982)Simple and efficient algorithms for functional RAM Testing. In: Proceedings of theInternational Test Conference, Nov.1982,pp. 236-239
  7. Suk DS, Reddy SM (1981)A March test for functional faults in Semiconductor Random-Access Memories.IEEETrans Comput C-30(12):982-985
  8. Bushnell ML, Agrawal VD (2000)Essentials of electronic testing for digital, memory & mixed-signal VLSl circuits. Kluwer, Norwell, MA.

5. MBSIT方法

我们已经进入了在单个芯片上集成来自不同公司的各种版图或称(IP core)的时代。例如,现在一个定制 VLSI 芯片可能包含嵌入式 RAM、微处理器、DSP 处理器和多种模拟电路版图。嵌人式 RAM 存储器可能是最难于测试的数字电路类型,因为存储器测试需要给存储器提供大量的测试矢量激励并读出大量的单元信息。在一个嵌入式核芯片中,通过各种胶连逻辑和总线传递所有这些信息所遇到的困难和所需要的时间,几乎使存储器BIST成为必须使用的方法。
对存储器可测试性设计( DFT),存储器测试算法中最耗费时间的部分在芯片上实现,这使存储器测试时间降低了一个数量级168。

使用嵌入存储器结构的专用数字硬件组件来执行存储器测试有如下几个原因。
首先,存储器测试向量非常有规律,可以用简单的计数器和移位寄存器轻松创建。
其次,存储器测试涉及一些从存储器中写入和读取数据的迭代行为,且计时器可以时序顺序轻易地追踪它们。
最后,由于存储器在芯片系统可靠性测试中扮演着重要的角色,应定期在不将其从系统中拆除的条件下对其进行测试
本节介绍了几个 MBIST 结构,它们能够实现功能测试部分描述的算法或算法的各种不同类型。

5.1 简单的 March MBIST

使用 MBIST 来实现简单的 March 存储器测试算法,包括电路结构、控制器等。
(存储器 MBIST 需要一个地址生成器或者步进器,和一个数据生成器,地址生成器可以是二进制计数器,也可以用LSFR来实现,这里只是给出了一个使用 MBIST 来实现 March 测试算法的简单示例,可以有很多的优化,而且针对不同类型的存储器,也会需要不同类型的测试算法。)

1. 简单的March MBIST结构

MBIST结构如图11-6所示。要测试的存储器以灰色显示,实线模块显示了测试电路。所使用的测试数据是通过MBIST电路生成的并应用在存储器中。随着数据从存储器中不断读出,将其与指定存储器位置处的相同数据进行比较。写入和读取所有位置后,我们期待从存储器中读取的所有数据都与写入值相同

在这里插入图片描述
计数器

计数器会提供输入数据、地址、存储器的读/写切换。
计数器的最低有效位提供了所有存储器位置的寻址。计数器用于地址的计数,在读写操作时,计数器输出的地址值会不断变换。
计数器的三个最大有效位被解码,以生成用于测试存储器字的8个测试向量

计数器的 verilog 代码如下:

module counter
	#(parameter length = 10) (d_in, clk, ld, u_d, cen, q, cout);
	
	input [length-1:0] d_in;
	input clk, ld, u_d, cen;
	output [length-1:0] q;
	output cout;

	reg [length:0] cnt_reg;

	always@(posedge clk) begin
		if(cen) begin	//cen应该是计数器使能端口
			if(ld) 
				cnt_reg <= {1'b0,d_in};
			else if(u_d)
				cnt_reg <= cnt_reg + 1;
			else
				cnt_reg <= cnt_reg - 1;
		end
	end
	
	assign q = cnt_reg[length-1:0];
	assign cout = cnt_reg[length];

endmodule

解码器

测试数据解码器使用一个3位输入向量查询存储器测试向量(如图11-8所示)。
在这里插入图片描述
解码器的 verilog 代码如下:

module decoder(input [2:0] in, output [7:0] out);
	wire [7:0] out_temp;
	
	assgin out_temp = (in[1:0] == 2'b 11) ? 8'b 01010101 :
					  (in[1:0] == 2'b 10) ? 8'b 00110011 :
					  (in[1:0] == 2'b 01) ? 8'b 00001111 :
					  (in[1:0] == 2'b 00) ? 8'b 00000000 :
					  8'b zzzzzzzz;
	assgin out = (in[2] == 1'b 0) ? out_temp : ~out_temp;
endmodule

多路选择器
图11-6所示的内建自测试结构的多路选择器的选择介于正常存储器输入和内建自测试所提供的输入之间。
当 NbarT 为 “ 0 ” 时,该存储器在正常模式下工作,当这个输入变为 “ 1 ”,则在测试模式下运行。

比较器
最初,将相同的测试向量写入所有的存储器位置,然后从这些位置读出这些数据。随着数据被写入和读出,解码器输入,从而保持测试向量不变。比较器会检查存储器数据并将其与解码器输出比较。当存储器被测试时和读取数据时,比较器的输人应该是相同的数据。

2.测试会话

当计数器是全0时,一个测试会话开始,当计数器达到全1时,该会话结束。
以所有0开始,将测试向量 0 写入位置 0。

随着计数器递增,所有存储器位置写入同样的向量。当写入所有存储器位置,计数器递增,这将造成至少相当一部分(地址位)翻转到全 0,rwbar 位变为 1 。 ( 这里 rwbar 应该是存储器读写控制器)

当发生此情况时,所有存储器位置处的读取数据相同。这样做时,rwbar 位变为 0,地址开始返回0,下一个测试向量开始被写入到所有位置。

此过程一直持续8个测试向量。完成后,所有的测试向量已被写入所有存储器位置并从中读取。与此同时,比较器会检查是否有错配,如果有,则发出错误检查信号。

个人理解:

这里就是,q[6] 为 1 之后,存储器执行读功能,然后q[5:0]的计数从低到高访问了刚刚进行写操作的内存单元。也就是说,q[6:0] 从全 0 到全 1 的过程,完成了对部分存储器单元的读写操作,这个时候 q [9:7] 是保持不变的,一直是000,也就是输出向量是不变的。当 q[6:0] 全为 1 之后,q[9:7]变为001,q[6:0]变为全0。q[9:7] 变化意味着输入向量的变化,q[6:0]全0,就意味着要开始新的一轮循环了。

这里也可以看的出来,当存储器很大的时候(一是datain的位数,一是存储空间的大小),就需要很多 bit 的计数器来完成测试。

在这里插入图片描述

3. 简单的 MBIST 控制器

当内建自测试控制器接收到启动信号时启动计数器,并等待计数器的进位。

(启动信号是外部给的,计数器进位表示测试结束。)

该控制器的Verilog 代码下所示:

module BIST_controller(input start, rst, clk, cout, output NbarT, ld);
	
	reg current = reset;
	
	parameter reset = 1'b 0, test = 1'b 1;
	
	always@(posedge clk) begin
		if(rst)
			currrent <= reset;
		else
			case(current)
				reset: if(start)
							current <= test;
					   else
							current <= reset;
				test: if(cout)
							current <= reset;
					  else
					  		current <= test;
				default:
							current <= reset;
			endcase
		end
	
	assgin NbarT = (current == test) ? 1'b 1 : 1'b 0;
	assgin ld = (current == reset) ? 1'b 1 : 1'b 0;	
endmodule

4. 简单的March BIST 结构

下面所示的 Verilog 代码显示了完整的内建自测试结构(包括正在测试的RAM)。在这里描述的已实例化的组件是根据图11-6所示的方框图完成的。除了已经实例化的组件,代码有一个 always 语句,它会在比较器发现错配之时发出失败标志的语句

module BIST # (parameter size = 6, length =8)
			  (start, rst, clk, csin, rwbarin, opr, address, datain, dataout, fail) ;
	input start, rst, clk, csin, rwbarin, opr;
	input [size-1:0] address;
	input [length-1:0] datain;
	output [length-1:0] dataout;
	output fail;
	reg fail;
	reg [9:0] zero;
	
	wire cout, ld, NbarT, cs, rwbar, gt, eq, lt;
	wire [9:0] q ;
	wire [7:0] data_t;
	wire [length-1:0] ramin, ramout, bit_array;
	wire [size-1:0] ramaddr;
	reg [iength-1:0] ram_testvalue;
	reg conv_enable;
	integer i, index, power, mult;
	integer faulty_adr, faulty_bit;
	initial zero = 10'b 0000000000;
	
	BIST_controller CNTRL (start, rst, clk, cout, NbarT, ld);
	counter CNT (zero, clk, ld, 1'b1, 1'b1, q, cout);
	decoder DEC (q[9:7], data_t);
	multiplexer #(8) MUX_D (datain, data_t, NbarT, ramin);
	multiplexer #(6) MUX_A (address, q[5:0], NbarT, ramaddr);
	
	assign rwbar = (~NbarT) ? rwbarin : q[6];
	assign cs = (~NbarT) ? csin : 1'b l;
	
	RAM MEM(ramaddr, ramin, cs, rwbar, opr, ramout);
	comparator CMP (data_t, ramout, gt, eq, lt);

	always @ (posedge clk) begin
		if( NbarT && rwbar && opr)
			if(~eq) begin
				faii <= 1'b1;
			end else begin
				fail <= 1'b0 ;
			end
		end
assign dataout = ramout;endmodule
endmodule

5. MBIST测试机

存储器及其内建自测试需在 BIST_tester 测试平台(testbench)上进行测试,此测试平台如图11-12所示。
(BIST也是用verilog实现的带电路,当然也需要 testbench 来验证功能是否正常。)

最初,测试平台会在当操作数变为 1 的 5ns 内将外部文件数据加载到存储器内,然后经过一些任意时间,使数据从存储器中读取和写入。待开始于50ns 处变为1时,内建自测试的测试会话开始,测试将继续进行直到所有 RAM 位置已经过测试。当存储器接受测试之时,需忽略外部读取和写入操作。

testbench 代码如下:

module BIST_tester ();
	reg [7:0] ramin;
	reg [5:0] addr;
	reg cs, rwbar, start;
	reg rst, clk;
	reg operate;
	wire [7:0] ramout;
	wire fail;
	
	initial begin
		cs = 0;
		rwbar = l;
		start = 0;
		rst = 0;
		operate = 0;
		clk = 0;
	end
	
	BIST UUT (start,rst,clk,cs,rwbar,operate,addr,ramin,ramout,fail);
	
	always #5 clk = ~clk;
	
	initial begin
		#5 operate =1'b1;
		#5 ramin = 8'b11110001;
		#5 cs = 1'b1;
		#5 addr =6'b101100;
		#10 ramin =8'b00101100;
		#10 addr =6'b101110;
		#10 start =1'b1;
		#140 rwbar = 1'b1;
		#147 cs =1 'b0;
		#463 operate =1'b0;
	end
endmodule

5.2 March-C MBIST计数-排序器

March-C 算法在第 4 节中已讨论过。对图11-6所示的 Match- C算法实现的结构做一些很小的改变后,见图11-13。

请注意在此结构中控制存储器 rwbar 的附加逻辑。用一个计数 - 排序器来替代简单 March 中的计数器,并处理 March-C 测试的10个阶段。在这里,我们正在处理一个有 8 位字长的存储器并测试 1 位深度的存储器局部。此字级实现并不是准确的 March-C 测试实现。
在这里插入图片描述

1. Match-C MBIST 计数-排序器

地址、地址生成方向(从最高到最低或与之相反)、测试数据、读取和写人存储器切换等功能由一个 13 位计数器处理。

计数 - 排序器的 6 个最低有效位可为所有存储器位置提供寻址。位地址组左侧的随后四位指定了 Match-C 的10个连续读/写操作。此外,对这四位和计数 - 排序器三个最高有效位进行解码,以生成测试存储器字的相应的测试向量

根据 Match-C 算法,在步骤1和步骤6中,地址递增(或递减),对具体地址而言只会发生读写操作。在所有其他的步骤中,读取和写入操作必须在进入到下一地址之前完成。为了实现这一点,当计数 –排序器位于步骤 1 或步骤 6 时,计数–排序器行为正常,每一时钟周期递增或递减1。在所有其他的步骤中,存储器的地址(6个最低有效位(cnt_reg[5:0] )在连续两个周期内不发生变化,但 cnt_reg[9:6] 先递增后递减1,此计数器的 Verilog 代码如下:

在这里插入图片描述在这里插入图片描述

2. 解码器

测试数据解码器使用一个7位输入向量来生成存储器测试向量和即将用来与存储器输出值进行比较的值

对于每个存储器字的每一位来说,都要使用 March-C 算法的所有6个步骤(即包含10个操作),因此使用3个最高有效的输入位对存储器的字执行10个指定操作。解码器指定必须将哪个测试值写人到存储器字之中

March-C MBIST硬件的其余部分必须与简单的 March 测试机中讨论的那些硬件相同。

解码器的 Verilog 代码如下:

在这里插入图片描述在这里插入图片描述

5.3 干扰 MBIST

干扰测试是在相邻单元状态发生变化时,用来研究闪存或 DRAM 单元数据存储鲁棒性的测试

在干扰测试中,在 “ 干扰写入状态 ” 的整个阵列中会写入一个棋盘模式。当有时间来处理数据时可从 “ 干扰读取状态 ” 中将这个模式读取回来,这是总数据保留故障的快速检查法。对于一个 N 位容量的存储器来说,干扰测试算法的复杂度为 O(N)。

该方法的一个 MBIST 具有与图11-6 相同的基本结构,只不过测试数据生成的方式有所不同。

在图11-6 中,解码器使用一个3位输入向量来寻找合适的存储器测试向量,而在该方法中,新的测试向量是用 walking-0 电路生成的。

在干扰测试MBIST中,会在所有存储器单元中写入一个初始值,在一定的延迟后,将从存储器中读取的数据与写入的数据进行比较。接着,初始数据向左翻转以形成新的测试向量。此过程会一直持续至每个存储器字(m)中每一位上的初始值都已经翻转。这将导致需检查每个存储器单元0至1和1至0的翻转。在读/写所有位置后,我们预期从存储器中读取的所有数据会与其初始值一样。

1. 干扰内建自测试 walking-0

walker 测试向量产生器使用一个3位输入向量来确定必须应用到初始测试值的左旋数量。存储器测试向量见图11-16,

在这里插入图片描述

walker测试产生器的 Verilog 代码如下:

在这里插入图片描述

2. 干扰结构

如下所示 Verilog 代码为干扰测试 MBIST (包括正在测试的存储器)的一部分代码。

在本描述中已实例化的组件是根据图 11-6 的框图完成的,主要区别是将图11-6中的解码器换成了一个具有 walking-0 电路的解码器

在这段代码中,第一行的 always 模块用来在比较器发现不匹配时发出故障标志,它也指定了故障地址和故障位。这个MBIST代码是一个综合的 Verilog,通过检查就可以轻易地了解其硬件相关性。

在这里插入图片描述

  • 15
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值