在Vivado下用Verilog语言完成红绿灯(利用状态机)

刚学Verilog时,写红绿灯的时候感觉到逻辑混乱。后来学习了状态机,决定使用状态机完成红绿灯。下面是代码

`timescale 1ns / 1ps
`define second 100_000_000   
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/12/02 10:12:23
// Design Name: 
// Module Name: r_g_y
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
/////////////////////////////////////////////////////////////////////////////////
module r_g_y(
led_rgb0,
led_rgb1,
led_rgb2,
clk,
rst_n
    );
    input clk;
     input rst_n;
    output [2:0]led_rgb2;
   	/*由于LED灯有红绿蓝三个输入,这里定义了3位寄存器,高位到低位依次是:红绿蓝。让黄灯亮需要红灯和绿灯同时亮。即led_rgb2=3'b110*/            
    output [2:0]led_rgb1;		
    output [2:0]led_rgb0;	
    reg [30:0]div_cnt;			//定义时间	
    reg [2:0]led_rgb2;
    reg [2:0]led_rgb1;
    reg [2:0]led_rgb0;
    reg [1:0]current_state;		//现态
    reg [1:0]next_state;		//次态
    parameter [1:0] IDLE = 2'b00;	//初始态,没有灯亮
    parameter [1:0] S1 = 2'b01;		//状态01
    parameter [1:0] S2 = 2'b10;		//状态10
    parameter [1:0] S3 = 2'b11;		//状态11
always @(posedge clk or negedge rst_n)begin      //状态机第一段
    if(!rst_n)begin			//按键复位
        current_state <= IDLE;		
    end
    else begin
        current_state <= next_state;	
    end
end


always @(*)begin
    case(current_state)                       //状态机第二段 
        IDLE:begin                                                  
            if(div_cnt==1*`second)begin	                        
                next_state=S1;		//进入S1
                end
            else begin
                next_state=IDLE;
            end
        end
        S1:begin
            if(div_cnt==4*`second)begin
                next_state=S2;		//进入S2
            end
            else begin
                next_state=S1;
            end           
        end
        S2:begin
            if(div_cnt==6*`second)begin
                next_state=S3;		//进入S3
            end
            else begin
                next_state=S2;
            end          
        end
        S3:begin
            if(div_cnt==9*`second)begin	
                next_state=S1;		//回到S1
            end
            else begin
                next_state=S3;
            end            
        end
        default : begin
            next_state = current_state;	//防止锁住
        end        
    endcase                        
end   

always @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin	
        led_rgb2=3'b000;		//灯全不亮
        led_rgb1=3'b000;
        led_rgb0=3'b000;
    end
    else if(next_state==S1)begin
        led_rgb2=3'b010;		//灯2绿
        led_rgb1=3'b000;
        led_rgb0=3'b000;    
    end
    else if(next_state==S2) begin
        led_rgb2=3'b000;		//灯1黄
        led_rgb1=3'b110;
        led_rgb0=3'b000;    
    end
    else if(next_state==S3) begin
        led_rgb2=3'b000;		//灯0红
        led_rgb1=3'b000;
        led_rgb0=3'b100;    
    end 
    else begin
        led_rgb2=3'b000;
        led_rgb1=3'b000;
        led_rgb0=3'b000; 
        end   
end                    
always@(posedge clk) begin
        if(rst_n==1'b0)begin		
        div_cnt <= 0;
        end
        else if(div_cnt >= 10*`second)begin		//设置时间周期10s
            div_cnt <= 0;
        end       
        else
            div_cnt <= div_cnt + 1;  
 end   
endmodule

有没有觉得逻辑好多了呢?

你可能感兴趣的:(在Vivado下用Verilog语言完成红绿灯(利用状态机))