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

时间:2018-11-16 00:37:48

标签: vhdl fpga multiplication

我对VHDL有点陌生,我尝试通过实例学习。长话短说,我从一些基本示例开始,例如创建此Full Adder。 enter image description here

 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位加法器

enter image description here

这是我编写的代码。

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位乘法器,但我有点卡住了。实际上,这就是我要实现的乘数。enter image description here

我写的代码是这样,但是我被困在端口图上

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

1 个答案:

答案 0 :(得分:2)

“我被卡在端口图上” 不是特定的问题说明。

使用命名关联,只要正式形式中的所有成员都已关联,地图中正式端口的成员就可以单独以及整个关联。 2008 6.5.7关联列表:

  

正式的接口对象应为显式声明的接口对象或该接口对象的成员(请参见5.1)。在前一种情况下,这种正式形式被称为“整体”。在后一种情况下,应使用命名关联将正式和实际关联起来;这种形式化的子元素被称为单独关联。此外,显式声明的接口对象的每个标量子元素应与同一关联列表中的实际(或其子元素)精确关联一次,并且所有此类关联应在该关联列表内以连续的顺序出现。每个与接口对象的切片或子元素(或其切片)相关联的关联元素都应使用本地静态名称标识形式。

请注意,您的携带元素太多(只需要两个),不需要andgate(0),不需要sumout(0),sumout(4)或sumout(11 downo 8),有一个多余的字符在multy架构中,您缺少上下文子句,而有未使用的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。