0

アルテラ Cyclone II FPGAボードにVerilogプログラムするコードを書いています。キー スイッチを押すとアクティブになるブロックがあります。always

reg START;

...
...

always @ (negedge key[3]) begin
    if (START != 1) START = 1;
end

私は有限状態マシンのプログラムを書いています。このキーの押下は、ユーザーがプログラムの使用を開始したいことを示し、初期状態から次の状態に移行する必要があることを示しているはずです。レジスタの初期化は合成できないため、START0 から始まるとは想定できません。

問題は、ボードをプログラムして電源alwaysを入れると、 に割り当てられたキーを押す前に、このブロックが既に 1 回実行されていることkey[3]です。STARTプログラムの実行時に の値を確認しましたが、既に1です。キーが押されたときにのみキーが負のエッジにあるため、なぜこれが起こるのかわかりません。START以前の状況で常に同じ条件のブロックを使用しましたが、正常に機能したため、これは?の初期化と関係があると思います。

4

2 に答える 2

1

シグナルのスタートアップ値を設定するには、「初期」ブロックを使用する必要があります。START と key[3] の値を設定する必要があります。

initial begin
  START = 1'b0;
  key[3] = 1'b1;
end

あなたが言った

レジスタの初期化は合成できないため、START が 0 から始まるとは想定できません。

しかし、これは正しくありません。上記の方法で、デザイン内の任意の信号にデフォルト値を設定できます。この値は、ファームウェアのビットストリームに含まれており、信号はまさにこの値で開始されます。

乾杯

于 2014-11-13T09:32:35.363 に答える
1

initialの合成可能性は、コーディング対象のターゲットに依存する ことに注意してください。
たとえば、シミュレーター用にコーディングすると、initialうまく機能します。ターゲットがFPGAの場合、ツール(あなたの場合はQuartus)は回路図とその内部のすべてのトリガーの初期状態を完全に制御できます。実際、ファームウェアをFPGAにアップロードすると、すべてのトリガーが既知の状態に設定され、Quartusはsを解析initialして各トリガーの状態を取得します。逆に、ターゲットがベアシリコンの場合、すべてのトリガーは単なるトランジスタの集まりであり、電源投入時の状態は完全に不定であるため、電源投入時の状態を制御する唯一の方法は、次のようなある種のリセットを適用することですこれ:

always @(posedge clk, negedge rst_n)
if( !rst_n )
    START <= 1'b0; // no start condition upon reset
else if( some_condition )
    START <= 1'b1;

コードのもう 1 つのポイントは、次のように、スイッチからの入力を解析するときに、最初にデザインのクロックに再同期する必要があることです。

reg start_r, start_rr;
always @(posedge clk)
begin
    start_r  <= START;
    start_rr <= start_r;
end
// now use start_rr instead of START

再同期は、同期設計で準安定状態を回避するための重要な要素です。

2 番目のポイントは、設計がスイッチの複数回のトリップに耐えられない限り、メカニック スイッチからの入力のデバウンスを検討する必要があるということです。

Ryan McClure が求める元の問題に戻ります。STARTのない元のコードでinitialは、起動時に定義されておらず、'1' 状態にしかトリップできないことがわかります。したがって、シンセサイザーは、START が定数であり、常に「1」であると想定しています。

于 2014-11-14T15:40:08.637 に答える