FC2カウンター FPGAの部屋 Vivado HLS でFIFO を作ってみた3(hiyuhさんに教えてもらった回路)

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

FPGAの部屋

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

Vivado HLS でFIFO を作ってみた3(hiyuhさんに教えてもらった回路)

Vivado HLS でFIFO を作ってみた2(指示子を入れた場合)”の続き。

hiyuh さんにFIFO のC++ のコードを教えてもらったので、それを typedef を取って書き直した。
それが、fifo_test_2b.cpp だ。その fifo_test_2b.cpp を示す。

// fifo_test2b.cpp
// 2016/10/01 by hiyuh, marsee
//

#include "ap_int.h"
#include "hls_stream.h"

#define TO_LITERAL(x) #x
#define PRAGMA_HLS(tok) _Pragma(TO_LITERAL(HLS tok))

static const size_t W = 32;
static const size_t L = 1 << 8;
typedef struct {
    hls::stream<ap_int<W> > ds;
} context_t;
void pp_write(
    context_t     &ctx,
    hls::stream<ap_int<W> > &is
) {
    ctx.ds.write(is.read());
    return;
}
void pp_read(
    context_t     &ctx,
    hls::stream<ap_int<W> > &os
) {
    PRAGMA_HLS(stream variable=ctx.ds depth=L)
    os.write(ctx.ds.read());
    return;
}

void fifo_top(
    hls::stream<ap_int<W> > &is,
    hls::stream<ap_int<W> > &os
) {
    PRAGMA_HLS(interface axis         port=is    )
    PRAGMA_HLS(interface axis         port=os    )
    PRAGMA_HLS(interface ap_ctrl_none port=return)
    PRAGMA_HLS(dataflow)
    static context_t ctx;
    pp_write(ctx, is);
    pp_read (ctx, os);
    return;
}


なお、このプラグマの書き方だと、define した値がプラグマに使える。今までは定数値を書くしかなかったのだが便利になった。
これについての情報はUG902 (2016.2) の49 ページの「プラグマ指示子の付いた #define の使用」を参照のこと。
更に、static const size_t で定義した変数もプラグマに使えるようだ。こっちは演算できるようなので更に便利だ。

プロジェクトを示す。
fifo_test_23_161001.png

このコードを合成した。その結果を示す。
fifo_test_24_161001.png

C テストベンチによるシミュレーションではなく、RTLシミュレーションを行うためにVivado 2016.2 のプロジェクトを作成した。fifo_test_2b プロジェクトだ。
fifo_test_25_161001.png

テストベンチに使用した Verilog HDL コードの fifo_test2b_tb.v を示す。

// fifo_test2b_tb.v
// 2016/10/01 by marsee
//

`default_nettype none
`timescale 100 ps / 1ps

module fifo_test2_tb;
    parameter CLK_PERIOD=100;

    reg  [31:0] is_V_V_TDATA;
    reg  is_V_V_TVALID;
    wire is_V_V_TREADY;
    wire [31:0] os_V_V_TDATA;
    reg  os_V_V_TREADY;
    wire os_V_V_TVALID;
    wire ap_clk;
    wire ap_rst_n;
    
    fifo_top fifo_top_i (
        .is_V_V_TDATA(is_V_V_TDATA),
        .os_V_V_TDATA(os_V_V_TDATA),
        .ap_clk(ap_clk),
        .ap_rst_n(ap_rst_n),
        .is_V_V_TVALID(is_V_V_TVALID),
        .is_V_V_TREADY(is_V_V_TREADY),
        .os_V_V_TVALID(os_V_V_TVALID),
        .os_V_V_TREADY(os_V_V_TREADY)
    );

    always @(posedge ap_clk) begin
        if (~ap_rst_n) begin
            is_V_V_TDATA <= 0;
        end else begin
            is_V_V_TDATA <= is_V_V_TDATA + 1; 
        end
    end

    initial begin
        is_V_V_TVALID = 0;
        os_V_V_TREADY = 0;

        #1100
        is_V_V_TVALID = 1;
        os_V_V_TREADY = 0;

        #(CLK_PERIOD * 8)
        is_V_V_TVALID = 1;
        os_V_V_TREADY = 1;

        #(CLK_PERIOD * 2)
        is_V_V_TVALID = 1;
        os_V_V_TREADY = 0;
       
        #(CLK_PERIOD * 1)
        is_V_V_TVALID = 1;
        os_V_V_TREADY = 1;
    end

    // ap_clk
    clk_gen #(
        .CLK_PERIOD(CLK_PERIOD),    // 10.0nsec, 100MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) sys_clock_i (
        .clk_out(ap_clk)
    );
    
    // ap_rst
    reset_gen #(
        .RESET_STATE(1'b0),
        .RESET_TIME(1000)    // 100nsec
    ) RESET2i (
        .reset_out(ap_rst_n)
    );
    
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
);
    begin
        initial begin
            reset_out = RESET_STATE;
            #RESET_TIME;
            reset_out = ~RESET_STATE;
        end
    end
endmodule

`default_nettype wire


RTLシミュレーション結果を示す。
fifo_test_26_161001.png

ざっと見た感じでは問題なくFIFO になっているようだ。
  1. 2016年10月01日 13:34 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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