10010序列检测器
重复检测输入,当检测到输入端顺序输入10010序列时,输出为1。
1.使用同步状态机实现
1.状态转移图
2.Verilog 实现
module detect_10010(
input clk,
input rst_n,
input in_a,
output reg detect);
parameter S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b010,
S3 = 3'b011,
S4 = 3'b100;
reg [2:0] state, next_state;
always @(posedge clk) begin
if(!rst_n)
state <= S0;
else
state <= next_state;
end
always @(*) begin
case(state)
S0: if(in_a) next_state = S1;
else next_state= S0;
S1: if(~in_a) next_state = S2;
else next_state = S1;
S2: if(~in_a) next_state = S3;
else next_state = S1;
S3: if(in_a) next_state = S4;
else next_state = S0;
S4: if(~in_a) next_state = S2;
else next_state = S1;
endcase
end
always @(*) begin
if(!rst_n)
detect = 1'b0;
else begin
if(state == S4 && in_a == 1'b0)
detect = 1'b1;
else
detect = 1'b0;
end
end
endmodule
3.TB代码
module tb();
reg in_a;
reg clk, rst_n;
reg detect;
initial begin
in_a = 0;
rst_n = 1;
clk = 0;
#40 rst_n = 0;
#70 rst_n = 1;
end
initial begin
@(posedge clk);
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
#150 $finish();
end
always #50 clk = ~clk;
initial begin
$fsdbDumpvars();
end
detect_10010 DUT(.clk(clk), .rst_n(rst_n), .in_a(in_a), .detect(detect));
endmodule
4.波形
2.使用移位寄存器实现
使用一个5位的寄存器寄存5个连续输入值,并在下一个时钟周期对其移位,最后与需要的检查的序列(10010)进行对比,根据对比结果输出检测结果。
1.Verilog 实现
module detect_10010_shifter(
input clk,
input rst_n,
input in_a,
output reg detect
);
reg [4:0] rega;
always @(posedge clk) begin
if(!rst_n) begin
detect <= 0;
rega <= 'b0;
end
else begin
rega <= {rega[3:0], in_a};
end
end
always @(*) begin
if(rega == 5'b10010)
detect = 1;
else
detect = 0;
end
endmodule
2.TB代码
module tb();
reg in_a;
reg clk, rst_n;
reg detect;
initial begin
in_a = 0;
rst_n = 1;
clk = 0;
#40 rst_n = 0;
#70 rst_n = 1;
end
initial begin
@(posedge clk);
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
@(posedge clk) #70 in_a = 0;
@(posedge clk) #70 in_a = 1;
#150 $finish();
end
always #50 clk = ~clk;
initial begin
$fsdbDumpvars();
end
detect_10010_shifter DUT(.clk(clk), .rst_n(rst_n), .in_a(in_a), .detect(detect));
endmodule
3.波形
参考