用VHDL语言创建分频器

用VHDL语言创建分频器,vhdl,intel-fpga,Vhdl,Intel Fpga,主要编辑: 在阅读威尔·迪恩的评论后,问题得到了解决。原来的问题在修订后的守则下: -- REVISED CODE (NOW WORKS) LIBRARY ieee; USE ieee.std_logic_1164.ALL; entity CLOCK_DIVIDER is port( reset : in std_logic; clk : in std_logic; half_clk : out std_logic

主要编辑:

在阅读威尔·迪恩的评论后,问题得到了解决。原来的问题在修订后的守则下:

-- REVISED CODE (NOW WORKS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity CLOCK_DIVIDER is
    port(
        reset   :   in std_logic;
        clk :   in std_logic;
        half_clk    :   out std_logic
        );
end CLOCK_DIVIDER;


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;

begin

    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                tick <= '1';
            elsif tick = '1' then
                tick <= '0';
            end if;
        end if;
    end process;

    process(tick)
    begin
        half_clk <= tick;
    end process

end CLOCK_DIVIDER;
——修订后的代码(现在生效)
图书馆ieee;
使用ieee.std_logic_1164.ALL;
实体时钟分频器为
港口(
复位:在标准逻辑中;
clk:标准逻辑中;
半时钟:输出标准逻辑
);
端时钟分频器;
时钟分频器的体系结构时钟分频器是
信号勾号:标准逻辑;
开始
过程(时钟、复位)
开始
如果重置='1',则
勾选如果半时钟用作启用时钟而不是真正的时钟,请忽略此建议

如果这是针对FPGA目标,并且“half_clk”确实被用作时钟(例如,转到DFF上的时钟引脚,而不是启用引脚)。。。不要这样做

使用通用FPGA逻辑/fabic创建派生时钟将导致构建工具出现问题,并最终导致构建失败(无法满足时间要求),或构建行为不符合预期,因为约束未正确传递到所有时钟网络

相反,使用内置在FPGA结构中的时钟管理块,尤其是用于此目的。在Xilinx部件中,这些部件被称为数字时钟管理器(DCM)或混合模式时钟管理器(MMCM)。我不确定等效的Altera组件是什么。阅读文档以确定应用程序的最佳用途。

如果halfclk用作启用时钟而不是真正的时钟,请忽略此建议

如果这是针对FPGA目标,并且“half_clk”确实被用作时钟(例如,转到DFF上的时钟引脚,而不是启用引脚)。。。不要这样做

使用通用FPGA逻辑/fabic创建派生时钟将导致构建工具出现问题,并最终导致构建失败(无法满足时间要求),或构建行为不符合预期,因为约束未正确传递到所有时钟网络


相反,使用内置在FPGA结构中的时钟管理块,尤其是用于此目的。在Xilinx部件中,这些部件被称为数字时钟管理器(DCM)或混合模式时钟管理器(MMCM)。我不确定等效的Altera组件是什么。阅读文档以确定应用程序的最佳用途。

您确定要在启动时重置吗?按照定义勾选条件的方式,如果勾选不是零或一(即:可能是U、Z、X等),则不会发生任何事情

我通常建议使用条件表达式覆盖所有情况,即:

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        else 
            half_clk <= '1';
            tick <= '0';
        end if;
如果勾号为“0”,则

half_clk您确定要在启动时重置吗?按照定义勾选条件的方式,如果勾选不是零或一(即:可能是U、Z、X等),则不会发生任何事情

我通常建议使用条件表达式覆盖所有情况,即:

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        else 
            half_clk <= '1';
            tick <= '0';
        end if;
如果勾号为“0”,则

half_clk基于您修订的代码,我对架构进行了以下修改:

-- REVISED CODE (NOW WORKS) and simplified and synthesisable
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
    signal tick : std_logic;
begin
    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif rising_edge(clk) then -- use of rising_edge() is the correct idiom these days
            tick <= not tick;
        end if;
    end process;

    half_clk <= tick;
end CLOCK_DIVIDER;
——修订后的代码(现在可以使用)并简化和合成
时钟分频器的体系结构时钟分频器是
信号勾号:标准逻辑;
开始
过程(时钟、复位)
开始
如果重置='1',则

根据修改后的代码,我对架构进行了如下修改:

-- REVISED CODE (NOW WORKS) and simplified and synthesisable
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
    signal tick : std_logic;
begin
    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif rising_edge(clk) then -- use of rising_edge() is the correct idiom these days
            tick <= not tick;
        end if;
    end process;

    half_clk <= tick;
end CLOCK_DIVIDER;
——修订后的代码(现在可以使用)并简化和合成
时钟分频器的体系结构时钟分频器是
信号勾号:标准逻辑;
开始
过程(时钟、复位)
开始
如果重置='1',则

勾选一个简单的计数器就可以做到这一点(正确的方法当然是DCM):

信号cnt:std_逻辑_向量(3到0);
...

clk_div_2一个简单的计数器就可以实现这一点(正确的方法当然是DCM):

信号cnt:std_逻辑_向量(3到0);
...

clk_div_2我是一个Verilog人,而不是VHDL,但我不明白为什么需要两个寄存器来进行除法运算。除了“滴答”的(延迟)反转之外,“半时钟”是什么?我不需要两个寄存器,我也不知道为什么它会推断出两个寄存器。half_clck是逻辑块的输出,而tick是内部信号-如果我将tick作为输出,它将无法读取,如果我将half_clk作为内部信号,我将无法输出。然而:它现在可以工作了——记住你说的,我从if语句中删除了half_-clk,并创建了一个单独的进程,它只在任何时候将tick的值分配给half_-clk,现在它可以工作了。我是一个Verilog人,而不是VHDL,但我不明白为什么需要两个寄存器来进行除法。除了“滴答”的(延迟)反转之外,“半时钟”是什么?我不需要两个寄存器,我也不知道为什么它会推断出两个寄存器。half_clck是逻辑块的输出,而tick是内部信号-如果我将tick作为输出,它将无法读取,如果我将half_clk作为内部信号,我将无法输出。然而:它现在可以工作了——记住你说的,我从if语句中删除了half_-clk,并创建了一个单独的进程,该进程始终只将tick的值分配给half_-clk,现在它可以工作了。你会惊讶地知道,这实际上是用户指南为我正在使用的CPLD推荐的方法。时钟是一个外部晶体,半时钟将被路由到一个内置的全球时钟网络。好的,太好了。我想向你和其他人指出,我看到这样的事情经常发生(当它不是推荐的做法时),并且它会给我带来很多痛苦。你会惊讶地知道,这实际上是用户指南为我正在使用的CPLD推荐的方法。时钟是一个外部晶体,半时钟将被路由到一个内置的全球时钟网络。好的,太好了。想指出这一点,你和其他人,我看到这样的事情发生很多(当它不是推荐的做法),它会导致很多痛苦在路上。使用ELSIF是根深蒂固的,我甚至没有考虑这一点,但它是健全的建议-我一定要它初始化。
    process(tick)
    begin
        half_clk <= tick;
    end process
signal cnt : std_logic_vector(3 downto 0);

...

clk_div_2  <= cnt(0);
clk_div_4  <= cnt(1);
clk_div_8  <= cnt(2);
clk_div_16 <= cnt(3);

...

process(clk)
 if clk'event and clk = '1' then
  cnt <= cnt + 1;
 end if;
end process;