Verilog分频器设计
- 格式:doc
- 大小:85.00 KB
- 文档页数:17
实验六Verilog设计分频器/计数器电路一、实验目的1、进一步掌握最基本时序电路的实现方法;2、学习分频器/计数器时序电路程序的编写方法;3、进一步学习同步和异步时序电路程序的编写方法。
二、实验内容1、用Verilog设计一个10分频的分频器,要求输入为clock(上升沿有效),reset(低电平复位),输出clockout为4个clock周期的低电平,4个clock周期的高电平),文件命名为fenpinqi10。
v.2、用Verilog设计一异步清零的十进制加法计数器,要求输入为时钟端CLK(上升沿)和异步清除端CLR(高电平复位),输出为进位端C和4位计数输出端Q,文件命名为coute r10.v。
3、用Verilog设计8位同步二进制加减法计数器,输入为时钟端CLK(上升沿有效)和异步清除端CLR(低电平有效),加减控制端UPDOWN,当UPDOWN为1时执行加法计数,为0时执行减法计数;输出为进位端C和8位计数输出端Q,文件命名为couter8.v。
4、用VERILOG设计一可变模数计数器,设计要求:令输入信号M1和M0控制计数模,当M1M0=00时为模18加法计数器;M1M0=01时为模4加法计数器;当M1M0=10时为模12加法计数器;M1M0=11时为模6加法计数器,输入clk上升沿有效,文件命名为mcout5。
v。
5、VerilogHDL设计有时钟时能的两位十进制计数器,有时钟使能的两位十进制计数器的元件符号如图所示,CLK是时钟输入端,上升沿有效;ENA是时钟使能控制输入端,高电平有效,当ENA=1时,时钟CLK才能输入;CLR是复位输入端,高电平有效,异步清零;Q[3.。
0]是计数器低4位状态输出端,Q[7..0]是高4位状态输出端;COUT是进位输出端.三、实验步骤实验一:分频器1、建立工程2、创建Verilog HDL文件3、输入10分频器程序代码并保存4、进行综合编译5、新建波形文件6、导入引脚7、设置信号源并保存8、生成网表9、功能仿真10、仿真结果分析由仿真结果可以看出clockout输出5个clock周期的低电平和5个clock的高电平达到10分频的效果,设计正确。
汇报总结1、偶数分频偶数倍分频相对简单,可以通过计数器对预分频的脉冲沿计数实现,如果要进行N倍(N为整数)偶数分频,可由预分频的时钟触发计数器计数,当计数器从0计数到N/2—1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数,以此循环下去。
分频的主体程序如下:`define div_en 8module freq_div_even(clk_in,reset,clk_out);input clk_in;input reset;output clk_out;reg clk_out;reg[2:0] count;initialbegincount=0;clk_out=0;endalways@(posedge clk_in)beginif(!reset)begincount<=0;clk_out<=0;endelseif(count==(`div_en/2-1))beginclk_out<=~clk_out;count<=0;endelsebegincount<=count+1;endendendmodule下面定义N为8,对一个脉冲8分频,测试程序如下:`timescale 1ns/1nsmodule testbench;reg reset;reg clk_in;reg[2:0] count;wire clk_out;freq_div_even test(.clk_in(clk_in),.reset(reset),.clk_out(clk_out));initialbeginreset=0;clk_in=0;#5 reset=1;endalways #10 clk_in=~clk_in;endmodule波形图如下:2、奇数分频对于对占空比没有特殊要求的奇数分频,需要对上升沿和下降沿脉冲进行计数,利用下降沿产生的波形移相半个输入脉冲的作用,最后用错位“异或”法实现。
module clk_div(//-----------input-----------iCLK,div,//-----------output----------oCLK);//-----------input-----------parameter WIDE=14;input iCLK;input[WIDE-1:0]div;//-----------output-----------output oCLK;wire oCLK_odd;wire oCLK_even;assign oCLK=div[0]?oCLK_odd:oCLK_even;div_odd DUTo (.iCLK(iCLK),.oCLK(oCLK_odd),.div(div)); div_even DUTe (.iCLK(iCLK),.oCLK(oCLK_even),.div(div));endmodule// oddmodule div_odd(//--------input--------iCLK,div,//--------output--------oCLK);//--------input--------parameter WIDE=14;input iCLK;input[WIDE-1:0]div;//--------output--------output oCLK;reg outCLK;/*=========================== solve 1=========================== reg cout;reg[WIDE-1:0] cnt;initial cnt=0;wire inCLK;reg cc;initial cc=0;always @(posedge cout)cc<=~cc;assign inCLK = iCLK^cc;always @(posedge inCLK)beginif(cnt<(div[WIDE-1:1]))begincnt<=cnt+1;cout<=1'b0;endelsebegincnt<=0;cout<=1'b1;endendalways @(negedge iCLK)outCLK <= cout;assign oCLK=cc;*///======================== //solve 2//======================== reg[WIDE-1:0] cnt_a;initial cnt_a=0;reg[WIDE-1:0] cnt_b;initial cnt_b=0; reg cout_a;reg cout_b;always @(negedge iCLK)beginelse if(cnt_a<=(div[WIDE-1:1]))begincnt_a=cnt_a+1;cout_a=1'b1;endelse if(cnt_a>(div[WIDE-1:1])&&cnt_a<(div[WIDE-1:0]-1))begincout_a=1'b0;cnt_a=cnt_a+1;endelsebegincnt_a=0;endendalways @(posedge iCLK)beginif(cnt_b<=(div[WIDE-1:1]))begincnt_b=cnt_b+1;cout_b=1'b1;endelse if(cnt_b>(div[WIDE-1:1])&&cnt_b<(div[WIDE-1:0]-1))begincout_b=1'b0;cnt_b=cnt_b+1;endelsebegincnt_b=0;endendassign oCLK = cout_a&cout_b;endmodule//evenmodule div_even(//--------input--------iCLK,div,//--------output--------oCLK);//--------input--------parameter WIDE=14;input iCLK;input[WIDE-1:0]div;//--------output--------output oCLK;reg oCLK;initial oCLK = 1'b0;reg[WIDE-1:0] cnt;initial oCLK = 0;always @(posedge iCLK)beginif(cnt<(div[WIDE-1:1]-1))cnt <= cnt + 1;elsebegincnt <= 0;oCLK <= ~oCLK;endendendmodule//============================//testbench//============================/*module clk_div_test;//-----------input-----------parameter WIDE=14;reg iCLK;reg[WIDE-1:0] div;//-----------output-----------wire oCLK;clk_div cc(.iCLK(iCLK),.div(div),.oCLK(oCLK));always #20 iCLK = ~iCLK;initialbeginiCLK = 0;div=14'd7;#1000 $stop;endendmodule*/module clk_div14bits(clk,a,clkout);input clk,a;output clkout;reg clkout;wire oCLK1,oCLK2;clk_div cc1(.div(14'd8),.iCLK(iCLK),.oCLK(oCLK1)); clk_div cc2(.div(14'd9),.iCLK(iCLK),.oCLK(oCLK2));always @(a or posedge clkin)beginif(a==1)clkout=oCLK1;elseclkout=oCLK2;endendmodule//测试代码//testbenchmodule clk_div14bits_test;//-----------input-----------parameter WIDE=14;reg clk;reg[WIDE-1:0] div;//-----------output-----------wire oCLK;clk_div14bits cc3(.clk(clk),.a(a),.clkout(clkout)); always #20 clk = ~clk;initialbeginiCLK = 0;div=14'd7;#1000 $stop;EndModelsim仿真结果1.七分频2.四分频。
实验六Verilog设计分频器/计数器电路一、实验目的1进一步掌握最基本时序电路的实现方法;2学习分频器/计数器时序电路程序的编写方法;3进一步学习同步和异步时序电路程序的编写方法。
二、实验内容1、用Verilog设计一个10分频的分频器,要求输入为clock(上升沿有效),reset(低电平复位),输出clockout为5个clock周期的低电平,5个clock周期的高电平),文件命名为fenpinqi10.v。
2、用Verilog设计一异步清零的十进制加法计数器,要求输入为时钟端CLK(上升沿)和异步清除端CLR(高电平复位),输出为进位端C和4位计数输出端Q,文件命名为couter10.v。
3、用Verilog设计8位同步二进制加减法计数器,输入为时钟端CLK(上升沿有效)和异步清除端CLR(低电平有效),加减控制端UPDOWN,当UPDOWN为1时执行加法计数,为0时执行减法计数;输出为进位端C和8位计数输出端Q,文件命名为couter8.v。
4、用VERILOG设计一可变模数计数器,设计要求:令输入信号M1和M0控制计数模,当M1M0=00时为模18加法计数器;M1M0=01时为模4加法计数器;当M1M0=10时为模12加法计数器;M1M0=11时为模6加法计数器,输入clk上升沿有效,文件命名为mcout5.v。
5、VerilogHDL设计有时钟时能的两位十进制计数器,有时钟使能的两位十进制计数器的元件符号如图所示,CLK是时钟输入端,上升沿有效;ENA是时钟使能控制输入端,高电平有效,当ENA=1时,时钟CLK才能输入;CLR是复位输入端,高电平有效,异步清零;Q[3..0]是计数器低4位状态输出端,Q[7..0]是高4位状态输出端;COUT是进位输出端。
三、实验步骤:第一个实验:1、打开QuartusII,新建一个工程f_fenpinq10yjq2、新建一个Verilog HDL文件3、输入程序:module fenpinqi10(clk,reset,clkout);input clk,reset;output clkout;reg clkout;reg[2:0] cnt;always @(posedge clk , negedge reset)beginif(!reset)begin clkout<=0;cnt<=0;endelse if(cnt==4)begin cnt<=0;clkout<=~clkout;endelse cnt<=cnt+1;endendmodule4、设置顶层实体名(点settings>general >下拉选fenpinqi10)5、编译6、执行file>Create/Update>Create Symbol Files for Current Flie为VHDI设计文件生成原件符号7、建立波形文件8、导入引脚9、仿真结果如下:总结:仿真结果与实验一的题意相符,所以仿真正确。
用verilog语言写的任意整数的分频器占空比:对于一串理想的脉冲序列中(如方波),正脉冲的持续时间与脉冲总周期的比值,叫做这个方波的占空比。
分频分为奇分频和偶分频第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。
如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。
以此循环下去。
这种方法可以实现任意的偶数分频。
第二:奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。
即是在计数值在邻近的1和2进行了两次翻转。
这样实现的三分频占空比为1/3或者2/3。
如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。
这种方法可以实现任意的奇数分频。
归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。
再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。
两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。
另外一种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于(n-1)/2+0.5),然后再进行二分频得到。
分频器设计一、实验目的1、熟悉分频器的原理;2、掌握采用Verilog HDL 语言设计分频器的方法;3、进一步学习利用VerilogHDL 语言进行层次设计的方法。
二、实验内容1、采用Verilog 语言设计一个十分频器,记录Verilog 程序;2、对十分频器进行功能仿真,观察仿真波形;3、仿真没有问题后,将分频比改为50000000,实现一个50M 分频器。
利用此分频器和开发板上的50MHz 时钟信号,得到1Hz 的秒脉冲信号,完成如图1-2.28所示的秒计数器。
50M分频器50MHz 脉冲信号二位十进制计数器1Hz 秒脉冲数码管(个位)数码管(十位)复位和计数使能(拨码开关)程序设计如下:module fenp(clk_out,clk_in,reset);output clk_out;input clk_in;input reset;reg [1:0] cnt;reg clk_out;always@(posedge clk_in or posedge reset)beginif(reset)begincnt<=0;clk_out<=0;endelsebeginif(cnt==24999999)beginclk_out<=!clk_out;cnt<=0;endelsecnt<=cnt+1;endendendmodule本程序经验证,完全可以实现实验要求。
文章来自某大学EDA实验课。
verilog十六分频实现Verilog是一种硬件描述语言,用于进行数字电路的设计和仿真。
十六分频是一种常见的时钟频率分频方法,即将一个时钟信号分频为十六分之一的频率。
下面是一个基于Verilog的简单示例,实现对一个时钟信号进行十六分频:```verilogmodule clk_dividerinput wire clk_in,output wire clk_outreg [3:0] count = 4'b0000;count <= count + 1;if (count == 4'b1111) begincount <= 4'b0000;clk_out <= ~clk_out; // 反相输出endendendmodule```在这个示例中,`clk_in`是输入时钟信号,`clk_out`是输出时钟信号。
我们使用一个4位的计数器 `count` ,每当输入时钟信号出现上升沿时,计数器就会加1,然后检查计数器的值。
当计数器的值等于1111时,表示已经计数到16,这时我们将计数器清零,并且将输出时钟信号取反。
这样,当输入时钟信号的频率为f时,输出时钟信号的频率就会变为f/16使用这个Verilog模块的示例代码如下所示:```verilogmodule top_module;reg clock = 0;//使用时钟分频器模块clk_divider divider.clk_in(clock),.clk_out(clk_out)always clock = ~clock; // 模拟一个5ns的时钟信号initial begin$dumpfile("wave.vcd");$dumpvars(0, top_module);$monitor("clock_out=%b", clk_out);//模拟100个时钟周期repeat (100) begin; // 延迟10nsend$finish;endendmodule```在这个示例中,我们创建了一个名为`top_module`的顶层模块,并将时钟分频器模块实例化为`clk_divider`。
verilog时钟分频设计1.偶分频模块设计偶分频意思是时钟模块设计最为简单。
首先得到分频系数M和计数器值N。
M = 时钟输入频率 / 时钟输出频率N = M / 2如输入时钟为50M,输出时钟为25M,则M=2,N=1。
偶分频则意味着M为偶数。
以M=4,N=2为例,我们希望得到的输出时钟时序如下:因此只需要将counter以clk_in为时钟驱动计数,当counter = (N-1)时,clk_out翻转即可。
verilog代码如下,其中WIDTH为(N的位宽-1):module time_adv_even #(parameter N = 2,WIDTH = 7)(input clk,input rst,output reg clk_out);reg [WIDTH:0]counter;always @(posedge clk or posedge rst) beginif (rst) begin// resetcounter <= 0;endelse if (counter == N-1) begincounter <= 0;endelse begincounter <= counter + 1;endendalways @(posedge clk or posedge rst) beginif (rst) begin// resetclk_out <= 0;endelse if (counter == N-1) beginclk_out <= !clk_out;endendendmoduletestbench测试8分频即N=4,ISE仿真结果如下:2.奇分频模块设计奇分频需要通过两个时钟共同得到。
首先得到分频系数M和计数器值N。
M = 时钟输入频率 / 时钟输出频率N = (M-1) / 2如输入时钟为50M,输出时钟为10M,则M=5,N=2。
奇分频则意味着M为奇数。
Verilog语言实现5分频电路的设计1.行为建模方法:使用行为建模方法,可以通过描述电路的功能行为来实现5分频电路。
以下是使用Verilog语言进行行为建模的代码示例:```verilogmodule DivideBy5input wire clk,output wire clk_outreg [2:0] counter;counter <= 0;clk_out <= ~clk_out;end else begincounter <= counter + 1;endendendmodule```在该示例中,定义了一个模块`DivideBy5`,包含一个输入端口`clk`和一个输出端口`clk_out`,分别用于输入时钟信号和输出分频后的时钟信号。
`reg [2:0] counter`是一个3位的寄存器,用于计数。
当计数达到5时,即计数器的值为5,会将`counter`复位为0,并将输出时钟信号`clk_out`取反。
否则,计数器的值会自增12.结构建模方法:使用结构建模方法,可以通过组合和顺序电路的连接方式来实现5分频电路。
以下是使用Verilog语言进行结构建模的代码示例:```verilogmodule DivideBy5input wire clk,output wire clk_outwire clk_out_2;wire clk_out_3;wire clk_out_4;DivideBy2 div_by_2 ( .clk(clk), .clk_out(clk_out_2) );DivideBy2 div_by_3 ( .clk(clk_out_2), .clk_out(clk_out_3) );DivideBy2 div_by_4 ( .clk(clk_out_3), .clk_out(clk_out_4) );DivideBy2 div_by_5 ( .clk(clk_out_4), .clk_out(clk_out) );endmodulemodule DivideBy2input wire clk,output wire clk_outreg clk_out;clk_out <= ~clk_out;endendmodule```在该示例中,定义了两个模块`DivideBy5`和`DivideBy2`。
VERILOG 分频原理众所周知,分频器是FPGA设计中使用频率非常高的基本设计之一,尽管在目前大部分设计中,广泛使用芯片厂家集成的锁相环资源,如altera 的PLL,Xilinx的DLL.来进行时钟的分频,倍频以及相移。
但是对于时钟要求不高的基本设计,通过语言进行时钟的分频相移仍然非常流行,首先这种方法可以节省芯片内部的锁相环资源,再者,消耗不多的逻辑单元就可以达到对时钟操作的目的。
另一方面,通过语言设计进行时钟分频,可以看出设计者对设计语言的理解程度。
因此很多招聘单位在招聘时往往要求应聘者写一个分频器(比如奇数分频)以考核应聘人员的设计水平和理解程度。
下面讲讲对各种分频系数进行分频的方法:第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。
如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。
以此循环下去。
这种方法可以实现任意的偶数分频。
第二,奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。
即是在计数值在邻近的1和2进行了两次翻转。
这样实现的三分频占空比为1/3或者2/3。
如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。
这种方法可以实现任意的奇数分频。
归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。
Verilog分频器的设计原理一、概述Verilog分频器是数字电路设计中常用的一个模块,它可以将输入的时钟信号分频成较低频率的信号。
在数字系统中,分频器的应用非常广泛,可以用于时钟频率控制、时序信号生成等领域。
本文将介绍Verilog分频器的设计原理,帮助读者了解其工作原理和实现方法。
二、分频器的基本结构1. 分频器的概念分频器是一种能够将输入时钟信号分频成较低频率的信号的电路。
在数字系统中,分频器通常用于降低时钟频率,以满足某些特定的时序要求。
其基本原理是通过对输入时钟信号进行计数和判断,当计数值达到一定阈值时输出一个时钟脉冲,从而实现对输入信号的分频操作。
2. 分频器的基本结构一个简单的分频器通常由计数器和触发逻辑两部分组成。
计数器用于对输入信号进行计数,触发逻辑用于判断计数值是否达到分频的要求,并生成相应的时钟脉冲输出。
根据计数器的位宽和触发逻辑的设计,可以实现不同的分频比。
三、Verilog分频器的设计原理1. Verilog分频器的模块化设计在Verilog中,通常将分频器设计为一个独立的模块,通过实例化和连接可以方便地集成到更大的数字系统中。
分频器的模块化设计可以使其具有良好的可重用性和扩展性,提高数字系统的整体设计效率。
2. Verilog分频器的时序要求在Verilog中设计分频器时,需要考虑到时钟信号的时序要求。
由于分频器通常用于时序控制,因此需要保证分频的输出信号能够与系统中其他模块的时钟信号同步,避免出现不稳定和不可预测的情况。
3. Verilog分频器的实现方法在Verilog中,可以使用寄存器、计数器和逻辑门等原语来实现分频器的功能。
通过合理的组合和连接这些原语,可以实现不同的分频比和时钟脉冲输出。
Verilog语言本身对于多种数字逻辑的建模和描述具有很好的支持,可以方便地实现各种分频器的设计。
四、Verilog分频器的设计实例1. 2分频器的设计以2分频器为例,其实现原理比较简单。
6. 偶数分频器的设计rate=even(偶数),占空比50%设计原理:定义一个计数器对输入时钟进行计数,(1)在计数的前一半时间里,输出高电平,(2)在计数的后一半时间里,输出低电平,这样输出的信号就是占空比为50%的偶数分频信号。
例如,设计一个6分频电路。
对什么计数?①计数值为0~2输出高电平,②计数值为3~5输出低电平。
上升沿计数一个计数周期0112分频module divder_even(clkin,clkout);parameter n=2;input clkin;output clkout;integer cnt;reg clkout;always@(posedge clkin)beginif(cnt<n-1) cnt<=cnt+1;else cnt<=0;endalways@(cnt)beginif(cnt<n/2) clkout<=1'b1;else clkout<=1'b0;end endmodule计数过程判断赋值过程module divder_even(clkin,clkout);parameter n=2;input clkin;output clkout;integer cnt;reg clkout;always@(posedge clkin)beginif(cnt==n/2-1)begincnt<=0;clkout<=~clkout;endelse cnt<=cnt+1;endendmodule 2分频分析4分频分析二分频四分频知识小结1.移位寄存器的verilog描述。
2.偶数分频的verilog描述。
作业1.设计一个5位串入并出的移位寄存器。
Clear :同步清零;clkin :时钟输入;databit :位输入y[4..0]并行数据输出;2.设计一个4位并入串出的移位寄存器Clear :同步清零;clkin :时钟输入(移位);dataIn :并行数据输入,y :串行数据输出。
Verilog常用分频器的实现在Verilog中,实现常用分频器可以通过多种方法,包括基于计数器、移位寄存器和频率除法器等技术。
下面将介绍三种常用的Verilog分频器实现方法。
1.计数器分频器:计数器分频器是一种基于计数器的分频器实现方法。
该方法通常通过计数器对输入脉冲进行计数,并根据计数值的变化来控制输出信号的频率。
```module CounterDividerinput wire clk,input wire reset,output wire outreg [31:0] count;if (reset) begincount <= 0;end else begincount <= count + 1;endendassign out = count[31];endmodule```在这个示例中,计数器模块接收一个时钟信号和复位信号,并在时钟上升沿时对计数器进行计数。
输出信号是计数器的最高位,用于将输入信号除以计数器的最大值。
2.移位寄存器分频器:移位寄存器分频器是一种基于移位寄存器的分频器实现方法。
该方法通过对输入信号进行连续的移位操作来实现分频。
```module ShiftDividerinput wire clk,input wire reset,input wire enable,output wire outreg [31:0] shift_register;reg [3:0] count;if (reset) beginshift_register <= 0;count <= 0;end else beginif (enable) beginshift_register <= {shift_register[30:0], shift_register[31]};count <= count + 1;endendendassign out = shift_register[0];endmodule```在这个示例中,移位寄存器分频器模块接收一个时钟信号、复位信号和使能信号,并在使能信号有效时对输入信号进行连续的位移操作。
用Verilog语言实现奇数倍分频电路 3分频 5分频 7分频分频器是FPGA设计中使用频率非常高的基本设计之一,尽管在目前大部分设计中,广泛使用芯片厂家集成的锁相环资源,如altera 的PLL,Xilinx的DLL.来进行时钟的分频,倍频以及相移。
但是对于时钟要求不高的基本设计,通过语言进行时钟的分频相移仍然非常流行,首先这种方法可以节省芯片内部的锁相环资源,再者,消耗不多的逻辑单元就可以达到对时钟操作的目的。
另一方面,通过语言设计进行时钟分频,可以看出设计者对设计语言的理解程度。
下面讲讲对各种分频系数进行分频的方法:第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。
如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。
以此循环下去,这种方法可以实现任意的偶数分频。
第二,奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:首先,占空比不限定时,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。
即是在计数值在邻近的1和2进行了两次翻转。
这样实现的三分频占空比为1/3或者2/3。
如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。
这种方法可以实现任意的奇数分频。
归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。
分频的Verilog实现1.分频:在实际应用中,自己设计的开发板上不会去装多个晶振来产生不同频率的时钟信号,这就要我们在已有的基础上自己来创造设计电路中所需要的时钟信号来,有时候所需要的频率并不是在已有的频率上直接进行简单的整数分频就可以得到的,有时需要进行小数的分频。
2.在分频的过程中,偶数分频并不困难,若要进行2N次分频的话,只需要计数到N的时候,波形进行翻转就行了,或者在最后一级加一个2分频也可以实现。
下面是我写的一个偶数分频的代码:module div2n(rst,clk,cnt,clk_2n);//偶数次分频input rst,clk;output clk_2n,cnt;reg [3:0] cnt;//刚开始没有定义计数的位宽仿真的时候老是出现输出为0的现象,看似很简单的程序搞的有些纠结啊reg clk_2n;always @(posedge clk )beginif(rst) //若复位信号为高电平则计数清零和输出清零begincnt<=0;clk_2n<=0;endelseif(cnt==3)//进行8分频,这里的cnt取不同的值进行其他的分频,若计数到达4时从0开始的输出电平翻转beginclk_2n<=~clk_2n;cnt<=0;endelse cnt<=cnt+1;endendmodule功能仿真波形以及后仿真波形如下:从后仿真中可以明显的看出输出时钟信号和输入的标准信号有延迟时间,在计数寄存器中出现了相邻两个数之间的竞争,但是没有出现在时钟的上升沿,不会引起最后实现的错误!奇数分频:若奇数分频中不考虑占空比的话,分频代码可以按照偶数分频的思路来写,但是大多数情况下需要考虑的是使占空比设计为50%。
若要进行奇数次的分频而且要求占空比为50%可以采用:用两个计数器,一个由输入时钟下降沿触发,一个由输入时钟的上升沿触发,最后将两个计数器的输出进行相或,就可得到。
Verilog常用分频器的实现分频器是指使输出信号频率为输入信号频率整数分之一的电子电路。
在许多电子设备中如电子钟、频率合成器等,需要各种不同频率的信号协同工作,常用的方法是以稳定度高的晶体振荡器为主振源,通过变换得到所需要的各种频率成分,分频器是一种主要变换手段。
早期的分频器多为正弦分频器,随着数字集成电路的发展,脉冲分频器(又称数字分频器)逐渐取代了正弦分频器。
下面以Verilog HDL语言为基础介绍占空比为50%的分频器。
1.偶分频偶分频比较简单,假设为N分频,只需要计数到N/2‐1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。
代码如下。
module fp_even(clk_out,clk_in,rst);input clk_in,rst;output clk_out;reg [7:0] cnt;reg clk_out;`define N 6always@(posedge clk_in or negedge rst)beginif(!rst)begincnt<=0;clk_out<=0;endelse beginif(cnt==`N/2‐1)beginclk_out<=~clk_out;cnt<=0;endelse cnt<=cnt+1;endendendmodule2.奇分频实现奇数分频(N)分频,分别用上升沿到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1。
得到两个波形,然后把它们相或即可得到N分频。
代码如下。
module fp_odd(clk_in,clk_out,rst,clk_neg,clk_pos);input clk_in,rst;output clk_out,clk_pos,clk_neg;reg [7:0] cnt_pos,cnt_neg;reg clk_pos,clk_neg;`define N 5always@(posedge clk_in or negedge rst) //从零到N‐1不停地循环计数(上升沿)beginif(!rst) cnt_pos<=0;else if(cnt_pos==`N‐1) cnt_pos<=0;else cnt_pos<=cnt_pos+1;endalways@(posedge clk_in or negedge rst)beginif(!rst) clk_pos<=0;else if( cnt_pos==(`N‐1)/2 ) clk_pos<=~clk_pos;else if(cnt_pos==`N‐1) clk_pos<=~clk_pos;endalways@(negedge clk_in or negedge rst) //从零到N‐1不停地循环计数(下降沿)beginif(!rst) cnt_neg<=0;else if(cnt_neg==`N‐1) cnt_neg<=0;else cnt_neg<=cnt_neg+1;endalways@(negedge clk_in or negedge rst)beginif(!rst) clk_neg<=0;else if( cnt_neg==(`N‐1)/2 ) clk_neg<=~clk_neg;else if(cnt_neg==`N‐1) clk_neg<=~clk_neg;endassign clk_out=clk_neg|clk_pos;endmodule3.任意占空比的任意分频在 verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求。
Verilog分频器设计module adder(clk,z);output z;reg q;reg z;always@(posedge clk)beginif(q%9==0)z<=q;elseq=q+1;endendmodulemodule counter9(clk,datein,z); output z;input clk;input datein;reg z;reg[3:0] q;always@(posedge clk)beginq<=q+1;if (q==4'b1001)beginq<=4'b0000;z<=datein;endendendmodule2008-11-04 19:58分频器是FPGA设计中使用频率非常高的基本单元之一。
尽管目前在大部分设计中还广泛使用集成锁相环(如altera的PLL,Xilinx的DLL)来进行时钟的分频、倍频以及相移设计,但是,对于时钟要求不太严格的设计,通过自主设计进行时钟分频的实现方法仍然非常流行。
首先这种方法可以节省锁相环资源,再者,这种方式只消耗不多的逻辑单元就可以达到对时钟操作的目的。
偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。
如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。
以此循环下去。
这种方法可以实现任意的偶数分频。
module odd_division(clk,rst,count,clk_odd); /*count没必要放在端口中,这里只是为了仿真时观察*/input clk,rst;output clk_odd;output[3:0] count;reg clk_odd;reg[3:0] count;parameter N = 6; /*6分频* /always @ (posedge clk)if(! rst)begincount <= 1'b0;clk_odd <= 1'b0;endelseif ( count < N/2-1)begincount <= count + 1'b1;endelsebegincount <= 1'b0;clk_odd <= ~clk_odd;endendmodule奇数倍分频:归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数从零开始,到N-1)/2进行输出时钟翻转,然后经过(N+1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。
再者同时进行下降沿触发的模N计数,到和上升沿过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。
两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。
module even_division(clk,rst,count1,count2,clk_even); /*count1,count2没必要放在端口中,这里只是为了仿真时观察*/input clk,rst;output[3:0] count1,count2;output clk_even;reg[3:0] count1,count2;reg clkA,clkB;wire clk_even,clk_re;parameter N = 5; /*5分频*/assign clk_re = ~clk;assign clk_even = clkA | clkB;always @(posedge clk)if(! rst)begincount1 <= 1'b0;clkA <= 1'b0;endelseif(count1 < (N - 1))begincount1 <= count1 + 1'b1; /*这里是非阻塞赋值是先执行了下面的IF判断,最后才赋的值。
最初看这程序时没注意,想了好半天*/if(count1 == (N - 1)/2)beginclkA <= ~clkA;endendelsebeginclkA <= ~clkA;count1 <= 1'b0;endalways @ (posedge clk_re)if(! rst)begincount2 <= 1'b0;clkB <= 1'b0;endelseif(count2 < (N - 1))begincount2 <= count2 + 1'b1;if(count2 == (N - 1)/2)beginclkB <= ~clkB;endendelsebeginclkB <= ~clkB;count2 <= 1'b0;endendmoduleVerilog HDL的分频器设计2009-12-03 10:22用D触发器实现2倍分频的Verilog描述?module divide2( clk , clk_o, reset);input clk , reset;output clk_o;wire in;reg out ;always @ ( posedge clk or posedge reset)if ( reset)out <= 0;elseout <= in;assign in = ~out;assign clk_o = out;endmodule用verilog实现分频的一点心得2007-08-04 22:40在用verilog编写程序的过程中,将时钟进行11分频,花了好多的心思才将其搞定。
通常实现偶数的分频比较容易,以十分频为例:always @( posedge clk or posedge reset)if(reset)begink<=0;clk_10<=0;endelseif(k==4)begink<=0;clk_10<=~clk_10;endelsek<=k+1;二分频最简单了,一句话就可以了:always @ (negedge clk)clk_2<=clk_2;若进行奇数分频,则稍微麻烦点,以11分频为例:always @( posedge clk)if(!reset)begini<=0;clk11<=0;endelseif(i==5)beginclk11<=~clk11;i<=i+1;endelseif(i==10)begini<=0;clk11<=~clk11;endelsei<=i+1;以上语句虽然可以实现,但是逻辑有点繁,弄不好就出错了,建议使用两个always语句来实现:always @( posedge clk)if(!reset)i<=0;elsebeginif(i==10)i<=0;elsei<=i+1;endalways @( posedge clk)if(!reset)clk11<=0;elseif((i==5)|(i==10))clk11<=~clk11;两个always,一个用来计数,一个用来置数。
另外,这个样子好像也可以,在时钟的上升沿和下降沿都计数,但是不被综合器综合,会提示敏感信号太复杂:always @( posedge clk or negedge clk)if(reset)begink<=0;clk_11<=0;endelseif(k==10)begink<=0;clk_11<=~clk_11;endelsek<=k+1;三分频的Verilog实现rickywu 发表于2005-12-12 11:14:00//很实用也是笔试面试时常考的,已经经过仿真占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述module div3(CLKIN,CLKOUT,RESETn);input CLKIN,RESETn;output CLKOUT;//internal counter signalsreg[1:0] count_a;reg[1:0] count_b;reg CLKOUT;always @(negedge RESETn or posedge CLKIN)beginif (RESETn==1'b0)count_a<=2'b00;elseif (count_a==2'b10)count_a<=2'b00;elsecount_a<=count_a+1;endalways @(negedge RESETn or negedge CLKIN)beginif (RESETn==1'b0)count_b<=2'b0;elseif (count_b==2'b10)count_b<=2'b00;elsecount_b<=count_b+1;endalways @(count_a or count_b or RESETn)beginif (RESETn==1'b0)CLKOUT=1'b0;else if((count_a+count_b==4)||(count_a+ count_b==1)) CLKOUT=~CLKOUT;endendmodule0 1 2 0 1 2\ / / \ \ / / \0 1 2 0 1 2下面是一个非50%的描述,只用了上升沿module div3(CLKIN,CLKOUT,RESETn);input CLKIN,RESETn;output CLKOUT;wire d;reg q1,q2;wire CLKOUT;always @(negedge RESETn or posedge CLKIN) beginif (RESETn==1'b0)q1<=1'b0;elseq1<=d;endalways @(negedge RESETn or posedge CLKIN)beginif (RESETn==1'b0)q2<=1'b0;elseq2<=q1;endassign d=~q1 & ~q2;assign CLKOUT=q2;endmodule占空比不是50%,只用了单沿触发器,寄存器输出。
至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。