vivado生成的function clogb2() can't synthesize with loop limit error
Function clogb2() generated by vivado can't synthesize with loop limit error
我正在尝试用 vivado 设计一个 AXI_master 外围设备。我在vivado菜单中使用了axi peripheral generator,修改了生成的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;
这在模拟 (GHDL) 中有效,但在合成中失败并出现错误:
[Synth 8-403] loop limit (65538) exceeded
我尝试使用以下 tcl 命令增加 vivado 中的循环限制:
set_param synth.elaboration.rodinMoreOptions "rt::set_parameter max_loop_limit <X>"
如解释的那样here,但是vivado 的合成时间是无限的,永远不会完成。
你知道如何解决这个问题吗?
尝试限制输入的范围,例如:
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;
最后我找到了一个解决方案,通过用大 case 重写函数来工作:
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;
你可以用它来标注其他东西,例如
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
-- ^
-- |
我正在尝试用 vivado 设计一个 AXI_master 外围设备。我在vivado菜单中使用了axi peripheral generator,修改了生成的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;
这在模拟 (GHDL) 中有效,但在合成中失败并出现错误:
[Synth 8-403] loop limit (65538) exceeded
我尝试使用以下 tcl 命令增加 vivado 中的循环限制:
set_param synth.elaboration.rodinMoreOptions "rt::set_parameter max_loop_limit <X>"
如解释的那样here,但是vivado 的合成时间是无限的,永远不会完成。 你知道如何解决这个问题吗?
尝试限制输入的范围,例如:
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;
最后我找到了一个解决方案,通过用大 case 重写函数来工作:
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;
你可以用它来标注其他东西,例如
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
-- ^
-- |