1

私は現在、「綱引き」のゲームを構築するために Verilog コードを書いています。以下のモジュールは、競技場を表す 15 個の LED の中央の LED を表しています。中央のライトは、ゲームが始まるまで点灯している必要があります。たとえば、何らかの入力を受け取ったときです (入力は L と R で与えられます。L は左への 1 つの動き、R は右への 1 つの動きです)。

しかし、私は奇妙なバグに遭遇しました。構築時に値 1をenabled指定し、L と R は構築時に 0 (またはそうあるべき) ですが、コードを実行するとenabledすぐに 0 になります。

私の質問は、なぜこれが起こるのですか?また、入力が表示されるまで変数の値を 1 に維持するにはどうすればよいでしょうか?

module centerLight(Clock, reset, L, R, NL, NR, lightOn);
    input Clock, reset, L, R, NL, NR;
    output reg lightOn;

    reg gameStart = 0;
    reg enabled = 1;

    always@(L or R)
    if (L | R) begin
        gameStart = 1;
        enabled = 0;
    end
    else if (enabled)
        gameStart = 0;
    wire PS;
    reg NS;

    always@(PS or L or R or NL or NR)
    if((NL && R) || (NR && L)) NS = ~PS;
    else               NS = PS;

    always@(PS or gameStart)
    case(PS || !gameStart)
        0: lightOn = 0;
        1: lightOn = 1;
    endcase

    D_FF cl (PS, NS, reset, Clock);

endmodule

module D_FF (q, d, reset, clk);
    input d, reset, clk;
    output reg q;

    always@(posedge clk or posedge reset)
    if (reset)
        q = 0;
    else
        q = d;

endmodule
4

3 に答える 3

1

あなたのデザインenableではラッチがあり、またはのいずれLRが最も短い時間で高い(またはおそらくフローティング)場合、enableスイッチがオンになります。

デザイン全体をシーケンシャルにしてから、リセットを使用してgameStartローであることを確認する方がよい場合があります。

これは私がそれをする方法です:

module centerLight(Clock, reset, L, R, NL, NR, lightOn);
    input Clock, reset, L, R, NL, NR;
    output reg lightOn;

    reg lightOn_d;
    reg gameStart, gameStart_d;
    reg PN, NS;

    always @ (posedge Clock or posedge reset)
        if(reset)
            begin
                gameStart <= 1'b0;
                PS        <= 1'b0;
                lightOn   <= 1'b0;
            end
        else
            begin
                gameStart <= gameStart_d;
                PS        <= NS;
                lightOn   <= lightOn_d;
            end

    always @ *
        begin
            if(L || R)
                gameStart_d = 1'b1;
            else
                gameStart_d = gameStart;

            if((NL && R) || (NR && L))
                NS = ~PS;
            else
                NS = PS;

            if(PS || !gameStart)
                lightOn_d = 1'b1;
            else
                lightOn_d = 1'b0;
        end

endmodule

それがお役に立てば幸いです。

于 2012-05-17T10:59:49.467 に答える
1

コンパイラの切り替えが原因である可能性があります。

初期ブロックは合成できないため、有効のデフォルト設定は事実上初期ブロックです (アルテラの Quartus は電源投入条件を設定するためにそれらを読み取るように指示できますが、公式には Doulos によれば、それらは合成ではサポートされていません)。 FPGAロジックの結果。

ただし、これは RTL として正常にシミュレートされるはずです。しかし、たとえばアルテラのデバイスでは、「Powerup don't care」スイッチがオンに設定されていない限り、起動時にすべてのロジックがゼロとしてパワーアップすることを知っています。この場合、ロジックを調べて、ロジックを最小化する値にレジスタを設定します。 .

この場合、ロジック 0 として有効に設定されます。最小のロジックが生成されるため、必要がなくなります (最初の構造を読み取っていたとしても、技術的に無視する必要がある初期構造を除いて、コードはどこでも enable を 1 に設定しないため)。次に、そのスイッチを使用すると、そうなる可能性があります)。

常に追加し、すべての割り当てをそこに有効にすることで、有効にリセットを追加しようとしました(ラッチとして保持します)

always@(reset) if (reset) enabled <= 1'b1; それ以外の場合 (L | R) 有効 <= 1'b0;

これを行うことで、有効化の機能がロジックに保持されていることがわかりました。

別の注意として、ラッチではなく同期登録アプローチを使用することをお勧めします。

また、最終的に問題が発生するため、Verilog がコード全体で大文字と小文字を区別しないようにすることをお勧めします (古典的なエラーは、モジュールを接続し、ステートメント `default_nettype none が使用されていない場合にコンパイラがワイヤを推論することです (コードを調べます)。 Sunburst テクノロジーの Clifford Cummin やインスピレーションを得た Doulos など)。

これが役立つことを願っています!

于 2012-07-04T10:32:12.303 に答える
0

L|R=1 の場合、コード内の有効値は 0 に割り当てられます。テストベンチの L と R の初期値、または FPGS のこれらのピンの値が最初に 1 の場合、イネーブルは 0 に切り替わります。ぶら下がっている L と R ピンも 1 として評価される場合があります。

Modelsim などのシミュレーターを使用すると、「enabled = 0;」のときに行にブレークポイントを設定できます。

于 2012-05-16T13:38:26.190 に答える