请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。
两个方法:一,状态机法;二:序列缓存对比法。
一,状态机法,注意用moore型状态机实现还是mealy型状态机实现,是重叠检测还是非重叠检测。
设计代码:
`timescale 1ns/1ns
module xulie(
input clk,
input rst_n,
input a,
output reg match
);
//moore型状态机检测01110001序列
reg [3:0] state_c;
reg [3:0] state_n;
parameter IDLE=4'b0000;
parameter S1=4'b0001;
parameter S2=4'b0011;
parameter S3=4'b0010;
parameter S4=4'b0110;
parameter S5=4'b0111;
parameter S6=4'b0101;
parameter S7=4'b0100;
parameter S8=4'b1100;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state_c<=IDLE;
end else begin
state_c<=state_n;
end
end
always @(*) begin
case(state_c)
IDLE:state_n=a?IDLE:S1;
S1:state_n=a?S2:S1;
S2:state_n=a?S3:S1;
S3:state_n=a?S4:S1;
S4:state_n=a?IDLE:S5;
S5:state_n=a?IDLE:S6;
S6:state_n=a?S2:S7;
S7:state_n=a?S8:S1;
S8:state_n=a?IDLE:S1;
default:state_n=IDLE;
endcase
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
match<=1'b0;
end else if(state_n==S8) begin
match<=1'b1;
end else begin
match<=1'b0;
end
end
endmodule
测试代码:
`timescale 1ns/1ns
module xulie_tb();
reg clk,rst_n;
reg a;
wire match;
initial begin
clk = 0;
rst_n = 0;
#10;
rst_n=1;
forever #20 a=({$random}%2);
#1000;
$stop;
end
always #10 clk=~clk;
xulie dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.match(match)
);
endmodule
二,序列缓存对比法,将八个时刻的数据缓存作为一个数组,进新的数据,就数组其他元素左移,新的数据在最低位。数组和目标序列对比。
1.声明数组,缓存数值;
2.移位:通过位截取操作和位拼接操作实现;
3.比较器:数组与目标序列对比。
8位移位寄存器由8个单独的寄存器组成,每个寄存器可以存储一位二进制数据。通过对这些寄存器进行适当的配置和操作,可以实现数据的移位和存储。
设计代码:
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg [7:0] rem_a;
parameter S=8'b01110001;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rem_a<=8'b0;
end else begin
rem_a<={rem_a[6:0],a};
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
match<=1'b0;
end else if(rem_a==S) begin
match<=1'b1;
end else begin
match<=1'b0;
end
end
endmodule
测试代码:
`timescale 1ns/1ns
module sequence_detect_tb();
reg clk,rst_n;
reg a;
wire match;
initial begin
$dumpfile("out.vcd");
$dumpvars(0,sequence_detect_tb);
clk = 0;
rst_n = 0;
#30;
rst_n=1;
forever #20 a=({$random}%2);
#1000;
$stop;
end
always #10 clk=~clk;
sequence_detect dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.match(match)
);
endmodule
仿真波形:
遗留问题:
牛客网一直都是显示???