利用简单的有限状态机(FSM)来实现一个简单的LED流水灯

时间:2023-03-09 18:56:40
利用简单的有限状态机(FSM)来实现一个简单的LED流水灯
  有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型
有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。一般来说,除了输入部分和输出部分外,有限状态机还含有一组具有“记忆”功能的寄存器,这些寄存器的功能是记忆有限状态机的内部状态,它们常被称为状态寄存器。在有限状态机中,状态寄存器的的下一个状态不仅与输入信号有关,而且还与该寄存器的当前状态有关,因此有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。其中,寄存器逻辑的功能是存储有限状态机的内部状态;而组合逻辑又可以分为次态逻辑和输出逻辑两部分,次态逻辑的功能是确定有限状态机的下一个状态,输出逻辑的功能是确定有限状态机的输出。 以下是用FSM*控制的led,
module led_test(clk,led_out);
input clk;
output reg[:] led_out; reg[:] state='b0000;
reg[:] timer='d0; parameter state_0='b0000;
parameter state_1='b0001;
parameter state_2='b0010;
parameter state_3='b0100;
parameter state_4='b1000; always@(posedge clk)
begin case(state) state_0:
if(timer>='d9999_9999)
begin
state<=state_1;
led_out<=state_1;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end state_1:
if(timer>='d9999_9999)
begin
state<=state_2;
led_out<=state_2;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end state_2:
if(timer>='d9999_9999)
begin
state<=state_3;
led_out<=state_3;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end state_3:
if(timer>='d9999_9999)
begin
state<=state_4;
led_out<=state_4;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end state_3:
if(timer>='d9999_9999)
begin
state<=state_4;
led_out<=state_4;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end state_4:
if(timer>='d9999_9999)
begin
state<=state_0;
led_out<=state_0;
timer<='d0;
end
else
begin
state<=state;
led_out<=led_out;
timer=timer+'d1;
end default:
state<=state_0; endcase
end endmodule 以下是用一个按键来控制LED流动的开始,当按下按键10s后LED会开始流动。
module practice(clk,key,led);
input clk; //时钟输入 50Mhz
input key; //按键
output reg[:] led; //4位LED
reg[:] count='d0; //一个计数器,如果编译软件不优化,将生成32个D触发器 reg[:] state='d0;
parameter state_0='d0;
parameter state_1='d1;
parameter state_2='d2;
parameter state_3='d3;
parameter state_4='d4; reg[:] key_count; //按键按下的时间控制寄存器 always@(posedge clk)
begin case(state)
state_0:
begin
if(key == 'b0)
key_count <= key_count + 'd1;
else
key_count <= 'd0;
if(key_count >= 'd49_999_999)
state <= state_1;
else
state <= state;
led <= 'b0000;
end state_1:
begin
led <= 'b0001;
if(count == 'd4999_9999)
begin
state <= state_2;//1秒后进入下一个状态
count <= 'd0;
end
else
begin
state <= state;
count <= count + 'd1;
end
end state_2:
begin
led <= 'b0010;
if(count == 'd9999_9999)
begin
state <= state_3;//1秒后进入下一个状态
count <= 'd0;
end
else
begin
state <= state;
count <= count + 'd1;
end
end state_3:
begin
led <= 'b0100;
if(count == 'd1_4999_9999)
begin
state <= state_4;//1秒后进入下一个状态
count <= 'd0;
end
else
begin
state <= state;
count <= count + 'd1;
end
end state_4:
begin
led <= 'b1000;
if(count == 'd1_9999_9999)
begin
state <= state_1;//1秒后进入下一个状态
count <= 'd0;
end
else
begin
state <= state;
count <= count + 'd1;
end
end default: //最好不要忘了写default,写别是组合逻辑使用case,不写会有大麻烦
state <= state_1; endcase
end
endmodule