FC2カウンター FPGAの部屋 ビットマップ・ディスプレイ・コントローラのReport CDC unsafe 箇所を確認し、修正する

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

ビットマップ・ディスプレイ・コントローラのReport CDC unsafe 箇所を確認し、修正する

Vivado のImplemented Design で Report CDC を確認する”で確認されたビットマップ・ディスプレイ・コントローラのReport CDC unsafe 箇所を確認して修正してみよう。

From は ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/cs_rdg_reg[0]/C
To は ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/hv_cnt_ena_d1_reg/D
だった。

bitmap_disp_eng.v でのFrom 部分を下に示す。

    // Readデータ処理モジュール用ステートマシン
    always @(posedge clk_axi) begin
        if (reset_axi)
            cs_rdg <= idle_rdg;
        else begin
            case (cs_rdg)
                idle_rdg :
                    if (ddr_cont_init_done)
                        cs_rdg <= init_full_mode;
                init_full_mode : // 最初にcam_data_afifo をFULLにするステート、このステートではVGA信号は出力しないで、ひたすらcam_data_afifo がFULLになるのを待つ。
                    if (read_count==0)
                        cs_rdg <= wait_half_full;
                wait_half_full : // cam_data_afifo がHALF_FULLになるまでこのステートで待機
                    if (vsync_axi)
                        cs_rdg <= frame_wait_state;
                    else if (wr_data_count<=AFIFO_HALF_FULL_VAL)
                        cs_rdg <= req_burst;
                req_burst :
                    if (vsync_axi)
                        cs_rdg <= frame_wait_state;
                    else if (read_count==0) // データが全部来たら
                        cs_rdg <= wait_half_full;
                frame_wait_state : // 1フレーム終了後vsync の時にWaitする
                    if (vsyncx_rise_pulse) // vsyncx の立ち上がり
                        cs_rdg <= frame_start_full;
                frame_start_full : // 1フレームのスタートの時にFIFOをフルにする
                    if (read_count==0)
                        cs_rdg <= wait_half_full;
            endcase
        end
    end
    assign hv_count_enable = (cs_rdg==wait_half_full || cs_rdg==req_burst || cs_rdg==frame_wait_state || cs_rdg==frame_start_full) ? 1'b1 : 1'b0;


リセット後ビットマップ・ディスプレイ・コントローラがスタートする時に、画像データ用FIFO を画像データで満たしてから水平カウンタ、垂直カウンタを始動しようと思っていて、そのためのイネーブル信号 (hv_count_enable) を生成している。 hv_count_enable は組み合わせ回路で作っている。 hv_count_enable はリセット後画像データ用FIFO が満たされるまでは 0 で、フルになった時に 1 になって、その後はずーと 1 だ。

この、hv_count_enable はピクセルクロックで動作する水平カウンタ、垂直カウンタにイネーブル信号として入力するために FF 2個を使用したシンクロナイザーを通してある。その後、水平カウンタ、垂直カウンタにイネーブル信号として入ってる。

    // h_count、v_count用にclk_axi 動作のcs_rdg の値を使用するので2回clk_disp 動作のFFでラッチする
    always @(posedge clk_disp) begin
        if (reset_disp) begin
            hv_cnt_ena_d1 <= 1'b0;
            hv_cnt_ena_d2 <= 1'b0;
        end else begin
            hv_cnt_ena_d1 <= hv_count_enable;
            hv_cnt_ena_d2 <= hv_cnt_ena_d1;
        end
    end

    // h_countの実装(水平カウンタ)
    always @(posedge clk_disp) begin
        if (reset_disp)
            h_count <= 0;
        else if (h_count>=(H_SUM-1)) // h_count がH_SUM-1よりも大きければ0に戻す(mod H_SUM)
            h_count <= 0;
        else if (hv_cnt_ena_d2) // 最初に非同期FIFOをフルにするまではカウントしない
            h_count <= h_count + 1;
    end

    // v_countの実装(垂直カウンタ)
    always @(posedge clk_disp) begin
        if (reset_disp)
            v_count <= 0;
        else if (h_count>=(H_SUM-1)) begin // 水平カウンタがクリアされるとき
            if (v_count>=(V_SUM-1)) // v_count がV_SUM-1よりも大きければ0に戻す(mode V_SUM)
                v_count <= 0;
            else if (hv_cnt_ena_d2) // 最初に非同期FIFOをフルにするまではカウントしない
                v_count <= v_count + 1;
        end
    end


よって、この信号が unsafe だとしても問題は無いと思うのだが、修正を試みてみよう。

Verilog HDL コードをこのまま修正することは容易だが、Vivado の修正を認知させるために、IP Integrator のブロックデザインの ZYBO_1_XGA_test を開いて、bitmap_disp_cntrler_axi_master_0 を IP Packager を起動して修正する。
ZYBO_1_XGA_test_48_151220.png

組み合わせ回路の出力を hv_count_ena_comb に変更して、それをFF に通して hv_count_enable 信号として出力した。

    assign hv_count_ena_comb = (cs_rdg==wait_half_full || cs_rdg==req_burst || cs_rdg==frame_wait_state || cs_rdg==frame_start_full) ? 1'b1 : 1'b0;
    always @(posedge clk_axi) begin
        if (reset_axi) begin
            hv_count_enable <= 1'b0;
        end else begin
            hv_count_enable <= hv_count_ena_comb;
        end
    end


これで、再度パッケージ化を行った。
ZYBO_1_XGA_test_49_151220.png

また、ZYBO_1_XGA_test プロジェクトに戻って、論理合成、インプリメント、ビットストリームの生成を行った。タイミングも満足して成功した。
Implemented Design を開いて、Tools -> Timing -> Report DRC... を実行した。
ZYBO_1_XGA_test_50_151220.png

Unsafe が消えて、問題が無くなった。
修正を行ったが、たぶん、動作は前と変わっていないと思う。
  1. 2015年12月20日 05:02 |
  2. IP
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3339-0ed9d581
この記事にトラックバックする(FC2ブログユーザー)