FC2カウンター FPGAの部屋 Vivado HLS 2014.4 でディスプレイ・コントローラを作る2(RTLシミュレーション)

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

FPGAの部屋

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

Vivado HLS 2014.4 でディスプレイ・コントローラを作る2(RTLシミュレーション)

Vivado HLS 2014.4 でディスプレイ・コントローラを作る1(高位合成、C/RTLコシミュレーション)”の続き。

前回は、ディスプレイ・コントローラをC++ で書いて高位合成し、きちんとハードウェアになることを検証した。
今回、return ポードの HLS INTERFACE を ap_ctrl_none にした状態で、つまり、ap_start, ap_done, ap_idle, ap_ready を取り払った状態で display_cont_sub() の高位合成された Verilog HDL ソースコードが自動的にループして画像の信号を出し続けるのか?に興味がある。そこで、Verilog HDLファイルをテストベンチを作製して、RTLシミュレーションすることで解明する。

まずは、display_cont_sub() の return ポードの HLS INTERFACE を ap_ctrl_none にして高位合成を行った。

//#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE ap_ctrl_none port=return


レポートを貼っておく。リソースが増えているのはなぜだろう?
HLS_Disp_Cont_7_150606.png
HLS_Disp_Cont_8_150606.png

新しいVivado のプロジェクトを作製し、C:\Users\Masaaki\Documents\Vivado_HLS\ZYBO\display_cont\solution1\syn\verilog フォルダの display_cont_sub.v をAdd し、テストベンチを書いてシミュレーションを行う。

まずは、Vivado 2015.1で display_cont_sim プロジェクトを作製した。

display_cont_sub.v を Add Source した。

テストベンチ display_cont_tb.v を作製した。

現在のプロジェクトの状態を示す。
HLS_Disp_Cont_9_150606.png

これで、Behavioral Simulation の準備が整った。

Flow Navigator から Simulation -> Run Simulation をクリックし、 Run Behavioral Simulation を選択した。

下に 34 ms までシミュレーションした時のシミュレーション波形を示す。
HLS_Disp_Cont_10_150606.png

大体、VGAの波形が出ている。1回目の画像フレームが終了した後もスムーズに2回目の画像フレームを出力している。

問題は、C++ ソースコードで、 for() の2重ループが終了して、初期化処理をして、また for() の2重ループに入るまでに時間が気になるので、検証した。
下にその部分のシミュレーション波形を示す。
HLS_Disp_Cont_11_150606.png

水平同期信号の周期は、通常は 26.4 us なのだが、ここでは、26.475 us となっている。つまり3クロック余計にかかっている。

通常の部分の水平同期信号の周期を見ると、26.4 us だった。
HLS_Disp_Cont_12_150606.png


次に、Vivado HLS 2014.4 で高位合成のTop Function を display_cont に変更して、高位合成を行った。
高位合成結果を下に示す。
HLS_Disp_Cont_13_150606.png
HLS_Disp_Cont_14_150606.png

C:\Users\Masaaki\Documents\Vivado_HLS\ZYBO\display_cont\solution1\syn\verilog フォルダの display_cont.v をVivado 2015.1のプロジェクトにコピーして、プロジェクトにAdd した。

テストベンチのインスタンス・モジュールを display_cont に書き換えた。
HLS_Disp_Cont_15_150606.png

Flow Navigator から Simulation -> Run Simulation をクリックし、 Run Behavioral Simulation を選択した。

下に 34 ms までシミュレーションした時のシミュレーション波形を示す。
HLS_Disp_Cont_16_150606.png

C++ ソースコードで、 for() の2重ループが終了して、while(1){ } に戻って、また for() の2重ループに入る所の水平同期信号の周期を測定したところ、26.45 us で2クロックだけ余計にかかっている。
HLS_Disp_Cont_17_150606.png

display_cont_sub.v との差は1 クロックとなった。

最後にテストベンチの display_cont_tb.v を貼っておく。

`default_nettype none
`timescale 100ps / 1ps

// display_cont_tb.v
// by marsee
// 2015/06/05
//

module display_cont_tb;

    wire    ap_clk;
    wire    ap_rst;
    wire    [7:0]   red_V;
    wire    [7:0]   green_V;
    wire    [7:0]   blue_V;
    wire    display_enable_V;
    wire    hsyncx_V;
    wire    vsyncx_V;

    //display_cont_sub uut (
    display_cont uut (
        .ap_clk(ap_clk),
        .ap_rst(ap_rst),
        .red_V(red_V),
        .green_V(green_V),
        .blue_V(blue_V),
        .display_enable_V(display_enable_V),
        .hsyncx_V(hsyncx_V),
        .vsyncx_V(vsyncx_V)
    );

    // clk_gen のインスタンス(ap_clk)
    clk_gen #(
        .CLK_PERIOD(250),    // 25 nsec, 40 MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) ACLKi (
        .clk_out(ap_clk)
    );

    // reset_gen のインスタンス
    reset_gen #(
        .RESET_STATE(1'b1),
        .RESET_TIME(1000)    // 100nsec
    ) RESETi (
        .reset_out(ap_rst),
        .init_done()
    );
endmodule

module clk_gen #(
    parameter         CLK_PERIOD = 100,
    parameter real    CLK_DUTY_CYCLE = 0.5,
    parameter        CLK_OFFSET = 0,
    parameter        START_STATE    = 1'b0 )
(
    output    reg        clk_out
);
    begin
        initial begin
            #CLK_OFFSET;
            forever
            begin
                clk_out = START_STATE;
                #(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
                #(CLK_PERIOD*CLK_DUTY_CYCLE);
            end
        end
    end
endmodule

module reset_gen #(
    parameter    RESET_STATE = 1'b1,
    parameter    RESET_TIME = 100 )
(
    output    reg        reset_out,
    output    reg        init_done
);
    begin
        initial begin
            reset_out = RESET_STATE;
            init_done = 1'b0;
            #RESET_TIME;
            reset_out = ~RESET_STATE;
            init_done = 1'b1;
        end
    end
endmodule

`default_nettype wire

  1. 2015年06月06日 05:32 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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