FPGA面试题:实现奇数倍分频,并且占空比为50%

使用计数器控制寄存器反转,很容易实现奇数倍分频,但是添加了占空比为50%这一限制条件的话,有些同学就会犯难,因为数字电路不存在小数,而奇数除以二却是一个小数,这导致占空比为50%无法实现。本文将通过图解的方式详细解答这个问题。

解这个题的思路非常简单,就是通过计数器控制两个寄存器实现两个占空比小于50%的奇数倍分频,但是这两个寄存器的时钟控制一个是上升沿触发,一个是下降沿触发,这会导致生成两个相位差为90度的时钟。对这两个时钟进行或运算,就可以得出结果。

在这里插入图片描述
Clk_out = Clk_reg1|Clk_reg2。
实现代码

module divfrequency(
	clk,
	rst_n,
	Clk_out
);

input clk;
input rst_n;
output Clk_out;

parameter n = 3'd5;//n为变频数,可以变换

wire Clk_out;
reg clk_reg1;
reg clk_reg2;

reg [2:0]div_cnt;
wire [2:0]a;
wire [2:0]b;

assign a = n>>1;//n>>1相当于除以2然后取整
assign b = n - 1'b1;

always@(posedge clk or negedge rst_n )//计数器
	if(!rst_n)
		div_cnt <= 0;
	else if(div_cnt == b)
		div_cnt <= 0;
	else	
		div_cnt <= div_cnt+ 1'b1;
	
always@(posedge clk or negedge rst_n )//第一个时钟寄存器
	if(!rst_n)
		clk_reg1 <= 0;
	else if(div_cnt == 0)
		clk_reg1 <= ~clk_reg1;
	else if(div_cnt == a)
		clk_reg1 <= ~clk_reg1;
		
always@(negedge clk or negedge rst_n )//第二个时钟寄存器
	if(!rst_n)
		clk_reg2 <= 0;
		else if(div_cnt == 1) //由于是下降沿触发,而计数器是上升沿触发,故比第一个时钟多1
		clk_reg2 <= ~clk_reg2;
	else if(div_cnt == a + 1'b1 )//同上
		clk_reg2 <= ~clk_reg2;
		
assign Clk_out = clk_reg1|clk_reg2;
			
endmodule
		

测试代码

`define clock_period 20
`timescale 1ns/1ns

module divfrequency_tb;
reg clk;
reg rst_n;
wire Clk_out;
initial 
	begin
		clk = 1;
	end
	always #(`clock_period/2) clk = ~clk;
divfrequency u0(
	clk,
	rst_n,
	Clk_out
);
initial
	begin
		rst_n =1;
		#(`clock_period)
		rst_n = 0;
		#(`clock_period)
		rst_n = 1;
		#(`clock_period*40)
		$stop;
	end
	endmodule
	

在这里插入图片描述
modelsim仿真结果

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>