Verilog-数字序列检测器101 (米利型)
四状态版
代码
`timescale 1ns / 1ps
module digit_sequence_detect_mili(
input clk,
input rstn,
input data,
output detect
);
localparam IDLE = 2'd0;
localparam S1 = 2'd1;
localparam S10 = 2'd2;
localparam S101 = 2'd3;
reg [1:0] state;
reg [1:0] next_state;
always @(posedge clk or negedge rstn) begin
if(!rstn) state <= IDLE;
else state <= next_state;
end
always @(*) begin
case(state)
IDLE: next_state = data ? S1 : IDLE; // 状态转移用三目运算符
S1: next_state = data ? S1 : S10;
S10: next_state = data ? S101 : IDLE;
S101: next_state = data ? S1 : S10;
default: next_state = IDLE;
endcase
end
assign detect = ((state == S10) && (data))? 1'b1 : 1'b0; // 米利状态机的输出还与输入有关
endmodule
仿真波形
三状态版
代码
`timescale 1ns / 1ps
module digit_sequence_detect_mili(
input clk,
input rstn,
input data,
output detect
);
localparam IDLE = 2'd0;
localparam S1 = 2'd1;
localparam S10 = 2'd2;
localparam S101 = 2'd3;
reg [1:0] state;
reg [1:0] next_state;
always @(posedge clk or negedge rstn) begin
if(!rstn) state <= IDLE;
else state <= next_state;
end
always @(*) begin
case(state)
IDLE: next_state = data ? S1 : IDLE;
S1: next_state = data ? S1 : S10;
S10: next_state = data ? S1 : IDLE; // 在S10状态下,输入1直接跳回S1状态,从而可以节省一个状态
//S101: next_state = data ? S1 : S10;
default: next_state = IDLE;
endcase
end
assign detect = ((state == S10) && (data))? 1'b1 : 1'b0;
endmodule
仿真波形
总结
可以看到,三状态版的仿真波形与四状态版的仿真波形一致,对于米利型序列检测器,最少状态数为序列长度,对于摩尔型序列检测器,最少状态数为序列长度加1.
米利型序列检测器在当周期出检测结果,摩尔型序列检测器在下一周期出检测结果
移位寄存器版本,并且是米利型的效果,还不带重叠检测
代码
reg [2:0] shifter;
always @(posedge clk or negedge rstn) begin
if(!rstn) shifter <= 0;
else if(detect) begin
shifter <= 0;
end
else begin
shifter <= {shifter[1:0],data};
end
end
assign detect = (shifter[1:0] == 2'b10 && data == 1'b1); // 已经检测到10,下个数据如果是1就置高检测标志