VHDL和时钟50MHz至25Mhz

VHDL和时钟50MHz至25Mhz,vhdl,quartus,Vhdl,Quartus,我正在用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; ARCHIT

我正在用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;
这可能吗?运算符的顺序不仅与时间和频率有关,例如:x=50000000=输入频率,z=25000000=输出频率。我认为这个问题可以用纯数学来解决,但它是用于VHDL应用的,因此这篇文章。process语句使数学更加混乱


请不要等待,这是完全不现实的定义。

要从50 MHz输入时钟生成25 MHz时钟,必须将输入时钟除以2。这可以通过在输入时钟的每个上升沿进行切换的单个触发器来实现

如果
clk\u set
为0,则可以执行此操作。
此外,您的设计支持两倍的分频器。

要从50 MHz输入时钟生成25 MHz时钟,必须将输入时钟除以2。这可以通过在输入时钟的每个上升沿进行切换的单个触发器来实现

如果
clk\u set
为0,则可以执行此操作。
此外,您的设计支持两倍的除法器。

使用逻辑生成时钟是一种非常糟糕且容易出错的习惯(门控时钟)。以这种方式生成的“时钟”信号实际上只是一个数据信号,它驱动的同步元素具有未定义的路由延迟偏差。请参考供应商的FPGA数据表或用户指南,查找可用的时钟生成组件(PLL、MMCM、DCM等)并使用它们。这可能会为您省去很多麻烦。

用逻辑生成时钟是一种非常糟糕且容易出错的习惯(门控时钟)。以这种方式生成的“时钟”信号实际上只是一个数据信号,它驱动的同步元素具有未定义的路由延迟偏差。请参考供应商的FPGA数据表或用户指南,查找可用的时钟生成组件(PLL、MMCM、DCM等)并使用它们。这可能会帮你省下一大堆麻烦。

你的原始设计似乎有点过度使用了所有这些变量等。我同意之前的海报,你基本上只是在寻找一个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;
过程(时钟、rst)
开始
如果rst='1',则

clk_out您的原始设计似乎有点过度使用了所有这些变量等。我同意之前的海报,您基本上只是在寻找一个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;
过程(时钟、rst)
开始
如果rst='1',则

clk_out除非您计划在硬件运行时更改时钟频率,否则请设置
clk_in_set,clk_out_set
常量,并从中导出
clk_set
。更好的是,可以使用物理单位使计算更加明显。相关:您好,这接近我想要做的,有一个可以定义显示器滚动速度的输入。输入值为频率。我认为这是一个很容易从50mhz的输入时钟计算出来的方程。但是没有,计数器需要额外的时间,这使得计算更加令人沮丧。我添加的第二个参数使事情变得更简单。但从来没有到过那里!:(除非您计划在硬件运行时更改时钟频率,否则请将
clk_in_set,clk_out_set
设置为常量,并将它们作为另一个常量导出
clk_set
。更好的是,您可以使用物理单位使计算更加明显。相关:您好,这接近我想要做的,有一个应该定义显示器的滚动速度。输入值是频率。我认为这是一个很容易从50mhz的输入时钟中计算出来的公式。但是没有,计数器需要额外的周期,这使得计算更加令人沮丧。我添加的第二个参数使事情变得更容易。但从未实现过!:(还考虑使用25MHz时钟。为了节省生成的时钟树的数量,您可以生成一个时钟使能,在50MHz时钟上切换,并使其以25MHz的速率实现逻辑。还考虑使用25MHz时钟。为了节省生成的时钟树的数量,您可以只使用基因。为切换50MHz时钟的时钟启用速率,并使用该速率以25MHz的速率启用逻辑。时钟分频器是否需要重置?如果不重置,clk_out将在模拟中为“x”。因此not(clk_out)仍为“x”。因此没有时钟输出;)在硅上,理论上不需要重置。但是知道信号的相位并总是有一个干净的重置开始是很好的。更不用说ASIC的可测试性问题。当然FPGA是不同的品种。在那些家伙中,你可以跳过重置,只使用声明中的信号的初始值?如:信号clk_out:std_logic:='0';是的,这是重置理论,但您正在设计一个T-FF。此重置增加了FPGA和ASIC上的重置树。不需要重置时钟除法器。设计中的所有寄存器都应该有一个默认值。如果利用率不是非常高,我不知道重置/时钟树是否真的有问题。很可能会出现clock路由在FPGA中没有使用(尽管我不是FPGA专家)。对于ASIC,公司/供应商可能有设计指南禁止使用非重置逻辑。当然,在ASIC中,重置是唯一的初始值;)重置树可能会影响时序和设计设计。这可以通过使用时钟网络进行重置来改善。时钟、重置和时钟启用形成一个控制集。更多重置通常意味着更多的控制集,这可能会阻碍切片压缩。ASIC中也可能有初始值。FFs可以设计为翻转到spe通电后的cific值。时钟分频器需要重置吗?不重置cl