一見すると、以下のVHDLソースコードがシフトレジスタとして動作することが予想されます。そのqでは、時間が経つと
"UUUU0", "UUU00", "UU000", "U0000", "00000", ....
ただし、常にU
5(以上)の連続したクロックサイクルの後です。
どうしてこれなの?
このコードは、実際にははるかに複雑なシミュレーションを大幅に簡略化したものです。しかし、それは私が見る症状を示しています。
ModelSimとActiveHDLの両方でのシミュレーション中に、この興味深い予想外の結果が示されます。他のシミュレーターを試したことがなく、(原因の説明として)他のシミュレーターが同じように動作するかどうかを知りたいと思っています。
この質問に適切に回答するには、次のことを理解する必要があります。
- これはシフトレジスタを実装する最良の方法ではないことを知っています
- RTL合成の場合、これにはリセットが必要です。
- std_logicの配列はstd_logic_vectorです。
- 集計演算子を知ってい
&
ます。
私が見つけたもの:
- 割り当て
temp(0)<='0';
がプロセス内で移動された場合、機能します。 - ループがラップされていない場合(コメント付きのコードを参照)、ループは機能します。
これは、予想外のシミュレーション結果を純粋に表示するように構成された(パイプラインCPUの)より複雑な設計の非常に簡略化されたバージョンであることを繰り返します。実際の信号タイプは単なる簡略化です。このため、フォームのコードをそのまま使用して回答を検討する必要があります。
私の推測では、VHDLシミュレーションエンジンのオプティマイザーは誤って(または仕様に従って)ループ内の信号を変更しないため、ループ内で式を実行する必要がありませんが、ループにラップされていないループを配置することでこれを反証することができます。
したがって、この質問への答えは、コード例が何かを行う最善の方法であるかどうかではなく、VHDLシミュレーションの標準ではないVHDL構文の標準と、VHDLシミュレーションエンジンが最適化をどのように行うかであると思います。
そして今私がシミュレートしているコードに:
library ieee;
use ieee.std_logic_1164.all;
entity test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end entity;
architecture example of test_simple is
type t_temp is array(4 downto 0) of std_logic;
signal temp : t_temp;
begin
temp(0) <= '0';
p : process (clk)
begin
if rising_edge(clk) then
for i in 1 to 4 loop
temp(i) <= temp(i - 1);
end loop;
--temp(1) <= temp(0);
--temp(2) <= temp(1);
--temp(3) <= temp(2);
--temp(4) <= temp(3);
end if;
end process p;
q <= temp(4);
end architecture;
そしてテストベンチ:
library ieee;
use ieee.std_logic_1164.all;
entity Bench is
end entity;
architecture tb of bench is
component test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end component;
signal clk:std_logic:='0';
signal q:std_logic;
signal rst:std_logic;
constant freq:real:=100.0e3;
begin
clk<=not clk after 0.5 sec / freq;
TB:process
begin
rst<='1';
wait for 10 us;
rst<='0';
wait for 100 us;
wait;
end process;
--Note: rst is not connected
UUT:test_simple port map (clk=>clk,q=>q) ;
end architecture;
temp(0)
リテラル定数に関連付けられた「イベント」がないため、シミュレータはへの同時割り当てを無視しているように見えます。内部に割り当てを置くと、process
それを機能させるクロックイベントとの関連付けが作成されます。after
割り当てに句を追加することは、潜在的な回避策になるだろうかと思います。