将数字提高到 VHDL 中变化的幂
Raise a number to a power that varies in VHDL
我需要编写一个实现此相关性的过程 table :
E -> S
0 -> 2
1 -> 4
2 -> 8
3 -> 16
4 -> 32
5 -> 64
等等。
你可以清楚地看到输出可以很容易地计算出来:
S = 1^(E+1)
但是我不确定是否可以在左移的 VHDL 中执行此操作。困扰我的是我们事先不知道 (E+1) 的大小,所以我们不知道需要添加多少个 0 所以等式两边的大小相同。
在 VHDL 中是否有一种聪明的方法来做到这一点(比做 MUX 更聪明)?
这在很多方面都是可行的。例如。
开始:
use ieee.math_real.all;
constant E : natural := 0; -- any value >= 0
constant S : integer := natural(2 ** real(E+1));
或
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0):= (
(E+1) => '1',
others => '0');
或
use ieee.math_real.all;
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0) :=
to_unsigned(integer(2 ** real(E+1)), E+2));
或
use ieee.numeric_std.all;
....
constant E : natural := 0;
signal S : unsigned((E+1) downto 0);
....
S <= left_shift(to_unsigned(1, (E+2)), E+1);
等等等等
我的意思是,你想达到什么目标?
有几种不同的方法可以实现这一点(为了综合的目的);我敢肯定,这里列出的不止这些。如果 E
是您模块的通用输入(听起来不像,否则您会提前知道 E+1
是什么),则不需要 "additional" 逻辑。
如果 E
是模块的输入,但你有 E 的上限,你可以简单地使用 ROM 作为查找(这不是内存的有效使用,但可以工作).或者,您可以使用一个函数,该函数将 E
作为输入,returns 表示结果的向量 S
(请注意,这还需要 E
有界,这限制结果的大小)。
constant MAX_WID : natural := 64;
...
-- You can use unsigned in place of slv, if that is more suitable
function calc_s(e : integer) return std_logic_vector is
-- MAX_WID is effectively your maximum value of E
variable ret : std_logic_vector(MAX_WID+1 downto 0) := (others => '0');
begin
ret(e+1) := '1';
return ret;
end calc_s;
我需要编写一个实现此相关性的过程 table :
E -> S
0 -> 2
1 -> 4
2 -> 8
3 -> 16
4 -> 32
5 -> 64
等等。
你可以清楚地看到输出可以很容易地计算出来:
S = 1^(E+1)
但是我不确定是否可以在左移的 VHDL 中执行此操作。困扰我的是我们事先不知道 (E+1) 的大小,所以我们不知道需要添加多少个 0 所以等式两边的大小相同。
在 VHDL 中是否有一种聪明的方法来做到这一点(比做 MUX 更聪明)?
这在很多方面都是可行的。例如。 开始:
use ieee.math_real.all;
constant E : natural := 0; -- any value >= 0
constant S : integer := natural(2 ** real(E+1));
或
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0):= (
(E+1) => '1',
others => '0');
或
use ieee.math_real.all;
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0) :=
to_unsigned(integer(2 ** real(E+1)), E+2));
或
use ieee.numeric_std.all;
....
constant E : natural := 0;
signal S : unsigned((E+1) downto 0);
....
S <= left_shift(to_unsigned(1, (E+2)), E+1);
等等等等
我的意思是,你想达到什么目标?
有几种不同的方法可以实现这一点(为了综合的目的);我敢肯定,这里列出的不止这些。如果 E
是您模块的通用输入(听起来不像,否则您会提前知道 E+1
是什么),则不需要 "additional" 逻辑。
如果 E
是模块的输入,但你有 E 的上限,你可以简单地使用 ROM 作为查找(这不是内存的有效使用,但可以工作).或者,您可以使用一个函数,该函数将 E
作为输入,returns 表示结果的向量 S
(请注意,这还需要 E
有界,这限制结果的大小)。
constant MAX_WID : natural := 64;
...
-- You can use unsigned in place of slv, if that is more suitable
function calc_s(e : integer) return std_logic_vector is
-- MAX_WID is effectively your maximum value of E
variable ret : std_logic_vector(MAX_WID+1 downto 0) := (others => '0');
begin
ret(e+1) := '1';
return ret;
end calc_s;