我需要编写一个实现此关联表的进程:
E - >小号
0 - > 2
1 - > 4
2 - > 8
3 - > 16
4 - > 32
5 - > 64
等等。
您可以清楚地看到输出可以轻松计算:
S = 1^(E+1)
但是,我不确定是否可以在左移VHDL中执行此操作。困扰我的是我们事先并不知道(E + 1)的大小,因此我们不知道需要添加多少0,因此方程的两边都有相同的大小。
有没有一种聪明的方法可以在VHDL中做到这一点(比做MUX更聪明)?
答案 0 :(得分:1)
这在很多方面都是可行的。例如。 开始:
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);
Etc等。
我的意思是,你想达到什么目标?
答案 1 :(得分:1)
实现这一目标的方法很少(为了合成的目的);我确定这里列出的不止这些。如果E
是您的模块的通用输入(它听起来不是这样,否则您会知道提前E+1
),否则&#34;其他&#34;逻辑是必需的。
如果E
是模块的输入,但是你有一个E的上限,你可以简单地使用ROM作为查找(这不是一个有效的内存使用,但会工作)。或者,您可以使用以E
作为输入的函数,并返回表示结果的向量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;