2

休眠構文を多用するVHDLコードがあります。

     signal_1   <= (others => '0')     when cau_state = st_idle       else
                  signal_2 - signal_3  when cau_state = st_cycle_1    else
                  signal_4             when cau_state = st_cycle_2    else
                  signal_5             when cau_state = st_cycle_3    else
                  signal_6             when cau_state = st_cycle_4    else
                  signal_1;

cau_state現在の状態を保持する信号はどこにありますか。この構文はModel-Simのシミュレーションで機能し、すべてが正常に機能しました。しかし、コードをFPGAに書き込みたいと思ったとき、コードはアルテラQuartusII32ビットバージョンで合成されませんでした。12.1そして私は休眠エラーメッセージを受け取りました:

Warning (13012): Latch CAU:uut|cross_3_sig[0][31] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal CAU:uut|cau_state.st_cycle_2
Warning (13012): Latch CAU:uut|cross_3_sig[0][30] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal CAU:uut|cau_state.st_cycle_2

多くのシグナルに対してこれらのメッセージが表示されますが、この構文を使用しているすべてのシグナルに対しては表示されません。そして、このメッセージを受け取るシグナルの場合、私はそのすべてのビットについてそれを受け取りcross_3_sig[0][31]ますcross_3_sig[0][0]。シグナルの構文cross_3_sig(0)は次のとおりです。

constant WIDTH          : integer := 32;
...
subtype scalar          is std_logic_vector((WIDTH-1) downto 0);                                  
type    vector_nd       is array (natural range <>) of scalar;
subtype vector_3d       is vector_nd(2 downto 0);
...
signal cross_3_sig          : vector_3d;
...
cross_3_sig(0)      <= sum_mults_out_sig              when cau_state = st_cycle_2  else              
                       mult1_out_sig - mult2_out_sig  when cau_state = st_cycle_9  else                          
                       cross_3_sig(0); 

cross_3_sig(0)そして、私が他の信号に割り当てる場所がいくつかあります。

numer_sig           <= C_ZERO - cross_3_sig(0) & (16 downto 0 => '0'); 
mult1_in2_sig       <= (others => '0') when cau_state = st_idle       else
                       ...
                       cross_3_sig(0)  when cau_state = st_cycle_11   else
                       ...

問題は何ですか、どうすれば修正できますか?

4

1 に答える 1

3

問題は、この形式の式がラッチ(制御信号のグリッチに敏感)を作成し、さらにそれが複数の制御信号を備えたラッチであり、実際のハードウェアに直接相当するものがないことです。

 signal_1   <= (others => '0')     when cau_state = st_idle       else
              ...
              signal_6             when cau_state = st_cycle_4    else
              signal_1;

(クロックプロセスの外で)次のようなものを見るときはいつでも

signal_1   <= ... else signal_1;

あなたはあなたが問題を抱えていることを知っています。これは、それ自体を直接供給する信号であり、単純なワイヤをメモリとして使用する試みです。

このパターンの正しい使用法は、メモリとしてではなく、マルチプレクサとしてです。

output_1 <= input_1 when ... else
            input_2 when ... else
            input_n;

signal1の古い値を記憶する正しい方法は、クロックプロセスです。

process (clk)
begin
    if rising_edge(clk) then
        if    cau_state = st_idle    then signal_1   <= (others => '0') 
        ...
        elsif cau_state = st_cycle_4 then signal_1  <= signal_6;
        end if;
    end if;
end process;

割り当てがない場合、signal_1は現在の値を維持します。

または、より良い代替方法:プロセスでcaseステートメントを使用します。

process (clk)
begin
    if rising_edge(clk) then
        case cau_state is
           when st_idle    => signal_1   <= (others => '0') 
           ...
           when st_cycle_4 => signal_1  <= signal_6;
           -- when others => some default action
        end case;
    end if;
end process;

これにより、セマンティクスがクロック付きデザインに変更されますが、クロックなしデザインは控えめに言ってもFPGAでは面倒です。

于 2013-03-19T13:45:27.830 に答える