首页 > 编程知识 正文

verilog实现九分频,verilog时钟分频设计

时间:2023-05-05 04:39:15 阅读:152968 作者:1426

FPGA时钟分频的几种方法1 .定义分频参数2 .直接计算2.CNT计数值3 .奇数分频4.PLL5 .奇偶分频通用程序

1 .定义分频参数localparam CLK_DIVIDE=4'd10; //时钟分频因子reg [ 3:0] clk_cnt; //时钟分频计数器reg dri_clk; //数码管驱动时钟always @ (posedgeclkornegedgerst _ n ) begin if (! rst_n ) begin clk_cnt=4'd0; dri_clk=1'b1; endelse if (clk _ CNT==clk _ divide/2-1 ' D1 ) begin clk_cnt=4'd0; dri_clk=~dri_clk; endelsebeginclk _ CNT=clk _ cn t1 ' B1; dri_clk=dri_clk; 直接计算endend2.CNT计数值reg [11:0] div_cnt; //分频计数器reg div_clk; //分频时钟分频,50MHz/(2*(3124 ) ) )=8khz,t=0.125 ms always @ (posedge sys _ clkornegedgesys _ rst _ n ) begin if sys_rst_n(Begindiv_CNT=12'D0; div_clk=1'b0; endelseif(div_CNT==12'd3124 ) begin div_cnt=12'd0; div_clk=~div_clk; end else div_cnt=div_cnt 12'b1; 结束

cnt的计算是将sysclk除以所需的频率,得到cnt_total,将cnt_total除以2,减去1即为cnt的值。

assign clk _ divide=(clk _ freq/I2C _ freq )2'd3; 用于驱动生成//模块驱动时钟分频系数//I2c的SCL的4倍频率的驱动时钟I2C的操作always @ (posedgeclkornegedgerst _ n ) beginif(rst_n==1) endelse if (clk _ CNT==clk _ divide-1 ' D1 ) begin clk_cnt=10'd0; dri_clk=~dri_clk; end else clk_cnt=clk_cnt 1'b1; end向右移位3位。 在这个程序中,对于I2C_FREQ时钟是频率*8,但是因为上述除以2的操作很少,所以最后是I2C_FREQ的4倍。 因为我们操作的是时钟需要反过来计数的值,与我们平时接触到的直接改变数字大小相反

3 .奇数分频上面的1和2适用于偶数分频,奇数分频采用以下方法

//7分频、奇数分频都可以相同。 只需要改变div1和div2的参数。 //div1是奇数分频除以2的整数部分,div2是分频系数减去1后的值。 ) )上升延迟和下降延迟分别产生不同的波形,最后通过叠加产生奇数分频。 moduleodd_div(clk,clk1x,rst,clk1xpose,clk1xnege,coutpose,coutnege ); 输入时钟; 输入rst; output clk1x; 输出clk1xpose; 输出clk 1x nege; 输出[ 2:0 ] cout pose; 输出[ 2:0 ] cout nege; reg clk1xpose; reg clk1xnege; reg[2:0] coutpose; reg[2:0] coutnege; parameter div1=3,div2=6; //div1=7/2,div2=7-1assign clk 1x=clk1xpose|clk 1x nege; Always@(PosedgeclkorNegedgerst ) begin if (! rst ) clk1xpose=0; elseif(coutpose==div1) clk1xpose=~clk1xpose; elseif(coutpose==div2) clk1xpose=~clk1xpose; else clk1xpose=clk1xpose; end always @ (negedgeclkornegedgerst ) begin if (! rst ) clk1xnege=0; elseif(coutnege==div1) clk1xnege=~clk1xnege; elseif(coutnege==div2) clk1xnege=~clk1xnege; else clk1xnege=clk1xnege; end always @ (posedgeclkornegedgerst ) begin if (! rst ) coutpose=0; elseif(coutposediv2) coutpose=coutpose 1; else coutpose=0; end always @ (negedgeclkornegedgerst ) begin if (! rst ) coutnege=0; elseif(coutnegediv2) coutnege=coutnege 1; else coutnege=0; 由于end endmodule采用计数方法进行分频,所以理论上看起来没有问题,但在实际应用中,时钟偏移有点严重,所以最好使用PLL,但如果对时钟要求不太准确,也可以使用计数方法。 下图为程序的时间序列模拟波形。

4.PLL 5.奇偶校验分频通用程序//N是分频系数,WIDTH是可以表示n的位数module clk _ divide # (parameter width=3,parameterN=5) )//inpth regclk_p,clk_n; assignclkout=(n==1)? CLK:(n[0]? (clk_pclk_n ) :clk_p; //sequentiallogicstylealways @ (posedge clk ) beginif (! rst_n ) cnt_p=0; ELSEif(CNT_p==(n-1 ) ) cnt_p=0; else cnt_p=cnt_p 1; endalways@(negedgeclk ) beginif (! rst_n ) cnt_n=0; ELSEif(CNT_n==(n-1 ) ) cnt_n=0; else cnt_n=cnt_n 1; endalways@(Posedgeclk ) beginif (! rst_n ) clk_p=0; ELSEif(CNT_p ) N1 ) ) clk_p=0; else clk_p=1; endalways@(negedgeclk ) beginif (! rst_n ) clk_n=0; ELSEif(CNT_n ) N1 ) ) clk_n=0; else clk_n=1; 结束模块

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。