最近在学习状态机,用状态机实现序列检测器10010.
思路如下:
1. S0代表当前数据0,如果检测到0就停在S0,如果检测到1就进入S1。
2. S1代表当前数据1,如果检测到0就进入S2,如果检测到1就停在S1。
3. S2 代表数据10,如果检测到0就进入S3,如果检测到1就回到S1。
4. S3代表数据100,如果检测到0就回到S0,如果检测到1就进入S4。
5. S4代表数据1001,如果检测到0就进入S5,如果检测到1就回到S1。
6. S5代表数据10010,如果检测到0就回到S0,如果检测到1就进入S1。
状态机图如下:
代码如下:
module Xulie(
input wire clk,
input wire rst_n,
input wire in,
output Bingo
);
reg [5:0] state;
parameter [5:0] S0 = 6'b00_0001;
parameter [5:0] S1 = 6'b00_0010;
parameter [5:0] S2 = 6'b00_0100;
parameter [5:0] S3 = 6'b00_1000;
parameter [5:0] S4 = 6'b01_0000;
parameter [5:0] S5 = 6'b10_0000;
always @ (posedge clk or rst_n) begin
if(!rst_n)
state <= S0;
else case(state)
S0: begin
if(in == 1'b1)
state <= S1;
else
state <= S0;
end
S1: begin
if(in == 1'b0)
state <= S2;
else
state <= S1;
end
S2: begin
if(in == 1'b0)
state <= S3;
else
state <= S1;
end
S3: begin
if(in == 1'b1)
state <= S4;
else
state <= S0;
end
S4: begin
if(in == 1'b0)
state <= S5;
else
state <= S1;
end
S5: begin
if(in == 1'b0)
state <= S0;
else
state <= S1;
end
default:
state <= S0;
endcase
end
assign Bingo = state==S5 ;
endmodule
Testbench如下:
`timescale 1ns/1ns
module Tb_Xulie;
reg clk, rst_n,in;
wire Bingo;
initial begin
clk = 0;
rst_n = 0;
in = 0;
#100;
rst_n =1;
end
initial begin
#200;
in = 1;
#10;
in = 1;
#10;
in = 0;
#10;
in = 0;
#10;
in = 1;
#10;
in = 0;
#10;
in = 1;
#10;
in = 1;
#10;
in = 0;
#10;
in = 1;
#10;
in = 0;
#10;
in = 0;
#10;
in = 1;
#10;
in = 0;
#10;
in = 1;
#100 ;
$finish ;
end
always #5 clk <= ~clk;
Xulie Xulie_inst(
.clk (clk),
.rst_n (rst_n),
.in (in),
.Bingo (Bingo)
);
endmodule
波形图如下: