关于三段式状态机第三段是组合逻辑还是时序逻辑的问题?

举报
李锐博恩 发表于 2021/07/15 03:36:44 2021/07/15
【摘要】 由于本人一直以来,用的三段式状态机,第三段写法都是组合逻辑写法,但是近期有小伙伴面试小公司,写到状态机的第三段时候,按照我一直用到的组合逻辑来写第三段,提供输出,被提出了质疑,曰:我们一直用的都是时序逻辑来写第三段? 由于本人从来没有遇到过这种质疑,所以具体什么情况也不是太清楚,仅仅以此篇博客来作为一种测试,解答第三段如何写的问题。 以序列检测器为例,我们分别提供组合逻辑...

由于本人一直以来,用的三段式状态机,第三段写法都是组合逻辑写法,但是近期有小伙伴面试小公司,写到状态机的第三段时候,按照我一直用到的组合逻辑来写第三段,提供输出,被提出了质疑,曰:我们一直用的都是时序逻辑来写第三段?

由于本人从来没有遇到过这种质疑,所以具体什么情况也不是太清楚,仅仅以此篇博客来作为一种测试,解答第三段如何写的问题。

以序列检测器为例,我们分别提供组合逻辑以及时序逻辑来实现第三段,并通过行为仿真来验证其功能的正确性:

要求无重叠检测序列01010,分别给出状态转移图以及Verilog设计。


组合逻辑写法

首先给出状态转移图,为了方便,使用Moore状态机的画法。

 

相应的Verilog描述为:


  
  1. module seq_detect(
  2. input clk,
  3. input rst_n,
  4. input seq_in,
  5. output reg out
  6. );
  7. //detect sequence 01010
  8. //first step: define parameter and state
  9. parameter s0 = 6'b0000_01, s1 = 6'b0000_10, s2 = 6'b0001_00, s3 = 6'b0010_00,
  10. s4 = 6'b0100_00, s5 = 6'b1000_00;
  11. reg [5:0] cur_state, nxt_state;
  12. //三段式状态机
  13. //第一段:时序逻辑
  14. always@(posedge clk or negedge rst_n) begin
  15. if(~rst_n) cur_state <= s0;
  16. else cur_state <= nxt_state;
  17. end
  18. //第二段:组合逻辑
  19. always@(*) begin
  20. nxt_state = s0;
  21. case(cur_state)
  22. s0: if(seq_in == 0) nxt_state = s1;
  23. else nxt_state = s0;
  24. s1: if(seq_in == 1) nxt_state = s2;
  25. else nxt_state = s1;
  26. s2: if(seq_in == 0) nxt_state = s3;
  27. else nxt_state = s0;
  28. s3: if(seq_in == 1) nxt_state = s4;
  29. else nxt_state = s1;
  30. s4: if(seq_in == 0) nxt_state = s5;
  31. else nxt_state = s0;
  32. s5: if(seq_in == 1) nxt_state = s0;
  33. else nxt_state = s1;
  34. default: nxt_state = s0;
  35. endcase
  36. end
  37. //第三段:组合逻辑
  38. always@(*) begin
  39. if(cur_state == s5) out = 1;
  40. else out = 0;
  41. end
  42. //第三段:时序逻辑
  43. /*
  44. always@(posedge clk or negedge rst_n) begin
  45. if(~rst_n) out <= 0;
  46. else if(nxt_state == s5) out <= 1;
  47. else out <= 0;
  48. end
  49. */
  50. endmodule

给出testbench文件:


  
  1. `timescale 1ns/1ps
  2. module seq_detect_tb();
  3. //输入输出分别转化为reg,wire
  4. reg clk;
  5. reg rst_n;
  6. reg seq_in;
  7. wire out;
  8. parameter PERIOD = 4;
  9. //设计时钟
  10. initial begin
  11. clk = 0;
  12. # PERIOD/2
  13. clk = ~clk;
  14. end
  15. //设计复位以及输入
  16. initial begin
  17. rst_n = 0;
  18. seq_in = 1;
  19. #5
  20. rst_n = 1;
  21. forever begin
  22. @(posedge clk)
  23. seq_in = 0;
  24. @(posedge clk)
  25. seq_in = 1;
  26. end
  27. end
  28. //例化设计模块得到输出
  29. seq_detect inst_seq_detect(
  30. .clk(clk),
  31. .rst_n(rst_n),
  32. .seq_in(seq_in),
  33. .out(out)
  34. );
  35. endmodule

行为仿真图:

如何最后一段换成时序逻辑,则仿真结果为:

可以发现,二者仿真结果一致,所以无论第三段是组合逻辑还是时序逻辑都可以,但是本人却觉得组合逻辑更让人容易理解,输入只需要根据当前状态进行判断即可。

千万不要在存有质疑了。

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/101852460

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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