0

私は柔軟な MUX を書いています。これには、選択行の数だけでなく、システムへの入力と出力の数も決定するジェネリックがあります。たとえば、サイズ = 3 の場合。システムには、8 つの入力、64 の出力、および 3 つの選択ラインがあります。これにより、2^size の MUX が作成され、選択ビットが変更されるたびにそれらを設定する必要があります (それらはグローバルです)。

これまでのところ、私はこれを持っています:

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;

entity mux is
    generic ( size : positive := 3 ) ;
    port    ( din  : in  std_logic_vector (((2**size)-1) downto 0) ;
              sel  : in  std_logic_vector (size-1 downto 0) ;
              y    : out std_logic_vector (((2**(size*2))-1) downto 0) ) ;
end mux ;

architecture arc_mux of mux is
begin

    process(sel)
    begin

    end process ;

end arc_mux ;

私がやりたいのは、ループ内の入力 ( 0 から ((2**size)-1) ) を調べて、正しい出力をその場所に格納されている値に調整することです。問題は、これに sel の値を i * 2**size へのオフセットとして使用する必要があることですが、この演習で使用できるライブラリでは、+ 演算子を使用してその値を i に追加することはできません。 * 2** サイズ。助言がありますか?

4

1 に答える 1

0

for ループで発生する可能性のあるエラーは、普遍的な整数の境界が数値リテラルまたは属性でなければならないということを伝えているはずです。2008 年版の VHDL で緩和されたルール。

ポート定義を使用して、合成に適した記述を生成することはそれほど難しくありません。din'reverse_range を使用するか、ループに必要な範囲で配列サブタイプを作成するか、暗黙のループ変数の型を整数として指定できます。

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

entity demux is
    generic ( size: positive := 3);
    port ( 
        din:    in  std_logic_vector (2**size-1 downto 0);
        sel:    in  std_logic_vector (size-1 downto 0);
        y:      out std_logic_vector (2**(size*2)-1 downto 0) 
    );
end entity;

architecture foo of demux is

begin

PROC:
    process(sel, din)
        -- subtype sel_range is std_logic_vector (0 to 2**size-1);
    begin

    SLCT:
        -- for i in sel_range'range loop
        for i in integer range 0 to 2**size-1 loop
            if i = to_integer(unsigned(sel)) then
                y(i*din'length+din'length-1 downto i*din'length) <= din;
            else
                y(i*din'length+din'length-1 downto i*din'length) <= (others => '0');
            end if;
        end loop;
    end process ;

end architecture;

このコードは、VHDL-93 ライブラリの numeric_std と unsigned への型変換を使用して と比較iselます。シノプシス ライブラリを簡単に使用できます。ループを使用し、yインデックス範囲に値を割り当てると、合成が可能になります。

for ループの反復は、ハードウェアで (並列に) 複製されます。の割り当てられたスライスは、静的であるおよびにy依存しています。idin'length

この例では、分析、詳細化、およびシミュレーションを行います。

demux_tb シミュレーション

'y' 値をラッチし、 にy基づいてスライスを順次更新するつもりだった場合sel、単純dinにプロセス機密リストを除外するだけでは十分ではありません。これは合成に適した構造ではなく、 の任意のイベントで動作しますseldinプロセス機密リストに追加したことに注意してください。アドレス可能なラッチまたはレジスタを使用する場合は、ゲートを介してイネーブルを生成する必要がある場合、要素の立ち上がり時間と立ち下がり時間selが必ずしも等しくないため、クロックまたは個別のラッチ イネーブルが必要です。実際のハードウェア実装でグリッチが発生する可能性があります。(あなたの言語「...その場所に保存されている値に正しい出力を調整する」は不明です)。

ポート宣言は、演算子の優先順位に基づいて実際に必要な数よりも多くの括弧の良い例です。

また、長さが不必要にビットdin数に結び付けられていることに気付くかもしれません。これが機能する理由です。はい、長さと長さの間に関係がある必要があり、長さは に関連しています。 そうでなければそうなるでしょう。これは、 のサイズの 2 番目のジェネリックを意味します。また、for ループ ステートメントの代入スライス境界の計算も変更されます。seldin'reverse_lengthdinyysizey'LEFT2**size*din'LENGTH-1diny

于 2014-04-27T03:42:48.053 に答える