/**************************************功能介绍***********************************
Date : 2023年7月27日19:50:03
Author : Alegg xy.
Version : 1.0
Description: 状态机点亮流水灯
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module fsm_led(
input clk ,
input rst_n ,
output reg [3:0] led
);
//---------<参数定义>---------------------------------------------------------
parameter MAX_500ms = 25'd25_000_000;//0.5s
//状态空间
parameter LED0 = 4'b0001;
parameter LED1 = 4'b0010;
parameter LED2 = 4'b0100;
parameter LED3 = 4'b1000;
//---------<内部信号定义>-----------------------------------------------------
reg [24:0] cnt ;
wire add_cnt ;
wire end_cnt ;
reg [3:0] cstate; //现态
reg [3:0] nstate; //次态
//0.5s计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 24'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 24'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == MAX_500ms - 1'd1;
//****************************************************************
//--三段式状态机
//****************************************************************
//第一段,现态跟随次态。时序逻辑,非阻塞赋值
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cstate <= LED0;
end
else begin
cstate <= nstate;
end
end
//第二段,组合逻辑,阻塞赋值
always @(*)begin
case (cstate)
LED0:begin
if (end_cnt) begin
nstate = LED1;
end
else begin
nstate = cstate;
end
end
LED1:begin
if (end_cnt) begin
nstate = LED2;
end
else begin
nstate = cstate;
end
end
LED2:begin
if (end_cnt) begin
nstate = LED3;
end
else begin
nstate = cstate;
end
end
LED3:begin
if (end_cnt) begin
nstate = LED0;
end
else begin
nstate = cstate;
end
end
default:nstate = LED0;
endcase
end
//第三段,赋值,时序逻辑,非阻塞赋值
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
led <= 4'b0000;
end
else begin
case (cstate)
LED0:led <= 4'b0001;
LED1:led <= 4'b0010;
LED2:led <= 4'b0100;
LED3:led <= 4'b1000;
default:led <= 4'b0000;
endcase
end
end
endmodule