Category: компьютеры

Category was added automatically. Read all entries about "компьютеры".

QuatCore

DMA для QuatCore

Вот фрагмент схемы нашего "процессорного ядра" QuatCore:


Справа сверху "притаилась" оперативная память. На той ПЛИС, что у меня есть сейчас (5576ХС4Т) и той, что хотел бы применить в лётном изделии (5576ХС6Т) полноценной двухпортовой памяти нет. Максимум - можно одновременно осуществлять чтение на один адрес и запись на другой адрес, при условии, что адреса не совпадают (если совпадают, то на выход пойдёт только что записанное значение, конкретно в этих ПЛИС, если они ведут себя аналогично Flex10k до последних мелочей). Но я пока и эту возможность не использовал из-за своей исключительной жадности: это бы потребовало два отдельных формирователя эффективного адреса, а они довольно толстые (выбрать базовый регистр, выбрать первый индексный, второй индексный регистры - и всё сложить).

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

Сейчас адрес используется ровно один. Кроме него, на оперативную память поступают 16 бит для записи, напрямую из шины данных, сигнал WREN (WRite ENable), а выход отправляется в модуль QuatCoreMem, где стоит мультиплексор, срабатывающий на "квадратные скобки" в мнемонике команды. Если они стоят - значит нам нужно значение из памяти, коммутируем его. Если нет - значение одного из регистров (X,Y,Z,SP), выдадим его.

Теперь бы как-нибудь к этой же памяти подключить "провода" D,Q, MemWrReq, MemRdReq и MemReady из протокольного контроллера МКО, желательно малой кровью... Обеспечить ему пресловутый Прямой Доступ к Памяти, или Direct Memory Access (DMA)...

Collapse )

Схема "верхнего уровня":


Барабанная дробь... Синтезируется в 1704 ЛЭ (перед фиттером), 1732 ЛЭ (после фиттера). Timing Analyzer: все требования выполнены, предельная частота 26,04 МГц!

Как-то слишком просто... Я ожидал, что будет эдак 20 МГц, и ещё неделю-другую надо будет "конвейер перебирать", чтобы вернуться к родным 25 МГц. Какая-то жуткая подлянка затаилась и ждёт своего часу.

Ну ладно, с завтрашнего дня начинаю отладку. Разрозненные части, наконец-то, собираются в целое.
QuatCore

"МКО через UART" в железе - 2

Продолжим проверять этот модулёк.


Collapse )

Выглядит неплохо! Есть, что улучшить:
- пусть и на индивидуальную команду "Синхронизация (с СД)" отвечает правильно, подтверждая, что команда пришла,
- если "пообещать" длинное сообщение (например, 32 слова), но не передать его целиком - контроллер будет до посинения ждать, пока нужное число слов данных будет передано, здесь никакого таймаута пока не предусмотрено. Когда "ручками" с ним общаешься - неприятно, что-то немного не то вбил - и вдруг ни ответа ни привета, и поди разберись, что с ним. На деле, не так уж это и страшно, пошлёшь запрос повторно, он "доберёт" сколько надо слов, уйдёт в sIdle по несовпадению CRC, и дело с концом. Но вообще с таймаутом правильнее, ГОСТ предписывает проверять временнЫе параметры и при отступлении от норм тихо ругаться.
- у меня были предусмотрены команды "дамп памяти" и "передать изображение", там маленькими кусочками передаётся содержимое памяти, "внутренней" и "внешней" соответственно. Можно было бы это дело на контроллер "взвалить", чтоб делал без участия процессора. Но пока было лень...

А сейчас, пожалуй, надо взяться за DMA.
QuatCore

"МКО через UART" в железе

Долго мучали эту штуковину на симуляции, пора уже в макет это прошить и посмотреть, как оно себя поведёт.

Оставлю "основную схему" (процессор, SPI, контроллер ЖК-экранчика, видеообработчик, детектор и селектор синхроимпульсов), но "отниму" у неё RS485 и "отдам" его новой схеме, этому самому "МКО". Позже они должны будут получить общий доступ к памяти, но давайте сначала обособленно его проверим.

Окинем прощальным взором львиную долю "схемы" TopLevel:


Collapse )



Что-то есть. Первое сообщение "начинаем работу" - это от старой прошивки. При подаче питания срабатывает она, потом я по JTAG "запихиваю" в ПЛИС текущий проект. Это показывает, что по крайней мере "железо" рабочее.

Далее даю командное слово: адрес 6, подадрес 110002, передача ОУ-КШ, передать одно слово данных. Байты переставлены местами, потому как у меня приёмник и передатчик передают по 16 бит за раз, от младшего бита к старшему, а на компьютере передаётся по байту, от младшего бита к старшему, из-за чего "endian" меняется.

В ответ получаю ответное слово 0x3000 (адрес 6, все флажки сброшены, "всё в порядке") и одно слово данных: 0000. Да: по нашей логике последнее слово это всегда CRC, даже если оно по совместительству первое :) Вот это оно и есть, CRC от пустого сообщения!

Потом посылаю командные слова на "чужой" адрес 0, и никакого ответа не получаю. Всё верно.

В следующий раз заказал по тому же адресу и подадресу ("телеметрия") 2 слова данных - и получил заголовок массива телеметрии, 0xFF00, а затем CRC от него. Тот же CRC можно получить на crccalc.com, если ввести 00FF, и в строке CRC16/KERMIT в результате 0x0F78 переставить местами байты.

Потом ещё попробовал 3 слова данных, 4, 5, 6, 7. Результат: ответное слово, за ним заголовок массива, за ним сплошные нули (ну да, здесь я в память никаких "интересных" значений не клал), и CRC. Во всех случаях корректный.

И ещё "заказал" 0 слов данных, только этот ноль в МКО (ГОСТ Р 52070-2003, Mil-Std 1553) интерпретируется как 32 слова, что нужно было также прописать в коде. Что ж, эта часть также работает, выдаётся ответное слово и ещё 32 слова данных, последнее из которых: CRC.

Продолжение следует...
QuatCore

"Ошибка на единицу" при передаче CRC

В прошлый раз обнаружили нехорошую вещь: при передаче данных от нашего устройства, CRC начинает работать одним словом раньше, чем надо, и результат своей работы отсылает одним словом раньше.

Пора уже это исправить, чего-то задолбался я немного.

Collapse )
Действительно обошлись "малой кровью", не добавив ни одного ЛЭ.

Вот, кажется, и всё, протокол информационного обмена исполнен в полном объёме, на "жёсткой логике", без обращения к процессору.

Осталось всё это "в железе" посмотреть, заодно написав "программу рабочего места". Потом, если всё нормально, написать примитивный DMA. Дальше ожидаю раунд борьбы с фиттером, который может завалить трассировку всего проекта целиком, и второй раунд, когда в кои-то веки придётся все части программы свести в единое целое, так что и ROM и RAM подрастут, и ширина адресных шин вместе с ними.

Тяжело идёт, и уже как-то "через силу". Кажется, что всё творческое уже позади, а сейчас надо просто стиснуть зубы и довести хреновину до кондиции...
QuatCore

"МКО через UART", часть 5, проверка командного слова

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

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

Collapse )

Я доволен, провели практически полное покрытие кода - всё работает. Осталось ещё с командами управления разобраться, это уже завтра.
QuatCore

"МКО (Mil-Std1553) через UART", часть 1

Громко подумали, пора начать ковыряние.

Вообще, я очень надеюсь, что написанный сейчас модуль практически без изменений подойдёт для "нормального" МКО. Там, разве что, ещё логику резервирования надо будет продумать, когда два приёмника, два передатчика, и ответ надо посылать по той шине, по которой мы получили запрос.

Сейчас идея, что этот контроллер работает независимо от процессора, напрямую обращаясь к памяти. Это "Оконечное Устройство" (ОУ, оно же Remote Terminal), т.е оно само не может инициировать информационный обмен, только отвечать контроллеру шины (КШ, Bus Controller).

И сделаем "задел" для реализации по ГОСТ 52070-2003 задания адреса оконечного устройства с помощью перемычек, хотя на первое время они будут "виртуальными" внутри ПЛИС :)

Не буду пытаться сделать "универсальный модуль на все времена", потому как неизбежно получится что-то вроде 1895ВА2Т, на которую под 300 страниц документации, где ещё попробуй разберись! Реализую лишь те функции, что нужны мне конкретно в этом приборе.

Начинаем традиционно с заголовка, тут он очень упитанный:
module MilStdRemoteTerminalController (input clk,
		//интерфейс с приёмником МКО
		input [15:0] D, input RXisData, input DataValid,
		//интерфейс с передатчиком МКО
		output [15:0] Q, output TXisData, output start, input TxBusy,
		//интерфейс с оперативной памятью (малого объёма, около 1000 слов)
		output [MemWidth-1:0] Addr, input [15:0] MemIn, input MemReady, output MemWrReq, output MemRdReq,
		//интерфейс с часами реал времени
		output sync, input [15:0] TimeStamp,
		//интерфейс с адресной заглушкой
		input [4:0] OurAddr, input AddrParity);
		
parameter MemWidth = 8;




Collapse )

Нда, снова громко подумали, написав аж 15 строчек кода... Продолжение следует! Там уже возьмёмся всерьёз.
QuatCore

"МКО (Mil-Std1553) через UART", часть 0

Некая подготовительная работа, конечно, уже проведена, ровно для этого мы сделали 16-битные передатчик и приёмник UART: они не только удобнее согласуются с 16-битным процессором, отправляя по одному слову за раз, но и куда ближе к этому самому МКО (ГОСТ Р 52070-2003), не на физическом уровне конечно (там манчестерский код и безусловная гальваническая развязка через трансформатор), но на логических. А дальше просто "поменяю" приёмопередатчик, подключённый к ПЛИС, и будет мне счастье.

А то паять два устройства МКО, общающихся друг с другом как-то стрёмно: они вполне могут нормально заработать, обмениваться информацией, только это будет ни разу не МКО, а какой-то "свой диалект" :) Покупать на свои PCIную плату чего-то совсем не хочется, последний раз когда я спрашивал цену, озвучивали 66 000 рублей, и ещё не факт что физическому лицу продадут. Где-то на предприятии, может даже в отделе, должен лежать компьютер с установленной платкой МКО, но пока удобнее всё отлаживать "у себя", а за этот компьютер засесть, когда уже почти всё будет готово.

В штатном приборе приёмник МКО явно должен быть достаточно умным, чтобы хотя бы "отфильтровывать" все командные слова, адресованные "не нам". Уж больно их много: устройств сидит чуть ли не под завязку, 30 штук, и каждого по крайней мере 5 раз в секунду опрашивают, а то и побольше: отдельно выдача целевой информации и отдельно телеметрия. И если бы нам приходилось каждый раз отвлекать процессор на такую фигню, он бы точно запарывал каждый кадр изображения, там его отвлекать нельзя!

Я стал думать, насколько это легко, "отпарсить" весь поток информации и выделить адресованную "нам" и на некоторое время впал в полнейший ступор, как же нам слово данных от командного слова отличить?


Ведь в слове данных могут произвольные 16 бит лежать, чего бы им не совпасть с определённым командным словом? Получается, надо чётко прослеживать логику посылок, типа "вот сейчас была пауза, значит первое слово - командное, в нём было запрошено 32 слова данных (СД). Значит, сейчас отсчитываем 33 слова: сначала ответное, потом СД, а первое после них - это и будет следующее командное слово!" И всё бы хорошо, но стоит один раз ошибиться - и можно по "мусору" из слов данных очень долго строить соответствующие цепочки и отлавливать непонятно что. Чисто по паузам ориентироваться?

Потом вспомнил, где собака зарыта...

Collapse )

В общем, что-то начинает проглядываться. Вот думаю, может сделать-таки здесь DMA, причём приоритет всегда за процессором, а контроллер информационного обмена может и подождать пару тактов, всё-таки информационный обмен весьма нетороплив, одно слово за 20 мкс, это 500 тактов!

Была другая идейка, но возможно она слишком "толстая". Там пара модулей памяти воткнуты между процессором и этим контроллером. В первый модуль процессор может только записывать, в любое время, а контроллер может читать в любое время (память в ПЛИС двухпортовая). Второй модуль - всё наоборот, причём адреса "на запись" и "на чтение" по сути они делят. Например, процессор запишет по адресу "0" - тем самым передаст первое слово целевой информации. А прочитает по адресу "0" - получит первое слово полётного задания. Но с DMA можно сделать контроллер более "самостоятельным" - с дампом памяти он сам справится, не заставляя процессор чего-то готовить :)

Такие вот мысли вслух...
QuatCore

"16-битный" передатчик UART

До сих пор у меня передатчик UART подсоединялся к 16-битной шине данных процессора, но брал из неё только младшие 8 бит, остальные игнорировал. Для передачи текстовой информации самое то, особенно с появлением байтового режима доступа к памяти. Но вот передавать 16-битные данные становится очень большой проблемой. Для дампа памяти ещё нашлось решение, как раз-таки через байтовый режим прочитать сначала все старшие байты, потом все младшие, а уже на компьютере их "склеить", но тоже костыль, что ни говори.

Всё-таки я уже решил: текстовую информацию буду выводить на ЖК-экранчик, чтобы наиболее наглядно продемонстрировать, что он уже "сам" всё обнаруживает и вычисляет. (когда оно подключено к компьютеру, могут возникнуть сомнения - может компьютер тоже вносит посильную лепту?) А уж если мы к этому делу приплели компьютер, надо уже переходить на передачу информации в "машинном" виде, тем более что рано или поздно предстоит заменить UART и RS485 на МКО, он же МКИО, он же Mil-Std 1553, он же ГОСТ Р 52070-2003, а там данные идут 16-битными словами.

То есть, я хочу, чтобы одна команда OUT, когда источником выбран UART, передавала бы два байта подряд. Какой сначала - старший или младший (endianness пресловутый) - это на наше усмотрение, главное потом на принимающей стороне не ошибиться.

Вроде бы халявная задача, а чего-то сегодня полдня соображал "как лучше" это сделать...

Collapse )

Завтра попробуем запустить. Сегодня ждал приезда заказчиков из РКК Энергия, приехал по такому случаю с утра, а оказалось, они так и не приедут, узнал об этом где-то час назад. Чего-то утром гораздо хуже мне соображается. Куда-то совсем не в ту степь полез, и только к 16:55 понял, как надо :) А тут уж и уходить пора.
QuatCore

FIFO уходит в себя - окончание

Начало

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



Collapse )

И наконец, испытаем "на железе", попытаемся получить изображение:


Кстати, качество получше стало: практически правильный уровень чёрного, нет такого "перенасыщения", как раньше. Это я две детали из схемы выкинул нафиг (одну выпаял, другую закоротил) :) Как так вышло, напишу отдельным постом.
QuatCore

Слишком общительный FIFO ушёл в себя...

8-го апреля я хотел запустить "супрематический алгоритм" обнаружения точек в железе (на своём макете), но для этого нужно было увеличить размеры буферов FIFO на вход и выход, чтобы всё влезло, а когда я это сделал - опять перестал "проходить" по таймингам. Мне квартус выдал Critical Warning, что работоспособность этой "схемы" на 25 МГц он не гарантирует.

Чтобы это исправить, пришлось довольно основательно "перебрать" QuatCore - "отбалансировать ему конвейер". Этого самую малость не хватило, и наблюдая дальше failed paths (слишком длинные комбинаторные пути, по которым переходные процессы и не успевают затихнуть к фронту тактовой частоты) увидел, что очень "жадное" исполнение входного буфера FIFO привело к "комбинаторной связи" между потрохами видеопроцессора и основным процессором, что и было, вероятно, главной проблемой.

Балансировки конвейера я очень боялся, был уверен, что чего-то поломаю, поэтому устроил ему жуткие испытания в лице нового алгоритма захвата на ближней дистанции. Как результат, на месяц "отвлёкся" от обнаружения точек, и вообще ушёл в "симуляцию" (the matrix has you), и да, именно с матрицами я и возился до упора :)

А вот вылечивание FIFO от излишней "болтливости" казалось плёвым делом, я даже проверять не стал, и почти что забыл об этом изменении.

А зря: когда на этой неделе я решил вернуться к "железу" и для начала "повторить пройденное" - получить изображение на компьютер - делать это макет отказался напрочь! Он на этом месте вис наглухо, и даже ни одного прерывания не возникало.

После танцев с осциллографом, проследив работу АЦП и выведя на отдельный шлейф "отладочные сигналы" с выходов нашего детектора и селектора синхроимпульсов, я понял: они работают нормально. Проверку чётности я тоже отключил от греха подальше, мало ли. Но мы всё равно висли. Только тогда я вспомнил об этом FIFO, поставил только что введённый там параметр AllowRWwhenFull = 1'b1 (т.е вернул "как было"), опять получил Critical Warning и предельную частоту 23,36 МГц, плюнул на это и прошил всё равно - и получил-таки изображение!

Collapse )

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