FC2カウンター FPGAの部屋 AXI Lite Master IPコアの作製

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

FPGAの部屋

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

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製4(XPSへAdd IP)

前回の記事は、”AXI VDMAのレジスタ設定用AXI Lite Master IPの作製3(HDLソースの公開)

一連のシリーズの目的は、なるべくXilinxで提供されているIPを使用してカメラの画像をディスプレイに表示することだ。AXI VDMAの使い方がわからないので、周辺を作りながらシミュレーションをしようと思っている。

今回は、AXI4 Lite Master IPの reg_set_axi_lite_master を上に書いたシミュレーション用のXPSプロジェクト VDMA_test に、Add IPした。

・まず、MPDファイル、PAOファイルを修正して、XPSプロジェクトの Projectメニューから Rescan User Repositories を実行した。(MUIファイルはいじる必要がなかった)

・ユーザーのカスタムIPとして、reg_set_axi_lite_master が見えた。
AXI_Lite_Master_4_130623.png

・Add IPを行った。ダイアログは設定項目がないので見るだけだ。
AXI_Lite_Master_5_130623.png

・reg_set_axi_lite_master がAdd IPされた。AXI VDMAの S_AXI_LITE バスと接続した。
AXI_Lite_Master_6_130623.png

MPDファイル、PAOファイルはほとんど修正していないので、省略する。
  1. 2013年06月23日 05:44 |
  2. AXI Lite Master IPコアの作製
  3. | トラックバック:0
  4. | コメント:0

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製3(HDLソースの公開)

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製2(シミュレーション)”でシミュレーションが動作したので、シミュレーション環境を紹介する。

テストベンチにAXI VDMAのレジスタを設定するコントローラ (reg_set_axi_lite_master.v)(これはプロセッサの変わりだ)と、AXI4 Lite Slave BFM を接続してシミュレーションを行なっている。、AXI4 Lite Slave BFM は以前に公開したAXI4 Slave BFM に AXI4 Liteのラッパーをかませたものだ。

それでは、テストベンチから貼っておく。下に reg_set_axi_lite_master_tb.v を示す。

`default_nettype none

`timescale 100ps / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   18:51:13 06/19/2013
// Design Name:   reg_set_axi_lite_master
// Module Name:   D:/HDL/FndtnISEWork/Zynq-7000/ZedBoard/test/reg_set_axi_lite_master/reg_set_axi_lite_master_tb.v
// Project Name:  reg_set_axi_lite_master
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: reg_set_axi_lite_master
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module reg_set_axi_lite_master_tb;

    // Inputs
    wire M_AXI_ACLK;
    wire M_AXI_ARESETN;
    wire M_AXI_AWREADY;
    wire M_AXI_WREADY;
    wire [1:0] M_AXI_BRESP;
    wire M_AXI_BVALID;
    wire M_AXI_ARREADY;
    wire [31:0] M_AXI_RDATA;
    wire [1:0] M_AXI_RRESP;
    wire M_AXI_RVALID;
    reg     init_done;

    // Outputs
    wire [31:0] M_AXI_AWADDR;
    wire [2:0] M_AXI_AWPROT;
    wire M_AXI_AWVALID;
    wire [31:0] M_AXI_WDATA;
    wire [3:0] M_AXI_WSTRB;
    wire M_AXI_WVALID;
    wire M_AXI_BREADY;
    wire [31:0] M_AXI_ARADDR;
    wire [2:0] M_AXI_ARPROT;
    wire M_AXI_ARVALID;
    wire M_AXI_RREADY;

    // Instantiate the Unit Under Test (UUT)
    reg_set_axi_lite_master uut (
        .M_AXI_ACLK(M_AXI_ACLK), 
        .M_AXI_ARESETN(M_AXI_ARESETN), 
        .M_AXI_AWADDR(M_AXI_AWADDR), 
        .M_AXI_AWPROT(M_AXI_AWPROT), 
        .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_WVALID(M_AXI_WVALID), 
        .M_AXI_WREADY(M_AXI_WREADY), 
        .M_AXI_BRESP(M_AXI_BRESP), 
        .M_AXI_BVALID(M_AXI_BVALID), 
        .M_AXI_BREADY(M_AXI_BREADY), 
        .M_AXI_ARADDR(M_AXI_ARADDR), 
        .M_AXI_ARPROT(M_AXI_ARPROT), 
        .M_AXI_ARVALID(M_AXI_ARVALID), 
        .M_AXI_ARREADY(M_AXI_ARREADY), 
        .M_AXI_RDATA(M_AXI_RDATA), 
        .M_AXI_RRESP(M_AXI_RRESP), 
        .M_AXI_RVALID(M_AXI_RVALID), 
        .M_AXI_RREADY(M_AXI_RREADY), 
        .init_done(init_done)
    );

    axi_lite_slave_BFM axi_lite_slave_BFM_i (
        .M_AXI_ACLK(M_AXI_ACLK), 
        .M_AXI_ARESETN(M_AXI_ARESETN), 
        .M_AXI_AWADDR(M_AXI_AWADDR), 
        .M_AXI_AWPROT(M_AXI_AWPROT), 
        .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_WVALID(M_AXI_WVALID), 
        .M_AXI_WREADY(M_AXI_WREADY), 
        .M_AXI_BRESP(M_AXI_BRESP), 
        .M_AXI_BVALID(M_AXI_BVALID), 
        .M_AXI_BREADY(M_AXI_BREADY), 
        .M_AXI_ARADDR(M_AXI_ARADDR), 
        .M_AXI_ARPROT(M_AXI_ARPROT), 
        .M_AXI_ARVALID(M_AXI_ARVALID), 
        .M_AXI_ARREADY(M_AXI_ARREADY), 
        .M_AXI_RDATA(M_AXI_RDATA), 
        .M_AXI_RRESP(M_AXI_RRESP), 
        .M_AXI_RVALID(M_AXI_RVALID), 
        .M_AXI_RREADY(M_AXI_RREADY)
    );

    initial begin
        // Initialize Inputs
        init_done = 1'b0;

        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here
        init_done = 1'b1;
    end

    // ACLK のインスタンス
    clk_gen #(
        .CLK_PERIOD(100),    // 10nsec, 100MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) ACLKi (
        .clk_out(M_AXI_ACLK)
    );
    
    // reset_gen のインスタンス
    reset_gen #(
        .RESET_STATE(1'b0),
        .RESET_TIME(1000)    // 100nsec
    ) RESETi (
        .reset_out(M_AXI_ARESETN)
    );
    
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


下に axi_lite_slave_BFM を示す。

//
// AXI Lite Master 用 AXI Slave Bus Fuction Model (BFM)
// axi_lite_slave_BFM.v
// AXI Master用 AXI Slave Bus Function Mode (BFM)へのラッパー
// 
// 2013/06/19 
//

`default_nettype none

module axi_lite_slave_BFM # (
    parameter integer C_M_AXI_ADDR_WIDTH = 32,
    parameter integer C_M_AXI_DATA_WIDTH = 32,
    parameter C_M_AXI_AxSIZE = 3'b010,        // 4バイト
    
    parameter integer C_OFFSET_WIDTH = 10,    // 割り当てるRAMのアドレスのビット幅
    
    parameter integer WRITE_RANDOM_WAIT = 0, // Write Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
    parameter integer WR_BVALID_RANDOM_WAIT = 0, // Write Transaction の時のM_AXI_BVALID をランダムにWaitする=1, Waitしない=0
    parameter integer READ_RANDOM_WAIT = 0 // Read Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
) (
    // System Signals
    input wire M_AXI_ACLK,
    input wire M_AXI_ARESETN,

    // Master Interface Write Address
    input wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
    input wire [3-1:0] M_AXI_AWPROT,
    input wire M_AXI_AWVALID,
    output wire M_AXI_AWREADY,

    // Master Interface Write Data
    input wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
    input wire [C_M_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB,
    input wire M_AXI_WVALID,
    output wire M_AXI_WREADY,

    // Master Interface Write Response
    output wire [2-1:0] M_AXI_BRESP,
    output wire M_AXI_BVALID,
    input wire M_AXI_BREADY,

    // Master Interface Read Address
    input wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR,
    input wire [3-1:0] M_AXI_ARPROT,
    input wire M_AXI_ARVALID,
    output wire M_AXI_ARREADY,

    // Master Interface Read Data 
    input wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA,
    input wire [2-1:0] M_AXI_RRESP,
    input wire M_AXI_RVALID,
    output wire M_AXI_RREADY
);
    

    // Instantiate the Unit Under Test (UUT_slave)
    axi_slave_bfm #(
        .C_M_AXI_ADDR_WIDTH(C_M_AXI_ADDR_WIDTH),
        .C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH),
        .C_OFFSET_WIDTH(C_OFFSET_WIDTH),
        .C_M_AXI_BURST_LEN(1),
        .WRITE_RANDOM_WAIT(WRITE_RANDOM_WAIT),
        .WR_BVALID_RANDOM_WAIT(WR_BVALID_RANDOM_WAIT),
        .READ_RANDOM_WAIT(READ_RANDOM_WAIT)
    ) axi_slave_bfm_i (
        .ACLK(M_AXI_ACLK), 
        .ARESETN(M_AXI_ARESETN), 
        .M_AXI_AWID(1'b0), 
        .M_AXI_AWADDR(M_AXI_AWADDR), 
        .M_AXI_AWLEN(8'd0),                // 1 Word
        .M_AXI_AWSIZE(C_M_AXI_AxSIZE), 
        .M_AXI_AWBURST(2'b01),             // INCR  (アドレスをインクリメント))
        .M_AXI_AWLOCK(1'b0),            // ノーマル・アクセス
        .M_AXI_AWCACHE(4'b0010),         // Normal Non-cacheable Non-bufferable
        .M_AXI_AWPROT(M_AXI_AWPROT),
        .M_AXI_AWQOS(4'b0000),            // default
        .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(1'b1), 
        .M_AXI_WUSER(), 
        .M_AXI_WVALID(M_AXI_WVALID), 
        .M_AXI_WREADY(M_AXI_WREADY), 
        .M_AXI_BID(), 
        .M_AXI_BRESP(M_AXI_BRESP), 
        .M_AXI_BUSER(), 
        .M_AXI_BVALID(M_AXI_BVALID), 
        .M_AXI_BREADY(M_AXI_BREADY), 
        .M_AXI_ARID(1'b0), 
        .M_AXI_ARADDR(M_AXI_ARADDR), 
        .M_AXI_ARLEN(8'd0),                // 1 Word
        .M_AXI_ARSIZE(C_M_AXI_AxSIZE), 
        .M_AXI_ARBURST(2'b01),             // INCR  (アドレスをインクリメント) 
        .M_AXI_ARLOCK(2'b00),            // ノーマル・アクセス
        .M_AXI_ARCACHE(4'b0010),         // Normal Non-cacheable Non-bufferable
        .M_AXI_ARPROT(M_AXI_ARPROT),
        .M_AXI_ARQOS(4'b0000),            // default
        .M_AXI_ARUSER(), 
        .M_AXI_ARVALID(M_AXI_ARVALID), 
        .M_AXI_ARREADY(M_AXI_ARREADY), 
        .M_AXI_RID(), 
        .M_AXI_RDATA(M_AXI_RDATA), 
        .M_AXI_RRESP(M_AXI_RRESP), 
        .M_AXI_RLAST(), 
        .M_AXI_RUSER(), 
        .M_AXI_RVALID(M_AXI_RVALID), 
        .M_AXI_RREADY(M_AXI_RREADY)
    );
endmodule

`default_nettype wire

  1. 2013年06月21日 03:29 |
  2. AXI Lite Master IPコアの作製
  3. | トラックバック:0
  4. | コメント:0

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製2(シミュレーション)

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製1(仕様の検討)”の続き。

AXI VDMAのレジスタを設定するコントローラのVerilog HDLコードとAXI4 Lite Master用AXI4 Lite Slave BFM(簡易版だけど)を作製できたので、シミュレーションを行った。
下図にシミュレーション結果を示す。
AXI_Lite_Master_3_130620.png

上の図では、AXI VDMAのレジスタを設定するコントローラ (reg_set_axi_lite_master.v) で、AXI VDMAのアドレスと設定値を保存しておくテキストファイル vdma_reg_set.txt の値を使用して、AXI4 Lite Masterアクセスを行なっている。下に、vdma_reg_set.txt の一部を示す。この後は全て0で、全部合計で256個ある。

00000010
12345678
00000020
11223344
00000030
55667788
ffffffff


vdma_reg_set.txt のフォーマットは1番目がアドレス、2番めが設定値となる。奇数番目がアドレス、偶数番目が設定値となる。そして、アドレスに”ffffffff”が現れた時に終了となる。

MicroBlaze があるのに、どうしてこのIPを作ったかというと、MicroBlazeでVDMAなどのレジスタを設定するとシミュレーションをするのに、SDKを立ちあげてソフトウェアを作る必要があるので面倒だ。レジスタを少し設定するだけだったら、すべてISimですることができる今回のレジスタを設定するコントローラIPを作ったほうが面倒が少ないと思ったからだ。設定アドレス、設定データのセットを作るのが面倒だったら、それを生成するスクリプトを作れば良いと思う。このIPは、主にシミュレーションに使用する。簡単な設定で値が固定されている場合は実機で使用しても良いと思う。
実機で頻繁に設定値を変える必要がある時は、プロセッサを使用する。そうすれば、FPGAを再インプリメントすることなしに、設定値を短時間で変更することができる。
下に、reg_set_axi_lite_master.v のコードを示す。

///////////////////////////////////////////////////////////////////////////////
//
// AXI4/Lite Master
//
////////////////////////////////////////////////////////////////////////////
//
// Structure:
//   reg_set_axi_lite_master
//
////////////////////////////////////////////////////////////////////////////

`default_nettype none

module reg_set_axi_lite_master # (
    parameter integer C_M_AXI_ADDR_WIDTH = 32,
    parameter integer C_M_AXI_DATA_WIDTH = 32
)(
    // System Signals
    input wire M_AXI_ACLK,
    input wire M_AXI_ARESETN,

    // Master Interface Write Address
    output wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
    output wire [3-1:0] M_AXI_AWPROT,
    output wire M_AXI_AWVALID,
    input wire M_AXI_AWREADY,

    // Master Interface Write Data
    output wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
    output wire [C_M_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB,
    output wire M_AXI_WVALID,
    input wire M_AXI_WREADY,

    // Master Interface Write Response
    input wire [2-1:0] M_AXI_BRESP,
    input wire M_AXI_BVALID,
    output wire M_AXI_BREADY,

    // Master Interface Read Address
    output wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR,
    output wire [3-1:0] M_AXI_ARPROT,
    output wire M_AXI_ARVALID,
    input wire M_AXI_ARREADY,

    // Master Interface Read Data 
    input wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA,
    input wire [2-1:0] M_AXI_RRESP,
    input wire M_AXI_RVALID,
    output wire M_AXI_RREADY,
    
    input    wire    init_done
);

    reg        [31:0] rom [0:255];
    reg        [31:0] rom_dout;
    
    initial begin
        $readmemh("vdma_reg_set.txt", rom, 0, 255);
    end
    
    reg        reset_1b, reset;
    reg     [31:0]    reg_addr;
    reg        [31:0]    reg_data;
    reg     [7:0]    rom_addr;
    reg        awvalid;
    reg        wvalid;
    reg        bready;

    localparam    RESP_OKAY =        2'b00,
                RESP_EXOKAY =    2'b01,
                RESP_SLVERR =    2'b10,
                RESP_DECERR =    2'b11;
    
    localparam    IDLE_RRSM =                3'b000,
                ADDRESS_READ =            3'b001,
                DATA_READ =                3'b011,
                REG_SET_DATA_VALID =    3'b010,
                END_RRSM =                3'b110;
    reg        [2:0]    rrsm_cs;
    
    localparam    IDLE_ADDR =            2'b00,
                AWVALID_ASSERT =    2'b01,
                AWVALID_HOLD_OFF =    2'b11;
    reg        [1:0]    addr_cs;
    
    localparam    IDLE_DATA =            2'b00,
                WVALID_ASSERT =        2'b01,
                WVALID_HOLD_OFF =    2'b11;
    reg        [1:0]    data_cs;
    
    localparam    IDLE_RESP =        1'b0,
                BREADY_ASSERT =    1'b1;
    reg        resp_cs;
    
    reg        reg_data_valid;
    reg        rom_read_done;
    
    // Read is not implement
    assign M_AXI_ARADDR = 0;
    assign M_AXI_ARPROT = 3'd0;
    assign M_AXI_ARVALID = 1'b0;
    assign M_AXI_RDATA = 0;
    assign M_AXI_RREADY = 1'b1;
    assign M_AXI_WSTRB = 4'b1111;
    assign M_AXI_AWPROT = 3'b000;
    
    // reset
    always @(posedge M_AXI_ACLK) begin
        reset_1b <= ~M_AXI_ARESETN | ~init_done;
        reset <= reset_1b;
    end
    
    // instantiaton of rom
    always @(posedge M_AXI_ACLK) begin
        rom_dout <= rom[rom_addr];
    end
    
    // rom read State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            rrsm_cs <= IDLE_RRSM;
            reg_data_valid <= 1'b0;
        end else begin
            case (rrsm_cs) 
                IDLE_RRSM : 
                    rrsm_cs <= ADDRESS_READ;
                ADDRESS_READ :
                    rrsm_cs <= DATA_READ;
                DATA_READ : begin
                    if (rom_dout == 32'hFFFF_FFFF) begin // end
                        rrsm_cs <= END_RRSM;
                        reg_data_valid <= 1'b0;
                    end else begin
                        rrsm_cs <= REG_SET_DATA_VALID;
                        reg_data_valid <= 1'b1;
                    end
                end
                REG_SET_DATA_VALID : begin
                    if (rom_read_done) begin
                        rrsm_cs <= ADDRESS_READ;
                        reg_data_valid <= 1'b0;
                    end
                end
                END_RRSM :
                    rrsm_cs <= END_RRSM;
            endcase
        end
    end
    
    // rom_addr
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            rom_addr <= 8'd0;
        end else begin
            if (rrsm_cs == ADDRESS_READ) // Data
                rom_addr <= rom_addr + 8'd1;
            else if (rrsm_cs == REG_SET_DATA_VALID && rom_read_done) // Address
                rom_addr <= rom_addr + 8'd1;
        end
    end
    
    // AXI4 Lite Master Address
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            reg_addr <= 32'd0;
        end else begin
            if (rrsm_cs == DATA_READ)
                reg_addr <= rom_dout;
        end
    end
    assign M_AXI_AWADDR = reg_addr;
    
    // AXI4 Lite Master WDATA
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            reg_data <= 32'd0;
        end else begin
            if (rrsm_cs == REG_SET_DATA_VALID)
                reg_data <= rom_dout;
        end
    end
    assign M_AXI_WDATA = reg_data;
    
    // AXI Lite Master Address State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            addr_cs <= IDLE_ADDR;
            awvalid <= 1'b0;
        end else begin
            case (addr_cs)
                IDLE_ADDR :
                    if (rrsm_cs == REG_SET_DATA_VALID) begin
                        addr_cs <= AWVALID_ASSERT;
                        awvalid <= 1'b1;
                    end
                AWVALID_ASSERT :
                    if (M_AXI_AWREADY) begin
                        addr_cs <= AWVALID_HOLD_OFF;
                        awvalid <= 1'b0;
                    end
                AWVALID_HOLD_OFF :
                    if (rrsm_cs != REG_SET_DATA_VALID)
                        addr_cs <= IDLE_ADDR;
            endcase
        end
    end
    assign M_AXI_AWVALID = awvalid;
    
    // AXI Lite Master Data State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            data_cs <= IDLE_DATA;
            wvalid <= 1'b0;
            rom_read_done <= 1'b0;
        end else begin
            case (data_cs)
                IDLE_DATA : begin
                    rom_read_done <= 1'b0;
                    if (rrsm_cs == REG_SET_DATA_VALID) begin
                        data_cs <= WVALID_ASSERT;
                        wvalid <= 1'b1;
                    end
                end
                WVALID_ASSERT :
                    if (M_AXI_WREADY) begin
                        wvalid <= 1'b0;
                        rom_read_done <= 1'b1;
                        data_cs <= WVALID_HOLD_OFF;
                    end
                WVALID_HOLD_OFF : begin
                    rom_read_done <= 1'b0;
                    if (addr_cs == AWVALID_HOLD_OFF)
                        data_cs <= IDLE_DATA;
                end
            endcase
        end
    end
    assign M_AXI_WVALID = wvalid;
    
    // bready State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            resp_cs <= IDLE_RESP;
            bready <= 1'b0;
        end else begin
            case (resp_cs)
                IDLE_RESP :
                    if (M_AXI_WREADY && data_cs == WVALID_ASSERT) begin
                        resp_cs <= BREADY_ASSERT;
                        bready <= 1'b1;
                    end
                BREADY_ASSERT :
                    if (M_AXI_BVALID) begin
                        resp_cs <= IDLE_RESP;
                        bready <= 1'b0;
                    end
            endcase
        end
    end
    assign M_AXI_BREADY = bready;
    
endmodule

`default_nettype none

  1. 2013年06月20日 05:47 |
  2. AXI Lite Master IPコアの作製
  3. | トラックバック:0
  4. | コメント:0

AXI VDMAのレジスタ設定用AXI Lite Master IPの作製1(仕様の検討)

ZedBoard用画像出力IPの作製3(Add IP)”で、Xilinx社の AXI4-Stream to Video Out IP に接続するIPは全て作り終えた。
AXI VDMAのシミュレーションを行うまでに、どんなIPが足りないかというと、AXI VDMAのレジスタを設定するコントローラとAXI Master のメモリの2つである。
AXI_Lite_Master_1_130613.png

今回は、AXI VDMAのレジスタを設定するコントローラを AXI Lite Master として作製する。MicroBlaze でも良いのだが、MicroBlaze を実装すると大げさになってしまうし、ソフトウェアを初期値としてRAMにロードする手間も必要になる。AXI VDMAのレジスタを設定するだけの AXI Lite Master インターフェースを有した簡単なコントローラを自作することにする。
AR# 37425 12.3 EDK、12.3 ISE - カスタム AXI IP コアの作成方法”の ar37425.zip には、AXI Lite Master のテンプレートもあるのでそれを使用する。
AXI_Lite_Master_2_130613.png

AXI4 Lite バスについては、下の2つの記事を参照下さい。

キャラクタROMをAXI4 Lite Slave として実装する1(AXI4 Lite バスの勉強)
キャラクタROMをAXI4 Lite Slave として実装する2(AXI4 Lite バスの勉強2)


AXI VDMAのレジスタの値は、Verilog で32ビット長のRAMを定義して、初期値を与えようと思っている。最初(偶数アドレス)の32ビットがAXI Lite バスのアドレスで、次の32ビット(奇数アドレス)がAXI Lite バスのデータにしようと思っている。Verilog HDL を使用した外部ファイルによるRAMの初期値の与え方は、下の記事を参照下さい。

soc-lm32をSpartan3E Stater Kitにコンフィギュレーション


VHDLで作るとすると、下の2つの記事を参照下さい。

VHDLでのブロックRAMや分散RAMの初期化(外部データファイル)
VHDLでのブロックRAMや分散RAMの初期化(16進数で書かれた外部データファイル)

  1. 2013年06月13日 05:27 |
  2. AXI Lite Master IPコアの作製
  3. | トラックバック:0
  4. | コメント:0