verilogHDL分频器(奇数分频和偶数分频)
FPGA分频与倍频的简单总结(涉及自己设计,调用时钟IP核,调用MMCM原语模块)
FPGA分频与倍频的简单总结(涉及⾃⼰设计,调⽤时钟IP核,调⽤MMCM原语模块)原理介绍1、分频FPGA设计中时钟分频是重要的基础知识,对于分频通常是利⽤计数器来实现想要的时钟频率,由此可知分频后的频率周期更⼤。
⼀般⽽⾔实现偶数系数的分频在程序设计上较为容易,⽽奇数分频则相对复杂⼀些,⼩数分频则更难⼀些。
1)偶分频系数=时钟输⼊频率/时钟输出频率=50MHz/5MHz=10,则计数器在输⼊时钟的上升沿或者下降沿从0~(10-1)计数,⽽输出时钟在计数到4和9时翻转。
2)奇分频系数=50MHz/10MHz=5,则两个计数器分别在输⼊时钟的上升沿和下降沿从0~ (5-1)计数,⽽相应的上升沿和下降沿触发的输出时钟在计数到1和4时翻转,最后将两个输出时钟进⾏或运算从⽽得到占空⽐为50%的5分频输出时钟。
下图所⽰为50MHz输⼊时钟进⾏10分频和5分频的仿真波形2、倍频两种思路:PLL(锁相环)或者利⽤门延时来搭建注意:此仿真是利⽤FPGA内部电路延迟来实现的倍频需要在后仿真下才能看到波形,在⾏为仿真下⽆法得到输出波形。
⼀、时钟IP的分频倍频相关参数说明输⼊时钟:clk_in1(125MHz)输出时钟:clk_out1(50MHz),clk_out2(74.25MHz)则VCO Freq=1262.5MHz=clk_in1*CLKFBOUT_MULT_F/DIVCLK_DIVIDE=125*50.5/5clk_out1(50MHz)=VCO_Freq/Divide=1265.5/25.250clk_out2(74.25MHz)=VCO_Freq/Divide=1265.5/17⼆、MMCME4_ADVMMCME4是⼀种混合信号块,⽤于⽀持频率合成、时钟⽹络设计和减少抖动。
基于相同的VCO频率,时钟输出可以有单独的分频、相移和占空⽐。
此外,MMCME4还⽀持动态移相和分数除法(1)Verilog 初始化模板MMCME4_ADV #(.BANDWIDTH("OPTIMIZED"), // Jitter programming.CLKFBOUT_MULT_F(5.0), // Multiply value for all CLKOUT.CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB.CLKFBOUT_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKIN1_PERIOD(0.0), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz)..CLKIN2_PERIOD(0.0), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz)..CLKOUT0_DIVIDE_F(1.0), // Divide amount for CLKOUT0.CLKOUT0_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT0.CLKOUT0_PHASE(0.0), // Phase offset for CLKOUT0.CLKOUT0_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT1_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT1_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT1_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT1_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT2_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT2_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT2_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT2_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT3_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT3_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT3_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT3_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT4_CASCADE("FALSE"), // Divide amount for CLKOUT (1-128).CLKOUT4_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT4_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT4_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT4_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT5_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT5_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT5_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT5_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).CLKOUT6_DIVIDE(1), // Divide amount for CLKOUT (1-128).CLKOUT6_DUTY_CYCLE(0.5), // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT6_PHASE(0.0), // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT6_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE).COMPENSATION("AUTO"), // Clock input compensation.DIVCLK_DIVIDE(1), // Master division value.IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN.IS_CLKIN1_INVERTED(1'b0), // Optional inversion for CLKIN1.IS_CLKIN2_INVERTED(1'b0), // Optional inversion for CLKIN2.IS_CLKINSEL_INVERTED(1'b0), // Optional inversion for CLKINSEL.IS_PSEN_INVERTED(1'b0), // Optional inversion for PSEN.IS_PSINCDEC_INVERTED(1'b0), // Optional inversion for PSINCDEC.IS_PWRDWN_INVERTED(1'b0), // Optional inversion for PWRDWN.IS_RST_INVERTED(1'b0), // Optional inversion for RST.REF_JITTER1(0.0), // Reference input jitter in UI (0.000-0.999)..REF_JITTER2(0.0), // Reference input jitter in UI (0.000-0.999)..SS_EN("FALSE"), // Enables spread spectrum.SS_MODE("CENTER_HIGH"), // Spread spectrum frequency deviation and the spread type .SS_MOD_PERIOD(10000), // Spread spectrum modulation period (ns).STARTUP_WAIT("FALSE") // Delays DONE until MMCM is locked)MMCME4_ADV_inst (.CDDCDONE(CDDCDONE), // 1-bit output: Clock dynamic divide done.CLKFBOUT(CLKFBOUT), // 1-bit output: Feedback clock.CLKFBOUTB(CLKFBOUTB), // 1-bit output: Inverted CLKFBOUT.CLKFBSTOPPED(CLKFBSTOPPED), // 1-bit output: Feedback clock stopped.CLKINSTOPPED(CLKINSTOPPED), // 1-bit output: Input clock stopped.CLKOUT0(CLKOUT0), // 1-bit output: CLKOUT0.CLKOUT0B(CLKOUT0B), // 1-bit output: Inverted CLKOUT0.CLKOUT1(CLKOUT1), // 1-bit output: CLKOUT1.CLKOUT1B(CLKOUT1B), // 1-bit output: Inverted CLKOUT1.CLKOUT2(CLKOUT2), // 1-bit output: CLKOUT2.CLKOUT2B(CLKOUT2B), // 1-bit output: Inverted CLKOUT2.CLKOUT3(CLKOUT3), // 1-bit output: CLKOUT3.CLKOUT3B(CLKOUT3B), // 1-bit output: Inverted CLKOUT3.CLKOUT4(CLKOUT4), // 1-bit output: CLKOUT4.CLKOUT5(CLKOUT5), // 1-bit output: CLKOUT5.CLKOUT6(CLKOUT6), // 1-bit output: CLKOUT6.DO(DO), // 16-bit output: DRP data output.DRDY(DRDY), // 1-bit output: DRP ready.LOCKED(LOCKED), // 1-bit output: LOCK.PSDONE(PSDONE), // 1-bit output: Phase shift done.CDDCREQ(CDDCREQ), // 1-bit input: Request to dynamic divide clock.CLKFBIN(CLKFBIN), // 1-bit input: Feedback clock.CLKIN1(CLKIN1), // 1-bit input: Primary clock.CLKIN2(CLKIN2), // 1-bit input: Secondary clock.CLKINSEL(CLKINSEL), // 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2.DADDR(DADDR), // 7-bit input: DRP address.DCLK(DCLK), // 1-bit input: DRP clock.DEN(DEN), // 1-bit input: DRP enable.DI(DI), // 16-bit input: DRP data input.DWE(DWE), // 1-bit input: DRP write enable.PSCLK(PSCLK), // 1-bit input: Phase shift clock.PSEN(PSEN), // 1-bit input: Phase shift enable.PSINCDEC(PSINCDEC), // 1-bit input: Phase shift increment/decrement.PWRDWN(PWRDWN), // 1-bit input: Power-down.RST(RST) // 1-bit input: Reset);(2)本实验仿真所⽤参数配置说明及部分端⼝调⽤1、参数配置说明本实验通过输⼊时钟CLKIN1(150MHz),实现输出反馈时钟CLKFBOUT(150MHz)、输出时钟CLKOUT0(74.25MHz)、输出时钟CLKOUT1(74.25MHz)、输出时钟CLKOUT2(59.4MHz)、输出时钟CLKOUT3(49.5MHz)。
在verilog中,求平均数,奇数和偶数的处理方法
在verilog中,求平均数,奇数和偶数的处理方法在Verilog中,你可以通过使用一些基本的算术操作符和逻辑操作符来计算平均数、奇数和偶数。
假设你有一个名为`input_data`的信号,你可以通过以下方式来计算平均数:```verilogreg [31:0] sum = 0; // 32位寄存器用于存储总和reg [31:0] count = 0; // 32位寄存器用于存储数据数量always (posedge clk) beginif (reset) beginsum <= 0;count <= 0;end else beginsum <= sum + input_data; // 累加输入数据count <= count + 1; // 计数器加1endend// 计算平均数reg [31:0] average;always (posedge clk) beginif (reset) beginaverage <= 0;end else beginaverage <= sum / count; // 计算平均数,注意这里需要整数除法 endend```对于奇数和偶数的处理,你可以使用简单的逻辑操作符:```verilogreg [31:0] is_odd; // 存储是否为奇数的标志位reg [31:0] is_even; // 存储是否为偶数的标志位always (posedge clk) beginif (reset) beginis_odd <= 0;is_even <= 0;end else beginif (input_data % 2 == 1) begin // 如果输入数据是奇数is_odd <= 1; // 设置奇数标志位end else begin // 如果输入数据是偶数is_even <= 1; // 设置偶数标志位endendend```请注意,这些代码示例仅供参考,你可能需要根据具体的应用场景和硬件平台进行适当的修改。
用Verilog语言实现奇数倍分频电路3分频5分频7分频
用Verilog语言实现奇数倍分频电路3分频5分频7分频Verilog是一种硬件描述语言(HDL),用于描述数字电路的行为和结构。
使用Verilog语言实现奇数倍分频电路可以分为以下几个步骤:1.定义输入和输出端口通过module关键字定义一个模块,并指定输入和输出端口的信号。
```verilogmodule OddDividerinput clk,output reg out_3x,output reg out_5x,output reg out_7x```2.定义局部变量和计数器定义一个局部变量和一个计数器,用于跟踪时钟周期并确定何时输出。
```verilogreg [2:0] count;```3.实现分频逻辑使用always块,根据计数器的值判断何时输出,并在输出端口上更新信号。
```verilogif (count == 3'b000) beginout_3x <= !out_3x;endif (count == 3'b001) beginout_5x <= !out_5x;endif (count == 3'b010) beginout_7x <= !out_7x;endcount <= count + 1;end```4.结束模块使用endmodule关键字结束模块定义。
```verilogendmodule完整的Verilog代码如下:```verilogmodule OddDividerinput clk,output reg out_3x,output reg out_5x,output reg out_7xreg [2:0] count;if (count == 3'b000) begin out_3x <= !out_3x;endif (count == 3'b001) begin out_5x <= !out_5x;endif (count == 3'b010) begin out_7x <= !out_7x;endcount <= count + 1;endmodule```以上代码实现了一个奇数倍分频电路,其中输入时钟信号为`clk`,输出分别是3倍分频的信号`out_3x`,5倍分频的信号`out_5x`和7倍分频的信号`out_7x`。
用verilog实现任意倍分频器的方法
用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),然后再进行二分频得到。
verilog时钟分频设计
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代码
奇偶分频电路verilog代码奇偶分频电路verilog代码1.偶数分频器偶数分频器只要在计数器为N/2-1时反转输出就⾏//4分频器module clk_div(input clk,input rst_n,output reg clk_div4);reg [3:0]count;parameter N=4;//若⽤integer i 采⽤always@(posedge clk or negedge rst_n)beginif(rst_n)begincount <=4'b0;endelse if(count==4'b1)begincount <=4'b0;endelse begincount <=count +4'd1;endendalways @(posedge clk or negedge rst_n)beginif(rst_n)beginclk_div4 <=1'b0;endelse if(count==4'b1)beginclk_div4<=~clk_div4;endelse beginclk_div4<=clk_div4;endendendmodule2.奇数分频器奇数分频器有两种,⼀种是占空⽐为50的⼀种是占空⽐⾮20的。
⾸先是占空⽐⾮50的,⽤错位异或实现module div5(input clk,input rst_n,output clk_div5);reg clk1;reg clk2;reg [2:0] count;always @(posedge clk or negedge rst_n) beginif(rst_n)begincount <=3'd0;endelse if(count==3'd4)begincount <=3'd0;endelse begincount <=count+1'b1;endendalways @(posedge clk or negedge rst_n) beginif(rst_n)beginclk1<=1'b0;endelse if(count==3'd4)beginclk1 <=~clk1;endelse beginclk1<=clk1;endendalways @(posedge clk or negedge rst_n) beginif(rst_n)beginclk2<=1'b0;endelse if(count==3'd2)beginclk2 <=~clk2;endelse beginclk2<=clk2;endendassign clk_div5 = clk2^clk1 ;endmodule关键是第⼀个clk等计数器=N-1跳,第⼆个在(N-1)/2跳接下来是50占空⽐的,⽤另⼀个下降沿实现module top(input clk,input rst_n,output clk_div);reg clk1;reg clk2;reg [2:0] count;always @(posedge clk or negedge rst_n) beginif(rst_n)beginclk1 <=1'd0;endelse if(count==3'd0)beginclk1 <=1'd1;endelse if(count==3'd2)beginclk1 <=1'b0;endendalways @(posedge clk or negedge rst_n) beginif(rst_n)begincount <=3'd0;endelse if(count==3'd4)begincount <=3'd0;endelse begincount <=count+1'b1;endendalways @(negedge clk or negedge rst_n) beginif(rst_n)beginclk2<=1'b0;endelse beginclk2<=clk1;endendassign clk_div = clk2 || clk1 ;endmodule关键在第⼀个于(N-1)/2的时候从1跳0,第⼆个下降沿触发,相当于第⼀个的后⼀级寄存器。
VERILOG 分频原理
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设计
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 HDL基础∙使用Verilog设计的Quartus II入门指南∙使用Verilog设计的ModelSIm入门指南内容1 从计数器到分频器此处所说的分频器,即把输入时钟的频率降低后再输出时钟的模块。
今天我们只讨论等占空比的偶数分频和奇数分频,关于小数分频以及倍频将不做介绍,有兴趣的朋友可以自行研究。
在之之前我们先看下前面讲的模-m计数器。
代码1.1 模-m计数器(缺省为模-10计数器)根据这个模-m计数器,我们再写一个testbench。
代码1.2 模m-计数器的testbench(重新配置为模-10计数器)但是我在使用Quartus II + Modelsim_Altera仿真的时候出现了下面的错误提示。
代码2的第10行,变量N未定义,然后第11行用N来索引的q数组也没有定义。
奇怪了,我在Quartus II都能综合通过,而且RTL视图也是正确的,为什么Modelsim_Altera就不可以这样定义呢?咳,把常量(localparam)换成参数(parameter)即可。
代码1.3 改进后的模-m计数器(重新配置为模-10计数器)修改完,在Quartus II 里再综合一下。
接下来就是按照[文档].艾米电子 - 使用Verilog 设计的Quartus II入门指南再做一次仿真。
告诉大家一个技巧,如果执行完一次RTL 级或门级的仿真,那么Quartus II 会为我们的主模块及其testbench生成do 文件的。
这样假如有错误,就无需重新启动Modelsim_Altera ,只需重新load 一下do 文件即可。
(路径格式:Quarter II 工程文件夹\simulation\modelsim \mod_m_bin_counter_run_msim_rtl_verilog.do ) 下面看下RTL 级仿真波形。
下面讨论一下如何测量波形的长度,我们注意两个工具。
数字集成电路课程设计
摘要Verilog HDL是一种硬件描述语言,是EDA技术的重要组成部分。
使用HDL 进行数字系统设计是电子设计技术的发展趋势和方向,因此学好这门知识并能够灵活运用于课程设计是非常有必要也非常有意义的。
本次设计主要实现了一个任意分频器的简单功能。
主要有以下两种方案:(一)对被分频时钟的上升沿和下降沿同时计数,计数到分频系数的一半时,对输出时钟进行电平翻转,从而得到占空比为50%的分频时钟。
(二)对被分频时钟的上升沿和下降沿分别计数,得到一个上升沿分频时钟clk_p 和一个下降沿分频时钟clk_q,最后通过对这两个时钟进行相应的逻辑运算,便可得到占空比为50%的输出时钟。
在仿真过程中,主要遇到的问题是无法综合。
经讨论思考发现对同一时钟的上升沿和下降沿同时进行操作时,Quartus II将无法对这一行为进行综合。
最后,为解决综合的问题,我们对程序进行了必要的修改。
最终,我们经过比较选择了方案(二),实现了预期的目标。
【关键词】Verilog HDL 任意分频器半整数分频综合ABSTRACTVerilog HDL is a hardware description language which is an important part of EDA technology. Nowadays,using HDL to design Digital systems is the development trend of electronic design technologies. So it is very necessary and very meaningful to learn this course and develop the ability to apply the knowledge learned to curriculum design flexibly.This design mainly realized a simple function of frequency divider at any frequency coefficients . Basically,we have the following two schemes:First: counting at the rise and fall of the input clock simultaneously, when arrive at half of the frequency coefficients, overturn the output clock, so a clock whose duty ratio is 50% can be achieved;Second: to get a clk_p at the rise of the input clock and a clk_q at the fall of the input clock respectively, then through the corresponding logic operation of the two clock,the wanted output clock can be easily achieved.In the debugging process, the main problem is unable to be synthesized. After discussion and reflection,we found that operations on one clock’s rise and fall at the same time are unable to be synthesized by Quartus II. Finally, in order to solve the problem, we have the program changed where is necessary and we choose the second scheme to meet the desired goals by comparison.【Key words】Verilog HDL Synthesize Divide at any Frequency Coefficients Frequency Division at Half an Integer第一章系统设计第一节课题目标及总体方案《集成电路设计》是一门专业性、技术性、应用性很强的学科,实验课教学是它的一个极为重要的环节。
使用VHDL进行分频器设计
使用VHDL 进行分频器设计作者:ChongyangLee摘要使用VHDL 进行分频器设计作者:ChongyangLee本文使用实例描述了在FPGA/CPLD 上使用VHDL 进行分频器设计,包括偶数分频、非50%占空比和50%占空比的奇数分频、半整数(N+0.5)分频、小数分频、分数分频以及积分分频。
所有实现均可通过Synplify Pro 或FPGA 生产厂商的综合器进行综合,形成可使用的电路,并在ModelSim 上进行验证。
目录概述 (1)计数器 (1)普通计数器 (1)约翰逊计数器 (3)分频器 (4)偶数分频器 (4)奇数分频器 (6)半整数分频器 (9)小数分频器 (11)分数分频器 (15)积分分频器 (18)概述分频器是数字电路中最常用的电路之一,在FPGA 的设计中也是使用效率非常高的基本设计。
基于FPGA 实现的分频电路一般有两种方法:一是使用FPGA 芯片内部提供的锁相环电路,如ALTERA 提供的PLL (Phase Locked Loop),Xilinx 提供的DLL(Delay Locked Loop);二是使用硬件描述语言,如VHDL、Verilog HDL 等。
使用锁相环电路有许多优点,如可以实现倍频;相位偏移;占空比可调等。
但FPGA 提供的锁相环个数极为有限,不能满足使用要求。
因此使用硬件描述语言实现分频电路经常使用在数字电路设计中,消耗不多的逻辑单元就可以实现对时钟的操作,具有成本低、可编程等优点。
计数器计数器是实现分频电路的基础,计数器有普通计数器和约翰逊计数器两种。
这两种计数器均可应用在分频电路中。
普通计数器最普通的计数器是加法(或减法)计数器。
下面是加法计数器的VHDL实现,其Synplify Pro下的RTL View如图1所示。
--file Name: ripple.vhd--Description: 带复位功能的加法计数器library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity ripple isgeneric (width: integer := 4);port(clk, rst: in std_logic;cnt: out std_logic_vector(width - 1 downto 0));end ripple;architecture a of ripple issignal cntQ: std_logic_vector(width - 1 downto 0);beginprocess(clk, rst)beginif (rst = '1') thencntQ <= (others => '0');elsif (clk'event and clk = '1') thencntQ <= cntQ + 1;end if ; end process ;cnt <= cntQ;end a;代码 1 加法计数器 VHDL 代码图 1 加法计数器 RTL 视图加法计数器的Test Bench 代码如下所示,在ModelSim 下进行功能仿真,仿真 波形结果如图 2所示。
奇数分频器VHDL设计
奇数分频器1 引言分频器在CPLD/FPGA设计中使用频率非常高,尽管目前大部分设计中采用芯片厂家集成的锁相环资源,但是对于要求奇数倍分频、小数倍分频的应用场合却往往不能满足要求。
硬件工程师希望有一种灵活的设计方法,根据需要,在实验室就能设计分频器并马上投入使用,更改频率时无需改动原器件或电路板,只需重新编程,在数分钟内即可完成。
对于偶数分频,使用一模N计数器模块即可实现,即每当模N计数器从0开始计数至N时,输出时钟进行翻转,同时使计数器复位,使之从0开始重新计数,以此循环即可实现。
但对于奇数分频,实现50%的占空比却是比较困难的。
下面给出占空比50%的奇数分频器的设计源程序和仿真结果。
2 VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;--添加库ENTITY fdiv IS --设计实体PORT( clk,reset : IN STD_LOGIC;--端口说明preset: IN INTEGER;--preset:分频预置数clkout : OUT STD_LOGIC);- -clkout :分频后得到的时钟END fdiv;ARCHITECTURE behave OF fdiv IS--设计构造体SIGNAL s1,s2 : STD_LOGIC;--内部信号s1,s2 SIGNAL cnt : INTEGER RANGE 0 TO preset-1;--模为preset的计数信号BEGINP1: PROCESS(clk,reset) --计数器BEGINIF reset='1' THENcnt<=0;ELSIF clk'event AND clk='1' THENIF cnt=0 THENcnt<=preset-1;ELSEcnt<=cnt-1;END IF;END IF;END PROCESS;P2: PROCESS(clk,reset) --信号1 BEGINIF reset='1' THENs1<='1';ELSIF clk'event AND clk='1' THENIF cnt=0 THEN --计数信号为0时,S1翻转s1<=NOT s1;ELSEs1<=s1;END IF;END IF;END PROCESS;P3: PROCESS(clk,reset) --信号2 BEGINIF reset='1' THENs2<='1';ELSIF clk'event AND clk='0' THENIF cnt=(preset-1)/2 THEN --计数信号为N时,S2翻转s2<=NOT s2;ELSEs2<=s2;END IF;END IF;END PROCESS;clkout<= s1 XOR s2; -- 异或输出END BEHA VE;程序说明:以上程序实现任意奇数为PRESET的50%占空比分频,计数器CNT的模值为PRESET,计数器是为了控制信号S1和信号S2,使两信号保持恒定的时间差。
Verilog实现三分频的多种方法(附有代码)
用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语言实现
分频的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常用分频器的实现分频器是指使输出信号频率为输入信号频率整数分之一的电子电路。
在许多电子设备中如电子钟、频率合成器等,需要各种不同频率的信号协同工作,常用的方法是以稳定度高的晶体振荡器为主振源,通过变换得到所需要的各种频率成分,分频器是一种主要变换手段。
早期的分频器多为正弦分频器,随着数字集成电路的发展,脉冲分频器(又称数字分频器)逐渐取代了正弦分频器。
下面以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奇偶分频、一段式、两段式、三段式状态机
汇报总结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、奇数分频对于对占空比没有特殊要求的奇数分频,需要对上升沿和下降沿脉冲进行计数,利用下降沿产生的波形移相半个输入脉冲的作用,最后用错位“异或”法实现。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
// odd
module 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)
begin
if(cnt<(div[WIDE-1:1]))
begin
cnt<=cnt+1;
cout<=1'b0;
end
else
begin
cnt<=0;
cout<=1'b1;
end
end
always @(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)
begin
else if(cnt_a<=(div[WIDE-1:1]))
begin
cnt_a=cnt_a+1;
cout_a=1'b1;
end
else if(cnt_a>(div[WIDE-1:1])&&cnt_a<(div[WIDE-1:0]-1))
begin
cout_a=1'b0;
cnt_a=cnt_a+1;
end
else
begin
cnt_a=0;
end
end
always @(posedge iCLK)
begin
if(cnt_b<=(div[WIDE-1:1]))
begin
cnt_b=cnt_b+1;
cout_b=1'b1;
end
else if(cnt_b>(div[WIDE-1:1])&&cnt_b<(div[WIDE-1:0]-1))
begin
cout_b=1'b0;
cnt_b=cnt_b+1;
end
else
begin
cnt_b=0;
end
end
assign oCLK = cout_a&cout_b;
endmodule
//even
module 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)
begin
if(cnt<(div[WIDE-1:1]-1))
cnt <= cnt + 1;
else
begin
cnt <= 0;
oCLK <= ~oCLK;
end
end
endmodule
//============================
//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;
initial
begin
iCLK = 0;
div=14'd7;
#1000 $stop;
end
endmodule
*/
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)
begin
if(a==1)
clkout=oCLK1;
else
clkout=oCLK2;
end
endmodule
//测试代码
//testbench
module 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;
initial
begin
iCLK = 0;
div=14'd7;
#1000 $stop;
End
Modelsim仿真结果
1.七分频
2.四分频。