现在的位置: 首页 > 编程 > 正文

Verilog学习笔记简单功能实现(三)……………同步有限状态机

2016年10月10日 编程 ⁄ 共 3578字 ⁄ 字号 暂无评论

在Verilog中可以采用多种方法来描述有限状态机最常见的方法就是用always和case语句。如下图所示的状态转移图就表示了一个简单的有限状态机:

图中:图表示了一个四状态的状态机,输入为A和Reset,同步时钟为clk,输出信号是K1和K2,状态机只能在信号的上升沿发生。

 (A)下面是可综合的Verilog模块设计状态机的典型方法:(格雷码表示状态)

 1 module fsm(A,Reset,K2,K1,clk,state);
 2  input A,Reset,clk;
 3  output K2,K1;
 4  output [1:0]state;
 5  reg K2,K1;
 6  reg [1:0]state;
 7  parameter Idel=2'b00,
 8            start=2'b01,
 9            stop=2'b10,
10            clear=2'b11;
11  always @(posedge clk)
12     if (!Reset)
13       begin
14       state<=Idel;
15       K2<=0;
16       K1<=0;
17       end
18     else
19      case(state)
20       Idel:if (A)
21              begin 
22                state<=start;
23                K1<=0;
24              end
25            else
26              begin
27                state<=Idel;
28                K2<=0;
29                K1<=0;
30              end
31       start:if(!A) state<=stop;
32             else   state<=start;
33       stop: if(A)
34               begin
35                state<=clear;
36                K2<=1;
37              end
38             else    
39              begin   
40                state<=stop;
41                K2<=0;
42                K1<=0;
43              end
44       clear:if(!A)
45               begin
46                 state<=Idel;
47                 K2<=0;
48                 K1<=1;
49               end
50             else
51               begin
52                 state<=clear;
53                 K2<=0;
54                 K1<=0;
55               end
56       default:state<=2'bxx;
57       endcase
58 endmodule

 

  (B)用可以综合的Verilog模块设计、用独热码表示状态的状态机

独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。

 1 module fsm(A,Reset,K2,K1,clk,state);
 2  input A,Reset,clk;
 3  output K2,K1;
 4  output [3:0]state;
 5  reg K2,K1;
 6  reg [3:0]state;
 7  parameter Idel=4'b1000,
 8            start=4'b0100,
 9            stop=4'b0010,
10            clear=4'b0001;
11  always @(posedge clk)
12     if (!Reset)
13       begin
14       state<=Idel;
15       K2<=0;
16       K1<=0;
17       end
18     else
19      case(state)
20       Idel:if (A)
21              begin 
22                state<=start;
23                K1<=0;
24              end
25            else
26              begin
27                state<=Idel;
28                K2<=0;
29                K1<=0;
30              end
31       start:if(!A) state<=stop;
32             else   state<=start;
33       stop: if(A)
34               begin
35                state<=clear;
36                K2<=1;
37              end
38             else    
39              begin   
40                state<=stop;
41                K2<=0;
42                K1<=0;
43              end
44       clear:if(!A)
45               begin
46                 state<=Idel;
47                 K2<=0;
48                 K1<=1;
49               end
50             else
51               begin
52                 state<=clear;
53                 K2<=0;
54                 K1<=0;
55               end
56       default:state<=Idel;
57       endcase
58 endmodule

View Code

二进制编码、格雷码编码使用最少的触发器,消耗较多的组合逻辑,而独热码编码反之。独热码编码的最大优势在于状态比较时仅仅需要比较一个位,从而一定程度上简化了译码逻辑。虽然在需要表示同样的状态数时,独热编码占用较多的位,也就是消耗较多的触发器,但这些额外触发器占用的面积可与译码电路(组合电路)省下来的面积相抵消。并且采用独热码可以使电路的速度和可靠性有显著提高,而总的单元数并无增加。

 (C)用可以综合的Verilog模块设计,用状态码直接作为输出

 1 module fsm(A,Reset,K2,K1,clk,state);
 2  input A,Reset,clk;
 3  output K2,K1;
 4  output [4:0]state;
 5  reg [4:0]state;
 6  assign K2=state[4];
 7  assign K1=state[0];
 8  parameter Idel    =   5'b0_000_0,
 9            start   =   5'b0_010_0,
10            stop    =   5'b0_010_0,
11            stoptoclear=5'b1_100_0,
12            clear   =   5'b0_101_0,
13            cleartoIdel=5'b0_011_1;
14  always @(posedge clk)
15     if (!Reset)
16       begin
17       state<=Idel;
18       end
19     else
20      case(state)
21       Idel: if (A) state<=start;      
22             else   state<=Idel;
23       start:if(!A) state<=stop;
24             else   state<=start;
25       stop: if(A)  state<=stoptoclear;
26             else   state<=stop;
27       stoptoclear: state<=clear;
28       clear:if(!A) state<=cleartoIdel;
29             else   state<=clear;
30       cleartoIdel: state<=Idel;
31       default:state<=Idel;
32       endcase
33       endmodule

View Code

利用状态机的状态直接作为输出可以提升信号的开关速度并节省电路器件,但是开关的维持时间必须与状态的维持时间一致,如果要实现上述的例子必须增加状态才能实现。

在这里state[4],state[0]分别表示前面的K2和K1。

  (D)用可以综合的Verilog模块设计,设计复杂多输出状态机时常用的方法

 1 module fsm(A,Reset,K2,K1,clk,state);
 2  input A,Reset,clk;
 3  output K2,K1;
 4  output [1:0]state;
 5  reg K2,K1;
 6  reg [1:0]state,nextstate;
 7  parameter Idel    = 2'b00,
 8            start   = 2'b01,
 9            stop    = 2'b10,
10            clear   = 2'b11;
11  always @(posedge clk)               //没一个时钟沿产生一次可能的变化
12     if (!Reset)
13       state<=Idel;
14     else
15       state<=nextstate;
16  always @(state or A)          //产生下一状态的组合逻辑F
17      case(state)
18       Idel: if (A) nextstate=start;      
19             else   nextstate=Idel;
20       start:if(!A) nextstate=stop;
21             else   nextstate=start;
22       stop: if(A)  nextstate=clear;
23             else   nextstate=stop;
24       clear:if(!A) nextstate=Idel;
25             else   nextstate=clear;
26       default:     nextstate=2'bxx;
27     endcase
28  always @(state or Reset or A)  //产生输出K1的组合逻辑
29      if(!Reset) K1=0;
30        else if(state==clear&&!A) K1=1; //由clear转向Idel,因为state为非阻塞赋值,所以此时state的状态还是clear
31             else K1=0;
32  always @(state or Reset or A)  //产生输出K2的组合逻辑
33      if(!Reset) K2=0;
34        else if(state==stop&&A) K2=1;  //由stop转向clear,因为state为非阻塞赋值,所以此时state的状态还是stop
35             else K2=0;   
36       endmodule

View Code

在比较复杂的状态机设计过程中,往往把状态的变化与输出开关的控制分为两部分,就像前面的Mealy型状态机输出部分的组合逻辑一样。为了调试方便还将每一个输出的开关写成一个个的独立的always块以方便调试。在设计复杂的多输出状态及时建议采用这种方法。

 

【上篇】
【下篇】

给我留言

您必须 [ 登录 ] 才能发表留言!

×