我很难在 16 位 ALU 中实现乘法过程。明显的问题是,当结果实际上是 32 位时,我有 2 个 16 位输入和 1 个 16 位输出。我尝试声明一个 32 位的内部信号,然后对其进行切片,但在基准测试中它总是输出 x"XXXX"。我的教授说,如果我使用多路复用器来每次选择 32 位输出的位,当 a 和 b 较大时选择 16msb,当它们较小时选择 16lsb,效果会更好。然而,他不擅长指导我,我似乎无法独自做到这一点。谁能告诉我我当前的代码有什么问题以及我的教授所说的是否可以做到?
library ieee; -- finished i think
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu is
port(
a : in std_logic_vector (15 downto 0); -- opperand a
b : in std_logic_vector (15 downto 0); -- opperand b
alu_sel : in std_logic_vector (3 downto 0);
sh : in std_logic_vector(2 downto 0);
c : out std_logic_vector (15 downto 0); -- output
zer : out std_logic); -- result equals 0
end entity;
architecture bhv of alu is
signal mul_sig : std_logic_vector(31 downto 0);
begin
process(a,b,alu_sel) is
begin
if alu_sel = "0000" then
c <= a and b;
elsif alu_sel = "0001" then
c <= a or b;
elsif alu_sel = "0010" then
c <= a xor b;
elsif alu_sel = "0011" then
c <= std_logic_vector(unsigned(a) + unsigned(b));
elsif alu_sel = "0100" then
c <= std_logic_vector(unsigned(a) - unsigned(b));
if a = b then
zer <= '1';
else
zer <= '0';
end if;
elsif alu_sel = "0101" then -- logical left shift
c <= std_logic_vector(shift_left(unsigned(a), to_integer(unsigned(sh))));
elsif alu_sel = "0110" then -- logical right shift
c <= std_logic_vector(shift_right(unsigned(a), to_integer(unsigned(sh))));
elsif alu_sel = "0111" then
mul_sig <= std_logic_vector(unsigned(a) * unsigned(b));
c <= mul_sig(31 downto 16); -- this isn't working for some reason
elsif alu_sel = "1000" then
c <= not a;
else
c <= (others =>'Z'); -- NULL?
end if;
end process;
end architecture;
您的进程在敏感度列表中缺少几个信号 - 特别是
sh
和 mul_sig
。如果敏感度列表中没有 mul_sig
,则分配 mul_sig 后C
无法更新,因此它始终为“X”。我建议使用 VHDL 2008,它允许 process(all)
允许编译器根据进程中的所有所需信号确定自身的敏感度列表。