Verilog IEEE 754 с одинарной точностью в целочисленное преобразование - PullRequest
2 голосов
/ 22 апреля 2011

Я пытаюсь преобразовать двоичный формат IEEE двоичного формата в целое число. Я использую следующий цикл:

for(i=22;i>=0;i=i-1)
begin
   a1=in1[i]*(2**(i-23));
end
a1=a1+1;
a1=a1*(2**(in1[30:23]-8'b01111111));
a1=((-1)**(in1[32]))*a1;

Мне нужно сделать это еще 7 раз в моей программе. Мой вопрос: есть ли библиотека для этого, которая принимает 32-битный ввод и дает целочисленный вывод? Если да, как мне включить эту функцию в мою программу? Спасибо.

обновление: будет ли корректно работать фрагмент кода выше?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2011

Один из способов сделать это будет:

  1. переупаковать операнды в 64-битном формате двойной точности
  2. преобразовать значения в действительные с $bitstoreal
  3. использовать собственную математику с плавающей точкой verilog для работы с реалами
  4. преобразовать реалы обратно в биты с помощью $realtobits
  5. преобразование 64-битного двойного возврата в формат с одинарной точностью. Значение должно быть обрезано, если оно выходит за пределы представимого диапазона (есть случаи «слишком далеко от нуля» и «слишком близко к нулю», которые необходимо зафиксировать).

Если вы хотите преобразовать числа с плавающей точкой в ​​фиксированную точку, используя стратегию в вопросе, имейте в виду, что Verilog не имеет встроенной поддержки фиксированной точки. Вы не можете осмысленно оценить 2 ^ (отрицательный показатель) как целое число, вы просто получите ноль. Либо реструктурируйте алгоритм так, чтобы показатели всегда были положительными, либо используйте сдвиги вправо (>>), а не умножение на отрицательную степень двойки.

2 голосов
/ 23 апреля 2011

Для поведенческого кода используйте $ rtoi () или $ realtobits ()

real in1;
integer     a1;
wire [63:0] b1;
a1 = $roti(in1); //Truncates fractional part
b1 = $realtobits(in1); //Probably not what you want

Вы можете использовать $ bitstoreal (), если вам нужно привести битовый вектор к реальному типу.

EDIT: Поэтому, если я правильно следую вашим комментариям, вы создаете модель ALU с плавающей запятой, которая работает с 32-битными значениями данных. В этом случае вы можете использовать real типы данных, поскольку Verilog может обрабатывать этот формат изначально. Конечно, вы не сможете обнаружить определенные ситуации

task [31:0] realAdd(input [31:0] in1, input [31:0] in2, output [31:0] out);
begin

real rIn1,rIn2,rOut;
rIn1 = $bitstoreal(in1);
rIn2 = $bitstoreal(in2);
rOut = rIn1 + rIn2;

out = $realtobits(rOut);

end
endtask

Все эти функции используют двойную точность, поэтому вам нужно будет выполнить тривиальные битовые расширения для обработки входов с одинарной точностью, а также некоторые нетривиальные проверки / усечение границ на выходе. Вы можете избежать этого, используя SystemVerilog, в котором есть функции $ bitstoshortreal () / $ shortrealtobits (), которые работают со значениями одинарной точности.

Если вам нужно оборудование для этого, Computer Organization & Design содержит описание многоцикловой реализации. Как писал Энди, для вашего случая могут быть лучшие ресурсы. Они не просты в разработке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...