2017-12-20 8 views
2

私はかなり一般的なVHDLコードを書こうとしていますが、私は十分に標準を十分に理解していない状況である に入っています。 (私はVHDL-2008を使用して です。)VHDL:エンティティポートへの入力として関数によって返された制約のない配列を処理する方法は?

私は拘束されない STD_LOGIC_VECTOR(S)上で動作し、制約のない STD_LOGIC_VECTORを返す関数を書かれています。しかし、 (constrained)std_logic_vectorsを2つ渡すと、この 関数を自分のエンティティのポートへの入力として使用できないように思えます( my exampleプログラムのtest_2のインスタンス化を参照してください)。しかし、何らかの理由で私が ビット文字列リテラルを渡すとうまくいくように思えます(test_1のインスタンス化を参照)。

は、test_1のインスタンス化で非常によく似た構文を使用することが許可されている間に、私はconcatenate() 関数をtest_2のインスタンス化の入力として使用できない理由を説明できますか?

あなたの関数呼び出しは、変換機能ではなく、また、暗黙的な信号宣言を惜しまするための要件を満たしていないvcom -2008 unconstrained_example.vhd

-- test entity/architecture 
library ieee; 
use ieee.std_logic_1164.all; 

entity test is 
    port (value : in std_logic_vector); 
end entity; 

architecture a of test is 
begin 
    -- Intentionally empty 
end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 

-- Test instantiation 
entity testit is 
end entity; 
architecture a of testit is 
    signal my_constrained_slv1 : std_logic_vector(5 downto 0); 
    signal my_constrained_slv2 : std_logic_vector(9 downto 0); 
    function concatenate(value1 : std_logic_vector; value2 : std_logic_vector) return std_logic_vector is 
    begin 
    return value1 & value2; 
    end function; 
begin 
    process begin 
    -- Using the function in this context seems to work ok 
    report "Value is " & to_string(concatenate(my_constrained_slv1, my_constrained_slv2)); 
    wait; 
    end process; 

    -- This instantiation seems to work 
    test_1: entity work.test 
    port map (
     value => concatenate("000000", "1111111111")); 

    -- For this entity instantiation I'm getting an error from ModelSim: 
    -- ** Error: unconstrained_example.vhd(43): (vcom-1383) Implicit signal in port map for port "value" is not fully constrained. 
    test_2: entity work.test 
    port map (
     value => concatenate(my_constrained_slv1, my_constrained_slv2)); 
end architecture; 

答えて

2

でそれをコンパイルのModelSim Iでコードをしようとします。

VHDL-2008では、ポート結合でこのような複雑な式を使用できます。

ブロックの正式な信号ポートの特定の関連要素の実際の部分が、慣性語の後に式が続く予約語である場合、またはそのような場合、暗黙の信号が作成されます。指定された関連要素 は、ブロックを直ちに囲む宣言領域で暗黙的に宣言された匿名信号とポートの関連付けに相当します。信号は、正式な信号ポートと同じサブタイプを有し、フォームの暗黙の同時信号代入文のターゲットである:Eは、所与の関連要素の実際の一部における発現である

anonymous <= E; 

。並行信号割当てステートメントは、ブロックと同じステートメント部分で発生します。

出典:IEEE-1076から2017年ドラフト5aの

signal temp : std_logic_vector; -- derived from the formal in the port association list 

temp <= concatenate(my_constrained_slv1, my_constrained_slv2); 
test_2: entity work.test 
    port map (
    value => temp 
); 
end block; 

問題は、VHDL、ポート関連リストに正式からの暗黙の信号tempのための型を推論する必要があること、である(value : std_logic_vector )。それはstd_logic_vectorであることがわかりますが、拘束されていないポートのために制約は知られていません。

エンティティtestでポートvalueが制約されているのであれば、それは動作するはずです:

entity test is 
    port (
    value : in std_logic_vector(15 downto 0) 
); 
end entity; 
+0

あなたは、私がサブタイプを定義した場合、それが動作することを右ですが、その解決策がすぐに全体以来、非常に有用ではありません私が書こうとしている関数の考え方は、最初にビット幅を指定する必要がないようにすることです。 (もっとも私を混乱させるのは、既知の幅のビットストリングリテラルが許されていますが、既知の幅のstd_logic_vectorsはこの関数への入力として許可されていません)。 – tamyrlin

+0

ローカルおよびグローバル静的規則に関連する必要があります。 'test_1'の式は' test_2'の式とは別のものです。最初のものはローカルで静的なオペランドを持ち、局所的に定義された*純粋な関数なので、局所的な静的性を保持する必要があります。私は 'test_1'では、中間の暗黙のシグナルは含まれていないと思います。私は一致するLRMの段落を検索していません... – Paebbels

2

私はかなり醜いです次の回避策を思い付いたが、 は私が手動で指定する必要はありません、私の主な基準を満たし 任意の幅または任意の情報を繰り返します。関数内で連結するための呼び出しを隠すことによって、 関数を再利用してさらに範囲を取得することができます。短い実験は、Vivado 2015.4もこの構造を受け入れることを示しています。

test_2_helper : block 
    impure function test_2_help_func return std_logic_vector is 
    begin 
    -- This is the only place I have to change in case the assignment has to 
    -- change in some way. (E.g. use other variables or become more complicated, etc.) 
    return concatenate(my_constrained_slv1, my_constrained_slv2); 
    end function; 
    signal test_2_helper_sig : std_logic_vector(test_2_help_func'range); 
begin 
    test_2: entity work.test 
    port map (
     -- It seems to be syntactically legal to use test_2_help_func(test_2_help_func'range) 
     -- here. Unfortunately this does not work in simulation. Probably because the 
     -- test_2_help_func does not have any explicit arguments and this may cause issues 
     -- with the event driven simulation. As a work around the test_2_helper_sig signal 
     -- is assigned every clock cycle below instead. 
     value => test_2_helper_sig); 

    process 
    begin 
    -- Note: If you remove the wait for the clock edge and instead use process(all) 
    -- test_2_helper_sig does not seem to change during simulation, at least in 
    -- Modelsim 10.6 where I tested this. 
    wait until rising_edge(clk); 
    test_2_helper_sig <= test_2_help_func; 
    end process; 
end block; 

注:これは、次の答えに触発さ:VHDL - Why does using the length attribute directly on a function produce a warning?

+0

私は持っています。以前はこのようなVHDL構成を想像したことはありません...そしてこれはVivadoによってサポートされていますか?どのバージョン? – Paebbels

+0

'' range'と修飾された式を使ってコードを組み合わせることはできますか? 'value => std_logic_vector(連結(my_constrained_slv1、my_constrained_slv2) '範囲)'(連結(my_constrained_slv1、my_constrained_slv2))'?修飾された式は、 'type '(comとplex xor expresもsion)'のようになります。 'type'は、期待される型の式のヒントをVHDLに与えるために使われます。私の提案されたサンプルコードでは、 '' range'のアイデアを使って、そのような式のinfrontの制約付き型を作成します。 – Paebbels

関連する問題