Xilinx FPGA:vivado用状态机写4位流水灯

一、代码设计

`timescale 1ns / 1ps
/*
三段式状态机设计1s流水灯
三段式状态机设计流程
(1)确定状态
(2)画状态转换图
(3)状态编码(二进制、格雷码、独热码)
*/
module stater_led(
    input               sysclk          ,
    input               rst_n           ,
    output  reg [3:0]   led
    );
/格雷码 (相邻两个状态之间仅有1位电平变化) 
localparam  IDLE = 3'b000; //空闲状态
localparam  LED1 = 3'b001; //第一个灯亮起来
localparam  LED2 = 3'b011; //第二个灯亮起来           
localparam  LED3 = 3'b111; //第三个灯亮起来          
localparam  LED4 = 3'b101; //第四个灯亮起来          
reg     [2:0]      cur_state;  //现态
reg     [2:0]      next_state; //次态
reg     [25:0]      cnt         ;
parameter           TIME_1s = 50_000_000;
//----state1(时序逻辑电路,非阻塞赋值,进行状态的切换)  对cur_state赋值   固定格式
always@(posedge sysclk)
    if(!rst_n)
        cur_state <= IDLE;
    else 
        cur_state <= next_state;  
//----state2(组合逻辑,根据现态和条件去确定次态)  状态转换图   对next_state赋值   
always@(*)  组合逻辑
    case(cur_state)   
        IDLE : begin
            next_state = LED1;
        end   
        LED1 :begin
            if(cnt == TIME_1s - 1)
                next_state = LED2;
            else
                next_state = cur_state;
        end
        LED2 :begin
            if(cnt == TIME_1s - 1)
                next_state = LED3;
            else
                next_state = cur_state;
        end
        LED3 :begin
            if(cnt == TIME_1s - 1)
                next_state = LED4;
            else
                next_state = cur_state;
        end
        LED4 :begin
            if(cnt == TIME_1s - 1)
                next_state = LED1;
            else
                next_state = cur_state;
        end
        default:;
    endcase
//----state3(确定每个状态的输出,即动作,时序逻辑,非阻塞赋值)
always@(posedge sysclk)
    if(!rst_n)begin
        led <= 4'b0000;
        cnt <= 0;   
    end
    else
        case(cur_state) /输出立马执行    next_state:输出会延迟一个时钟周期
            IDLE :begin
                led <= 4'b0000;
                cnt <= 0;
            end    
            LED1 :begin
                led <= 4'b0001; 
                if(cnt == TIME_1s - 1)
                    cnt <= 0;    清零的目的:为了下一个状态的正常跳转
                else   
                    cnt <= cnt + 1;
            end
            LED2 :begin
                led <= 4'b0010; 
                if(cnt == TIME_1s - 1)
                    cnt <= 0;    清零的目的:为了下一个状态的正常跳转
                else   
                    cnt <= cnt + 1;
            end
            LED3 :begin
                led <= 4'b0100; 
                if(cnt == TIME_1s - 1)
                    cnt <= 0;    清零的目的:为了下一个状态的正常跳转
                else   
                    cnt <= cnt + 1;
            end
            LED4 :begin
                led <= 4'b1000; 
                if(cnt == TIME_1s - 1)
                    cnt <= 0;    清零的目的:为了下一个状态的正常跳转
                else   
                    cnt <= cnt + 1;
            end
            default:;          
        endcase
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值