比较好的三段式状态机verilog范例

状态机采用VerilogHDL语言编码,建议分为三个always段完成。三段式描述方法虽然代码结构复杂了一些,但是换来的优势是使FSM做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。

示列如下:

//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
always @ (posedge clk or negedge rst_n)   //异步复位
if(!rst_n)
current_state <= IDLE;
else
current_state <= next_state;//注意,使用的是非阻塞赋值

//第二个进程,组合逻辑always模块,描述状态转移条件判断或者状态转移规律
always @ (current_state)    //电平触发
begin
next_state = x;   //要初始化,使得系统复位后能进入正确的状态
case(current_state)
S1: if(...)
next_state = S2;   //阻塞赋值
...
endcase
end

//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always @ (posedge clk or negedge rst_n)
...//初始化
case(next_state)
S1:
out1 <= 1'b1;   //注意是非阻塞逻辑
S2:
out2 <= 1'b1;
default:...    //default的作用是免除综合工具综合出锁存器。
endcase
end

三段式并不是一定要写为3个always块,如果状态机更复杂,就不止3段了。

附一个比较好的状态机范例:
01moduleFSM(clk,rst,in,out);
02inputclk,rst;
03input[7:0]in;
04output[7:0]out;
05
06parameter[1:0]//synopsys enum code
07START=2'd0,
08SA=1,
09 SB =2,
10SC=3;
11
12reg[1:0]CS,NS;
13reg[7:0]tmp_out,out;
14
15// state transfer
16always@ (posedgeclkornegedgerst)
17begin
18if (!rst) CS<=#1START;
19else      CS<=#1 NS;
20end
21
22// state transfer discipline
23always@ (inorCS)
24begin
25     NS =START;
26     case (CS)
27        START:case (in[7:6])
28                        2'b11: NS =SA;
29                        2'b00: NS =SC;
30                        default: NS =START;
31                        endcase
32        SA:if(in==8'h3c) NS = SB;
33        SB:begin
34                 if (in==8'h88) NS =SC;
35                 else             NS =START;
36                 end
37        SC:case(1'b1) //synopsys parallel_case full_case
38                 (in==8'd0): NS =SA;
39                 (8'd0
40                 (in>8'd37): NS = SB;
41                   endcase
42        endcase
43end
44
45// temp out
46always@ (CS)
47begin
48     tmp_out=8'bX;
49     case (CS)
50        START:tmp_out=8'h00;
51        SA:   tmp_out=8'h08;
52        SB:   tmp_out=8'h18;
53        SC:   tmp_out=8'h28;
54     endcase
55end
56
57// reg out
58always@ (posedgeclkornegedgerst)
59begin
60     if (!rst) out<=#18'b0;
61     else     out<=#1tmp_out;
62end
63
64endmodule

你可能感兴趣的:(FPGA)