VHDL:使用通用的一个整数的长度来确定的选择线数(VHDL: use the length of

2019-08-01 04:55发布

我试图创建一个可重复使用的桶式移位器; 它需要的比特的输入阵列,并转移他们一定的数量的位置(由另一个输入确定的)。 我想参数化模块,以便它可以用于任何n

选择线是由确定的所需数量n >即, - SHIFT_CNT = log2(NUMBITS-1)+1在下面的代码。 它被认为是不好的形式在我的组织(我认为整体)有是不是端口std_logic_vectorstd_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;

Answer 1:

您可以使用数学库来计算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,你的代码是合成的 (我做到了)。

如果你不想在实体使用它,你可以在图书馆或一般具有这些功能申报。



Answer 2:

您可以在库中创建的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)

它是一个有些丑陋的解决方案,但它不使用任何资源(因为该函数是纯和所有的输入是在编译时已知的)。

我经常这样做,但你可能更喜欢指定日志值就像你提到的一般。



Answer 3:

两种做法可供选择:

你可以反向工作,并有genericshift_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                 
        );  

并让工具弄清楚你。



Answer 4:

当我使用汗提到的方法,我遇到的舍入误差。 所以我写了我自己的版本,是免疫舍入误差,并在原则处理超过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;


Answer 5:

您可以代替输入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
标签: generics vhdl