如何计算向量的模块?
由于向量不是VHDL中的预定义类型,因此我认为没有实现向量模块的函数。如果有这样的话我还没找到。
这基本上是获得数字的平方根的问题,因为模块可以定义为:
SQRT(A ^ 2 + B ^ 2 + ... + N ^ 2)
实现向量平方的所有成员的总和不是一个挑战,所以我认为最必要的部分是具有计算数字的平方根的函数。
就我而言,没有任何官方包实现此功能。如何实现一个函数来计算向量的模块?
或者如果你喜欢它,如何实现平方根?
答案 0 :(得分:2)
这是一种可能的解决方案。我会为你提供3个密码。
- 第一个提供用于向量的类型定义。它并不重要,但它需要它才能发挥作用。
- 第二个是定义函数的包。它被评论,以便您可以轻松地将其适应任何类型的向量。它可以升级,以便通过一些参数自行调整,这可以正常工作。
- 第三个是试用它的测试平台。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package tipos is
constant bandas : positive := 4;
type vector32 is array (0 to bandas-1) of signed (31 downto 0);
end package tipos;
请注意使用向量定义正确调用库。在我的情况下,它被编译为适用于ModelSim模拟
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work; use work.tipos.all;
package propios is
--function declaration.
function module (a : vector32; bands: natural) return unsigned;
end propios; --end of package.
package body propios is --start of package body
--definition of function
--based on: https://en.m.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29
function module (a : vector32; bands: natural) return unsigned is --To adapt it to a diferent number of bits in the input vector:
--substitute the 71 for the needed number. Number of bits in each element of the vector *2 + power of two that can represent the maximum
--number of bands, or fields. In this case, 32bit numbers, maximum number of bands, 256, so 2^8. 32*2+8=72.
variable sum : unsigned(71 downto 0):= (others => '0');
variable b : unsigned(71 downto 0):=(0=>'0', 70 => '1', others => '0');
variable a_unsig: unsigned(31 downto 0):=(others =>'0');--for this vector use the same length as the input vector, 32bit in my case.
variable result: unsigned (71 downto 0):= (others => '0');
begin
for i in 0 to bands-1 loop--Sum of all the elements squared
a_unsig:=unsigned(a(i));
sum:=sum + (a_unsig * a_unsig);
end loop;
--Square root of sum
while b>sum loop--Do any needed changes here. You only have to change the 71's
b:='0'&'0'& b(71 downto 2);
end loop;
while (b/=0) loop
if (sum>=result+b) then
sum:=sum - (result + b);
result:=('0'& result(71 downto 1))+b;
else
result:='0'& result(71 downto 1);
end if;
b:='0' & '0' & b(71 downto 2);
end loop;
return result(35 downto 0);--sqrt(2^72)=2^36. Use half of the bits you put in place of 71
end module;
end propios; --end of the package body
这是测试平台。再次注意正确调用包
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.propios.all;
use work.tipos.all;
ENTITY test IS
END test;
Architecture simple of test is
signal a:vector32;
signal c: unsigned(35 downto 0);
signal b: natural:= 4;
begin
a(0)<="00000000110010011010011100000000";
a(1)<="00000000110010011010011100000000";
a(2)<="00000000110010011010011100000000";
a(3)<="00000000110010011010011100000000";
process
begin
wait for 200ps;
c<= module (a , b);
wait;
end process;
end simple;