1

主要编辑:

阅读 Will Dean 的评论后问题得到解决。原始问题在修改后的代码下方:

-- 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;

修改后的代码的综合逻辑块是一个异步复位 DFF,它以 half_clk 作为输出,反相 half_clk 作为输入,这意味着 half_clk 的值在 clk 的每个上升沿发生变化。

谢谢,威尔迪恩:)

==== ==== ==== ==== ====

下面的原始问题:

==== ==== ==== ==== ====

我需要一个简单的时钟分频器(只是除以二),而不是使用模板,我想我会尝试自己写一个来继续训练。

不幸的是,合成的逻辑块似乎不起作用——我按顺序展示了逻辑块和代码(我真的认为应该起作用)。

逻辑块 http://img808.imageshack.us/img808/3333/unledly.png

我真正想知道的是,“tick”DFF 到底是怎么回事——它显然是从 mux-selector 获取输入的……是的。

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
            half_clk <= '0';
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                half_clk <= '0';
                tick <= '1';
            elsif tick = '1' then
                half_clk <= '1';
                tick <= '0';
            end if;
        end if;
    end process;
end CLOCK_DIVIDER;

我确信代码中的错误很明显,但我一直盯着自己盲目地试图找到它。

4

4 回答 4

3

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

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

使用通用 FPGA 逻辑/fabic 创建派生时钟将导致构建工具出现问题,并最终导致构建失败(不符合时序),或者由于约束未正确传递到所有时钟网络而无法按预期运行的构建.

而是使用内置于 FPGA 架构中的时钟管理模块,特别是为此目的。在 Xilinx 器件领域,这些器件称为数字时钟管理器 (DCM) 或混合模式时钟管理器 (MMCM)。我不确定等效的 Altera 组件是什么。阅读文档以确定最适合您的应用程序的用途。

于 2011-06-07T12:02:03.657 回答
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;

我已删除此过程并替换为并发分配:

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

因为这要求的是在tick.

就波形以您想要的方式摆动而言,这似乎可以达到您想要的效果,但不会合成。它还为输出增加了额外的增量延迟,如果您将其用作“未来”的时钟,这可能会或可能不会导致问题。正如其他人所评论的那样,无论如何这在大多数架构中都不是一个好计划(但对于某些人来说这是“正确的方式”)。

于 2011-06-10T09:32:09.470 回答
0

你确定你在启动时重置?您定义刻度条件的方式,如果刻度不是零或一(即:它可能是 U、Z、X 等),则不会发生任何事情。

我通常建议用您的条件表达式涵盖所有情况,即:

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        else 
            half_clk <= '1';
            tick <= '0';
        end if;

或者

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        elsif tick = '1' then
            half_clk <= '1';
            tick <= '0';
        else
            -- Throw error or something here
        end if;
于 2011-06-07T12:15:56.550 回答
0

一个简单的计数器就可以解决问题(正确的方法当然是 DCM):

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;
于 2011-11-17T14:42:15.700 回答