Введение (можно не читать

):
к ПЛИС подключено статическое асинхронное ОЗУ 32 кБ (имена выводов начинаются с MEM_)
имеется два счётчика адреса addr1 и addr2. По первому адресу при наступлении некоторых условий нужно читать данные из ОЗУ (после чего адрес инкрементировать), при наступлении другого условия нужно записывать
данные в ОЗУ по второму адресу.
сигнал write_MEM управляет тристабильным буфером и когда он равен '1' MEM_D настроена на запись (т.е. вывод данных из ПЛИС)
Суть вопроса (желательно ознакомиться перед ответом):
После компиляции в Quartus получаю, что MEM_A, MEM_CS, MEM_RD, MEM_WR
являются выходами защёлок и, соотвественно, предупреждение об этом от design Assistant: "Design should not contain combinational loops". Как побороть эту неприятность (на форуме неоднократно слышал высказывания, что люди умудряются делать проекты вообще без защёлок).
Собственно, кусок кода с пояснениями:
Схему описываю как автомат, изменение состояний которого происходит по положительному фронту синхросигнала CLK.
Ниже приводится часть кода процесса, формирующего значение выходов автомата, в зависимости от его текущего состояния.
if (CLR = '1') then
MEM_CS <= '1';
MEM_RD <= '1';
MEM_WR <= '1';
inc_addr1 <= '0';
write_MEM <= '1';
else
case CurState is
when sStartReadMem =>
write_MEM <= '0';
MEM_A(14 downto 0) <= addr1 (14 downto 0);
MEM_CS <= '0';
MEM_RD <= '0';
when sEndReadMem =>
MEM_CS <= '1';
MEM_RD <= '1';
data(7 downto 0) <= MEM_D(7 downto 0);
inc_addr1 <= '1';
when sSaveData =>
write_MEM <= '0';
inc_addr1 <= '0';
-------
when sStartWriteMem =>
MEM_A(14 downto 0) <= addr2(14 downto 0);
MEM_CS <= '0';
MEM_WR <= '0';
when sEndWriteMem =>
MEM_CS <= '1';
MEM_WR <= '1';
Сопутствующий вопрос:
Как наиболее глюкобезопасно сделать инкрементацию addr1 после чтения? Сейчас для этого (см. выше) я изменяю состояние сигнала inc_addr1, который подан на вход разрешения счёта счётчика, реализованного на базе lpm_counter. Синхросигналом для счётчика является инвертированная частота CLK. Т.е. всё построено на том, что изменение состояния автомата (а значит и inc_addr1) происходит по положительному фронту CLK, а инкремент счётчика addr1 по отрицательному.
Существуют опасения, что при некоторых вариантах разводки кристалла установление значения inc_addr1 может произойти позднее, чем через пол-такта CLK=60MГц, и соотвественно инкремент не произойдёт.
приветствуются ссылки на литературу и исходники, где можно на конкретных примерах посмотреть как решаются такие вопросы.
Спасибо