Я пытаюсь синтезировать дизайн на VHDL в FPGA ProASIC3 с помощью инструмента Synplify Pro. В сводном отчете содержится следующее предупреждение о предполагаемых часах.
@W:MT420 : | Found inferred clock counter_unit| pstate_inferred_clock[1] with period 10.00ns. Please declare a user-defined clock on object "n:bcu_ins.ctr_ins.pstate[1]"
Я проследил до части кода, где генерируется предупреждение, и то же самое воспроизводится здесь для справки.
p_fsm_clk : process(reset_n_in, clk_25mhz_in)
begin
if (reset_n_in = '0') then
pstate <= s0;
elsif rising_edge(clk_25mhz_in) then
pstate <= nstate;
end if;
end process p_fsm_clk;
p_fsm : process(pstate,restart_ctr,enable_ctr2,sys_fail)
begin
start_ctr1 <= '0';
start_ctr2 <= '0';
case pstate is
when s0 =>
--Reset state. All counters are reset
if (sys_fail = '0' and restart_ctr = '1') then
nstate <= s1; --move to start counter1
else
nstate <= s0;
end if;
when s1 =>
start_ctr1 <= '1'; --Initiate counter1
if (restart_ctr = '1') then
--restart the counters
start_ctr1 <= '0'; --reset counter1
nstate <= s1;
elsif (enable_ctr2 = '1') then
--move to start counter2
nstate <= s2;
else
nstate <= s1;
end if;
when s2 =>
--Save the counter1 value and start counter2
start_ctr2 <= '1'; --assert flag to start counter2
if (restart_ctr = '1') then
--restart the counters
nstate <= s1;
else
nstate <= s3;
end if;
when s3 =>
start_ctr2 <= '1';
if (sys_fail = '1') then
nstate <= s0;
elsif (restart_ctr = '1') then
--restart the counters
nstate <= s1;
else
nstate <= s3;
end if;
when others =>
nstate <= s0;
end case;
end process p_fsm;
--counter1
p_ctr1 : process(reset_n_in, clk_25mhz_in)
begin
if (reset_n_in = '0') then
ctr1 <= 0; --value on reset
elsif rising_edge(clk_25mhz_in) then
if (start_ctr1 = '1') then
--flag is asserted to start counter1
ctr1 <= ctr1 + 1; --increment counter
else
--flag de-asserted
ctr1 <= 0; --reset the counter
end if;
end if;
end process p_offset_cnt;
--save the value of counter1
offset_val <= ctr1 when pstate = s2;
Логика содержит два счетчика – ctr1
и ctr2
. Счетчики запускаются при отсутствии системных сбоев. На первом этапе ctr1
запускается, за которым затем следует ctr2
. ctr1
перестает считать, когда ctr2
включен. Значение ctr1
определяет, насколько позже ctr2
запускается (с точки зрения тактового периода 25 МГц), называемое смещением. Это значение смещения сохраняется в векторе сигнала, как видно из последней строки кода. Состояние s2
используется для захвата значения ctr1
до его сброса в 0.
offset_val <= ctr1 when pstate = s2;
Я понял, что этот оператор присваивания вызывает предполагаемые часы в дизайне (но не знаю, почему). Когда я помещаю тот же оператор в синхронизируемый процесс, предполагаемое предупреждение о часах исчезает. Однако моя логика работает неправильно.
Я ищу несколько разъяснений в этом отношении.
Вы добавили FPGA
тег, поэтому я отвечу с точки зрения FPGA. Если вы создаете ASIC или используете какой-либо другой поток, может применяться другой ответ.
1. Почему в этом дизайне включены предполагаемые часы pstate[1]
?
offset_val <= ctr1 when pstate = s2;
Эта строка не описывает ничего, что происходит, когдаpstate
нет . Это представляет собой закрытую защелку. В любой ПЛИС, которую я использовал, это будет реализовано путем активации режима «защелки» в обычном триггере с использованием контакта «часы» в качестве «ворота». Ваш сигнал затвора в этот момент использует тактовый ресурс, но в конечном итоге он получен из другого сигнала «данных», а не «настоящих» часов. s2
2. Можно ли иметь такие утверждения в дизайне? Указывает ли наличие предполагаемых часов на плохую практику проектирования?
Защелок в целом следует избегать, если только нет веских причин для их использования, потому что они обычно обеспечивают плохие временные характеристики и могут легко привести к опасностям и гонкам в конструкции. Одним из примеров, когда необходимо использовать защелки, может быть, если какой-то внешний интерфейс должен использовать какой-либо вход, чувствительный к уровню. В вашем случае похоже, что избежать защелки должно быть довольно легко.
3. Если недопустимо иметь предполагаемые часы в дизайне, как я могу исправить это, закодировав логику по-другому?
Используйте синхронизированный процесс, который содержит назначение. Это будет означать триггер для offset_val
. Вам придется смоделировать свой проект или протестировать его на плате, чтобы убедиться, что функция эквивалентна в вашем конкретном случае, но основная философия в FPGA должна заключаться в том, что любое назначение, кроме простого, a <= b and c;
или some_vec <= smaller_vec & another_bit;
использует синхронизированный процесс. Это даст вам предсказуемые временные результаты и упростит написание ограничений. Есть исключения, но это должно быть отправной точкой.
4. Если выводить предполагаемые часы — это нормально, как я могу сообщить об этом инструменту? Какое ограничение периода я могу предоставить для таких предполагаемых часов? Как я могу определить значимый период для таких предполагаемых часов?
В случае внешнего интерфейса чувствительный к уровню вход будет иметь некоторую минимальную ширину импульса, и вы можете использовать это для создания ограничения периода, которое представляет собой наихудший возможный случай того, как этот сигнал может переключаться. Для любых внутренних интерфейсов я бы работал над тем, чтобы защелки вообще не существовали, но может применяться тот же метод. Избегая защелок вообще, вы избегаете необходимости думать о такого рода проблемах.
В дополнение к этому, конструкция конечного автомата с двумя процессами, показанная в вашем коде, не требуется. Вы можете поместить всю машину и переходы состояний в один тактовый процесс. Результирующий процесс будет очень похож на ваш второй процесс, описанный выше, со всем, что заключено в if (rising_edge(clk)) then
, и каждое вхождение nstate
заменено на pstate
. Вы должны быть в состоянии найти существующие ответы относительно дизайна конечного автомата либо здесь, в EE, либо в теге VHDL Stack Overflow .
пользователь_1818839
рвкрыш
рвкрыш
If you are creating an ASIC or using some other flow, a different answer might apply
. Как будет отличаться синтез в случае ASIC? Не является ли здесь проблемой наличие предполагаемых защелок?scary_jeff