这里采用夏宇闻教授第十五章的序列检测为例来学习;
从以上的状态转换图可以写出状态机的程序:
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 ,在这里感谢齐威王!