FC2カウンター FPGAの部屋 Vivado HLS 2014.4 の高位合成テスト7(ラプラシアンフィルタ2、シミュレーション)
FC2ブログ

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

FPGAの部屋

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

Vivado HLS 2014.4 の高位合成テスト7(ラプラシアンフィルタ2、シミュレーション)

”Vivado HLS 2014.4 の高位合成テスト6(ラプラシアンフィルタ1)”の続き。

前回、ラプラシアンフィルタをVivado HLS 2014.4 で高位合成して、laplacian_filter.v と laplacian_filter.vhd のファイルを生成した。
今回は、その laplacian_filter.v を使用してシミュレーションを行った。

まずは、Vivado 2014.4 でZYBO 用のプロジェクトを作製して、laplacian_filter.v をプロジェクトに追加した。
次に、laplacian_filter_tb.v という名前のテストベンチを作製した。
Vivado 2014.4 で論理シミュレーションを行った。その結果を下に示す。
Vivado_HLS_Study_37_150113.png

latency = 2, interval = 3 で、Vivado HLSのレポートと同じだった。
Vivado_HLS_Study_34_150112.png

laplacian_filter.c の高位合成レポートのAnalysis の結果の図を2つ示す。
Vivado_HLS_Study_38_150113.png

Vivado_HLS_Study_39_150113.png

段階的に入力データを read して計算していくようだ。2番めのVivado HLSの図のResource タブのExpressions の下の tmp2_fu_113 を見て欲しい。これは、シミュレーション波形 (tmp2_fu_113_p2) では、ap_start = 1 の時に、254 になったので、2つの入力を加算したものだろう?(注:このシミュレーション波形は、parameter LAP_FILTER_END_COUNT = 2; でのシミュレーション波形である)
Vivado_HLS_Study_40_150113.png
laplacian_filter.v を見ると、

assign tmp2_fu_113_p2 = (x2y0 + x0y1);

と記述されていた。

最後に、laplacian_filter_tb.v を貼っておく。

`default_nettype none

`timescale 100ps / 1ps

//
// laplacian_filter_tb.v
// 2015/01/13
//

module laplacian_filter_tb;
    parameter DELAY = 1;
    parameter LAP_FILTER_END_COUNT = 3;

    wire   ap_clk;    // input
    wire   ap_rst;    // input
    reg       ap_start;    // input
    wire   ap_done;
    wire   ap_idle;
    wire   ap_ready;
    reg        [31:0]    x0y0;
    reg        [31:0]    x1y0;
    reg        [31:0]    x2y0;
    reg        [31:0]    x0y1;
    reg        [31:0]    x1y1;
    reg        [31:0]    x2y1;
    reg        [31:0]    x0y2;
    reg        [31:0]    x1y2;
    reg        [31:0]    x2y2;
    wire    [31:0]    ap_return;
    integer            i;

    laplacian_filter uut (
        .ap_clk(ap_clk),
        .ap_rst(ap_rst),
        .ap_start(ap_start),
        .ap_done(ap_done),
        .ap_idle(ap_idle),
        .ap_ready(ap_ready),
        .x0y0(x0y0),
        .x1y0(x1y0),
        .x2y0(x2y0),
        .x0y1(x0y1),
        .x1y1(x1y1),
        .x2y1(x2y1),
        .x0y2(x0y2),
        .x1y2(x1y2),
        .x2y2(x2y2),
        .ap_return(ap_return)
    );

    // clk_gen のインスタンス(ap_clk)
    clk_gen #(
        .CLK_PERIOD(100),    // 10nsec, 100MHz
        .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
    ) RESET_ARESETN (
        .reset_out(ap_rst),
        .init_done()
    );

    initial begin
        // Initialize Inputs
        ap_start    = 1'b0;
        x0y0         = 32'd0;
        x1y0        = 32'd0;
        x2y0        = 32'd0;
        x0y1        = 32'd0;
        x1y1        = 32'd0;
        x2y1        = 32'd0;
        x0y2        = 32'd0;
        x1y2        = 32'd0;
        x2y2        = 32'd0;

        // Wait until Reset falling edge
        @(negedge ap_rst);

        #1000; // 100 ns Wait
        @(posedge ap_clk); // 次のクロックへ
        #DELAY;

        ap_start    = 1'b1;
        x0y0         = 32'd127;
        x1y0        = 32'd127;
        x2y0        = 32'd127;
        x0y1        = 32'd127;
        x1y1        = 32'd127;
        x2y1        = 32'd127;
        x0y2        = 32'd0;
        x1y2        = 32'd0;
        x2y2        = 32'd0;

        @(posedge ap_clk); // 次のクロックへ
        #DELAY;

        ap_start    = 1'b0;

        for (i=0; i<LAP_FILTER_END_COUNT; i=i+1) begin // laplacian_filter の終了を待つ
            @(posedge ap_clk); // 次のクロックへ
            #DELAY;        
        end

        ap_start    = 1'b1;
        x0y0         = 32'd127;
        x1y0        = 32'd127;
        x2y0        = 32'd127;
        x0y1        = 32'd127;
        x1y1        = 32'd81;
        x2y1        = 32'd127;
        x0y2        = 32'd0;
        x1y2        = 32'd0;
        x2y2        = 32'd0;

        @(posedge ap_clk); // 次のクロックへ
        #DELAY;

        ap_start    = 1'b0;

        for (i=0; i<LAP_FILTER_END_COUNT; i=i+1) begin // laplacian_filter の終了を待つ
            @(posedge ap_clk); // 次のクロックへ
            #DELAY;        
        end
    end
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年01月13日 05:41 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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