Найти тему
IT. Как это работает?

Какие бывают FIFO буферы?

Оглавление
Источник: https://slidemodel.com/templates/fifo-powerpoint-template/6249-01-fifo-concept-2/
Источник: https://slidemodel.com/templates/fifo-powerpoint-template/6249-01-fifo-concept-2/

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

Поворот не туда

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

Место кольцевого буфера FIFO при передачи данных между модулями
Место кольцевого буфера FIFO при передачи данных между модулями

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

Принцип работы FIFO буфера на основе двухпортовой памяти
Принцип работы FIFO буфера на основе двухпортовой памяти

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

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

Рваный режим работы системы ЦОС при использовании учебного буфера
Рваный режим работы системы ЦОС при использовании учебного буфера

На картинке выше результат моделирование такого FIFO, которое хранит данные, пришедшие по медленному интерфейсу RS-232. Обратите внимание, что большую часть времени быстрая система ЦОС в лице интегратора простаивает в ожидании данных. Это видно по ступенчатому накоплению результата на выходе интегратора (y). Только при готовности данных в буфере срабатывают пачки импульсов на линии clk.

Для случая, когда пишущий модуль работает быстро, а читающий медленно, такая схема уже не работает. В наших планах передавать в компьютер результаты вычислений системы цифровой обработки сигнала (ЦОС) при помощи довольно медленного интерфейса RS-232. Очевидно, пора взять на вооружение FIFO подходящей конструкции.

Одна важная деталь

Как вы понимаете, конструкций FIFO буферов множество. Для самых различных жизненных ситуаций нашему вниманию предлагаются двунаправленные FIFO, а также буферы с приоритетами, где очередь может совсем не соблюдается (совсем как в жизни). Но из тех простых, что подходят для нашей задачи есть, так называемые, SCFIFO и DCFIFO. Не нужно пугаться, SCFIFO это синхронный буфер, он же с одной тактовой линией (читатель и писатель на одной тактовой частоте),а DCFIFO с двумя тактовыми линиями.

SCFIFO. Заметна одна линия тактов clock
SCFIFO. Заметна одна линия тактов clock

По первым двум буквам видно отличие: SC - single clock (одна тактовая линия), DC - dual clock (две тактовые линии).

DCFIFO. Заметны отдельные тактовые линии на запись (wrclk) и чтение (rdclk)
DCFIFO. Заметны отдельные тактовые линии на запись (wrclk) и чтение (rdclk)

У этих кольцевых буферов FIFO много общего. В каждый из буферов входят данные (data). Разумеется, они и выходят (q). Запрос на запись данных поступает по линии wrreq, запрос на чтение по линии rdreq. Эти линии запросов не дадут буферу записать данные, если они еще не готовы и выдать их, если необходимости в них еще не было. Несколько линий на выходе этих модулей сигнализируют о предельной загрузке буфера (full), отсутствии данных (empty). Значение остальных линий и шин (если они есть) можно узнать из документации.

Принцип работы

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

Как уже было сказано, центральным узлом FIFO буфера является двухпортовая память, один из портов предназначен для записи данных, другой для их чтения. На схеме ниже такая память обозначена как FIFO Memory (Dual Port RAM).

Общее устройство кольцевого буфера типа DCFIFO
Общее устройство кольцевого буфера типа DCFIFO

Обязательным условием является наличие двух счетчиков адреса. Один (wptr) подсчитывает адрес ячейки памяти (waddr), предназначенной для записи данных . Другой счетчик (rptr) ведет подсчет адреса ячейки (raddr), где хранится слово данных для чтения. Эти счетчики находятся во взаимодействии друг с другом с помощью линий wptr и rptr. Основное назначение этого взаимодействия это полный контроль над ситуацией. А ситуации, как известно, бывают разные.

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

OpenSource модули - для того чтобы их использовали

Разрабатывать все то, что уже давно написано это занятие больше тренировочное. У нас пока цель немного другая - собираем испытательный стенд. Не нужно стесняться брать в пользование то, что для этого выкладывается в открытый доступ. Тем самым мы не обижаем авторов, а даже напротив, делаем им комплимент. По запросу поисковой системы готовые модули чаще всего находятся на GitHub.com и opencores.org, хотя и других ресурсов хватает. За кольцевой буфер DCFIFO наше спасибо отправляется автору Damien Pretet)

Страница пользователя ресурса GitHub.com
Страница пользователя ресурса GitHub.com

По ссылке выше лежит неплохой проект (async_fifo), это стало понятно после сборки и моделирования.

При скорости записи выше скорости чтения свободная память постепенно исчезает. Указатель (адрес) записи бежит по кругу от младших адресов к старшим и догоняет медленный указатель чтения. При этом на выход выставляется предупреждающий сигнал о переполнении.

Появление сигнала о переполнении кольцевого буфера
Появление сигнала о переполнении кольцевого буфера

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

Теперь другая ситуация. Запись идет медленно, а считывание происходит быстро. При моделировании дадим памяти слегка заполниться путем запрета считываний, а потом их разрешим.

Появление сигнала об отсутствии данных в памяти
Появление сигнала об отсутствии данных в памяти

Довольно быстро адрес на чтение догоняет адрес на запись и происходит то, что должно было произойти: появляется сигнал об отсутствии данных. Этот сигнал необходимо обрабатывать модулю чтения по той простой причине, что на шине данных буфера будет какое-то число, но это совсем не валидные данные. Считывание с буфера в момент сигнала empty будет ошибочным.

По всей видимости, мы нашли что искали, осталось собрать и протестировать испытательный стенд. Делать это мы будем в следующих выпусках. До новых встреч!

Поддержите статью лайком если понравилось и подпишитесь чтобы ничего не пропускать.

Также не обойдите вниманием канал на YouTube. Подписки и лайки будут приятным ответом от аудитории.