У меня есть следующий код (который является выдержкой того, над чем я сейчас работаю):
library ieee;
use ieee.std_logic_1164.all;
entity tb_min_example is
end entity tb_min_example;
architecture arch of tb_min_example is
signal clk1, clk2, slow_clk : std_logic;
signal y : std_logic;
procedure drive_clk(signal clk : out std_logic; constant period : time) is
begin
loop
clk <= '1';
wait for period / 2;
clk <= '0';
wait for period / 2;
end loop;
end procedure drive_clk;
begin
drive_clk(clk1, period => 4 ns);
drive_clk(slow_clk, period => (119.0 / 8.0) * 4 ns);
clk2 <= clk1;
process(slow_clk) is
begin
if rising_edge(slow_clk) then
y <= clk1 xor clk2;
end if;
end process;
end architecture arch;
Я ожидаю, что сигнал y
будет все время низким, так как clk2
назначен на clk1
и x xor x == 1
. Однако я вижу эту странную форму волны:
Кажется, что clk2
(или clk1
) сэмплируется немного раньше, чем другой, и поэтому результат clk2 xor clk1
не равен нулю. Почему это происходит, происходят какие-то странные дельта-циклы?
Я использую XSim с Vivado версии 2020.2.
Кроме того, это рецепт метастабильной конструкции.
И, наконец, не рекомендуется выполнять логические операции с часами (по крайней мере, для конструкций FPGA, что вы делаете из-за тега Vivado). Если вам нужно выполнять операции с часами, используйте специальный модуль MMCM.
Это не отвечает на мой вопрос. Я включил только тег vivado
, потому что в настоящее время я использую xsim (для которого нет тега). Нигде я не предлагал (или не планирую) использовать конструкцию сверху для каких-либо реальных прошивок.
И действительно, я прокомментировал, а не ответил.
clk2
— это отложенная версия clk1
— с задержкой на 1 дельта-цикл симуляции.
Поскольку slow_clk
и clk1
изначально возрастают в одно и то же время, они всегда будут синхронизированы на каждые 2 нарастающих фронта slow_clk
(119/8 = 59,5, и, следовательно, они оба являются связанными часами и выравнивают каждый 2-й нарастающий фронт slow_clk
). В этот момент clk1 будет «1», а clk2 будет «0», что даст вам результат XOR «1».
Обычно поэтому переназначение часов в проекте может вызвать проблемы с моделированием.
Если вы просто задержите начало slow_clock
, вы должны увидеть, что y
всегда равно «0».
Вы сэмплируете более быстрый сигнал с гораздо более медленными часами, я знаю, что это симуляция, но вы не соблюдаете здесь теорему выборки Шеннона.