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译码器的真值表给出来,确实如此。

我觉得上面两种说法已经够了,可以理解了为什么采用独热码会节省组合逻辑 。


既然说到了状态机,我还想写一些东西,下次博文,还是这个状态转移图,我们采用另外一种方式来写这个有限状态机。

一段式?二段式?三段式?

下篇博文见。

下篇博文地址:状态机的描述方法案例分析

  • 17
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李锐博恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值