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

如何根据常量的对数设置VHDL向量大小,vhdl,verilog,fpga,Vhdl,Verilog,Fpga,我想知道$clog2(数据宽度)对应的VHDL代码是什么,例如在这一行: parameter DATA_OUT_WIDTH = $clog2(DATA_WIDTH) 在这个例子中,这个符号“-:” if ( Pattern == In[i_count-:PATTERN_WIDTH] ) 如果有人能帮助我,我将不胜感激。你可以这样做 constant DATA_OUT_WIDTH : positive := positive(ceil(log2(real(DATA_WIDTH)))); 或者

我想知道
$clog2(数据宽度)
对应的VHDL代码是什么,例如在这一行:

parameter DATA_OUT_WIDTH = $clog2(DATA_WIDTH)
在这个例子中,这个符号“-:”

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

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

你可以这样做

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中是一个保留字。

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

IEEE库中没有预定义函数的原因已经在Lars answer中表达出来了,您通常不太使用它,您可以将值赋给常量,并且可以从现有函数中拼凑出一个表达式

clog2函数示例

if ( Pattern == In[i_count-:PATTERN_WIDTH] )
从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;
类型为NATURAL的参数可防止传递负整数值。四舍五入是严格的,任何低于2.0的余数都会导致四舍五入

注意,因为它使用REAL和division,所以它只适合在分析和精化期间使用。这是一个纯函数

您可以注意到Lars示例:

constant DATA_OUT_WIDTH : positive := positive(ceil(log2(real(DATA_WIDTH))));
在用于分析(局部静态)和精化(全局静态)方面具有相同的约束。合成通常不支持实数类型,浮点操作可能会消耗大量的实数

if条件

if ( Pattern == In[i_count-:PATTERN_WIDTH] )
是基索引(lsb或msb,取决于所声明的升序或降序位顺序)和宽度

参见IEEE标准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_计数可以是可变的

根据中声明的
范围,例如:

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_计数
小于
DATAWIDTH-1
,则会出现运行时错误。-1是因为In_In'RIGHT=0

如果不提供In(或Pattern)和DATAWIDTH的声明,就无法提供更好的答案。它真的希望被重新编写为VHDL友好


注意,
中的
是保留字(此处VHDL不区分大小写),名称已更改。

我认为您的舍入条件应为
Y>1.0
Y
始终为正,在当前舍入条件下,函数为
2
的输入生成
2
,这不是我期望从
ceil(log2())
函数得到的结果。