FPGA中有限状态机的状态编码采用格雷码还是独热码?
今天看《从算法设计到硬件逻辑的实现》这本电子书时,遇到了一个问题,就是有限状态机的编写中,状态编码是采用格雷码还是独热码呢?究竟采用哪一种编码呢?
采用独热码为什么节省许多组合电路?
等等问题,就这些问题我收集了一些说法,觉得很有意思,在这里我们一起讨论下。
还是先简介下有限状态机:
有限状态机是由寄存器组和组合逻辑构成的硬件时序电路,其状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只可能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态,究竟转向哪一状态还是留在原状态不但取决于各个输入值,还取决于当前所在状态。这里是指Mealy型有限状态机。
Moore型有限状态机的状态转移只取决于当前状态,与输入值无关。
在Verilog HDL中可以用许多种方法来描述有限状态机,最常用的方法是用always语句和case语句。下面的状态转移图表示了一个有限状态机:
上面的状态转移图表示了一个四状态的有限状态机,它的同步时钟是Clock,输入信号是 A 和 rst_n ,输出信号是 F 和 G。状态的转移只能在同步时钟(Clock)的上升沿时发生,往哪个状态的转移则取决于目前所在的状态和输入的信号(Reset 和 A)。
我们采用两种状态编码方式来实现这个有限状态机:
1)采用格雷码:
-
`timescale 1ns / 1ps
-
//
-
// Company:
-
// Engineer:
-
//
-
// Create Date: 21:27:04 09/02/2018
-
// Design Name:
-
// Module Name: fsm
-
// Project Name:
-
// Target Devices:
-
// Tool versions:
-
// Description:
-
//
-
// Dependencies:
-
//
-
// Revision:
-
// Revision 0.01 - File Created
-
// Additional Comments:
-
//
-
//
-
module fsm(
-
input Clock,
-
input rst_n,
-
input A,
-
output F,
-
output G
-
);
-
reg F, G;
-
reg [1:0] state;
-
-
parameter Idle = 00, Start = 01, Stop = 10, Clear = 11;
-
-
always @(posedge Clock) begin
-
-
if(!rst_n)
-
state <= Idle;
-
else
-
case(state)
-
-
Idle: begin
-
if(A) begin
-
state <= Start;
-
G <= 1'b0;
-
end
-
else
-
state <= Idle;
-
end
-
-
Start: begin
-
if(!A)
-
state <= Stop;
-
else
-
state <= Start;
-
-
end
-
-
Stop: begin
-
if(A) begin
-
state <= Clear;
-
F <= 1'b1;
-
end
-
else
-
state <= Stop;
-
-
end
-
-
Clear: begin
-
if(!A)begin
-
state <= Idle;
-
F <= 1'b0;
-
G <= 1'b1;
-
end
-
else
-
state <= Clear;
-
-
end
-
-
default: ;
-
-
endcase
-
-
end
-
-
-
endmodule
在ISE中,综合后,得到的RTL Schematic:
2)采用独热码:
程序和上面的几乎一样,只需要改下,各个状态对应的编码值即可,还有最后的default:state <= Idle;
还是给出程序吧:
-
`timescale 1ns / 1ps
-
//
-
// Company:
-
// Engineer:
-
//
-
// Create Date: 21:27:04 09/02/2018
-
// Design Name:
-
// Module Name: fsm
-
// Project Name:
-
// Target Devices:
-
// Tool versions:
-
// Description:
-
//
-
// Dependencies:
-
//
-
// Revision:
-
// Revision 0.01 - File Created
-
// Additional Comments:
-
//
-
//
-
module fsm(
-
input Clock,
-
input rst_n,
-
input A,
-
output F,
-
output G
-
);
-
reg F, G;
-
reg [3:0] state;
-
-
parameter Idle = 4'b1000, Start = 4'b0100, Stop = 4'b0010, Clear = 4'b0001;
-
-
always @(posedge Clock) begin
-
-
if(!rst_n)
-
state <= Idle;
-
else
-
case(state)
-
-
Idle: begin
-
if(A) begin
-
state <= Start;
-
G <= 1'b0;
-
end
-
else
-
state <= Idle;
-
end
-
-
Start: begin
-
if(!A)
-
state <= Stop;
-
else
-
state <= Start;
-
-
end
-
-
Stop: begin
-
if(A) begin
-
state <= Clear;
-
F <= 1'b1;
-
end
-
else
-
state <= Stop;
-
-
end
-
-
Clear: begin
-
if(!A)begin
-
state <= Idle;
-
F <= 1'b0;
-
G <= 1'b1;
-
end
-
else
-
state <= Clear;
-
-
end
-
-
default: state <= Idle;
-
-
endcase
-
-
end
-
-
-
endmodule
上面两个程序的主要不同点是状态编码,2)采用了独热编码,而1)则采用Gray码,究竟采用哪一种编码好要看具体情况而定。对于用FPGA实现的有限状态机建议采用独热码,因为虽然采用独热编码多用了两个触发器,但所用组合电路可省下许多,因而使电路的速度和可靠性有显著提高,而总的单元数并无显著增加。采用了独热编码后有了多余的状态,就有一些不可到达的状态,为此在CASE语句的最后需要增加default分支项,以确保多余状态能回到Idle状态。
上面所说的多余状态是:4位编码有16种,独热码只列出了4种,剩下了12种,就是多余的状态。
更多的解释,我从网路上搜集了一些:
先看看知乎中的其中一种说法:
作者:龚黎明
链接:https://www.zhihu.com/question/40994717/answer/89125204
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
格雷码:相邻之间只变1bit,编码密度高。
独热码:任何状态只有1bit为1,其余皆为0,编码密度低。
比如说,表示4个状态,那么状态机寄存器采用格雷码编码只需要2bit:00(S0),01(S1),11(S2),10(S3);
采用独热码需要4bit:0001(S0),0010(S1),0100(S2),1000(S3)。所以很明显采用格雷码可以省2bit寄存器。
难理解的是,为什么独热码更节省组合逻辑:
其实很简单,
例一:
假如我们要在代码中判断状态机是否处于某状态S1,
对于格雷码的状态机来说,代码是这样的:assign S1 = (STATUS==2'b01);
对于独热码来说,代码是这样的就行:assign S1=STATUS[1];
所以独热码的译码非常简单。
例二:
考虑最简单的跳变,当A为1时,状态机会从S0跳到S1:。
采用格雷码写:
STATUS[1:0] <= (STATUS==2'h00) & A ? 2'h01 : 2'h00;
采用独热码写:
STATUS[1] <= STATUS[0] & A;有人怀疑这里的逻辑,认为只check独热码的一个bit有问题。当然是没问题的,0110,0011等编码属于不care的编码,在卡诺图化简中,不care的编码可以与其余的有效编码合并化简。实际上综合器也会这么做,所以独热码非常容易化简。
假如说S0跳到S1条件为A;S1跳到S2条件为B;S2跳到S3条件为C;S3跳到S0条件为D;
那么整个状态机化简之后代码就是:
STATUS[0] <= STATUS[3] & D;
STATUS[1] <= STATUS[0] & A;
STATUS[2] <= STATUS[1] & B;
STATUS[3] <= STATUS[2] & C;总结一下:
独热码适合写条件复杂但是状态少的状态机;
格雷码适合写条件不复杂但是状态多的状态机。
另一位大牛只说了一句话,但很有启发:
因为,独热码实际上相当于已经译码过后的信号。
把数电书翻出来看看3-8译码器,看看译码以后的信号长什么样。
那我把3—8译码器的真值表给出来,确实如此。
我觉得上面两种说法已经够了,可以理解了为什么采用独热码会节省组合逻辑 。
既然说到了状态机,我还想写一些东西,下次博文,还是这个状态转移图,我们采用另外一种方式来写这个有限状态机。
一段式?二段式?三段式?
下篇博文见。
下篇博文地址:状态机的描述方法案例分析
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/82319317
- 点赞
- 收藏
- 关注作者
评论(0)