FSM设计之一

FSM的设计是数字FPGA设计的一个主要课题之一,是Verilog必须掌握的设计手段。状态机FSM的设计一般分成三个部分,即三个always设计。

   三段式风格:其中一个always块用于状态转移,一个always块用于状态译码逻辑,另一个always块用于状态输出的寄存;但它并不一定指整个状态机只能包括三个always块,在满足输出寄存的前提下,可以使用三个及以上的always块,甚至在某些特殊情况,用两个always块的状态机也可以认为是三段式的写法。

第一个always(同步时序)格式化的描述次态寄存器到现态寄存器的转移(CS<=NS);

always @ (posedge clk,negedge rst_n)
begin
if(!rst_n)
cs
<= idle;
else
cs
<= ns;
end

第二个always (纯组合逻辑)描述状态转移的条件判断,描述状态转移的规律;

always @ (cs,a)
begin
case(cs)
idle :
begin
if(a) ns = start;
else ns = idle;
end
start:
begin
if(!a) ns = stop;
else ns = start;
end
stop:
begin
if(a) ns = clear;
else ns = stop;
end
clear:
begin
if(!a) ns = idle;
else ns = clear;
end
default: ns ='bx;
endcase
end

第三个always块群,分别用always块来描述每个输出的组合逻辑

//--------------------------------------
always @ (cs,rst_n,a)
begin
if(!rst_n)
k1
= 1'b0;
else
if(cs == clear && !a) k1 = 1'b1;
else k1 = 1'b0;
end
//--------------------------------------
always @ (cs,rst_n,a)
begin
if(!rst_n)
k2
= 1'b0;
else
if(cs==stop && a) k2=1'b1;
else k2 = 1'b0;
end

整个FSM的程序结构如下:

1 module fsm
2 (
3 input clk,
4 input rst_n,
5 input a,
6 output reg k1,
7 output reg k2
8 );
9  //-----------------------------------
10 reg [1:0] cs,ns;
11 //-----------------------------------
12 parameter
13 idle = 2'b00,
14 start = 2'b01,
15 stop = 2'b11,
16 clear = 2'b10;
17 //-----------------------------------
18 always @ (posedge clk,negedge rst_n)
19 begin
20 if(!rst_n)
21 cs <= idle;
22 else
23 cs <= ns;
24 end
25 //-----------------------------------
26 always @ (cs,a)
27 begin
28 case(cs)
29 idle :
30 begin
31 if(a) ns = start;
32 else ns = idle;
33 end
34 start:
35 begin
36 if(!a) ns = stop;
37 else ns = start;
38 end
39 stop:
40 begin
41 if(a) ns = clear;
42 else ns = stop;
43 end
44 clear:
45 begin
46 if(!a) ns = idle;
47 else ns = clear;
48 end
49 default: ns = idle;
50 endcase
51 end
52 //--------------------------------------
53 always @ (cs,rst_n,a)
54 begin
55 if(!rst_n)
56 k1 = 1'b0;
57 else
58 if(cs == clear && !a) k1 = 1'b1;
59 else k1 = 1'b0;
60 end
61 //--------------------------------------
62 always @ (cs,rst_n,a)
63 begin
64 if(!rst_n)
65 k2 = 1'b0;
66 else
67 if(cs==stop && a) k2=1'b1;
68 else k2 = 1'b0;
69 end
70 //----------------------------------------
71 endmodule

---------------------------------------------------------------------

在第三个always块也可以写出时序输出形式

always @ (posedge clk,negedge rst_n)

if(!rst_n)

  {out1,out2,out3}
<= 3'b000;

else

  
case(NS)

     idle : {out1,out2,out3}
<= 3'b001;

     .......

endcase

 

posted on 2010-11-28 15:32  齐威王  阅读(858)  评论(0编辑  收藏  举报

导航