vhdl 中的 4 位加法器 [英] 4 bit adder in vhdl

查看:46
本文介绍了vhdl 中的 4 位加法器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 vhdl 语言还很陌生,所以请耐心等待.我刚刚为 1 位加法器编写了 vhdl 代码,但我在为 4 位加法器编写代码时遇到了麻烦.这就是我到目前为止所得到的,如果有人能指出我要查找的正确方向,那就太棒了!

im pretty new to the vhdl language so please bear with me. I just did the vhdl code for a 1 bit adder, but I am having trouble writing for the 4bit adder. This is what I got so far, if anybody could point me in the right direction of what to look up that would be awesome!

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;

推荐答案

鉴于您确实打算在 Adder4 中实例化 N 个 Adder1 的机会,考虑到 sharth 的好答案:

In deference to sharth's fine answer on the chance you did intend to have an N number of Adder1s instantiated in 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-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 用于进位,但大大简化了任何生成构造.两者在层次结构上有所不同,第一个更容易阅读.

I prefer the first architecture (imp) myself, requiring a second std_logic_vector for carry_in, but greatly simplifying any generate construct. There's a difference in hierarchy between the two and first is easier to read.

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

The first architecture (imp) also shows how to instantiate Adder1 four times manually, eliminating the generate construct and substituting all (i) range expressions for their respective Adder1 instance range expressions ((0),(1),(2),(3), respectively).

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

The manually instantiated adder1s would look something like:

-- 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_in 向量使用carry_sig 向上调整,最低有效carry_in 为0",这使得编写变得简单.如果进位信号和进位信号分开命名,那么实现进位前瞻方法也更容易阅读.

The additional carry_in vector using carry_sig adjusted upward with a least significant carry_in of '0' makes it simple to write. It can also be easier to read implementing a carry look ahead method if the carry in and carry out signals are separately named.

测试台还可以容纳宽度为 N 的 Adder4:

A test bench can also accommodate a width 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;

所有这些都没有考虑进位树延迟时间,进位树延迟时间可能会受到实现或使用快速进位电路(例如进位前瞻)的影响.

All this without regard to carry tree delay time which can be affected by implementation or the use of fast carry circuits (e.g. carry look ahead).

这给了我们一个看起来像这样的模拟:

And this gives us a simulation that looks like:

或者近距离观察:

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

When using a generate statement based architecture if you changed the declaration of N you'd have an adder that would synthesis and simulate in variable widths specified by N up until the ripple carry would no longer work for the input data rate (10 ns in the test bench currently).

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

Note the generic map association of he generic N formal with the actual N declared in the test bench means in this case that the N declared in the test bench sets the width N in Adder4 as well.

这篇关于vhdl 中的 4 位加法器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆