FC2カウンター FPGAの部屋 2013年01月03日
FC2ブログ

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

FPGAの部屋

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

ZedBoard用CMOSカメラ回路の作製3(HDLソースの公開2)

ZedBoard用CMOSカメラ回路の作製2(HDLソースの公開1)”の続き。
今度は、テストベンチとMT9D111のモデルのVerilog ソースを貼っておく。勿論、無保証です。

最初にテストベンチ、mt9d111_inf_axi_master_tb.v から。

`default_nettype none

`timescale 100ps / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   09:51:18 12/31/2012
// Design Name:   mt9d111_inf_axi_master
// Module Name:   K:/HDL/FndtnISEWork/Zynq-7000/ZedBoard/ZedBoard_CamDisp_wHDMI_144/mt9d111_inf_axi_master/mt9d111_inf_axi_master_tb.v
// Project Name:  mt9d111_inf_axi_master
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: mt9d111_inf_axi_master
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module mt9d111_inf_axi_master_tb;

    // Inputs
    wire ACLK;
    wire ARESETN;
    wire M_AXI_AWREADY;
    wire M_AXI_WREADY;
    wire [0:0] M_AXI_BID;
    wire [1:0] M_AXI_BRESP;
    wire [0:0] M_AXI_BUSER;
    wire M_AXI_BVALID;
    wire M_AXI_ARREADY;
    wire [0:0] M_AXI_RID;
    wire [63:0] M_AXI_RDATA;
    wire [1:0] M_AXI_RRESP;
    wire M_AXI_RLAST;
    wire [0:0] M_AXI_RUSER;
    wire M_AXI_RVALID;
    wire init_done;
    wire pclk_from_pll;
    wire pclk;
    wire href;
    wire vsync;
    wire [7:0] cam_data;

    // Outputs
    wire [0:0] M_AXI_AWID;
    wire [31:0] M_AXI_AWADDR;
    wire [7:0] M_AXI_AWLEN;
    wire [2:0] M_AXI_AWSIZE;
    wire [1:0] M_AXI_AWBURST;
    wire M_AXI_AWLOCK;
    wire [3:0] M_AXI_AWCACHE;
    wire [2:0] M_AXI_AWPROT;
    wire [3:0] M_AXI_AWQOS;
    wire [0:0] M_AXI_AWUSER;
    wire M_AXI_AWVALID;
    wire [63:0] M_AXI_WDATA;
    wire [7:0] M_AXI_WSTRB;
    wire M_AXI_WLAST;
    wire [0:0] M_AXI_WUSER;
    wire M_AXI_WVALID;
    wire M_AXI_BREADY;
    wire [0:0] M_AXI_ARID;
    wire [31:0] M_AXI_ARADDR;
    wire [7:0] M_AXI_ARLEN;
    wire [2:0] M_AXI_ARSIZE;
    wire [1:0] M_AXI_ARBURST;
    wire [1:0] M_AXI_ARLOCK;
    wire [3:0] M_AXI_ARCACHE;
    wire [2:0] M_AXI_ARPROT;
    wire [3:0] M_AXI_ARQOS;
    wire [0:0] M_AXI_ARUSER;
    wire M_AXI_ARVALID;
    wire M_AXI_RREADY;
    wire wr_error;
    wire xck;
    wire standby;
    wire pfifo_overflow;
    wire pfifo_underflow;

    // Instantiate the Unit Under Test (UUT)
    mt9d111_inf_axi_master uut (
        .ACLK(ACLK), 
        .ARESETN(ARESETN), 
        .M_AXI_AWID(M_AXI_AWID), 
        .M_AXI_AWADDR(M_AXI_AWADDR), 
        .M_AXI_AWLEN(M_AXI_AWLEN), 
        .M_AXI_AWSIZE(M_AXI_AWSIZE), 
        .M_AXI_AWBURST(M_AXI_AWBURST), 
        .M_AXI_AWLOCK(M_AXI_AWLOCK), 
        .M_AXI_AWCACHE(M_AXI_AWCACHE), 
        .M_AXI_AWPROT(M_AXI_AWPROT), 
        .M_AXI_AWQOS(M_AXI_AWQOS), 
        .M_AXI_AWUSER(M_AXI_AWUSER), 
        .M_AXI_AWVALID(M_AXI_AWVALID), 
        .M_AXI_AWREADY(M_AXI_AWREADY), 
        .M_AXI_WDATA(M_AXI_WDATA), 
        .M_AXI_WSTRB(M_AXI_WSTRB), 
        .M_AXI_WLAST(M_AXI_WLAST), 
        .M_AXI_WUSER(M_AXI_WUSER), 
        .M_AXI_WVALID(M_AXI_WVALID), 
        .M_AXI_WREADY(M_AXI_WREADY), 
        .M_AXI_BID(M_AXI_BID), 
        .M_AXI_BRESP(M_AXI_BRESP), 
        .M_AXI_BUSER(M_AXI_BUSER), 
        .M_AXI_BVALID(M_AXI_BVALID), 
        .M_AXI_BREADY(M_AXI_BREADY), 
        .M_AXI_ARID(M_AXI_ARID), 
        .M_AXI_ARADDR(M_AXI_ARADDR), 
        .M_AXI_ARLEN(M_AXI_ARLEN), 
        .M_AXI_ARSIZE(M_AXI_ARSIZE), 
        .M_AXI_ARBURST(M_AXI_ARBURST), 
        .M_AXI_ARLOCK(M_AXI_ARLOCK), 
        .M_AXI_ARCACHE(M_AXI_ARCACHE), 
        .M_AXI_ARPROT(M_AXI_ARPROT), 
        .M_AXI_ARQOS(M_AXI_ARQOS), 
        .M_AXI_ARUSER(M_AXI_ARUSER), 
        .M_AXI_ARVALID(M_AXI_ARVALID), 
        .M_AXI_ARREADY(M_AXI_ARREADY), 
        .M_AXI_RID(M_AXI_RID), 
        .M_AXI_RDATA(M_AXI_RDATA), 
        .M_AXI_RRESP(M_AXI_RRESP), 
        .M_AXI_RLAST(M_AXI_RLAST), 
        .M_AXI_RUSER(M_AXI_RUSER), 
        .M_AXI_RVALID(M_AXI_RVALID), 
        .M_AXI_RREADY(M_AXI_RREADY), 
        .init_done(init_done), 
        .wr_error(wr_error), 
        .pclk_from_pll(pclk_from_pll), 
        .pclk(pclk), 
        .xck(xck), 
        .href(href), 
        .vsync(vsync), 
        .cam_data(cam_data), 
        .standby(standby), 
        .pfifo_overflow(pfifo_overflow), 
        .pfifo_underflow(pfifo_underflow)
    );
    
    assign init_done = 1'b1;

    // ACLK のインスタンス
    clk_gen #(
        .CLK_PERIOD(100),    // 10nsec, 100MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) ACLKi (
        .clk_out(ACLK)
    );
    
    // pclk_from_pll のインスタンス
    clk_gen #(
        .CLK_PERIOD(278),    // 27.8nsec, 約36MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) pclk_from_pll_i (
        .clk_out(pclk_from_pll)
    );
    
    // reset_gen のインスタンス
    reset_gen #(
        .RESET_STATE(1'b0),
        .RESET_TIME(1000)    // 100nsec
    ) RESETi (
        .reset_out(ARESETN)
    );
    
    // MT9D111 モデル
    mt9d111_model #(
        .HORIZONTAL_PIXELS(800),
        .VERTICAL_LINES(600),
        .HBLANK_REG(174),
        .VBLANK_REG(16),
        .PCLK_DELAY(1)
    ) mt9d111_model_i (
        .xck(xck),
        .pclk(pclk),
        .href(href),
        .vsync(vsync),
        .d(cam_data),
        .scl(1'b1),
        .sda(),
        .standby(standby)
    );

    // Instantiate the Unit Under Test (UUT_slave)
    axi_slave_bfm #(
        .C_M_AXI_DATA_WIDTH(64)
    ) uut_slave (
        .ACLK(ACLK), 
        .ARESETN(ARESETN), 
        .M_AXI_AWID(M_AXI_AWID), 
        .M_AXI_AWADDR(M_AXI_AWADDR), 
        .M_AXI_AWLEN(M_AXI_AWLEN), 
        .M_AXI_AWSIZE(M_AXI_AWSIZE), 
        .M_AXI_AWBURST(M_AXI_AWBURST), 
        .M_AXI_AWLOCK(M_AXI_AWLOCK), 
        .M_AXI_AWCACHE(M_AXI_AWCACHE), 
        .M_AXI_AWPROT(M_AXI_AWPROT), 
        .M_AXI_AWQOS(M_AXI_AWQOS), 
        .M_AXI_AWUSER(M_AXI_AWUSER), 
        .M_AXI_AWVALID(M_AXI_AWVALID), 
        .M_AXI_AWREADY(M_AXI_AWREADY), 
        .M_AXI_WDATA(M_AXI_WDATA), 
        .M_AXI_WSTRB(M_AXI_WSTRB), 
        .M_AXI_WLAST(M_AXI_WLAST), 
        .M_AXI_WUSER(M_AXI_WUSER), 
        .M_AXI_WVALID(M_AXI_WVALID), 
        .M_AXI_WREADY(M_AXI_WREADY), 
        .M_AXI_BID(M_AXI_BID), 
        .M_AXI_BRESP(M_AXI_BRESP), 
        .M_AXI_BUSER(M_AXI_BUSER), 
        .M_AXI_BVALID(M_AXI_BVALID), 
        .M_AXI_BREADY(M_AXI_BREADY), 
        .M_AXI_ARID(M_AXI_ARID), 
        .M_AXI_ARADDR(M_AXI_ARADDR), 
        .M_AXI_ARLEN(M_AXI_ARLEN), 
        .M_AXI_ARSIZE(M_AXI_ARSIZE), 
        .M_AXI_ARBURST(M_AXI_ARBURST), 
        .M_AXI_ARLOCK(M_AXI_ARLOCK), 
        .M_AXI_ARCACHE(M_AXI_ARCACHE), 
        .M_AXI_ARPROT(M_AXI_ARPROT), 
        .M_AXI_ARQOS(M_AXI_ARQOS), 
        .M_AXI_ARUSER(M_AXI_ARUSER), 
        .M_AXI_ARVALID(M_AXI_ARVALID), 
        .M_AXI_ARREADY(M_AXI_ARREADY), 
        .M_AXI_RID(M_AXI_RID), 
        .M_AXI_RDATA(M_AXI_RDATA), 
        .M_AXI_RRESP(M_AXI_RRESP), 
        .M_AXI_RLAST(M_AXI_RLAST), 
        .M_AXI_RUSER(M_AXI_RUSER), 
        .M_AXI_RVALID(M_AXI_RVALID), 
        .M_AXI_RREADY(M_AXI_RREADY)
    );
      
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


次に、mt9d111_model.v を貼っておく。RGBのデータにはM系列の疑似乱数を使用している。(2013/08/27:修正)

// mt9d111_model.v 
// mt9d111 の動作モデル
// RGB565 を出力

`default_nettype none
`timescale 1ns / 1ps

module mt9d111_model # (
    parameter    integer HORIZONTAL_PIXELS    = 800,
    parameter    integer    VERTICAL_LINES        = 600,
    parameter    integer    HBLANK_REG            = 174,     // pixels
    parameter    integer    VBLANK_REG            = 16,    // rows
    parameter    integer    PCLK_DELAY            = 1
)(
    input    wire    xck,
    output    reg        pclk = 1'b1,
    output    reg        href = 1'b0,
    output    reg        vsync = 1'b1,
    output    reg        [7:0]    d = 8'd0,
    input    wire    scl,
    inout    wire    sda,
    input    wire    standby
);

    parameter    [2:0]    FRAME_START_BLANKING =    3'b000,
                        ACTIVE_DATA_TIME =        3'b001,
                        HORIZONTAL_BLANKING =    3'b011,
                        FRAME_END_BLANKING =    3'b010,
                        VERTICAL_BLANKING =        3'b110;
                        
    reg        [2:0]    mt9d111_cs = FRAME_START_BLANKING;
    reg        [2:0]    fseb_count = 3'd5;
    reg        [15:0]    adt_count = (HORIZONTAL_PIXELS * 2) - 1;
    reg        [15:0]    hb_count = HBLANK_REG - 1;
    reg        [15:0]    fvt_count = VERTICAL_LINES - 1;
    reg        [31:0]    vb_count = VBLANK_REG * (HORIZONTAL_PIXELS + HBLANK_REG) - 1;
    reg        href_node = 1'b0;
    reg        vsync_node = 1'b1;
    reg        dout_is_even = 1'b0;

    // R, G, B 毎に違った生成多項式のM系列を用意した
    function [7:0] mseqf8_R (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
            mseqf8_R = {din[6:0], xor_result};
        end
    endfunction
    
    function [7:0] mseqf8_G (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[4] ^ din[2] ^ din[0];
            mseqf8_G = {din[6:0], xor_result};
        end
    endfunction

    function [7:0] mseqf8_B (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[5] ^ din[2] ^ din[1];
            mseqf8_B = {din[6:0], xor_result};
        end
    endfunction

    reg        [7:0]    mseq8r = 8'd1;
    reg        [7:0]    mseq8g = 8'd1;
    reg        [7:0]    mseq8b = 8'd1;
    
    // pclk の出力
    always @*
        pclk <= #PCLK_DELAY    xck;
        
    // MT9D111 のステート
    always @(posedge pclk) begin
        case (mt9d111_cs)
            FRAME_START_BLANKING : begin
                if (fseb_count==0) begin
                    mt9d111_cs <= ACTIVE_DATA_TIME;
                    href_node <= 1'b1;
                end
            end
            ACTIVE_DATA_TIME : begin
                if (adt_count==0) begin
                    if (fvt_count==0)    // frame end
                        mt9d111_cs <= FRAME_END_BLANKING;
                    else
                        mt9d111_cs <= HORIZONTAL_BLANKING;
                    href_node <= 1'b0;
                end
            end
            HORIZONTAL_BLANKING : begin
                if (hb_count==0) begin
                    mt9d111_cs <= ACTIVE_DATA_TIME;
                    href_node <= 1'b1;
                end
            end
            FRAME_END_BLANKING : begin
                if (fseb_count==0) begin
                    mt9d111_cs <= VERTICAL_BLANKING;
                    vsync_node <= 1'b0;
                end
            end
            VERTICAL_BLANKING : begin
                if (vb_count==0) begin
                    mt9d111_cs <= FRAME_START_BLANKING;
                    vsync_node <= 1'b1;
                end
            end
        endcase
    end
                
    // vsync, href 出力、レーシングを防ぐためにpclk よりも出力を遅らせる
    always @* begin
        vsync <= #1    vsync_node;
        href <= #1    href_node;
    end
    
    // Frame Start/End Blanking Counter (6 pixel clocks)
    always @(posedge pclk) begin
        if (mt9d111_cs==FRAME_START_BLANKING || mt9d111_cs==FRAME_END_BLANKING) begin
            if (fseb_count > 0)
                fseb_count <= fseb_count - 3'd1;
        end else
            fseb_count <= 3'd5;
    end
    
    // Active Data Time Counter
    always @(posedge pclk) begin
        if (mt9d111_cs==ACTIVE_DATA_TIME) begin
            if (adt_count > 0)
                adt_count <= adt_count - 16'd1;
        end else
            adt_count <= (HORIZONTAL_PIXELS * 2) - 1;
    end
    
    // Horizontal Blanking Counter
    always @(posedge pclk) begin
        if (mt9d111_cs==HORIZONTAL_BLANKING) begin
            if (hb_count > 0)
                hb_count <= hb_count - 16'd1;
        end else
            hb_count <= HBLANK_REG - 1;
    end
    
    // Frame Valid Time Counter
    always @(posedge pclk) begin
        if (mt9d111_cs==ACTIVE_DATA_TIME && adt_count==0) begin
            if (fvt_count > 0)
                fvt_count <= fvt_count - 16'd1;
        end if (mt9d111_cs == VERTICAL_BLANKING)
            fvt_count <= VERTICAL_LINES - 1;
    end
    
    // Vertical Blanking Counter
    always @(posedge pclk) begin
        if (mt9d111_cs==VERTICAL_BLANKING) begin
            if (vb_count > 0)
                vb_count <= vb_count - 32'd1;
        end else
            vb_count <= VBLANK_REG * (HORIZONTAL_PIXELS + HBLANK_REG) - 1;
    end
    
    // Red のM系列符号生成
    always @(posedge pclk) begin
        // if (mt9d111_cs==ACTIVE_DATA_TIME)
            mseq8r <= mseqf8_R(mseq8r);
    end
    
    // Green のM系列符号生成
    always @(posedge pclk) begin
        // if (mt9d111_cs==ACTIVE_DATA_TIME)
            mseq8g <= mseqf8_G(mseq8g);
    end
    
    // Blue のM系列符号生成
    always @(posedge pclk) begin
        // if (mt9d111_cs==ACTIVE_DATA_TIME)
            mseq8b <= mseqf8_B(mseq8b);
    end
    
    // d 出力のODD とEVEN を示す
    always @(posedge pclk) begin
        if (mt9d111_cs==ACTIVE_DATA_TIME)
            dout_is_even <= ~dout_is_even;
        else
            dout_is_even <= 1'b0;
    end
    
    // d 出力、レーシングを防ぐためにpclk よりも出力を遅らせる
    always @(posedge pclk) begin
        if (mt9d111_cs==ACTIVE_DATA_TIME) begin
            if (dout_is_even)
                d <= #1 {mseq8g[4:2], mseq8b[7:3]};
            else
                d <= #1 {mseq8r[7:3], mseq8g[7:5]};
        end
    end

endmodule

`default_nettype wire


AXI Master用 AXI Slave Bus Function Mode (BFM)も貼っておく。(2013/01/23:修正)

-----------------------------------------------------------------------------
--
-- AXI Master用 AXI Slave Bus Function Mode (BFM)
--
-----------------------------------------------------------------------------
-- 2012/02/25 : M_AXI_AWBURST=1 (INCR) にのみ対応、AWSIZE, ARSIZE = 000 (1byte), 001 (2bytes), 010 (4bytes) のみ対応。
-- 2012/01/15 : BVALID が1になる間隔をランダム変更できるようにした。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;

package m_seq_bfm_pack is
    function M_SEQ16_BFM_F(mseq16in : std_logic_vector
        )return std_logic_vector;
end package m_seq_bfm_pack;
package body m_seq_bfm_pack is
    function M_SEQ16_BFM_F(mseq16in : std_logic_vector
        )return std_logic_vector is
            variable mseq16 : std_logic_vector(15 downto 0);
            variable xor_result : std_logic;
    begin
        xor_result := mseq16in(15) xor mseq16in(12) xor mseq16in(10) xor mseq16in(8) xor mseq16in(7) xor mseq16in(6) xor mseq16in(3) xor mseq16in(2);
        mseq16 := mseq16in(14 downto 0) & xor_result;
        return mseq16;
    end M_SEQ16_BFM_F;
end m_seq_bfm_pack;


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use IEEE.math_real.all;

library work;
use work.m_seq_bfm_pack.all;

--library unisim;
--use unisim.vcomponents.all;

entity axi_slave_bfm is
  generic (
    C_M_AXI_ID_WIDTH     : integer := 1;
    C_M_AXI_ADDR_WIDTH   : integer := 32;
    C_M_AXI_DATA_WIDTH   : integer := 32;
    C_M_AXI_AWUSER_WIDTH : integer := 1;
    C_M_AXI_ARUSER_WIDTH : integer := 1;
    C_M_AXI_WUSER_WIDTH  : integer := 1;
    C_M_AXI_RUSER_WIDTH  : integer := 1;
    C_M_AXI_BUSER_WIDTH  : integer := 1;
    
    C_M_AXI_TARGET        : integer := 0;
    C_OFFSET_WIDTH        : integer := 10; -- 割り当てるRAMのアドレスのビット幅
    C_M_AXI_BURST_LEN    : integer := 256;
    
    WRITE_RANDOM_WAIT    : integer := 1; -- Write Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
    WR_BVALID_RANDOM_WAIT    : integer := 1; -- Write Transaction の時のM_AXI_BVALID をランダムにWaitする=1, Waitしない=0
    READ_RANDOM_WAIT    : integer := 0 -- Read Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
    );
  port(
    -- System Signals
    ACLK    : in std_logic;
    ARESETN : in std_logic;

    -- Master Interface Write Address Ports
    M_AXI_AWID     : in  std_logic_vector(C_M_AXI_ID_WIDTH-1 downto 0);
    M_AXI_AWADDR   : in  std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
    M_AXI_AWLEN    : in  std_logic_vector(8-1 downto 0);
    M_AXI_AWSIZE   : in  std_logic_vector(3-1 downto 0);
    M_AXI_AWBURST  : in  std_logic_vector(2-1 downto 0);
    -- M_AXI_AWLOCK   : in  std_logic_vector(2-1 downto 0);
    M_AXI_AWLOCK   : in  std_logic;
    M_AXI_AWCACHE  : in  std_logic_vector(4-1 downto 0);
    M_AXI_AWPROT   : in  std_logic_vector(3-1 downto 0);
    M_AXI_AWQOS    : in  std_logic_vector(4-1 downto 0);
    M_AXI_AWUSER   : in  std_logic_vector(C_M_AXI_AWUSER_WIDTH-1 downto 0);
    M_AXI_AWVALID  : in  std_logic;
    M_AXI_AWREADY  : out std_logic;

    -- Master Interface Write Data Ports
    M_AXI_WDATA  : in  std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
    M_AXI_WSTRB  : in  std_logic_vector(C_M_AXI_DATA_WIDTH/8-1 downto 0);
    M_AXI_WLAST  : in  std_logic;
    M_AXI_WUSER  : in  std_logic_vector(C_M_AXI_WUSER_WIDTH-1 downto 0);
    M_AXI_WVALID : in  std_logic;
    M_AXI_WREADY : out std_logic;

    -- Master Interface Write Response Ports
    M_AXI_BID    : out std_logic_vector(C_M_AXI_ID_WIDTH-1 downto 0);
    M_AXI_BRESP  : out std_logic_vector(2-1 downto 0);
    M_AXI_BUSER  : out std_logic_vector(C_M_AXI_BUSER_WIDTH-1 downto 0);
    M_AXI_BVALID : out std_logic;
    M_AXI_BREADY : in  std_logic;

    -- Master Interface Read Address Ports
    M_AXI_ARID     : in  std_logic_vector(C_M_AXI_ID_WIDTH-1 downto 0);
    M_AXI_ARADDR   : in  std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
    M_AXI_ARLEN    : in  std_logic_vector(8-1 downto 0);
    M_AXI_ARSIZE   : in  std_logic_vector(3-1 downto 0);
    M_AXI_ARBURST  : in  std_logic_vector(2-1 downto 0);
    M_AXI_ARLOCK   : in  std_logic_vector(2-1 downto 0);
    M_AXI_ARCACHE  : in  std_logic_vector(4-1 downto 0);
    M_AXI_ARPROT   : in  std_logic_vector(3-1 downto 0);
    M_AXI_ARQOS    : in  std_logic_vector(4-1 downto 0);
    M_AXI_ARUSER   : in  std_logic_vector(C_M_AXI_ARUSER_WIDTH-1 downto 0);
    M_AXI_ARVALID  : in  std_logic;
    M_AXI_ARREADY  : out std_logic;

    -- Master Interface Read Data Ports
    M_AXI_RID    : out std_logic_vector(C_M_AXI_ID_WIDTH-1 downto 0);
    M_AXI_RDATA  : out std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
    M_AXI_RRESP  : out std_logic_vector(2-1 downto 0);
    M_AXI_RLAST  : out std_logic;
    M_AXI_RUSER  : out std_logic_vector(C_M_AXI_RUSER_WIDTH-1 downto 0);
    M_AXI_RVALID : out std_logic;
    M_AXI_RREADY : in  std_logic
    );

end axi_slave_bfm;

architecture implementation of axi_slave_bfm is

constant    AxBURST_FIXED    : std_logic_vector := "00";
constant    AxBURST_INCR    : std_logic_vector := "01";
constant    AxBURST_WRAP    : std_logic_vector := "10";

constant    RESP_OKAY        : std_logic_vector := "00";
constant    RESP_EXOKAY        : std_logic_vector := "01";
constant    RESP_SLVERR        : std_logic_vector := "10";
constant    RESP_DECERR        : std_logic_vector := "11";

constant    DATA_BUS_BYTES     : natural := C_M_AXI_DATA_WIDTH/8; -- データバスのビット幅
constant    ADD_INC_OFFSET    : natural := natural(log(real(DATA_BUS_BYTES), 2.0));

-- RAMの生成
constant    SLAVE_ADDR_NUMBER    : integer := 2**(C_OFFSET_WIDTH - ADD_INC_OFFSET);
type ram_array_def is array (SLAVE_ADDR_NUMBER-1 downto 0) of std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
signal ram_array : ram_array_def := (others => (others => '0'));

-- for write transaction
type write_transaction_state is (idle_wr, awr_wait, awr_accept, wr_burst, wr_bvalid_assert);
type write_response_state is (idle_wres, bvalid_assert);
type write_wready_state is (idle_wrdy, wready_assert);
signal wrt_cs : write_transaction_state;
signal wrres : write_response_state;
signal wrwr : write_wready_state;
signal addr_inc_step_wr : integer := 1;
signal awready         : std_logic;
signal wr_addr         : std_logic_vector(C_OFFSET_WIDTH-1 downto 0);
signal wr_bid         : std_logic_vector(C_M_AXI_ID_WIDTH-1 downto 0);
signal wr_bresp     : std_logic_vector(1 downto 0);
signal wr_bvalid     : std_logic;
signal m_seq16_wr    : std_logic_vector(15 downto 0);
signal wready        : std_logic;
type wready_state is (idle_wready, assert_wready, deassert_wready);
signal cs_wready : wready_state;
signal cdc_we : std_logic;

-- for read transaction
type read_transaction_state is (idle_rd, arr_wait, arr_accept, rd_burst);
type read_last_state is (idle_rlast, rlast_assert);
signal rdt_cs : read_transaction_state;
signal rdlast : read_last_state;
signal addr_inc_step_rd : integer := 1;
signal arready         : std_logic;
signal rd_addr         : std_logic_vector(C_OFFSET_WIDTH-1 downto 0);
signal rd_axi_count    : std_logic_vector(7 downto 0);
signal rvalid        : std_logic;
signal rlast        : std_logic;
signal m_seq16_rd    : std_logic_vector(15 downto 0);
type rvalid_state is (idle_rvalid, assert_rvalid, deassert_rvalid);
signal cs_rvalid : rvalid_state;

signal reset_1d, reset_2d, reset : std_logic := '1';
signal bvalid_cnt : std_logic_vector(3 downto 0);

begin
    -- ARESETN をACLK で同期化
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            reset_1d <= not ARESETN;
            reset_2d <= reset_1d;
        end if;
    end process;
    reset <= reset_2d;
    
    -- AXI4バス Write Transaction State Machine
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                wrt_cs <= idle_wr;
                awready <= '0';
            else
                case (wrt_cs) is
                    when idle_wr =>
                        if M_AXI_AWVALID='1' then -- M_AXI_AWVALID が1にアサートされた
                            if rdt_cs=idle_rd then -- Read Transaction が終了している(Writeの方が優先順位が高い)
                                wrt_cs <= awr_accept;
                                awready <= '1';
                            else -- Read Transaction が終了していないのでWait
                                wrt_cs <= awr_wait;
                            end if;
                        end if;
                    when awr_wait => -- Read Transaction の終了待ち
                        if rdt_cs=idle_rd or rdt_cs=arr_wait then -- Read Transaction が終了
                            wrt_cs <= awr_accept;
                            awready <= '1';
                        end if;
                    when awr_accept => -- M_AXI_AWREADY をアサート
                        wrt_cs <= wr_burst;
                        awready <= '0';
                    when wr_burst => -- Writeデータの転送
                        if M_AXI_WLAST='1' and M_AXI_WVALID='1' and wready='1' then -- Write Transaction 終了
                            wrt_cs <= wr_bvalid_assert;
                        end if;
                    when wr_bvalid_assert => -- M_AXI_BVALID アサート
                        if wr_bvalid='1' and M_AXI_BREADY='1' then -- wr_bvalid が1でMaster側のReadyも1ならばWrite resonse channel の転送も終了
                            wrt_cs <= idle_wr;
                        end if;
                end case;
            end if;
        end if;
    end process;
    M_AXI_AWREADY <= awready;
    
    -- m_seq_wr、16ビットのM系列を計算する
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                m_seq16_wr <= (0 => '1', others => '0');
            else
                if WRITE_RANDOM_WAIT=1 then -- Write Transaction 時にランダムなWaitを挿入する
                    if wrt_cs=wr_burst and M_AXI_WVALID='1' then
                        m_seq16_wr <= M_SEQ16_BFM_F(m_seq16_wr);
                    end if;
                else -- Wait無し
                    m_seq16_wr <= (others => '0');
                end if;
            end if;
        end if;
    end process;
                
    -- wready の処理、M系列を計算して128以上だったらWaitする。
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                cs_wready <= idle_wready;
                wready <= '0';
            else
                case (cs_wready) is
                    when idle_wready =>
                        if wrt_cs=awr_accept then -- 次はwr_burst
                            if m_seq16_wr(7)='0' then -- wready='1'
                                cs_wready <= assert_wready;
                                wready <= '1';
                            else -- m_seq16_wr(7)='1' then -- wready='0'
                                cs_wready <= deassert_wready;
                                wready <= '0';
                            end if;
                        end if;
                    when assert_wready => -- 一度wreadyがアサートされたら、1つのトランザクションが終了するまでwready='1'
                        if wrt_cs=wr_burst and M_AXI_WLAST='1' and M_AXI_WVALID='1' then -- 終了
                            cs_wready <= idle_wready;
                            wready <= '0';
                        elsif wrt_cs=wr_burst and M_AXI_WVALID='1' then -- 1つのトランザクション終了。
                            if m_seq16_wr(7)='1' then
                                cs_wready <= deassert_wready;
                                wready <= '0';
                            end if;
                        end if;
                    when deassert_wready =>
                        if m_seq16_wr(7)='0' then -- wready='1'
                            cs_wready <= assert_wready;
                            wready <= '1';
                        end if;
                end case;
            end if;
        end if;
    end process;
    
    M_AXI_WREADY <= wready;
    cdc_we <= '1' when wrt_cs=wr_burst and wready='1' and M_AXI_WVALID='1' else '0';
    
    -- addr_inc_step_wr の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                addr_inc_step_wr <= 1;
            else
                if wrt_cs=awr_accept then
                    case (M_AXI_AWSIZE) is
                        when "000" => -- 8ビット転送
                            addr_inc_step_wr <= 1;
                        when "001" => -- 16ビット転送
                            addr_inc_step_wr <= 2;
                        when "010" => -- 32ビット転送
                            addr_inc_step_wr <= 4;
                        when "011" => -- 64ビット転送
                            addr_inc_step_wr <= 8;
                        when "100" => -- 128ビット転送
                            addr_inc_step_wr <= 16;
                        when "101" => -- 256ビット転送
                            addr_inc_step_wr <= 32;
                        when "110" => -- 512ビット転送
                            addr_inc_step_wr <= 64;
                        when others => --"111" => -- 1024ビット転送
                            addr_inc_step_wr <= 128;
                    end case;
                end if;
            end if;
        end if;
    end process;
    
    -- wr_addr の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                wr_addr <= (others => '0');
            else
                if wrt_cs=awr_accept then
                    wr_addr <= M_AXI_AWADDR(C_OFFSET_WIDTH-1 downto 0);
                elsif wrt_cs=wr_burst and M_AXI_WVALID='1' and wready='1' then -- アドレスを進める
                    wr_addr <= wr_addr + addr_inc_step_wr;
                end if;
            end if;
        end if;
    end process;
    
    -- wr_bid の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                wr_bid <= "0";
            else
                if wrt_cs=awr_accept then
                    wr_bid <= M_AXI_AWID;
                end if;
            end if;
        end if;
    end process;
    M_AXI_BID <= wr_bid;
    
    -- wr_bresp の処理
    -- M_AXI_AWBURSTがINCRの時はOKAYを返す。それ以外はSLVERRを返す。
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                wr_bresp <= (others => '0');
            else
                if wrt_cs=awr_accept then
                    if M_AXI_AWBURST=AxBURST_INCR then -- バーストタイプがアドレス・インクリメントタイプ
                        wr_bresp <= RESP_OKAY; -- Write Transaction は成功
                    else
                        wr_bresp <= RESP_SLVERR; -- エラー
                    end if;
                end if;
            end if;
        end if;
    end process;
    M_AXI_BRESP <= wr_bresp;
    
    -- wr_bvalid の処理
    -- WR_BVALID_RANDOM_WAIT が1の時にランダムにWait、0の時は1クロックWait
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                bvalid_cnt <= (others => '0');
            else
                if WR_BVALID_RANDOM_WAIT=1 then -- ランダムWait
                    if M_AXI_WLAST='1' and M_AXI_WVALID='1' and wready='1' then -- Write Transaction 終了
                        bvalid_cnt <= m_seq16_wr(3 downto 0); -- 0 ~ 15 wait
                    elsif bvalid_cnt /= 0 then
                        bvalid_cnt <= bvalid_cnt - 1;
                    end if;
                else
                    bvalid_cnt <= (others => '0');
                end if;
            end if;
        end if;
    end process;
        
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                wr_bvalid <= '0';
            else
                if wr_bvalid='1' and M_AXI_BREADY='1' then -- wr_bvalid が1でMaster側のReadyも1ならばWrite resonse channel の転送も終了
                    wr_bvalid <= '0';
                elsif wrt_cs=wr_bvalid_assert and bvalid_cnt=0 then -- Write Transaction 終了
                    wr_bvalid <= '1';
                end if;
            end if;
        end if;
    end process;
    M_AXI_BVALID <= wr_bvalid;
    M_AXI_BUSER <= (others => '0');
    
    
    -- AXI4バス Read Transaction State Machine
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                rdt_cs <= idle_rd;
                arready <= '0';
            else
                case (rdt_cs) is
                    when idle_rd =>
                        if M_AXI_ARVALID='1' then -- Read Transaction 要求
                            if wrt_cs=idle_wr and M_AXI_AWVALID='0' then -- Write Transaction State Machine がidle でWrite要求もない
                                rdt_cs <= arr_accept;
                                arready <= '1';
                            else -- Write Transaction が終了していないのでWait
                                rdt_cs <= arr_wait;
                            end if;
                        end if;
                    when arr_wait => -- Write Transaction の終了待ち
                        if wrt_cs=idle_wr and M_AXI_AWVALID='0' then -- Write Transaction State Machine がidle でWrite要求もない
                            rdt_cs <= arr_accept;
                            arready <= '1';
                        end if;
                    when arr_accept => -- M_AXI_ARREADY をアサート
                        rdt_cs <= rd_burst;
                        arready <= '0';
                    when rd_burst => -- Readデータの転送
                        if rd_axi_count=0 and rvalid='1' and M_AXI_RREADY='1' then -- Read Transaction 終了
                            rdt_cs <= idle_rd;
                        end if;
                end case;
            end if;
        end if;
    end process;
    M_AXI_ARREADY <= arready;

    -- m_seq_rd、16ビットのM系列を計算する
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                m_seq16_rd <= (others => '1'); -- Writeとシードを変更する
            else
                if READ_RANDOM_WAIT=1 then -- Read Transaciton のデータ転送でランダムなWaitを挿入する場合
                    if rdt_cs=rd_burst and M_AXI_RREADY='1' then
                        m_seq16_rd <= M_SEQ16_BFM_F(m_seq16_rd);
                    end if;
                else -- Wati無し
                    m_seq16_rd <= (others => '0');
                end if;
            end if;
        end if;
    end process;
                
    -- rvalid の処理、M系列を計算して128以上だったらWaitする。
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                cs_rvalid <= idle_rvalid;
                rvalid <= '0';
            else
                case (cs_rvalid) is
                    when idle_rvalid =>
                        if rdt_cs=arr_accept then -- 次はrd_burst
                            if m_seq16_rd(7)='0' then -- rvalid='1'
                                cs_rvalid <= assert_rvalid;
                                rvalid <= '1';
                            else -- m_seq16_rd(7)='1' then -- rvalid='0'
                                cs_rvalid <= deassert_rvalid;
                                rvalid <= '0';
                            end if;
                        end if;
                    when assert_rvalid => -- 一度rvalidがアサートされたら、1つのトランザクションが終了するまでrvalid='1'
                        if rdt_cs=rd_burst and rlast='1' and M_AXI_RREADY='1' then -- 終了
                            cs_rvalid <= idle_rvalid;
                            rvalid <= '0';
                        elsif rdt_cs=rd_burst and M_AXI_RREADY='1' then -- 1つのトランザクション終了。
                            if m_seq16_rd(7)='1' then
                                cs_rvalid <= deassert_rvalid;
                                rvalid <= '0';
                            end if;
                        end if;
                    when deassert_rvalid =>
                        if m_seq16_rd(7)='0' then -- rvalid='1'
                            cs_rvalid <= assert_rvalid;
                            rvalid <= '1';
                        end if;
                end case;
            end if;
        end if;
    end process;
    
    M_AXI_RVALID <= rvalid;
    
    -- addr_inc_step_rd の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                addr_inc_step_rd <= 1;
            else
                if rdt_cs=arr_accept then
                    case (M_AXI_ARSIZE) is
                        when "000" => -- 8ビット転送
                            addr_inc_step_rd <= 1;
                        when "001" => -- 16ビット転送
                            addr_inc_step_rd <= 2;
                        when "010" => -- 32ビット転送
                            addr_inc_step_rd <= 4;
                        when "011" => -- 64ビット転送
                            addr_inc_step_rd <= 8;
                        when "100" => -- 128ビット転送
                            addr_inc_step_rd <= 16;
                        when "101" => -- 256ビット転送
                            addr_inc_step_rd <= 32;
                        when "110" => -- 512ビット転送
                            addr_inc_step_rd <= 64;
                        when others => -- "111" => -- 1024ビット転送
                            addr_inc_step_rd <= 128;
                    end case;
                end if;
            end if;
        end if;
    end process;
    
    -- rd_addr の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                rd_addr <= (others => '0');
            else
                if rdt_cs=arr_accept then
                    rd_addr <= M_AXI_ARADDR(C_OFFSET_WIDTH-1 downto 0);
                elsif rdt_cs=rd_burst and M_AXI_RREADY='1' and rvalid='1' then
                    rd_addr <= rd_addr + addr_inc_step_rd;
                end if;
            end if;
        end if;
    end process;
    
    -- rd_axi_count の処理(AXIバス側のデータカウント)
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                rd_axi_count <= (others => '0');
            else
                if rdt_cs=arr_accept then -- rd_axi_count のロード
                    rd_axi_count <= M_AXI_ARLEN;
                elsif rdt_cs=rd_burst and rvalid='1' and M_AXI_RREADY='1' then -- Read Transaction が1つ終了
                    rd_axi_count <= rd_axi_count - 1;
                end if;
            end if;
        end if;
    end process;
    
    -- rdlast State Machine
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                rdlast <= idle_rlast;
                rlast <= '0';
            else
                case (rdlast) is
                    when idle_rlast =>
                        if rd_axi_count=1 and rvalid='1' and M_AXI_RREADY='1' then -- バーストする場合
                            rdlast <= rlast_assert;
                            rlast <= '1';
                        elsif rdt_cs=arr_accept and M_AXI_ARLEN=0 then -- 転送数が1の場合
                            rdlast <= rlast_assert;
                            rlast <= '1';
                        end if;
                    when rlast_assert => 
                        if rvalid='1' and M_AXI_RREADY='1' then -- Read Transaction 終了(rd_axi_count=0は決定)
                            rdlast <= idle_rlast;
                            rlast <= '0';
                        end if;
                end case;
            end if;
        end if;
    end process;
    M_AXI_RLAST <= rlast;
    
    -- M_AXI_RID, M_AXI_RUSER の処理
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                M_AXI_RID <= (others => '0');
            else
                if rdt_cs=arr_accept then
                    M_AXI_RID <= M_AXI_ARID;
                end if;
            end if;
        end if;
    end process;
    M_AXI_RUSER <= (others => '0');
    
    -- M_AXI_RRESP は、M_AXI_ARBURST がINCR の場合はOKAYを返す。それ以外はSLVERRを返す。
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if reset='1' then
                M_AXI_RRESP <= (others => '0');
            else
                if rdt_cs=arr_accept then
                    if M_AXI_ARBURST=AxBURST_INCR then
                        M_AXI_RRESP <= RESP_OKAY;
                    else
                        M_AXI_RRESP <= RESP_SLVERR;
                    end if;
                end if;
            end if;
        end if;
    end process;
    
    -- RAM
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            if cdc_we='1' then
                for i in 0 to C_M_AXI_DATA_WIDTH/8-1 loop
                    if M_AXI_WSTRB(i)='1' then -- Byte Enable
                        ram_array(CONV_INTEGER(wr_addr(C_OFFSET_WIDTH-1 downto ADD_INC_OFFSET)))(i*8+7 downto i*8) <= M_AXI_WDATA(i*8+7 downto i*8);
                    end if;
                end loop;
            end if;
        end if;
    end process;
    M_AXI_RDATA <= ram_array(CONV_INTEGER(rd_addr(C_OFFSET_WIDTH-1 downto ADD_INC_OFFSET)));

end implementation;

  1. 2013年01月03日 17:18 |
  2. ZedBoard
  3. | トラックバック:0
  4. | コメント:0

ZedBoard用CMOSカメラ回路の作製2(HDLソースの公開1)

ZedBoard用CMOSカメラ回路の作製1(単体シミュレーション)”でシミュレーションを行ったHDLソースを公開します。バグなどで、予告なく修正する場合があります。なお、無保証です。

最初に、トップのmt9d111_inf_axi_master.vhd です。(2013/01/23:修正)(2013/02/10:修正)

-------------------------------------------------------------------------------
--
-- AXI Master
--
-- VHDL-Standard:   VHDL'93
----------------------------------------------------------------------------
--
-- Structure:
--   mt9d111_inf_axi_master
--
----------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;

--library unisim;
--use unisim.vcomponents.all;

entity mt9d111_inf_axi_master is
  generic(
    C_M_AXI_SUPPORTS_THREADS            : integer := 0;
    C_M_AXI_THREAD_ID_WIDTH             : integer := 1;
    C_M_AXI_ADDR_WIDTH                     : integer := 32;
    C_M_AXI_DATA_WIDTH                     : integer := 64;
    C_INTERCONNECT_M_AXI_WRITE_ISSUING    : integer := 8;
    C_INTERCONNECT_M_AXI_READ_ISSUING    : integer := 8;
    C_M_AXI_SUPPORTS_READ                : integer := 0;
    C_M_AXI_SUPPORTS_WRITE                : integer := 1;
    C_M_AXI_SUPPORTS_USER_SIGNALS        : integer := 0;
    C_M_AXI_AWUSER_WIDTH                : integer := 1;
    C_M_AXI_ARUSER_WIDTH                : integer := 1;
    C_M_AXI_WUSER_WIDTH                 : integer := 1;
    C_M_AXI_RUSER_WIDTH                 : integer := 1;
    C_M_AXI_BUSER_WIDTH                 : integer := 1;
    C_M_AXI_SUPPORTS_NARROW_BURST        : integer := 0;
    C_M_AXI_TARGET                        : std_logic_vector(31 downto 0) := x"00000000";
    C_M_AXI_BURST_LEN                    : integer := 16;
    C_OFFSET_WIDTH                        : integer := 9;
    
    C_DISPLAY_START_ADDRESS                : std_logic_vector(31 downto 0) := x"10000000";
    C_UPSIDE_DOWN                        : integer := 0    -- 1 = 上下反転、0 = 正常
  );
  port(
    -- System Signals
    ACLK    : in std_logic;
    ARESETN : in std_logic;

    -- Master Interface Write Address
    M_AXI_AWID    : out std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
    M_AXI_AWADDR  : out std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
    M_AXI_AWLEN   : out std_logic_vector(8-1 downto 0);
    M_AXI_AWSIZE  : out std_logic_vector(3-1 downto 0);
    M_AXI_AWBURST : out std_logic_vector(2-1 downto 0);
    M_AXI_AWLOCK  : out std_logic;
    M_AXI_AWCACHE : out std_logic_vector(4-1 downto 0);
    M_AXI_AWPROT  : out std_logic_vector(3-1 downto 0);
    -- AXI3    M_AXI_AWREGION:out std_logic_vector(4-1 downto 0);
    M_AXI_AWQOS   : out std_logic_vector(4-1 downto 0);
    M_AXI_AWUSER  : out std_logic_vector(C_M_AXI_AWUSER_WIDTH-1 downto 0);
    M_AXI_AWVALID : out std_logic;
    M_AXI_AWREADY : in  std_logic;

    -- Master Interface Write Data
    -- AXI3   M_AXI_WID(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
    M_AXI_WDATA  : out std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
    M_AXI_WSTRB  : out std_logic_vector(C_M_AXI_DATA_WIDTH/8-1 downto 0);
    M_AXI_WLAST  : out std_logic;
    M_AXI_WUSER  : out std_logic_vector(C_M_AXI_WUSER_WIDTH-1 downto 0);
    M_AXI_WVALID : out std_logic;
    M_AXI_WREADY : in  std_logic;

    -- Master Interface Write Response
    M_AXI_BID    : in  std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
    M_AXI_BRESP  : in  std_logic_vector(2-1 downto 0);
    M_AXI_BUSER  : in  std_logic_vector(C_M_AXI_BUSER_WIDTH-1 downto 0);
    M_AXI_BVALID : in  std_logic;
    M_AXI_BREADY : out std_logic;

    -- Master Interface Read Address
    M_AXI_ARID    : out std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
    M_AXI_ARADDR  : out std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
    M_AXI_ARLEN   : out std_logic_vector(8-1 downto 0);
    M_AXI_ARSIZE  : out std_logic_vector(3-1 downto 0);
    M_AXI_ARBURST : out std_logic_vector(2-1 downto 0);
    M_AXI_ARLOCK  : out std_logic_vector(2-1 downto 0);
    M_AXI_ARCACHE : out std_logic_vector(4-1 downto 0);
    M_AXI_ARPROT  : out std_logic_vector(3-1 downto 0);
    -- AXI3   M_AXI_ARREGION:out std_logic_vector(4-1 downto 0);
    M_AXI_ARQOS   : out std_logic_vector(4-1 downto 0);
    M_AXI_ARUSER  : out std_logic_vector(C_M_AXI_ARUSER_WIDTH-1 downto 0);
    M_AXI_ARVALID : out std_logic;
    M_AXI_ARREADY : in  std_logic;

    -- Master Interface Read Data 
    M_AXI_RID    : in  std_logic_vector(C_M_AXI_THREAD_ID_WIDTH-1 downto 0);
    M_AXI_RDATA  : in  std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
    M_AXI_RRESP  : in  std_logic_vector(2-1 downto 0);
    M_AXI_RLAST  : in  std_logic;
    M_AXI_RUSER  : in  std_logic_vector(C_M_AXI_RUSER_WIDTH-1 downto 0);
    M_AXI_RVALID : in  std_logic;
    M_AXI_RREADY : out std_logic;

    init_done    : in std_logic;
    
    wr_error        : out std_logic;    -- AXI4 Write 時のエラー(M_AXI_BRESP/=RESP_OKAY)
    
    -- MT9D111 Camera Interface
    pclk_from_pll    : in    std_logic;    -- PLLからMT9D111のxck に出力するクロック
    pclk            : in     std_logic;    -- MT9D111からのピクセルクロック入力
    xck                : out    std_logic;    -- MT9D111へのピクセルクロック出力
    href            : in     std_logic;
    vsync            : in    std_logic;
    cam_data        : in    std_logic_vector(7 downto 0);
    standby            : out    std_logic;    -- STANDBY出力(ディスエーブル、0固定)
    pfifo_overflow    : out    std_logic;    -- pfifo overflow
    pfifo_underflow    : out    std_logic    -- pfifo underflow
);

end mt9d111_inf_axi_master;

-------------------------------------------------------------------------------
-- Architecture
-------------------------------------------------------------------------------
architecture implementation of mt9d111_inf_axi_master is
constant    RESP_OKAY        : std_logic_vector := "00";
constant    RESP_EXOKAY        : std_logic_vector := "01";
constant    RESP_SLVERR        : std_logic_vector := "10";
constant    RESP_DECERR        : std_logic_vector := "11";

constant    DDR3_START_ADDR    : std_logic_vector := x"10000000";

constant    ROW_ALL_PIXELS : integer := 640;
constant    COULMN_ALL_PIXELS : integer := 480;

constant    SVGA_ADDR_LIMIT : integer := ROW_ALL_PIXELS*COULMN_ALL_PIXELS*4; -- SVGAのアドレスリミット(横ピクセル数 * 縦ピクセル数 * 1ピクセルを表すバイト数)

signal reset_1d, reset_2d, reset : std_logic;
type wr_main_transaction_state is (idle_wr_main, write_state);
signal wr_main_cs, wr_main_1d : wr_main_transaction_state;
type write_transaction_state is (idle_wr, awvalid_assert, data_write_hold, bready_assert, wr_tran_end);
signal wrt_cs : write_transaction_state;
type write_wvalid_state is (idle_wvalid, wvalid_assert, wvalid_hold);
signal wrt_wv_cs : write_wvalid_state;

signal awvalid, wvalid, bready : std_logic;
signal awlen, write_count : std_logic_vector(7 downto 0);
signal wlast : std_logic;
signal preset_1d, preset_2d, preset : std_logic;
signal pfifo_empty        : std_logic;
signal pfifo_almost_empty    : std_logic;
signal pfifo_rd_data_count    : std_logic_vector(9 downto 0);
signal pfifo_rd_dcount_dec : unsigned(9 downto 0);
signal pfifo_rd_en : std_logic;

component mt9d111_cam_cont generic (
        DISPLAY_START_ADDRESS : std_logic_vector(31 downto 0) := x"10000000";
        UPSIDE_DOWN : integer := 0
    );
    port(
        aclk            : in std_logic;
        areset            : in std_logic;
        pclk            : in std_logic;
        preset            : in std_logic;
        pclk_from_pll    : in std_logic;
        xclk            : out std_logic;
        line_valid        : in std_logic;
        frame_valid        : in std_logic;
        cam_data        : in std_logic_vector(7 downto 0);
        standby            : out std_logic;
        paddr            : out std_logic_vector(31 downto 0);
        pfifo_rd_en        : in std_logic;
        pfifo_dout        : out std_logic_vector(63 downto 0);
        pfifo_empty        : out std_logic;
        pfifo_almost_empty        : out std_logic;
        pfifo_rd_data_count    : out std_logic_vector(9 downto 0);
        pfifo_overflow        : out std_logic;
        pfifo_underflow        : out std_logic
    ); 
end component;

begin
    -- ARESETN をACLK で同期化
    process (ACLK) begin
        if ACLK'event and ACLK='1' then 
            reset_1d <= not ARESETN or not init_done;
            reset_2d <= reset_1d;
        end if;
    end process;
    reset <= reset_2d;
    
    -- ARESETN をpclk で同期化
    process(pclk) begin
        if pclk'event and pclk='1' then
            preset_1d <= not ARESETN or not init_done;
            preset_2d <= preset_1d;
        end if;
    end process;
    preset <= preset_2d;
    
    -- Write Transaction State Machine
    -- ピクセルデータが存在する時(pfifo_empty=0)の時に、 Writeを行う。Readは無し
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                wr_main_cs <= idle_wr_main;
            else
                case (wr_main_cs) is
                    when idle_wr_main =>
                        if pfifo_rd_data_count/=std_logic_vector(to_unsigned(0, pfifo_rd_data_count'length)) then
                            wr_main_cs <= write_state;
                        end if;
                    when write_state =>
                        if wrt_cs = wr_tran_end then -- pfifo のピクセルデータをAXI4バス経由で転送終了
                            wr_main_cs <= idle_wr_main;
                        end if;
                end case;
            end if;
        end if;
    end process;
    
    pfifo_rd_en <= M_AXI_WREADY and wvalid;
    mt9d111_cam_cont_i : mt9d111_cam_cont generic map(
        DISPLAY_START_ADDRESS    => C_DISPLAY_START_ADDRESS,
        UPSIDE_DOWN                => C_UPSIDE_DOWN
    )port map(
        aclk                => ACLK,
        areset                => reset,
        pclk                => pclk,
        preset                => preset,
        pclk_from_pll        => pclk_from_pll,
        xclk                => xck,
        line_valid            => href,
        frame_valid            => vsync,
        cam_data            => cam_data,
        standby                => standby,
        paddr                => M_AXI_AWADDR,
        pfifo_rd_en            => pfifo_rd_en,
        pfifo_dout            => M_AXI_WDATA,
        pfifo_empty            => pfifo_empty,
        pfifo_almost_empty    => pfifo_almost_empty,
        pfifo_rd_data_count    => pfifo_rd_data_count,
        pfifo_overflow        => pfifo_overflow,
        pfifo_underflow        => pfifo_underflow
    );
        
    -- Write
    M_AXI_AWID        <= "0";
    M_AXI_AWSIZE     <= "011";    -- 8 bytes fixed
    M_AXI_AWBURST    <= "01";    -- INCR
    M_AXI_AWLOCK    <= '0';    -- Normal Access
    M_AXI_AWCACHE    <= "0010";    -- Normal Non-cacheable Non-bufferable
    -- M_AXI_AWCACHE    <= "0011";    -- Normal Non-cacheable Bufferable, Zynq-7020ではBRESPが10でSLVERRになってしまい設定してはならない。
    M_AXI_AWPROT    <= "000";    -- Data access, Secure access, Unprivileged access
    M_AXI_AWQOS        <= "0000";    -- default
    M_AXI_AWUSER    <= "0";
    M_AXI_WSTRB        <= (others => '1');
    M_AXI_WUSER        <= "0";
    M_AXI_AWLEN        <= awlen;
    
    -- AXI4バス Write Transaction State Machine
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                wrt_cs <= idle_wr;
                awvalid <= '0';
                bready <= '0';
            else 
                case(wrt_cs) is
                    when idle_wr =>
                        if wr_main_cs = write_state then
                            wrt_cs <= awvalid_assert;
                            awvalid <= '1';
                        end if;
                    when awvalid_assert =>
                        if M_AXI_AWREADY='1' then
                            if wrt_wv_cs=wvalid_hold or (wrt_wv_cs=wvalid_assert and unsigned(write_count)=0 and M_AXI_WREADY='1') then
                                wrt_cs <= bready_assert;
                                bready <= '1';
                            else
                                wrt_cs <= data_write_hold;
                            end if;
                            awvalid <= '0';
                        end if;
                    when data_write_hold =>
                        if wrt_wv_cs=wvalid_hold or (wrt_wv_cs=wvalid_assert and unsigned(write_count)=0 and M_AXI_WREADY='1') then
                            wrt_cs <= bready_assert;
                            bready <= '1';
                        end if;
                    when bready_assert =>
                        if M_AXI_BVALID='1' then
                            wrt_cs <= wr_tran_end;
                            bready <= '0';
                        end if;
                    when wr_tran_end =>
                        wrt_cs <= idle_wr;
                end case;
            end if;
        end if;
    end process;
    -- AXI4 バス Write Transaction WVALID State Machine
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                wrt_wv_cs <= idle_wvalid;
                wvalid <= '0';
            else 
                case(wrt_wv_cs) is
                    when idle_wvalid =>
                        if wrt_cs=awvalid_assert then
                            wrt_wv_cs <= wvalid_assert;
                            wvalid <= '1';
                        end if;
                    when wvalid_assert =>
                        if unsigned(write_count)=0 and M_AXI_WREADY='1' then -- 終了
                            wrt_wv_cs <= wvalid_hold;
                            wvalid <= '0';
                        end if;
                    when wvalid_hold =>
                        if wrt_cs=bready_assert then
                            wrt_wv_cs <= idle_wvalid;
                        end if;
                end case;
            end if;
        end if;
    end process;
    
    M_AXI_AWVALID    <= awvalid;
    M_AXI_WVALID    <= wvalid;
    M_AXI_BREADY    <= bready;
    
    -- write_count の処理
    pfifo_rd_dcount_dec <= unsigned(pfifo_rd_data_count) - 1;
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                write_count <= (others => '0');
                awlen <= (others => '0');
            else
                if wr_main_cs = write_state and wrt_cs=idle_wr then -- wr_main_cs がwrite_state になった最初の1クロック
                    if C_UPSIDE_DOWN = 0 then -- 正常表示の場合
                        write_count <= std_logic_vector(pfifo_rd_dcount_dec(7 downto 0));
                        awlen <= std_logic_vector(pfifo_rd_dcount_dec(7 downto 0));
                    else -- 上下反転する場合はシングル転送
                        write_count <= std_logic_vector(to_unsigned(0, write_count'length));
                        awlen <= std_logic_vector(to_unsigned(0, awlen'length));
                    end if;    
                elsif wrt_wv_cs=wvalid_assert and M_AXI_WREADY='1' and unsigned(write_count)/=0 then -- 1つデータ転送出来た
                    write_count <= std_logic_vector(unsigned(write_count) - 1);
                end if;
            end if;
        end if;
    end process;
    
    -- wlastの処理
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                wlast <= '0';
            else
                if wr_main_cs = write_state and wrt_cs=idle_wr then -- Wrire Transaction を開始する際に、
                    if C_UPSIDE_DOWN = 0 then -- 正常表示の場合
                        if unsigned(pfifo_rd_data_count)=1 then -- pfifo_rd_data_count が1の時はデータ転送の最初からwlast をアサートする
                            wlast <= '1';
                        end if;
                    else -- 上下反転する場合はシングル転送
                        wlast <= '1';
                    end if;
                elsif wrt_wv_cs=wvalid_assert and unsigned(write_count)=1 and M_AXI_WREADY='1' then -- awlen が0で無い時はwrite_count が1でM_AXI_WREADY='1'の時、つまりwrite_count が0の時にwlastをアサートする
                    wlast <= '1';
                elsif wrt_wv_cs=wvalid_assert and unsigned(write_count)=0 and M_AXI_WREADY='1' then -- データ転送が終了なのでwlast を0にする
                    wlast <= '0';
                end if;
            end if;
        end if;
    end process;
    M_AXI_WLAST <= wlast;
    
    -- wr_error の処理、M_AXI_BRESPがRESP_OKAY以外の時にwr_errorを点灯する
    process(ACLK) begin
        if ACLK'event and ACLK='1' then
            if reset='1' then
                wr_error <= '0';
            else
                if wrt_cs=bready_assert and M_AXI_BVALID='1' and M_AXI_BRESP/=RESP_OKAY then
                    wr_error <= '1';
                end if;
            end if;
        end if;
    end process;
    
    -- Readは無し
    M_AXI_ARID        <= "0";
    M_AXI_ARLEN        <= (others => '0');
    M_AXI_ARSIZE    <= "010";    -- 4bytes
    M_AXI_ARBURST    <= "01";    -- INCR
    M_AXI_ARLOCK    <= "00";    -- Normal Access
    M_AXI_ARCACHE    <= "0010";    -- Normal Non-cacheable Non-bufferable
    M_AXI_ARPROT    <= "000";    -- Data access, Secure access, Unprivileged access
    M_AXI_ARQOS        <= "0000";    -- default
    M_AXI_ARUSER    <= "0";
    M_AXI_ARADDR    <= (others => '0');
    M_AXI_ARVALID    <= '0';
    M_AXI_RREADY    <= '0';

end implementation;


次に、下位モジュールのmt9d111_cam_cont.v を貼っておきます。(2013/01/23:修正)

// MT9D111カメラコントローラ
// MT9D111_cam_cont.v
// 2012/12/26
// 

`default_nettype none

module mt9d111_cam_cont # (
    parameter    DISPLAY_START_ADDRESS = 32'h10000000,    // Frame Buffer Start Address
    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
);
    `include "./disp_timing_parameters.vh"
    
    // Frame Buffer End Address
    localparam    DISPLAY_END_ADDRESS    = DISPLAY_START_ADDRESS + (H_ACTIVE_VIDEO * V_ACTIVE_VIDEO)*4 - 8; // 最後のピクセル、1ピクセル = 4バイトで、64ビットバス幅なので、8バイトごと
    
    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;

    
    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
    
    // frame_valid_1d を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;
            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 (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 <= DISPLAY_START_ADDRESS;
            else // 上下反転
                paddr_reg <= DISPLAY_END_ADDRESS;
        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 <= DISPLAY_START_ADDRESS;
                else // 上下反転
                    paddr_reg <= DISPLAY_END_ADDRESS;
            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 <= 32'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


最後に、pixel_fifo.xco です。(2013/01/23:修正)

##############################################################
#
# Xilinx Core Generator version 14.4
# Date: Wed Jan 16 12:27:21 2013
#
##############################################################
#
# This file contains the customisation parameters for a
# Xilinx CORE Generator IP GUI. It is strongly recommended
# that you do not manually alter this file as it may cause
# unexpected and unsupported behavior.
#
##############################################################
#
# Generated from component: xilinx.com:ip:fifo_generator:9.3
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = Verilog
SET device = xc7z020
SET devicefamily = zynq
SET flowvendor = Other
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = clg484
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -1
SET verilogsim = true
SET vhdlsim = false
# END Project Options
# BEGIN Select
SELECT FIFO_Generator xilinx.com:ip:fifo_generator:9.3
# END Select
# BEGIN Parameters
CSET add_ngc_constraint_axi=false
CSET almost_empty_flag=true
CSET almost_full_flag=true
CSET aruser_width=1
CSET awuser_width=1
CSET axi_address_width=32
CSET axi_data_width=64
CSET axi_type=AXI4_Stream
CSET axis_type=FIFO
CSET buser_width=1
CSET clock_enable_type=Slave_Interface_Clock_Enable
CSET clock_type_axi=Common_Clock
CSET component_name=pixel_fifo
CSET data_count=false
CSET data_count_width=9
CSET disable_timing_violations=false
CSET disable_timing_violations_axi=false
CSET dout_reset_value=0
CSET empty_threshold_assert_value=4
CSET empty_threshold_assert_value_axis=1022
CSET empty_threshold_assert_value_rach=1022
CSET empty_threshold_assert_value_rdch=1022
CSET empty_threshold_assert_value_wach=1022
CSET empty_threshold_assert_value_wdch=1022
CSET empty_threshold_assert_value_wrch=1022
CSET empty_threshold_negate_value=5
CSET enable_aruser=false
CSET enable_awuser=false
CSET enable_buser=false
CSET enable_common_overflow=false
CSET enable_common_underflow=false
CSET enable_data_counts_axis=false
CSET enable_data_counts_rach=false
CSET enable_data_counts_rdch=false
CSET enable_data_counts_wach=false
CSET enable_data_counts_wdch=false
CSET enable_data_counts_wrch=false
CSET enable_ecc=false
CSET enable_ecc_axis=false
CSET enable_ecc_rach=false
CSET enable_ecc_rdch=false
CSET enable_ecc_wach=false
CSET enable_ecc_wdch=false
CSET enable_ecc_wrch=false
CSET enable_read_channel=false
CSET enable_read_pointer_increment_by2=false
CSET enable_reset_synchronization=true
CSET enable_ruser=false
CSET enable_tdata=false
CSET enable_tdest=false
CSET enable_tid=false
CSET enable_tkeep=false
CSET enable_tlast=false
CSET enable_tready=true
CSET enable_tstrobe=false
CSET enable_tuser=false
CSET enable_write_channel=false
CSET enable_wuser=false
CSET fifo_application_type_axis=Data_FIFO
CSET fifo_application_type_rach=Data_FIFO
CSET fifo_application_type_rdch=Data_FIFO
CSET fifo_application_type_wach=Data_FIFO
CSET fifo_application_type_wdch=Data_FIFO
CSET fifo_application_type_wrch=Data_FIFO
CSET fifo_implementation=Independent_Clocks_Block_RAM
CSET fifo_implementation_axis=Common_Clock_Block_RAM
CSET fifo_implementation_rach=Common_Clock_Distributed_RAM
CSET fifo_implementation_rdch=Common_Clock_Block_RAM
CSET fifo_implementation_wach=Common_Clock_Distributed_RAM
CSET fifo_implementation_wdch=Common_Clock_Block_RAM
CSET fifo_implementation_wrch=Common_Clock_Distributed_RAM
CSET full_flags_reset_value=1
CSET full_threshold_assert_value=511
CSET full_threshold_assert_value_axis=1023
CSET full_threshold_assert_value_rach=1023
CSET full_threshold_assert_value_rdch=1023
CSET full_threshold_assert_value_wach=1023
CSET full_threshold_assert_value_wdch=1023
CSET full_threshold_assert_value_wrch=1023
CSET full_threshold_negate_value=510
CSET id_width=4
CSET inject_dbit_error=false
CSET inject_dbit_error_axis=false
CSET inject_dbit_error_rach=false
CSET inject_dbit_error_rdch=false
CSET inject_dbit_error_wach=false
CSET inject_dbit_error_wdch=false
CSET inject_dbit_error_wrch=false
CSET inject_sbit_error=false
CSET inject_sbit_error_axis=false
CSET inject_sbit_error_rach=false
CSET inject_sbit_error_rdch=false
CSET inject_sbit_error_wach=false
CSET inject_sbit_error_wdch=false
CSET inject_sbit_error_wrch=false
CSET input_data_width=64
CSET input_depth=512
CSET input_depth_axis=1024
CSET input_depth_rach=16
CSET input_depth_rdch=1024
CSET input_depth_wach=16
CSET input_depth_wdch=1024
CSET input_depth_wrch=16
CSET interface_type=Native
CSET output_data_width=64
CSET output_depth=512
CSET overflow_flag=true
CSET overflow_flag_axi=false
CSET overflow_sense=Active_High
CSET overflow_sense_axi=Active_High
CSET performance_options=First_Word_Fall_Through
CSET programmable_empty_type=No_Programmable_Empty_Threshold
CSET programmable_empty_type_axis=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rach=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rdch=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wach=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wdch=No_Programmable_Empty_Threshold
CSET programmable_empty_type_wrch=No_Programmable_Empty_Threshold
CSET programmable_full_type=No_Programmable_Full_Threshold
CSET programmable_full_type_axis=No_Programmable_Full_Threshold
CSET programmable_full_type_rach=No_Programmable_Full_Threshold
CSET programmable_full_type_rdch=No_Programmable_Full_Threshold
CSET programmable_full_type_wach=No_Programmable_Full_Threshold
CSET programmable_full_type_wdch=No_Programmable_Full_Threshold
CSET programmable_full_type_wrch=No_Programmable_Full_Threshold
CSET rach_type=FIFO
CSET rdch_type=FIFO
CSET read_clock_frequency=1
CSET read_data_count=true
CSET read_data_count_width=10
CSET register_slice_mode_axis=Fully_Registered
CSET register_slice_mode_rach=Fully_Registered
CSET register_slice_mode_rdch=Fully_Registered
CSET register_slice_mode_wach=Fully_Registered
CSET register_slice_mode_wdch=Fully_Registered
CSET register_slice_mode_wrch=Fully_Registered
CSET reset_pin=true
CSET reset_type=Asynchronous_Reset
CSET ruser_width=1
CSET synchronization_stages=2
CSET synchronization_stages_axi=2
CSET tdata_width=64
CSET tdest_width=4
CSET tid_width=8
CSET tkeep_width=4
CSET tstrb_width=4
CSET tuser_width=4
CSET underflow_flag=true
CSET underflow_flag_axi=false
CSET underflow_sense=Active_High
CSET underflow_sense_axi=Active_High
CSET use_clock_enable=false
CSET use_dout_reset=true
CSET use_embedded_registers=true
CSET use_extra_logic=true
CSET valid_flag=false
CSET valid_sense=Active_High
CSET wach_type=FIFO
CSET wdch_type=FIFO
CSET wrch_type=FIFO
CSET write_acknowledge_flag=false
CSET write_acknowledge_sense=Active_High
CSET write_clock_frequency=1
CSET write_data_count=false
CSET write_data_count_width=10
CSET wuser_width=1
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2012-11-19T12:39:56Z
# END Extra information
GENERATE
# CRC: 73737d3d

  1. 2013年01月03日 05:23 |
  2. ZedBoard
  3. | トラックバック:0
  4. | コメント:0

筑波山に登って来ました

昨日、筑波山に登って来ました。麓の筑波総合体育館に車を置いて、つくば道を通って筑波山神社に行って、そこから登山道を登って、御幸ヶ原まで上りました。帰りはケーブルカーで筑波山神社まで降りて、そこからまた、つくば道を通って帰りました。行ったのは、私と奥さんと娘2人です。受験生の息子は家で勉強していました。

最初に筑波総合体育館に車を置いて、平沢官衙遺跡に方に歩いていきます。tukubasan_tozan_1_130103.jpg

更に、つくば道を歩いて行くと神郡の部落の中を歩いていきます。おいしいドーナツを売っているお菓子屋さんがあるんですが、正月で休みでした。残念。。。
tukubasan_tozan_2_130103.jpg

この辺まで来ると筑波山がとっても大きく見えるようになってきます。歩いていて熱くなってくるので、上着を脱いでいます。
tukubasan_tozan_3_130103.jpg

段々と上りになってきます。だいぶ歩くのが辛くなってきます。服を脱いで上りました。途中で鳥居をくぐります。
tukubasan_tozan_4_130103.jpg

鳥居の所のちょっとした公園で、コンビニで買ってきたお昼を食べました。おにぎりやパンです。

こんな風に民家の間を縫って登ってきます。車も来ますが、エンジンが焼ける匂いがします。
tukubasan_tozan_5_130103.jpg

後ろを振り返ると、こんな感じです。
tukubasan_tozan_6_130103.jpg

やっと筑波山神社に到着です。
tukubasan_tozan_7_130103.jpg

筑波山神社の奥の方の階段を登って行くとケーブルカーの発着所(宮脇駅)と登山口があります。ここから登山道に入ります。登山道は、木の間を歩いて上ります。木の階段もありますが、岩もあるので、スニーカーや登山靴が良いと思います。
tukubasan_tozan_8_130103.jpg

tukubasan_tozan_9_130103.jpg

手をついて登る必要が有るところもあります。岩ですね。かなりきつかったです。娘2人は若いので?、元気でした。奥さんもハーフマラソン出てるくらいなので、持久力がありましたね。私がへばってましたが、なんとか御幸ヶ原までたどり着きました。杖があったほうが楽でしたね。特に下りはスキーのストックのような杖を持っている人が多かったです。
tukubasan_tozan_10_130103.jpg

ここからはケーブルカーで宮脇駅まで降りてきました。その後、つくば道をもどりました。筑波山がとっても綺麗なスポットで写真を取りました。
tukubasan_tozan_11_130103.jpg

最後の頃に、私の去年の十月に痛めた左足が痛くなったので、奥さんが走って行って車取ってきてくれました。その後、マクドナルドでカフェラテを飲んで帰りました。とても疲れましたが、なかなか良かったです。
  1. 2013年01月03日 04:40 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0