1

我对 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;
4

2 回答 2

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 用于进位输入,但大大简化了任何生成构造。两者之间的层次结构有所不同,第一个更易于阅读。


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

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

-- 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 的附加进位向量向上调整,最低有效进位进位为“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 仿真波形

或者为了更仔细地查看:

Adder4_tb 仿真波形,特写

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

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

于 2013-09-14T03:20:21.243 回答
1

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

在此处输入图像描述

于 2013-09-13T20:45:36.013 回答