时序电路—分频器使用Verilog实现(一)

1. PWM介绍

PWM是“脉冲宽度调制”的英文缩写,矩形波中高电平脉冲宽度 t w t_{w} tw与周期T的比值叫占空比。占空比用符号p表示
p = t w / T p=t_{w}/T p=tw/T
当占空比为50%时,称此时的矩形波为方波。0和1交替出现并持续占用相同的时间。
三种不同占空比的矩形波如下图所示
在这里插入图片描述

2. 设计分析

我们通过设置分频器中高脉冲的时间就可以得到不同占空比的PWM。
分频器通常是由计时器来实现的,将高频脉冲信号作为时钟信号送入计数器的时钟输入端进行计数,在计数器的输出端就可以得到频率低的信号。设输入信号的时钟信号的频率为 f i f_{i} fi,计数值为N,则输出的最低频率为
f o = f i / N f_{o}=f_{i}/N fo=fi/N
对于分频得到的频率一定的矩形波,那我们如何调节其占空比呢?
我可以通过另外一个计数器对高电平脉冲宽度 t w t_{w} tw这段时间内通过的高频率脉冲进行计数,若计数值为a则
t w = a ∗ T i = a / f i t_{w}=a*T_{i}=a/f_{i} tw=aTi=a/fi
因此我们可以得到输出的占空比为
p = t w / T o = t w ∗ f o = a / f i ∗ f i / N = a / N p=t_{w}/T_{o}=t_{w}*f_{o}=a/f_{i}*f_{i}/N=a/N p=tw/To=twfo=a/fifi/N=a/N

3. 逻辑设计

module	frequency_div(
		input								clk,    //系统时钟
		input								rst_n,		//复位
		input								En,				//分频使能信号
		input		wire		[2:0]		sw_fre,		//切换频率的开关信号
		input		wire		[1:0]		sw_duty,		//切换占空比的开关信号
		output	reg					CP_out		//矩形波输出
);
reg	[7:0]		Division;//保存计数分频数值
reg	[6:0]	 	Pulse;//保存计数值
reg	[6:0]		count;

always@(*)
	begin
		case(sw_fre)
		3'b000:Division=8'd4;     //4分频
		3'b001:Division=8'd8;     //8分频
		3'b010:Division=8'd16;    //16分频
		3'b011:Division=8'd32;    //32分频
		3'b100:Division=8'd64;    //64分频
		3'b101:Division=8'd128;   //128分频
		default: Division=8'd4;
		endcase
	end
	

always@(*)
	begin
		case(sw_duty)
		2'b00: 	Pulse=Division/2;      //50%占空比
		2'b01:	Pulse=Division* 3/4;   //75%占空比
		2'b10: 	Pulse=Division/4;      //25%占空比
		2'b11:	Pulse=Division/8;      //12.5占空比
		endcase
	end

always@(posedge	clk  or  negedge	rst_n)    //分频计数
	begin
		if(!rst_n)
		begin
		count<=7'd0;
		end
		else
			if(En)
			begin
					if(count==Division-1'b1)
					count<=7'd0;
					else
					count<=count+1'b1;
					end
			else
				count<=7'd0;
	end
	
always@(posedge	clk  or  negedge	rst_n)   //占空比计数
	begin
		if(!rst_n)
			begin
			CP_out<=1'd0;
			end
		else
			if(En)
			begin
			if((count>=7'd0)&&(count<Pulse))
			CP_out<=7'd1;
			else
			CP_out<=7'd0;
			end
			else
			CP_out<=7'd0;
	end
endmodule 

4.testbench测试

`timescale	1ns/1ps
`define		clk_period	20
module	frequency_div_tb();
		reg 	clk		;
		reg	rst_n		;
		reg 	En			;
		reg 	[2:0]	sw_fre	;
		reg 	[1:0]	sw_duty	;
		wire  CP_out	;

frequency_div   frequency_divu1(
		.clk(clk),    //系统时钟
		.rst_n(rst_n),		//复位
		.En(En),				//分频使能信号
		.sw_fre(sw_fre),		//切换频率的开关信号
		.sw_duty(sw_duty),		//切换占空比的开关信号
		.CP_out(CP_out)		//矩形波输出
);

initial	clk=1;
always	#(`clk_period/2)	clk=~clk;

initial
begin
	rst_n=0;
	En=0;
	sw_fre=3'b000;
	sw_duty=2'b00;
	#(`clk_period*20+1);
	rst_n=1;
	En=1;
	#(`clk_period*20);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b000;
	sw_duty=2'b01;
	#(`clk_period*20);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b000;
	sw_duty=2'b10;
	#(`clk_period*20);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b001;
	sw_duty=2'b11;
	#(`clk_period*40);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b001;
	sw_duty=2'b01;
	#(`clk_period*40);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b001;
	sw_duty=2'b10;
	#(`clk_period*40);
	
	En=0;
	#(`clk_period);
	En=1;
	sw_fre=3'b010;
	sw_duty=2'b11;
	#(`clk_period*60);
	$stop;
	
end
endmodule	

5. 测试结果

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值