Verilog七分频
- 格式:doc
- 大小:48.50 KB
- 文档页数:4
Verilog实现任意分频在Verilog中实现任意分频可以通过使用计数器和分频比例来实现。
下面是一个基于计数器的Verilog代码示例,用于实现任意分频。
```verilogmodule frequency_dividerinput clk,input rst,input [7:0] div_ratio,output reg outreg [7:0] count;beginif (rst)count <= 0;else if (count == div_ratio - 1)count <= 0;elsecount <= count + 1;endbeginif (rst)out <= 0;else if (count == div_ratio - 1)out <= ~out;endendmodule```在以上代码中,我们定义了一个名为"`frequency_divider`"的模块,该模块具有以下输入和输出:- `clk`:时钟信号- `rst`:复位信号- `div_ratio`:分频比例,使用8位二进制表示,范围为0到255- `out`:输出信号我们使用一个8位计数器(`count`)来进行分频。
每当计数器达到分频比例减1时,输出信号取反。
例如,如果分频比例为1,则输出信号将与时钟信号同步;如果分频比例为2,则输出信号将是时钟信号的一半频率;如果分频比例为4,则输出信号将是时钟信号的四分之一频率,以此类推。
需要注意的是,以上示例代码仅展示了分频的基本原理,并未考虑输入和输出信号的时序问题,如使 `div_ratio` 在运行时可更改、输出信号的不稳定性等。
针对具体应用需求,可以根据实际情况做出适当的修改和调整。
希望以上内容对您有所帮助!。
高质量七倍分频电路的设计与实现作者:张继刚李维忠来源:《现代电子技术》2008年第06期摘要:提出一种可实现占空比为50%的7倍时钟分频电路的高可靠性设计方案,并分别给出由分立元件组构和由Verilog HDL语言描述的2种实现方法。
与已有方案相比,该设计不仅可以节省器件资源,而且完全避免了冒险现象对于分频时钟波形造成的影响。
在Quartus环境下,分别对门级设计和基于Verilog HDL语言的行为级描述进行仿真验证,结果显示该方案合理可行。
关键词:奇数次分频器;格雷码计数器;时钟波形;FPGA中图分类号:TN772 文献标识码:B文章编号:1004-373X(2008)06-012-02Design and Implementation of High Quality 1∶7 Frequency DividerZHANG Jigang,LI Weizhong(Inner Mongolia University of Technology,Huhhot,010051,China)Abstract:Design method of high-reliability 1∶7 clock frequency divider with half duty cycle is brought forward,and then implementation method based on separate component or described by Verilog HDL is paring with former design method,not only can the method economize on hardware resource,but it can be absolutely avoided that waveform of divided frequency clock is interfered by hazard in this method.After function of gate level design as well as behavior level design based on Verilog HDL is simulated in Quartus software,the method is proved logical and feasible as a result.Keywords:odd number frequency divider;Gary code counter;clock waveform;FPGA1 引言数字电路设计中常采用对主频时钟分频的方法产生所需的时钟。
汇报总结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语言实现奇数倍分频电路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 hdl语言100例详解Verilog HDL语言是一种硬件描述语言,用于描述数字电路和系统的行为和结构。
它是硬件设计工程师在数字电路设计中的重要工具。
本文将介绍100个例子,详细解释Verilog HDL语言的应用。
1. 基本门电路:Verilog HDL可以用于描述基本门电路,如与门、或门、非门等。
例如,下面是一个描述与门电路的Verilog HDL代码:```verilogmodule and_gate(input a, input b, output y);assign y = a & b;endmodule```2. 多路选择器:Verilog HDL也可以用于描述多路选择器。
例如,下面是一个描述2:1多路选择器的Verilog HDL代码:```verilogmodule mux_2to1(input a, input b, input sel, output y);assign y = sel ? b : a;endmodule```3. 寄存器:Verilog HDL可以用于描述寄存器。
例如,下面是一个描述8位寄存器的Verilog HDL代码:```verilogmodule register_8bit(input [7:0] d, input clk, input reset, output reg [7:0] q);always @(posedge clk or posedge reset)if (reset)q <= 0;elseq <= d;endmodule```4. 计数器:Verilog HDL可以用于描述计数器。
例如,下面是一个描述8位计数器的Verilog HDL代码:```verilogmodule counter_8bit(input clk, input reset, output reg [7:0] count);always @(posedge clk or posedge reset)if (reset)count <= 0;elsecount <= count + 1;endmodule```5. 加法器:Verilog HDL可以用于描述加法器。
任意分数Verilog实现网上常见的多为小数分频,分数分频也为有规律的分频,如N/2、M-1/N等。
而像M/N型分数分频却很少。
现介绍一下本人的分数分频实现方法,如果不当之处敬请指教。
分数分频实现基本上都是靠吞脉冲方法实现,如5/2分频,就可以分成一个2分频,一个3分频接替出现,这样(2+3)/2就是5/2分频。
下面以68/9为例介绍下怎么计算。
68=9*7+5,即商为7,余数为5。
可以推出68/9分频,可以看成5个8分频和4个7分频,即(5*8+4*7)/9=68/9。
这个7分频和8分频中的数字7和8就是从商中得出来的。
那5个8分频和4个7分频中的数字5和4就是从余数中的出来的,5是余数,4是(9-5)。
分子:numerator。
分母denominator。
商quotient。
余数remainder。
(翻译不是很准确,表达下意思就行了,呵呵)。
numerator=quotient*denominator+remainder.那么numerator/ denominat or分频就可以通过remainder个(quotient+1)分频和(denominator -remaind er)个quotient分频组成。
还是以68/9为例。
我们得出了5个8分频和4个7分频可以实现这个分数分频,但这5个8分频和4个7分频怎么放置呢?先放5个8分频,再放4个7分频,这样绝对是不行的。
为了均匀的放置这两种频率,我从小数分频中学到一种方法。
找个临时变量temp(程序中用的是sum)。
初始化为0。
每次分频完让它加上余数,判断是否大于分母,如果小于分母,择输出7分频,否则输出8分频,并且将这个值减去分母(让它小于分母)。
这样temp值就变成了5 1 6 2 7 3 8 4 0 5……分频值就成了7 8 7 8 7 8 7 8 8 7 8 7 8 7 8 7 8 8……可以统计一下7分频和8分频的比例就正好是4:5,这样就实现了分数分频。
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.偶分频模块设计偶分频意思是时钟模块设计最为简单。
首先得到分频系数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奇数分频:以七分频为例
FPGA菜鸟,刚做了个简单Verilog奇数分频实验,附上代码只需修改两个参数即可得到需要的奇数分频:
/* 功能:完成时钟n=7奇数分频
clk : 时钟
reset :复位信号
Clkdivout :分频时钟输出
Cntposege :上升沿计数
Cntnegege :下降沿计数
clkpos :上升沿计数产生时钟
clkneg :下降沿计数产生时钟
基本思路:cntposege 时钟上升沿到来计数到n=7,前a=3个周期为低电
平,后b=4个周期为高电平;
cntnegege 时钟下降沿到来计数到n=7,前a=3个周期为低电
平,后b=4个周期为高电平;
最后两个时钟信号相与即得n=7分频。
a,b取值:a+b=n;b-a=1;
*/
module clkdiv (clk, reset, clkdivout);
input clk; //时钟
input reset; //复位信号
output clkdivout; //分频时钟输出
wire clkdivout;
parameter N = 3'd7; //修改这两个参数即可得想要的奇数分频
parameter a = 3'd3; //a、b取值:a+b=N;b-a=1;
//parameter b = 3'd4;
reg [2:0] cntposege; //上升沿计数7个周期
reg [2:0] cntnegege; //下降沿计数7个周期
//上升沿计数7个周期
always @ (posedge clk or negedge reset) begin
if (!reset)
cntposege <= 3'd0;
else if (cntposege == N - 1'b1)
//cntposege等于6,下一个时钟到来时执行操作,即7个周期,以下同理cntposege <= 3'd0;
else
cntposege <= cntposege + 1'b1;
end
//下降沿计数7个周期
always @ (negedge clk or negedge reset) begin if (!reset)
cntnegege <= 3'd0;
else if (cntnegege == N - 1'b1)
cntnegege <= 3'd0;
else
cntnegege <= cntnegege + 1'b1;
end
reg clkpos; //上升沿计数得到的占空比4:7的时钟reg clkneg; //下降沿计数得到的占空比4:7的时钟
//上升沿计数得到的占空比4:7的时钟
always @ (posedge clk or negedge reset) begin if (!reset)
clkpos <= 1'b0;
else if (cntposege <= a - 1'b1)
clkpos <= 1'b0;
else
clkpos <= 1'b1;
end
//下降沿计数得到的占空比4:7的时钟
always @ (negedge clk or negedge reset) begin if (!reset)
clkneg <= 1'b0;
else if (cntposege <= a - 1'b1)
clkneg <= 1'b0;
else
clkneg <= 1'b1;
end
assign clkdivout = clkpos & clkneg;
//两个时钟相与得到占空比50%的七分频时钟输出
endmodule
Testbench测试代码比较简单:
`timescale 1 ns/ 1 ps module clkdiv_vlg_tst();
reg clk;
reg reset;
wire clkdivout;
parameter cycle = 20; parameter rst_time=3;
clkdiv i1 (
.clk(clk),
.clkdivout(clkdivout),
.reset(reset)
);
initial begin
clk = 0;
forever
#(cycle/2)
clk = ~clk;
end
initial begin
reset=1;
#2;
reset=0;
#(cycle*rst_time);
reset=1;
end
Endmodule
Modelsim RTL级仿真波形:
观测波形可以看到分频信号clkdivout准确7分频,而clkpos和clkneg两个占空比4:7信号相与后得到50%占空比分频时钟。
代码较为粗糙未经优化,望同志们继续努力,欢迎交流FPGA学习心得。
panthera_chen@
2015/9/24。