Контроллеры Fast Ethernet для встроенных применений
Описание блоков FIFO в канале приема и передачи данных
Для различных реализаций проекта могут потребоваться различные варианты исполнения FIFO, поэтому блоки полностью параметризированы и имеют следующие параметры:
- Data_width = 16 — шина данных на запись, разрядность;
- Ctrl_width = 16 — шина служебных слов на запись, разрядность;
- Frame_min_len = 8 — длина минимального пакета в словах Data_width;
- Fifo_len = 128 — «глубина» буфера в словах Data_width.
Рассмотрим более подробно FIFO на прием
На рис. 1 приведено изображение блока FIFO на прием (функции rx_fifo), а сигналы этого блока перечислены в таблице 1.
Приемный FIFO на стороне записи
Приемный FIFO на стороне записи все сигналы получает из приемной части блока mii2_16. Синхрочастота для записи (wrclk) приходит из трансивера, причем трансивер выбирает частоту после стабилизации работы линии связи. Шина данных на запись в FIFO wrData[Data_width-1… 0] синхронизируется сигналом разрешения записи данных (wr_data_ena), который также приходит из mii2_16 и устанавливается, когда принято слово данных полной разрядности 16 или 32 бит, в зависимости от разрядности шины FIFO. Слово управления (счетчик принятых слов, ошибки, адреса и пр.) записывается в FIFO со входов шины управления wrCtrl[Ctrl_width-1… 0].
Управляющий сигнал rx_kadr сообщает блоку FIFO, что можно принимать кадр (строб кадра). Этот сигнал устанавливается в случае, если МАС-адрес приходящего из сети пакета совпал с МАС-адресом контроллера, либо если приходящий пакет — широковещательный. Блок mii2_16 установит строб кадра при выдаче первого слова данных в FIFO.
Сигнал rx_err передает информацию о том, что в потоке данных пришли коды ошибки и этот пакет обрабатывать на верхнем уровне не нужно. На основании обработки состояния FIFO формируются сигналы time_word_err (когда слово данных пришло, а буфер записи полон) и rx_err_tg (когда в потоке данных пришел сигнал rx_err).
Сигналы wrempty (сигнал о пустоте FIFO) и wrfull (переполнение FIFO) используются для проверки режимов работы FIFO. Сигнал wr_cnt_ena — разрешение на запись состояния счетчика принятых слов в регистр контроля.
Приемный FIFO на стороне чтения
Приемный FIFO на стороне чтения работает под управлением хоста. Сигнал rdclk (частота для чтения) — это системная частота хоста, сигналы rd_data_ena (разрешение чтения данных) и rd_ctrl_ena (разрешение чтения регистра управления) — это дешифрованные адреса регистров чтения со стороны хоста. Шина данных на чтение rdData[Data_width-1… 0] поступает из FIFO в хост.
На стороне чтения так же формируются сигналы о заполнении FIFO — rdhalf (заполнен наполовину) и rdempty (отсутствие записей в FIFO). Сигнал rd_begin показывает, что в FIFO есть хотя бы один целый кадр или что он заполнен наполовину — его можно использовать как запрос на прерывание по уровню для начала чтения буфера. Сигнал data_block показывает, что кадр из FIFO считан весь, и дальнейшее чтение данных из FIFO заблокировано — его можно использовать как запрос на прерывание по уровню для окончания чтения буфера.
Счетчик числа целых пакетов, находящихся в Буфере — frame_cnt_q[FRAME_WIDTHU-1… 0].
Работа приемного FIFO
Блок mii2_16 устанавливает строб кадра и выдает слова данных, которые записываются в FIFO.
При необходимости в буфер помещаются служебные слова, причем их число не ограничено. Единственное ограничение — слова данных во время приема кадра имеют приоритет над записью служебных слов.
Последнее слово данных в буфере не имеет признака конца кадра, так как этот признак может быть выработан только после приема последнего слова по снятию строба кадра. Поэтому следом за последним словом данных должно быть записано служебное слово с признаком конца кадра. Это слово должно содержать информацию о числе слов в пакете, ошибках, адресации и пр.
Чтение данных из приемного FIFO производится либо «порциями» фиксированной длины, например 16 слов, либо до получения прерывания, сигнализирующего о конце пакета. Чтобы не прочитать «лишних» данных, автомат управления приемным FIFO блокирует чтение слов данных после получения признака конца кадра. Блокировка будет снята только при чтении слова состояния по адресу регистра статуса.
Биты ошибок сбрасываются при чтении по адресу «wr_err_ena». Диаграмма работы автомата управления приемным FIFO представлена на рис. 2 и рис. 7 из первой части статьи.
Автомат управления приемным FIFO rx_process имеет следующие состояния:
- Idle — исходное;
- Frame — состояние, при котором происходит прием пакета;
- Kadr_end_state — состояние, при котором происходит определение конца кадра;
- Report_state — при этом состоянии в FIFO производится запись сообщения об ошибке;
- IFG_state — определение паузы между кадрами.
До начала приема данных автомат управления приемным FIFO находился в состоянии Idle.
Когда блок mii2_16 установит строб кадра и выдаст первое слово данных в FIFO, происходит следующее:
- Если буфер пуст, то автомат управления приемным FIFO, получив признак начала кадра, помещает первое слово данных в буфер с признаком «начала кадра» и затем переходит в состояние Frame.
- Если буфер полон, то есть хост не считал предыдущий кадр, то автомат управления приемным FIFO переходит в состояние Report_state, в котором он ждет освобождения буфера и по освобождении помещает туда сообщение об ошибке. Затем автомат переходит в состояние IFG_state и ждет окончания текущего кадра путем определения паузы между кадрами, после чего переходит в исходное состояние — Idle.
Находясь в состоянии Frame, автомат управления приемным FIFO может осуществить три перехода:
- Если буфер не полон, есть rx_kadr (строб кадра), то есть можно принимать кадр и есть сигнал wr_data_ena (разрешение записи данных), то производится запись данных в FIFO. Автомат управления продолжает находиться в состоянии Frame. Это рабочая ветвь по приему данных.
- Если есть rx_kadr (строб кадра), то есть можно принимать кадр и есть сигнаwr_data_ena, но буфер полон, то производить запись данных в FIFO невозможно и слово данных будет потеряно. Поэтому автомат переходит в состояние Report_state, в котором он ждет освобождения буфера и по освобождении помещает туда сообщение об ошибке. Затем автомат переходит в состояние IFG_state и ждет окончания текущего кадра путем определения паузы между кадрами, после чего переходит в исходное состояние — Idle.
- Если сигнал rx_kadr (строб кадра) снимается, то это значит, что последнее принятое слово данных было последним в этом кадре, кадр закончился и можно переходить в состояние Kadr_end_state, а оттуда — в Idle.
Находясь в состоянии Kadr_end_state, автомат управления приемным FIFO может осуществить три перехода:
- По нормальному завершению — в Idle.
- Если буфер полон, но следующий кадр еще не пришел, то в Kadr_end_state, здесь производится ожидание освобождения буфера.
- Если буфер полон, но следующий кадр уже пришел, то производится переход в состояние Report_state, в котором автомат ждет освобождения буфера и по освобождении помещает туда сообщение об ошибке. Затем автомат переходит в состояние IFG_state и ждет окончания текущего кадра путем определения паузы между кадрами, после чего переходит в исходное состояние — Idle.
Находясь в состоянии IFG_state, автомат управления приемным FIFO может осуществить только один переход — по определению окончания кадра — в состояние Idle.
Кроме автомата управления, в состав приемного FIFO так же входит счетчик числа целых пакетов, находящихся в буфере. Счетчик инкрементирует свое значение при записи слова управления «конца» пакета на стороне записи, то есть когда в буфер помещен целый кадр и сопровождающее его слово управления. Счетчик декрементирует свое значение при прочтении одного кадра на стороне чтения. Сигнал rd_begin означает, что в FIFO есть хотя бы один целый кадр, то есть значение счетчика числа целых пакетов, находящихся в буфере, не равно нулю или FIFO заполнен на половину. Этот сигнал можно использовать как запрос на прерывание по уровню для начала чтения буфера.
Как было сказано выше, данный блок поддерживает единую структуру сигналов управления. Сигнал rx_kadr от нижнего по иерархии блока запускает все процессы в данном блоке. Обработав данные, блок приемного FIFO передает верхнему по иерархии блоку сигнал rd_begin, который в свою очередь запускает процессы чтения данных из FIFO в верхнем блоке.
Работа FIFO на передачу
На рис. 3 приведено изображение блока FIFO на передачу — функции tx_fifo, а сигналы этого блока перечислены в таблице 2.
Передающий FIFO получает данные и сигналы управления от хоста, поэтому все, что относится к стороне записи — связано с хостом. Wrclk — системная частота хоста, wrData[Data_width-1..0] — шина данных на запись от хоста, все сигналы вида wr_хх_ena — это продешифрированные сигналы разрешения записи, которые формируются на дешифраторе адресов регистров, поступающих от хоста. Что же касается сигналов, которые формирует сам FIFO, то они тоже поступают в хост. Это сигналы состояния: wrempty — сигнал о пустоте в FIFO, wrfull — переполнение FIFO и wrhalf — заполненность данных на половину. Кроме того, в хост поступают сигналы от счетчика числа целых пакетов, находящихся в буфере, и от триггеров ошибок, которые проверяют правильность работы с FIFO.
Передающий FIFO передает данные и сигналы управления в передающую часть блока mii2_16, поэтому все, что относится к стороне чтения, связано с трактом передачи в линию. Rdclk — частота для чтения в передающем FIFO — формируется в трансивере после того, как он определит режим работы линии. RdData[Data_width-1..0] — шина данных на чтение из FIFO — поступает в передающую часть блока mii2_16, где из слов данных формируются 4-битные нибблы для передачи. Чтение данных производится по сигналам rd_data_ena — разрешение чтения данных, которые формируются в блоке mii2_16 во время передачи данных. Так же, на сторону чтения передаются и сигналы «сопровождения»: tx_begin — признак того, что можно передавать кадр и tx_data_end — признак окончания кадра.
Передающий FIFO работает следующим образом:
- По адресу регистра начала кадра (wr_kadr_len_ena) хост записывает 16-битное слово, означающее ХХХХ — число слов в пакете. Запись этого слова трактуется как начало кадра.
- По адресу регистра данных — wr_data_ena записываются слова данных, их число определяется емкостью буфера и величиной кадра. Если весь кадр не поместился в буфер, то он будет дописан при частичном освобождении буфера.
- Последнее слово кадра записывается по адресу регистра конца кадра — wr_kadr_end_ena. Туда можно записывать и «пустое» слово, но оно также будет передано в кадре.
- По адресу регистра управления wr_ctrl_ena может быть записана любая служебная информация, которая тоже будет помещена в тот же кадр данных с признаком служебной информации и далее будет извлечена из пакета при чтении. Можно записывать не более 3-х слов служебной информации подряд для режима 100 Мбит, кроме случая, когда требуется прервать передачу. В противном случае будет взведен триггер control_word_err — ошибка в положении слова управления в пакете.
- Чтение данных из FIFO на стороне приема начинается в том случае, если записан целый пакет, или буфер заполнен на половину.
- На приемной стороне производится контроль числа слов в пакете, и если есть несоответствие, то в поток данных, передаваемых далее в MII, вставляется сигнал «ошибка передачи» и взводится триггер ошибки длины пакета.
- Если чтение данных из FIFO уже началось и FIFO уже освободился, а новые данные не дописаны, то есть нет признака окончания кадра, то в поток данных вставляется сигнал «ошибка передачи» и взводится триггер time_word_err — когда из буфера все считано, а слово с «концом» пакета не пришло.
Автомат управления передающим FIFO имеет два состояния: Idle и Frame, см. первую часть статьи, рис. 7.
На стороне чтения производится определение состояния выходов тегов. Автомат ждет появления кода начала пакета и находится в состоянии Idle. При поступлении кода, соответствующего признаку начала пакета, автомат переходит в состояние Frame. При этом производится чтение слова из FIFO и значение, соответствующее числу последующих слов в пакете, помещается в счетчик, который будет проверять количество переданных слов. Далее в состоянии Frame возможны следующие события:
- Следующее слово на выходе FIFO — слово управления. Автомат управления формирует импульс чтения слова из FIFO. Слово управления считывается и помещается в регистр управления. Автомат управления продолжает находиться в состоянии Frame. Сигнал разрешения передачи для блока mii2_16 — tx_begin на этом этапе еще не формируется.
- На выходе FIFO нет данных. Автомат управления продолжает находиться в состоянии Frame.
- На выходе FIFO есть данные. Автомат управления продолжает находиться в состоянии Frame. Если на стороне записи в FIFO был записан признак «конца пакета», то счетчик пакетов, находящихся в FIFO, инкрементируется, и этот сигнал поступает в автомат управления. Он формирует сигнал разрешения передачи tx_begin для блока mii2_16. Чтение данных производится по сигналам разрешения чтения данных rd_data_ena, поступающим от mii2_16.
- На выходе FIFO есть данные. Автомат управления продолжает находиться в состоянии Frame. Если на стороне записи при записи данных в FIFO установится признак wrhalf — заполненность FIFO наполовину, но признак «конца пакета» еще не записан, то счетчик пакетов, находящихся в FIFO не инкрементируется. То есть началась передача большого пакета, и он целиком не помещается в FIFO. Поэтому сигнал wrhalf тоже поступает в автомат управления. Он формирует сигнал разрешения передачи tx_begin для блока mii2_16. Чтение данных производится по сигналам rd_data_ena.
- На выходе FIFO есть признак «конец пакета» и счетчик, который проверял количество переданных слов, не показывает ошибки по числу переданных слов. Есть успешное окончание передачи пакета. Счетчик пакетов, находящихся в FIFO, декрементируется, и этот сигнал поступает в автомат управления и в хост. Автомат управления переходит в состояние Idle.
- На выходе FIFO есть признак «конец пакета», но счетчик, который проверял количество переданных слов, показывает, что пакет передан не весь и данные «кончились рано». Взводится триггер ошибки длины пакета cnt_error. Происходит завершение передачи пакета. Счетчик пакетов, находящихся в FIFO, декрементируется, и этот сигнал поступает в автомат управления и в хост. Автомат управления переходит в состояние Idle.
- На выходе FIFO нет признака «конец пакета», но счетчик, который проверял количество переданных слов, показывает, что пакет передан весь. Взводится триггер ошибки длины пакета cnt_error. Происходит завершение передачи пакета. Счетчик пакетов, находящихся в FIFO, декрементируется, и этот сигнал поступает в автомат управления и в хост. Автомат управления переходит в состояние Idle.
- На выходе FIFO нет данных и FIFO пуст, но счетчик, который проверял количество переданных слов, показывает, что пакет передан не весь. Формируется сигнал ошибки time_word_err — когда из буфера все считано, а следующее слово не пришло. Ситуация возможна, если хост не успел дописать в FIFO очередное слово. По этому состоянию взводится триггер ошибки и блок mii2_16 устанавливает сигнал tx_er, по которому трансивер вставляет в поток данных на передачу соответствующие коды и сообщает абоненту о том, что в передаваемом потоке данных произошла ошибка. Автомат управления продолжает находиться в состоянии Frame.
- На выходе FIFO находится слово управления, но его не успели считать из FIFO к моменту прихода сигнала rd_data_ena — разрешение чтения данных. Формируется сигнал control_word_err — ошибка в положении слова управления в пакете. Ситуация возможна, если хост записал в FIFO слов управления больше, чем можно успеть считать. По этому состоянию взводится триггер ошибки и блок mii2_16 устанавливает сигнал tx_er, по которому трансивер вставляет в поток данных на передачу соответствующие коды и сообщает абоненту о том, что в передаваемом потоке данных произошла ошибка. Автомат управления продолжает находиться в состоянии Frame.
По окончании передачи, когда из FIFO извлекается признак конца кадра, что происходит вместе чтением последнего слова данных, в блок mii2_16 выдается сигнал tx_data_end о том, что передача данных текущего кадра закончена.
Описание блока mii2_16
Блок mii2_16 и является тем самым блоком, который выполняет основные функции МАС-контроллера. Он преобразует интерфейс FIFO в интерфейс MII, формирует передаваемый кадр данных, производит подсчет CRC на стороне передачи и автоматически добавляет CRC к кадру данных на передаче. Кроме того, на стороне передачи автоматически формируется пауза между кадрами — IFG. На стороне приема блок mii2_16 производит прием кадров от трансивера, выделяет кадры, предназначенные для данного контроллера или широковещательные кадры, производит проверку кадра по CRC. На стороне приема блок mii2_16 так же производит согласование интерфейса MII и интерфейса FIFO. Блок формирует 16 или 32-битные слова из принимаемых нибблов, причем по окончании кадра блок дополняет последнее принятое слово до требуемой разрядности.
На рис. 4 приведено изображение блока mii2_16, а сигналы этого блока перечислены в таблице 3.
Описание сигналов блока mii2_16
Блок mii2_16 имеет параметры:
- MAC_ADDR_0 = H»1234» — записывать адрес в прямом порядке следования байтов
- MAC_ADDR_1 = H»5678» — например, слово 693Е писать как 693Е
- MAC_ADDR_2 = H»9ABC»
Блок состоит из двух независимых частей: передающей и приемной.
Блок передатчика содержит следующие узлы:
- Сдвиговые регистры передаваемых данных t x _ d a t a _ s h i f t _ r g _ a [ 3 . . 0 ] , t x _ d a t a _ s h i f t _ r g _ b [ 3 . . 0 ] , t x _ d a t a _ s h i f t _ r g _ c [ 3 . . 0 ] , tx_data_shift_rg_d[3..0].
- Счетчик нибблов при передаче: tx_nibble_cnt (разрядность 5), выполняющий роль счетчика нибблов и таймера, определяющего паузы.
- Блок генерации CRC для передачи.
Передающая часть блока mii2_16 получает из FIFO на передачу следующие сигналы:
- Dout[15..0] — выходная шина данных из FIFO.
- Сигнал tx_begin — вызывает начало передачи в линию, устанавливается автоматом управления, когда FIFO на передачу заполнен наполовину или в FIFO уже есть один целый кадр.
- Сигнал tx_err — устанавливается автоматом управления FIFO, когда в потоке данных, поступающих из FIFO по каналу передачи, обнаруживается ошибка.
- Сигнал tx_data_end — устанавливается автоматом управления FIFO, передача данных данного кадра окончена.
Передающая часть блока mii2_16 отдает в FIFO на передачу следующие сигналы:
- Сигнал data_trm — устанавливается автоматом управления tx_process и показывает, что идет передача данных, преамбула уже передана.
- Сигнал data_trm_load — устанавливается автоматом управления tx_process и показывает, что идет загрузка данных в передатчик.
- Сигнал tx_rdy — устанавливается автоматом управления tx_process и показывает, что «слово передано».
- Сигнал tx_end — устанавливается автоматом управления tx_process и показывает, что передача кадра полностью завершена.
Передающая часть блока mii2_16 получает из хоста следующие сигналы:
Сигналы, поступающие по шине ifg_tmr[4..0], определяют длительность паузы между кадрами в линии.
Передающая часть блока mii2_16 отдает на передачу в MII следующие сигналы:
- TXD[3..0]: OUTPUT — Parallel data output ( input for transceiver ) path;
- TX_CLK: INPUT — Recovered clok input ( output for transceiver );
- TX_DV: OUTPUT — Data Valid;
- TX_ER: OUTPUT — Error.
Описание и назначение сигналов MII приведено в описании интерфейса MII.
Процессом передачи управляют автомат управления процессом передачи tx_process и счетчик нибблов при передаче tx_nibble_cnt.
Автомат управления процессом передачи tx_process имеет следующие состояния:
- Idle — исходное;
- Data_state — состояние, при котором передаются данные;
- Wait — состояние ожидания;
- Crc_state — состояние, при котором производится передача в линию CRC;
- IFG_state — состояние формирования паузы между кадрами в линии;
- Pause_state — ожидания снятия сигнала tx_begin.
Процесс передачи начинается с выдачи из хоста в блок FIFO на передачу одного целого кадра или FIFO на передачу заполняется данными наполовину. При этом автомат управления FIFO выдаст в блок mii2_16 сигнал управления tx_begin = 1. Этот сигнал вызывает начало передачи. Сигнал tx_begin запускает счетчик tx_nibble_cnt, а затем — автомат управления процессом передачи. Счетчик tx_nibble_cnt начинает отсчет нибблов, формирующих преамбулу, и в линию передается преамбула. Автомат управления процессом передачи tx_process в это время находится в состоянии Idle. Счетчик tx_nibble_cnt производит отсчет тактов при передаче. До тех пор пока счетчик не досчитает до 14, в линию будет передаваться преамбула. Когда будет достигнуто состояние tx_nibble_cnt.q[3..0] = 14, в линию будет передаваться преамбула и старт передачи. В этом же такте из FIFO загрузится первое слово на передачу. И в этом же такте автомат управления процессом передачи перейдет из состояния Idle в состояние Data_state. Когда будет достигнуто состояние tx_nibble_cnt.q[3..0] = 15, в линию начнут передаваться данные. Под сигнал tx_data_load = 1 производится загрузка передаваемых данных в сдвиговые регистры t x _ d a t a _ s h i f t _ r g _ a [ 3 . . 0 ] , t x _ d a t a _ s h i f t _ r g _ b [ 3 . . 0 ] , t x _ d a t a _ s h i f t _ r g _ c [ 3 . . 0 ] , tx_data_shift_rg_d[3..0]. Передача данных в и из MII обычно осуществляется в 4-битном формате — нибблами. Поэтому, когда сигнал tx_data_load снимается, т. е. становится равным нулю, то производится потетрадный сдвиг данных на выходную шину блока TXD[3..0].
Далее автомат управления формирует сигналы tx_rdy, по которым производится считывание данных из блока FIFO. Эти сигналы будут привязаны к частоте TX_CLK. Частота TX_CLK формируется в трансивере и определяется трансивером после автопереговоров в линии или назначается трансиверу при начале работы.
При выдаче нибблов данных в линию блок генерации CRC для передачи производит подсчет CRC.
Процесс передачи данных продолжается до тех пор, пока из блока FIFO не поступит сигнал tx_data_end, который устанавливается автоматом управления FIFO, когда передача данных данного кадра окончена. По получении этого сигнала автомат управления процессом передачи tx_process переходит из состояния Data_state в промежуточное состояние, формирующее такт задержки для перехода в состояние Pause_state, а оттуда в состояние Crc_state. Когда автомат управления попадает в состояние Crc_state, данные, полученные при подсчете CRC, выдаются в линию потетрадно.
По окончании передачи CRC, автомат управления из состояния Crc_state переходит в состояние IFG_state. При переходе в состояние IFG_state автомат управления формирует сигнал tx_end, который передается автомату управления FIFO и подтверждает завершение передачи кадра. При получении этого сигнала автомат управления FIFO снимает свой сигнал управления tx_begin.
Во время состояния IFG_state формируется пауза между кадрами в линии. Для этого по окончании состояния Crc_state счетчик tx_nibble_cnt обнуляется и начинает считать заново. Код, поступающий по шине ifg_tmr[4..0] из хоста, сравнивается с выходом счетчика tx_nibble_cnt, который используется в данном состоянии как таймер. После выдержки времени автомат управления из состояния IFG_state переходит в состояние Pause_state, где он находится в ожидании снятия сигнала tx_begin, поступавшего от автомата управления FIFO. Таким образом, следующая передача кадра возможна только в том случае, когда данный кадр передан полностью и оба автомата, участвующие в передаче кадра, — автомат управления передачей FIFO и автомат управления передачей mii2_16 полностью выполнили задачу и оба находятся в исходном состоянии для передачи нового кадра.
Блок приемника содержит следующие узлы:
- Регистры принятых данных rx_rg_a[3..0], rx_rg_b[3..0], rx_rg_c[3..0], rx_rg_d[3..0]
- Счетчик нибблов при приеме rx_nibble_cnt (разрядность 2)
- Счетчик слов MAC-адреса при приеме addr_word_cnt (разрядность 2)
- Блок проверки CRC на приеме: rx_crc : crc32_nibble.
Приемная часть блока mii2_16 получает из трансивера следующие сигналы интерфейса MII:
- RXD[3..0]: INPUT — Parallel data input (output for transceiver) path;
- RX_CLK: INPUT — Recovered clock input (output for transceiver);
- RX_DV: INPUT — Data Valid;
- RX_ER: INPUT — Error.
Приемная часть блока mii2_16 отдает в FIFO на прием следующие сигналы:
- Din[15..0] — выходная шина данных — вход для FIFO.
- Сигнал готовности выдачи одного слова данных rx_rdy.
- Сигнал data_rcv — вызывает начало приема данных, выдается под фронт RX_CLK.
- Сигнал rx_rdy_addr — готовности выдачи слов, что МАС-адрес уже определен.
- Сигнал rx_dv_addr — Data Valid — с учетом того, что МАС-адрес уже определен.
- Сигнал addr_hit — MAC-адрес выбран.
- Сигнал multicast_addr — есть признак широковещательного кадра.
- Сигнал data_rcv_addr — вызывает начало приема данных с учетом определения МАС-адреса.
- Сигнал rx_begin.
- Сигнал rx_crc_eq — подсчет CRC совпал с заданной константой.
Процесс приема для блока mii2_16 начинается с определения состояния сигнала RX_DV, поступающего от трансивера. Этот сигнал устанавливается, когда из линии в трансивер приходят коды, определенные как коды данных для трансивера. Трансивер помещает первую тетраду на свою выходную шину RXD[3..0], и устанавливает сигнал RX_DV. Эти данные под сигнал приемной синхрочастоты RX_CLK записываются во входной регистр приемной части блока mii2_16. Частота RX _CLK формируется в трансивере и определяется трансивером после автопереговоров в линии или назначается трансиверу при начале работы. Приемник проверяет принятые тетрады на совпадение с кодом «5D», соответствующим Start Frame Delimiter (SFD). Код SFD отделяет преамбулу от остальных полей кодов в кадре. При получении SFD запускается узел, определяющий МАС-адрес устройства. МАС-адрес устройства в данном варианте проекта задается как набор параметров: MAC_ADDR_0, MAC_ADDR_1, MAC_ADDR_2. Определитель МАС-адреса устройства состоит из двух частей. Первая определяет уникальный МАС-адрес. Для этого тетрады, приходящие от трансивера на вход приемника, поочередно сравниваются с соответствующими тетрадами МАС-адреса. Этой цели служит счетчик слов MAC-адреса при приеме — addr_word_cnt, мультиплексор, схема сравнения и соответствующие триггера. Вторая часть определяет широковещательный адрес. Когда счетчик принятых слов отсчитает 6 принятых байт, производится прием данных, если МАС-адрес выбран или это широковещательный кадр, или приемник заканчивает работу и ждет, когда сигнал RX_DV будет снят, а затем снова установлен с приходом следующего кадра. Если определитель МАС-адреса дает сигнал rx_dv_addr о том, что MAC-адрес выбран, то взводится либо триггер addr_hit (уникальный MAC-адрес выбран), либо триггер multicast_addr (есть признак широковещательного кадра). Затем устанавливается сигнал rx_begin, который поступает на вход приемного FIFO и все слова данных, принятые из MII и преобразованные из тетрад в 16-битные слова, помещаются в FIFO. Слова данных стробируются сигналом rx_rdy_addr, который формируется при формировании 16-битного слова. Если процесс приема заканчивается с нечетным числом принятых байт, то блок дополняет нулями последнее принятое слово до 16-битного формата. Во время приема кадра производится проверка принятого и обработанного потока данных в блоке приемного CRC. Если совпадение происходит, то устанавливается сигнал rx_crc_eq — подсчет CRC совпал с заданной константой. Этот сигнал поступает в приемный FIFO на шину статуса и записывается в FIFO как служебная информация по окончании приема кадра. Сигналы триггеров addr_hit и multicast_addr также записываются в FIFO как служебная информация по окончании приема кадра.
Сигнал CRS не обрабатывается в блоке mii2_16, поскольку его нет необходимости обрабатывать, когда установлен дуплексный режим.
Описание контроллера MI в FPGA
Контроллер представляет собой блок, формирующий диаграмму интерфейса MII MI, описанную выше, см. первую часть статьи, рис. 6.
На рис. 5 приведено изображение блока mii, а сигналы этого блока перечислены в таблице 4.
Блок состоит из частей:
- Узел связи с интерфейсом хоста — блока регистров, на которых хранится адрес и данные для передачи в MI.
- Приемо-передающий узел для обмена сигналами по интерфейсу MI на сдвиговом регистре, счетчик битов и автомат управления передатчиком и приемником.
Блок mi содержит следующие узлы:
6-разрядный счетчик битов bit_cnt, буферный регистр передаваемых адресов Addr[10..0], буферный регистр передаваемых данных D[15..0], сдвиговый регистр принятых и передаваемых данных shift_rg[15..0], триггер готовности rdy_tg.
Для упрощения принято, что код операции будет представлять собой старший бит в слове адреса, тогда с точки зрения программы будут отдельные адреса для записи и отдельные для чтения данных.
Порядок работы с блоком mi следующий. Сигнал записи в регистр адреса A_wrn инициализирует процесс обмена по интерфейсу MI. Поэтому для чтения данных из MI нужно только произвести запись слова адреса, которое будет содержать код операции «чтение», адрес требуемого трансивера и адрес регистра трансивера. Во время цикла обмена готовность снимается, а по завершении обмена — устанавливается. При установлении триггера готовности rdy_tg на выходной шине блока Din[15..0] будут находиться данные, полученные из MI. Для записи слова данных в MI нужно сначала записать слово данных для передачи в MI в регистр передаваемых данных. После этого нужно записать слово адреса, но с кодом операции «запись» и аналогично указать адрес требуемого трансивера и адрес регистра трансивера. Далее, как и в цикле чтения, при установлении триггера готовности rdy_tg блок будет готов к следующему циклу обмена.
Блок работает следующим образом. При записи в регистр адреса по положительному перепаду сигнала A_wrn триггер готовности сбрасывается и разрешает работать счетчику битов bit_cnt, который начинает отсчитывать такты преамбулы. Выходной трехстабильный порт MDIO исходно открыт и в MI выдаются биты преамбулы. Когда счетчик доходит до значения H»1F» в сдвиговый регистр shift_rg[15..0] переписываются стартовые биты, код операции, код адреса и значения двух битов, требуемых для разворота шины. При записи эти два бита имеют значение B»10», а при чтении — B»00». Производится сдвиг, и на выход MDIO выдаются требуемые по интерфейсу значения адреса и служебных битов — старта, кода операции, битов для разворота шины. В цикле записи в MI порт и далее остается открытым, а в цикле чтения, когда счетчик достигает значения H»2E», выходной порт закрывается и остается закрытым до конца цикла обмена. Когда счетчик досчитывает до значения H«2F», в сдвиговый регистр переписываются данные из буферного регистра передаваемых данных D[15..0]. Производится цикл приема-передачи данных в MI. Данные с выхода сдвигового регистра поступают на порт с трехстабильным выходом, и если он открыт (цикл запись), то эти данные выводятся в MI. Данные со входа MI поступают на вход сдвигового регистра и заполняют этот регистр. Если производится операция чтения, то к моменту приема данных порт с трехстабильным выходом будет закрыт, и все данные, принимаемые из MDIO, будут данными, которые передавал трансивер. Данные со входа MI заполняют сдвиговый регистр и выдаются на выходную шину данных блока Din[15..0] Эта шина будет входом для хоста при чтении данных из блока. Когда счетчик достигнет значения H»3F», сформируется сигнал для установки триггера готовности, который в свою очередь, остановит счетчик. Выходной трехстабильный порт MDIO открывается. На этом цикл обмена завершается.
Подсчет CRC32 производится в блоке CRC32_nibble, выполненном в соответствии с документацией Л[5].
Образующий полином: X^32 + X^26+ X^23+ X^22+ X^16+ X^12+ X^11+ X^10+ X^8+ X^7+ X^5+ X^4+ X^2+ X^1+ X^0 преобразуется в константу H»04C11DB7», подаваемую на вход poly[31..0] блока. Блок представлен на рис. 6, а сигналы блока представлены в таблице 5.
Работа блока
При установке на входе sload = 1 происходит загрузка в регистры исходного состояния для подсчета CRC32.
При sload = 0 и shift = 1, происходит подсчет контрольной суммы. Блок отличается от мегафункции фирмы Altera тем, что если при его использовании задействован вход shift, то при sload = 0 и shift = 0 происходит сдвиг данных из регистра потетрадно.
Программирование МАС-контроллера со стороны хоста
Контроллер состоит из 2-х частей:
- MI — служебный интерфейс
- МАС — контроллер
Программирование MI
- MI предназначен для чтения и записи данных в регистрах трансивера.
- MI программируется как порт с 16-битным словом.
- Адресация регистров трансивера косвенная.
- Для чтения регистра трансивера в MI записывается слово адреса регистра трансивера. Формат слова адреса:
- D [4..0] — register addr — адрес регистра трансивера;
- D [9..5] — PHY addr — физический адрес самого трансивера, устанавливается переключателями на трансивере;
- D [15..10] = «0» — чтение.
- Для записи данных в регистр MI записывается слово адреса регистра трансивера
Формат слова адреса MI:
- D [4..0] — register addr — адрес регистра трансивера;
- D [9..5] — PHY addr — физический адрес самого трансивера, устанавливается переключателями на трансивере;
- D [10] = «1» — запись;
- D [15..11] = «0».
Чтение и запись производятся по готовности.
Меняя режимы работы трансивера можно устанавливать различные режимы, такие, как программный сброс трансивера, состояние петли, позволяющее проверить прохождение данных через МАС-контроллер и трансивер, рабочее состояние. Можно менять режимы индикации светодиодов, подключенных к трансиверу.
Программирование МАС
Обычно уникальный адрес MAC-адрес «прошивается» в устройстве при его изготовлении фирмой-изготовителем. Зоны адресов «поделены» между изготовителями оборудования так, что в сети не должно быть двух устройств с одинаковыми адресами. В рассматриваемом здесь проекте сетевой адрес MAC может задаваться при загрузке FPGA, то есть изготовителем устройства или программно загружаться хост-процессором. В случае загрузки с хост-процессора у сетевого администратора при настройке сети появляется возможность изменить MAC-адрес.
Для примера рассмотрим программирование МАС-контроллера, не имеющего каналов DMA. В такой контроллер данные передаются в программном режиме. МАС-контроллер программируется как порт с 16-битным словом или 32-битным словом, в зависимости от реализации. Данные записываются и читаются либо при опросе готовности FIFO, либо по прерываниям. Сигналы регистра статуса и регистра контроля MAC-контроллера приведены в таблицах 6–7. Эти регистры доступны на чтение и содержат всю информацию, необходимую для контроля работы устройства.
Для записи данных в МАС-контроллер производятся следующие действия:
- Читается готовность на передачу, и если буфер пуст или пуст наполовину, то в буфер записываются слова данных. Если пакет не влезает в буфер, то ждем освобождения буфера и «подкачиваем» данные порциями до тех пор, пока в буфер не будет записан весь пакет. При этом в буфер дописывается определенное число слов данных, это число, например, может быть равно половине емкости буфера. То же самое производится и в режиме работы по прерываниям.
- Когда все слова данных записаны в буфер, то по адресу «конец пакета», записывается еще одно слово и это может быть последнее слово пакета или пустое слово. Обращение хост-процессора по адресу «конец пакета» записывает в FIFO признак «конец пакета» и при этом инкрементируется счетчик числа пакетов на передачу в буфере. Передача пакета инициализируется в двух вариантах. В первом варианте пакет целиком помещается в буфер, и тогда передача начинается при записи признака «конец пакета». Во втором варианте, когда пакет целиком не помещается в буфер, передача начинается при заполнении буфера наполовину.
Для чтения данных из МАС-контроллера производятся следующие действия:
- Читается готовность на прием, и если готовность есть, то производится чтение данных. Так же на чтение доступен счетчик принятых целых пакетов. То есть, если есть целые пакеты, то читаем целый пакет, иначе читаем только часть пакета (весь пакет не влез в буфер). Чтение данных можно производить пословно, проверяя состояние «буфер пуст», или можно производить чтение данных «порциями» фиксированной длины. При чтении данных в пакетном режиме необходимо проверять состояние «буфер пуст наполовину». При работе с прерываниями чтение можно производить до момента получения прерывания, означающего получение конца кадра, или прерывания, означающего состояние «буфер пуст наполовину». Поскольку автомат управления приемным FIFO производит блокирование чтения слов данных после получения признака «конца кадра», то прочитать «лишние» данные из следующего пакета невозможно. Эта блокировка будет снята только при чтении слова состояния по адресу регистра статуса.
- Читается слово контроля и производится анализ битов регистра контроля. Если принятый кадр не имеет признаков ошибок при приеме (то есть нет ошибок по CRC, не было переполнения буфера, не приходил сигнал RX_ER и т. д.), то принятый кадр считается достоверным.
- Читается слово состояния. Производится анализ битов регистра статуса. Принимается решение о продолжении приема данных из буфера.
В том случае, если контроллер имеет каналы DMA, процессы приема и передачи значительно упрощаются, поскольку примененный в данном проекте принцип организации FIFO позволяет провести аппаратное согласование всего тракта как на прием, так и на передачу. Для передачи необходимо просто указать адрес пакета в поле памяти и его длину. По окончании передачи или при ошибке передачи будет получено прерывание. То же самое и для канала приема: необходимо только указать адрес в поле памяти, куда должен быть записан пакет. По окончании приема или при ошибке приема будет получено прерывание. Такой способ работы значительно уменьшает нагрузку на хост-процессор, но требует некоторого увеличения задействованного в FPGA ресурса.
При отладке проекта была разработана тестовая программа, позволяющая загружать FPGA, контролировать режим работы трансивера, передавать и принимать пакеты. На рис. 7 приведено окно тестовой программы, позволяющее читать регистры трансивера, производить запись режимов работы. На рис. 8 приведено окно программы, при помощи которого производится запись пакета в буфер, инициализируется передача данных и производится прием данных. Мониторинг сети проводился стандартными программами, например netXray3.
Заключение
Приведенное в данной статье описание проекта МАС-контроллера, конечно, не является полным описанием. Но тем не менее оно позволяет представить суть проекта, произвести оценку требуемых для данного проекта ресурсов, оценить его трудоемкость. В данной статье более подробно описаны те проблемы, которые наиболее часто поднимаются в телеконференциях, а следовательно, интересуют разработчиков.
Литература
- А. Сигаев. Embedded Internet // Компоненты и технологии. 2000. № 2.
- Н. Олифер, В. Олифер. Высокоскоростная технология Fast Ethernet (IEEE 802.3u). Центр Информационных Технологий (lxt972d.pdf).
- Л. Куин, Р. Рассел. Fast Ethernet. BHV. 1998.
- М. В. Кульгин. Коммутация и маршрутизация IP/IPX трафика. М.: Компьютер Пресс. 1998.
- Implementing CRCCs in Altera Devices и ALTERA CRC MegaCore Function, Parameterized CRC Generator/Checker Data Sheet. ALTERA AN049.