Vhdl vivado can';带回路极限误差的t综合

Vhdl vivado can';带回路极限误差的t综合,vhdl,vivado,Vhdl,Vivado,我想用vivado设计一个AXI_主外设。我在vivado菜单中使用了axi外围设备生成器,并修改了生成的vhdl代码 在vhdl代码中,有一个函数clogb2是用以下代码声明的: function clogb2 (bit_depth : integer) return integer is variable depth : integer := bit_depth; variable count : integer := 1; begin for clogb2 in 1

我想用vivado设计一个AXI_主外设。我在vivado菜单中使用了axi外围设备生成器,并修改了生成的vhdl代码

在vhdl代码中,有一个函数clogb2是用以下代码声明的:

function clogb2 (bit_depth : integer) return integer is
    variable depth  : integer := bit_depth;
    variable count  : integer := 1;
begin
  for clogb2 in 1 to bit_depth loop  -- Works for up to 32 bit integers
    if (bit_depth <= 2) then
      count := 1;
    else
      if(depth <= 1) then
          count := count;
        else
          depth := depth / 2;
        count := count + 1;
        end if;
    end if;
  end loop;
  return(count);
end;
函数clogb2(位深度:整数)返回整数为
可变深度:整数:=位深度;
变量计数:整数:=1;
开始
对于1到位深度循环中的clogb2——最多可用于32位整数

如果(位深度尝试约束输入范围,例如:

function clogb2 (bit_depth : integer range 1 to 32) return integer is

此外,如果Vivado正在生成无法编译的代码,这是一个错误,您应该在Xilinx论坛上报告。

您也可以尝试其他路径。虽然逻辑中不支持浮点(尽管支持正在增加),但允许进行内部计算等。(至少Xilinx和Altera/Intel支持)

试试这个:

use ieee.math_real.all;

function ceillog2(input : positive) return natural is
begin
    return integer(ceil(log2(real(input))));
end function;

最后,我找到了一个解决方案,通过用一个大箱重写函数:

function clogb2 (bit_depth : integer) return integer is
 begin
     case bit_depth is
         when 0 to 2             => return( 1);
         when (2** 1)+1 to 2** 2 => return( 2);
         when (2** 2)+1 to 2** 3 => return( 3);
         when (2** 3)+1 to 2** 4 => return( 4);
         when (2** 4)+1 to 2** 5 => return( 5);
         when (2** 5)+1 to 2** 6 => return( 6);
         when (2** 6)+1 to 2** 7 => return( 7);
         when (2** 7)+1 to 2** 8 => return( 8);
         when (2** 8)+1 to 2** 9 => return( 9);
         when (2** 9)+1 to 2**10 => return(10);
         when (2**10)+1 to 2**11 => return(11);
         when (2**11)+1 to 2**12 => return(12);
         when (2**12)+1 to 2**13 => return(13);
         when (2**13)+1 to 2**14 => return(14);
         when (2**14)+1 to 2**15 => return(15);
         when (2**15)+1 to 2**16 => return(16);
         when (2**16)+1 to 2**17 => return(17);
         when (2**17)+1 to 2**18 => return(18);
         when (2**18)+1 to 2**19 => return(19);
         when (2**19)+1 to 2**20 => return(20);
         when (2**20)+1 to 2**21 => return(21);
         when (2**21)+1 to 2**22 => return(22);
         when (2**22)+1 to 2**23 => return(23);
         when (2**23)+1 to 2**24 => return(24);
         when (2**24)+1 to 2**25 => return(25);
         when (2**25)+1 to 2**26 => return(26);
         when (2**26)+1 to 2**27 => return(27);
         when (2**27)+1 to 2**28 => return(28);
         when (2**28)+1 to 2**29 => return(29);
         when (2**29)+1 to 2**30 => return(30);
         when (2**30)+1 to (2**31)-1 => return(31);
         when others => return(0);
     end case;
 end;

使用这种奇怪的代码结构,可以在合成和模拟中工作。

此递归版本合成:

function clogb2 (bit_depth : integer) return integer is 
  begin
    if bit_depth <= 1 then
      return 0;
    else
      return clogb2(bit_depth / 2) + 1;
    end if;
  end function clogb2;
也可以将其用作组合逻辑:

process (I)
begin
  O <= clogb2(I);
end process;

你看过其他答案吗?这根本不是一个优雅的解决方案。但是你喜欢这个答案吗?
clog2bee.vhdl:20:9:@0ms:(报告注释):clogb2(112000)=16
。这个特定的值需要一个17的二进制长度来描述。函数调用也应该有一个正的范围。负整数或零值永远不会达到位\u depth=1。根据工具的不同,它会有一个递归限制,它只会循环,否则调用堆栈就会用完。@user1155120我喜欢答案:log2 o在整数数学中,f 112000是16。原始函数确实使用了正输入-我更改了接口和函数名称以匹配问题。2**16是65536。容纳112000值的上限(如接受答案的ceillog2)是2**17(131072)其中11200介于两者之间。您的函数提供了一个下限值。在您的辩护中,该问题可能显示了函数调用的用途。具有未指定初始值的整数类型将默认为integer'LEFT,这是一个负数。如果参数类型标记为允许一个负值。我个人发现旋转循环进行递归调用的模拟器在道德上令人反感,但在标准下并没有被定义为错误或错误。
entity counter is
  generic (max_count : POSITIVE);
  port (clock, reset : in  std_logic;
        Q            : out std_logic_vector(clogb2(max_count) downto 0)  
       );
end;
process (I)
begin
  O <= clogb2(I);
end process;
function clogb2 (bit_depth : positive) return integer is 
--                               ^
--                               |