数字电子技术实验——可控分频器设计

本文介绍了如何设计一个基于50MHz时钟的可控分频器,通过sel选择不同输出频率(sn/1,sn/2,sn/5),使用计数器控制输出信号的翻转。实验中利用Verilog编程实现了分频器逻辑,并在ModelSim中进行了仿真验证。
摘要由CSDN通过智能技术生成

一、实验分析与设计原理

设计一个可控分频器,clk_in 为分频器时钟输入(50MHz)。

sel 为选择开关,clk_out[1:0]为分频器信号输出。sn[3:0]为四位数字。

        当 sel=0 时,clk_out[0]=sn[3:0]Hz,clk_out[1]=sn[3:0]/2Hz;

        当 sel=1 时,clk_out[0]=sn[3:0]Hz,clk_out[1]=sn[3:0]/5Hz。

可知,有输入clk_in、sel;输出clk_out[1:0]。

本实验需要通过给定的时钟信号clk_in,分频出频率小于输入时钟信号的输出信号clk_out。

通过输出信号的频率sn,可以计算出一个输出信号的周期需要多少个输入信号的周期。

例:当sn=1234Hz时,通过50MHz / 1234Hz = 40518可得,当输入信号经过40518个周期,输出信号经过一个周期。当占空比为50%时,输出信号每经过40518 / 2个周期,输出信号翻转一次。

实验有两个输出和三种输出频率,所以需要两个计数器分别记录两个输出,以及三个常数确定输出频率需要的输入信号的周期。

对于clk_out[0],sel的取值不影响其频率,所以可以将其从sel的选择语句中独立出来。

对于clk_out[1],通过if选择语句,可以输出对应的频率。

二、代码编写

程序代码

L0、L1、L2分别表示三种输出频率需要的输入信号的周期数;i0、i1为两个计数器值。

每当i0(i1)计数到L0(L1、L2)时,将输出信号clk_out[0](clk_out[1])翻转一次。

module Test(clk_in,clk_out,sel);
	input clk_in;		//50MHz输入
	input sel;			//选择信号
	output reg[1:0]clk_out = 2'b00; 	//分频器输出信号
	
	parameter sn = 1234;	//分频后频率
	
	parameter L0 = 50000000/sn/2;	//snHz需要的信号翻转的计数次数
	parameter L1 = L0*2;			//sn/2Hz需要的信号翻转的计数次数
	parameter L2 = L0*5;			//sn/5Hz需要的信号翻转的计数次数
	
	integer i0 = 1, i1 = 1;		//clk_out[0]、clk_out[1]计数
	
	always@(posedge clk_in)
	begin
		//由于clk_out[0]频率不变,所以将其单独独立出来
		if(i0 >= L0)	//达到snHz需要的计数次数
			begin
				i0 <= 1;	//计数器重置
				clk_out[0] <= ~clk_out[0];	//输出信号翻转
			end
		else i0 <= i0 + 1;	//计数器加一
		
		if(sel==0)	
			begin
				if(i1 >= L1)	//达到sn/2Hz需要的计数次数
					begin
						i1 <= 1;	//计数器重置	
						clk_out[1] <= ~clk_out[1];	//输出信号翻转
					end
				else i1 <= i1 + 1;	//计数器加一
			end
		else			
			begin
				if(i1 >= L2)	//达到sn/5Hz需要的计数次数	
					begin
						i1 <= 1;
						clk_out[1] <= ~clk_out[1];
					end
				else i1 <= i1 + 1;	//计数器加一
			end
	end
endmodule

三、ModelSim仿真

1、Test Bench文件

时间单位为1ns,输入信号clk每隔10个时间单位翻转一次,使输入信号的频率为50MHz。

初始sel为0,输出一种频率;延时5ms后,sel为1,输出另一种频率。

`timescale 1 ns/ 1 ns
module Test_vlg_tst();
reg clk_in;
reg sel;
                                              
wire [1:0]  clk_out;

Test i1 (
	.clk_in(clk_in),
	.clk_out(clk_out),
	.sel(sel)
);
initial                                                
begin                                                  
   clk_in = 0;
   sel = 0;
   #5000000
   sel = 1;                                      
$display("Running testbench");                       
end                                                    
always#10 clk_in = ~clk_in;                                                                                             
endmodule

2、波形图

温馨提示:基础操作可以查看本专栏中的其他博客。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值