В VHDL, как считать начальные нули вектора?

Я работаю над проектом VHDL, и у меня возникла проблема с вычислением длины вектора. Я знаю, что у вектора есть атрибут длины, но это не та длина, которую я ищу. Например, у меня есть std_logic_vector

    E : std_logic_vector(7 downto 0);  

потом

    E <= "00011010";

Итак, len = E'length = 8 но я не ищу это. Я хочу вычислить len после отбрасывания самых левых нулей, поэтому len = 5;

Я знаю, что могу использовать цикл for, проверяя биты «0» слева направо и останавливаясь, если бит «1» встречается. Но это неэффективно, потому что у меня 1024 или более бит, и это замедлит мою схему. Итак, есть ли какой-либо метод или алгоритм для эффективного расчета длины? Например, использование комбинационных ворот логарифмического (n) уровня ворот (где n = количество битов).


person Moha Blugrana    schedule 13.05.2013    source источник
comment
Вы пробовали наивный подход? Синтезаторы могут быть удивительно умны в изменении вашей логики. В противном случае Hackers Delight имеет ряд вариантов на стр.77-80, которые могут поддаваться синтезу. Им не нужно много времени, чтобы написать код и попробовать — ответьте на этот вопрос!   -  person Martin Thompson    schedule 13.05.2013


Ответы (4)


То, что вы делаете со своим «подсчетом битов», очень похоже на логарифм (основание 2).

Это обычно используется в VHDL, чтобы выяснить, сколько битов требуется для представления сигнала. Например, если вы хотите хранить до N элементов в ОЗУ, число битов, необходимых для адресации этого ОЗУ, равно ceil(log2(N)). Для этого я использую:

function log2ceil(m:natural) return natural is
begin -- note: for log(0) we return 0
    for n in 0 to integer'high loop
        if 2**n >= m then
            return n;
        end if;
    end loop;
end function log2ceil;

Обычно вы хотите сделать это во время синтеза с константами, и скорость не имеет значения. Но вы также можете сгенерировать логику FPGA, если это действительно то, что вам нужно.

Как уже упоминалось, цикл for в VHDL просто используется для создания таблицы поиска, которая может быть медленной из-за длинных путей прохождения сигнала, но все же занимает всего один такт. Что может случиться, так это то, что ваша максимальная тактовая частота снижается. Обычно это проблема только в том случае, если вы работаете с векторами размером более 64 бит (вы упомянули 1024 бита) и с тактовой частотой более 100 МГц. Возможно, синтезатор уже сказал вам, что это ваша проблема, в противном случае предлагаю сначала попробовать.

Затем вам нужно разделить операцию на несколько часов и сохранить некоторый промежуточный результат в FF. (Я бы заранее забыл о попытках перехитрить синтезатор, перестроив свой код. Таблица поиска — это таблица. Почему должно иметь значение, как вы генерируете значения в этой таблице? Но обязательно сообщите синтезатору о том, что «все равно». " значения, если они у вас есть.)

Если вам важна скорость, используйте первый такт для параллельной проверки всех 16-битных блоков (независимо друг от друга), а затем используйте второй такт для объединения результатов всех 16-битных блоков в один результат. Если вас беспокоит объем логики FPGA, реализуйте конечный автомат, который проверяет один 16-битный блок в каждом такте.

Но будьте осторожны, чтобы при этом не изобретать ЦП заново.

person Community    schedule 14.05.2013
comment
Я думаю, что ваш ответ самый близкий ... Спасибо. - person Moha Blugrana; 14.05.2013

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

Другой способ взглянуть на вашу проблему — найти индекс старшего установленного бита. Для этого вы можете использовать приоритетный энкодер. Хорошая вещь в этом заключается в том, что вы можете создать кодировщик с большим приоритетом, используя кодировщики с меньшим приоритетом в древовидной структуре, поэтому задержка составляет O (log N) вместо O (N).

Вот кодировщик с 4-битным приоритетом: http://en.wikibooks.org/wiki/VHDL_for_FPGA_Design/Priority_Encoder Вы можете сделать 16-битный кодер с приоритетом, используя 5 таких блоков, затем 256-битный кодер из пяти 16-битных кодировщиков и т. д.

Но поскольку у вас так много битов, он будет довольно огромным.

person Bull    schedule 14.05.2013
comment
ваше предложение стоит попробовать. - person Moha Blugrana; 14.05.2013

Что ж, VHDL — это не SW, для выполнения такой операции не требуется время, он просто отбирает ресурсы у вашей FPGA.

Вы можете разделить свои 1024-битные данные на 32-битную секцию и выполнить ИЛИ между всеми битами, таким образом, вы проверяете 32 бита за раз. На самом деле это не обязательно, так как цикл for будет отлично работать для того, что вы хотите сделать, просто напишите код, найдите первую 1 в массиве, остановите цикл и используйте номер индекса цикла в качестве указателя на первый 1 в вашем массиве. Я не компилировал этот код, но что-то вроде этого должно работать для вас:

FirstOne <= 1023;
for i in E'reverse_range loop
  if (E(i) == '1') then
    FirstOne <= i;
    exit;
  end if;
end loop;

В конце концов, внутри FPGA не будет таких больших блоков.

person FarhadA    schedule 14.05.2013

Большинство современных синтезаторов поддерживают рекурсивные функции. И действительно, это даст вам сложность, сравнимую с log(N), где N — количество битов:

  • Разрежьте свой вектор пополам
  • If the top half are all zeros
    • The leading bit of your answer is '1', low bits depend on the bottom half vector
  • Otherwise
    • The leading bit of your answer is '0', low bits depend on the top half vector
  • Рекурсия по интересующему полувектору, выбранному выше
person Ben Voigt    schedule 14.05.2013