【FPGA/verilog -入门学习16】fpga状态机实现

需求:

用两段式状态机设计序列码检测机。这个序列码检测机用于检索连续输入的 1bit 数据

(每个时钟周期输入 1bit),当检测到一串“101100”的输入数据时,产生一个时钟周期的

高脉冲指示信号

状态图

【FPGA/verilog -入门学习16】fpga状态机实现_第1张图片

 //实现状态机切换
 //101100 
 //完成切换后,输出高脉冲
 
`timescale 1ns/1ps
module vlg_design(
    input i_clk,
    input i_rest_n,
    input i_incode,
    output reg   o_vaild
    );

parameter IDLE = 4'd0; 
parameter S1   = 4'd1; 
parameter S2   = 4'd2; 
parameter S3   = 4'd3; 
parameter S4   = 4'd4; 
parameter S5   = 4'd5; 
parameter S6   = 4'd6; 


reg [3:0] cstate;
reg [3:0] nstate;

always @(posedge i_clk) begin
    if(!i_rest_n) cstate <= IDLE;
    else cstate <= nstate;
end


always @(*) begin
    case(cstate)
        IDLE:begin
                o_vaild <= 1'd0;
                 if(i_incode == 1) nstate <= S1;
                 else nstate <= IDLE;
             end

        S1:begin
                 o_vaild <= 1'd0;
                 if(i_incode == 0) nstate <= S2;
                 else nstate <= S1;
             end
             
        S2:begin
                o_vaild <= 1'd0;
                 if(i_incode == 1) nstate <= S3;
                 else nstate <= IDLE;
             end

        S3:begin
                 o_vaild <= 1'd0;
                 if(i_incode == 1) nstate <= S4;
                 else nstate <= S2;
             end
             
        S4:begin
                 o_vaild <= 1'd0;
                 if(i_incode == 0) nstate <= S5;
                 else nstate <= S1;
             end

        S5:begin
                o_vaild <= 1'd0;
                if(i_incode == 0) nstate <= S6;
                 else nstate <= S3;
             end
             
        S6:begin
                 o_vaild <= 1'd1;
                 if(i_incode == 1) nstate <= S1;
                 else nstate <= IDLE;
             end        
        default :begin
                nstate <= IDLE;
                o_vaild <= 1'd0;
             end
        endcase
end


endmodule


`timescale 1ns/1ps

module testbench_top();
    

//参数定义

`define CLK_PERIORD        20        //时钟周期设置为20ns(50MHz)    


//接口申明
reg i_clk;
reg i_rest_n;
reg i_incode;
wire o_vaild;
 

    
//对被测试的设计进行例化
    
vlg_design        uut_vlg_design(
    .i_clk(i_clk),
    .i_rest_n(i_rest_n),
    .i_incode(i_incode),
    .o_vaild(o_vaild) 
    );    

///

 

initial begin

i_clk <= 0;
i_rest_n <= 0;
#20;
i_rest_n <= 1;
 

end


always #(`CLK_PERIORD/2) i_clk = ~i_clk;
integer i;
 
initial begin

@(posedge i_clk);
@(posedge i_rest_n);

my_task(6'b101100);
my_task(6'b101100);

my_task(6'b111100);
my_task(6'b101110);
my_task(6'b101100);
repeat(10)@(posedge i_clk);


#2_000_000;
$stop;
end


task my_task;  
  input [5:0] data;    
  begin  
   for(i=0;i < 6;i = i+1) begin
    i_incode <= data[5-i];
    @(posedge i_clk);
   end
   
   
  end  
endtask
 

endmodule

仿真波形

你可能感兴趣的:(verilog,&FPGA,fpga开发)