Перейти к содержанию
    

Уже по вопросу понятно, что он чайниковский :)

 

Задача банальная: подсчитывать некие импульсы, порожденные внутри ПЛИС т.е. изменяющиеся синхронно клоку (например, просто 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 одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня.

Так как лучше делать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в первом примере вы породили метастабильность и никак её не учитываете. (возможно, не знаете о последствиях?)

 

во втором случае при наличии констрейна на тактовый сигнал clk заботой о метастабильности занимаестя STA (static timing analyzer) вашего пакета САПР.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;

 

Ну и по разрешению счета наворачивать счетчик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня.

Один триггер, задерживающий на такт clk ваш pulse, и потом проверка, что до триггера уже 1, а после еще 0. Так найдете фронт. Вот эти фронты и считайте. Фактически, то же самое укорачивание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уже по вопросу понятно, что он чайниковский :)

 

 

C одной стороны, второй вариант вроде как правильнее с точки зрения "синхронной" идеологии, но это лишние аппаратные затраты на укорачивание импульса и проверку его уровня.

Так как лучше делать?

На самом деле все, что происходит внутри ПЛИС и должно делаться по "укороченным импульсам". Так что никаких "лишних" затрат и не будет...

Скорее всего дело в том, что Вы не умеете применять автоматы. С автоматами все дело значительно упрощается... Могу рассказать по скайпу.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

always @(posedge clk) if (front==3'b011) a<=a+1;

 

А (front==3'b001) хуже или без разницы?

 

 

if(short_pulse == 1)

 

А short_pulse чему равен или это макрос некий?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лучше всего 4'b0011, чтобы одиночные палки не ловило. :rolleyes: А по мне, хватает 2'b01.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А (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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А насколько правильно делать импульсы так? :

pulse <= {s_reg, s} == 2'b01; // выделяем фронт
if(pulse) pulse <= 0;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А насколько правильно делать импульсы так? :

pulse <= {s_reg, s} == 2'b01; // выделяем фронт
if(pulse) pulse <= 0;

А нинасколько...

Если импульсы приходят в ПЛИС извне, то все равно надо ставить синхронизатор из двух триггеров. И можно добавить еще один...

Или если эти импульсы медленные и есть опасность дребезга фронта, то лучше сразу сделать фильтр...

 

А если импульсы генерируются внутри, то значит идеология "генерирования, а потом выделения" сама по себе неправильная..

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А нинасколько...

Если импульсы приходят в ПЛИС извне, то все равно надо ставить синхронизатор из двух триггеров. И можно добавить еще один...

Или если эти импульсы медленные и есть опасность дребезга фронта, то лучше сразу сделать фильтр...

 

А если импульсы генерируются внутри, то значит идеология "генерирования, а потом выделения" сама по себе неправильная..

 

 

Дико извиняюсь, но я немного не то написал :)

Имелся в виду код вот такого вида:

if(cnt > 0) begin
    pulse <= 1; // генерируем импульс в начале счета
    cnt <= cnt - 1;
end
if(pulse) pulse <= 0;

Ну то есть идея такая что в одном месте (там где нужно сделать одиночный импульс во время какого-то длительного процесса) ставим сигнал в единицу, а потом на следующем же также его сбрасываем конструкцией if(pulse) pulse <= 0;. Насколько такой подход адекватен?

Изменено пользователем dmy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дико извиняюсь, но я немного не то написал :)

 

Ну то есть идея такая что в одном месте (там где нужно сделать одиночный импульс во время какого-то длительного процесса) ставим сигнал в единицу, а потом на следующем же также его сбрасываем конструкцией

Насколько такой подход адекватен?

Совершенно не "адекватен"!!! Даже идейно вреден...

Ставим автомат и таймер если нужно, только так... Автомат выдает "одиночный импульс", и на следующих тактах продолжает "длительного процесса"... Длительность которого задается таймером...

Подробнее могу по скайпу...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Насколько такой подход адекватен?

Подход адекватен, код неадекватен.

Надо учитывать, что в always-блоках все операторы выполняются последовательно.

Сам так пишу (без "else"):

pulse <= 0;
if(cnt == 0) pulse <= 1;

Второй оператор "отменяет" первый при выполнении условия "cnt == 0".

Условие "if(pulse)" - лишнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...