//序列检测器 画出可以检测11101串的状态转移图,并用Verilog实现FSM;
//要求每检测到一次该序列,输出2个周期的高电平信号;要求使用低功耗的状态机编码方式;
module xmonitor(
input clk,
input rstn,
input data_in,
output reg valid_out
);
reg [4:0] state, next_state;
parameter IDLE = 5'b00000,
S1 = 5'b00001,
S11 = 5'b00010,
S111 = 5'b00100,
S1110 = 5'b01000,
S11101 = 5'b10000;
always@(posedge clk or negedge rstn) begin
if(!rstn)
state <= IDLE;
else
state <= next_state;
end
always@(*) begin
case(state)
IDLE : next_state = (data_in === 1'b1) ? S1 : IDLE ;
S1 : next_state = (data_in === 1'b1) ? S11 : IDLE ;
S11 : next_state = (data_in === 1'b1) ? S111 : IDLE ;
S111 : next_state = (data_in === 1'b1) ? S111 : S1110 ;
S1110 : next_state = (data_in === 1'b1) ? S11101 : IDLE ;
S11101 : next_state = (data_in === 1'b1) ? S11 : IDLE ;
default : next_state = IDLE;
endcase
end
always@(posedge clk or negedge rstn) begin
if(!rstn)
valid_out <= 1'b0;
else begin
case(state)
S1110: valid_out <= (data_in === 1'b1) ? 1'b1 : 1'b0;
S11101: valid_out <= 1'b1;
default: valid_out <= 1'b0;
endcase
end
end
endmodule
`timescale 1ns/1ns
module xmonitor_tb();
reg clk;
reg rstn;
reg data_in;
wire valid_out;
initial begin
clk = 1'b0;
forever begin
#10 clk = ~clk;
end
end
initial begin
rstn = 1'b0;
data_in = 1'b0;
#30 rstn = 1'b1;
data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b0;
#20 data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b1;
#20 data_in = 1'b0;
#20 data_in = 1'b1;
end
xmonitor u_xmonitor(
clk,
rstn,
data_in,
valid_out
);
endmodule