Vhdl 制作时钟分频器

Vhdl 制作时钟分频器,vhdl,clock,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 clkd

我在如何制作时钟分频器中找到了这段代码。我对如何使用计数器生成除法器有一个大致的了解,但我不确定这段代码在做什么以及为什么要这样做

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;
实体clkdiv是
端口(mclk:标准逻辑中;
clr:标准逻辑中;
clk190:输出标准逻辑;
clk48:输出标准逻辑);
结束clkdiv;
clkdiv的体系结构clkdiv是
信号q:std_逻辑_向量(23向下至0);
开始
--时钟分频器
进程(mclk、clr)
开始
如果clr='1',则

q上述代码的作用很简单,它创建了一个VHDL模块,其中包含一个24位计数器
q
,该计数器从主时钟
mclk
的每个上升沿开始计数。然后,它通过直接使用此计数器的不同位作为时钟信号来导出
clk190
clk48

例如,在50 MHz下使用
mclk
,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
然而,这样生成时钟通常是错误的

看起来好像你得到了很好的同步时钟,但实际上,它们之间的比较会有点偏差,因为你正在生成所谓的门控时钟(许多工具甚至会警告你这一点)


关于这方面的更多信息,包括一种使用时钟启用做同样事情(但更好)的方法:

50MHz/48Hz=104166.7,因此您无法准确到达那里

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


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

因此,如果我使用的是100MHz时钟,我如何生成这些频率(190hz、48hz)有那么难看到吗?;)我之所以问这个问题,是因为我确实把位移到了左边,信号不好,这是我尝试的第一件事,我想我做错了什么,但是谢谢你的例子,你说的“信号不好”是什么意思?有多快?正如Martin在他的回答中提到的,你不能精确地命中那些频率……你的意思是像这样的“clkdiv的架构clkdiv是信号计数5Hz:std_逻辑_向量(从27下降到0):=(其他=>“0”);常数clk5HzEndVal:STD_逻辑_向量(27向下至0):=X“2FAF080”;begin——时钟除法器进程(mclk,clr)开始,如果(clr='1'),那么Count5Hz我不能将该代码理解为注释,但我建议使用整数类型,因为它比std_逻辑_向量更容易处理这类事情。你也可以使用编译器来计算所需频率和已知时钟频率的最终值,而不仅仅是难以检查的硬编码常量。如果使用xilinx中的ip核,是的,我不知道如何使用。不,不需要ip核,只需使用
integer
类型编写VHDL