У меня есть следующий упрощенный пример моего кода, в котором объект модели DeltasTest
можно моделировать, чтобы показать проблему. Часы реального дизайна инвертированы или не основаны на общем значении и подают несколько других объектов ниже этого.Как решить эту проблему с задержкой тактового цикла Delta
Проблема в том, что простой детектор края не работает (data_out
- это просто сбой) в поведенческом моделировании из-за задержки цикла дельта, введенной на часах на этапе инверсии. Есть ли стандартный или иначе элегантный способ решить эту проблему?
До сих пор мое лучшее решение - назначить сигнал data_in
другому сигналу, чтобы дать ему такую же задержку цикла дельта, как clk
. Я подумал о том, чтобы использовать функцию для инвертирования часов по мере необходимости на основе общего параметра в качестве второго параметра функции, но часы используются во многих местах, и это не показалось нам очень изящным, и я заметил, что он даже решит проблему проблема. Прижимаясь к соломинкам, я также попытался сделать назначение инверсии тактового сигнала transport
, но, как и ожидалось, это не имело никакого значения.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Deltas is
Generic (
CLK_INVERT : boolean := false
);
Port (
clk : in std_logic;
data_in : in std_logic
);
end Deltas;
architecture Behavioral of Deltas is
-- Signals
signal data_reg : std_logic := '0';
signal clk_inverted : std_logic := '0';
signal data_out : std_logic := '0';
begin
ClkInvert : if (CLK_INVERT) generate
clk_inverted <= not clk;
else generate
clk_inverted <= clk;
end generate;
process (clk_inverted)
begin
if (rising_edge(clk_inverted)) then
data_reg <= data_in;
end if;
end process;
process (data_reg, data_in)
begin
if (data_reg /= data_in) then
data_out <= '1';
else
data_out <= '0';
end if;
end process;
-- Other entities use `clk_inverted`. Commented out so that this example compiles
--LowerEntity : entity work.Counter
--port map (
-- clk => clk_inverted
--);
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DeltasTest is
end DeltasTest;
architecture Behavioral of DeltasTest is
signal clk : std_logic := '0';
signal data_in : std_logic := '0';
begin
clk <= not clk after 10 ns;
process (clk)
variable count : integer := 0;
begin
if (rising_edge(clk)) then
count := count + 1;
if (count = 4) then
count := 0;
data_in <= not data_in;
end if;
end if;
end process;
uut : entity work.Deltas
Port map (
clk => clk,
data_in => data_in
);
end Behavioral;
Два вопроса: 1) Почему в 'Deltas'' '' '' '' '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ вместо того, чтобы генерировать' clk_inverted' с дельта-задержкой, а затем использовать 'rising_edge()' на этом? 2) Почему не генерируются стимулы на 'data_in', созданные на основе' clk', как это было бы в реальном дизайне, а не только на основе времени? Изменение этого приведет к тому, что краевой детектор будет работать. Если требуется инвертированные часы, сделайте это на уровне, отличном от clk, и распределите по иерархии. –
@MortenZilmer Спасибо за комментарии. 1) Я не использую 'fall_edge()', потому что полярность часов зависит от общего. 2) Сигнал данных фактически генерируется 'clk', но это в конечном счете не имеет никакого значения, поскольку мой пример не был точно таким же, как мой реальный код. Я обновлю пример, чтобы включить ваши изменения. –
Вы можете найти более широкую аудиторию по адресу http://electronics.stackexchange.com/ – Tansir1