分享:任意奇数分频(50%占空比) verilog 代码

2020-02-28 18:32发布

网上这样的帖子很多,各种写法,但是发现一个问题,产生的时钟分频信号与原始信号并不同相。我自己写了个,只需要修改一下两个参数,就可以产生任意分频,而且与原始时钟同相,占空比50% 。也欢迎 大家提出问题。

以3 分频为例:
module clk_dive(clk,rst,clk_out);
input clk; // 输入时钟
input rst;
output clk_out;// 分频后的输出时钟
reg clk_3; //  中间时钟
reg clk_4;// 中间时钟
reg [2:0]cnt1; // clk_3的计数器
reg [2:0]cnt2;// clk_4的计数器

assign clk_out=clk_3|clk_4; //  两个中间时钟信号或后 为最终输出的时钟信号

always @(posedge clk ) //  产生中间时钟clk_3
if(!rst)
begin
clk_3<=1'b0;
cnt1<=3'd0;
end
else  if(cnt1<1)  //  3分频为<1 , 5分频改为<2 ,7分频改为<3,9分频 改为<4    依次类推!
  begin
  clk_3<=1'b1;
  cnt1<=cnt1+1'b1;
  end
else if (cnt1==3)  //  3 分频==3 , 5分频改为==5 ,7分频 改为==7   几分频就改为==几!
   begin
   clk_3<=1;
   cnt1<=1;
   end
else begin
  cnt1<=cnt1+1'b1;
  clk_3<=1'b0;
   end
     
     
always @(negedge clk )  //  产生中间时钟clk_4

if(!rst)
begin
clk_4<=1'b0;
cnt2<=3'd0;
end
else  if(cnt2<1)//  3分频为<1 , 5分频改为<2 ,7分频改为<3,9分频 改为<4    依次类推!
  begin
  clk_4<=1'b1;
  cnt2<=cnt2+1'b1;
  end
else if (cnt2==3)  //  3 分频==3 , 5分频改为==5 ,7分频 改为==7   几分频就改为==几!
   begin
   clk_4<=1;
   cnt2<=1;
   end
else begin
  cnt2<=cnt2+1'b1;
  clk_4<=1'b0;
   end
endmodule

总结下:1. 占空比50%的奇数分频的 思想就是利用原始时钟的上升沿和下降沿 分别产生两个时钟 。这两个时钟的占空比有规律(3分频 为1:2  ;5分频 为 2:3  7分频 为3:4) 由于是由不同触发沿产生,所以这两个中间时钟 交错半个时钟周期。相或后,就得到占空比为 50% 的分频信号。 只需要改动两个参数   第二个参数很好记,第一个参数也是有规律的。
              2.不过目前还没有使用过自己写的分频时钟,因为有PLL/DLL,最好用PLL/DLL ! 不过话说这个奇数分频 是经常考察的东西。

5分频.jpg

3分频.jpg

7分频.jpg


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
ifpga
1楼-- · 2020-02-28 22:13
jakfens
2楼-- · 2020-02-29 03:05
:victory:
jahnson066
3楼-- · 2020-02-29 03:16
这个不错,菜鸟学习一下,哈哈
触觉的爱
4楼-- · 2020-02-29 09:05
 精彩回答 2  元偷偷看……
GoldSunMonkey
5楼-- · 2020-02-29 10:33
不错,感谢啦
Death格雷尔
6楼-- · 2020-02-29 14:12
请问 占空比 50%的 偶分频 改动数字 能实现吗 要怎么改啊

这个程序对么 是占空比50%的奇分频么   谢谢
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fpq is
port(
     clk:in std_logic;
     clkoutut std_logic);
end entity fpq;
architecture one of fqp is
signal cnt:std_logic_vector(1 downto 0);
begin
process(clk)
veriable cnt:integer range 0 to 3;
begin
if rising_edge(clk) then
  if cnt=3
    then cnt :=0;
    else cnt :=cnt+1;
end if;
if cnt< 2
  then clkout< ='0';
else clkout<='1';
end if;
end if;
end process;
end architecture one;

一周热门 更多>