module sequencer(
input wire i_clk,
input wire i_rst_n,
input wire i_valid,
input wire i_data,
output wire o_en,
output wire [2:0] o_cnt
);
reg i_valid_reg;
reg i_data_reg;
reg [3:0] state, state_n;
localparam s0 = 4'b0001,
s1 = 4'b0010,
s2 = 4'b0100,
s3 = 4'b1000;
always@(posedge i_clk)begin
i_valid_reg <= i_valid;
i_data_reg <= i_data;
end
always@(posedge i_clk)begin
if(!i_rst_n)
state <= s0;
else
state <= state_n;
end
always@(*)begin
state_n = state;
case(state)
s0:
begin
if(i_valid_reg && i_data_reg)
state_n = s1;
else
state_n = s0;
end
s1:
begin
if(i_valid_reg && i_data_reg)
state_n = s2;
else
state_n = s0;
end
s2:
begin
if(i_valid_reg && (i_data_reg == 1'b0) )
state_n = s3;
else if(i_valid_reg && i_data_reg)
state_n = s1;
else
state_n = s2;
end
s3:
begin
if(i_valid_reg && i_data_reg)
state_n = s0;
else if(i_valid_reg && (i_data_reg == 1'b0))
state_n = s0;
else
state_n = s3;
end
default: state_n = state;
endcase
end
reg o_en_reg;
reg [2:0] o_cnt_reg;
assign o_en = o_en_reg;
assign o_cnt = o_cnt_reg;
always@(posedge i_clk)begin
if(!i_rst_n)
o_en_reg <= 1'b0;
else if((state == s3)&& i_valid_reg && i_data_reg)
o_en_reg <= 1'b1;
else
o_en_reg <= 1'b0;
end
always@(posedge i_clk)begin
if(!i_rst_n)
o_cnt_reg <= 3'd0;
else if(o_cnt_reg == 3'd7)
o_cnt_reg <= o_cnt_reg;
else if((state == s3)&& i_valid_reg && i_data_reg)
o_cnt_reg <= o_cnt_reg + 1'b1;
else
o_cnt_reg <= o_cnt_reg;
end
endmodule