1

Verilog を使用して、Lattice CPLD から VGA コントローラーを構築しています。私は過去にかなりの量の Verilog に触れていましたが、しばらく経ち、モニターを制御するために必要な同期ラインが駆動されていない点に錆びていて (O.Scope で確認)、なぜだかわかりません。

Active-HDL でコードをシミュレートしようとしましたが、奇妙なエラー メッセージ (非ブロッキング トランザクションにメモリを割り当てられませんでした) が表示され、カウンターに負荷がないという警告が表示されます (この場合は無視できると思いますか? ) コードは以下のとおりです。

module CtrlLines(NRST, CLK, H_SYNC, V_SYNC);
    input  wire CLK;        /*< CLK input from Top module   >*/
    input  wire NRST;       /*< Reset input from Top module >*/
    output reg  H_SYNC;
    output reg  V_SYNC;

    reg [10:0] h_counter;   /*< Tracks amount of pulses from CLK    >*/
    reg [10:0] v_counter;   /*< Tracks amount of pulses from H_SYNC >*/

    `define H_FRONT_PORCH   10'd95
    `define H_BACK_PORCH    10'd720
    `define H_COUNT_MAX     10'd800

    `define V_FRONT_PORCH   10'd2
    `define V_BACK_PORCH    10'd514
    `define V_COUNT_MAX     10'd528

    always @(negedge NRST, posedge CLK) begin
        if (!NRST) begin
            h_counter <= 10'b00;
        end
        else begin
            h_counter <= h_counter + 1'b1;
            case (h_counter)
                `H_FRONT_PORCH: H_SYNC <= 1;    /*< If the counter has reached Front Porch, go High >*/
                `H_BACK_PORCH : H_SYNC <= 0;    /*< If the counter has reached Back Porch, go Low   >*/
                `H_COUNT_MAX  : h_counter <= 0; /*< If the counter has reached Max, Reset   >*/
            endcase                             /*< Else, remain at current level           >*/
        end
    end

    always @(negedge NRST, negedge H_SYNC) begin
        if (!NRST) begin
            v_counter <= 10'b00;
        end
        else begin
            v_counter <= v_counter +1'b1;
            case (v_counter)
                `V_FRONT_PORCH  : V_SYNC <= 1;
                `V_BACK_PORCH   : V_SYNC <= 0;
                `V_COUNT_MAX    : v_counter <= 0;
            endcase
        end
    end
endmodule
4

3 に答える 3

2

reg同じ( )に対して複数のノンブロッキング割り当てがあるため、このコードには問題がありますh_counter。どちらが最初に実行されるかは非決定論的であり、シミュレーションの競合状態につながります。

    h_counter <= h_counter + 1'b1;
    case (h_counter)
        `H_FRONT_PORCH: H_SYNC <= 1;    /*< If the counter has reached Front Porch, go High >*/
        `H_BACK_PORCH : H_SYNC <= 0;    /*< If the counter has reached Back Porch, go Low   >*/
        `H_COUNT_MAX  : h_counter <= 0; /*< If the counter has reached Max, Reset   >*/

私の推測では、合成ツールにもこれに問題があると思います。

おそらく、ステートメントのdefault句でインクリメントが発生することを意図していたのでしょう。case

についても同様v_counterです。

于 2013-03-18T12:35:37.717 に答える
1

それが問題を引き起こしているかどうかはわかりませんが、奇妙な線があります:

default         : V_SYNC = V_SYNC;

ここで、それ自体へのブロッキング割り当てを使用してV_SYNCを割り当てます。

この行を削除することをお勧めします。

于 2013-03-17T19:31:56.237 に答える
0

H_SYNC をクロックとして使用しない方法で V_SYNC 部分をコーディングするという Tim の提案を繰り返します。データをクロックとして使用すること (およびその逆) は、ほとんどのツールが適切に処理できないため、一般的に嫌われています。

主な問題として、H_SYNC および V_SYNC 信号がトップ レベルおよび IO に適切にルーティングされていることを確認することをお勧めします。警告に基づいて、syn 中にロジックが最適化されている可能性があると思います。あなたが投稿したものに大きな機能上の問題は見られません。

于 2013-03-18T14:56:41.973 に答える