不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

verilog 状态机的分类及编写方式

本节主要谈一谈Verilog的状态机实现模板,并浅析比较。

1 一段式状态机 (单always块结构):

  1. always @(posedge clk or posedge rst) begin
  2.  if(rst)
  3. FSM <= S0
  4. else begin
  5. case(FSM)
  6. S0:begin
  7. Out_0; //输出
  8. if(condition1) FSM<= S1;//状态转移
  9. else if (condition2) FSM<= S2;//状态转移
  10. end
  11. S1:begin
  12. Out_1; //输出
  13. if(condition3) FSM<= S3;//状态转移
  14. else if (condition4) FSM <=S4;
  15. end
  16. default: begin
  17. Out_0; //输出
  18. if(condition0) FSM<= S0;//状态转移
  19. end
  20. endcase
  21. end
  22. end

单always块把组合逻辑和时序逻辑放在一个时序always块描述。输出时为寄存器输出,所以无毛刺。但是这种方式会产生多余的触发器(因为把组合逻辑也放在时序逻辑中实现),而且代码难以修改调试。对于那些简单的状态机,一段式方便理解。但是对于复杂状态机,代码难于更改,条件复杂带来电路开销大,工作性能(电路最高频率)亦受限,因此实际中这种结构很少使用。
2 两段式状态机 (双always块结构):

  1. //时序逻辑,这段一般是不变的,描述从现态转移到次态
  2. always @ (posedge clk or posedge rst ) begin
  3. if(rst)
  4. current_state <= S0;
  5. else
  6. current_state<=next_state;
  7. end
  8. //组合逻辑,包括转移条件以及输出
  9. always @ (current_state) begin
  10. case(current_state)
  11. S0:begin
  12. Out_0; //输出
  13. if(condition1) next_state <= S1;//状态转移
  14. else if (condition2) next_state <= S2;//状态转移
  15. else next_state <= S0;
  16. end
  17. S1:begin
  18. Out_1; //输出
  19. if(condition3) next_state <= S3;//状态转移
  20. else if (condition4) next_state <=S4;
  21. end
  22. default: begin
  23. Out_0; //输出
  24. if(condition0) next_state <= S0;//状态转移
  25. end
  26. endcase
  27. end

 

二段式中,一个always块采用同步时序描述状态转移;另一个采用组合逻辑判断转移条件,以及描述输出。二段式便于阅读,理解和维护,有利于综合出更少的资源。但是由于采用的是组合逻辑输出,容易产生毛刺,且不利于约束,也不利于布局布线。

3 三式状态机 (三always块结构):

  1. //第一个always块,时序逻辑,描述现态转移到次态
  2. always @ (posedge clk or negedge rst) begin
  3. if(rst_n)
  4. current_state<=S0;
  5. else
  6. current_state<=next_state;
  7. end
  8. //第二个always块,组合逻辑,描述状态转移的条件
  9. always @ (current_state) begin
  10. case(current_state)
  11. S0:begin
  12. if(condition1) next_state <= S1;//状态转移
  13. else if (condition2) next_state <= S2;//状态转移
  14. else next_state <= S0;
  15. end
  16. S1:begin
  17. if(condition3) next_state <= S3;//状态转移
  18. else if (condition4) next_state <=S4;
  19. end
  20. default: begin
  21. if(condition0)   next_state <= S0;//状态转移
  22. end
  23. endcase
  24. end
  25. //第三个always块,时序逻辑,描述输出
  26. always @ (posedge clk or negedge rst) begin
  27. if(rst)
  28. out0;
  29. else
  30. case(current_state)
  31. S0: out0
  32. S1: out1;
  33. default:Out0;
  34. endcase
  35. end

三段式结构中,2个时序always块分别用来描述状态跳转和输出。组合always块用于描述状态转移条件。虽然使用的硬件资源较多,但输出采用寄存器结构,无毛刺,而且代码更清晰易读,对于复杂的状态机来说逻辑清晰,是一种比较流行的状态机结构。

另外,对于更为复杂的状态机模型,并不限于以上结构,状态可能直接硬件多个电路,状态中包含子状态等,都会派生出更为复杂的写法。但一般来讲,小组合、大时序,状态跳转、状态转移条件判定,状态机输出分开描述,既可以做到逻辑清晰,也能控制电路的复杂度。
————————————————

 

posted on 2021-06-29 10:47  皮皮祥  阅读(427)  评论(0编辑  收藏  举报