PWM呼吸灯+流水灯设计

完成任务: 在流水灯基础上加入pwm呼吸灯设计,关于pwm呼吸灯设计可以看博主上一篇博客PWM呼吸灯设计 ,开发板上灯每两秒进行一次切换,每一个的亮灭间隔为一秒。

代码参考:

Verilog 复制代码
module pwm_led_change(
    input   wire        clk     ,
    input   wire        rst_n   ,

    output  reg [3:0]   led
);

parameter TIME_US = 6'd49;//50*20ns 1us
parameter TIME_MS = 10'd999;//1000ns*1000 1ms
parameter TIME_S = 10'd999;//1000ms*1000 1s


reg [5:0] cnt_us;
reg [9:0] cnt_ms;
reg [9:0] cnt_s;
reg [1:0] cnt_2s;
reg [1:0]  state;//保存led灯状态
reg flag;//闪烁标志


wire add_cnt_us;//us计数器开始计数标志
wire end_cnt_us;//us计数器结束计数标志

wire add_cnt_ms;//ms计数器开始计数标志
wire end_cnt_ms;//ms计数器结束计数标志

wire add_cnt_s;
wire end_cnt_s;

wire end_cnt_2s;


//1us计时器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt_us <= 6'd0;
    end
    else if(add_cnt_us) begin
        if(end_cnt_us) begin
            cnt_us <= 6'd0;
        end
        else begin
            cnt_us <= cnt_us +1'd1;
        end
    end
    else begin
        cnt_us <= cnt_us;
    end
end

assign add_cnt_us = 1'b1;
assign end_cnt_us = add_cnt_us && (cnt_us == TIME_US);

//1ms计时器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt_ms <= 10'd0;
    end
    else if(add_cnt_ms) begin
        if(end_cnt_ms) begin
            cnt_ms <= 10'd0;
        end
        else begin
            cnt_ms <= cnt_ms + 1'd1;
        end
    end
    else begin
        cnt_ms <= cnt_ms;
    end
end

assign add_cnt_ms = end_cnt_us;
assign end_cnt_ms = add_cnt_ms && (cnt_ms == TIME_MS);

//1s计时器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt_s <= 10'd0;
    end
    else if(add_cnt_s) begin
        if(end_cnt_s) begin
            cnt_s <= 10'd0;
        end
        else begin
            cnt_s <= cnt_s + 1'd1;
        end
    end
    else begin
        cnt_s <= cnt_s;
    end
end

assign add_cnt_s = end_cnt_ms;
assign end_cnt_s = add_cnt_s && (cnt_s == TIME_S);

//2s计时
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt_2s <= 2'd0;
    end
    else if(end_cnt_s)begin
        cnt_2s <= cnt_2s + 1'd1;
    end
    else if(cnt_2s == 2'd2) begin
        cnt_2s <= 2'd0;
    end
    else begin
        cnt_2s <= cnt_2s;
    end
end

assign end_cnt_2s = (cnt_2s == 2'd2);

//state状态
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        state <= 2'd0;
    end
    else if(end_cnt_2s) begin
        state <= state + 1'd1;
    end
    else begin
        state <= state;
    end
end

//flag值判断
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        flag <= 1'b0;
    end
    else if(end_cnt_s) begin
        flag <= ~flag ;
    end
    else begin
        flag <= flag;
    end
end

//led变化
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        led = 4'b0000;
    end
    else begin
        case(state)
            2'd0 : begin
                if(flag == 1'b1) begin//电亮
                    if(cnt_s > cnt_ms) begin
                        led[0] <= 1'b1;
                        led[3:1] <= 3'b000;
                    end
                    else begin
                        led[0] <= 1'b0;
                        led[3:1] <= 3'b000;
                    end
                end
                else begin//熄灭
                    if(cnt_s > cnt_ms) begin
                        led[0] <= 1'b1;
                        led[3:1] <= 3'b000;
                    end
                    else begin
                        led[0] <= 1'b1;
                        led[3:1] <= 3'b000;
                    end
                end
            end 

            2'd1 : begin
                if(flag == 1'b1) begin//电亮
                    if(cnt_s > cnt_ms) begin
                        led[1] <= 1'b1;
                        led[3:2] <= 2'b00;
                        led[0] <= 1'b0;
                    end
                    else begin
                        led[1] <= 1'b0;
                        led[3:2] <= 2'b00;
                        led[0] <= 1'b0;
                    end
                end
                else begin//熄灭
                    if(cnt_s > cnt_ms) begin
                        led[1] <= 1'b0;
                        led[3:2] <= 2'b00;
                        led[0] <= 1'b0;
                    end
                    else begin
                        led[1] <= 1'b1;
                        led[3:2] <= 2'b00;
                        led[0] <= 1'b0;
                    end
                end
            end

            2'd2 : begin
                if(flag == 1'b1) begin//电亮
                    if(cnt_s > cnt_ms) begin
                        led[2] <= 1'b1;
                        led[3] <= 1'b0;
                        led[1:0] <= 2'b0;

                    end
                    else begin
                        led[2] <= 1'b0;
                         led[3] <= 1'b0;
                        led[1:0] <= 2'b0;
                    end
                end
                else begin//熄灭
                    if(cnt_s > cnt_ms) begin
                        led[2] <= 1'b0;
                         led[3] <= 1'b0;
                        led[1:0] <= 2'b0;
                    end
                    else begin
                        led[2] <= 1'b1;
                        led[3] <= 1'b0;
                        led[1:0] <= 2'b0;
                    end
                end
            end

            2'd3 : begin
                if(flag == 1'b1) begin//电亮
                    if(cnt_s > cnt_ms) begin
                        led[3] <= 1'b1;
                        led[2:0] <= 3'b000;

                    end
                    else begin
                        led[3] <= 1'b0;
                        led[2:0] <= 3'b000;
                    end
                end
                else begin//熄灭
                    if(cnt_s > cnt_ms) begin
                        led[3] <= 1'b0;
                        led[2:0] <= 3'b000;
                    end
                    else begin
                        led[3] <= 1'b1;
                        led[2:0] <= 3'b000;
                    end
                end
            end
            default :led <= 4'b0000;
        endcase
    end
end

endmodule

测试文件:

Verilog 复制代码
`timescale 1ns/1ns
module pwm_led_change_tb();

    reg clk;
    reg rst_n;

    wire [3:0] led;

    parameter CYCLE = 20;
    parameter TIME_US = 5;
    parameter TIME_MS = 10;
    parameter TIME_S = 10;

    always #(CYCLE/2) clk = ~clk;

    initial begin
        clk = 1'b0;
        rst_n = 1'b0;
        #(CYCLE);
        rst_n = 1'b1;
        #((TIME_US + 1)*(TIME_MS + 1)*(TIME_S + 1)*CYCLE*2*4);
        $stop;
    end

pwm_led_change #(
        .TIME_US    (TIME_US),
        .TIME_MS    (TIME_MS),
        .TIME_S     (TIME_S)
    )u_pwm_led_change(
        .clk    (clk),
        .rst_n  (rst_n),

        .led    (led)

    );



endmodule 

我们通过modelsim仿真结果如下:

结果展示:

相关推荐
花月mmc1 天前
【FPGA】神经网络内容简介预告
嵌入式硬件·深度学习·神经网络·fpga开发
LabVIEW开发3 天前
LabVIEW FPGA 编程:少编译几次的办法(系列 04/05)
fpga开发·labview
cmc10283 天前
318.关于在ip内部封装PLL,MMCM的注意事项
fpga开发
LabVIEW开发4 天前
LabVIEW CompactRIO 编程模式怎么选(系列 02/05)
fpga开发·labview
FPGA小迷弟4 天前
FPGA 与千兆以太网校验和:从原理到 Verilog 实现
嵌入式硬件·fpga开发·无人机·ai编程·fpga
码农小韩5 天前
FPGA学习(二)——LED闪烁
fpga开发·verilog·fpga·led·组合逻辑·分频设计
9527华安6 天前
FPGA纯verilog实现DP视频接口,支持2K60帧分辨率,提供3套工程源码和技术支持
fpga开发·音视频·dp
ChaseVLSI6 天前
FPGA与ASIC的区别详解:内部结构、开发成本与适用场景,项目选型到底该选哪个
嵌入式硬件·fpga开发·硬件架构·硬件工程
9527华安7 天前
FPGA实现ARINC818总线协议,基于GT Transceivers Wizard高速收发器,提供7套工程源码和技术支持
fpga开发·transceivers·arinc818
小蘇的FPGA7 天前
fpga-wide-data-crc32
fpga开发