FPGA流水灯

FPGA流水灯Demo
说明

image-20221120220206012

8个led灯依次点亮,形成流水效果

分析
框图

状态机FSM

water_led_FSM

Verilog代码
`timescale 1ns / 1ps
//
// Create Date: 2022/11/20 20:41:08
// Design Name: wkk
// Module Name: water_led
// Description:  running 8 water leds 
// Revision 0.01 - File Created
// Additional Comments:
//

module water_led(
    input    sys_clk,                    // 50M
    input    sys_rst_n,
    output   reg [7:0] led_out
);

parameter  SYS_CLK          = 50_000_000;
parameter  TIME_MAX_COUNT   = 500_000;

localparam  S0               = 8'b0000_0001;
localparam  S1               = 8'b0000_0010;
localparam  S2               = 8'b0000_0100;
localparam  S3               = 8'b0000_1000;
localparam  S4               = 8'b0001_0000;
localparam  S5               = 8'b0010_0000;
localparam  S6               = 8'b0100_0000;
localparam  S7               = 8'b1000_0000;

wire   time_en;
reg    [19:0]   time_count;

reg [7:0] curr_state;
reg [7:0] next_state;

assign time_en = (time_count == TIME_MAX_COUNT -1) ? (1'b1) :(1'b0);

// clock division
// create time_en signal
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        time_count <= 20'b0;
    else if(time_count == TIME_MAX_COUNT-1)
        time_count <= 20'b0;
    else
        time_count <= time_count +1'b1;
end

// update current state from next state
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        curr_state <= 8'b0;
    else
        curr_state <= next_state;
end

// update fsm next state
always @(*) begin
    if(!sys_rst_n)
        next_state <= 8'b0;
    else if(time_en)
        case(curr_state) 
        S0:      next_state <= S1;
        S1:      next_state <= S2;
        S2:      next_state <= S3;
        S3:      next_state <= S4;
        S4:      next_state <= S5;
        S5:      next_state <= S6;
        S6:      next_state <= S7;
        S7:      next_state <= S0;
        default: next_state <= S0;
        endcase
    else ;
end

// create output signal
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        led_out <= 8'b0;
    else
        led_out <= curr_state;
end
    
endmodule
testbench
`timescale 1ns / 1ns
// Create Date: 2022/11/20 21:15:13
// Design Name: wkk
// Module Name: water_led_tb
// Description: water_led testbench
// Revision 0.01 - File Created
// Additional Comments:
//
module water_led_tb;

reg                sys_clk;
reg                sys_rst_n;
wire       [7:0]   led_out;
water_led  #(
    .TIME_MAX_COUNT (2)
)u_water_led(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .led_out     (led_out)
);
initial begin
    sys_clk   = 0;
    sys_rst_n = 0;
    #20 sys_rst_n = 1;
end
always begin 
    #5 sys_clk = !sys_clk;
end

initial begin
    # 2000;
    $stop;
end
endmodule

仿真结果

water_led_sim

通用代码

在这里插入图片描述

// author : wkk

module WaterLed#(
    parameter   INPUT_CLK    =     27_000_000       ,   // input clk frequency
    parameter   LED_NUM      =     6                ,   // led quantity
    parameter   COUNT_WIDTH  =     36               ,   // time counter bit quantity
    parameter   COUNT_MAX    =     27_000_000       ,   // max count value
    // LED MODE 1 ? 0 -> on       
    parameter   LED_MODE     =     0                    // led control mode: if 1 --> led on  or  0 --> led on                     

)(
    input                                       clk                     ,
    input                                       rst_n                   ,

    output      [LED_NUM-1:0]                   led                     
);


reg     [LED_NUM-1: 0]     curr_state                   ;
reg     [LED_NUM-1: 0]     next_state                   ;
reg     [LED_NUM-1:0]      led_out                      ;

reg                        time_en                      ;
reg     [COUNT_WIDTH-1:0]  time_count                   ;


always  @(posedge   clk or negedge rst_n) begin 
    if( !rst_n ) begin
        time_count <= {COUNT_WIDTH{1'b0}};
        time_en    <=  1'b0;
    end
    else begin
        if( time_count == COUNT_MAX-1) begin
            time_count <= {COUNT_WIDTH{1'b0}};
            time_en    <= 1'b1;
        end 
        else begin
            time_en    <= 1'b0;
            time_count <= time_count + 1'b1;
        end

    end
end

always @(posedge clk or negedge rst_n) begin
    if( !rst_n ) 
          curr_state <=  {{(LED_NUM-1){1'b0}},1'b1};
    else
          curr_state <= next_state;

end

always @(*) begin
    if(!rst_n )
        next_state = {{(LED_NUM-1){1'b0}},1'b1};
    else begin
        if( time_en )  
            next_state = {curr_state[LED_NUM-2:0],curr_state[LED_NUM-1]};
        else
            next_state = curr_state;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n ) 
        led_out <= {LED_NUM{1'b0}};
    else begin
        if( LED_MODE == 1) 
               led_out <= curr_state;
        else
               led_out <= ~curr_state;
    end
end

assign led = led_out;

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴风雨中的白杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值