Перейти к содержанию
    

Расходятся результаты моделирования и синтеза

Доброго дня!

Столкнулся то ли лютой особенностью синтезатора 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;

Но это не отменят того, что я не постиг причину проблемы

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/10/2023 at 11:14 AM, OparinVD said:

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

А сигнал S_AXIS_TKEEP поправить не забыли?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в этот момент я tkeep не анализирую, беру то, что физически присутствует на tdata, т.е. даже если бы пакет оказался короче, чем я ожидаю для заполнения header, то остаток заполнился бы мусором из не валидных позиций... но на чипскопе tkeep не нулевой, и в нужных позициях tdata находятся правильные значения, а не нули

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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);

Что разумеется ему не понравилось...

 

 

Дополнение: Насчет разумеется я возможно и погорячился, нужно смотреть, что на такое говорит стандарт:)

Изменено пользователем Самурай

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, Самурай said:

Как предположение: У Вас сигнал BlockBytesLeft от 0 до 8, следовательно вот тут:

с точки зрения синтезатора возможен и вот такой вариант:

Block_ShReg    <= S_AXIS_TDATA(8*8-1 downto 0) & Block_ShReg(63 downto 8*8);

Что разумеется ему не понравилось...

 

 

Дополнение: Насчет разумеется я возможно и погорячился, нужно смотреть, что на такое говорит стандарт:)

 

С нулем тоже вопросы возникают

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это очень похоже на правду... только скорей всего ему не понравился вариант с 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...