VHDL:使用整数通用的长度来确定选择行的数量

Nic*_*ckD 10 generics vhdl

我正在尝试创建一个可重复使用的桶形移位器; 它需要一个输入的位数组并将它们移位一定数量的位置(由另一个输入确定).我想参数化模块,以便它适用于任何模块n.

所需的选择行数由n- > 确定,即SHIFT_CNT = log2(NUMBITS-1)+1在下面的代码中.它被认为是不好的形式在我的组织(我认为整体的)有不属于港口std_logic_vectorstd_logic,所以我用一个std_logic_vector用于选择线的数量.我需要调整std_logic_vector基于输入泛型的长度.有没有办法在不使用第二个通用的情况下执行此操作?我看过这篇文章,但它没有涉及泛型.这篇文章完全消除了泛型或使用日志值作为泛型,这对于未来的用户来说并不直观(如果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;
Run Code Online (Sandbox Code Playgroud)

Kha*_*ang 16

您可以使用数学库来计算logarit结果的log2和ceil,以声明SHIFT_CNT的大小.

use IEEE.math_real.all;
Run Code Online (Sandbox Code Playgroud)

或具体功能

use IEEE.math_real."ceil";
use IEEE.math_real."log2";
Run Code Online (Sandbox Code Playgroud)

例如,您想要计算值a的clog2

result := integer(ceil(log2(real(a))));
Run Code Online (Sandbox Code Playgroud)

如果您只是使用这些函数来计算参数,那么您的代码是可合成的 (我做到了).

如果您不想在实体中使用它,可以使用这些函数在库中或通用中声明它们.

  • `result := integer(ceil(log2(real(a) + real(1))));` 以防止舍入错误,例如当 a = 8 时。 (2认同)

pc3*_*c3e 7

您可以在库中创建log2函数,如下所示:

   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;
Run Code Online (Sandbox Code Playgroud)

如果导入库,则可以指定端口,如下所示:

shift_cnt : in std_logic_vector(f_log2(NUMBITS)-1 downto 0)
Run Code Online (Sandbox Code Playgroud)

这是一个有点难看的解决方案,但它不使用任何资源(因为函数是纯的,所有输入在编译时都是已知的).

我通常这样做,但您可能更喜欢将日志值指定为通用,就像您提到的那样.


Mar*_*son 5

两种替代方法:

您可以向后工作并使用genericas 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)                 
        ); 
Run Code Online (Sandbox Code Playgroud)

或者将计数视为一个数字:

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                 
        );  
Run Code Online (Sandbox Code Playgroud)

并让工具为您解决问题。