数电实验6:可控分频器设计

一、实验目的

  1. 学习 ModelSim 仿真方法。
  2. 巩固 Verilog HDL 时序电路设计。

二、基本实验内容

  1. FPGA 开发板上有一个 50MHz 的高频时钟。设计一个可控分频器,clk_in 为分频器时钟输入, sel为选择开关, clk_out为分频器信号输出。当sel=0时,fclk_out=sn[2:0]Hz;当 sel=1 时, fclk_out=sn[4:0] Hz。
  2. clk_out 的占空比 D=28%;(D=tH/T, tH 为高电平时间, T 为周期)
  3. 说明。 sn 为学号, sn[2:0]表示取十进制学号的后 3 位, sn[4:0]表示取十进制学号的后 5 位,若学号后 3 位为 0 则学号后 5 位按 32768 取值。例如,学号 sn=2017112345,sn[2:0]=345; sn=2017100000, sn[2:0]=768.
  4. 实验测试
  5. 用导线将 clk_out 接入实验箱的 CH0 逻辑分析仪通道, 测试 clk_out 实际输出频率及占空比, 若与要求不相符(误差须小于 1‰), 修改电路程序使之符合要求。

三、提高性实验内容(选做)

  1. 增加占空比调节功能,每按一下“+”键,占空比增加 10%;每按一下“-”键,占空比减少 1%;
  2. 使输出信号的占空比按正弦波规律自动变化,正弦波频率为 300Hz;
  3. 其他

四、预习实验

  1. 写出设计思路。
  2. 由于 FPGA 只能进行整数计数来分频, 会存在除不尽的情况而只能四舍五入取整数,
    请根据实际分频系数计算因为取整导致的理论误差。
  3. 自学 ModelSim 仿真方法, 用 ModelSim 对实验电路进行仿真(需使用标尺功能测
    量输出信号频率/周期、占空比),并将仿真代码及仿真结果截图打印。
  4. 自行安排所用引脚, 列出引脚锁定分配表(信号名->主板器件名->引脚号)

五、实验报告要求

  1. 列出程序代码(有详细注释)。
  2. 列出通电测试结果。
  3. 列出实验过程出现的问题及解决措施。
  4. 附源程序

六、内容讲解(基础实验内容)

我们以学号为2017112345为例讲解本次实验。
首先,先将基本框架写出来。

module controlled_frequency
(
    input   wire            clk_in  ,
    input   wire			reset_n ,
    input   wire            sel     ,
    output  wire            clk_out 
);

endmodule

sn[2:0] = 345,sn[4:0] = 12345 。输入时钟clk_in的频率为50MHz,周期T0 = 20ns。当输出时钟的频率为345Hz时,周期为T1 ≈ 144927T0,占空比为28%,则高电平时间为T1H = 40580T0 ;当输出时钟的频率为12345Hz时,周期T2 ≈ 4050T0,高电平时间T2H = 1134T0;因此我们首先需要一个计数器,并且对各个计数值进行编码。sel = 0 ,输出时钟频率为345Hz时,计数器从0到144926循环计数,并且在0 ~ 40579内,clk_out保持高电平,剩下的时间保持低电平;sel = 1,输出时钟频率为12345Hz时,计数器从0到4049循环计数,并且在0 ~ 1133内,clk_out保持高电平,剩下时间保持低电平。代码如下

module controlled_frequency
(
    input   wire            clk_in  ,
    input   wire            reset_n ,
    input   wire            sel     ,
    output  wire            clk_out 
);

//以学号2017112345为例
parameter   CNT_CLK1 = 20'd144926       ;//频率为345Hz时钟计数(从0开始):144927 - 1
parameter   CNT_CLK2 = 20'd4049         ;//频率为12345Hz时钟计数(从0开始):4050 - 1
parameter   CNT_CLK1_HIGH = 20'd40579   ;//345Hz时钟高电平计数(从0开始):40580 - 1
parameter   CNT_CLK2_HIGH = 20'd1133    ;//12345Hz时钟高电平计数(从0开始):1134 - 1


reg [19:0]  CNT ;
//CNT的计数逻辑
always@(posedge clk_in, negedge reset_n)
    begin
        if(!reset_n)
            CNT <= 20'd0;
        else    if((sel == 1'b0) && (CNT >= CNT_CLK1))//输出时钟频率345Hz
            CNT <= 20'd0;
        else    if((sel == 1'b1) && (CNT >= CNT_CLK2))//输出时钟频率为12345Hz
            CNT <= 20'd0;
        else
            CNT <= CNT + 1'b1;
    end

//clk_out的逻辑
assign clk_out = (  (sel == 0 && CNT <= CNT_CLK1_HIGH) || 
                    (sel == 1 && CNT <= CNT_CLK2_HIGH)  )? 1'b1:1'b0;

endmodule

在更换频率时(sel从0变为1),计数器计数可能会大于CNT_CLK2(4049),需要将计数器清零,因此我们计数器清零的条件是 CNT >= CNT_CLK2。

七、testbench及仿真结果

1.testbench

`timescale 10ns/1ns//时间单位10ns,时间精度1ns

module  tb_controlled_frequency();

reg     clk_in  ;
reg     reset_n ;
reg     sel     ;
wire    clk_out ;

initial
    begin
        clk_in <= 1'b1;
        reset_n <= 1'b0;
        sel     <= 1'b0;
        # 5 reset_n <= 1'b1;
        # 1500000    sel <= 1'b1;
    end

always #1   clk_in = ~clk_in;//时钟周期为20ns



controlled_frequency    controlled_frequency_inst//实例化
(
    .clk_in  (clk_in    ),
    .reset_n (reset_n   ),
    .sel     (sel       ),
    .clk_out (clk_out   )   
);

endmodule

2.仿真结果

![请添加图片描述](https://img-blog.csdnimg.cn/4b2b14f59d304e389a3237f5ee3f17cd.jpeg
sel = 0,CNT从0开始计数,clk_out为高电平。

在这里插入图片描述
在这里插入图片描述

计数到40579,clk_out变为低电平,保持低电平到144926,计数器清零,clk_out又变为高电平。

sel = 1时
在这里插入图片描述
在这里插入图片描述

CNT从0计数到1133,clk_out保持高电平,在1134后保持低电平。

在这里插入图片描述
计数到4049后,计数器清零,clk_out又变为高电平。

欢迎在评论区留言,感谢您的关注与支持!

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

堂钰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值