Для моделирования длительных задержек часто бывает полезно ускорить симуляцию, чтобы получить более быстрые результаты. Это можно сделать с помощью верхнего уровня Boolean generic, который вы проверяете, чтобы выбрать между реальной константой задержки и меньшей для моделирования.
Моделирование тактовых импульсов 100 Гц не является особенно сложным. В течение одного периода в 100 Гц будет только 1e6 тактовых событий. Вы можете дополнительно автоматизировать проверку путем проверки процесса, что задержка между последовательными ребрами на выходе составляет ~ 5 мс в пределах некоторого предела погрешности.
constant CLOCK_FREQ : integer := 50e6; -- 50 MHz
constant TARGET_FREQ : integer := 100; -- 100 Hz
...
constant MAX_ERROR : delay_length := 10 ns;
constant EXPECTED_HALF_PERIOD : delay_length := 1 sec/TARGET_FREQ/2;
assert abs(clk_100Hz'last_event - EXPECTED_HALF_PERIOD) <= MAX_ERROR
report "100Hz clock has wrong period"
severity error;
Тогда вам не нужно беспокоиться о измерении ребер в окне формы волны. Обратите внимание, что это утверждение должно быть заблокировано на первом генерированном краю 100 Гц, чтобы избежать ложной ошибки в начале моделирования.
В общем, лучше избегать наличия магических чисел в вашем коде, если это вообще возможно. Пояснительный комментарий, хотя и полезный, может выйти из синхронизации с фактическим кодом. Нет необходимости вручную преобразовывать счетчик в шестнадцатеричный. Просто используйте счетчик типа integer
, ограниченный от 0 до 250000-1 (не 2500000), и пусть моделирование/синтез сортируют детали реализации.
В этом случае у вас есть непонятная ошибка, потому что вы рассчитали неверное постоянное значение. Вам нужен только 18-разрядный счетчик, поэтому ваша построенная вручную реализация с использованием unsigned
также уничтожает биты. И, наконец, сбрасывание до нуля предпочтительнее для простых счетчиков, поскольку сравнение с 0 дешевле в некоторых целевых архитектурах (один большой ворот NOR).
constant DELAY_CYCLES : integer := CLOCK_FREQ/TARGET_FREQ/2 - 1;
signal counter : integer range 0 to DELAY_CYCLES;
if reset = '1' then
counter <= DELAY_CYCLES;
elsif rising_edge(clk_50Mhz) then
if counter = 0 then
counter <= DELAY_CYCLES;
else
counter <= counter - 1;
end if;
end if;
Теперь, если вам нужно изменить систему, чтобы генерировать 80 Гц или 120 Гц все, что требуется, это просто, очевидно, постоянные изменения в TARGET_FREQ
без необходимости знать, как пересчитывать непрозрачный шестнадцатеричное значение. Все остальное будет автоматически корректироваться без дополнительных усилий.
Что вы попробовали и какие результаты у вас получили? Какова ваша проблема, точно, с симуляцией этой модели? –
Привет! Я попытался имитировать код выше, но havent найти код для моделирования кода. Я там простой код моделирования, который может показать, если часы преобразуются в 100 Гц часы? – remivass
Как долго вы запускали симуляцию? –