基于FPGA的PWM模块

以驱动led灯实现呼吸灯为例

RTL代码:

module breath_led(
	input sys_clk,
	input sys_rst,
	output led
);

reg [15:0] divider; // frequency divider, 50Mhz/20ns -> 1Khz/1ms  about 50000 clk
reg [15:0] D; // duty cycle 

reg flag; // 1 for increment 

// 通过D和divider的比较得到驱动led的PWM波
assign led = (divider >= D) ? 1'd1 : 1'd0;

// 方便仿真观察时序,将50000计数改成50
always @(posedge sys_clk or negedge sys_rst) begin
	if(!sys_rst)
		divider <= 16'd0;
	else if (divider == 16'd50)
		divider <= 16'd0;
	else	
		divider <= divider + 1'd1;
end

// 占空比根据flag标志位递增或递减
always @(posedge sys_clk or negedge sys_rst) begin	
	if (!sys_rst) begin
		D <= 16'd0;
		flag <= 1'd1;
	end
	else begin
		if (flag == 1'd1)	begin
			if (D < 16'd50) begin
				if (divider == 16'd50)
					D <= D + 16'd5;
				else 
					D <= D;
			end
			else
				flag <= 1'd0;
		end
		else begin
			if (D > 16'd0) begin
				if (divider == 16'd50)
					D <= D - 16'd5;
				else
					D <= D;
			end
			else
				flag <= 1'd1;
		end
	end
end
endmodule
			
		

Testbench:

`timescale 1 ns/ 1 ns
module breath_led_vlg_tst();

reg sys_clk;
reg sys_rst;

reg [15:0] divider;
reg [15:0] D;

wire led;

parameter T = 10;

always #T sys_clk = ~ sys_clk;

initial begin
	sys_clk <= 1'b0;
	sys_rst <= 1'b0;
	# 40 sys_rst <= 1'b1;
end

breath_led i1(
	sys_clk,
	sys_rst,
	led
);

endmodule

仿真时序分析:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值