FPGA学习记录
题目二:设计序列检测器
题目描述
当检测到序列“1101”时,输出结果为1,否则输出为0。
其中系统输入时钟clk为100MHz;
低电平复位有效,信号为rst_n;
输入数据信号为data_in;
输出结果信号为data_out.
(提示:可以采用条件语句,也可以采用移位寄存器来实现)
设计思路
d表示正在检测的1位数据,y表示当前是否检测到序列
-
IDLE
从IDLE空闲状态开始,若检测到当前数据是1时,符合1101第一位为1的特征,前往下一状态 -
S1
在S1状态时,表明上一状态已经检测到第一个1了。
若在S1状态里检测到当前数据是1时,符合1101第一二位为11的特征,前往下一状态。
若在S1状态里检测到当前数据是0时,表明已检测到10,不符合1101第一二位为11的特征,返回IDLE状态。 -
S2
在S2状态时,表明前述状态已经检测到11了。
若在S2状态里检测到当前数据是0时,符合1101第一二三位为110的特征,前往下一状态。
若在S2状态里检测到当前数据是1时,表明已检测到111,不符合1101第一二三位为110的特征,但这时符合检测到11这一条件,停留在S2状态。 -
S3
在S3状态时,表明前述状态已经检测到110了。
若在S3状态里检测到当前数据是1时,符合1101第一二三四位为1101的特征,前往下一状态。
若在S3状态里检测到当前数据是0时,表明已检测到1100,不符合1101。此时因为当前状态没有1,无法前往S1,所以前往S5过渡状态,等待检测到1。 -
S4
在S4状态时,表明前述状态已经检测到1101了。输出y=1。
若在S4状态里检测到当前数据是1时,表明检测到一个1,前往S1状态。
若在S4状态里检测到当前数据是0时,此时因为当前状态没有1,无法前往S1,所以前往S5过渡状态,等待检测到1。 -
S5
S5为过渡状态,在该状态下等待检测到1后,前往S1状态。
如果没有检测到1,停留在S5状态。
模块代码
module Sequential_Detector(clk,rst_n,d,data_out);
input clk,rst_n,d;
output [3:0] data_out;
reg [3:0] data_out;
reg [2:0]state;
parameter IDLE = 3'd0,
s1 = 3'd1,
s2 = 3'd2,
s3 = 3'd3,
s4 = 3'd4,
s5 = 3'd5;
always@(posedge clk or negedge rst_n)
begin
if(rst_n)
state=IDLE;
else
begin
case(state)
IDLE:begin
data_out=4'b0000;
if(d==1) state<=s1;
else state<=IDLE;
end
s1:begin
if(d==1) state<=s2;
else state<=IDLE;
end
s2:begin
if(d==0) state<=s3;
else state<=s2;
end
s3:begin
if(d==1) state<=s4;
else state<=s5;
end
s4:begin
if(d==1)
begin
data_out=4'b1101;
state<=s1;
end
else state<=s5;
end
s5:begin
if(d==1) state<=s1;
else state<=s5;
end
default: state <=IDLE;
endcase
end
end
endmodule
测试代码
module testbench( );
reg Clock,RESET;
reg [23:0]data_in;
wire d;
initial
begin
Clock = 0;
RESET = 1;
#5 RESET = 0;
#20 data_in = 24'b0011_1100_1001_1101_1001_0100;
#500 $stop; //
end
always #5 Clock = ~Clock;
always@(negedge Clock) #5 data_in = {data_in[22 : 0], data_in[23]};//Shift 1 bit in a period
assign d = data_in[23];//detect the highest bit
Sequential_Detector m0(.clk(Clock), .rst_n(RESET), .d(d));
endmodule