目录
1.编码器
1.1普通编码器
1.2优先编码器
8线-3线优先编码器
1.3利用Verilog描述编码器
1.3.1 8线-3线普通编码器
1.3.2 8线-3线优先编码器
2.译码器/数据分配器
2.1译码器
2.1.1 2线-4线译码器
与非门、或非门和与门、非门的比较
2.1.2 3线-8线译码器
2.1.3利用Verilog描述译码器
2.2数据分配器
2.2.1数据分配器的定义及功能
2.2.2数据分配器的使用方法
2.2.3利用Verilog描述数据分配器
3.数据选择器
3.1数据选择器的定义与功能
3.2 2选1数据选择器
3.3 用2选1数据选择器构成4选1数据选择器
3.4利用Verilog描述4选1数据选择器
3.5典型数据选择器电路及应用
3.5.1用数据选择器实现逻辑函数
3.5.2用数据选择器构成查找表LUT
4.数值比较器
4.1数值比较器的定义及功能
4.1.1 一位数值比较器
4.1.2 利用一位数值比较器构成两位数值比较器
4.1.3 集成二进制数比较器
4.1.4 利用Verilog描述数值比较器
5.加法器
5.1半加器和全加器
5.1.1半加器
5.1.2全加器
5.2多位数加法器
5.2.1串行进位加法器
5.2.1超前进位加法器
5.3利用Verilog描述加法器
组合逻辑电路主要有编码器、译码器、数据选择器和加法器,篇幅所限,本文仅对组合逻辑电路的功能以及应用进行阐述,器件的定义以及原理等详细可参见《电子技术基础 数字部分》。
数字系统中存储和处理的信息,常常是用二进制码表示的。用一个二进制代码表示特定含义的信息称为编码(例如电脑CPU无法直接识别键盘输入的字符,因此需要编码器将键盘输入的字符转换成CPU能够识别的二进制代码)。而具有编码功能的编码功能的逻辑电路称为编码器。二进制编码器通常由个输入和个二进制输出共同组成,二进制编码器结构框图如下图所示:
普通编码器(又叫互斥编码器)在任何时刻只允许一个输入信号有效,否则将产生错误输出。以简单的4线-2线普通编码器为例,4线-2线普通编码器的真值表如下表所示。除了表中列出4个输入变量的4中取值组合有效外,其余12种组合所对应的输出均为0。
根据真值表分别画出和的卡诺图:
根据卡诺图分别写出 和的表达式:,。
任何一个时刻只有一个输入为1,将上述表中没有列出的12种组合所对应的输出看作无关项(将12种组合对应卡诺图中的"0"换为"x",再圈画卡诺圈),并化简得:,,其对应的逻辑图如下所示:
注:根据真值表写含有一个输出变量的表达式,只需要将这个输出变量所有可能等于1的情况相或起来。
这一电路实现正常编码时,对输入信号有严格的限制,即任何时刻~ 中只能并且必须有一个取值为1。例如,当、同时为1时,输出出现错误编码=11。因为正常编码时,输出11表示=1。
在实际应用中,经常会遇到两个以上的输入同时为有效信号的情况。因此,必须根据轻重缓急,事先规定好这些输入编码的先后次序,即优先级别(优先编码器允许2个以上的输入同时为1,但只对优先级别比较高的输入进行编码)。识别这类请求信号的优先级别并进行码编码的逻辑电路称为优先编码器。
首先给出8线-3线普通编码器的真值表和电路图,并详细阐述优先编码器是如何由普通编码器得到的。下图是8线-3线普通编码器的真值表:
根据真值表,写出函数表达式(真值表中仅列出了8种排列,其余的项组合均作为无关项):
,,。
根据逻辑表达式画出逻辑(可以先画出三个或门符号,再将输入变量通过连线经过对应的或门与其对应输出变量相连):
在以上互斥编码器的基础上,去除输入互相排斥这一特殊的约束条件,允许在某一刻时刻多个输入端为有效电平,但只对优先级最高的输入信号进行编码 ,并规定~优先级由高到低,其中优先级最高,优先级最低。列出8线-3线优先编码器的真值表如下:
在实际工作中,很少会选择用门电路进行搭建,而是会选择一些现成的中规模集成电路模块,以74148(SN74LS148)芯片为例,其真值表如下所示:
这里的真值表与先前的8线-3线编码器有些不一样,尽管它们的逻辑功能是一样的。
(1)之前的真值表表示的是输入为高电平有效,这里的真值表表示的是输出为低电平有效,74148输入信号是~,输出信号为~,并且它们均是以低电平有效。输入信号中优先级最高,优先级最低;
(2)在管脚输入端,增加了,它的作用是作为使能输入端使用,也就是说这个管脚可以控制芯片工作状态,低电平为工作,高电平为不工作;
(3)在输出管脚端,增加了及,其中作为扩展输出端,作用是用于多个芯片连接扩展,高电平有效;为编码器的工作标志,低电平表示编码器处于正常工作状态,高电平表示未正常工作。
1 module Digital_Encoder //模块名
2 (
3 I,A //端口名
4 );
5
6 input [7:0] I; //端口类型说明
7 output [2:0] A;
8
9 reg [2:0] A;
10
11 always @ (*) //关键字
12 begin
13 case(I) //多分支选择语句
14 8'b0000_0001 : A = 3'b000;
15 8'b0000_0010 : A = 3'b001;
16 8'b0000_0100 : A = 3'b010;
17 8'b0000_1000 : A = 3'b011;
18 8'b0001_0000 : A = 3'b100;
19 8'b0010_0000 : A = 3'b101;
20 8'b0100_0000 : A = 3'b110;
21 8'b1000_0000 : A = 3'b111;
22 default: A = 3'b000; //缺省值
23 endcase
24 end
25
26 endmodule
注:1.第9行使用reg类型的原因是,描述过程中用的是过程赋值语句always;而如果是连续赋值语句assign,就应该使用wire型(可以省略,因为变量默认是wire类型)。具体可参考笔者的另一篇博客《数字电路的基础知识(结合Verilog)》。
2.begin和and之间内部语句是顺序执行的;module和endmodule之间是并行执行的(比如,如果module和endmodule之间有两个always模块,这两个模块执行顺序没有先后,而是同时执行)。
1 module Digital_Priority_Encoder
2 (
3 I,A
4 );
5 input [7:0] I;
6 output [2:0] A;
7 reg [2:0] A;
8
9 always @ (*)
10 begin
11 if(I[7] == 1'b0) A = 3'b000;
12 else if(I[6] == 1'b0) A = 3'b001;
13 else if(I[5] == 1'b0) A = 3'b010;
14 else if(I[4] == 1'b0) A = 3'b011;
15 else if(I[3] == 1'b0) A = 3'b100;
16 else if(I[2] == 1'b0) A = 3'b101;
17 else if(I[1] == 1'b0) A = 3'b110;
18 else if(I[0] == 1'b0) A = 3'b111;
19 else A = 3'b000;
20 end
21
22 endmodule
这里仅对与前述8线-3线普通编码器不同的部分进行说明: 这里使用的是if关键字,以第11行为例,这行语句的含义是,如果输入,便会执行A = 3'b001;如果,便不会执行A = 3'b001,转而判断下面的else if语句;第19行的含义是,~都,那么执行A = 3'b000这条语句。可以看出,~优先级由高到低。
数字系统中,经常需要将一种代码转换位另一种代码,以满足特定的需要,完成这种功能的电路称为码转换电路,译码器和编码器都是码转换电路。译码是编码的逆过程,它的功能是将具有特定含义的二进制码转换成对应的输出信号,具有译码功能的逻辑电路称为译码器。译码器通常用于计算机中对存储单元的地址的译码,即将每一个地址代码转换成一个有效信号,从而选中对应的单元。
二进制译码器具有n个输入端、个输出端和一个使能输入端。在使能输入端位有效电瓶时,对应每一组输入代码,只有其中一个输出端为有效电平,其余输出端则为相反电平,输出信号可以是高电平,也可以是低电平。二进制译码器框图如下所示:
2输入变量、 共有4种不同状态组合,因而译码器由4个输出信号~,并且输出为低电平有效。2线-4线译码器的真值表如下图所示:
除了2输入和4输出,另外设置了使能控制端,当 时,无论和为何种状态,输出全为1,此时译码器处于非正常工作状态;而当时,对应于、的一种输入状态,输出端只有一个为0,其余输出均为1。例如,当时,为0,~均为1。
根据真值表写出各输出端的逻辑表达式:
这里关于逻辑表达式的表达形式稍作解释,为何不写成与-或的形式,先放出结论。
(PS:刚开始看到书中这部分也是对用这种形式表达有所疑惑,学过数电一眨眼也过去三四年了,很多细节都已经忘干净了,当时翻书的时候不小心书坠地了,捡起来时里面慢飘飘飞出了一张白纸,上面写了一些数电考前整理的知识点,其中下面一段话以红笔记录在白纸上,因此显得特别显眼。笔者啰嗦这些,是想说尽管现在书籍、电子稿遍布,很多人都习惯于收藏,内心独白,我也是其中之一,但还是要以自己记录的形式记录和整理一些东西,纸质也好,电子形式也成。这也是题主开始写博客的原因,共勉之)
(1)相同输入端的与非门相对于与门、或门而言,所用晶体管少,速度快;
(2)或非门相对与或门、非门而言,速度快。
按照正常卡诺图画圈或者单一变量直接将输出对应为1的输入相或的方式写出表达式,应该是如下的形式:
,,,
由于前述与非门的优点,因此对原表达式进行两次取反操作:
,,,
化简得到:
,,,
根据逻辑表达式画出逻辑图如下:
注:关于低电平输入有效,也就是当输入或输出取反时,在卡诺图中的变量即是取反后的变量。例如,上述的2线-4线译码器的使能输入端为低电平有效,因此带入卡诺图中的逻辑变量就应该是;输入变量为高电平有效,因此卡诺图就应该是和;输出变量为低电平有效,因此输出变量为~。
以的卡诺图为例:
3先-8线译码器有三个二进制输入、、,它们共有8中组合状态,即可译出8个输出信号~,输出为低电平有效。此外,还设置了3个使能输入端、和,并且,为扩展电路的功能提供了方便。编码其中下图是3线-8线译码器的真值表:
根据真值表写出各输出端的逻辑表达式。
并根据输出端的逻辑表达式画出逻辑图。
注:这里的verilog代码段未加入使能控制端,仅为展示译码器原理与verilog描述过程。
1 module Digital_Decoder
2 (
3 A,I
4 );
5
6 input [2:0] A;
7 output [7:0] I;
8
9 reg [7:0] I;
10
11 always @ (*)
12 begin
13 case(A)
14 3'b000 : I = 8'b01111111;
15 3'b001 : I = 8'b10111111;
16 3'b010 : I = 8'b11011111;
17 3'b011 : I = 8'b11101111;
18 3'b100 : I = 8'b11110111;
19 3'b101 : I = 8'b11111011;
20 3'b110 : I = 8'b11111101;
21 3'b111 : I = 8'b11111110;
22 default: I = 8'b11111111;
23 endcase
24 end
25
26 endmodule
数据分配是将公共路线上的数据根据需要送到不同的通道上去,实现数据分配功能的逻辑电路称为数据分配器。它的作用相当于多个输出的单刀多掷开关,示意图如下图所示:
数据分配器可以用带有使能控制端的二进制译码器实现。如用3线-8线译码器可以把1个数据信号分配到8个不同的通道上去,只需要在3-8线译码器的基础上添加8个数据输入端~和一个或门。称之为8-1数据分配器。 下图是8-1数据分配器的示意图:
根据上图可以看出,~ 为数据输入端,为输入端,、、为3线-8线译码器的输入端,、、地址码经过3线-8线译码器,产生有效信号,来控制8个开关,最终选择一路数据输出。根据以上数据分配器的示意图写出8-1数据分配器的真值表如下:
根据真值表可知,当时,输出为高电平,其余为低电平,对应高电平的开关闭合,而对应低电平的开关保持断开,因此,此时的输出为。当时,;当时,。根据真值表写出8-1数据分配器的函数表达式如下:
根据函数表达式画出8-1数据分配器的电路图,如下所示。
用3线-8线译码器(74HC138)作为数据分配器的逻辑原理图如下图所示:
将 接低电平,作为使能端,、、作为选择通道地址输入,作为数据输入。例如,当,时,得到的逻辑表达式
而其余输出端均为高电平。因此,当地址时,只有输出端得到与输入相同的数据波形。改变的取值可以将数据送到不同的输出端。
1 module Selector
2 (
3 A,D0,D1,D2,D3,
4 D4,D5,D6,D7,Y
5 );
6 input D0,D1,D2,D3,D4,D5,D6,D7;
7 input [2:0] A;
8 output [7:0] Y;
9
10 reg [7:0] Y;
11
12 always @ (*)
13 begin
14 case(A)
15 3'b000 : Y = D0;
16 3'b001 : Y = D1;
17 3'b010 : Y = D2;
18 3'b011 : Y = D3;
19 3'b100 : Y = D4;
20 3'b101 : Y = D5;
21 3'b110 : Y = D6;
22 3'b111 : Y = D7;
23 default: Y = 1'b0;
24 endcase
25 end
26
27 endmodule
数据选择是指经过选择,把多路数据中的某一数据传送到公共数据上,实现数据选择功能的逻辑电路称为数据选择器。它的作用相当于多个输入的单刀多掷开关,示意图如下图所示。
2选1数据选择器的真值表如下所示:
根据真值表写出逻辑表达式:
下图是用与门和或门构成的2选1数据选择器及其对应逻辑符号。
4选1数据选择器对4个数据源进行选择,需要两位选择输入。当取00、01、10、11时,分别控制4个数据通道的开关。任何时候只有一种可能的取值,使对应的那一路数据通过,送达端。4选1数据选择器的真值表如下图所示:
根据真值表得到4选1数据选择器的函数表达式。
用3个2选1数据选择器构成两级电路,第1级两个数据选择器分别实现和。第二级实现。电路及认购及逻辑符号如下图所示:
依据上述的方法可以构成更多通道的数据选择器。被选数据源越多,所需选择输入端的位数也越多,若选择输入端为n,可选输入通道为。
1 module Mux4_to_1
2 (
3 OUT,I,S
4 );
5
6 input [3:0] I;
7 input [1:0] S;
8 output OUT ;
9
10 reg OUT;
11
12 always @ (*)
13 begin
14 case({S1,S0})
15 2'b00 : OUT = I0;
16 2'b01 : OUT = I1;
17 2'b10 : OUT = I2;
18 2'b11 : OUT = I3;
19 default: OUT = 1'bx;
20 endcase
21 end
22
23 endmoudule
数据选择器的应用非常广泛,并且是构成PFGA器件内部查找表(LUT)的基本单元。常用的数据选择器有2选1数据选择器、4选1数据选择器、8选1数据选择器、16选1数据选择器。还有一些数据选择器具有三态输出功能,除了正常的0或1输出之外,当使能输入端为无效信号时,输出为高阻态。利用这一特点,可以将多个数据选择器的输出端线与连在一起,共用一根数据传输线,而不会出现相互干扰问题。
以4选1数据选择器为例,它有2个选择输入、和4个数据输入、、和,其输出与输入的关系式可以写成
式中是选择输入端、 构成的最小项。数据输入作为控制信号,当时,其对应的最小项在表达式中出现,当时,对应的最小项就不会出现。利用这一点将函数变换成最小项表达式,函数的变量接入选择输入端,就可以实现组合逻辑函数。
(1)用4选1数据选择器实现
1.将所给的函数时变换成最小项表达式:
2.将变量A、B分别接4选1数据选择器的两个选择端和(这里函数表达式刚好是两个变量、4选1数据选择器有两个数据选择段,一一对应)。和对应的数据输入端、都应该等于1,而没有出现的最小项和对应的数据输入端、都应该等于0。
3.画出逻辑图如下所示:
(2)用4选1数据选择器实现
方法一:
1.将所给的函数时变换成最小项表达式:
2.将变量A、B分别接到4选1数据选择器的数据选择段(由于函数表达式有3个变量,而4选1数据选择器仅有两个数据选择段,因此需要有一个变量接到4选1数据选择器的输入端),再依次决定00、01、10、11对应的输入变量,,对照函数表达式,得到,,,。
3.画出逻辑图如下所示:
方法二(真值表):
(3)用2选1数据选择器和必要的逻辑门实现
方法一:
1.将所给的函数时变换成最小项表达式:
(上述问题2已得)
2.由于2选1数据选择器只有一个数据选择端,因此将A接到数据选择段,将表达式化成的形式,因此
注:如果这里直接依据上述的函数表达式搭建电路图,会出现多用门电路的现象,也就是说,实现同样的逻辑功能选择了门电路较多的构成。这里采用偶数次取反的方法(常用于表达式含非变量比较多)对进行化简:。因此,。
3.画出逻辑图如下所示:
方法二(真值表):
注:刚才采用的是观察结合表达式化简的方法,优点是简单易懂,缺点是容易导致门电路多用。采用真值表化简表达式的方法可以有效避免这一点。
1.同样选择A作为选择输入端,列出真值表如下:
根据真值表可知,当时,可以求出,即数据端;当时,可以求出,即数据段。
总结:用一个具有n位选择输入的数据选择器,实现变量数不大于n+1的逻辑函数时,每一个数据输入端可以接0、1、单变量或者它的非。当变量书大于n+1时,可以用多个数据选择器扩展使用,也可以附加其他门电路后连接到数据输入端。
构成FPGA基本单元的逻辑块主要是查找表LUT。LUT实质上是一个小规模的存储器,以真值表的形式实现给定的逻辑函数。3输LUT的结构及逻辑符号如下图所示。
由7个二选1数据选择器组成3级电路,第一级的数据输入端接存储单元,每个存储单元可以存放一个逻辑值0或1,由编程决定取0还是1。4输入的LUT则由15个2选1数据选择器构成4级电路,4个选择输入端对16个存储单元进行选择。当输入端增加时,LUT使用的数据选择器呈几何级增长。FPGA中的LUT的输入端数一般位4个。
在数字系统中,特别是在计算机中常需要对两个数的大小进行比较。数值比较器就是对两个二进制数A和B进行比较的逻辑电路,比较结果有、以及三种情况。
1位数值比较器是多位比较器的基础。当A和B都是1位二进制数时,它们只能取0或1两种值,由此可写出1位数值比较器的真值表。
根据真值表得到逻辑表达式:
由逻辑表达式得到如下的逻辑电路:
用、、表示两位二进制数和的比较结果。当高位(、)不相等时,无需比较低位(、),高位比较的结果就是两个数的比较结果。当高位相等时,两数的比较结果由低位比较的结果决定。下图是两位数值比较器的真值表。
根据真值表写出两位数值比较器的逻辑表达式:
根据上式画出逻辑图,电路利用了1位数值比较器的输出作为中间结果。它所依据的原理是,如果两位数和的高位不相等,则高位比较结果就是两位数的比较结果,与地位无关。这时,高位输出,使与门、、均封锁,而或门都打开,低位比较结果不能影响或门,高位比较结果直接从或门输出。如果高位相等,即,使与门、、均打开,同时
由和作用,或门也打开,低位的比较结果直接送达输出端,即低位的比较结果据欸的决定两数的大、小或者相等。如下是两位数值比较器的逻辑图:
以常用的7485集成4位二进制数比较器为例,下图是其真值表:
从真值表可以看出,输出变量、 、 、是最终的比较结果。输入变量、、、和、、、是两个逐位比较的4位二进制数,、、是两外两个低位数的比较结果,该低位数比较结果是为了与其他数值比较器连接,以便扩展成更多位数值比较器(如果需要比较两个八位二进制数,只需要两片7485相连,一片用来做高四位的比较结果,另一片用作低四位的比较结果,然后将低四位进行比较的芯片输出引脚依次接到高四位比较的芯片扩展端,也就是I端)。如果只比较两个4位数,应将和接低电平,接高电平。
1 module Digital_Comparator
2 (
3 A,B,F
4 );
5 input [3:0] A;
6 input [3:0] B;
7 output [2:0] F;
8 reg [2:0] F;
9
10 always @ (*)
11 begin
12 if(A > B)
13 F = 3'b001;
14 else if(A == B)
15 F = 3'b010;
16 else
17 F = 3'b100;
18 end
19
20 endmodule
数字信号的算法运算主要是加、减、乘、除四个类型,而加法运算是最基础的运算,并且其他三种运算都可以分解为若干步加法运算,因此加法器是算术运算的基本单元电路。
如果只考虑了两个加数本身,而没有考虑低位进位的加法运算,称为半加,实现半加运算的逻辑电路称为半加器。下表是两个1位二进制的半加运算的真值表,其中、是两个加数,表示和数,表示进位数,
根据真值表写出逻辑表达式: ,
根据半加器的逻辑表示式画出逻辑图及对应图形符号:
由于半加器没有考虑低位的进位,所以仅仅靠半加器是无法解决问题的。全加器能进行被加数、加数和来自低位的进位信号相加,并根据求和结果给出该位的进位信号。实现半加运算的逻辑电路称为半加器。
根据全加器的功能,列出其真值表如下,其中和分别是被加数及加数,位低位进位数,为本位和数(称为全加和),为向高位的进位数。
为了求出和的逻辑表达式,根据真值表画出全加器的卡诺图。
根据卡诺图,依次得到和的函数表达式:
注:这里圈画逻辑变量的卡诺圈没问题,但是的卡诺图圈画的方法有多种,这里选取的是利用中的项,这样就可以在画逻辑图时两个输出端口享有一部分共同的输入电路,能够有效地减少布线的复杂度。
根据函数表达式画出全加器的逻辑图及其对应图形符号:
下图是由门电路构成的一位全加器(引用自:https://www.cnblogs.com/qidaiymm/p/4887355.html)。
为了更好地理解全加器的数学过程,这里以两个4位二进制数相加的过程为例:
根据上面的计算过程,可以看到两个4位二进制相加,其中1101是被加数,1111为加数,而11110则是低位向高位的进位,在相加的过程中,除最低位外,其余各位均要考虑本位的相加,并且要考虑低位向本位的进位(例如在做加法器的扩展时,会有低位的进位)。因此,所谓全加就是将、、这三个二进制数相加,得到和本位向高位的进位的过程。
要进行多位数相加,最简单的方法是将多个全加器进行级联,称为串行进位加法器。例如,两个4位二进制数和相加,可以采用4个全加器构成4位数加法器(全加器的个数等于相加数的位数,并且最低位全加器的进位端接0),其原理图如下所示。将低位的进位输出信号接到高位的进位输入端,因此,任1位的加法运算必须在低1位的运算完成之后才能进行,这种进位方式称为串行进位(由低位依次向高位进位)。串行进位加法器逻辑电路的优点是结构简单,但运行速度不高。
由于穿行进位加法器进位信号是串行传递,最后一位的进位输出要经过四位全加器之后才能形成。如果位数增加,传输延迟时间将更长,工作速度慢。为了提高速度,设计出了一种多位数快速进位(又称超前进位)的加法器。所谓快速仅为,是对普通的全加器进行改良而设计成的并行加法器,主要是针对普通全加器串联式互相进位产生的延迟进行了改良,各级进位信号可以同时送到各位全加器的进位输入端。
由于超前进位加法器的真值表过于庞大,推导过程这里不再给出(可参阅《数字电子技术基础》)。下图是用与门和或门实现的超前进位产生电路。
根据超前进位概念构成的4位加法器的结构示意图如下:
4位二进制全加器74F283是一种典型的超前进位加法器,仅给出其真值表的一部分以作解释:
是一组被加数,是一组加数,为和,为低位进位信号,为高位进位信号。以上述真值表的第一行为例,,为1010,对应十进制数10;为1001,对应十进制数9;则为0011,对应十进制数3,为1,因此(为0,代表为10000,对应十进制数16)。
1 module Digital_Adder
2 (
3 A,B,S
4 );
5
6 input [3:0] A;
7 input [3:0] B;
8 output [3:0] S;
9
10 reg [3:0] S;
11
12 always @ (*)
13 begin
14 S = A + B;
15 end
16
17 endmodule
上述代码没有考虑进位及溢出情况。当相加结果超过4' hF时,最高位(进位输出)丢失。因为这里定义的输出端口为4位,意味着最大输出为十进制15,也就是十六进制F。
注:Verilog HDL 中绝大多数运算操作符都是可以直接使用的,比如:+(加)、-(减)、*(乘)、/(除)、!(逻辑非)、~(取反)、&(与)、~&(与非)、|(或)、~|(或非)、^(异或)、~^(同或)、%(取模)、<<(逻辑左移)、>>(逻辑右移)、<(小于)、<=(小等于)、>(大于)、>=(大等于)、==(等于)、!(逻辑不等于)、&&(逻辑与)、||(逻辑或)。
References:
1.康华光《 电子技术基础 数字部分》(第六版);
2.锆石科技《HELLO FPGA数字部分》;
3.https://www.cnblogs.com/qidaiymm/p/4887355.html