`timescale 1ns / 1ps
module SY6_PWM(
input clk ,
input rst_n ,
//input key ,
output reg [3:0] led
);
//parameter delay=1;
parameter delay=50;
reg [31:0] cnt ;
reg [31:0] us ;
reg [31:0] ms ;
parameter H = 1 ;//上升
parameter L = 0 ;//下降
reg [2:0] mode = H;
//基础计数 先计数到50
always @(posedge clk)
if(!rst_n)
cnt <=0;
else if(cnt == delay -1)
cnt<=0;
else
cnt<=cnt+1;
always @(posedge clk)
if(!rst_n)
us <=0;
else if(cnt == delay -1)begin
if(us == 999)
us <=0;
else
us<=us+1;
end
else
us<=us;
always @(posedge clk)
if(!rst_n)begin
ms <=0;
mode <= H;
end
else if(cnt == delay -1 && us== 999)begin
if(ms == 999)begin
ms <=0;
if(mode == H)
mode <= L;
else
mode <= H;
end
else
ms<=ms+1;
end
else
ms<=ms;
//led = (ms>=us)?4'b1111:4'b0000 //从低变亮
always @(*)begin
if(!rst_n) begin
led <= 0;
//mode <= H;
end
else if(mode == H)
led <= (ms>=us)?4'b0111:4'b0000;
else if(mode == L )
led <= (ms<=us)?4'b0111:4'b0000;
end
//assign led = (ms>=us)?4'b1111:4'b0000;
endmodule
这段代码实现了一个基于时钟的PWM控制器,通过控制LED的亮度来模拟脉宽调制(PWM)信号。
模块定义:
timescale 1ns / 1ps
声明时钟周期和时间精度。module SY6_PWM(...)
定义了一个名为SY6_PWM的模块,包括时钟输入clk
,复位输入rst_n
,LED输出led
。
参数和寄存器定义:
parameter delay=50
设置延迟参数,默认为50。reg [31:0] cnt;
定义了一个32位的寄存器cnt
用于计数。reg [31:0] us;
定义了一个32位的寄存器us
用于计数微秒。reg [31:0] ms;
定义了一个32位的寄存器ms
用于计数毫秒。reg [2:0] mode = H;
定义了一个3位的寄存器mode
,用于控制PWM的模式。
时钟计数和时间计数:
always @(posedge clk)
这个always块在每个时钟上升沿触发。if(!rst_n) cnt <= 0;
如果复位信号rst_n
处于低电平,则将计数器cnt
清零。else if(cnt == delay - 1) cnt <= 0;
如果计数器cnt
达到了延迟值delay - 1
,将其重置为0。else cnt <= cnt + 1;
在其他情况下,将计数器cnt
递增1。
微秒计数和毫秒计数:
always @(posedge clk)
这个always块在每个时钟上升沿触发。if(!rst_n) us <= 0;
如果复位信号rst_n
处于低电平,则将微秒计数器us
清零。else if(cnt == delay - 1)
如果计数器cnt
达到了延迟值delay - 1
,开始计数微秒。if(us == 999) us <= 0;
如果微秒计数器us
达到999,则将其重置为0。else us <= us + 1;
在其他情况下,将微秒计数器us
递增1。
毫秒计数和模式切换:
always @(posedge clk)
这个always块在每个时钟上升沿触发。if(!rst_n) ms <= 0; mode <= H;
如果复位信号rst_n
处于低电平,则将毫秒计数器ms
清零,并将模式mode
设置为上升模式(H)。else if(cnt == delay - 1 && us == 999)
如果计数器cnt
达到延迟值delay - 1
且微秒计数器us
达到999,则开始计数毫秒。if(ms == 999)
如果毫秒计数器ms
达到999,则将其重置为0。if(mode == H)
如果模式mode
为上升模式(H),则将其切换为下降模式(L)。else mode <= H;
在其他情况下,将模式mode
设置为上升模式(H)。
LED控制:
always @(*)
这个always块在任何输入信号变化时触发。if(!rst_n) led <= 0;
如果复位信号rst_n
处于低电平,则将LED输出led
清零。else if(mode == H) led <= (ms >= us) ? 4'b0111 : 4'b0000;
如果模式为上升模式(H),则根据毫秒计数器ms
是否大于等于微秒计数器us
来控制LED输出。else if(mode == L) led <= (ms <= us) ? 4'b0111 : 4'b0000;
如果模式为下降模式(L),则根据毫秒计数器ms
是否小于等于微秒计数器us
来控制LED输出。
这段代码实现了一个通过控制LED的亮度模拟脉宽调制(PWM)信号的功能。
注意:语句中一定要考虑到所有情况,否则容易卡死在某个不明位置。