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

Adder4 でインスタンス化された N 個の Adder1s を意図していた可能性に関する sharth の素晴らしい回答に敬意を表して:

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) を好みます。carry_in には 2 番目の std_logic_vector が必要ですが、生成構造が大幅に簡素化されます。両者には階層の違いがあり、最初の方が読みやすいです。


最初のアーキテクチャ (imp) は、Adder1 を手動で 4 回インスタンス化する方法も示しています。生成構造を削除し、すべての (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

最下位の「0」のキャリ_インで上向きに調整されたキャリ_sig を使用する追加のキャリ_イン ベクトルにより、書き込みが簡単になります。また、キャリー イン信号とキャリー アウト信号に別々の名前を付けると、キャリー ルック アヘッド メソッドを実装した方が読みやすくなります。


テスト ベンチは幅 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 とジェネリック N フォーマルのジェネリック マップの関連付けは、この場合、テストベンチで宣言された N が Adder4 の幅 N も設定することを意味することに注意してください。

于 2013-09-14T03:20:21.243 に答える