我最近一直在为我的系统设计一个时钟分频器 - 我重新设计了它,现在有一个异步复位,它会为系统的其余部分产生同步复位。为此,我按照answers & advice跟我自己的问题并使用时钟使能来切换输出,从而产生占空比为50%的时钟(这是所需的)。
但是,这会在生成
PhysDesignRules:372 - Gated clock. Clock net ... is sourced by a combinatorial pin. This is not good design practice. Use the CE pin to control the loading of data into the flip-flop.
关于使用时钟使能,请参阅此question,但在创建时钟使能时出现是正确的,因为我需要一个方波(而不仅仅是1 / 200MHz脉冲),因此使用能够切换另一个信号,在question中显示这是一个有意的门控时钟。
所以我的问题是;这个门控时钟警告是否显着?无论是模拟还是示波器,它似乎都能正常工作(所以我倾向于忽略它),但我是否会存储问题以供日后使用?有没有办法在没有门控时钟的情况下获得非常慢的50%占空比脉冲?
我已将我的代码放在下面了!
非常感谢(尤其是那些集体花了很多时间来处理我最近的不间断问题的人)
大卫
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
ENTITY CLK_DIVIDER IS
GENERIC(INPUT_FREQ : INTEGER;
OUT1_FREQ : INTEGER;
OUT2_FREQ : INTEGER
);
PORT(SYSCLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
RESET_N_OUT : OUT STD_LOGIC;
OUT1 : OUT STD_LOGIC;
OUT2 : OUT STD_LOGIC);
END CLK_DIVIDER;
architecture Behavioral of Clk_Divider is
constant divider1 : integer := INPUT_FREQ / OUT1_FREQ / 2;
constant divider2 : integer := INPUT_FREQ / OUT2_FREQ / 2;
signal counter1 : integer := 0;
signal counter2 : integer := 0;
signal output1 : std_logic := '0';
signal output2 : std_logic := '0';
signal reset : boolean;
begin
reset_proc : process(RESET_N, SYSCLK)
variable cycles : integer := 0;
variable reset_counter : integer := 0;
begin
if rising_edge(SYSCLK) then
if cycles < 2 then
if reset_counter >= divider1 then
cycles := cycles + 1;
reset_counter := 0;
else
reset_counter := reset_counter + 1;
end if;
reset <= true;
else
reset <= false;
end if;
end if;
if RESET_N = '0' then
cycles := 0;
reset_counter := 0;
reset <= true;
end if;
end process;
output1_proc : process(SYSCLK)
begin
if rising_edge(SYSCLK) then
if counter1 >= divider1 - 1 then
output1 <= not output1;
counter1 <= 0;
else
counter1 <= counter1 + 1;
end if;
if RESET_N = '0' then
counter1 <= 0;
output1 <= '1';
end if;
end if;
end process;
output2_proc : process(SYSCLK)
begin
if rising_edge(SYSCLK) then
if counter2 >= divider2 - 1 then
output2 <= not output2;
counter2 <= 0;
else
counter2 <= counter2 + 1;
end if;
if RESET_N = '0' then
counter2 <= 0;
output2 <= '1';
end if;
end if;
end process;
OUT1 <= output1;
OUT2 <= output2;
RESET_N_OUT <= '0' when reset else '1';
end Behavioral;
答案 0 :(得分:2)
评论表明,时钟分频器是在更大的设计中实例化的。
如果你想在那里使用生成的时钟,你必须在信号output2
和输出out2
之间添加一个BUFG,如下所示:
out2_bufg : BUFG port map(I => output2, O => out2);
组件BUFG在库unisim.vcomponents
中定义。同样适用于输出out1
。
BUFG确保使用时钟树分配生成的时钟,以便时钟信号同时到达所有目标触发器。这样可以最大限度地减少保持时间,并为数据信号的设置提供更多空间。
如果您仍然收到警告/错误,那么您将生成的时钟信号与较大设计中其他位置的另一个信号合并。
答案 1 :(得分:1)
reset_proc
进程在时钟部分之外写有elsif cycles > 1 then
,并且从cycles
派生的条件也被指定为重置的一部分。目前还不清楚这里实际描述了什么硬件,但这使得综合工具不满意。
如果要将RESET_N
用作异步复位,则只需制作一个简单的if RESET_N = '0' then ... end if;
,并指定需要重置的任何信号或变量。其他作业应移至计时部分。
注意:上述更新后代码已更改...这可能已删除了问题的原因。
顺便说一下。 RESET_N
在reset_proc
中用作异步复位,但在其他进程中使用同步复位,这种不一致的用法看起来可能存在重置方案的潜在问题。