模塊接口說明
信號 | 方向 | 描述 |
---|
clk | 輸入 | 系統時鐘(100MHz,周期10ns) |
rst_n | 輸入 | 低電平有效的異步復位信號 |
led_en | 輸入 | 總使能信號(1=開啟呼吸燈,0=關閉) |
speed_en | 輸入 | 呼吸速度調節使能信號 |
speed[2:0] | 輸入 | 呼吸速度分級(0-7對應8級速度,0最慢,7最快) |
led | 輸出 | 即PWM輸出(受led_en 控制) |
模塊代碼:
/* 呼吸燈模塊例化
led_breath #(.STEP (1)
) led_breath(.clk (clk ), .rst_n (rst_n ),.led_en (led_en ),.speed_en (speed_en), .speed (speed ),.led (led )
);
*/`timescale 1ns/1ps
// 呼吸燈模塊(輸出PWM波實現)
module led_breath #(parameter STEP = 1 //默認PWM占空比變化步長
)(input wire clk, // 時鐘(100MHz)input wire rst_n, // 復位input wire led_en, // LED使能控制信號 1亮 0滅input wire speed_en, // 設置LED呼吸頻率使能信號input wire [2:0]speed, // LED呼吸頻率(8級調節 0最慢 7最快)output wire led // LED(PWM波)
);
localparam T_MAX = 100000;// 占空比閾值變化周期的計數上限(1ms閾值變化一次)
localparam DUTY_MAX = 1000; // 占空比計數上限(也是PWM波周期,同一占空比下周期長短不影響平均電壓)
// 占空比閾值1ms變化一次,占空比計數上限1000,最小步長為1,最大8:因此LED呼吸一次周期最長2s、最短0.25sreg [3:0] step; // PWM波占空比變化步長
reg [23:0] t_cnt; // 呼吸周期計數器
reg [15:0] duty; // 當前占空比閾值
reg [15:0] duty_cnt; // 占空比計數
reg direction; // 亮度變化方向 0變亮 1變暗
wire PWM; //PWM波信號線// 設置PWM波占空比步長(最小步長為1,最大8)
always @(posedge clk or negedge rst_n) beginif (!rst_n) step <= STEP;else if (speed_en)step <= (speed==7) ? 8 : (speed+1); //步長+1:最小步長1、最大8
end// 呼吸周期計數器
always @(posedge clk or negedge rst_n) beginif (!rst_n) t_cnt <= 0;else if (t_cnt == T_MAX-1)t_cnt <= 0;elset_cnt <= t_cnt + 1;
end// PWM占空比閾值變化
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginduty <= 0;direction <= 0;endelse if (t_cnt == T_MAX-1) begin if (direction == 0) begin //變亮if (duty +step < DUTY_MAX) //防止占空比閾值不超過最大duty <= duty + step;elsedirection <= 1;endelse begin //變暗if (duty -step > 0 && duty -step < DUTY_MAX) //防止減法溢出的情況duty <= duty - step;elsedirection <= 0;endend
end// 占空比計數器
always @(posedge clk or negedge rst_n) beginif (!rst_n)duty_cnt <= 0;else if (duty_cnt == DUTY_MAX-1)duty_cnt <= 0;elseduty_cnt <= duty_cnt + 1;
end
// PWM波輸出
assign PWM = (duty_cnt <= duty);// LED使能輸出
assign led = led_en && PWM;endmodule