VHDL:生成具有可调整的用例数量的通用用例语句

  • 本文关键字:语句 可调整 VHDL vhdl
  • 更新时间 :
  • 英文 :


我想通过将值保存在LUT中获得Tanh函数的近似值(通过这种方式,我正在进行量化)。我想选择LUT中的条目数。

作为一个不正确的例子,我想象一个像 这样的代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.fixed_pkg.all;
entity tanh_lut is
generic (
MIN_RANGE: real := 0.0; -- Minimum value of x
MAX_RANGE: real := 5.0; -- Maximum value of x
DATA_RANGE_int: positive:= 8; 
DATA_RANGE_frac: positive:= 8; 
);
Port ( DIN : in sfixed(DATA_RANGE_int-1 downto -(DATA_RANGE_frac-1));
DOUT : out sfixed(DATA_RANGE_int-1 downto -(DATA_RANGE_frac-1))
end tanh_lut;
architecture Behavioral of tanh_lut is
begin

lut_gen: for i in 0 to LUT_SIZE-1 generate
constant x_val :      real := MIN_RANGE + (MAX_RANGE - MIN_RANGE) *  i    / (LUT_SIZE-1);
constant x_val_next : real := MIN_RANGE + (MAX_RANGE - MIN_RANGE) * (i+1) / (LUT_SIZE-1);
constant y_val :      real := tanh(x_val);
if DIN>=x_val_previous AND DIN<x_val then
DOUT  <= to_sfixed(tanh(y_val),DOUT  ) ;
END IF
end generate;
end Behavioral;

例如,如果我想在0到3的范围内有4个条目,我希望它合成如下代码:

if DIN>0 AND DIN<=1 then
DOUT  <= to_sfixed(0, DOUT);
else DIN>1 AND DIN<=2 then
DOUT  <= to_sfixed(0.76159415595, DOUT);
else DIN>2 AND DIN<=3 then
DOUT  <= to_sfixed(0.96402758007, DOUT);
else DIN>3 AND DIN<=4 then
DOUT  <= to_sfixed(0.99505475368, DOUT);
End if

这样的代码或实现其背后思想的代码是否有可能实现?

带地址的简单LUT是不可能的,因为地址总是整数,DIN是定点,例如1.5

另一种可能是两个LUT,一个用于将Input映射到地址,另一个用于将地址映射到LUT项,例如,LUT1: 1.5=>地址5,LUT2:地址5 =>0.90. 但是这样的话,我就会把我不想要的资源翻倍

我的要求:像tanh(x)这样的东西不应该被合成,只有tanh(x)的最终值。它还应该是硬件高效的

无论您是使用嵌套的" if-elsif "结构还是为每个检查使用新的" if "结构都没有关系。所以你可以创建一个这样的循环:

for i in 0 to c_number_of_checks-1 loop
if c_boundaries(i)<DIN and DIN<=c_boundaries(i+1) then
DOUT <= c_output_values(i);
end if;
end loop;

当然你必须提供常量c_number_of_checks和c_boundaries, c_output_values。可以这样做:

constant c_number_of_checks : natural := 4;
type array_of_your_data_type is array (natural range <>) of your_data_type;
constant c_boundaries : array_of_your_data_type(c_number_of_checks downto 0) := init_c_boundaries(c_number_of_checks);
constant c_output_values : array_of_your_data_type(c_number_of_checks-1 downto 0) := init_c_output_values(c_number_of_checks);

这意味着您将需要init_c_boundaries, init_c_output_values函数,它们创建值数组,可以初始化常量c_boundaries和c_output_values。但这并不复杂(您可以使用ieee。math_real(函数TANH),因为函数不需要是可合成的,因为它们只在编译时被调用。

如你所见,你将有一些努力。因此,也许遵循其他建议更容易。如果您这样做(值作为LUT的地址),您应该考虑自动ROM推断,这是由几个工具链提供的,并将为您提供非常高效(小型)的硬件。

最新更新