一个简单的状态机设计--序列检测器
//------------ 文件名:seqdet.v -------------------
module seqdet( x, z, clk, rst);
input x,clk, rst;
output z;
reg [2:0] state;//状态寄存器
wire z;
parameter IDLE = 3 'd0,
A = 3 'd1,
B = 3 'd2,
C = 3 'd3,
D = 3 'd4,
E = 3 'd5,
F = 3 'd6,
G = 3 'd7;
assign z =(state==D && x==0) ? 1 :0;
//状态为D时又收到了0,表明10010收到应有输出Z为高
always @(posedge clk or negedge rst)
if(!rst)
begin
state<=IDLE;
end
else
casex( state)
IDLE: if(x==1)
state<=A; //用状态变量记住高电平(x==1)来过
else state<= IDLE; //输入的是低电平,不符合要求,所以状态保留不变
A: if (x==0)
state<=B; //用状态变量记住第二位正确低电平(x==0)来过
else state<= A; //输入的是高电平,不符合要求,所以状态保留不变
B: if (x==0)
state<=C; //用状态变量记住第三位正确低电平(x==0)来过
else state<=F; //输入的是高电平,不符合要求,记住只有一位曾经对过
C: if(x==1)
state<=D; //用状态变量记住第四位正确高电平(x==1)来过
else state<=G; //输入的是低电平,不符合要求,记住没有一位曾经对过
D: if(x==0)
state<=E; //用状态变量记住第五位正确低电平(x==0)来过
else state<=A; //输入的是高电平,不符合要求,记住只1位对过
//回到状态A
E: if(x==0)
state<=C; //用状态变量记住1 0 0曾经来过,此状态为C
else state<=A; //输入的是高电平,只有1位正确,该状态是A
F: if(x==1)
state<=A; //输入的是高电平,只有1位正确,该状态是A
else
state<=B; //输入的是低电平,已有2位正确,该状态是B
G: if(x==1)
state<=F; //输入的又是高电平,只有1位正确,记该状态F
else state <=B; //输入的是低电平,已有2位正确,该状态是B
default: state<=IDLE;
endcase
endmodule
//------ seqdet.v 文件的结束------------------------------------
//-------- 测试文件名:t.v ----------------------
`timescale 1ns/1ns
module t;
reg clk, rst;
reg [23:0] data;
wire z,x;
assign x=data[23];
initial
begin
clk =0;
rst =1;
#2 rst =0;
#30 rst =1; //复位信号
data= 20 'b1100_1001_0000_1001_0100; //码流数据
end
always #10 clk=~clk; //时钟信号
always @ (posedge clk) // 移位输出码流
data={data[22:0],data[23]};
seqdet m ( .x(x), .z(z), .clk(clk), .rst(rst)); //调用序列检测器模块
endmodule // 测试模块的结束