FC2カウンター FPGAの部屋 ビットマップ・ディスプレイ・コントローラIPとカメラ・インタフェースIPのAXI4 Lite Slaveのバグをフィックス

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

FPGAの部屋

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

ビットマップ・ディスプレイ・コントローラIPとカメラ・インタフェースIPのAXI4 Lite Slaveのバグをフィックス

Zybo Z7-20上の白線間走行CNNシステムのプロジェクトが動作しないバグ”で、ビットマップ・ディスプレイ・コントローラIPとカメラ・インタフェースIPのAXI4 Lite Slave インターフェース回路にバグがあることが分かった。
今回はそのバグをフィックスする。

ビットマップ・ディスプレイ・コントローラIP とカメラ・インタフェースIP はAXI4 バスを作り始めた初期のころに作成したAXI4 Lite Slave インターフェース回路で、まだAXI4 バスのWrite トランザクションでは、アドレスとデータの依存関係はないということが分かっていなかった。よって、Write トランザクションを1つのステートマシンで作成してしまった。アドレス処理するステートマシンとデータの処理をするステートマシンに分ける必要がある。
ビットマップ・ディスプレイ・コントローラIP のAXI4 Lite Slave インターフェース回路 bm_disp_cntrler_axi_lite_slave.v を変更した。下に貼っておく。

// bm_disp_cntrler_axi_lite_slave.v
// bitmap_disp_cntrler_axi_master のAXI Lite Slave モジュール。Frame Buffer のスタートアドレス・レジスタを持つ。
//
// Addr 0x0 - frame buffer start address
//

`default_nettype none

module bm_disp_cntrler_axi_lite_slave # (
    parameter integer C_S_AXI_LITE_ADDR_WIDTH = 9, // Address width of the AXI Lite Interface
    parameter integer C_S_AXI_LITE_DATA_WIDTH = 32, // Data width of the AXI Lite Interface

    parameter [31:0] C_DISPLAY_START_ADDRESS = 32'h1A00_0000
)(
    input    wire                                    s_axi_lite_aclk,
    input    wire                                    axi_resetn,

    // AXI Lite Write Address Channel
    input    wire                                    s_axi_lite_awvalid,
    output    wire                                    s_axi_lite_awready,
    input    wire    [C_S_AXI_LITE_ADDR_WIDTH-1: 0]    s_axi_lite_awaddr,

    // AXI Lite Write Data Channel
    input    wire                                    s_axi_lite_wvalid,
    output    wire                                    s_axi_lite_wready,
    input    wire    [C_S_AXI_LITE_DATA_WIDTH-1: 0]    s_axi_lite_wdata,

    // AXI Lite Write Response Channel
    output    wire    [1:0]                            s_axi_lite_bresp,
    output    wire                                    s_axi_lite_bvalid,
    input    wire                                    s_axi_lite_bready,

    // AXI Lite Read Address Channel
    input    wire                                    s_axi_lite_arvalid,
    output    wire                                    s_axi_lite_arready,
    input    wire    [C_S_AXI_LITE_ADDR_WIDTH-1: 0]    s_axi_lite_araddr,

    // AXI Lite Read Data Channel
    output    wire                                    s_axi_lite_rvalid,
    input    wire                                    s_axi_lite_rready,
    output    wire    [C_S_AXI_LITE_DATA_WIDTH-1: 0]    s_axi_lite_rdata,
    output    wire    [1:0]                            s_axi_lite_rresp,

    output    wire    [31:0]                            fb_start_address,    // Frame Buffer のスタートアドレス
    output    reg                                        init_done            // PS部の初期化終了
);

    // RESP の値の定義
    parameter    RESP_OKAY =        2'b00;
    parameter    RESP_EXOKAY =    2'b01;
    parameter    RESP_SLVERR =     2'b10;
    parameter    RESP_DECERR =    2'b11;

    parameter  IDLE_WRA =           1'b0,
                 ADDR_ASERT =        1'b1;
                 
    parameter  IDLE_WRD =          1'b0,
                 BREADY_ASSERT =    1'b1;

    parameter    IDLE_RD    =        1'b0,            //  for rdt_cs
                AR_DATA_WAIT =    1'b1;

    reg    wrta_cs = IDLE_WRA;
    reg    wrtd_cs = IDLE_WRD;

    reg        [31:0]    fb_start_addr_reg = C_DISPLAY_START_ADDRESS;

    reg        rdt_cs = IDLE_RD;

    reg        reset_1d = 1'b0;
    reg        reset = 1'b0;
    reg        awready = 1'b1;
    reg        bvalid = 1'b0;
    reg        arready = 1'b1;
    reg        rvalid = 1'b0;
    wire    aclk;

    assign aclk = s_axi_lite_aclk;
    // Synchronization of axi_resetn
    always @(posedge aclk) begin
        reset_1d <= ~axi_resetn;
        reset <= reset_1d;
    end

    // AXI4 Lite Slave Write Transaction State Machine
    always @(posedge aclk) begin
        if (reset) begin
            wrta_cs <= IDLE_WRA;
            awready <= 1'b1;
        end else begin
            case (wrta_cs)
                IDLE_WRA :
                    if (s_axi_lite_awvalid) begin
                        wrta_cs <= ADDR_ASERT;
                        awready <= 1'b0;
                    end
                ADDR_ASERT :
                begin
                    wrta_cs <= IDLE_WRA;
                    awready <= 1'b1;
                end
            endcase
        end
    end
                        
    always @(posedge aclk) begin
        if (reset) begin
            wrtd_cs <= IDLE_WRD;
            bvalid <= 1'b0;
        end else begin
            case (wrtd_cs)
                IDLE_WRD :
                    if (s_axi_lite_wvalid) begin    // Write Transaction Start with data
                        wrtd_cs <= BREADY_ASSERT;
                        bvalid <= 1'b1;
                    end
                BREADY_ASSERT :
                    if (s_axi_lite_bready) begin    // The write transaction was terminated.
                        wrtd_cs <= IDLE_WRD;
                        bvalid <= 1'b0;
                    end
            endcase
        end
    end
    assign s_axi_lite_awready = awready;
    assign s_axi_lite_bvalid = bvalid;
    assign s_axi_lite_wready = 1'b1;
    assign s_axi_lite_bresp = RESP_OKAY;

    // AXI4 Lite Slave Read Transaction State Machine
    always @(posedge aclk) begin
        if (reset) begin
            rdt_cs <= IDLE_RD;
            arready <= 1'b1;
            rvalid <= 1'b0;
        end else begin
            case (rdt_cs)
                IDLE_RD :
                    if (s_axi_lite_arvalid) begin
                        rdt_cs <= AR_DATA_WAIT;
                        arready <= 1'b0;
                        rvalid <= 1'b1;
                    end
                AR_DATA_WAIT :
                    if (s_axi_lite_rready) begin
                        rdt_cs <= IDLE_RD;
                        arready <= 1'b1;
                        rvalid <= 1'b0;
                    end
            endcase
        end
    end
    assign s_axi_lite_arready = arready;
    assign s_axi_lite_rvalid = rvalid;
    assign s_axi_lite_rresp = RESP_OKAY;

    // fb_start_addr_reg
    always @(posedge aclk) begin
        if (reset)
            fb_start_addr_reg <= C_DISPLAY_START_ADDRESS;
        else
            if (s_axi_lite_wvalid)
                fb_start_addr_reg <= s_axi_lite_wdata;
    end
    assign fb_start_address = fb_start_addr_reg;
    assign s_axi_lite_rdata = fb_start_addr_reg;

    // generated init_done
    always @(posedge aclk) begin
        if(reset) begin
            init_done <= 1'b0;
        end else if(wrtd_cs==BREADY_ASSERT) begin
            init_done <= 1'b1;
        end
    end
endmodule

`default_nettype wire


これは、ビットマップ・ディスプレイ・コントローラの全アドレス空間に 1 つのレジスタしかない例だが、いささか乱暴な気もするが、面倒なので、これで行こうと思う。もし複数レジスタがある場合には、アドレスが後なので、テンポラリなレジスタに一旦、Write データを入れておいて、アドレスが来た時に指定されたアドレスのレジスタに入れる必要がある。。。それは面倒だ。
カメラ・インタフェースIP も同様に変更した。
論理合成、インプリメント、ビットストリームの生成を行った。
ハードウェアをエクスポートして、SDKを立ち上げた。
そういえば、SDKのハードウェア・プラットフォームを残しておくと、変更が反映されない感じなので、SDK のプロジェクトとハードウェア・プラットフォームは全消去している。
と言う訳で、HelloWorld プロジェクトと cam_disp3_axis プロジェクトは作り直した。

SDK でZYBO Z7 をコンフィギュレーションして、HelloWorld プロジェクトを走らせた。前回も書いたようにPS のクロックが出力されたので、Vivado 2017.2 でVivado Analyzer を起動した(Open Hardware Manager を開いてOpen Target をクリックし、Auto Target を選択した)。ビットマップ・ディスプレイ・コントローラ のAXI4 Lite Slave インタフェースのAWVALID にトリガを仕掛けて、SDK で cam_disp3_axis.elf を起動するとトリガがかかった。
ZYBO_Z7_102_171012.png

今度はビットマップ・ディスプレイ・コントローラIP のAXI4 Master インタフェースにRead トランザクションが発生している。成功の様だ。
ZYBO_Z7_103_171012.png

だが、表示は下の写真のようになった。
ZYBO_Z7_115_171012.jpg

カメラ・インタフェースのAXI4 Lite Slave インターフェース回路の動作を確認する。
AXI4 Lite Slave インターフェース回路のAWVALID にトリガを掛けるが、SDK で cam_disp3_axis.elf を起動してもトリガがかからない。
ZYBO_Z7_104_171012.png

カメラ・インタフェースのAXI4 Lite Slave インターフェース回路のアドレスにWrite しているのだが、AWVALID のトリガかからないとはどうした訳なのか?

もしかして、AXI インターコネクトのポートを空けているところがあるのがまずいのか?
ZYBO_Z7_105_171012.png

M06_AXI が空いているのが分かると思う。ビットマップ・ディスプレイ・コントローラIP はM05_AXI に接続されている。カメラ・インタフェースIP はM14_AXI に接続されている。
  1. 2017年10月12日 05:35 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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