这里采用夏宇闻教授第十五章的序列检测为例来学习;
从以上的状态转换图可以写出状态机的程序:
1 module seqdet(x,out,clk,rst);
2 input x,clk,rst;
3 output out;
4 reg [2:0]state;
5 wire out;
6 parameter IDLE=3'b0,
7 A=3'd1,
8 B=3'd2,
9 C=3'd3,
10 D=3'd4,
11 E=3'd5,
12 F=3'd6,
13 G=3'd7;
14 assign out=(state==D&&x==0)?1:0;
15 always @(posedge clk or negedge rst)
16 begin
17 if(!rst)
18 state=IDLE;
19 else
20 case(state)
21 IDLE:if(x==1) state<=A;
22 else state<=IDLE;
23 A:if(x==0) state<=B;
24 else state<=A;
25 B:if(x==0) state<=C;
26 else state<=F;
27 C:if(x==1) state<=D;
28 else state<=G;
29 D:if(x==0) state<=E;
30 else state<=A;
31 E:if(x==0) state<=C;
32 else state<=A;
33 F:if(x==0) state<=B;
34 else state<=A;
35 G:if(x==1) state<=F;
36 else state<=G;
37 default: state<=IDLE;
38 endcase
39
40 end
41 endmodule
以下是测试模块:
1 `timescale 1ns/1ns
2 `define halfperiod 20
3
4 module testseqdet;
5 reg clk,rst;
6 reg [23:0]data;
7 wire out,x;
8 assign x=data[23];
9 initial begin
10 clk=0;
11 rst=1;
12 #2 rst=0;
13 #30 rst=1;
14 data=20'b1100_1001_0000_1001_0100;
15 end
16 always #(`halfperiod) clk=~clk;
17 always @(posedge clk)
18 begin
19 #2 data={data[22:0],data[23]};
20 end
21 seqdet m(.x(x),.out(out),.clk(clk),.rst(rst));
22 endmodule
其实这里也可以采用六个状态来实现功能:
1 module seqdet(x,out,clk,rst,state); 2 input x,clk,rst; 3 output out; 4 output [2:0]state; 5 reg [2:0]state; 6 wire out; 7 parameter IDLE=3'd0, 8 A=3'd1, 9 B=3'd2, 10 C=3'd3, 11 D=3'd4, 12 E=3'd5; 13 assign out=(state==D&&x==0)?1:0; 14 always @(posedge clk) 15 begin 16 if(!rst) state<=IDLE; 17 else 18 case(state) 19 IDLE:if(x==1) state<=A; 20 else state<=IDLE; 21 A:if(x==0) state<=B; 22 else state<=A; 23 B:if(x==0) state<=C; 24 else state<=A; 25 C:if(x==1) state<=D; 26 else state<=IDLE; 27 D:if(x==0) state<=E; 28 else state<=A; 29 E:if(x==0) state<=C; 30 else state<=A; 31 default: state<=IDLE; 32 endcase 33 end 34 endmodule
以下是测试模块:
1 `timescale 1ns/1ns
2 module test_seqdet;
3 reg clk,rst;
4 reg [22:0]data;
5 wire [2:0]state;
6 wire x,out;
7 assign x=data[22];
8 initial
9 begin
10 clk=0;
11 rst=1;
12 #2 rst=0;
13 #30 rst=1;
14 data=20'b1100_1001_0000_1001_0100;
15 end
16
17 always #20 clk=~clk;
18 always @(posedge clk)
19 begin
20 data={data[21:0],data[22]};
21 end
22 seqdet m(.x(x),.clk(clk),.rst(rst),.out(out),.state(state));
23 endmodule
也可以用移位寄存器来实现:
1 module seqdet
2 (
3 input wire x,
4 input wire clk,
5 input wire rst,
6 output wire z,
7 output reg [4:0] q
8 );
9
10 wire [4:0] q_next;
11
12 assign q_next ={q[3:0],x};
13 assign z = (q_next== 5'b10010) ? 1'b1:1'b0;
14
15 always @ (posedge clk,negedge rst)
16 if(!rst)
17 q <= 5'd0;
18 else
19 q <= q_next;
20
21 endmodule
寄存器的实现参照http://www.cnblogs.com/qiweiwang/archive/2011/04/18/2019952.html ,在这里感谢齐威王!