Добро пожаловать в Stackoverflow. Ваш вопрос интересен, но на самом деле он не содержит достаточно информации, чтобы получить полный ответ (быстрый взгляд на справочный центр и особенно на Как создать минимальный, полный и проверяемый пример * Раздел 1004 *, возможно, поможет вам улучшить его, если хотите).
В любом случае, давайте попробуем угадать. Ваш процесс возобновляется каждый раз, когда изменяется start
, и, благодаря вашему выражению if
, он вызывает вашу процедуру gen_start_impulse
, только если новое значение start
равно '1'
. Итак, просто чтобы прояснить ситуацию, мы могли бы сгладить вашу модель и переписать ваш процесс следующим образом:
process (start)
variable clk_counter: integer := 0;
constant duration: integer := 1;
begin
if (start = '1') then
if (rising_edge(clk)) then
if (clk_counter = duration) then
start_impulse <= '0';
clk_counter := 0;
else
start_impulse <= '1';
clk_counter := clk_counter + 1;
end if;
end if;
end if;
end process;
Важное примечание : это не является строго эквивалентным вашему исходному коду, потому что в вашем коде переменная clk_counter
переинициализируется каждый раз, когда ваша процедура gen_start_impulse
вызывается, в то время как здесь она сохраняет свое предыдущее значение . * * 1019
Теперь, как вы думаете, что произойдет, если start
является синхронным? То есть всегда ли он меняется сразу после нарастающего фронта clk
? Просто: условие:
if (rising_edge(clk)) then
Оператор
всегда ложен, и ваши присвоения сигналов start_impulse
никогда не выполняются. Это потому, что start
и clk
никогда не изменяются одновременно. Между ними всегда есть хотя бы один шаг моделирования (« дельта-цикл »).
Если вы разрабатываете синхронную систему, подождите или проверьте нарастающие фронты ваших часов, а затем протестируйте другие сигналы, а не наоборот. Пример:
procedure gen_start_impulse (
signal rising_signal : out std_logic;
signal starter : in std_logic;
constant duration : in integer) is
variable clk_counter : integer := 0;
begin
if (starter = '1') then
if (clk_counter = duration) then
rising_signal <= '0';
clk_counter := 0;
else
rising_signal <= '1';
clk_counter := clk_counter + 1;
end if;
end if;
end gen_start_impulse;
...
process (clk)
begin
if (rising_edge(clk)) then
gen_start_impulse(start_impulse, start, 1);
end if;
end process;
Важное примечание : поскольку переменная clk_counter
переинициализируется каждый раз, когда вызывается процедура gen_start_impulse
(см. Предыдущее примечание), это не будет работать так, как вы ожидаете. Если вы хотите, чтобы это работало, вам нужно будет немного переделать его, либо полностью удалив процедуру (кстати, зачем она вам нужна) и используя только один синхронный процесс, либо добавив четвертый параметр inout
в Ваша процедура для переменной clk_counter
и ее объявление в качестве переменной процесса.