FPGA基础学习——状态机

以FPGA流水灯点亮为例

传统流水点电点亮可以利用计数器,当每计数49_999_999 (即1s)时,依次循环点亮LED0~LED3;

verilog 示例如下:

module led(

                 input clk,        //系统时钟,50MHz

                 output reg [3:0] led   // 4个led灯输出,高电平点亮

                );

reg[31:0] count;    //流水灯延时1s

always@(posedge clk)
begin

    if(count==32'd199_999_999)        //每4s计数器清零(4s/20ns=200_000_000)

count<=32'd0;
else
count<=count+32'd1;
end

always@(posedge clk)
begin
   if(count==32'd0)
led<=4'b0001;           //初始状态为led0点亮
else if(count==32'd49_999_999)
led<=4'b0010;           //延时1s点亮led1
else if(count==32'd99_999_999)
led<=4'b0100;          //延时1s点亮led2
else if (count==32'd149_999_999)
led<=4'b1000;          //延时1s点亮led3
else 
led<=led;                 //其他情况保持不变

end

endmodule


换用状态机来描述,四个led灯点亮为四个状态,还有一个初始状态

module led_sm(

                 input clk,        //系统时钟,50MHz

                 output reg [3:0] led   // 4个led灯输出,高电平点亮

                          );

reg [31:0] count;    //延时1s计数

reg[2:0] state;   //定义状态机,5种状态,2^3=8 寄存器够用

//---状态参数定义---------------

parameter S_IDLE=3'd0;

parameter S_LED0=3'd1;

parameter S_LED1=3'd2;

parameter S_LED2=3'd3;

parameter S_LED3=3'd4;

always@(posedge clk)

begin

case(state)

S_IDLE:   

    begin

         state<=S_LED0;          //初始状态直接跳转到led0点亮

         led<=4'b0000;          //初始状态四个灯全灭

    end

S_LED0:

    begin

            led<=4'b0001;            //S_LED0状态为led0灯亮

            if(count==32'd49_999_999)

                 begin 

                      state<=S_LED1;         //如果计数达1s,则跳转到S_LED1状态

                      count<=32'd0;         //计数清零

                 end

            else 

                   begin

                          state<=state;            //否则状态保持

                          count<=count+32'b1;

                      end

   end

S_LED1:

    begin

            led<=4'b0010;

            if(count==32'd49_999_999)

                 begin 

                      state<=S_LED2;

                      count<=32'd0;

                 end

            else 

                   begin

                          state<=state;

                          count<=count+32'b1;

                      end

   end

S_LED2:

    begin

            led<=4'b0001;

            if(count==32'd49_999_999)

                 begin 

                      state<=S_LED3;

                      count<=32'd0;

                 end

            else 

                   begin

                          state<=state;

                          count<=count+32'b1;

                      end

   end

S_LED3:

    begin

            led<=4'b0001;

            if(count==32'd49_999_999)

                 begin 

                      state<=S_LED0;

                      count<=32'd0;

                 end

            else 

                   begin

                          state<=state;

                          count<=count+32'b1;

                      end

   end

 default: 
       state<=S_IDLE;                       //默认为初始空闲状态
 endcase

end

endmodule


猜你喜欢

转载自blog.csdn.net/changengchu3961/article/details/80187070