VHDL 4位向量中的无符号乘法?

Unsigned multiplication in VHDL 4bit vector?

我正在制作一个 ALU,可以选择执行 A + 2B 但我无法理解乘以 2B 并在我的测试台上得到正确的答案。

例如:A = 0110 B = 0011 方程式是 A + 2B 我得到 0110

我的代码片段是

entity ALU is 
         port( A     :IN     STD_LOGIC_VECTOR(3 DOWNTO 0) ;
               B     :IN     STD_LOGIC_VECTOR(3 DOWNTO 0) ;
               S0    :IN     STD_LOGIC ;
               S1    :IN     STD_LOGIC ;
               M     :IN     STD_LOGIC ;
                    C0    :IN     STD_LOGIC ;

               Cout  :OUT    STD_LOGIC ;    
               Z     :OUT    STD_LOGIC ;
               F     :OUT    STD_LOGIC_VECTOR(3 DOWNTO 0));







  SIGNAL VariableAlu : STD_LOGIC_VECTOR(3 DOWNTO 0);
    SIGNAL FTEMP       : STD_LOGIC_VECTOR(3 DOWNTO 0);  
    SIGNAL FTEMP2      : STD_LOGIC_VECTOR(4 DOWNTO 0);
    SIGNAL ZTEMP        : STD_LOGIC;
    SIGNAL BTEMP1        : STD_LOGIC_VECTOR(4 DOWNTO 0);

        END ALU ;
        PROCESS(A,B,S0,S1,M,C0)
        BEGIN   

                VariableAlu <= (S0 & S1 & C0 & M); 
                 --M = 1 ARITHMETIC

  (part that shifts it, lab teacher told us to do this)
                    BTEMP1(4 DOWNTO 1)<= B;
                    BTEMP1(0)<= '0';

when "1111" => FTEMP2 <= ((A) + BTEMP1);

如有任何帮助,我们将不胜感激。

关于您的代码,有几点需要注意。首先,对于任何算法,避免使用 SLV 并坚持使用 numeric_std 库中的 unsignedsigned 类型。

您对操作数 B 的显式移位(乘以 2):

BTEMP1(4 DOWNTO 1)<= B;
BTEMP1(0)<= '0';

a) 不需要,b) 冗长。您可以通过简单地执行 BTEMP <= B & '0'; 来实现此目的,或者更好的是,甚至不使用中间信号并直接分配给 switch 语句中的 FTEMP2。例如

when "1111" => FTEMP2 <= std_logic_vector(unsigned(A) + unsigned(B&'0'));

注意上一行中的转换。它们是必需的,因为默认情况下,SLV 不支持 + 运算符(除非您使用 std_logic_unsignedstd_logic_signed 库)。为此,您需要包含 numeric_std 库。

编辑:

我还忘了提到 FTEMP 可能会溢出给定的函数; F <= A + 2B,其中AB都是4位,F是5位。

除了GSM说的,你也可以随便写。 IE。乘以 2。合成软件足够智能,可以识别您在做什么。 你要记住的是,结果会太大,所以必须调整大小。

library IEEE;
use IEEE.std_logic_1164.all;

entity input_output_adder is
    port (
        input_a : in  std_logic_vector(4 downto 0);
        input_b : in  std_logic_vector(4 downto 0);
        output  : out std_logic_vector(4 downto 0)
        );
end entity;

architecture rtl of input_output_adder is
    use IEEE.numeric_std.all;
begin
    output <= std_logic_vector(unsigned(input_a) + resize((unsigned(input_b) * 2), 5));
end architecture;

这将导致仅 LUT...nu 乘数。

来自 Vivado 的结果:

Quartus 的结果: