我在VHDL中制作时钟分频器。我的输入时钟频率为50Mhz,我开始使用以下内容输出25Mhz:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY CLK25 IS
PORT(clk_in,rst : IN std_logic;
clk_out : OUT std_logic);
END ENTITY CLK25;
ARCHITECTURE behav OF CLK25 IS
SIGNAL clk_in_set : integer RANGE 1000000000 DOWNTO 0 := 50000000;
SIGNAL clk_out_set : integer RANGE 1000000000 DOWNTO 0 := 25000000;
BEGIN
CLK1 : PROCESS (clk_in,rst) IS
VARIABLE cnt : unsigned(31 DOWNTO 0);
VARIABLE clk_tmp : std_logic;
VARIABLE clk_set : unsigned(31 DOWNTO 0);
BEGIN
clk_set := to_unsigned(clk_in_set/(clk_out_set*4),32); --< x4 to account for process time delay
IF (rst = '0') THEN
cnt := (OTHERS => '0');
clk_tmp := '0';
ELSIF rising_edge(clk_in) THEN
IF cnt = clk_set THEN
clk_tmp := not(clk_tmp);
cnt := (OTHERS => '0');
ELSE cnt := cnt + 1;
END IF;
END IF;
clk_out <= clk_tmp;
END PROCESS CLK1;
END ARCHITECTURE behav;
在模拟和b测试中它可以正常工作。 - &gt;虽然我知道通常的数学运算,但请不要堆叠&lt; - VHDL guru浮点请! 无论如何我想整理模型并制作一个可由用户定义的时钟,输入了2个参数(x和(Z#Y))
(clk_in_set(X)/(clk_out_set(Z) # Y )
这可能吗?运算符的顺序与时间和频率的关系并不重要,例如:x = 50000000 =输入频率,z = 25000000 =输出频率。我认为这个问题可以通过纯数学解决,但它适用于VHDL应用,因此是帖子。流程陈述使数学更加混乱。
没有等待声明,请定义是完全不现实的。
答案 0 :(得分:3)
使用逻辑生成时钟是一种非常糟糕且容易出错的习惯(门控时钟)。时钟&#39;你产生这种方式的信号确实只是一个数据信号,它正在驱动的同步元件有一个未定义的路由延迟偏差。请参考供应商的FPGA数据表或用户指南,查看可用的时钟生成组件(PLL,MMCM,DCM,...)并使用它们。这可能会给你带来很多麻烦。
答案 1 :(得分:2)
您的原始设计似乎对所有这些变量有点过分等我同意早期的海报,您基本上只是在寻找2的时钟分频器。
只是时钟分频器的一个简单示例:
proces(clk, rst)
begin
if rst = '1' then
clk_out <= '0';
elsif rising_edge(clk) then
clk_out <= not(clk_out);
end if;
end process;
但正如所说,这可能不适合物理实现。您可能希望从库中实例化一个触发器,以便获得一个硬编码实例端口(clk_out),您可以在其中创建新的时钟源。这样你就可以在真正的硅片上获得50/50的时钟周期。
通过级联这些分频器可以实现除以4,8等。或者planB是从0..N创建一个简单的计数器,并且每当计数达到N时,只需要clk_out.N将设置时钟速率。这也使您可以获得更灵活的时钟速率,但并非所有时钟速率都是50/50!但是在这个方案中再次使用硬编码的触发器非常重要,这样你就可以使用一个可靠的实例名称作为时钟根。
答案 2 :(得分:0)
要从50 MHz输入时钟生成25 MHz时钟,您必须将输入时钟除以2。这可以通过在输入时钟的每个上升沿切换的单个触发器来实现。
如果clk_set
为0,则设计完成此操作。
此外,您的设计支持两倍的倍数的分频器。