序列检测器
作用:从一串码流中检测出指定序列10010,监测到一个序列后就输出一个高电平。
设计状态转换机制:
初始是IDLE态,然后输入1后进入A状态,输出0;输入0依然保持IDLE,输出0;
在A状态,输入0进入B状态,输出0;输入1进入F中间态,输出0;
在B状态,输入0进入C状态,输出0;输入1进入G中间态,输出0;
.....以此类推所有状态。
一共8个状态,需要3位记录状态的寄存器,实现代码如下:
/*
从输入序列中找到指定序列10010,并在找到的下标下标记1
状态转换:
初始状态idle
状态a->1 0/0->b 1/0->a
状态b->10 0/0->c 1/0->f
状态c->100 1/0->d 0/0->g
状态d->1001 0/1->e 1/0->a
状态e->10010 1/0->a 0/0->c
状态f->101 0/0->b 1/0->a
状态g->1000 0/0->g 1/0->a
串行输入seq位串,只要检测到10010,立即输出一个1
输入端口:seq,clk, rst
输出端口:z
状态一共有8个,所以用三位表示状态0-7
*/
module seqdet(seq, clk, rst, z);
input seq, clk, rst;
output z;
wire z;//因为要立刻输出z,z用wire型
reg[2:0] state;//状态用寄存器型
parameter IDLE = 3'b000, A = 3'b001, B = 3'b010, C = 3'b011, D = 3'b100, E = 3'b101, F = 3'b110, G = 3'b111;
assign z = (state == D && seq == 0) ? 1 : 0; //到状态D并且输入是0的时候输出为1;
always @(posedge clk, negedge rst) begin
if(!rst)
state <= IDLE;//复位初始状态,时序逻辑电路,赋值用非阻塞赋值
else
begin
casex (state) //casex在state状态为不定值时可以匹配进入到IDLE
IDLE:
if(seq == 1)
state <= A;
else
state <= IDLE;
A:
if(seq == 1)
state <= A;
else
state <= B;
B:
if(seq == 1)
state <= F;
else
state <= C;
C:
if(seq == 1)
state <= D;
else
state <= G;
D:
if(seq == 1)
state <= A;
else
state <= E;
E:
if(seq == 1)
state <= A;
else
state <= C;
F:
if(seq == 1)
state <= A;
else
state <= B;
G:
if(seq == 1)
state <= F;
else
state <= G;
default: state <= IDLE;
endcase
end
end
endmodule
测试模块:生成时钟信号,调用被测模块测试
module t_seqdet;
reg clk, rst; //时钟信号用寄存器记住
wire x, z;//测试输入和输出
reg[23:0] data;//存放输入序列
assign x = data[23];//测试输入赋值