Как стать автором
Обновить
4
0
Yuri Klimov @yuklimov

Пользователь

Отправить сообщение

Я начал лет на 15 позже, все успокоились, наверное, т.к. std_logic_unsigned нормально поддерживается всеми используемыми инструментами. Рекомендацию слышал, но писать как предлагает numeric_std вообще не захотелось. Явно это были голоса тех, то продвигали Verilog ;)

Я использу ieee.std_logic_unsigned.all, и тогда std_logic_vector можно складывать без приведения.
Да, в VHDL нет расширения до размера результата, а только до максимальной ширины аргументов, но это спорный вопрос что лучше. Больший контроль за разрядностью - меньше ошибок, но чуть больше кода, когда надо разрядность изменить.

P.S. Сразу скажу, что в моих ПЛИС и чипах нет знаковых чисел совсем (вот такие задачи ;)), да и расширения разрядности тоже не вспомню, чтобы требовались, кроме при выдачи в PCIe, где все регистры, видимые из процессора, 32 битные.

P.P.S. В листинге про 2+2 sum потерялось.

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

P.S. Мой вариант с счетчиком - это по сути и есть FIFO ширины 0, только реализованная руками.

А какое решение Apple предполагает?

При низкой интенсивности можно вместо уровнем '1' кодировать сменой '0'->'1' или '1'->'0'.

Если интенсивность высокая то, то можно завести счетчик выбранных из FIFO пакетов (в кодировке Грея) и чего инкрементировать. А на приемной конце завести счетчик посланных в FIFO пакетов и кредит - их разность. Только в этом случае обратно не один провод, а шина. В каком-то смысле это и есть адреса в FIFO. Примерно так я и делаю, когда надо через PCIe кредитный трафик гнать.

Всё так, можно было не расписывать ;).

Мне нужны были и кредиты, и переход между клоками. Делать две FIFO в ПЛИС, где блоков памяти мало, не целесообразно. Поэтому и делал всё на одной FIFO. И т.к. FIFO большая, то экономить ячейки не стоит.

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

Наверное не очень аккуратно выразился. С двух местах надо указывать размер FIFO: в самом FIFO, и в счетчике. Можно ошибиться ;). Как можно ошибиться с количеством шагов конвейера (тогда схема с подсчетом кредитов в FIFO сломается).

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

Но и такое решение имеет право на жизнь: в ПЛИС FIFO на 1 шт. блочной памяти будет иметь зачастую больший, чем нужно размер. Или если FIFO двухклоковое, то напрямую кредит как в Вашем рисунке https://habr.com/ru/post/706484/#comment_25030966 не проведешь. Или бывает нужно пропустить кредитный сигнал через регистр для лучший разводимости, тогда в FIFO надо закладывать запас для максимальной пропускной способности.
Я у себя для таких потоковых задач (в том числе и с мультиплексорами и демультиплексорами), и для мультиплексоров использую а-ля almost_full сигнал: из FIFO вывожу количество свободных мест, из него вычитаю количество регистров на пути данных от источника до FIFO, так и на пути этого управляющего сигнала от FIFO до источника, и если величина положительна, то можно слать. Тогда всё вычисление кредита локализовано у FIFO (а не находится в двух местах, где надо одновременно менять размер FIFO), а источник по сигналу посылает данные.
В общем, специалист должен знать многие варианты и понимать когда что лучше использовать.

Впечатляет!

А не думали делать замкнутый контур охлаждения? Чтобы воздух с пылью извне не попадал вовнутрь. Внутри вентилятор гоняет воздух через теплообменник, снаружи - другой вентилятор через другую сторону теплообменника.

В качестве теплообменника использовать пару (или двухсторонний) радиаторов, соединенных основаниями? Или даже элемент Пельтье добавить для повышения эффективности. Примерно так делают в небольших винных холодильниках ;).

Абстрактно :) : если на локальном компьютере L делаем ssh -R OP:H:P -p RP RH, то
1) ssh коннектится на удаленный компьютер R по адресу RH на порт RP;
2) на удаленном компьютере R открывает порт OP;
3) поступающие на порт OP компьютера R данные отправляет через компьютер L на компьютер H на порт P (с точки зрения компьютера L).

P.S. Опция -L делает всё наоборот: если на локальном компьютере L делаем ssh -L OP:H:P -p RP RH, то
1) ssh коннектится на удаленный компьютер R по адресу RH на порт RP;
2) на локальном компьютере L открывает порт OP;
3) поступающие на порт OP компьютера L данные отправляет через компьютер R на компьютер H на порт P (с точки зрения компьютера R).

Не совсем. 43022 будет открыт этим ssh'ем на той машине, т.е. на RPI, на которую коннектимся. Всё как описано. Если хотим заходить на RPI:43022 только из локальной сети RPI'я, то и открывать его не нужно.

Соединение явно проходящее через роутер (остальные в нем завернуты) одно: от Vostok на myhome.router.com на порт XXX, указанный в опции -p XXX (или XXX=22 по умолчанию). Его и надо открывать на роутере и пробрасывать на RPI.

Спасибо за интересное описание!

По-моему, у Вас перепутаны два 22-ых порта.

Порт ReverseSshServerPort, на который коннектится ssh при запуске команды ssh -tt -i /home/user/.ssh/id_rsa -R 43022:localhost:22 pi@myhome.router.com указывается в опции -p. В данном случае опция отсутствует и порт будет 22.

А порт 22 в параметре -R - это порт на localhost (т.е. на Vostok), на который будут перенаправлены запросы с порта 43022 на RPI.

Т.е. эту команду надо читать так (находясь на Vostok): соединяемся с узлом myhome.router.com на стандартный порт 22 (была бы опция -p - был бы другой порт), на удаленной (remote, -R) стороне (т.е. на myhome.router.com) открываем порт 43022, данные на который перенаправляем на узел localhost на локальной стороне (т.е. с точки зрения Vostok'а) на порт 22.

Да, я думал о такой дуальности, но это немного не то: тогда вместо одной вершины-блока будут несколько ребер, и на каждом придется писать задержку. Что не есть красиво...

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

Понятно. Тогда вопрос: на какого читателя рассчитана книга? С каким научным багажом? Если считать, что на студентов 1-2 курса, только освоивших логику, то задачи "управлять потоками" им еще не понятны. В общем, IMHO перебор сложности на начальном этапе погружения в материал. И, главное, он для дальнейшего понимания материала не нужен.

P.S. Если считать, что читатель уже освоил языки программирования и компиляторы, то, наверное, можно говорить, что арифметические операции будут отображены в такие-то схемы, if-конструкции - в другие. Т.е. описывать одновременно и схемы, и язык программирования/описания схем (а-ля VHDL/Verilog). Только тогда не забыть четко проговорить отличие в семантики таких схем от принятых логических выражений и if-ов в обычных языках (C, Java, Python и т.п.). Но IMHO это более трудный путь.

P.P.S. В общем, я, наверное, повторюсь. По своему опыту не надо стараться внести всё в книгу/статью/диссертацию. Это утяжеляет книгу, не дает неподготовленному читателю понять суть, которая оказывается скрыта за многими деталями. IMHO.

Про константы. В итоге я понял так:

  1. Сначала вводим задержку, причем говорит что она имеет смысл [только] на нулевом такте.

  2. Потом ее учитывам на всех тактах (?).

  3. Потом говорим, что она равна нулю (??).

В результате я как читатель запутался.

IMHO не стоит пытаться описать всё, Вы поставили другую цель - описать "удивительный мир", и надо его описывать как можно проще, но не теряя сути. Усложнить можно и потом, а пока читатель не понял о чем тут вообще речь (а он еще не понял), грузить его излишними деталями не нужно.

P.S. В целом это всё мелочи. Сейчас, думаю, Вы стремитесь скорее в черновом виде написать все главы книги, чтобы книга сложилась. И тогда будет лучше видно, что нужно сказать вначале, а что стоит отложить на потом. Вы делаете большую работу!

Гм, меня это не смущает. Вы же при построении ассоциированного направленного графа регистры разбиваете на два, а другие - почему-то нет ;).

Кстати, по поводу этого графа. Вы построили граф портов, а потом приходится на часть ребер ставить веса, а на часть - нет. Т.е. всё равно ребра оказались разного типа. Может не стоит так дробить граф только для того, чтобы посчитать задержку. Я бы предложил оставить схему как есть, только регистр разбить на два: регистр-выход и резистор-вход. Тогда времена будут приписаны вершинам, а не ребрам, но всё считаться аналогично. Такой граф будет минимально отличаться от графа-схемы, но при его построении мы делаем более просто объяснимую вещь: рвем те связи, по которым данные текут через границу такта. Остаются только чисто комбинационные/функциональные стрелки, по которым считаем задержку.

P.S. Да и для констант задержка точна нужна? Вы написали, что в нулевой такт выход станет нужным через Δtc, но в остальные такты (гм, мы же для них на самом деле считаем) выход сразу будет правильный.

Про минимальность. Про произвольные булевы функции - понятно. Тогда предлагаю сократить до AND, OR, NOT - пусть тоже излишнего, но всё же достаточно фундаментального. И будет правильная ассоциация с булевыми формулами в алгебре высказываний. И, наверное, какие-нибудь теоремы/факты из этой алгебры будут красиво перекликаться с Вашими рассуждениями.

Оценка площади будет тоже плюс-минус адекватна. Например, площадь одного MUX - как два элемента AND/OR. Да, не три, но в одном порядке. Для оценки тоже сгодится.

Для регистров - аналогично.

Просто мне (наверное испорченному математическим образованием ;)) понятно, когда берется минимальный набор. Когда нет, то возникает вопрос: почему именно этот, а не какой-то другой. И может надо что-то еще добавить? А что будет если убрать? И критерий выбора мне надо понять как можно раньше (даже до аксиом). Минимальность - понятный критерий. Взять все схемы с двумя входами и одним выходом - понятный. А взять мультиплексор и не взять трехвходовой OR - мне не понятно.

P.S. Можно зайти в объяснении со стороны транзисторов и построении элементарных схем из них, тогда за основу придется взять NOT, NAND, NOR (они и раза в 2 меньше, чем AND/OR). Но, это, видимо, совсем в сторону.

А нужно ли так детально погружаться? Например, точно ли нужны времена Δtsʀ и Δtdʀ? Как Вы пишите в другом комментарии, можно считать что клок приходит во все регистры практически одновременно, так что эти времена - это всего лишь какая-то общая константа, которая на смысл дальнейших рассуждений не сильно влияет, но усложняет понимание.

Если хочется быть физически точным, то надо и длину путей (а это значит разводить схему на плоскости) учитывать. У меня часто критический путь - этот тот, у которого 80% - это провода, а только 20% - логика.

А если огрублять, то IMHO это то место, которое вполне можно отложить, считая что регистры срабатывают мгновенно и одновременно. А ближе к концу, если захочется рассмотреть поближе к реальности, то добавить дополнительные времена (и регистров, и проводов).

А на схеме (Граф, ассоциированный с «пульсаром») должна быть стрелка из reg.in и reg.out?

Еще комментарий.

С точки зрения науки сразу ввести полный набор аксиом и с ним продираться через трудности - это правильно.

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

Может и тут, сначала ограничиться функциональными схемами (без регистров), с ними пройти нужный путь. А потом ввести регистры и с ними повторить всё еще раз? И запомнится легче, и перегруза понятий не будет.

А может тогда вместо линий и черный и белых полукужков, мнемоника которых может быть прочитана по-разному, использовать линии со стрелочками? Тогда сразу видно куда "текут" данные. И в зависимости от ситуации можно будет нарисовать и так, и так, и читатель сможет прочитать.

Более сложные блоки (например, FIFO с, скажем, valid/ready интерфейсом для симметричности (или любое другое устройство с AXI-подобным интерфейсом)) мне приходится рисовать так, что у него входы и выходы с двух стороны, и группировать сигналы не по направлению, а по смыслу: с одной стороны вход FIFO (входные данные и валидности и выходной сигнал готовности), с другой - выход FIFO (выходные данные и валидность и входной - готовность).

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность