我试图创建一个可重复使用的桶式移位器; 它需要的比特的输入阵列,并转移他们一定的数量的位置(由另一个输入确定的)。 我想参数化模块,以便它可以用于任何n
。
选择线是由确定的所需数量n
>即, - SHIFT_CNT = log2(NUMBITS-1)+1
在下面的代码。 它被认为是不好的形式在我的组织(我认为整体)有是不是端口std_logic_vector
或std_logic
,所以我用一个std_logic_vector
的选择线数。 我需要调整的长度std_logic_vector
根据输入通用。 有没有办法做到这一点不使用第二通用? 我已经看到了这个帖子,但它不与仿制药处理。 这个帖子完全消除仿制药或使用log值作为通用的,这是不一样直观的未来用户(以及可能会造成问题,如果INPUT
是不是2的幂)。
的声明SHIFT_CNT
下面肯定是不正确; 有一种方法来自动生成在实体声明的长度而无需使用第二通用?
entity BarrelShifter is
generic ( NUMBITS : integer :=8);
Port ( INPUT : in std_logic_vector (NUMBITS-1 downto 0);
OUTPUT : out std_logic_vector (NUMBITS-1 downto 0);
SHIFT_CNT : in std_logic_vector ((NUMBITS-1)'length downto 0)
);
end BarrelShifter;
您可以使用数学库来计算logarit结果的log 2和小区申报SHIFT_CNT的大小。
use IEEE.math_real.all;
或特定功能
use IEEE.math_real."ceil";
use IEEE.math_real."log2";
例如要计算值的clog2
result := integer(ceil(log2(real(a))));
如果你只是使用这些函数来计算paramater,你的代码是合成的 (我做到了)。
如果你不想在实体使用它,你可以在图书馆或一般具有这些功能申报。
您可以在库中创建的log 2功能,就像这样:
function f_log2 (x : positive) return natural is
variable i : natural;
begin
i := 0;
while (2**i < x) and i < 31 loop
i := i + 1;
end loop;
return i;
end function;
如果库是进口的,你可以再指定这样的端口:
shift_cnt : in std_logic_vector(f_log2(NUMBITS)-1 downto 0)
它是一个有些丑陋的解决方案,但它不使用任何资源(因为该函数是纯和所有的输入是在编译时已知的)。
我经常这样做,但你可能更喜欢指定日志值就像你提到的一般。
两种做法可供选择:
你可以反向工作,并有generic
的shift_bits
-然后计算从输入和输出向量的宽度:
generic ( shift_bits: integer :=3);
Port ( INPUT : in std_logic_vector ((2**shift_bits)-1 downto 0);
OUTPUT : out std_logic_vector ((2**shift_bits)-1 downto 0);
SHIFT_CNT : in std_logic_vector (shift_bits-1 downto 0)
);
或治疗计数数字:
generic ( NUMBITS : integer :=8);
Port ( INPUT : in std_logic_vector (NUMBITS-1 downto 0);
OUTPUT : out std_logic_vector (NUMBITS-1 downto 0);
SHIFT_CNT : in integer range 0 to numbits-1
);
并让工具弄清楚你。
当我使用汗提到的方法,我遇到的舍入误差。 所以我写了我自己的版本,是免疫舍入误差,并在原则处理超过32位。 您可以使用具有左移运算逻辑移位的任何类型替换L的类型。
大多数时候,你要使用log2ceil这是存储给定数量需要的比特量,同时log2floor可以更可谓最高位设置时间。
在大多数情况下,因为它们是用于产生常数的那些功能是精细合成。 因此,没有硬件推断他们。
function log2ceil (L: POSITIVE) return NATURAL is
variable i, bitCount : natural;
begin
i := L-1;
bitCount:=0;
while (i > 0) loop
bitCount := bitCount + 1;
i:=srlInteger(i,1);
end loop;
return bitCount;
end log2ceil;
function log2floor (L: POSITIVE) return NATURAL is
variable i, bitCount : natural;
begin
i := L;
bitCount:=0;
while (i > 1) loop
bitCount := bitCount + 1;
i:=srlInteger(i,1);
end loop;
return bitCount;
end log2floor;
function srlInteger(arg: integer; s:natural) return integer is
begin
return to_integer(SHIFT_RIGHT(to_UNSIGNED(ARG,32), s));
end srlInteger;
您可以代替输入NUMBITS值8,输入它作为2(LOG 2(8)),然后重新键入如下绕过这个问题,你一般就不会像干净的,但它的规模,能。
entity BarrelShifter is
generic ( NUMBITS : integer :=2);
Port ( INPUT : in std_logic_vector (((2**Nbits)-1) downto 0);
OUTPUT : out std_logic_vector (((2**Nbits)-1) downto 0);
SHIFT_CNT : in std_logic_vector ((NUMBITS-1) downto 0)
);
end BarrelShifter;
文章来源: VHDL: use the length of an integer generic to determine number of select lines