制作时钟分频器

时间:2013-10-31 13:47:58

标签: vhdl clock

我在如何制作时钟分频器时发现了这段代码。我对如何使用计数器制作分频器有一个大致的了解,但我不确定这个代码在做什么以及它为什么这样做。

entity clkdiv is
    Port ( mclk : in  STD_LOGIC;
           clr : in  STD_LOGIC;
           clk190 : out  STD_LOGIC;
           clk48 : out  STD_LOGIC);
end clkdiv;

architecture clkdiv of clkdiv is
signal q: std_logic_vector(23 downto 0);
begin
    --clock divider
    process(mclk,clr)
    begin   
        if clr ='1' then
            q <= X"000000";
        elsif mclk'event and mclk = '1' then
            q <= q+1;
        end if;
    end process;
    clk48 <= q(19);
    clk190 <= q(17);

end clkdiv;

我知道这个例子是基于2板,输入时钟是50MHz。该代码应该产生48hz时钟信号和190hz时钟信号。

2 个答案:

答案 0 :(得分:2)

50MHz / 48Hz = 104166.7,所以你无法准确到达那里。

如果您使用的计数器在50MHz时计数高达104167,您将获得接近48 Hz的单脉冲(47.9999846 Hz - 这对于大多数用途来说可能已经足够了)。

不要将计数器的输出用作时钟,当它作为时钟启用时使用单个脉冲 - 这样可以获得更好的结果。整个设计中的单个时钟与启用的部分是实现它的方法。

答案 1 :(得分:1)

上述代码的作用仅仅是它创建了一个包含24位计数器q的VHDL模块,该计数器在主时钟mclk的每个上升沿计数。然后通过将此计数器的不同位直接用作时钟信号,它导出clk190clk48

例如,当mclk为50 MHz时,lsb(q(0))将有效地以25 MHz运行。 mclk的每个上升沿为q(0)提供一条边 - 同样向上,因此每个后续位的运行频率都是前一位的一半。

例如:

mclk = 50 MHz
q(0) = mclk / 2 = 25 Mhz
q(1) = q(0) / 2 = mclk / 4 = 12.5 MHz
...
q(n) = mclk / (2^(n+1))

您的派生时钟将取决于您的主时钟,并且是:

q(17) = 50 MHz / 262144 = 191 Hz
q(19) = 50 MHz / 1048576 = 48 Hz

然而 - 生成这样的时钟往往是错误的做法!

看起来好像你得到了很好的同步时钟,但实际上,它们相互之间会稍微偏斜,因为你正在生成所谓的门控时钟(许多工具甚至会警告你这个)。

此处有更多信息,包括使用时钟启用相同功能(但更好)的方法:VHDL: creating a very slow clock pulse based on a very fast clock