【问题标题】:How to set VHDL vector size based on the log of a constant如何根据常数的对数设置 VHDL 向量大小
【发布时间】:2015-10-19 13:52:50
【问题描述】:

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

parameter DATA_OUT_WIDTH = $clog2(DATA_WIDTH)

在这个例子中也是这个符号“-:”

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

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

【问题讨论】:

    标签: vhdl verilog fpga


    【解决方案1】:

    你可以这样做

    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 中的保留字。

    【讨论】:

      【解决方案2】:

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

      在 Lars 的回答中已经表达了 IEEE 库中没有预定义函数的原因,您倾向于不经常使用它,您可以将值分配给常量,并且可以从现有函数拼凑出一个表达式。

      一个示例 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 类型 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 此处不区分大小写)并且名称已更改。

      【讨论】:

      • 我认为你的舍入条件应该是Y > 1.0Y 始终为正数,在当前的舍入条件下,对于 2 的输入,函数会产生 2,这不是我对 ceil(log2()) 函数的期望。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多