如何根据常量的对数设置VHDL向量大小

时间:2015-10-19 13:52:50

标签: vhdl verilog fpga

我想知道$clog2(DATA_WIDTH)的相应VHDL代码是什么,例如在这一行中:

parameter DATA_OUT_WIDTH = $clog2(DATA_WIDTH)

也是这个标志" - :"在这个例子中

if ( Pattern == In[i_count-:PATTERN_WIDTH] )

如果有人能帮助我,我将不胜感激。

2 个答案:

答案 0 :(得分:4)

你可以做这样的事情

constant DATA_OUT_WIDTH : positive := positive(ceil(log2(real(DATA_WIDTH))));

或定义封装该表达式的clog2函数。 ceil和log2可以在math_real

中找到
use ieee.math_real.all;

在VHDL中,您只需指定完整范围,例如

foo(i_count to i_count + 7)
foo(i_count downto i_count - 7)

不要使用 In 作为标识符,它是VHDL中的保留字。

答案 1 :(得分:4)

除了Lars示例之外,您还可以轻松编写一个函数来查找天花板日志2,以确定元素地址的位数'一些公交车宽度需要。一些供应商或验证支持库已经提供了一个。

IEEE库中没有预定义功能的原因已经在Lars答案中表达,你不会使用它太多,你可以将值赋值给一个常量,表达式可以从现有函数拼凑在一起。

示例clog2函数

来自IEEE包float_generic的借用和转换的log2例程:

  function clog2 (A : NATURAL) return INTEGER is
    variable Y : REAL;
    variable N : INTEGER := 0;
  begin
    if  A = 1 or A = 0 then  -- trivial rejection and acceptance
      return A;
    end if;
    Y := real(A);
    while Y >= 2.0 loop
      Y := Y / 2.0;
      N := N + 1;
    end loop;
    if Y > 0.0 then
      N := N + 1;  -- round up to the nearest log2
    end if;
   return N;
  end function clog2;

参数A type NATURAL可防止传递负整数值。舍入是严格的,任何低于2.0的余数都会导致四舍五入。

请注意,因为它使用REAL并使用除法,所以它仅适用于分析和详细说明。它是一个纯粹的功能。

你可以注意到Lars的例子:

constant DATA_OUT_WIDTH : positive := positive(ceil(log2(real(DATA_WIDTH))));

对分析(本地静态)和精化(全局静态)的使用具有相同的约束。通常不支持REAL类型进行综合,浮点运算会消耗大量的空间。

if条件

if ( Pattern == In[i_count-:PATTERN_WIDTH] )

是基本索引(lsb或msb,取决于声明的位顺序的升序或降序)和宽度。

参见IEEE Std 1800-2012(SystemVerilog),11.5.1向量位选择和部分选择寻址。

  

使用以下语法给出索引的部分选择:

logic [15:0] down_vect;  
logic [0:15] up_vect;  

down_vect[lsb_base_expr +: width_expr]  
up_vect[msb_base_expr +: width_expr]  
down_vect[msb_base_expr -: width_expr]  
up_vect[lsb_base_expr -: width_expr]  
     

msb_base_expr和lsb_base_expr应为整数表达式,width_expr应为正常数整数表达式。应在自定义的上下文中评估这些表达式中的每一个。 lsb_base_expr和msb_base_expr可以在运行时变化。前两个示例选择从基数开始并在位范围内上升的位。选择的位数等于宽度表达式。后两个示例选择从基数开始并降低位范围的位。

在VHDL术语中,这将是一个切片,其边界由高索引确定,宽度由减法确定。

PATTERN_WIDTH可以是全局静态的(如通用常量)以及本地静态(非延迟常量)。 i_count可以是变量。

取决于In的声明范围,例如:

constant DATAWIDTH:  natural := 8;
signal In_in:        std_logic_vector (31 downto 0);

等效表达式为

if Pattern = In_in(i_count downto i_count - DATAWIDTH - 1) then

请注意,如果切片长度或i_count小于DATAWIDTH - 1,则会出现运行时错误。 -1是因为In_in' RIGHT = 0。

如果不提供In(或Pattern)和DATAWIDTH的声明,则无法提供更好的答案。它真的想重写为VHDL友好。

注意,Lars表示in是保留字(VHDL在这里不区分大小写)并且名称已更改。