FPGA中有限状态机的状态编码采用格雷码还是独热码?

举报
李锐博恩 发表于 2021/07/15 08:16:22 2021/07/15
【摘要】 今天看《从算法设计到硬件逻辑的实现》这本电子书时,遇到了一个问题,就是有限状态机的编写中,状态编码是采用格雷码还是独热码呢?究竟采用哪一种编码呢? 采用独热码为什么节省许多组合电路? 等等问题,就这些问题我收集了一些说法,觉得很有意思,在这里我们一起讨论下。 还是先简介下有限状态机: 有限状态机是由寄存器组和组合逻辑构成的硬件时序电路,其状态(即由寄存器组的1和0的...

今天看《从算法设计到硬件逻辑的实现》这本电子书时,遇到了一个问题,就是有限状态机的编写中,状态编码是采用格雷码还是独热码呢?究竟采用哪一种编码呢?

采用独热码为什么节省许多组合电路?

等等问题,就这些问题我收集了一些说法,觉得很有意思,在这里我们一起讨论下。


还是先简介下有限状态机:

有限状态机是由寄存器组和组合逻辑构成的硬件时序电路,其状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只可能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态,究竟转向哪一状态还是留在原状态不但取决于各个输入值,还取决于当前所在状态。这里是指Mealy型有限状态机。

Moore型有限状态机的状态转移只取决于当前状态,与输入值无关。

在Verilog HDL中可以用许多种方法来描述有限状态机,最常用的方法是用always语句和case语句。下面的状态转移图表示了一个有限状态机:

上面的状态转移图表示了一个四状态的有限状态机,它的同步时钟是Clock,输入信号是 A 和 rst_n ,输出信号是 F 和 G。状态的转移只能在同步时钟(Clock)的上升沿时发生,往哪个状态的转移则取决于目前所在的状态和输入的信号(Reset 和 A)。

我们采用两种状态编码方式来实现这个有限状态机:

1)采用格雷码:


  
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 21:27:04 09/02/2018
  7. // Design Name:
  8. // Module Name: fsm
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module fsm(
  22. input Clock,
  23. input rst_n,
  24. input A,
  25. output F,
  26. output G
  27. );
  28. reg F, G;
  29. reg [1:0] state;
  30. parameter Idle = 00, Start = 01, Stop = 10, Clear = 11;
  31. always @(posedge Clock) begin
  32. if(!rst_n)
  33. state <= Idle;
  34. else
  35. case(state)
  36. Idle: begin
  37. if(A) begin
  38. state <= Start;
  39. G <= 1'b0;
  40. end
  41. else
  42. state <= Idle;
  43. end
  44. Start: begin
  45. if(!A)
  46. state <= Stop;
  47. else
  48. state <= Start;
  49. end
  50. Stop: begin
  51. if(A) begin
  52. state <= Clear;
  53. F <= 1'b1;
  54. end
  55. else
  56. state <= Stop;
  57. end
  58. Clear: begin
  59. if(!A)begin
  60. state <= Idle;
  61. F <= 1'b0;
  62. G <= 1'b1;
  63. end
  64. else
  65. state <= Clear;
  66. end
  67. default: ;
  68. endcase
  69. end
  70. endmodule

在ISE中,综合后,得到的RTL Schematic:

2)采用独热码:

程序和上面的几乎一样,只需要改下,各个状态对应的编码值即可,还有最后的default:state <= Idle;

还是给出程序吧:


  
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 21:27:04 09/02/2018
  7. // Design Name:
  8. // Module Name: fsm
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module fsm(
  22. input Clock,
  23. input rst_n,
  24. input A,
  25. output F,
  26. output G
  27. );
  28. reg F, G;
  29. reg [3:0] state;
  30. parameter Idle = 4'b1000, Start = 4'b0100, Stop = 4'b0010, Clear = 4'b0001;
  31. always @(posedge Clock) begin
  32. if(!rst_n)
  33. state <= Idle;
  34. else
  35. case(state)
  36. Idle: begin
  37. if(A) begin
  38. state <= Start;
  39. G <= 1'b0;
  40. end
  41. else
  42. state <= Idle;
  43. end
  44. Start: begin
  45. if(!A)
  46. state <= Stop;
  47. else
  48. state <= Start;
  49. end
  50. Stop: begin
  51. if(A) begin
  52. state <= Clear;
  53. F <= 1'b1;
  54. end
  55. else
  56. state <= Stop;
  57. end
  58. Clear: begin
  59. if(!A)begin
  60. state <= Idle;
  61. F <= 1'b0;
  62. G <= 1'b1;
  63. end
  64. else
  65. state <= Clear;
  66. end
  67. default: state <= Idle;
  68. endcase
  69. end
  70. 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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。