vhdl中的4位加法器

时间:2013-09-13 19:49:16

标签: vhdl intel-fpga

我对vhdl语言很新,所以请耐心等待。我刚刚为1位加法器做了vhdl代码,但是我在编写4位加法器时遇到了麻烦。这就是我到目前为止所得到的,如果有人能够指出我正确的方向,那将会是什么样的!

VHDL代码:

LIBRARY IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 

ENTITY Adder4 IS
  GENERIC(CONSTANT N: INTEGER := 4);
  PORT(
    a, b: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);  -- Input SW[7..4]: a[3..0] inputs,
                                              -- SW[3..0]: b[3..0]
    sum: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); -- Output LEDR[3..0]
    cOut: OUT STD_LOGIC -- Output LEDR[4]
  );
END Adder4;

ARCHITECTURE imp OF Adder4 IS
  COMPONENT Adder1 
  PORT(
    a, b, cIn : in STD_LOGIC;
    sum, cOut : out STD_LOGIC);
  END COMPONENT;
  SIGNAL carry_sig: std_logic_vector(N DOWNTO 0);
BEGIN
  -- What to write here?
END imp;

2 个答案:

答案 0 :(得分:3)

根据sharth关于你有意在Adder4中实例化N个Adder1的机会的正确答案:

ARCHITECTURE imp OF Adder4 IS
COMPONENT Adder1 
PORT(
a, b, cIn : in STD_LOGIC;
sum, cOut : out STD_LOGIC);
END COMPONENT;
SIGNAL carry_sig: std_logic_vector(N-1 DOWNTO 0);
signal carry_in:  std_logic_vector(N-1 DOWNTO 0);
BEGIN
-- What to write here?

    carry_in <= ((carry_sig(N-2 downto 0)) &'0');
Adders:
for i in 0 to N-1 generate
    begin
    ADD1:
        Adder1 port map (
            a => a(i), 
            b => b(i),
            cIn => carry_in(i),
            sum => sum(i),
            cOut => carry_sig(i)            
        );
    end generate;

Carry_Out:
    cOut <= carry_sig(N-1);

END imp;

ARCHITECTURE gen OF Adder4 IS
    COMPONENT Adder1 
    PORT(
        a, b, cIn : in STD_LOGIC;
        sum, cOut : out STD_LOGIC);
        END COMPONENT;

SIGNAL carry_sig: std_logic_vector(N-1 DOWNTO 0);

BEGIN
-- What to write here?

Adders:
    for i in 0 to N-1 generate
    ADD0:    
        if i = 0 generate
        Add1:
            Adder1 port map (
                a => a(i), 
                b => b(i),
                cIn => '0',
                sum => sum(i),
                cOut => carry_sig(i)            
            );
        end generate;
    ADDN:
        if i /= 0 generate
            Add1:
            Adder1 port map (
                a => a(i), 
                b => b(i),
                cIn => carry_sig(i-1),
                sum => sum(i),
                cOut => carry_sig(i)  
            );          
        end generate;

    end generate;

Carry_Out:
    cOut <= carry_sig(N-1);

END architecture;

我自己更喜欢第一个架构(imp),需要第二个std_logic_vector用于carry_in,但是大大简化了任何生成构造。两者之间的层次结构存在差异,第一个更容易阅读。


第一个体系结构(imp)还显示了如何手动实例化Adder1四次,消除了generate构造并将所有(i)范围表达式替换为它们各自的Adder1实例范围表达式((0),(1),(2) ,(3),分别)。

手动实例化的adder1s看起来像:

-- Note in this case you'd likely declare all the std_logic_vector with 
-- ranges (3 downto 0)


    SIGNAL carry_sig: std_logic_vector(3 DOWNTO 0);
    signal carry_in:  std_logic_vector(3 downto 0);
BEGIN
-- What to write here?

    carry_in <= ((carry_sig(2 downto 0)) &'0'); 

    ADD0:
        Adder1 port map (
            a => a(0), 
            b => b(0),
            cIn => carry_in(0),
            sum => sum(0),
            cOut => carry_sig(0)            
        );

 ...

    ADD3:
        Adder1 port map (
            a => a(3), 
            b => b(3),
            cIn => carry_in(3),
            sum => sum(3),
            cOut => carry_sig(3)            
        );

cOut <= carry_sig(3); -- or connect directly to cOut in ADD3 above

使用carry_sig的附加carry_in向量向上调整,最小有效carry_in为'0',这使得编写起来很简单。如果进位和执行信号分别命名,则执行进位超前方法也会更容易阅读。


测试台也可以容纳宽度N Adder4:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity adder4_tb is
       constant N:  natural := 4; 
end entity;

architecture tb of adder4_tb is
   signal a,b,sum:  std_logic_vector (N-1 downto 0);
   signal carryout:    std_logic;

begin

DUT: entity work.Adder4
    generic map (N => N)  -- associates formal N with actual N (a constant)
    port map (
        a => a,
        b => b,
        sum => sum,
        cOut => carryout
    );

STIMULUS:
    process 
    variable i,j:   integer;
    begin
        for i in 0 to N*N-1 loop
            for j in 0 to N*N-1 loop
                a <= std_logic_vector(to_unsigned(i,N)); 
                b <= std_logic_vector(to_unsigned(j,N));
                wait for 10 ns;     -- so we can view waveform display
            end loop;
        end loop;
        wait;   -- end the simulation
    end process;   
end architecture;

所有这些都不考虑承载树延迟时间,这可能会受到实施或使用快速进位电路的影响(例如,抬头向前看)。

这为我们提供了一个模拟:

Adder4_tb Simulation Waveform

或者仔细观察:

Adder4_tb Simulation Waveform, closeup

当使用基于生成语句的体系结构时,如果更改了N的声明,则会有一个加法器,它将以N指定的可变宽度进行合成和模拟,直到纹波进位不再适用于输入数据速率(10 ns目前在测试平台上)。

注意,通用N形式与测试平台中声明的实际N的通用映射关联意味着在这种情况下,在测试平台中声明的N也在Adder4中设置宽度N.

答案 1 :(得分:1)

那么,我们应该问的第一个问题是原理图应该是什么样子。也许是这样的:

enter image description here