реклама на сайте
подробности

 
 
> Боремся с защёлками, то бишь latch'ами
Vincent Vega
сообщение Dec 11 2004, 22:26
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 46
Регистрация: 26-09-04
Пользователь №: 721



Введение (можно не читать smile.gif):

к ПЛИС подключено статическое асинхронное ОЗУ 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Гц, и соотвественно инкремент не произойдёт.

приветствуются ссылки на литературу и исходники, где можно на конкретных примерах посмотреть как решаются такие вопросы.

Спасибо
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
oval
сообщение Aug 24 2005, 08:01
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 265
Регистрация: 15-03-05
Из: Москва
Пользователь №: 3 367



Цитата(maxus @ Aug 23 2005, 20:57)
Обычно операции разносят по разным тактам (например изменение состояния автомата и увеличение счетчика). Делают модуль, который после прихода управляющего сигнала выдает последовательные импульсы. И уже от этих импульсов ты синхронизируешься.

in        __|``|______________
out_1  ______|``|___________
out_2  __________|``|_______
out_3  ______________|``|___

например по out_1 меняешь состояние автомата, по out_2 - инкрементируешь счетчик. Работает железно - проверенно.
*

Не думаю, что подобная идея подойдет для данной конкретной задачи, ибо, как минимум, растянется цикл доступа к памяти. Что, если мы не имеем возможности разнести операции по последовательным тактам? Что, если этих операций 100? Чем повышается надежность работы схемы при таком подходе? Модуль, который после прихода управляющего сигнала выдает последовательные импульсы, это тот же автомат состояний. Идея понятна, но на мой взгляд, никакой надежности не добавит.

P.S. Господа, при проектировании автоматов "не опускайтесь" до уровня импульсов, думайте "выше", на уровне действий, операций. Про управляющие сигналы, конечно, не забывайте.
Go to the top of the page
 
+Quote Post
maxus
сообщение Aug 25 2005, 06:18
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 113
Регистрация: 5-04-05
Пользователь №: 3 864



Как раз в данной конкретной задаче не 100 операций а две - изменение состояния и инкремент адреса. Бало бы 100, никто не предлагал бы вариант с последовательными импульсами...
А надежность будет выше, тк не надо будет думать - успеет ли счетчик посчитать, потому что со слов автора: "Т.е. всё построено на том, что изменение состояния автомата (а значит и inc_addr1) происходит по положительному фронту CLK, а инкремент счётчика addr1 по отрицательному." А так все будет разнесено по отдельным тактам. Что может быть надежней? Если схема позволяет по времени растянуть операцию на два такта - то это будет хороший вариант.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 01:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01372 секунд с 7
ELECTRONIX ©2004-2016