当前位置:   article > 正文

【 FPGA 】序列检测器 11010 (mealy状态机,moore状态机)_状态机实验(实现序列发生器11010100的设计)

状态机实验(实现序列发生器11010100的设计)

1.mealy状态机和moore状态机me

        状态机是硬件电路设计的常用的描述工具,也是电路设计的重要思想。很早之前我就知道mealy状态机和moore状态机,但是对两者的差别不是非常的清楚,最近在学习系列检测器的设计时对这两种状态机和一段式、三段式状态机有了更深刻的了解,在这里分享自己的见解给大家。有什么理解不准确的地方也希望大家指正。

1.1序列检测器

        在介绍两种状态机之前首先先介绍一下序列检测器。

        序列检测器:从一串数据流中找到需要检测的序列号。例如如下一串数据流,需要检测的序列为11010,则每一次检测到11010时序列检测器需要输出一次使能。

9ab5e22aae8540ccbbd6a57138f57c58.png        设计该电路就可以使用状态机来实现。接下来讲解两种状态机区别和用这两种状态机实现该电路的状态图。

1.2.mealy状态机和moore状态机区别

        mealy状态机:输出由当前状态机状态和控制信号共同决定。

        moore状态机:输出仅仅取决于当前的状态机状态。

        下图时两种状态机的状态转移图 

3a785cd07e4f4685bdb6e76b7ba33563.png

7038a8a3363b477ca34409c71717da56.png

        首先解释两种状态机的工作:

        1.mealy状态机:s0状态表示一个最初状态,该状态检测到1表示序列11010的第一个1被检测到,跳转到s1,此时需要检测11010的第二个1,当在检测到第二个1时,跳转到s2,一次类推到跳转到s4,此时如果下一时刻检测到0,则表示检测到了所需要的序列,输出正确。

具体状态解释:s0:等待检测第一个需要的序列

                        s1:已经检测到1,等待检测到第二位1

                        s2:已经检测到11,等待检测第三位0    

                        s3:已经检测到110, 等待检测第四位1

                        s4:已经检测到1101,等待检测第五位0

        检测成功条件:状态机处于s4状态,并且下一个时刻输入的检测信号是0

        2.moore状态机:s0表示一个空闲状态,该状态等待第一位1的到来,当检测到第一个1后,跳转到s1,等待检测第二位1,一次类推直到跳转到s5。

具体状态解释:s0:等待检测第一个需要的序列

                        s1:已经检测到1,等待检测到第二位1

                        s2:已经检测到11,等待检测第三位0    

                        s3:已经检测到110, 等待检测第四位1

                        s4:已经检测到1101,等待检测第五位0

                        s5:已经检测到11010

        检测成功条件:状态机处于s5状态。

        在该电路中,两种状态机本质上,moore状态机是比mealy多一个s5状态,moore状态机就是通过判定是否处于该状态来判定条件是否正确,而mealy状态机则时通过s4状态以及下一个时刻的条件信号是否有效来判定条件是否正确。

2.序列检测器的verilog代码实现

2.1.mealy状态机verilog实现ssf

  1. module sequence_11010_chack (
  2. input clk ,
  3. input rst_p ,
  4. input sequence_num ,
  5. output num_en
  6. );
  7. localparam s0 = 5'd0 ;
  8. localparam s1 = 5'd1 ;
  9. localparam s2 = 5'd2 ;
  10. localparam s3 = 5'd4 ;
  11. localparam s4 = 5'd8 ;
  12. localparam s5 = 5'd16 ;
  13. reg [ 4 : 0 ] cur_state ;
  14. reg chack_right ;
  15. reg [ 4 : 0 ] next_state ;
  16. //-----------------------------------------------------------------------
  17. //-----mealy状态机
  18. //---三段式实现
  19. //--序列11010检测
  20. //-----------------------------------------------------------------------
  21. //第一段
  22. always @(posedge clk) begin
  23. if(rst_p)
  24. cur_state <= 5'd0 ;
  25. else
  26. cur_state <= next_state ;
  27. end
  28. //第二段
  29. always @( *) begin
  30. case(cur_state)
  31. s0 : next_state = (sequence_num) ? s1 : s0 ;
  32. s1 : next_state = (sequence_num) ? s2 : s0 ;
  33. s2 : next_state = (sequence_num) ? s2 : s3 ;
  34. s3 : next_state = (sequence_num) ? s4 : s0 ;
  35. s4 : next_state = (sequence_num) ? s1 : s0 ;
  36. default : next_state = s0 ;
  37. endcase
  38. end
  39. //第三段
  40. always @(posedge clk) begin
  41. if(rst_p)
  42. chack_right <= 1'b0 ;
  43. else begin
  44. case(cur_state)
  45. s4 : chack_right <= (sequence_num) ? 1'b0 : 1'b1 ;
  46. default : chack_right <= 1'b0 ;
  47. endcase
  48. end
  49. end
  50. assign num_en = chack_right ;

         mealy状态机输出与当前状态以及输入信号有关 可以看到代码中chack_right信号是由cur_state和sequence_num共同决定的。

2.2.moore状态机的Verilog代码实现

  1. module sequence_11010_chack (
  2. input clk ,
  3. input rst_p ,
  4. input sequence_num ,
  5. output num_en
  6. );
  7. localparam s0 = 5'd0 ;
  8. localparam s1 = 5'd1 ;
  9. localparam s2 = 5'd2 ;
  10. localparam s3 = 5'd4 ;
  11. localparam s4 = 5'd8 ;
  12. localparam s5 = 5'd16 ;
  13. reg [ 4 : 0 ] cur_state ;
  14. reg chack_right ;
  15. //-----------------------------------------------------------------------------
  16. //----------Moore状态机
  17. //---三段式
  18. //--序列11010检测
  19. //-----------------------------------------------------------------------------
  20. reg [ 4 : 0 ] next_state ;
  21. //第一段
  22. always @(posedge clk) begin
  23. if(rst_p)
  24. cur_state <= 5'd0 ;
  25. else
  26. cur_state <= next_state ;
  27. end
  28. //第二段
  29. always @( *) begin
  30. case(cur_state)
  31. s0 : next_state = (sequence_num) ? s1 : s0 ;
  32. s1 : next_state = (sequence_num) ? s2 : s0 ;
  33. s2 : next_state = (sequence_num) ? s2 : s3 ;
  34. s3 : next_state = (sequence_num) ? s4 : s0 ;
  35. s4 : next_state = (sequence_num) ? s2 : s5 ;
  36. s5 : next_state = (sequence_num) ? s1 : s0 ;
  37. default : next_state = s0 ;
  38. endcase
  39. end
  40. //第三段
  41. always @(*) begin
  42. case(cur_state)
  43. s5 : chack_right = 1'b1 ;
  44. default : chack_right = 1'b0 ;
  45. endcase
  46. end
  47. assign num_en = chack_right ;

        moore状态机输出只与当前状态有关,从代码中表示就是输出chack_right信号只要当cur_state处于s5就输出1,反之就输出0。

2.3.仿真代码

  1. `timescale 1ns/1ps
  2. module sequence_11010_chack_tb;
  3. // Parameters
  4. //Ports
  5. reg clk=0;
  6. reg rst_p=1;
  7. reg sequence_num=0;
  8. reg [4:0] tb_data = 5'b11010;
  9. wire num_en;
  10. sequence_11010_chack sequence_11010_chack_inst (
  11. .clk(clk),
  12. .rst_p(rst_p),
  13. .sequence_num(sequence_num),
  14. .num_en(num_en)
  15. );
  16. always #5 clk = ! clk ;
  17. initial begin
  18. #201;
  19. rst_p = 1'b0 ;
  20. //1
  21. @(posedge clk)begin
  22. sequence_num <= tb_data[4] ;
  23. end
  24. @(posedge clk)begin
  25. sequence_num <= tb_data[3] ;
  26. end
  27. @(posedge clk)begin
  28. sequence_num <= tb_data[2] ;
  29. end
  30. @(posedge clk)begin
  31. sequence_num <= tb_data[1] ;
  32. end
  33. @(posedge clk)begin
  34. sequence_num <= tb_data[0] ;
  35. tb_data <= {tb_data[3:0],tb_data[4]};
  36. end
  37. //2
  38. @(posedge clk)begin
  39. sequence_num <= tb_data[4] ;
  40. end
  41. @(posedge clk)begin
  42. sequence_num <= tb_data[3] ;
  43. end
  44. @(posedge clk)begin
  45. sequence_num <= tb_data[2] ;
  46. end
  47. @(posedge clk)begin
  48. sequence_num <= tb_data[1] ;
  49. end
  50. @(posedge clk)begin
  51. sequence_num <= tb_data[0] ;
  52. tb_data <= {tb_data[3:0],tb_data[4]};
  53. end
  54. //3
  55. @(posedge clk)begin
  56. sequence_num <= tb_data[4] ;
  57. end
  58. @(posedge clk)begin
  59. sequence_num <= tb_data[3] ;
  60. end
  61. @(posedge clk)begin
  62. sequence_num <= tb_data[2] ;
  63. end
  64. @(posedge clk)begin
  65. sequence_num <= tb_data[1] ;
  66. end
  67. @(posedge clk)begin
  68. sequence_num <= tb_data[0] ;
  69. tb_data <= {tb_data[3:0],tb_data[4]};
  70. end
  71. //4
  72. @(posedge clk)begin
  73. sequence_num <= tb_data[4] ;
  74. end
  75. @(posedge clk)begin
  76. sequence_num <= tb_data[3] ;
  77. end
  78. @(posedge clk)begin
  79. sequence_num <= tb_data[2] ;
  80. end
  81. @(posedge clk)begin
  82. sequence_num <= tb_data[1] ;
  83. end
  84. @(posedge clk)begin
  85. sequence_num <= tb_data[0] ;
  86. tb_data <= {tb_data[3:0],tb_data[4]};
  87. end
  88. //5
  89. @(posedge clk)begin
  90. sequence_num <= tb_data[4] ;
  91. end
  92. @(posedge clk)begin
  93. sequence_num <= tb_data[3] ;
  94. end
  95. @(posedge clk)begin
  96. sequence_num <= tb_data[2] ;
  97. end
  98. @(posedge clk)begin
  99. sequence_num <= tb_data[1] ;
  100. end
  101. @(posedge clk)begin
  102. sequence_num <= tb_data[0] ;
  103. tb_data <= {tb_data[3:0],tb_data[4]};
  104. end
  105. //6
  106. @(posedge clk)begin
  107. sequence_num <= tb_data[4] ;
  108. end
  109. @(posedge clk)begin
  110. sequence_num <= tb_data[3] ;
  111. end
  112. @(posedge clk)begin
  113. sequence_num <= tb_data[2] ;
  114. end
  115. @(posedge clk)begin
  116. sequence_num <= tb_data[1] ;
  117. end
  118. @(posedge clk)begin
  119. sequence_num <= tb_data[0] ;
  120. tb_data <= {tb_data[3:0],tb_data[4]};
  121. end
  122. //7
  123. @(posedge clk)begin
  124. sequence_num <= tb_data[4] ;
  125. end
  126. @(posedge clk)begin
  127. sequence_num <= tb_data[3] ;
  128. end
  129. @(posedge clk)begin
  130. sequence_num <= tb_data[2] ;
  131. end
  132. @(posedge clk)begin
  133. sequence_num <= tb_data[1] ;
  134. end
  135. @(posedge clk)begin
  136. sequence_num <= tb_data[0] ;
  137. tb_data <= {tb_data[3:0],tb_data[4]};
  138. end
  139. //移位方向改变
  140. //1
  141. @(posedge clk)begin
  142. sequence_num <= tb_data[4] ;
  143. end
  144. @(posedge clk)begin
  145. sequence_num <= tb_data[3] ;
  146. end
  147. @(posedge clk)begin
  148. sequence_num <= tb_data[2] ;
  149. end
  150. @(posedge clk)begin
  151. sequence_num <= tb_data[1] ;
  152. end
  153. @(posedge clk)begin
  154. sequence_num <= tb_data[0] ;
  155. tb_data <= {tb_data[0],tb_data[4:1]};
  156. end
  157. //2
  158. @(posedge clk)begin
  159. sequence_num <= tb_data[4] ;
  160. end
  161. @(posedge clk)begin
  162. sequence_num <= tb_data[3] ;
  163. end
  164. @(posedge clk)begin
  165. sequence_num <= tb_data[2] ;
  166. end
  167. @(posedge clk)begin
  168. sequence_num <= tb_data[1] ;
  169. end
  170. @(posedge clk)begin
  171. sequence_num <= tb_data[0] ;
  172. tb_data <= {tb_data[0],tb_data[4:1]};
  173. end
  174. //3
  175. @(posedge clk)begin
  176. sequence_num <= tb_data[4] ;
  177. end
  178. @(posedge clk)begin
  179. sequence_num <= tb_data[3] ;
  180. end
  181. @(posedge clk)begin
  182. sequence_num <= tb_data[2] ;
  183. end
  184. @(posedge clk)begin
  185. sequence_num <= tb_data[1] ;
  186. end
  187. @(posedge clk)begin
  188. sequence_num <= tb_data[0] ;
  189. tb_data <= {tb_data[0],tb_data[4:1]};
  190. end
  191. #100;
  192. $stop;
  193. end
  194. endmodule

仿真结果如下:

811e7a1ca5b94302b34ff5fad50a0af7.png

 3.Reference

本文参考了csdn、知乎上相关文章。如果存在什么问题请指正!!!

完成工程和仿真代码如下链接免费下载:【免费】verilog序列检测器,序列11010,(mealy状态机和moore状态机)资源-CSDN文库

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/622327
推荐阅读
相关标签
  

闽ICP备14008679号