FC2カウンター FPGAの部屋 ZYBO用の Linaro Ubuntu のPL部にカメラ・コントローラを搭載する10(デバック2)
FC2ブログ

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

FPGAの部屋

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

ZYBO用の Linaro Ubuntu のPL部にカメラ・コントローラを搭載する10(デバック2)

ZYBO用の Linaro Ubuntu のPL部にカメラ・コントローラを搭載する9(デバック)”の続き。

前回は、カメラの画像が表示されないので、ZYBOのLinux(Ubuntu) 環境からベアメタル・アプリケーションに変更してデバックを行った。Vivado logic analyzer を入れて原因を探ってきたが、デバックをしてカメラ画像を表示し、キャプチャモードでワンショットでカメラ画像をキャプチャすることができるようになった。つまり、ベアメタル・アプリケーションとしては、仕様通りに動作している。
ZYBO_Cam_Linux_72_141122.jpg

原因は複合的だったが、(と言うか、しばらくソフトウェアばかりやっていたので、Verilog HDL コードがダメダメだった)カメラが表示されなかった第一の原因は、カメラの frame_valid を適切に処理できなかったことだ。カメラからの出力信号の frame_valid は有効なフレームであることを示しているので、それを L レベルにすれば、カメラ・コントローラIP回路は動作しない。それを利用しているわけだ。つまり独自の frame_valid を作って、今までの回路に送り込んでいる。但し、frame の途中で、frame_valid を L にすると画像表示がおかしくなるため、実際のframe_valid が L の時にいろいろな処理をするようにステートマシンが書いてある。それが、”ZYBO用の Linaro Ubuntu のPL部にカメラ・コントローラを搭載する2(IPのシミュレーション)”の one_shot_sm でここで、作り替えた frame_valid_1d_oh を出力している。だが、よく見ると、条件があった時にしか frame_valid_1d をラッチしていない。これは、ステートマシンのステートのところに書く必要があった。

ワンショットのトリガも不完全だった。これは、ワンショットを出力するのは、AXI Lite Slave のアクセスの1クロックで、クロックは100MHz であるため 10ns 幅のパルスとなる。受ける方は pixel clock 動作なので、16MHz位で受けていた。これでは受かるはず無いので、100MHzで 20 クロック、200 ns まで幅を広げた。非同期処理も加えた結果、画像のワンショット取得ができるようになった。

今は、ベアメタル・アプリケーションなので、これを Linux でできれば完成だ。

修正した mt9d111_axi_lite_slave.v と mt9d111_cam_cont.v を貼っておく。
まずは、 mt9d111_axi_lite_slave.v を下に示す。

// mt9d111_axi_lite_slave.v 
// mt9d111_inf_axi_master のAXI Lite Slave モジュール。Frame Buffer のスタートアドレス・レジスタを持つ。
//
// 2014/11/08 : one_shot_reg を実装。
// オフセット0番地: フレーム・バッファの先頭アドレス(fb_start_address)
// オフセット4番地: 0 ビット目が 0 の時動画、0 ビット目に 1 の時に、ワンショットで取得した1フレームのカメラ画像を表示(one_shot_reg)
//            1 ビット目に 1 を Write した時に、ワンショットで1フレームの画像をフレーム・バッファに保存
// 2014/11/11 : init_done を追加
//

`default_nettype none

module mt9d111_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,
    parameter integer ONE_SHOT_PULSE_LENGTH = 20   // 1ショットパルスの長さのAXI Lite Slave ACLKのクロック数をセット
)(
    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    reg        [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,            // fb_start_address に書き込まれた
    output    wire                                    one_shot_state,        // 1フレーム分取り込んだカメラ画像を保持する
    output    reg                                        one_shot_trigger    // 1フレーム分のカメラ画像取り込みのトリガー、1クロックパルス
);

    // RESP の値の定義
    parameter    RESP_OKAY =        2'b00;
    parameter    RESP_EXOKAY =    2'b01;
    parameter    RESP_SLVERR =     2'b10;
    parameter    RESP_DECERR =    2'b11;
    
    parameter    [1:0]    IDLE_WR =            2'b00,    // for wrt_cs
                        DATA_WRITE_HOLD =    2'b01,
                        BREADY_ASSERT =        2'b11;
                
    parameter    IDLE_RD    =        1'b0,            //  for rdt_cs
                AR_DATA_WAIT =    1'b1;

    reg        [1:0]    wrt_cs = IDLE_WR;
    
    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;
    reg        [31:0]    one_shot_reg;

    parameter    [1:0]    IDLE_TSM =            2'b00,    // for one_shot_tsm
                        WAIT_ONE_SHOT =        2'b01,
                        ONE_SHOT_TRIG =        2'b11;
    reg        [1:0]    one_shot_tsm;
    integer    one_shot_counter;

    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
            wrt_cs <= IDLE_WR;
            awready <= 1'b1;
            bvalid <= 1'b0;
        end else begin
            case (wrt_cs)
                IDLE_WR :
                    if (s_axi_lite_awvalid & ~s_axi_lite_wvalid) begin    // Write Transaction Start
                        wrt_cs <= DATA_WRITE_HOLD;
                        awready <= 1'b0;
                    end else if (s_axi_lite_awvalid & s_axi_lite_wvalid) begin    // Write Transaction Start with data
                        wrt_cs <= BREADY_ASSERT;
                        awready <= 1'b0;
                        bvalid <= 1'b1;
                    end
                DATA_WRITE_HOLD :
                    if (s_axi_lite_wvalid) begin    // Write data just valid
                        wrt_cs <= BREADY_ASSERT;
                        bvalid <= 1'b1;
                    end
                BREADY_ASSERT :
                    if (s_axi_lite_bready) begin    // The write transaction was terminated.
                        wrt_cs <= IDLE_WR;
                        bvalid <= 1'b0;
                        awready <= 1'b1;
                    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) begin
            init_done <= 1'b0;
            fb_start_addr_reg <= C_DISPLAY_START_ADDRESS;
        end else begin
            if (s_axi_lite_wvalid==1'b1 && s_axi_lite_awaddr[2]==1'b0) begin
                init_done <= 1'b1;
                fb_start_addr_reg <= s_axi_lite_wdata;
            end
        end
    end
    assign fb_start_address = fb_start_addr_reg;

    // one_shot_reg
    always @(posedge aclk) begin
        if (reset)
            one_shot_reg <= 32'd0;    // default is continuous display mode
        else
            if (s_axi_lite_wvalid==1'b1 && s_axi_lite_awaddr[2]==1'b1)
                one_shot_reg <= s_axi_lite_wdata;
    end
    assign one_shot_state = one_shot_reg[0];

    // one_shot_tsm(State Machine for one_shot_trgger)
    always @(posedge aclk) begin
        if (reset) begin
            one_shot_tsm <= IDLE_TSM;
            one_shot_trigger <= 1'b0;
        end else begin
            case (one_shot_tsm)
                IDLE_TSM :
                    if (s_axi_lite_awvalid & awready & s_axi_lite_awaddr[2]) begin // one_shot_reg address
                        if (s_axi_lite_wvalid) begin // s_axi_wready is always 1
                            if (s_axi_lite_wdata[1]) begin // one_shot was triggered
                                one_shot_tsm <= ONE_SHOT_TRIG;
                                one_shot_trigger <= 1'b1;
                            end else begin // is not trigger
                                one_shot_tsm <= IDLE_TSM;
                                one_shot_trigger <= 1'b0;
                            end
                        end else begin // s_axi_lite_wvalid is not asserted
                            one_shot_tsm <= WAIT_ONE_SHOT;
                            one_shot_trigger <= 1'b0;
                        end
                    end
                WAIT_ONE_SHOT :
                    if (s_axi_lite_wvalid) begin // s_axi_wready is always 1
                        if (s_axi_lite_wdata[1]) begin // one_shot was triggered
                            one_shot_tsm <= ONE_SHOT_TRIG;
                            one_shot_trigger <= 1'b1;
                        end else begin // is not trigger
                            one_shot_tsm <= IDLE_TSM;
                            one_shot_trigger <= 1'b0;
                        end
                    end
                ONE_SHOT_TRIG : begin
                    if (one_shot_counter == 0) begin
                        one_shot_tsm <= IDLE_TSM;
                        one_shot_trigger <= 1'b0;
                    end
                end
            endcase
        end
    end

    // one shot pulse length counter
    always @(posedge aclk) begin
        if (reset) begin
            one_shot_counter <= ONE_SHOT_PULSE_LENGTH;
        end else if (one_shot_tsm == ONE_SHOT_TRIG) begin
            one_shot_counter <= one_shot_counter - 1;
        end else begin
            one_shot_counter <= ONE_SHOT_PULSE_LENGTH;
        end
    end
    // s_axi_lite_rdata
    always @(posedge aclk) begin
        if (reset) begin
            s_axi_lite_rdata <= 0;
        end else if (s_axi_lite_arvalid) begin
            case (s_axi_lite_araddr[2])
                1'b0 :     s_axi_lite_rdata <= fb_start_addr_reg;
                1'b1 :    s_axi_lite_rdata <= one_shot_reg;
            endcase
        end
    end
endmodule
    
`default_nettype wire        


次に、mt9d111_cam_cont.v を下に示す。

// MT9D111カメラコントローラ
// mt9d111_cam_cont.v
// 2012/12/26
//
// 2014/11/07 : fb_start_address を追加。レジスタに設定された値をスタートアドレスとして参照。
// 2014/11/08 : one_shot_state, one_shot_trigger の入力ポートを追加

`default_nettype none

module mt9d111_cam_cont # (
    parameter    integer    UPSIDE_DOWN = 0        // 1 = 上下反転、0 = 正常
)(
    input    wire    aclk,
    input    wire    areset,
    input    wire    pclk,
    input    wire    preset,
    input    wire    pclk_from_pll,
    output    wire    xclk,
    input    wire    line_valid,
    input    wire    frame_valid,
    input    wire    [7:0]    cam_data,
    output    wire    standby,
    output    wire    [31:0]    paddr,
    input    wire    pfifo_rd_en,
    output    wire    [63:0]    pfifo_dout,
    output    wire    pfifo_empty,
    output    wire    pfifo_almost_empty,
    output    wire    [9:0]    pfifo_rd_data_count,
    output    wire    pfifo_overflow,
    output    wire    pfifo_underflow,
    input    wire    [31:0]    fb_start_address,
    input    wire    one_shot_state,        // 1フレーム分取り込んだカメラ画像を保持する
    input    wire    one_shot_trigger    // 1フレーム分のカメラ画像取り込みのトリガー、1クロックパルス
);
    `include "./disp_timing_parameters.vh"

    // Frame Buffer End Address
    reg        line_valid_1d;
    reg        frame_valid_1d;
    reg        [7:0]    cam_data_1d;
    reg        line_valid_1d_odd;
    reg        line_v_1d_odd_1d;
    reg        [63:0]    rgb565;
    wire    pfifo_full, pfifo_almost_full;
    reg        frame_valid_1d_aclk_1d, frame_valid_1d_aclk_2d;
    parameter    [1:0]    IDLE_ADDR_RST =    2'b00,
                        ADDR_RST =        2'b01,
                        ADDR_RST_HOLD =    2'b11;
    reg        [1:0]    addr_rst_cs;
    reg        [31:0]    paddr_reg;
    reg        rgb565_2nd;

    parameter    [2:0]    IDLE_OS =                3'b000,
                        WAIT_FRAME_VALID_END =    3'b001,
                        HOLD_PICTURE =            3'b011,
                        WAIT_FRAME_VALID_LOW =    3'b010,
                        WAIT_FRAME_VALID_HIGH =    3'b110;
    reg        [2:0]    one_shot_sm;
    reg        frame_valid_1d_oh;
    reg        ost_1d, ost_2d, ost_3d, ost_4d;
    reg        one_shot_tig_pclk;

    assign standby = 1'b0;

    // MT9D111 へのクロックを出力 (xclk)
    ODDR #(
        .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
        .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
        .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
    ) ODDR_inst (
        .Q(xclk), // 1-bit DDR output
        .C(pclk_from_pll), // 1-bit clock input
        .CE(1'b1), // 1-bit clock enable input
        .D1(1'b1), // 1-bit data input (positive edge)
        .D2(1'b0), // 1-bit data input (negative edge)
        .R(1'b0), // 1-bit reset
        .S(1'b0) // 1-bit set
    );

    // 入力信号を一旦ラッチする
    always @(posedge pclk) begin
        if (preset) begin
            line_valid_1d <=    1'b0;
            frame_valid_1d <=    1'b0;
            cam_data_1d <=        8'd0;
        end else begin
            line_valid_1d <=    line_valid;
            frame_valid_1d <=    frame_valid;
            cam_data_1d <=        cam_data;
        end
    end

    // one_shot_trigger はAXIバスのaclkで生成されているので、pclkで動作するステートマシンでは、本当にone shotでは取れない
    // よって、one shotと言ってもある程度の幅を用意してある。pclk の幅のone shot pulse を作る必要がある
    always @(posedge pclk) begin // one_shot_trigger を pclk で同期化
        if (preset) begin
            ost_1d <= 1'b0;
            ost_2d <= 1'b0;
            ost_3d <= 1'b0;
            ost_4d <= 1'b0;
        end else begin
            ost_1d <= one_shot_trigger;
            ost_2d <= ost_1d;
            ost_3d <= ost_2d;
            ost_4d <= ost_3d;
        end
    end

    // pclk 幅の one shot pulse を生成
    always @(posedge pclk) begin
        if (preset) begin
            one_shot_tig_pclk <= 1'b0;
        end else if (ost_3d==1'b1 && ost_4d==1'b0) begin // rising edge
            one_shot_tig_pclk <= 1'b1;
        end else begin
            one_shot_tig_pclk <= 1'b0;
        end
    end
    
    // one shot state machine
    // frame_valid_1d_oh を生成する
    always @(posedge pclk) begin
        if (preset) begin
            one_shot_sm <= IDLE_OS;
            frame_valid_1d_oh <= frame_valid_1d;
        end else begin
            case (one_shot_sm)
                IDLE_OS : begin
                    frame_valid_1d_oh <= frame_valid_1d;
                    if (one_shot_state) begin
                        one_shot_sm <= WAIT_FRAME_VALID_END;
                    end
                end
                WAIT_FRAME_VALID_END : begin
                    frame_valid_1d_oh <= frame_valid_1d;
                    if (!frame_valid_1d) begin
                        one_shot_sm <= HOLD_PICTURE;
                    end
                end
                HOLD_PICTURE : begin
                    frame_valid_1d_oh <= 1'b0;
                    if (one_shot_tig_pclk) begin
                        one_shot_sm <= WAIT_FRAME_VALID_LOW;
                    end else if (~one_shot_state & ~frame_valid_1d) begin
                        one_shot_sm <= IDLE_OS;
                    end
                end
                WAIT_FRAME_VALID_LOW : begin
                    frame_valid_1d_oh <= 1'b0;
                    if (!frame_valid_1d) begin
                        one_shot_sm <= WAIT_FRAME_VALID_HIGH;
                    end
                end
                WAIT_FRAME_VALID_HIGH : begin
                    frame_valid_1d_oh <= frame_valid_1d;
                    if (frame_valid_1d) begin
                        one_shot_sm <= WAIT_FRAME_VALID_END;
                    end
                end
            endcase
        end
    end

    // frame_valid_1d_oh をaclk でラッチする
    always @(posedge aclk) begin
        if (areset) begin
            frame_valid_1d_aclk_1d <= 1'b0;
            frame_valid_1d_aclk_2d <= 1'b0;
        end else begin
            frame_valid_1d_aclk_1d <= frame_valid_1d_oh;
            frame_valid_1d_aclk_2d <= frame_valid_1d_aclk_1d;
        end
    end

    // line_valid_1d が偶数か奇数かをカウント
    always @(posedge pclk) begin
        if (preset)
            line_valid_1d_odd <= 1'b0;
        else begin
            if (!frame_valid_1d_oh)
                line_valid_1d_odd <= 1'b0;
            else if (line_valid_1d)
                line_valid_1d_odd <= ~line_valid_1d_odd;
            else
                line_valid_1d_odd <= 1'b0;
        end
    end

    // rgb565でラッチしているので、line_valid_1d_odd を1クロック遅延する
    always @(posedge pclk) begin
        if (preset)
            line_v_1d_odd_1d <= 1'b0;
        else
            line_v_1d_odd_1d <= line_valid_1d_odd;
    end

    // 2番めのRGB565を示す。64ビット長のFIFOに入れるのに2ピクセル集めてから非同期FIFOにWriteする
    always @(posedge pclk) begin
        if (preset)
            rgb565_2nd <= 1'b0;
        else begin
            if (line_valid_1d_odd)
                rgb565_2nd <= ~rgb565_2nd;
        end
    end

    // addressの生成
    always @(posedge aclk) begin
        if (areset) begin
            if (UPSIDE_DOWN==0) // 正常、それ以外は上下反転
                paddr_reg <= fb_start_address;
            else // 上下反転
                paddr_reg <= fb_start_address + (H_ACTIVE_VIDEO * V_ACTIVE_VIDEO)*4 - 8;
        end else begin
            if (pfifo_rd_en) begin
                if (UPSIDE_DOWN==0) // 正常
                    paddr_reg <= paddr_reg + 32'd8;
                else // 上下反転
                    paddr_reg <= paddr_reg - 32'd8;
            end else if (addr_rst_cs==ADDR_RST) begin    // frame_valid が0になって、pfifoにデータが無くなった時にアドレスをクリア
                if (UPSIDE_DOWN==0) // 正常、それ以外は上下反転
                    paddr_reg <= fb_start_address;
                else // 上下反転
                    paddr_reg <= fb_start_address + (H_ACTIVE_VIDEO * V_ACTIVE_VIDEO)*4 - 8;
            end
        end
    end
    assign paddr = paddr_reg;

    // address をリセットするためのステートマシン
    always @(posedge aclk) begin
        if (areset)
            addr_rst_cs <= IDLE_ADDR_RST;
        else begin
            case (addr_rst_cs)
                IDLE_ADDR_RST :
                    if (~frame_valid_1d_aclk_2d & pfifo_empty)
                        addr_rst_cs <= ADDR_RST;
                ADDR_RST :
                    addr_rst_cs <= ADDR_RST_HOLD;
                ADDR_RST_HOLD :
                    if (frame_valid_1d_aclk_2d)
                        addr_rst_cs <= IDLE_ADDR_RST;
            endcase
        end
    end

    // RGB565 のデータを保存する。正常と上下反転ではバイト配列が異なる
    always @(posedge pclk) begin
        if (preset)
            rgb565 <= 64'd0;
        else begin
            if (UPSIDE_DOWN==0) begin // 正常、それ以外は上下反転
                case ({rgb565_2nd, line_valid_1d_odd})
                    2'b00 : // 1番目
                        rgb565[63:45] <= {8'd0, cam_data_1d[7:3], 3'b000, cam_data_1d[2:0]};    // cam_data_1d = R7 R6 R5 R4 R3 G7 G6 G5
                    2'b01 : // 2番目
                        rgb565[44:32] <= {cam_data_1d[7:5], 2'b00, cam_data_1d[4:0], 3'b000};    // cam_data_1d = G4 G3 G2 B7 B6 B5 B4 B3
                    2'b10 : // 3番目
                        rgb565[31:13] <= {8'd0, cam_data_1d[7:3], 3'b000, cam_data_1d[2:0]};    // cam_data_1d = R7 R6 R5 R4 R3 G7 G6 G5
                    2'b11 : // 4番目
                        rgb565[12:0] <= {cam_data_1d[7:5], 2'b00, cam_data_1d[4:0], 3'b000};    // cam_data_1d = G4 G3 G2 B7 B6 B5 B4 B3
                endcase
            end else begin // 上下反転
                case ({rgb565_2nd, line_valid_1d_odd})
                    2'b00 : // 1番目
                        rgb565[31:13] <= {8'd0, cam_data_1d[7:3], 3'b000, cam_data_1d[2:0]};    // cam_data_1d = R7 R6 R5 R4 R3 G7 G6 G5
                    2'b01 : // 2番目
                        rgb565[12:0] <= {cam_data_1d[7:5], 2'b00, cam_data_1d[4:0], 3'b000};    // cam_data_1d = G4 G3 G2 B7 B6 B5 B4 B3
                    2'b10 : // 3番目
                        rgb565[63:45] <= {8'd0, cam_data_1d[7:3], 3'b000, cam_data_1d[2:0]};    // cam_data_1d = R7 R6 R5 R4 R3 G7 G6 G5
                    2'b11 : // 4番目
                        rgb565[44:32] <= {cam_data_1d[7:5], 2'b00, cam_data_1d[4:0], 3'b000};    // cam_data_1d = G4 G3 G2 B7 B6 B5 B4 B3
                endcase
            end
        end
    end

    // pixel FIFO をインスタンスする
    pixel_fifo pfifo (
        .rst(areset), // input rst
        .wr_clk(pclk), // input wr_clk
        .rd_clk(aclk), // input rd_clk
        .din(rgb565), // input [63 : 0] din
        .wr_en(line_v_1d_odd_1d & ~rgb565_2nd), // input wr_en, 2つのピクセルが揃うには4クロック掛かる
        .rd_en(pfifo_rd_en), // input rd_en
        .dout(pfifo_dout), // output [63 : 0] dout
        .full(pfifo_full), // output full
        .almost_full(pfifo_almost_full), // output almost_full
        .overflow(pfifo_overflow), // output overflow
        .empty(pfifo_empty), // output empty
        .almost_empty(pfifo_almost_empty), // output almost_empty
        .underflow(pfifo_underflow), // output underflow
        .rd_data_count(pfifo_rd_data_count) // output [9 : 0] rd_data_count
    );
endmodule

`default_nettype wire

  1. 2014年11月22日 17:29 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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