【VHDL设计—仿真实验】设计出你想要的分频器

Orianna ·
更新时间:2024-09-21
· 867 次阅读

设计之前,我们首先要明白“分频器是什么?为什么要设计分频器?”

在硬件电路设计中时钟信号是最重要的信号之一,而在数字电路中,常需要对较高频率的时钟进行分频操作,得到较低频率的时钟信号,分频器就扮演着这个角色,从而才有了分频器的设计。

那好,理解了分频器的大致原理,我们就从最简单的分频器设计开始,逐步深入、触类旁通,带领你设计出实战项目中所需的每一种分频器,得到你想要的分频器(毕竟需要,才想要,(#^.^#))。

 

一、2的整数次幂的偶数分频器——2、4、8、16分频器

用VerilogHDL语言完成对时钟信号 CLK 的 2 分频, 4 分频, 8 分频, 16 分频,即:2^{n}(n为整数)。 这也是最简单的分频电路,只需要一个计数器即可 。

/*2的整数次幂偶数分频器:2、4、8、16分频器*/ module freq_div(clk,rst,clk2,clk4,clk8,clk16);     input    rst,clk;     output    clk2,clk4,clk8,clk16;     wire    clk2,clk4,clk8,clk16; //用"assign"语句赋值的变量,需定义为wire型     reg    [3:0]    cnt;     always@(posedge clk or posedge rst) //上升沿触发,只有复位才会重置为零的计数器         begin                 if(rst==1'b1)                         cnt <= 4'b0000;                 else                     cnt <= cnt+1;         end     assign    clk2 = cnt[0]; //取出计数变量cnt的相应位的0、1状态作为本身的0、1状态     assign    clk4 = cnt[1];     assign    clk8 = cnt[2];     assign    clk16 = cnt[3]; endmodule 

仿真结果: 

 

 二、不为2的整数次幂的偶数分频器——6分频器(10分频、12分频等同理)

对于分频倍数不为2^{n}(n为整数)的情况,我们只需要对源代码中的计数器进行一下计数控制就可以了,如下代码,用VHDL设计一个对时钟信号进行 6 分频的分频器。

/*不为2的整数次幂的偶数分频器————6分频器*/ module freq_div(clk,rst,clk6); input rst,clk; output clk6; reg clk6; reg [1:0] cnt; always@(posedge clk or posedge rst) begin if(rst == 1'b1) begin cnt <= 2'b00; clk6 <= 2'b00; end else if(cnt == 2) //00 01 10 -- 00 01 10 -- 00 01 10 -- 00 01 10 ··· begin cnt <= 2'b00; clk6 <= ~clk6; end else cnt<=cnt+1; end endmodule

仿真结果:

三、 占空比不为50%的分频器——占空比为2:14的16分频器

在进行硬件设计的时候,往往要求得到一个占空比不是 1:1 的分频信号,这时仍采用计数器的方法来产生占空比不是 1:1 的分频信号。

下面源代码描述的是这样一个分频器:将输入的时钟信号进行 16 分频,分频信号的占空比为 2:14 ,也就是说,其中高电位的脉冲宽度为输入时钟信号的一个周期。

/*占空比不为50%的分频器————2:14占空比16分频器*/ module freq_div(clk,rst, clk2_14);     input clk,rst;     output reg clk2_14;     reg [3:0] cnt;     always@(posedge clk or posedge rst) //上升沿触发,只有复位才会重置为零的计数器         begin             if(rst == 1'b1)                 cnt <=4'b0000; //重置计数变量cnt为0             else                  cnt <= cnt + 1;          end     always@(posedge clk or posedge rst)         begin             if(rst == 1'b1)                 clk2_14 <= 1'b0; //rst重置clk2_14为0(低电平)             else if(cnt ==13 || cnt == 14)                  clk2_14 <= 1'b1;     //当rst==0、上升沿到来,且cnt已经计数到13或14时,将clk2_14置为1(高电平)             else                 clk2_14=1'b0; //当rst==0、上升沿到来,且cnt没有计数到13、14,clk2_14置为0(低电平)         end     endmodule 

仿真结果: 

四、 奇数分频器——5分频器(3分频、7分频、9分频等同理) /*奇数分频器——5分频器*/ module freq_div(clk, rst, clk_5);     input clk, rst;     output clk_5;     wire clk_5;        //用"assign"语句赋值的变量,需定义为wire型     reg  [2:0]  cnt_pre, cnt_later;     reg  clk_5_pre, clk_5_later;     always@(posedge clk or posedge rst)    // 上升沿触发,5进制计数器。范围:000、001、010、011、100         if(rst == 1)             cnt_pre 000 001 010 011 100 --> 001 010 011 100 --> ···             cnt_pre <= 3'b000;         else             cnt_pre <= cnt_pre + 1;     always@(posedge clk or posedge rst)    //上升沿触发,占空比为2:3的分频器         if(rst == 1)             clk_5_pre <= 0;         else if(cnt_pre == 3'b000 || cnt_pre == 3'b100)  // 在上升沿到来时,计数到000或100之后这样判断为1,才会置为1(高电平)              clk_5_pre <= 1;         else             clk_5_pre =0;     always@(negedge clk or posedge rst)    // 下降沿触发,5进制计数器。范围:000、001、010、011、100         if(rst == 1)             cnt_later 000 001 010 011 100 --> 001 010 011 100 --> ···             cnt_later <= 3'b000;         else             cnt_later <= cnt_later + 1;     always@(negedge clk or posedge rst)    //下降沿触发,占空比为2:3的分频器         if(rst == 1)             clk_5_later <= 0;         else if(cnt_later == 3'b000 || cnt_later == 3'b100)  // 在下降沿到来时,计数到000或100之后这样判断为1,才会置为1(高电平)              clk_5_later <= 1;         else             clk_5_later =0;     assign clk_5 = clk_5_pre | clk_5_later;  endmodule

仿真结果: 


作者:Xin~So



vhdl 分频器

需要 登录 后方可回复, 如果你还没有账号请 注册新账号