МАРСОХОД

Open Source Hardware Project

Quartus II. Часть4. Элементы комбинированной логики. Счетчик.

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

Рассмотрим простой пример, синхронный "SR"-триггер описываемый примитивом "SRFF":

Триггер на схеме Altera Quartus II

Результат компиляции этого проекта можно посмотреть в "RTL Viewer" среды Quartus II:
Триггер в RTL-viewer среды Quartus II
Как мы видим, компилятор реализовал этот компонент из D-триггера и некой комбинаторной логики. В свою очередь, реализованная логическая функция - уже известный нам мультиплексор 2х1, адресным входом которого является выход триггера, один из коммутируемых входов  это сигнал "S", другой - инверсия от сигнала  "R". Таким образом можно понять , как работает этот элемент.

При наличии активного сигнала на входе "S" , на выходе , по фронту клока, будет установлена "1".

При наличии активного сигнала на входе "R",  на выходе , по фронту клока, будет установлен "0".

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

Примерно такая же комбинаторная логика и для такой-же цели (ситуационная установка регистра в определенное состояние) будет добавлена компилятором в мегафункцию "LPM_DFF", если в свойствах элемента добавить входы "sset" и "sclr" (синхронная установка и синхронный сброс ):

Регистр с синхронным сбросом и установкой
При наличии сигнала на входе "sset" , все триггера , по фронту клока, будет установлены в "1".

При наличии сигнала на входе "sclr" , все триггера , по фронту клока, будет установлены в "0".

При отсутствии обоих сигналов в регистр будут фиксироваться входные данные.
При наличии одновременно двух сигналов "sset" и "sclr", в отличие от примитива "SRFF",
приоритет имеет "sclr", и  все триггера будет установлены в "0".

Еще один пример комбинированной логики - счетчик.
Если использовать уже знакомые нам конструкции , простой четырехразрядный
счетчик можно изобразить так:
Счетчик в Altera Quartus II

Как видно из схемы, работает он следующим образом, функция "LPM_ADD_SUB" к имеющемуся на выходе регистра "LPM_DFF" числу прибавляет константу "1". Таким образом, по каждому клоку тактовой частоты, в регистр "LPM_DFF" будет заноситься значение, на 1 превышающее предыдущее. То есть, будет подсчитываться количество клоков. Реализовать точно-такую же функциональность можно с помощью мегафункции "LPM_COUNTER":

Счетчик в среде Altera Quartus II

Поскольку счетчик - очень часто используемый элемент, опишу некоторые свойства
мегафункции "LPM_COUNTER" более подробно:
Счетчик
Входы:

  • "sset" и "sclr" имеют такое- же действие, как и в случае "LPM_DFF" , т.е. установка или сброс всех  триггеров.
  • "sload" используется  вместе с "data[]" и устанавливает все триггера в состояние, имеющееся на  входе "data[]".( Если  вход "data[]" отсутствует, то по "sload" будут загружаться "0"). Из этих трех входов максимальный приоритет имеет "sclr", затем "sload", минимальный - "sset". 
  • "updown" - управление направлением счета. В случае если "updown" - "1", то по каждому счетному циклу значение счетчика будет увеличиваться , если "0" - уменьшаться. Если этот вход отсутствует, направление  счета можно задать в параметре "LPM_DIRECTION" ( по умолчанию - "UP"). 
  • "clk_en" разрешение клока. Отсутствие активного сигнала на этом входе запрещает любые операции с триггерами.
  • "cnt_en" и "cin"  равноценные входы. Управляют только счетными циклами и не влияют на операции"sload","sset" и "sclr".
  • Выходы "q[]" - собственно , биты счетчика. Их количество (разрядность)  указывается в "LPM_WIDTH"
  • Выход "cout" - перенос. В случае если параметр "LPM_MODULUS" отсутствует или равен "0", сигнал "cout" будет активен, если на выходе счетчика все "1".
    Если параметр "LPM_MODULUS"  имеет какое-то значение, то "cout" будет активен при достижении счетчиком значения на 1 меньше чем в "LPM_MODULUS" и на следующем счетном цикле в счетчик будет загружен "0".

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

 

 

 

 


 

Комментарии  

0 #9 Shire 03.12.2013 04:28
Поправьте LPM_MODULS на LPM_MODULUS, да и ссылку на краткое описание библиотеки неплохо бы дать:
http://www.altera.com/literature/catalogs/lpm.pdf
0 #8 shlash 20.09.2012 14:25
Наверное на вход cin надо подавать с выходов cout всех предшествующих?
На второй с первого. На третий с первого И второго. На четвёртый с первого И второго И третьего и т. д.?

А для счёта - вниз?
cout должен устанавливаться при значении 0.
Значит, при исходном состоянии 9 или 0, меняя направление Updown - cout тоже меняет значение?
0 #7 shlash 20.09.2012 14:23
Цитирую Ю р и й:

"cout" младшей цифры нужно соединить с "cin" старшей, все остальные сигналы - параллельно.

Это справедливо только для двухразрядного. А дальше?

В документации очень скудное описание алгоритма работы cout. И только для восходящего счёта - устанавливается при значении 9 (для десятичного).

Первый разряд считает каждый импульс. Достигнув 9 и выставив cout разрешает второй разряд.
Следующий (10) импульс увеличивает второй разряд и снимает с него cin - подсчитывается каждый десятый импульс.
Достигнув состояния 9 (90) выставляет cout и разрешает третий разряд. В этом состоянии остаётся 10 тактов. Которые подсчитываются третьим разрядом.
0 #6 Ю р и й 20.09.2012 05:07
Цитирую shlash:
А как соединять несколько экземпляров lpm_module, для получения многоразрядного десятичного реверсивного счётчика?

"cout" младшей цифры нужно соединить с "cin" старшей,
все остальные сигналы - параллельно.
0 #5 shlash 19.09.2012 20:51
А как соединять несколько экземпляров lpm_module, для получения многоразрядного десятичного реверсивного счётчика?
0 #4 virtual9900 15.11.2011 11:45
Цитирую nckm_:
[quote name="poi_83"]Сделать расширитель импульса с сохранением фазы не просто, если вообще возможно.

8) Дрожание фронта всегда будет, какие требования к джиттеру?
0 #3 nckm_ 10.11.2011 06:01
Цитирую poi_83:
Как с помощью ПЛИС можно расширить импульс?
Есть 1кГц 2мкс, нужно 1кГц 50мкс.

не уверен, что можно дать хороший ответ на этот вопрос, так как не вполне ясна задача.
Самый простой способ - это "опрашивать" ваш сигнал с очень высокой частотой. Так можно обнаружить фронт с некоторой погрешностью, потом отсчитать заданное число тактов о[censored]й высокой частоты и это будет конец широкого импульса. При таком методе, конечно фаза выходного широкого импульса будет немного дрожать относительно исходного. Сделать расширитель импульса с сохранением фазы не просто, если вообще возможно.
0 #2 Ю р и й 09.11.2011 16:28
Цитирую poi_83:
Как с помощью ПЛИС можно расширить импульс?
Есть 1кГц 2мкс, нужно 1кГц 50мкс.

Есть способ определить момент начала импульса - http://marsohod.org/index.php/verilog/157-verilogedges
а от него можно отсчитать любое количество клоков,
которое вам нужно.
0 #1 poi_83 09.11.2011 15:36
Как с помощью ПЛИС можно расширить импульс?
Есть 1кГц 2мкс, нужно 1кГц 50мкс.

Добавить комментарий


Защитный код
Обновить


GitHub YouTube Twitter
Вы здесь: Начало Статьи о разном Quartus II. Часть4. Элементы комбинированной логики. Счетчик.