简析
序列检测问题可以用移位寄存器,也可以使用状态机。
移位寄存器方法比较简单。设置一个和序列等长的寄存器,每个时钟都将输入移入寄存器的最低位,并判断寄存器中的值是否与序列相同。
状态机方法较为麻烦些。设置若干个状态(一般是序列长度+1个状态),然后每个时钟根据新的输入以及当前状态判断下一状态。
代码
移位寄存器
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[7:0] a_r;
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
a_r<='b0;
end
else begin
a_r<={a_r[6:0],a};
end
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
match <= 1'b0;
end
else begin
match <= a_r==8'b01110001;
end
end
endmodule
状态机
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
parameter ZERO=0, ONE=1, TWO=2, THREE=3, FOUR=4, FIVE=5, SIX=6, SEVEN=7, EIGHT=8;
reg [3:0] state, nstate;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
state <= ZERO;
else
state <= nstate;
end
always@(*) begin
case(state)
ZERO : nstate = a? ZERO : ONE;
ONE : nstate = a? TWO : ONE;
TWO : nstate = a? THREE: ONE;
THREE : nstate = a? FOUR : ONE;
FOUR : nstate = a? ZERO : FIVE;
FIVE : nstate = a? TWO : SIX;
SIX : nstate = a? TWO : SEVEN;
SEVEN : nstate = a? EIGHT: ONE;
EIGHT : nstate = a? THREE: ONE ;
default: nstate = ZERO;
endcase
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
match <= 0;
else
match <= state==EIGHT;
end
endmodule