将数字提高到VHDL中不同的幂

将数字提高到VHDL中不同的幂,vhdl,Vhdl,我需要编写一个实现此关联表的流程: 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;

我需要编写一个实现此关联表的流程:

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));

使用ieee.numeric\u std.all;
....
常数E:自然值:=0;
信号S:无符号((E+1)向下至0);
....

这在许多方面是可能的。例如。 开始:

use ieee.math_real.all;

constant E : natural := 0; -- any value >= 0
constant S : integer := natural(2 ** real(E+1));

使用ieee.numeric\u std.all;
....
常数E:自然值:=0;
信号S:无符号((E+1)向下至0);
....

S实现这一点的方法很少(用于合成);我相信这里列出的不止这些。如果
E
是模块的通用输入(听起来不像,否则您会事先知道
E+1
是什么),则不需要“附加”逻辑

如果
E
是模块的一个输入,但您在E上有一个上限,您可以简单地使用ROM作为查找(这不是内存的有效使用,但会起作用)。或者,您可以使用一个函数,该函数将
E
作为输入,并返回一个表示结果的向量,
S
(请注意,这也要求
E
有界,从而限制结果的大小)


实现这一点的方法很少(用于合成);我相信这里列出的不止这些。如果
E
是模块的通用输入(听起来不像,否则您会事先知道
E+1
是什么),则不需要“附加”逻辑

如果
E
是模块的一个输入,但您在E上有一个上限,您可以简单地使用ROM作为查找(这不是内存的有效使用,但会起作用)。或者,您可以使用一个函数,该函数将
E
作为输入,并返回一个表示结果的向量,
S
(请注意,这也要求
E
有界,从而限制结果的大小)


在VHDL中有很多可能。但你想要什么:只是一个模拟,还是一个可合成的代码?如果是后者,您希望运行的时钟频率是多少?这个问题其实并不难,但输出的长度(即位数)是可变的。在VHDL中有很多可能。但你想要什么:只是一个模拟,还是一个可合成的代码?如果是后者,您希望运行的时钟频率是多少?这个问题其实并不难,但输出的长度(即位数)是可变的。它可以工作,但“MAX_WID+1 downto 0”是如何合成的?如果总线发生变化,合成器如何知道总线的长度;MAX_WID是一个表示输入上限的常数,例如,是的,这也是一种可能性;)显然是最好的;PIt可以工作,但是如何合成“(MAX_WID+1到0)”呢?如果总线发生变化,合成器如何知道总线的长度;MAX_WID是一个表示输入上限的常数,例如,是的,这也是一种可能性;)显然是最好的;P
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);
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;