Сообщение об ошибке не об итерациях вашего цикла, а об итерациях внутреннего алгоритма вашей программы синтеза.Он говорит вам, что Vivado не удалось создать схему, которая могла бы быть реализована на выбранной вами ПЛИС с выбранной вами тактовой частотой и которая действительно выполняет то, что вы просите.
Позвольте мне уточнить, после того как я упомянудва элемента общего импорта: не используйте блокирующие назначения (=
) внутри блоков always @(posedge clk)
.Они почти никогда не делают то, что вы хотите.Только неблокирующие назначения (<=
) должны быть синхронизированы.Во-вторых, правильный способ синтеза цикла for
- это generate
, хотя Вивадо, кажется, принимает простой for
.
Вы строите здесь довольно большой блок комбинаторной логики.Помните, что когда вы синтезируете комбинаторную логику, вы запрашиваете схему, которая может оценить выражение, которое вы написали за один такт .Фактическое выражение, принятое во внимание, - это выражение после цикла for.То есть вы (условно) добавляете 16-битное число к 32-битному числу 16 раз, каждый раз сдвигаясь на один бит дальше влево.Каждое из этих дополнений имеет бит переноса.Таким образом, каждое из этих дополнений фактически должно рассматривать все старшие 16 битов результата предыдущего добавления, и каждое из них будет зависеть от всех, кроме самого младшего бита предыдущего добавления.Сумматор на один бит + перенос требует O (5) затворов.Каждое дополнение является условным, которое добавляет по крайней мере еще один вентиль для каждого бита.Таким образом, вы запрашиваете как минимум 16 * 16 * 6 = 1300 взаимозависимых вентилей, которые должны стабилизироваться в течение одного такта.Vivado говорит вам, что он не может выполнить эти требования.
Одним из способов решения этой проблемы будет синтез для более низкой тактовой частоты, когда у затворов будет больше времени для стабилизации, и, таким образом, вы сможете построить более длинные логические цепочки.,Другим вариантом может быть конвейеризация операции, скажем, путем оценки только того, что соответствует четырем итерациям цикла в течение одного тактового цикла, а затем построения результата за несколько тактовых циклов.Это добавит некоторую логику учета в ваш код, но это неизбежно, если кто-то захочет оценивать сложные выражения с конечными ресурсами на высоких тактовых частотах.Это также познакомит вас с синхронной логикой, которую вам все равно придется изучить, если вы хотите сделать что-нибудь нетривиальное с FPGA.Обратите внимание, что этот тип конвейерной передачи не окажет значительного влияния на пропускную способность, поскольку ваша FPGA будет затем выполнять несколько умножений параллельно.
Вы также можете переписать выражение для обработки битов переноса и взаимозависимостей в более умномспособ, который позволяет Vivado найти свой путь через выражение (вероятно, есть такой способ, я предполагаю, что он синтезирует, если вы просто напишите оператор умножения?).
Наконец, многие FPGA поставляются с выделенными единицами умножения, потому что умножениеэто обычная операция, но ее реализация в логических элементах тратит много ресурсов.Как вы узнали.