暑期实习准备——Verilog手撕代码(持续更新中。。。

news2024/12/28 20:25:49

暑期实习准备——手撕代码

  • 牛客刷题笔记
    • Verilog快速入门
      • VL4 移位运算与乘法
      • VL5 位拆分与运算
      • VL6 多功能数据处理器
      • VL8 使用generate…for语句简化代码
      • VL9 使用子模块实现三输入数的大小比较
      • VL11 4位数值比较器电路
      • VL12 4bit超前进位加法器电路
      • VL13 优先编码器电路①
    • Verilog进阶挑战
    • Verilog企业真题
  • 常见数字IC手撕代码

牛客刷题笔记

牛客Verilog题库

Verilog快速入门

VL4 移位运算与乘法

在这里插入图片描述

  • 要点1:题目用状态机实现,经典的两段式模板。
  • 要点2:需要一个d_reg信号临时记录当前要加倍的d信号,这样才能保证d信号变化时,加倍的仍然是原本的d信号,注意d_reg<=d;赋值语句应该在11状态,即每一轮状态转换结束后,开启新一轮状态前。
  • 要点3:always @ (posedge clk or negedge rst or current_state) 第二段的敏感事件表套模板的时候误删了current_state信号,导致所有的状态机状态转换被延长了一拍,因此这里的敏感时间表一定要将记住写current_state。
  • 要点4:注意为状态机以及其他输出信号赋初始值。
  • 要点5:1、3、7、8倍数通过移位运算和加运算实现,不需要乘法运算。
`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
reg [1:0] current_state,next_state;
reg[7:0] d_reg;
//*************code***********//

always @ (posedge clk or negedge rst) begin
    if(!rst) current_state<=2'b00;
	else current_state<=next_state;//非阻塞赋值
end

always @ (posedge clk or negedge rst or current_state) begin
    next_state<=2'b00;
    if(!rst) begin
        input_grant<=1'b0;
        out<=11'b0;
        d_reg<=d;
    end
    else begin
	case(current_state)
		2'b00:begin
			input_grant<=1'b1;
			out<=d_reg;
			next_state<=2'b01;
		end
		2'b01:begin
			input_grant<=1'b0;
			out<= d_reg + {2'b0, d_reg, 1'b0};
			next_state<=2'b10;
		end
		2'b10:begin
			input_grant<=1'b0;
			out<=d_reg + {2'b0, d_reg, 1'b0} + {1'b0 ,d_reg, 2'b00};
			next_state<=2'b11;
		end
		2'b11:begin
			input_grant<=1'b0;
			out<={d_reg, 3'b000};
			next_state<=2'b00;
			d_reg<=d;
		end
	endcase
    end
end
//*************code***********//
endmodule

VL5 位拆分与运算

在这里插入图片描述

  • 要点1:仔细读题,注意题目中提到的只有在sel=0时输入才有效,因此需要reg_d把输入d锁存。
  • 要点2:仔细读题,还是要理解题目的意思。
`timescale 1ns/1ns

module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,

output reg [4:0]out,
output reg validout
);
//*************code***********//
reg [15:0] reg_d;

always @ (posedge clk or rst or d) begin
    if(!rst) begin
        out<=5'b0;
		validout<=0;
    end
    else begin
        case(sel)
			2'b00:begin out<=5'b0; validout<=0; reg_d<=d ;end
			2'b01:begin out<=reg_d[3:0]+reg_d[7:4]; validout<=1; end
			2'b10:begin out<=reg_d[3:0]+reg_d[11:8]; validout<=1; end
			2'b11:begin out<=reg_d[3:0]+reg_d[15:12]; validout<=1; end
		endcase
    end
end
//*************code***********//
endmodule

VL6 多功能数据处理器

在这里插入图片描述

  • 要点1:有符号数以补码形式存储,可以直接进行加减运算。
  • 要点2:always @ (posedge clk or negedge rst_n) 的写法是正确的,但有点疑惑是初始状态下就是低电平会不会触发,本题既然是正确的就说明初始低电平会触发。
    always @ (posedge clk or rst_n) 的写法是错误的,会在rst_n由0变为1时触发,但此时可能并非时钟上升沿,造成异常输出。
    always @ (posedge clk)的写法会使得初始状态下输出信号处于无效状态,额外在always块前加上initial c<=9'b0;这样可以通过测试用例,但是initial语句不可综合,最好不要使用。
`timescale 1ns/1ns
module data_select(
	input clk,
	input rst_n,
	input signed[7:0]a,
	input signed[7:0]b,
	input [1:0]select,
	output reg signed [8:0]c
);

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        c<=9'b0;
    end
    else begin
        case(select)
			2'b00:begin c<=a; end
			2'b01:begin c<=b; end
			2'b10:begin c<=a+b; end
			2'b11:begin c<=a-b; end
		endcase
    end
end
endmodule

VL8 使用generate…for语句简化代码

在这里插入图片描述

  • 要点1:必须使用genvar声明循环变量。
  • 要点2:begin-end之间插入赋值语句,begin后面必须声明循环实例的名称。
  • 要点3:generate-for常用来简化assign的赋值,assign data_out[i]=data_in[7-i];展开后的8条assign语句是并行赋值的。如,在6线-64线、8线-256线译码器中可以用来简化代码。
`timescale 1ns/1ns
module gen_for_module( 
    input [7:0] data_in,
    output [7:0] data_out
);

    genvar i;
    generate for(i=0;i<=7;i=i+1)
        begin:label
            assign data_out[i]=data_in[7-i];
        end
    endgenerate
endmodule

VL9 使用子模块实现三输入数的大小比较

在这里插入图片描述

  • 要点1:两个比较器会导致进入比较器的三个输入时间不同步,需要使用三个子模块才可以正确实现。
    在这里插入图片描述
    在第一个上升沿,ab进入第一个比较器,c进入第二个比较器。但是比较器输出是需要时间的,在第一个上升沿,c立刻进入第二个比较器,但ab比较器的输出会较晚的进入第二个比较器,这就造成了输入时间不同步,从而造成输出错误。
    使用三个比较器将c延迟一拍,就可以让输入子模块的时间都相等,从而不会出现进入时间不同导致的错误。
    在这里插入图片描述
    我们可以对波形进行分析来比较这两种写法的差别,testbench如下:
`timescale 1ns/1ns
module testbench();
	reg signed [7:0] a,b,c;
	reg clk,rst_n;
	wire [7:0]d;
main_mod dut(
	.clk(clk),
	.rst_n(rst_n),
	.a(a),
	.b(b),
	.c(c),
	.d(d)
);
always #5 clk = !clk;
initial begin
	clk=0;rst_n=0;
	#5 rst_n=1;
	#10 a=2;b=3;c=4;
	#10 a=4;b=2;c=1;
	#10 a=5;b=4;c=3;
end
endmodule

三个比较器的仿真波形如下。可以看到每一次比较的结果都在下一个时钟周期输出,分别为2,1,3。
在这里插入图片描述
二个比较器的仿真波形如下,此时比较结果为1,2,3,这是因为上一轮a,b的最小值实际上是与当前周期的c进行比较的,因此对于第一组输入,a和b的比较结果是2,2和下一组输入的c=1进行了比较,所以输出的最小值是1;同样第二组输出,a和b的比较结果是2,2和下一组输入的c=3进行了比较,所以输出为2;第二组输出,a和b的比较结果是4,4和下一组输入的c=3进行了比较,所以输出为3。
在这里插入图片描述

  • 要点2:子模块中c<=(a>b)?b:a;语句需要使用非阻塞赋值。
    不知道为什么非阻塞不会报错,阻塞会报错显示有用例不通过。使用vivado综合出来的电路这两个是一样的。待解决!!!
    在这里插入图片描述
    在这里插入图片描述
    但还是复习一下阻塞赋值和非阻塞赋值
    非阻塞赋值b <= a; :非阻塞赋值中赋值并不是马上执行的,也就是说"always"块内的下一条语句执行后,b并不等于a,而是保持原来的值。"always"块结束后,才进行赋值。
    阻塞赋值b=a;:方式是马上执行的。也就是说执行下一条语句时,b已等于a。
`timescale 1ns/1ns
module main_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	input [7:0]c,
	
	output [7:0]d
);
wire [7:0] ab,ac;
sub_mod U1(.clk(clk),.rst_n(rst_n),.a(a),.b(b),.c(ab));
sub_mod U2(.clk(clk),.rst_n(rst_n),.a(a),.b(c),.c(ac));
sub_mod U3(.clk(clk),.rst_n(rst_n),.a(ab),.b(ac),.c(d));
endmodule

module sub_mod(clk,rst_n,a,b,c);
	input clk,rst_n;
	input[7:0] a,b;
	output [7:0] c;
	reg[7:0]c;
	always@(posedge clk or negedge rst_n)begin
		if(~rst_n)c<=8'b0;
		else begin
			c<=(a>b)?b:a;
		end
	end
endmodule

VL11 4位数值比较器电路

要点1:题目中说要用门级描述完成,对于1bit数的比较对应的门运算如下,A>B对应~A&B,A<B对应A&~B,A=B对应~(A^B)。

`timescale 1ns/1ns

module comparator_4(
	input		[3:0]       A   	,
	input	   [3:0]		B   	,
 
 	output	 wire		Y2    , //A>B
	output   wire        Y1    , //A=B
    output   wire        Y0      //A<B
);

assign Y2=(A[3]>B[3])|((A[3]==B[3])&(A[2]>B[2]))|((A[3]==B[3])&(A[2]==B[2])&(A[1]>B[1]))|((A[3]==B[3])&(A[2]==B[2])&(A[1]==B[1])&(A[0]>B[0]));
assign Y1=(A==B);
assign Y0=(A[3]<B[3])|((A[3]==B[3])&(A[2]<B[2]))|((A[3]==B[3])&(A[2]==B[2])&(A[1]<B[1]))|((A[3]==B[3])&(A[2]==B[2])&(A[1]==B[1])&(A[0]<B[0]));
endmodule

要点2:抽象描述可以写到直接比较A和B。

`timescale 1ns/1ns
module comparator_4(
	input		[3:0]       A   	,
	input	   [3:0]		B   	,
 	output	 wire		Y2    , //A>B
	output   wire        Y1    , //A=B
    output   wire        Y0      //A<B
);
assign Y2=(A>B)?1:0;
assign Y1=(A==B)?1:0;
assign Y0=(A<B)?1:0;
endmodule

VL12 4bit超前进位加法器电路

在这里插入图片描述

加法器与半加器
超前进位加法器

1比特进位加法器的两种实现:

//实现1:逻辑代数
assign sum=a^b^cin;
assign cout=a&b|(cin&(a^b));或者assign cout=(a&b)|(a&cin)|(b&cin);
//实现2:抽象描述
assign {cout,sum}=a+b+cin;

assign cout=(a&b)|(a&cin)|(b&cin);很容易理解,即a,b,cin中任意两个或以上为1就进位。
assign cout=a&b|(cin&(a^b));可以理解为除了a,b为1的情况外,还有c为1同时 a和b中任意一个为1(a^b)。

多位数进位加法器
多位数进位加法器的实现有两种方式:串行进位加法器、超前进位加法器。
串行进位加法器就是将1比特加法器级联。
超前进位加法器是对串行全加器进行改良设计的并行加法器,以解决普通全加器串联互相进位产生的延迟。
一位全加器的进位的运算逻辑(前面的式子是(A^B)这里是(A|B),对结果没有影响,|包含了^):
在这里插入图片描述
其中,令进位函数Gi = AiBi, 令进位传送函数Pi = Ai + Bi
在这里插入图片描述
对于4比特超前进位加法器来说,进位输出如下:
在这里插入图片描述

Si=Ai^Bi^(CI)i,对应的(CI)i=(CO)i-1,即Si=Ai^Bi^(CO)i-1。通过前面的推导已经得出了,可得:
在这里插入图片描述

  • 要点1:需要明确4bit超前进位加法器的原理与推导过程,上一位运算的输出CO是下一位运算的输入CI,COi=(Ai&Bi)|(CIi&(Ai|Bi))。
  • 要点2:仿真自测时定义了一个8bit数num每个时钟周期累加1,将低4比特和高4比特赋值给A和B,需要注意的是给num赋初值!!!要不然仿真波形一片红!!!
`timescale 1ns/1ns

module lca_4(
	input		[3:0]       A_in  ,
	input	    [3:0]		B_in  ,
    input                   C_1   ,
 
 	output	 wire			CO    ,
	output   wire [3:0]	    S
);
wire[3:0] g,p,c;
assign p=A_in|B_in;
assign g=A_in&B_in;
assign c[0]=g[0]|(p[0]&C_1);
assign c[1]=g[1]|(p[1]&(g[0]|(p[0]&C_1)));
assign c[2]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&C_1)))));
assign c[3]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&C_1))))))); 
assign CO=c[3];

assign S=A_in^B_in^{c[2:0],C_1};
endmodule

测试代码:

`timescale 1ns/1ns
module testbench();
reg[3:0] A_in,B_in;
reg C_1;
wire CO;
wire[3:0] S;
reg[7:0] num;

lca_4 U1(.A_in(A_in),.B_in(B_in),.C_1(C_1),.CO(CO),.S(S));
initial begin
	C_1=0;
	num=0;
end
always #10 begin 
	num=num+1;
	A_in<=num[3:0];
	B_in<=num[7:4];
end
endmodule

VL13 优先编码器电路①

在这里插入图片描述

要点1:题目给的是I1-I9,注意顺序。
要点2:casecasezcasex三者都是可以综合的。case进行全等匹配,casez忽略?z对应的位进行匹配,casex忽略x?z对应的位进行匹配。

`timescale 1ns/1ns
module encoder_0(
   input      [8:0]         I_n,
   output reg [3:0]         Y_n   
);
always@(I_n)begin
	casez(I_n)
	9'b111111111:Y_n<=4'b1111;
	9'b0????????:Y_n<=4'b0110;
	9'b10???????:Y_n<=4'b0111;
	9'b110??????:Y_n<=4'b1000;
	9'b1110?????:Y_n<=4'b1001;
	9'b11110????:Y_n<=4'b1010;
	9'b111110???:Y_n<=4'b1011;
	9'b1111110??:Y_n<=4'b1100;
	9'b11111110?:Y_n<=4'b1101;
	9'b111111110:Y_n<=4'b1110;
	endcase
end
endmodule

要点3:《CPU设计实战》这本书中提到在CPU设计中必须遵守的硬性规定是代码中禁止出现casezcasex,因此可以采用如下写法,看Y9~Y0中出现的第一个0的位置。

`timescale 1ns/1ns
module encoder_0(
   input      [8:0]         I_n,
   output     [3:0]         Y_n   
);
assign Y_n=(~I_n[8])?4'b0110:
		   (~I_n[7])?4'b0111:
		   (~I_n[6])?4'b1000:
		   (~I_n[5])?4'b1001:
		   (~I_n[4])?4'b1010:
		   (~I_n[3])?4'b1011:
		   (~I_n[2])?4'b1100:
		   (~I_n[1])?4'b1101:
		   (~I_n[0])?4'b1110:
					 4'b1111;
endmodule

Verilog进阶挑战

Verilog企业真题

常见数字IC手撕代码

数字IC笔试面试题汇总

  1. 异步fifo。格雷码的镜像对称。格雷码和二进制的互相转换。
  2. 同步fifo。
  3. 除法器。
  4. Wallace乘法器。
  5. Booth乘法器。
  6. Booth+Wallace乘法器。
  7. 超前进位加法器。
  8. 边沿检测,输入消抖,毛刺消除。
  9. 异步复位同步释放。
  10. 三种计数器。二进制,移位,移位+反向。
  11. 无毛刺时钟切换。
  12. 串行-并行CRC。(ARM)。
  13. 线性反馈移位寄存器。
  14. 握手实现CDC。
  15. AXI-S接口,2T一次传输,1T一次传输,1T一次传输还要寄存器寄存。(Nvidia考题)Xilinx有例程。
  16. 其他简单功能的HDL实现以及状态转换图。(序列检测 ,回文序列检测(NVIDIA),奇、偶、半分频,小数分频,自动售货机)。

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

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

相关文章

Scala-模式匹配

基本语法 模式守卫 匹配类型 匹配对象 Scala 中的模式匹配类似于 Java 中的 switch 语法 基本语法 模式匹配语法中&#xff0c;采用 match 关键字声明&#xff0c;每个分支采用 case 关键字进行声明&#xff0c;当需 要匹配时&#xff0c;会从第一个 case 分支开始&#…

C++学习笔记-内存空间

考虑这样一种情况&#xff0c;当我们使用相同的名称&#xff0c;叫Zara的两个人在同一个班级。我们需要明确区分它们将不得不使用一些额外的信息&#xff0c;如他们的名字&#xff0c;如他们生活在不同的区域或母亲或父亲的名字等等。 同样的情况也出现在C应用程序中。例如&am…

Ubuntu 18.04.6 LTS 服务版安装参考

文章目录安装环境安装过程等待安装进行设置语言选择更新设置键盘样式设置IP地址配置代理配置 Ubuntu 存档镜像自定义存储配置设置账号配置 SSH安装软件包等待安装完成重启后验证安装后的基础优化重置 root 密码放开 root 远程登陆网卡信息变更修改ubuntu-18.04.6-live-server-a…

怎么用白光干涉仪的拼接测量功能

白光干涉仪的基本原理是通过不同的光学元件形成参考光路和探测光路&#xff0c;是利用干涉原理测量光程差&#xff0c;从而确定相关物理量的光学仪器。结合精密Z向扫描模块、3D 建模算法等&#xff0c;可以对器件表面进行非接触式扫描并建立表面3D图像&#xff0c;然后通过一体…

普通指针扫盲

一、什么是指针 C语言里&#xff0c;变量存放在内存中&#xff0c;而内存其实就是一组有序字节组成的数组&#xff0c;每个字节有唯一的内存地址。 CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里&#xff0c;数据对象是指存储在内存 中的一个指定数据…

【项目精选】病历管理系统设计与实现(源码+视频)

点击下载源码 企业财务管理系统主要用于电子病历来提高医院各项工作的效率和质量&#xff0c;促进医学科研、教学&#xff1b;减轻各类事务性工作的劳动强度&#xff0c;使他们腾出更多的精力和时间来服务于病人。本系统结构如下&#xff1a; 电子病例系统&#xff1a; 病人登…

通过知识库深度了解用户的心理

自助服务知识库的价值是毋庸置疑的&#xff0c;如果执行得当&#xff0c;可以帮助减少客户服务团队的工作量&#xff0c;仅仅编写内容和发布是不够的&#xff0c;需要知道知识库对客户来说是否有用&#xff0c;需要了解客户获得的反馈&#xff0c;如果你正确的使用知识库软件&a…

哪款蓝牙耳机打电话好用?打电话音质好的蓝牙耳机

现在几乎是人人离不开耳机的时代。在快节奏的生活和充满嘈杂声音的世界中&#xff0c;戴着耳机听歌&#xff0c;是每个人生活中最不可或缺的一段自由、放松的时光&#xff0c;下面小编就来分享几款通话音质好的蓝牙耳机。 一、南卡小音舱蓝牙耳机 动圈单元&#xff1a;13.3mm…

伯恩光学再成被执行人:多次因劳动纠纷被起诉,曾冲刺港交所上市

近日&#xff0c;贝多财经从天眼查APP了解到&#xff0c;伯恩光学&#xff08;深圳&#xff09;有限公司&#xff08;下称“伯恩光学”&#xff09;因《伯恩光学&#xff08;深圳&#xff09;有限公司与温*燕劳动合同纠纷的案件》一事&#xff0c;被广东省深圳市龙岗区人民法院…

服务端开发之Java备战秋招面试篇6-Java各种并发锁

努力了那么多年,回头一望,几乎全是漫长的挫折和煎熬。对于大多数人的一生来说,顺风顺水只是偶尔,挫折、不堪、焦虑和迷茫才是主旋律。我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。继续加油吧&#xff01; 目录 1、Java中主流锁分类体系介绍 2、乐观锁CAS原理刨…

wordpress 占用内容过高的解决方案

WordPress占用内存过高可能由多种因素引起&#xff0c;以下是一些可能的原因和解决方法&#xff1a; 主题和插件&#xff1a; WordPress的主题和插件是最常见的内存占用原因。确保使用的主题和插件是最新版本&#xff0c;并且只使用必需的插件。禁用不需要的插件&#xff0c;并…

【Linux】文件时间-ACM

文章目录文件时间-acmAccessChangeModify文件时间-acm 我们可以使用stat 文件名的方式查看对应的文件的时间信息 Access 表示文件最近一次被访问的时间 文件的访问 实际也就是文件的读取 实际操作中,文件的Access时间可能没有变化,这是因为在新的Linux内核中,Access时间不…

JavaScript 闭包的理解

1、概念 一个函数对周围状态的引用捆绑在一起&#xff0c;内层函数中访问到其外层函数的作用域 2、简单理解 闭包 内层函数 引用的外层函数变量 简单代码示例&#xff1a; function outer(){let i 1; // 被内层函数引用的变量function fn(){ // 内层函数console.log(i…

用javascript分类刷leetcode5.二分查找(图文视频讲解)

二分搜索 时间复杂度O(logn) 步骤&#xff1a; 从数组中间的元素开始&#xff0c;如果中间的元素正好是目标值&#xff0c;搜索结束如果目标值大于或小于中间的元素&#xff0c;则在大于或小于中间的元素的那一半继续搜索 代码模版 //二分查找伪代码模版 while (left <…

3.1 模拟栈+表达式求值+模拟队列+单调栈

模拟栈 题目链接 栈的数组模拟非常简单&#xff0c;不详细描述 设置一个指针指向栈顶第一个元素即可 STL中stack实现已经更新在STL_Stack #include<iostream> #include<string>using namespace std;const int N1e51; int m; string s; int stack[N]; int p;//指针…

Cartesi 2023 年 2 月回顾

2023年2月28日&#xff0c;通过ETH Denver和Cartesi的在线全球黑客马拉松一起开启黑客马拉松赛季!ETH Denver 正在热火朝天的进行着&#xff0c;我们正在为3月25日开始的首个全球在线黑客马拉松做准备。但这并不是本月发生的所有事情。我们在继续扩展和发展在全世界各地的社区&…

【软件测试】接口测试和接口性能测试,资深测试老鸟的总结......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 只会独立使用工具&a…

程序员必备!最值得收藏的宝藏网站大盘点

做为程序员&#xff0c;没有收藏点宝藏网站都说不过去。 除了常见的大家熟知的知乎、谷歌、b站、CSDN、掘金等&#xff0c;今天将介绍一些其他更加实用的宝藏网站&#xff0c;程序员小伙伴们可以按需收藏哦&#xff5e; 1.菜鸟教程&#xff1a;https://www.runoob.com/ 国内…

大数据处理技术导论(6) | Datawhale组队学习46期

文章目录1. hive 概述2. hive 与传统关系型数据库的对比3. hive 数据类型4. hive 数据模型5. hive 实战5.1 创建表5.2 修改表5.3 清空表、删除表5.4 其他命令项目地址 https://github.com/datawhalechina/juicy-bigdata&#xff0c;感谢项目团队的付出。本次主要学习 hive 相关…

web,h5海康视频接入监控视频流记录三(后台node取流)

前端vue&#xff0c;接入ws视频播放 云台控制 &#xff0c;回放预览&#xff0c;都是需要调对应的海康接口。相当于&#xff0c;点击时&#xff0c;请求后台写好的接口&#xff0c;接口再去请求海康的接口 调用云台控制是&#xff0c;操作一次&#xff0c;不会自己停止&#x…