• 【HDLBits 刷题 10】Circuits(6)Finite State Manchines 10-17


    目录

    写在前面

    Finite State Manchines

    Lemmings1

    Lemmings2

    Lemmings3

    Lemmings4

    Fsm onehot

    Fsm ps2

    Fsm ps2data

    Fsm serial


    写在前面

    HDLBits 刷题来到了最为重要的一部分---有限状态机,都说 Verilog 设计的精髓就是状态机的设计,可见状态机设计的重要性,通过三十多道的状态机的练习,可以更加熟悉状态机设计的要点,通常都设计为三段式,这样设计的状态机层次清晰且易于设计,时序上更为易懂。以下的解题方法不一定为最佳解决方案,有更好的方法欢迎提出,共同学习,共同进步!

    Finite State Manchines

    Lemmings1

    游戏 Lemmings1 涉及大脑相当简单的小动物。如此简单,以至于我们将使用有限状态机对其进行建模。

    在Lemmings  的2D世界中,Lemmings 可以处于两种状态之一:向左走或向右走。如果它撞到障碍物,它会改变方向。特别是,如果旅鼠在左侧被撞倒,它将向右走。如果它被撞到右边,它会向左走。如果它同时在两侧颠簸,它仍然会切换方向。

    实现具有两个状态、两个输入和一个输出的 Moore 状态机,以对此行为进行建模。

    以下四道题还挺有趣的,以游戏为引入,对其状态进行建模。

    44e10a32e34244deb48d256b9b9a55a8.png

    1. module top_module(
    2. input clk,
    3. input areset,
    4. input bump_left,
    5. input bump_right,
    6. output walk_left,
    7. output walk_right
    8. );
    9. //状态机状态定义
    10. parameter LEFT = 0;
    11. parameter RIGHT = 1;
    12. reg state;
    13. reg next_state;
    14. //状态机第一段,状态初始化,时序逻辑非阻塞赋值
    15. always @(posedge clk or posedge areset) begin
    16. if (areset) begin
    17. state <= LEFT;
    18. end
    19. else begin
    20. state <= next_state;
    21. end
    22. end
    23. //状态机第二段,状态跳转,阻塞复制
    24. always @(*) begin
    25. next_state = state;
    26. case(state)
    27. LEFT: begin
    28. if (bump_left) begin
    29. next_state = RIGHT;
    30. end
    31. else begin
    32. next_state = LEFT;
    33. end
    34. end
    35. RIGHT: begin
    36. if (bump_right) begin
    37. next_state = LEFT;
    38. end
    39. else begin
    40. next_state = RIGHT;
    41. end
    42. end
    43. endcase
    44. end
    45. //状态机第三段,结果输出,组合逻辑
    46. assign walk_left = (state==LEFT);
    47. assign walk_right = (state==RIGHT);
    48. endmodule

    Lemmings2

    除了左右走之外,如果地面消失在他们下面,Lemmings也会摔倒(并且大概会“啊!”)。

    除了左右走和颠簸时改变方向外,当地面=0时,旅鼠会摔倒并说“啊啊!当地面重新出现(地面=1)时,旅鼠将恢复沿与坠落前相同的方向行走。在跌倒时被撞到不会影响行走方向,并且与地面消失(但尚未下降)在同一周期中被撞击,或者当地面在仍然下降时重新出现时,也不影响行走方向。

    构建一个有限状态机来模拟这种行为。

    38adb6740e54431ca6b5d7a62d8b2492.png

    1. //`timescale 100ps / 1ps
    2. //
    3. // Stage: Finite_State_Manchines
    4. // Engineer: LQC
    5. // Create Date: 2022/08/06
    6. // Design Name:
    7. // Module Name: top_module
    8. // Description:
    9. // 除了左右走之外,如果地面消失,Lemmings也会摔倒(并且大概会“啊!”)。
    10. //
    11. // 除了左右走和颠簸时改变方向外,当地面=0时,旅鼠会摔倒并说“啊啊!
    12. // 当地面重新出现(地面=1)时,旅鼠将恢复沿与坠落前相同的方向行走。
    13. // 在跌倒时被撞到不会影响行走方向,并且与地面消失(但尚未下降)
    14. // 在同一周期中被撞击,或者当地面在仍然下降时重新出现时,也不影响行走方向。
    15. //
    16. // 构建一个有限状态机来模拟这种行为。
    17. //
    18. module top_module(
    19. input clk,
    20. input areset, // Freshly brainwashed Lemmings walk left.
    21. input bump_left,
    22. input bump_right,
    23. input ground,
    24. output walk_left,
    25. output walk_right,
    26. output aaah
    27. );
    28. //状态机状态定义
    29. parameter LEFT = 0;
    30. parameter RIGHT = 1;
    31. parameter LEFT_AAAH = 2;
    32. parameter RIGHT_AAAH = 3;
    33. reg [1:0] state;
    34. reg [1:0] next_state;
    35. //状态机第一段,初始化状态,时序逻辑非阻塞赋值
    36. always @(posedge clk or posedge areset) begin
    37. if (areset) begin
    38. state <= LEFT;
    39. end
    40. else begin
    41. state <= next_state;
    42. end
    43. end
    44. //状态机第二段,状态跳转,阻塞赋值
    45. always @(*) begin
    46. case(state)
    47. LEFT: begin
    48. if (~ground) begin
    49. next_state <= LEFT_AAAH;
    50. end
    51. else if (bump_left) begin
    52. next_state <= RIGHT;
    53. end
    54. else begin
    55. next_state <= LEFT;
    56. end
    57. end
    58. RIGHT: begin
    59. if (~ground) begin
    60. next_state <= RIGHT_AAAH;
    61. end
    62. else if (bump_right) begin
    63. next_state <= LEFT;
    64. end
    65. else begin
    66. next_state <= RIGHT;
    67. end
    68. end
    69. LEFT_AAAH: begin
    70. if (ground) begin
    71. next_state <= LEFT;
    72. end
    73. else begin
    74. next_state <= LEFT_AAAH;
    75. end
    76. end
    77. RIGHT_AAAH: begin
    78. if (ground) begin
    79. next_state <= RIGHT;
    80. end
    81. else begin
    82. next_state <= RIGHT_AAAH;
    83. end
    84. end
    85. endcase
    86. end
    87. //状态机第三段,结果输出,组合逻辑
    88. assign walk_left = (state==LEFT);
    89. assign walk_right = (state==RIGHT);
    90. assign aaah = ((state==LEFT_AAAH) | (state==RIGHT_AAAH));
    91. endmodule

    Lemmings3

    除了走路和摔倒之外,Lemmings有时还可以被告知做一些有用的事情,比如挖(当dig=1时开始挖)。如果旅鼠当前在地面上行走(地面=1且未掉落),则可以挖掘,并将继续挖掘,直到到达另一侧(地面=0)。在这一点上,由于没有地面,它会掉下来(啊啊!),然后一旦它再次撞击地面,就继续朝着原来的方向走。与坠落一样,在挖掘时被撞击没有效果,并且在跌倒或没有地面时被告知要挖掘会被忽略。

    (换句话说,行走的旅鼠可能会摔倒,挖掘或改变方向。如果满足这些条件中的多个条件,则下降的优先级高于 dig,后者的优先级高于切换方向。

    扩展有限状态机以对此行为进行建模。

    7cc441f99f254abc93bd8a29ffcc15a9.png

    1. module top_module(
    2. input clk,
    3. input areset, // Freshly brainwashed Lemmings walk left.
    4. input bump_left,
    5. input bump_right,
    6. input ground,
    7. input dig,
    8. output walk_left,
    9. output walk_right,
    10. output aaah,
    11. output digging
    12. );
    13. //状态申明
    14. parameter LEFT = 8'b00000001; //向左走状态
    15. parameter RIGHT = 8'b00000010; //向右走状态
    16. parameter LEFT_AH = 8'b00000100; //向左走出现没地喊叫
    17. parameter RIGHT_AH = 8'b00001000; //向右走出现没地喊叫
    18. parameter LEFT_DIG = 8'b00010000; //向左走挖掘指令
    19. parameter RIGHT_DIG = 8'b00100000; //向右走挖掘指令
    20. parameter LEFT_DIG_AH = 8'b01000000; //向左走挖掘出现地空
    21. parameter RIGHT_DIG_AH = 8'b10000000; //向右走挖掘出现地空
    22. reg [7:0] state;
    23. reg [7:0] next_state;
    24. //状态机第一段,状态初始化,时序逻辑非阻塞赋值
    25. always @(posedge clk or posedge areset) begin
    26. if (areset) begin
    27. state <= LEFT;
    28. end
    29. else begin
    30. state <= next_state;
    31. end
    32. end
    33. //状态机第二段,状态跳转,阻塞赋值
    34. always @(*) begin
    35. next_state = state;
    36. case(state)
    37. LEFT: begin
    38. if (~ground) begin
    39. next_state = LEFT_AH;
    40. end
    41. else if (dig) begin
    42. next_state = LEFT_DIG;
    43. end
    44. else if (bump_left) begin
    45. next_state = RIGHT;
    46. end
    47. else begin
    48. next_state = LEFT;
    49. end
    50. end
    51. RIGHT: begin
    52. if (~ground) begin
    53. next_state = RIGHT_AH;
    54. end
    55. else if (dig) begin
    56. next_state = RIGHT_DIG;
    57. end
    58. else if (bump_right) begin
    59. next_state = LEFT;
    60. end
    61. else begin
    62. next_state = RIGHT;
    63. end
    64. end
    65. LEFT_AH: begin
    66. if (ground) begin
    67. next_state = LEFT;
    68. end
    69. else begin
    70. next_state = LEFT_AH;
    71. end
    72. end
    73. RIGHT_AH: begin
    74. if (ground) begin
    75. next_state = RIGHT;
    76. end
    77. else begin
    78. next_state = RIGHT_AH;
    79. end
    80. end
    81. LEFT_DIG: begin
    82. if (~ground) begin
    83. next_state = LEFT_DIG_AH;
    84. end
    85. else begin
    86. next_state = LEFT_DIG;
    87. end
    88. end
    89. RIGHT_DIG: begin
    90. if (~ground) begin
    91. next_state = RIGHT_DIG_AH;
    92. end
    93. else begin
    94. next_state = RIGHT_DIG;
    95. end
    96. end
    97. LEFT_DIG_AH: begin
    98. if (ground) begin
    99. next_state = LEFT;
    100. end
    101. else begin
    102. next_state = LEFT_DIG_AH;
    103. end
    104. end
    105. RIGHT_DIG_AH: begin
    106. if (ground) begin
    107. next_state = RIGHT;
    108. end
    109. else begin
    110. next_state = RIGHT_DIG_AH;
    111. end
    112. end
    113. default: begin
    114. next_state = LEFT;
    115. end
    116. endcase
    117. end
    118. //状态机第三段,结果输出,组合逻辑
    119. assign walk_left = (state == LEFT);
    120. assign walk_right = (state == RIGHT);
    121. assign aaah = ((state == LEFT_AH) | (state == RIGHT_AH) | (state == LEFT_DIG_AH) | (state == RIGHT_DIG_AH));
    122. assign digging = ((state == LEFT_DIG) | (state == RIGHT_DIG));
    123. endmodule

    Lemmings4

    虽然旅鼠可以走路,摔倒和挖掘,但旅鼠并不是无懈可击的。如果旅鼠坠落太久然后撞到地面,它可能会飞溅。特别是,如果一只旅鼠坠落超过20个时钟周期,然后撞击地面,它将飞溅并停止行走,坠落或挖掘(所有4个输出变为0),永远(或直到FSM被重置)。旅鼠在落地之前可以落多远没有上限。旅鼠只在撞击地面时飞溅;它们不会在半空中飞溅。

    扩展有限状态机以对此行为进行建模。

    1f487024b9234fb68ff7dfed806bcee6.png

    1. module top_module(
    2. input clk,
    3. input areset, // Freshly brainwashed Lemmings walk left.
    4. input bump_left,
    5. input bump_right,
    6. input ground,
    7. input dig,
    8. output walk_left,
    9. output walk_right,
    10. output aaah,
    11. output digging
    12. );
    13. //状态申明
    14. parameter LEFT = 9'b000000001; //向左走状态
    15. parameter RIGHT = 9'b000000010; //向右走状态
    16. parameter LEFT_AH = 9'b000000100; //向左走出现没地喊叫
    17. parameter RIGHT_AH = 9'b000001000; //向右走出现没地喊叫
    18. parameter LEFT_DIG = 9'b000010000; //向左走挖掘指令
    19. parameter RIGHT_DIG = 9'b000100000; //向右走挖掘指令
    20. parameter LEFT_DIG_AH = 9'b001000000; //向左走挖掘出现地空
    21. parameter RIGHT_DIG_AH = 9'b010000000; //向右走挖掘出现地空
    22. parameter SPLATTER = 9'b100000000; //掉落时间过久碰地飞溅
    23. reg [8:0] state;
    24. reg [8:0] next_state;
    25. reg [100:0] fall_cnt;
    26. //状态机第一段,状态初始化,时序逻辑非阻塞赋值
    27. always @(posedge clk or posedge areset) begin
    28. if (areset) begin
    29. state <= LEFT;
    30. end
    31. else begin
    32. state <= next_state;
    33. end
    34. end
    35. //状态机第二段,状态跳转,阻塞赋值
    36. always @(*) begin
    37. next_state = state;
    38. case(state)
    39. LEFT: begin
    40. if (~ground) begin
    41. next_state = LEFT_AH;
    42. end
    43. else if (dig) begin
    44. next_state = LEFT_DIG;
    45. end
    46. else if (bump_left) begin
    47. next_state = RIGHT;
    48. end
    49. else begin
    50. next_state = LEFT;
    51. end
    52. end
    53. RIGHT: begin
    54. if (~ground) begin
    55. next_state = RIGHT_AH;
    56. end
    57. else if (dig) begin
    58. next_state = RIGHT_DIG;
    59. end
    60. else if (bump_right) begin
    61. next_state = LEFT;
    62. end
    63. else begin
    64. next_state = RIGHT;
    65. end
    66. end
    67. LEFT_AH: begin
    68. if (ground && fall_cnt>='d20) begin
    69. next_state = SPLATTER;
    70. end
    71. else if (ground && fall_cnt<='d19) begin
    72. next_state = LEFT;
    73. end
    74. else begin
    75. next_state = LEFT_AH;
    76. end
    77. end
    78. RIGHT_AH: begin
    79. if (ground && fall_cnt>='d20) begin
    80. next_state = SPLATTER;
    81. end
    82. else if (ground && fall_cnt<='d19) begin
    83. next_state = RIGHT;
    84. end
    85. else begin
    86. next_state = RIGHT_AH;
    87. end
    88. end
    89. LEFT_DIG: begin
    90. if (~ground) begin
    91. next_state = LEFT_DIG_AH;
    92. end
    93. else begin
    94. next_state = LEFT_DIG;
    95. end
    96. end
    97. RIGHT_DIG: begin
    98. if (~ground) begin
    99. next_state = RIGHT_DIG_AH;
    100. end
    101. else begin
    102. next_state = RIGHT_DIG;
    103. end
    104. end
    105. LEFT_DIG_AH: begin
    106. if (ground && fall_cnt>='d20) begin
    107. next_state = SPLATTER;
    108. end
    109. else if (ground && fall_cnt<='d19) begin
    110. next_state = LEFT;
    111. end
    112. else begin
    113. next_state = LEFT_DIG_AH;
    114. end
    115. end
    116. RIGHT_DIG_AH: begin
    117. if (ground && fall_cnt>='d20) begin
    118. next_state = SPLATTER;
    119. end
    120. else if (ground && fall_cnt<='d19) begin
    121. next_state = RIGHT;
    122. end
    123. else begin
    124. next_state = RIGHT_DIG_AH;
    125. end
    126. end
    127. SPLATTER: begin
    128. next_state = next_state;
    129. end
    130. default: begin
    131. next_state = LEFT;
    132. end
    133. endcase
    134. end
    135. //对掉落时间计数
    136. always @(posedge clk or posedge areset) begin
    137. if (areset) begin
    138. fall_cnt <= 'd0;
    139. end
    140. else if (state==LEFT_AH || state==RIGHT_AH || state==LEFT_DIG_AH || state==RIGHT_DIG_AH) begin
    141. fall_cnt <= fall_cnt + 'd1;
    142. end
    143. else begin
    144. fall_cnt <= 'd0;
    145. end
    146. end
    147. //状态机第三段,结果输出,组合逻辑
    148. assign walk_left = (state == LEFT);
    149. assign walk_right = (state == RIGHT);
    150. assign aaah = ((state == LEFT_AH) | (state == RIGHT_AH) | (state == LEFT_DIG_AH) | (state == RIGHT_DIG_AH));
    151. assign digging = ((state == LEFT_DIG) | (state == RIGHT_DIG));
    152. endmodule

    Fsm onehot

    给定具有以下具有 1 个输入和 2 个输出的状态机:

    f3c274e95be54cee9dd236ef49ff1bcc.png

    假设此状态机使用单热编码,其中状态[0]到状态[9]分别对应于状态S0到S9。除非另有说明,否则输出为零。

    实现状态机的状态转换逻辑和输出逻辑部分(但不是状态触发器)。您将获得状态为当前状态[9:0],并且必须产生next_state[9:0]和两个输出。通过假设一个热编码的检查来推导逻辑方程。(测试平台将使用非一个热输入进行测试,以确保您不会尝试执行更复杂的操作)。

    1. module top_module(
    2. input in,
    3. input [9:0] state,
    4. output [9:0] next_state,
    5. output out1,
    6. output out2
    7. );
    8. assign next_state[0] = (state[0] & ~in) | (state[1] & ~in) | (state[2] & ~in) | (state[3] & ~in) | (state[4] & ~in) | (state[7] & ~in) | (state[8] & ~in) | (state[9] & ~in);
    9. assign next_state[1] = (state[0] & in) | (state[8] & in) | (state[9] & in);
    10. assign next_state[2] = (state[1] & in);
    11. assign next_state[3] = (state[2] & in);
    12. assign next_state[4] = (state[3] & in);
    13. assign next_state[5] = (state[4] & in);
    14. assign next_state[6] = (state[5] & in);
    15. assign next_state[7] = (state[6] & in) | (state[7] & in);
    16. assign next_state[8] = (state[5] & ~in);
    17. assign next_state[9] = (state[6] & ~in);
    18. assign out1 = (state[8] | state[9]);
    19. assign out2 = (state[7] | state[9]);
    20. endmodule

    Fsm ps2

    PS/2 鼠标协议发送长度为 3 个字节的消息。但是,在连续的字节流中,消息的开始和结束位置并不明显。唯一的迹象是,每个三字节消息的第一个字节总是有位[3]=1(但其他两个字节的位[3]可能是1或0,具体取决于数据)。

    我们想要一个有限状态机,当给定一个输入字节流时,它将搜索消息边界。我们将使用的算法是丢弃字节,直到我们看到一个bit[3]=1的字节。然后,我们假设这是消息的字节1,并在收到所有3个字节(完成)后发出消息接收信号。

    FSM 应在成功接收每条消息的第三个字节后立即在周期内完成信号。

    4c313525c5ce47b983bc4c8da5eba45e.png

    1. module top_module(
    2. input clk,
    3. input [7:0] in,
    4. input reset, // Synchronous reset
    5. output done
    6. );
    7. parameter IDLE = 'd0;
    8. parameter BYTE1 = 'd1;
    9. parameter BYTE2 = 'd2;
    10. parameter BYTE3 = 'd3;
    11. reg [1:0] state;
    12. reg [1:0] next_state;
    13. //状态机第一段,初始状态,时序逻辑非阻塞赋值
    14. always @(posedge clk or posedge reset) begin
    15. if (reset) begin
    16. state <= IDLE;
    17. end
    18. else begin
    19. state <= next_state;
    20. end
    21. end
    22. //状态机第二段,状态跳转,阻塞赋值
    23. always @(*) begin
    24. next_state = state;
    25. case(state)
    26. IDLE: begin
    27. if (in[3]) begin
    28. next_state = BYTE1;
    29. end
    30. else begin
    31. next_state = IDLE;
    32. end
    33. end
    34. BYTE1: begin
    35. next_state = BYTE2;
    36. end
    37. BYTE2: begin
    38. next_state = BYTE3;
    39. end
    40. BYTE3: begin
    41. if (in[3]) begin
    42. next_state <= BYTE1;
    43. end
    44. else begin
    45. next_state <= IDLE;
    46. end
    47. end
    48. endcase
    49. end
    50. //状态机第三段,结果输出,组合逻辑
    51. assign done = (state == BYTE3);
    52. endmodule

    Fsm ps2data

    现在,您已经有了一个状态机,该状态机将识别 PS/2 字节流中的三字节消息,请添加一个数据路径,该数据路径在收到数据包时也会输出 24 位(3 字节)消息(out_bytes[23:16] 是第一个字节,out_bytes[15:8] 是第二个字节,依此类推)。

    每当置位完成的信号时,out_bytes都必须有效。您可以在其他时间输出任何内容(即,不在乎)。

    例如:

    fbae3bc925114edd8aa7901bd290fccd.png

    1. module top_module(
    2. input clk,
    3. input [7:0] in,
    4. input reset,
    5. output [23:0] out_bytes,
    6. output done
    7. );
    8. parameter IDLE = 'd0;
    9. parameter BYTE1 = 'd1;
    10. parameter BYTE2 = 'd2;
    11. parameter BYTE3 = 'd3;
    12. reg [1:0] state;
    13. reg [1:0] next_state;
    14. reg [23:0] byte_rx;
    15. //状态机第一段,初始状态,时序逻辑非阻塞赋值
    16. always @(posedge clk) begin
    17. if (reset) begin
    18. state <= IDLE;
    19. end
    20. else begin
    21. state <= next_state;
    22. end
    23. end
    24. //状态机第二段,状态跳转,阻塞赋值
    25. always @(*) begin
    26. next_state = state;
    27. case(state)
    28. IDLE: begin
    29. if (in[3]) begin
    30. next_state = BYTE1;
    31. end
    32. else begin
    33. next_state = IDLE;
    34. end
    35. end
    36. BYTE1: begin
    37. next_state = BYTE2;
    38. end
    39. BYTE2: begin
    40. next_state = BYTE3;
    41. end
    42. BYTE3: begin
    43. if (in[3]) begin
    44. next_state = BYTE1;
    45. end
    46. else begin
    47. next_state = IDLE;
    48. end
    49. end
    50. endcase
    51. end
    52. //
    53. always @(posedge clk) begin
    54. if (next_state == BYTE1) begin
    55. byte_rx <= {byte_rx[15:0],in};
    56. end
    57. else if (next_state == BYTE2) begin
    58. byte_rx <= {byte_rx[15:0],in};
    59. end
    60. else if (next_state == BYTE3) begin
    61. byte_rx <= {byte_rx[15:0],in};;
    62. end
    63. else begin
    64. byte_rx <= 'd0;
    65. end
    66. end
    67. //状态机第三段,结果输出,组合逻辑
    68. assign done = (state == BYTE3);
    69. assign out_bytes = byte_rx;
    70. endmodule

    Fsm serial

    在许多(较旧的)串行通信协议中,每个数据字节都与起始位和停止位一起发送,以帮助接收方从位流中分隔字节。一种常见的方案是使用一个起始位 (0)、8 个数据位和 1 个停止位 (1)。当没有传输任何内容(空闲)时,该线也处于逻辑1。

    设计一个有限状态机,当给定比特流时,它将识别何时正确接收字节。它需要识别起始位,等待所有8个数据位,然后验证停止位是否正确。如果停止位未按预期出现,则 FSM 必须等到找到停止位后再尝试接收下一个字节。

    95accebcb00a473091dc17c1344d503b.png

    1. module top_module(
    2. input clk,
    3. input in,
    4. input reset,
    5. output done
    6. );
    7. //状态机状态申明
    8. parameter IDLE = 12'b000000000001;
    9. parameter START = 12'b000000000010;
    10. parameter DATA_ONE = 12'b000000000100;
    11. parameter DATA_TWO = 12'b000000001000;
    12. parameter DATA_THREE = 12'b000000010000;
    13. parameter DATA_FOUR = 12'b000000100000;
    14. parameter DATA_FIVE = 12'b000001000000;
    15. parameter DATA_SIX = 12'b000010000000;
    16. parameter DATA_SEVEN = 12'b000100000000;
    17. parameter DATA_EIGHT = 12'b001000000000;
    18. parameter STOP = 12'b010000000000;
    19. parameter WAIT = 12'b100000000000;
    20. reg [11:0] state;
    21. reg [11:0] next_state;
    22. //状态机第一段,状态初始化,时序逻辑,非阻塞赋值
    23. always @(posedge clk) begin
    24. if (reset) begin
    25. state <= IDLE;
    26. end
    27. else begin
    28. state <= next_state;
    29. end
    30. end
    31. //状态机第二段,状态跳转,阻塞赋值
    32. always @(*) begin
    33. next_state = state;
    34. case(state)
    35. IDLE: begin
    36. if (~in) begin
    37. next_state = START;
    38. end
    39. else begin
    40. next_state = IDLE;
    41. end
    42. end
    43. START: begin
    44. next_state = DATA_ONE;
    45. end
    46. DATA_ONE: begin
    47. next_state = DATA_TWO;
    48. end
    49. DATA_TWO: begin
    50. next_state = DATA_THREE;
    51. end
    52. DATA_THREE:begin
    53. next_state = DATA_FOUR;
    54. end
    55. DATA_FOUR: begin
    56. next_state = DATA_FIVE;
    57. end
    58. DATA_FIVE: begin
    59. next_state = DATA_SIX;
    60. end
    61. DATA_SIX: begin
    62. next_state = DATA_SEVEN;
    63. end
    64. DATA_SEVEN: begin
    65. next_state = DATA_EIGHT;
    66. end
    67. DATA_EIGHT: begin
    68. if (in) begin
    69. next_state = STOP;
    70. end
    71. else begin
    72. next_state = WAIT;
    73. end
    74. end
    75. WAIT: begin
    76. if (in) begin
    77. next_state = IDLE;
    78. end
    79. else begin
    80. next_state = WAIT;
    81. end
    82. end
    83. STOP: begin
    84. if (in) begin
    85. next_state = IDLE;
    86. end
    87. else begin
    88. next_state = START;
    89. end
    90. end
    91. default: begin
    92. next_state = IDLE;
    93. end
    94. endcase
    95. end
    96. //状态机第三段,结果输出,组合逻辑
    97. assign done = (state==STOP);
    98. endmodule

  • 相关阅读:
    渗透测试-xml注入以及xxe漏洞
    实时的语音降噪神经网络算法
    数据结构 图
    【Linux私房菜】第六期——Shell编程
    Linux:mongodb数据库源码包安装(4.4.25版本)
    【jq】如何优雅在shell脚本处理json?
    解决ubuntu22.04共享文件夹问题
    PMP每日一练 | 考试不迷路-8.5(包含敏捷+多选)
    6.27 JAVA笔试题
    C++空间配置器
  • 原文地址:https://blog.csdn.net/m0_61298445/article/details/126368390