OparinVD 0 10 марта, 2023 Опубликовано 10 марта, 2023 · Жалоба Доброго дня! Столкнулся то ли лютой особенностью синтезатора Vivado, то ли сам что-то не так понимаю. Задача такая: Принимаю axis-поток, забираю из него header, остальное ретранслирую дальше (всё в litle endian). Длина заголовка и ширина входных данных задаются в generic, но для упрощения внешнего вида ширину tdata зафиксирую на 32 бит: generic ( g_block_length : natural := 8; ...); port( ... S_AXIS_TDATA : in STD_LOGIC_VECTOR(31 downto 0); ... ); ... signal Block_ShReg : std_logic_vector(g_block_length*8-1 downto 0); Для отслеживания, сколько байт заголовка, принято есть счетчик: signal BlockBytesLeft : natural range 0 to g_block_length := g_block_length; Поведение вполне простое: если заголовок еще не заполнен, т.е. BlockBytesLeft больше, чем приходит за одну транзакцию, то всю эту транзакцию забираем в сдвиговый регистр: Block_ShReg <= S_AXIS_TDATA & Block_ShReg(Block_ShReg'high downto 32); BlockBytesLeft <= BlockBytesLeft - 4; Если же очередная транзакция полностью заполнит заголовок, то из S_AXIS_TDATA берем фрагмент шириной, которая зависит от количества оставшихся байт: Block_ShReg <= S_AXIS_TDATA(BlockBytesLeft*8-1 downto 0) & Block_ShReg(Block_ShReg'high downto BlockBytesLeft*8); BlockBytesLeft <= 0; И вот тут прозвенел первый звоночек. На симуляции и в ActiveHDL, и в Vivado всё прошло хорошо, а вот синтез вывалился с ошибкой. Синтезатор заявил, что правая и левая часть не совпадают по ширине и отличаются ровно на ширину S_AXIS_TDATA. Тогда я разделил прием последней транзакции на явный сдвиг сдвигового регистра вправо на BlockBytesLeft байт и прописывания в освободившееся место новых байтов: Block_ShReg(Block_ShReg'high-BlockBytesLeft*8 downto 0) <= Block_ShReg(Block_ShReg'high downto BlockBytesLeft*8); -- shift right low part Block_ShReg(Block_ShReg'high downto Block_ShReg'high-BlockBytesLeft*8+1) <= S_AXIS_TDATA(BlockBytesLeft*8-1 downto 0); -- get high part Синтез прошел успешно, но в железе не заработало. Отладка с чипскопом показала, что сдвиг проходит успешно, а вот освободившиеся байты заполняются нулями. Подобное заполнение нулями я встречал в другом месте, там в результате ошибки по формуле получался неправильный диапазон S_AXIS_TDATA(-1 downto 0). В этом же случае выглядит всё правильно, формула (BlockBytesLeft*8-1) на чипскопе отображается корректно числом из диапазона (31 downto 0). Но очевидно, что проблема топчется именно вокруг диапазона для S_AXIS_TDATA, но я не пойму как. Есть мысли, как это работает? PS: на данный момент проблема решена побитным копированием из S_AXIS_TDATA в старшую часть сдвигового регистра: for i in S_AXIS_TDATA'range loop if (i <= BlockBytesLeft*8-1) then Block_ShReg(Block_ShReg'length - BlockBytesLeft*8 + i) <= S_AXIS_TDATA(i); end if; end loop; Но это не отменят того, что я не постиг причину проблемы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 25 10 марта, 2023 Опубликовано 10 марта, 2023 · Жалоба On 3/10/2023 at 11:14 AM, OparinVD said: Отладка с чипскопом показала, что сдвиг проходит успешно, а вот освободившиеся байты заполняются нулями. А сигнал S_AXIS_TKEEP поправить не забыли? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 10 марта, 2023 Опубликовано 10 марта, 2023 · Жалоба в этот момент я tkeep не анализирую, беру то, что физически присутствует на tdata, т.е. даже если бы пакет оказался короче, чем я ожидаю для заполнения header, то остаток заполнился бы мусором из не валидных позиций... но на чипскопе tkeep не нулевой, и в нужных позициях tdata находятся правильные значения, а не нули Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 10 марта, 2023 Опубликовано 10 марта, 2023 (изменено) · Жалоба В 10.03.2023 в 11:14, OparinVD сказал: signal BlockBytesLeft : natural range 0 to g_block_length := g_block_length; Как предположение: У Вас сигнал BlockBytesLeft от 0 до 8, следовательно вот тут: В 10.03.2023 в 11:14, OparinVD сказал: Block_ShReg <= S_AXIS_TDATA(BlockBytesLeft*8-1 downto 0) & Block_ShReg(Block_ShReg'high downto BlockBytesLeft*8); с точки зрения синтезатора возможен и вот такой вариант: Block_ShReg <= S_AXIS_TDATA(8*8-1 downto 0) & Block_ShReg(63 downto 8*8); Что разумеется ему не понравилось... Дополнение: Насчет разумеется я возможно и погорячился, нужно смотреть, что на такое говорит стандарт:) Изменено 10 марта, 2023 пользователем Самурай Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tausinov 0 10 марта, 2023 Опубликовано 10 марта, 2023 · Жалоба Just now, Самурай said: Как предположение: У Вас сигнал BlockBytesLeft от 0 до 8, следовательно вот тут: с точки зрения синтезатора возможен и вот такой вариант: Block_ShReg <= S_AXIS_TDATA(8*8-1 downto 0) & Block_ShReg(63 downto 8*8); Что разумеется ему не понравилось... Дополнение: Насчет разумеется я возможно и погорячился, нужно смотреть, что на такое говорит стандарт:) С нулем тоже вопросы возникают Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 10 марта, 2023 Опубликовано 10 марта, 2023 · Жалоба это очень похоже на правду... только скорей всего ему не понравился вариант с BlockBytesLeft=0... Тогда, с точки зрения синтезатора, получится так: Block_ShReg <= S_AXIS_TDATA(-1 downto 0) & Block_ShReg(Block_ShReg'high downto 0); Как я уже заметил в другом эксперименте, S_AXIS_TDATA(-1 downto 0) при синтезе дает S_AXIS_TDATA, на всю ширину, заполненную нулями. Т.е. слева Block_ShReg'range а справа S_AXIS_TDATA'range & Block_ShReg'range - разница как раз на ширину S_AXIS_TDATA. Оно, конечно, находится в ветке if, которая исключает вариант с BlockBytesLeft=0, но синтезатор вряд ли это отслеживает, и его возмущение тогда вполне оправдано. Осталось понять почему это: Block_ShReg(Block_ShReg'high downto Block_ShReg'high-BlockBytesLeft*8+1) <= S_AXIS_TDATA(BlockBytesLeft*8-1 downto 0); -- get high part порождает нули... ведь видно, что на момент принятия порции данных BlockBytesLeft не равен 0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться