b-volkov 0 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба Уже по вопросу понятно, что он чайниковский :) Задача банальная: подсчитывать некие импульсы, порожденные внутри ПЛИС т.е. изменяющиеся синхронно клоку (например, просто clk/N). Я всегда поступал просто - подавал импульсы сразу на тактовый вход счетчика: always @(posedge pulse) begin count = count + 1'd1; end Но роясь в чужих исходниках увидел, что люди делают это по-другому: на тактовый вход подают клок, а подсчитываемыми импульсами (укороченными до одного клока) разрешают счет: always @(posedge clk) begin if(short_pulse == 1) count = count + 1'd1; end C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня. Так как лучше делать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба в первом примере вы породили метастабильность и никак её не учитываете. (возможно, не знаете о последствиях?) во втором случае при наличии констрейна на тактовый сигнал clk заботой о метастабильности занимаестя STA (static timing analyzer) вашего пакета САПР. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня. Так как лучше делать? Вся логика должна быть синхронной, кроме разве что сброса или управляющих сигналов, но и они должны быть описаны с ограничениями. Что касается подсчета импульсов, то возьмите бОльшую частоту (больше чем в 2 раза) ну и как-то так: reg [1:0] imp_r; always @(posedge clk) imp_r<={imp_r[0],imp}; wire cnt_en=(imp_r==2'b10)?1'b1:1'b0; Ну и по разрешению счета наворачивать счетчик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня. Один триггер, задерживающий на такт clk ваш pulse, и потом проверка, что до триггера уже 1, а после еще 0. Так найдете фронт. Вот эти фронты и считайте. Фактически, то же самое укорачивание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба Уже по вопросу понятно, что он чайниковский :) C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня. Так как лучше делать? На самом деле все, что происходит внутри ПЛИС и должно делаться по "укороченным импульсам". Так что никаких "лишних" затрат и не будет... Скорее всего дело в том, что Вы не умеете применять автоматы. С автоматами все дело значительно упрощается... Могу рассказать по скайпу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lmx2315 2 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба wire pulse; reg [2:0] front; reg [15:0] a; always @(posedge clk) front<={front[1:0],pulse}; always @(posedge clk) if (front==3'b011) a<=a+1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 24 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба always @(posedge clk) if (front==3'b011) a<=a+1; А (front==3'b001) хуже или без разницы? if(short_pulse == 1) А short_pulse чему равен или это макрос некий? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба Лучше всего 4'b0011, чтобы одиночные палки не ловило. :rolleyes: А по мне, хватает 2'b01. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lmx2315 2 13 июля, 2016 Опубликовано 13 июля, 2016 · Жалоба А (front==3'b001) хуже или без разницы? ..если на то пошло, то лучше наверное так - wire pulse; reg [3:0] front; reg [15:0] a; always @(posedge clk) front<={front[2:0],pulse}; always @(posedge clk) if (front[3:1]==3'b011) a<=a+1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
b-volkov 0 14 июля, 2016 Опубликовано 14 июля, 2016 · Жалоба Спасибо за советы! Буду делать "по канонам" :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dummy 0 14 июля, 2016 Опубликовано 14 июля, 2016 · Жалоба А насколько правильно делать импульсы так? : pulse <= {s_reg, s} == 2'b01; // выделяем фронт if(pulse) pulse <= 0; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 14 июля, 2016 Опубликовано 14 июля, 2016 · Жалоба А насколько правильно делать импульсы так? : pulse <= {s_reg, s} == 2'b01; // выделяем фронт if(pulse) pulse <= 0; А нинасколько... Если импульсы приходят в ПЛИС извне, то все равно надо ставить синхронизатор из двух триггеров. И можно добавить еще один... Или если эти импульсы медленные и есть опасность дребезга фронта, то лучше сразу сделать фильтр... А если импульсы генерируются внутри, то значит идеология "генерирования, а потом выделения" сама по себе неправильная.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dummy 0 14 июля, 2016 Опубликовано 14 июля, 2016 (изменено) · Жалоба А нинасколько... Если импульсы приходят в ПЛИС извне, то все равно надо ставить синхронизатор из двух триггеров. И можно добавить еще один... Или если эти импульсы медленные и есть опасность дребезга фронта, то лучше сразу сделать фильтр... А если импульсы генерируются внутри, то значит идеология "генерирования, а потом выделения" сама по себе неправильная.. Дико извиняюсь, но я немного не то написал :) Имелся в виду код вот такого вида: if(cnt > 0) begin pulse <= 1; // генерируем импульс в начале счета cnt <= cnt - 1; end if(pulse) pulse <= 0; Ну то есть идея такая что в одном месте (там где нужно сделать одиночный импульс во время какого-то длительного процесса) ставим сигнал в единицу, а потом на следующем же также его сбрасываем конструкцией if(pulse) pulse <= 0;. Насколько такой подход адекватен? Изменено 14 июля, 2016 пользователем dmy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 14 июля, 2016 Опубликовано 14 июля, 2016 · Жалоба Дико извиняюсь, но я немного не то написал :) Ну то есть идея такая что в одном месте (там где нужно сделать одиночный импульс во время какого-то длительного процесса) ставим сигнал в единицу, а потом на следующем же также его сбрасываем конструкцией Насколько такой подход адекватен? Совершенно не "адекватен"!!! Даже идейно вреден... Ставим автомат и таймер если нужно, только так... Автомат выдает "одиночный импульс", и на следующих тактах продолжает "длительного процесса"... Длительность которого задается таймером... Подробнее могу по скайпу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 14 июля, 2016 Опубликовано 14 июля, 2016 · Жалоба ...Насколько такой подход адекватен? Подход адекватен, код неадекватен. Надо учитывать, что в always-блоках все операторы выполняются последовательно. Сам так пишу (без "else"): pulse <= 0; if(cnt == 0) pulse <= 1; Второй оператор "отменяет" первый при выполнении условия "cnt == 0". Условие "if(pulse)" - лишнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться