基于4位加法器的VHDL 4位乘法器

VHDL 4-bit multiplier based on 4-bit adder

我对 VHDL 有点陌生,我尝试通过示例学习。长话短说,我从一些基本的例子开始,比如创建这个全加器。

 entity FA is
 Port ( A : in STD_LOGIC;
    B : in STD_LOGIC;
    Cin : in STD_LOGIC;
    S : out STD_LOGIC;
    Cout : out STD_LOGIC);
end FA;

architecture gate_level of FA is

begin

 S <= A XOR B XOR Cin ;
 Cout <= (A AND B) OR (Cin AND A) OR (Cin AND B) ;

end gate_level;

之后我尝试实现这个 4 位加法器

这是我写的代码。

entity Ripple_Adder is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Cin : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0);
Cout : out STD_LOGIC);
end Ripple_Adder;

architecture Behavioral of Ripple_Adder is

-- Full Adder VHDL Code Component Decalaration
component FA
Port (  A : in STD_LOGIC;
    B : in STD_LOGIC;
    Cin : in STD_LOGIC;
    S : out STD_LOGIC;
    Cout : out STD_LOGIC);
end component;

-- Intermediate Carry declaration
signal c1,c2,c3: STD_LOGIC;

begin

-- Port Mapping Full Adder 4 times
FA1: FA port map( A(0), B(0), Cin, S(0), c1);
FA2: FA port map( A(1), B(1), c1, S(1), c2);
FA3: FA port map( A(2), B(2), c2, S(2), c3);
FA4: FA port map( A(3), B(3), c3, S(3), Cout);

end Behavioral;

我还使用了 4_bit_adder 测试台文件,我发现输出是正确的。现在我正在尝试使用 4 位加法器实现 4 位乘法器,但我有点卡住了。实际上这是我要实现的乘数。

我写的代码是这样的,但是卡在了端口映射

--library
library IEEE;
   use IEEE.std_logic_1164.all;
   use IEEE.std_logic_textio.all;
   use IEEE.std_logic_unsigned.all;

--entity
entity multy is
  port (x: in std_logic_vector(3 downto 0);
        y: in std_logic_vector(3 downto 0);
        p : out std_logic_vector(7 downto 0)
        );
end multy ;

-- architecture
architecture rtl of multy is
component Ripple_Adder
  Port ( A : in std_logic_vector (3 downto 0);
     B : in std_logic_vector (3 downto 0);
     Cin : in std_logic;
     S : out std_logic_vector (3 downto 0);
     Cout : out std_logic);
end component ;

signal andgate: std_logic_vector(15 downto 0);
signal sumout: std_logic_vector( 11 downto 0);
signal carry: std_logic_vector(11 downto 0);


begin
    andgate(0) <= x(0) and y(0);
    andgate(1) <= x(1) and y(0); --b0
    andgate(2) <= x(2) and y(0); --b1
    andgate(3) <= x(3) and y(0); --b2
B

    andgate(4) <= x(0) and y(1);
    andgate(5) <= x(1) and y(1);
    andgate(6) <= x(2) and y(1);
    andgate(7) <= x(3) and y(1);

    andgate(8) <= x(0) and y(2);
    andgate(9) <= x(1) and y(2);
    andgate(10) <= x(2) and y(2);
    andgate(11) <= x(3) and y(2);

    andgate(12) <= x(0) and y(3);
    andgate(13) <= x(1) and y(3);
    andgate(14) <= x(2) and y(3);
    andgate(15) <= x(3) and y(3);

--gates


cell_1: Ripple_Adder port map();
cell_2: Ripple_Adder port map();
cell_3: Ripple_Adder port map();


 --Assigning p values
    p(0) <= andgate(0);
    p(1) <= sumout(0);
    p(2) <= sumout(4);
    p(3) <= sumout(8);
    p(4) <= sumout(9);
    p(5) <= sumout(10);
    p(6) <= sumout(11);
    p(7) <= carry(11);

end rtl ;  

"I am stuck on the port map" 不是具体的问题陈述。

在映射中正式端口的命名关联成员可以单独关联,也可以整体关联,只要正式关联 - IEEE Std 1076-2008 6.5.7 关联列表:

A formal interface object shall be either an explicitly declared interface object or member (see 5.1) of such an interface object. In the former case, such a formal is said to be associated in whole. In the latter cases, named association shall be used to associate the formal and actual; the subelements of such a formal are said to be associated individually. Furthermore, every scalar subelement of the explicitly declared interface object shall be associated exactly once with an actual (or subelement thereof) in the same association list, and all such associations shall appear in a contiguous sequence within that association list. Each association element that associates a slice or subelement (or slice thereof) of an interface object shall identify the formal with a locally static name.

注意你有太多的进位元素(只需要两个),不需要andgate(0),不需要sumout(0),sumout(4) or sumout(11 downo 8),有一个多体系结构中的无关字符,您缺少上下文子句并且有未使用的 use 子句。

您的代码使用数组中间信号:

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_textio.all;   -- NOT USED
-- use ieee.std_logic_unsigned.all; -- NOT USED

entity multy is 
    port (
        x: in  std_logic_vector (3 downto 0);
        y: in  std_logic_vector (3 downto 0);
        p: out std_logic_vector (7 downto 0)
    );
end entity multy;

architecture rtl of multy is
    component Ripple_Adder
        port ( 
            A:      in  std_logic_vector (3 downto 0);
            B:      in  std_logic_vector (3 downto 0);
            Cin:    in  std_logic;
            S:      out std_logic_vector (3 downto 0);
           Cout:    out std_logic
        );
    end component;
-- AND Product terms:
    signal G0, G1, G2:  std_logic_vector (3 downto 0);
-- B Inputs (B0 has three bits of AND product)
    signal B0, B1, B2:  std_logic_vector (3 downto 0);

begin

    -- y(1) thru y (3) AND products, assigned aggregates:
    G0 <= (x(3) and y(1), x(2) and y(1), x(1) and y(1), x(0) and y(1));
    G1 <= (x(3) and y(2), x(2) and y(2), x(1) and y(2), x(0) and y(2));
    G2 <= (x(3) and y(3), x(2) and y(3), x(1) and y(3), x(0) and y(3));
    -- y(0) AND products (and y0(3) '0'):
    B0 <=  ('0',          x(3) and y(0), x(2) and y(0), x(1) and y(0));

-- named association:
cell_1: 
    Ripple_Adder 
        port map (
            a => G0,
            b => B0,
            cin => '0',
            cout => B1(3), -- named association can be in any order
            S(3) => B1(2), -- individual elements of S, all are associated
            S(2) => B1(1), -- all formal members must be provide contiguously
            S(1) => B1(0),
            S(0) => p(1)
        );
cell_2: 
    Ripple_Adder 
        port map (
            a => G1,
            b => B1,
            cin => '0',
            cout => B2(3),
            S(3) => B2(2),
            S(2) => B2(1),
            S(1) => B2(0),
            S(0) => p(2)
        );
cell_3: 
    Ripple_Adder 
        port map (
            a => G2,
            b => B2,
            cin => '0',
            cout => p(7),
            S => p(6 downto 3)  -- matching elements for formal
        );
    p(0) <= x(0) and y(0); 
end architecture rtl;

并借来一个测试台来演示:

library ieee;
use ieee.std_logic_1164.all;

entity multy_tb is           -- testbench
end entity;

architecture foo of multy_tb is
    signal x, y:        std_logic_vector (3 downto 0);
    signal yp, rp:      std_logic_vector (7 downto 0);

    use ieee.numeric_std.all;

    function to_string (inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end function;

begin
DUT:
    entity work.multy
        port map (
            x => x,
            y => y,
            p => yp
        );
STIMULI:
    process
    begin
        for i in 0 to 15 loop
            x <= std_logic_vector(to_unsigned(i, x'length));
            for j in 0 to 15 loop
                y <= std_logic_vector(to_unsigned(j, y'length));
                wait for 0 ns; -- assignments take effect
                rp <= std_logic_vector(unsigned (x) * unsigned(y));
                wait for 10 ns;
                if yp /= rp then
                    report "multy error";
                    report HT & "expected " & to_string (rp);
                    report HT & "got      " & to_string (yp);
                end if;
            end loop;
        end loop;
        wait;
    end process;
end architecture;

-2008 之前的模拟器包含 to_string 函数。上下文子句已添加到 FA 和 Ripple_Adder.