主要编辑:
阅读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的每个上升沿都会发生变化。
谢谢,Will Dean:)
==== ==== ==== ==== ====
以下原始问题:
==== ==== ==== ==== ====
我需要一个简单的时钟分频器(只是除以2)而不是使用模板,我想我会尝试自己编写一个以继续训练。
不幸的是,合成的逻辑块似乎不起作用 - 我按顺序呈现逻辑块和代码(我认为应该工作)。
logic block http://img808.imageshack.us/img808/3333/unledly.png
我真正想知道的是魔鬼是如何使用“滴答”DFF - 它显然是从多路复用选择器输入的......是的。是的。
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;
我确信代码中的错误是显而易见的,但我一直盯着自己试图找到它。
答案 0 :(得分:3)
如果halfclk用作启用而不是真正的时钟,请忽略此建议......
如果这是针对FPGA目标而且“half_clk”实际上被用作时钟(例如,转到DFF上的时钟引脚,而不是使能引脚)...... 不要这样做< / em>的
使用通用FPGA逻辑/ fabic创建派生时钟将导致构建工具出现问题,最终可能导致构建失败(无法满足时序),或构建因行为不正确而无法正常传递的构建所有时钟网络。
而是使用内置于FPGA架构中的时钟管理块,尤其是为此目的。在Xilinx器件领域,这些器件称为数字时钟管理器(DCM)或混合模式时钟管理器(MMCM)。我不确定等效的Altera组件是什么。阅读文档以确定最适合您的应用程序。
答案 1 :(得分: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
的两个边缘都有一个触发器。
这似乎可以实现您想要的波形摆动,但不会合成。它还会为输出增加额外的增量延迟,如果您将其用作“即时”时钟,则可能会或可能不会导致问题。正如其他人所评论的那样,在大多数架构中,这不是一个好的计划(但有些人认为这是“正确的方式”)。
答案 2 :(得分:0)
你确定你在启动时重置了吗?你定义了tick的条件的方式,如果tick不是零或一个(即:它可能是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;
答案 3 :(得分: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;