AXI_BRAM和AXI_Stream FIFO的通信

平台:vivado2017.4

芯片:kintex-7  xc7k325tffg900-2

学习AXI总线。上一篇学习了AXI BRAM 和AXI_Stream FIFO。这里使用仿真看看他们之间的通信,为了更加深入的理解AXI总线。

前面分析了,AXI_BRAM的信号,支持突发模式。最大一次突发传输s_axi_awlen位宽的数据。这里即256个数据。

第一部分实现由AXI_BRAM产生256个数据,将其读出后,写入AXI_FIFO缓存。

第二部分实现由AXI_FIFO产生256个数据后,将其读出,写入AXI_BRAM缓存。

目录

第一部分

代码实现

仿真分析

第二部分

代码实现

仿真分析


第一部分

代码实现

第一部分,AXI_BRAM产生数据,将其读出后在写入AXI_FIFO。

产生数据时写入数据时,BRAM作为数据的接收方,我们需要向其提供地址,数据,传输次数,字节大小,突发类型,以及握手valid信号。将数据读出写入AXI_FIFO时,我们作为数据的接收方,需要向AXI_BRAM提供READY信号。

第一步将读通道信号引出。

module bram_control_burst#(
parameter	U_DLY = 1
										)
										(
input	wire		lb_clk				,
input	wire		lb_rst				,
input	wire	    reg_axi_write	    ,		
input	wire    	reg_axi_read        ,
//AXI_BRAM接口
output  wire [3:0]  s_axi_rid           ,//读IDtag。RID的数值必须与ARID的数值匹配
output  wire [31:0] s_axi_rdata         ,//读数据
output  wire [1:0]  s_axi_rresp         ,//读响应。这个信号指明读传输状态
output  wire        s_axi_rlast         ,//读取最后一个数据
output  wire        s_axi_rvalid        ,//读取有效'1'读数据有效
input   wire        s_axi_rready         //读数据就绪'1'主机就绪


										);

在AXI_BRAM里面设置突发长度len:

localparam          len             = 8'hFF;//突发256个数据

AXI_BRAM测准备就绪。

下面准备TOP层代码,TOP层例化,AXI_BRAM和AXI_FIFO。将AXI_BRAM读出的数据当做AXI_FIFO写入的数据。

分析一下。

对于AXI_FIFO来说,AXI_BRAM里面读出的数据向AXI_FIFO里面写入。则AXI_BRAM作为数据的发送方,为AXI_FIFO提供DATA,VALID,LAST信号。

核心部分连接代码如下:

assign  s_axis_tlast    = s_axi_rlast;//AXI_FIFO一次传输的最后一个数据

assign  s_axi_rready    = s_axis_tready;//AXI_BRAM的读就绪

assign  s_axis_tvalid   = s_axi_rvalid;//AXI_FIFO的读有效
assign  s_axis_tdata    = s_axi_rdata;//数据

如上,AXI_BRAM作为数据的发送方,将s_axi_rlast,s_axi_rvalid,s_axi_rdata作为AXI_FIFO的直接输入。

这里需要将AXI_BRAM的valid作为AXI_FIFO的valid输入。

需要将AXI_FIFO的ready,作为AXI_BRAM的ready信号输入。这样即保证了握手的过程。

AXI_FIFO读取部分,当写入的数据计数器大于256时,开启AXI_FIFO读。

always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_tready   <= 1'b0;
        else if(m_axis_tvalid == 1'b1 &&  m_axis_rd_req == 2'b01)
                m_axis_tready   <= 1'b1;
        else if(rd_cnt == 8'd256)
                m_axis_tready   <= 1'b0;
        else
                m_axis_tready   <= m_axis_tready;
end


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_rd_req   <= 2'b0;
        else if(axis_wr_data_count >= 11'd256)
                m_axis_rd_req   <= {m_axis_rd_req[0],1'b1};
        else
                m_axis_rd_req   <= m_axis_rd_req;
end
                


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                rd_cnt  <= 8'd1;
        else if(m_axis_tready == 1'b1 && m_axis_tvalid == 1'b1)//同时有效读取
                rd_cnt  <= rd_cnt + 8'd1;
        else
                rd_cnt  <= rd_cnt;
end

仿真分析

接下来看看仿真。

首先AXI_BRAM自己产生数据并写入。

 AXI_BRAM数据读出。

 AXI_FIFO数据写入。

 AXI_FIFO数据读出。

AXI_FIFO读取完毕。

 

 插入代码。

// *********************************************************************************/
// Project Name :
// Author       : i_huyi
// Email        : i_huyi@qq.com
// Creat Time   : 2021/8/9 10:04:53
// File Name    : .v
// Module Name  : 
// Called By    :
// Abstract     :
//
// CopyRight(c) 2020, xxx xxx xxx Co., Ltd.. 
// All Rights Reserved
//
// *********************************************************************************/
// Modification History:
// 1. initial
// *********************************************************************************/
// *************************
// MODULE DEFINITION
// *************************
`timescale 1 ns / 1 ps
module axi_top#(
parameter   U_DLY = 1
                                        )
                                        (
input	wire		lb_clk				,
input	wire		lb_rst				,
input	wire	    reg_axi_write	    ,		
input	wire    	reg_axi_read        
      
                                        );
//--------------------------------------
// localparam
//--------------------------------------

//--------------------------------------
// register
//--------------------------------------
//reg     [7:0]   wr_cnt                  ;
reg     [7:0]   rd_cnt                  ;
//reg     [1:0]   last_cnt                ;
reg     [1:0]   m_axis_rd_req           ;


//--------------------------------------
// wire
//--------------------------------------
//axis_fifo interface
//wire            wr_rst_busy             ;
//wire            rd_rst_busy             ;
//axis_wr_interface
wire            s_axis_tvalid           ;//输入数据有效
wire            s_axis_tready           ;//axis_fifo准备好接收数据
wire    [31:0]  s_axis_tdata            ;//axis_fifo接收的数据
wire            s_axis_tlast            ;//指示当前突发的最后一个数据
//reg     [3:0]   s_axis_tuser            ;//

//aixs_rd_interface
wire            m_axis_tvalid           ;//fifo(主机)读数据有效
reg             m_axis_tready           ;//rd_en
wire    [31:0]  m_axis_tdata            ;//读出的数据
wire            m_axis_tlast            ;//读出的数据最后一位
//wire    [3:0]   m_axis_tuser            ;//自定义信息
//读写数据计数器
wire    [10:0]  axis_wr_data_count      ;
wire    [10:0]  axis_rd_data_count      ;

//axs_bram interface
//AXI_BRAM接口
wire    [3:0]   s_axi_rid               ;//读IDtag。RID的数值必须与ARID的数值匹配
wire    [31:0]  s_axi_rdata             ;//读数据
wire    [1:0]   s_axi_rresp             ;//读响应。这个信号指明读传输状态
wire            s_axi_rlast             ;//读取最后一个数据
wire            s_axi_rvalid            ;//读取有效'1'读数据有效
wire            s_axi_rready            ;//读数据就绪'1'主机就绪

//--------------------------------------
// assign
//--------------------------------------

//------------------------------------------------------------
//------------------------------------------------------------
axis_fifo_control u_axis_fifo_control(
    .wr_clk                     (lb_clk                     ),
    .rd_clk                     (lb_clk                     ),
    .rst                        (lb_rst                     ),
    .axis_wr_data_count         (axis_wr_data_count         ),
    .axis_rd_data_count         (axis_rd_data_count         ),
    //全局信号
    .wr_rst_busy                (                           ),
    .rd_rst_busy                (                           ),
//axis_wr_interface
    .s_axis_tvalid              (s_axis_tvalid              ),
    .s_axis_tready              (s_axis_tready              ),
    .s_axis_tdata               (s_axis_tdata               ),
    .s_axis_tlast               (s_axis_tlast               ),
    .s_axis_tuser               (4'b0000                    ),
    //axis_rd_interface
    .m_axis_tvalid              (m_axis_tvalid              ),
    .m_axis_tready              (m_axis_tready              ),
    .m_axis_tdata               (m_axis_tdata               ),
    .m_axis_tlast               (m_axis_tlast               ),
    .m_axis_tuser               (m_axis_tuser               )
);

bram_control_burst u_bram_control_burst(
    .lb_clk                     (lb_clk                     ),
    .lb_rst                     (lb_rst                     ),
    .reg_axi_write              (reg_axi_write              ),
    .reg_axi_read               (reg_axi_read               ),
//AXI_BRAM_rd_data接口
    .s_axi_rid                  (s_axi_rid                  ),
    .s_axi_rdata                (s_axi_rdata                ),
    .s_axi_rresp                (s_axi_rresp                ),
    .s_axi_rlast                (s_axi_rlast                ),
    .s_axi_rvalid               (s_axi_rvalid               ),
    .s_axi_rready               (s_axi_rready               )
);

//------------------------------------------------------------
//------------------------------------------------------------
assign  s_axis_tlast    = s_axi_rlast;//AXI_FIFO一次传输的最后一个数据

assign  s_axi_rready    = s_axis_tready;//AXI_BRAM的读就绪

assign  s_axis_tvalid   = s_axi_rvalid;//AXI_FIFO的读有效
assign  s_axis_tdata    = s_axi_rdata;//数据






//------------------------------------------------------------
//------------------------------------------------------------
自测试,fifo产生数据,先写后读
FIFO写,先等待tready信号有效,表示FIFO里面可以写入数据
//
//always@(posedge lb_clk or posedge lb_rst)
//begin
//        if(lb_rst == 1'b1)
//        begin
//                s_axis_tvalid   <= 1'b0;
//                s_axis_tuser    <= 4'd0;
//        end
//        else if(wr_cnt  <= 8'd99 )
//                s_axis_tvalid   <= 1'b1;
//        else
//                s_axis_tvalid   <= 1'b0;   
                s_axis_tvalid   <= 1'b1;   
//end
//
//always@(posedge lb_clk or posedge lb_rst)
//begin
//        if(lb_rst == 1'b1)
//                s_axis_tlast    <= 1'b0;
//        else if(wr_cnt  == 8'd99 && last_cnt == 2'b00)
//                s_axis_tlast    <= 1'b1;
//        else
//                s_axis_tlast    <= 1'b0;
//end
//                
//
//always@(posedge lb_clk or posedge lb_rst)
//begin
//        if(lb_rst == 1'b1)
//                last_cnt    <= 2'b00;
//        else if(wr_cnt  == 8'd99)
//                last_cnt    <= {last_cnt[0],1'b1};
//        else
//                last_cnt    <= 2'b00;
//end
//
//
//always@(posedge lb_clk or posedge lb_rst)
//begin
//        if(lb_rst == 1'b1)
//        begin
//                wr_cnt          <= 8'd1;
//                s_axis_tdata    <= 32'd1;
//        end
//        else if(s_axis_tvalid == 1'b1 && s_axis_tready == 1'b1)
//        begin
//                wr_cnt  <= wr_cnt + 8'd1;
//                s_axis_tdata    <= s_axis_tdata + 32'd1;
//        end
//        else
//        begin
//                wr_cnt  <= wr_cnt;
//                s_axis_tdata    <= s_axis_tdata;
//        end
//end
//
//FIFO读,作为接收方(从机)可以等待主机VALID有效后在拉高READY,这里我们不这样
//做,我们准备读一次读100个数据有停止,要求一次读100个数据
always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_tready   <= 1'b0;
        else if(m_axis_tvalid == 1'b1 &&  m_axis_rd_req == 2'b01)
                m_axis_tready   <= 1'b1;
        else if(rd_cnt == 8'd256)
                m_axis_tready   <= 1'b0;
        else
                m_axis_tready   <= m_axis_tready;
end


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_rd_req   <= 2'b0;
        else if(axis_wr_data_count >= 11'd256)
                m_axis_rd_req   <= {m_axis_rd_req[0],1'b1};
        else
                m_axis_rd_req   <= m_axis_rd_req;
end
                


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                rd_cnt  <= 8'd1;
        else if(m_axis_tready == 1'b1 && m_axis_tvalid == 1'b1)//同时有效读取
                rd_cnt  <= rd_cnt + 8'd1;
        else
                rd_cnt  <= rd_cnt;
end





//------------------------------------------------------------
//------------------------------------------------------------
endmodule

第二部分

代码实现

做从AXI_FIFO里面产生数据,读出后,写入AXI_BRAM内。

首先AXI_FIFO内部自己产生数据。产生数据量为256个数据。数据产生完成后,将数据读出。这时将读出的数据接入AXI_BRAM的写数据通道上。将AXI_FIFO的m_axis_tready信号直接接入AXI_BRAM的写有效S_AXI_WVALID。

assign  S_AXI_WDATA     = m_axis_tdata;
assign  S_AXI_WVALID    = m_axis_tready;
assign  S_AXI_WLAST     = m_axis_tlast && m_axis_tvalid && m_axis_tready;
assign  S_AXI_WSTRB     = 4'b1111;

同时为了保证在数据写入AXI_BRAM之前写地址通道先握手成功。先判断AXI_FIFO里面是否写入了256个数据,在数据量达到后,使用m_axis_rd_req信号作为,AXI_BRAM写地址有效信号。

具体的操作如下。顶层TOP实现。

// *********************************************************************************/
// Project Name :
// Author       : i_huyi
// Email        : i_huyi@qq.com
// Creat Time   : 2021/8/9 10:04:53
// File Name    : .v
// Module Name  : 
// Called By    :
// Abstract     :
//
// CopyRight(c) 2020, xxx xxx xxx Co., Ltd.. 
// All Rights Reserved
//
// *********************************************************************************/
// Modification History:
// 1. initial
// *********************************************************************************/
// *************************
// MODULE DEFINITION
// *************************
`timescale 1 ns / 1 ps
module axi_top#(
parameter   U_DLY = 1
                                        )
                                        (
input	wire		lb_clk				,
input	wire		lb_rst				,
input	wire	    reg_axi_write	    ,		
input	wire    	reg_axi_read        
      
                                        );
//--------------------------------------
// localparam
//--------------------------------------

//--------------------------------------
// register
//--------------------------------------
reg     [15:0]  wr_cnt                  ;
reg     [7:0]   rd_cnt                  ;
reg     [1:0]   last_cnt                ;
reg     [3:0]   m_axis_rd_req           ;


//--------------------------------------
// wire
//--------------------------------------
//axis_fifo interface

//axis_wr_interface
reg             s_axis_tvalid           ;//输入数据有效
wire            s_axis_tready           ;//axis_fifo准备好接收数据
reg     [31:0]  s_axis_tdata            ;//axis_fifo接收的数据
reg             s_axis_tlast            ;//指示当前突发的最后一个数据
//reg     [3:0]   s_axis_tuser            ;//

//aixs_rd_interface
wire            m_axis_tvalid           ;//fifo(主机)读数据有效
reg             m_axis_tready           ;//rd_en
wire    [31:0]  m_axis_tdata            ;//读出的数据
wire            m_axis_tlast            ;//读出的数据最后一位
//wire    [3:0]   m_axis_tuser            ;//自定义信息
//读写数据计数器
wire    [10:0]  axis_wr_data_count      ;
wire    [10:0]  axis_rd_data_count      ;

//axs_bram interface
//AXI_BRAM接口写
wire    [31:0]  S_AXI_WDATA             ;
wire    [3:0]   S_AXI_WSTRB             ;
wire            S_AXI_WLAST             ;
wire            S_AXI_WVALID            ;
wire            S_AXI_WREADY            ;

//
//AXI_BRAM接口读
//
wire    [3:0]   s_axi_rid               ;//读IDtag。RID的数值必须与ARID的数值匹配
wire    [31:0]  s_axi_rdata             ;//读数据
wire    [1:0]   s_axi_rresp             ;//读响应。这个信号指明读传输状态
wire            s_axi_rlast             ;//读取最后一个数据
wire            s_axi_rvalid            ;//读取有效'1'读数据有效
wire            s_axi_rready            ;//读数据就绪'1'主机就绪

//--------------------------------------
// assign
//--------------------------------------

assign  S_AXI_WDATA     = m_axis_tdata;
assign  S_AXI_WVALID    = m_axis_tready;
assign  S_AXI_WLAST     = m_axis_tlast && m_axis_tvalid && m_axis_tready;
assign  S_AXI_WSTRB     = 4'b1111;



//------------------------------------------------------------
//------------------------------------------------------------
axis_fifo_control u_axis_fifo_control(
    .wr_clk                     (lb_clk                     ),
    .rd_clk                     (lb_clk                     ),
    .rst                        (lb_rst                     ),
    .axis_wr_data_count         (axis_wr_data_count         ),
    .axis_rd_data_count         (axis_rd_data_count         ),
    //全局信号
    .wr_rst_busy                (                           ),
    .rd_rst_busy                (                           ),
//axis_wr_interface
    .s_axis_tvalid              (s_axis_tvalid              ),
    .s_axis_tready              (s_axis_tready              ),
    .s_axis_tdata               (s_axis_tdata               ),
    .s_axis_tlast               (s_axis_tlast               ),
    .s_axis_tuser               (4'b0000                    ),
    //axis_rd_interface
    .m_axis_tvalid              (m_axis_tvalid              ),
    .m_axis_tready              (m_axis_tready              ),
    .m_axis_tdata               (m_axis_tdata               ),
    .m_axis_tlast               (m_axis_tlast               ),
    .m_axis_tuser               (                           )
);

bram_control_burst u_bram_control_burst(
    .lb_clk                     (lb_clk                     ),
    .lb_rst                     (lb_rst                     ),
    .reg_axi_write              (m_axis_rd_req == 4'b0001   ),
    .reg_axi_read               (                           ),
    .S_AXI_WDATA                (S_AXI_WDATA                ),
    .S_AXI_WSTRB                (S_AXI_WSTRB                ),
    .S_AXI_WLAST                (S_AXI_WLAST                ),
    .S_AXI_WVALID               (S_AXI_WVALID               ),
    .S_AXI_WREADY               (S_AXI_WREADY               ),
//AXI_BRAM_rd_data接口
    .s_axi_rid                  (s_axi_rid                  ),
    .s_axi_rdata                (s_axi_rdata                ),
    .s_axi_rresp                (s_axi_rresp                ),
    .s_axi_rlast                (s_axi_rlast                ),
    .s_axi_rvalid               (s_axi_rvalid               ),
    .s_axi_rready               (s_axi_rready               )
);

//------------------------------------------------------------
//------------------------------------------------------------
//自测试,fifo产生数据,先写后读
//FIFO写,先等待tready信号有效,表示FIFO里面可以写入数据

always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
        begin
                s_axis_tvalid   <= 1'b0;
//                s_axis_tuser    <= 4'd0;
        end
        else if(wr_cnt  <= 16'd255 )
                s_axis_tvalid   <= 1'b1;
        else
                s_axis_tvalid   <= 1'b0;   
//                s_axis_tvalid   <= 1'b1;   
end

always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                s_axis_tlast    <= 1'b0;
        else if(wr_cnt  == 16'd255 && last_cnt == 2'b00)
                s_axis_tlast    <= 1'b1;
        else
                s_axis_tlast    <= 1'b0;
end
                

always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                last_cnt    <= 2'b00;
        else if(wr_cnt  == 16'd255)
                last_cnt    <= {last_cnt[0],1'b1};
        else
                last_cnt    <= 2'b00;
end


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
        begin
                wr_cnt          <= 16'd1;
                s_axis_tdata    <= 32'd1;
        end
        else if(s_axis_tvalid == 1'b1 && s_axis_tready == 1'b1)
        begin
                wr_cnt  <= wr_cnt + 16'd1;
                s_axis_tdata    <= s_axis_tdata + 32'd1;
        end
        else
        begin
                wr_cnt  <= wr_cnt;
                s_axis_tdata    <= s_axis_tdata;
        end
end
//
//FIFO读,作为接收方(从机)可以等待主机VALID有效后在拉高READY,这里我们不这样
//做,我们准备读一次读100个数据有停止,要求一次读100个数据
always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_tready   <= 1'b0;
//        else if(m_axis_tvalid == 1'b1 &&  m_axis_rd_req == 2'b0111)
        else if(m_axis_tvalid == 1'b1 &&  S_AXI_WREADY == 1'b1)
                m_axis_tready   <= 1'b1;
        else if(rd_cnt == 8'd256)
                m_axis_tready   <= 1'b0;
        else
                m_axis_tready   <= m_axis_tready;
end



always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                m_axis_rd_req   <= 4'b0;
        else if(axis_wr_data_count >= 11'd256)
                m_axis_rd_req   <= {m_axis_rd_req[2:0],1'b1};
        else
                m_axis_rd_req   <= m_axis_rd_req;
end
                


always@(posedge lb_clk or posedge lb_rst)
begin
        if(lb_rst == 1'b1)
                rd_cnt  <= 8'd1;
        else if(m_axis_tready == 1'b1 && m_axis_tvalid == 1'b1)//同时有效读取
                rd_cnt  <= rd_cnt + 8'd1;
        else
                rd_cnt  <= rd_cnt;
end





//------------------------------------------------------------
//------------------------------------------------------------
endmodule

底层AXI_BRAM代码修改如下。

对于写地址通道,通过组合逻辑预先设置好需要突发的数据地址数据长度,数据位宽,以及突发模式。

对于写数据通道,将从AXI_FIFO里面引出来的数据接入写数据通道,同时注意为了握手传输数据,需要将AXI_BRAM的s_axi_wready信号作为作为AXI_FIFO读ready。

// *********************************************************************************/
// Project Name :
// Author       : i_huyi
// Email        : i_huyi@qq.com
// Creat Time   : 2021/8/2 14:06:24
// File Name    : .v
// Module Name  : 
// Called By    :
// Abstract     :
// v1.0对AXI_BRAM单独读写模块。
// v1.1更新对AXI_BRAM的突发读写。设置突发长度。
// v1.2实现AXI IP之间的互联。比如实现将AXI_BRAM里面我们生成的数据发送到
// AXI_FIFO里面去。
//
// CopyRight(c) 2020, xxx xxx xxx Co., Ltd.. 
// All Rights Reserved
//
// *********************************************************************************/
// Modification History:
// 1. initial
// *********************************************************************************/
// *************************
// MODULE DEFINITION
// *************************
`timescale 1 ps / 1 ps
module bram_control_burst#(
parameter	U_DLY = 1
										)
										(
input	wire		lb_clk				,
input	wire		lb_rst				,
input	wire	    reg_axi_write	    ,		
input	wire    	reg_axi_read        ,
//AXI_BRAM写接口
input   wire [31:0] S_AXI_WDATA         ,
input   wire [3:0]  S_AXI_WSTRB         ,
input   wire        S_AXI_WLAST         ,
input   wire        S_AXI_WVALID        ,
output  wire        S_AXI_WREADY        ,

//AXI_BRAM接口
output  wire [3:0]  s_axi_rid           ,//读IDtag。RID的数值必须与ARID的数值匹配
output  wire [31:0] s_axi_rdata         ,//读数据
output  wire [1:0]  s_axi_rresp         ,//读响应。这个信号指明读传输状态
output  wire        s_axi_rlast         ,//读取最后一个数据
output  wire        s_axi_rvalid        ,//读取有效'1'读数据有效
input   wire        s_axi_rready         //读数据就绪'1'主机就绪

										);
//--------------------------------------
// localparam
//--------------------------------------

//--------------------------------------
// register
//--------------------------------------

//--------------------------------------
// wire
//--------------------------------------
//全局信号
wire 				rsta_busy			;
wire 				rstb_busy			;
wire 				s_aclk				;//时钟 
wire 				s_aresetn			;//复位 
//写地址通道
wire[3:0]			s_axi_awid			;//写地址ID,这个信号是写地址信号组的IDtag      
wire[31:0]			s_axi_awaddr		;//写地址    
wire[7:0]			s_axi_awlen			;//突发次数
wire[2:0]			s_axi_awsize		;//一次传输字节数。一个时钟节拍传输的数据的最大位。s_axi_awsize = 3'b000,传输1byte。s_axi_awsize = 3'b001,传输2byte。s_axi_awsize = 3'b010,传输4byte。s_axi_awsize = 3'b011,传输8byte。s_axi_awsize = 3'b100,传输16byte。s_axi_awsize = 3'b101,传输32byte。s_axi_awsize = 3'b110,传输64byte。s_axi_awsize = 3'b111,传输128byte。
wire[1:0]			s_axi_awburst		;//突发类型
wire 				s_axi_awvalid		;//握手信号,写地址有效。'1'有效
wire 				s_axi_awready		;//握手。写地址准备好,'1'设备准备好
//写数据通道
wire[31:0]			s_axi_wdata			;//写入数据     
wire[3:0]			s_axi_wstrb			;//写阀门,WSTRB[n]表示的区间为WDATA[(8*n) + 7:(8*n)];说明:s_axi_wstrb[0]表示s_axi_wdata[7:0]有效。依次类推。
wire				s_axi_wlast			;//最后一个数据  
wire				s_axi_wvalid		;//写数据有效
wire 				s_axi_wready		;//写数据准备就绪
//写请求通道
wire [3:0]			s_axi_bid			;//响应ID,这个数值必须与AWID的数值匹配。
wire [1:0]			s_axi_bresp			;//写入响应,这个信号指明写事务的状态。可能有的响应:OKAY,EXOKAY,SLVERR,DECERR  
wire 				s_axi_bvalid		;//写响应有效。'1'有效
wire				s_axi_bready		;//接收响应就绪,该信号表示主机已经能够接受响应信息。'1'主机就绪
//读地址通道
wire[3:0]			s_axi_arid			;//读地址ID      
wire[31:0]			s_axi_araddr		;//低地址
wire[7:0]			s_axi_arlen			;//读地址突发长度
wire[2:0]			s_axi_arsize		;//一次传输字节数
wire[1:0]			s_axi_arburst		;//突发类型
wire				s_axi_arvalid		;//握手信号,读地址有效。该信号一直保持,直到ARREADY为高。'1'地址和控制信号有效。
wire 				s_axi_arready		;//握手信号,读地址就绪,指明设备已经准备好接收数据了。'1'设备就绪。
//读数据通道
//wire [3:0]		s_axi_rid			;//读IDtag。RID的数值必须与ARID的数值匹配
//wire [31:0]		s_axi_rdata			;//读数据
//wire [1:0]		s_axi_rresp			;//读响应。这个信号指明读传输状态
//wire 				s_axi_rlast			;//读取最后一个数据
//wire 				s_axi_rvalid		;//读取有效'1'读数据有效
//reg 				s_axi_rready		;//读数据就绪'1'主机就绪

//system signal
wire                lb_rst_n            ;

//--------------------------------------
// assign
//--------------------------------------
//system signal
assign      lb_rst_n = ~lb_rst;
assign      s_aclk = lb_clk;
assign      s_aresetn = ~lb_rst;

//assign      s_axi_wlast = (c_state == write && write_cnt == len) ? 1'b1 : 1'b0;

//写地址通道
assign      s_axi_awid	  =  4'b0000;
assign      s_axi_awaddr  =  32'b0;
assign      s_axi_awlen	  =  len;
assign      s_axi_awsize  =  3'b010;
assign      s_axi_awburst =  2'b01;
assign      s_axi_awvalid =  reg_axi_write;


//写数据通道
assign      S_AXI_WREADY = s_axi_wready;
assign      s_axi_wvalid = S_AXI_WVALID;
assign      s_axi_wlast  = S_AXI_WLAST;
assign      s_axi_wstrb  = S_AXI_WSTRB;
assign      s_axi_wdata  = S_AXI_WDATA;
//写响应
assign      s_axi_bready = 1'b1;

//读地址通道
assign      s_axi_arid	 =  4'b0;
assign      s_axi_araddr =  32'b0;
assign      s_axi_arlen	 =  len;
assign      s_axi_arsize =  3'b010;
assign      s_axi_arburst=  2'b01;
assign      s_axi_arvalid=  reg_axi_write;

//读数据通道


//------------------------------------------------------------
//------------------------------------------------------------

blk_mem_gen_0 u_double_ram (
    //全局信号
    .rsta_busy                  (rsta_busy                  ),          
    .rstb_busy                  (rstb_busy                  ),          
    .s_aclk                     (s_aclk                     ),
    .s_aresetn                  (s_aresetn                  ),
    //写地址通道
    .s_axi_awid                 (s_axi_awid                 ),//写地址ID        
    .s_axi_awaddr               (s_axi_awaddr               ),//写地址    
    .s_axi_awlen                (s_axi_awlen                ),//突发次数
    .s_axi_awsize               (s_axi_awsize               ),//一次传输字节数
    .s_axi_awburst              (s_axi_awburst              ),//突发类型
    .s_axi_awvalid              (s_axi_awvalid              ),//握手有效
    .s_axi_awready              (s_axi_awready              ),//握手准备好    
    //写数据通道 
    .s_axi_wdata                (s_axi_wdata                ),//写入数据     
    .s_axi_wstrb                (s_axi_wstrb                ),//表示写字节通道保存有效,在每8位的写数据总线上有1位被选通。
    .s_axi_wlast                (s_axi_wlast                ),//最后一个数据     
    .s_axi_wvalid               (s_axi_wvalid               ),//写数据有效
    .s_axi_wready               (s_axi_wready               ),//写数据准备就绪
    //写请求通道    
    .s_axi_bid                  (s_axi_bid                  ),//
    .s_axi_bresp                (s_axi_bresp                ),//写入响应   
    .s_axi_bvalid               (s_axi_bvalid               ),//写响应有效
    .s_axi_bready               (s_axi_bready               ),//已准备好写入响应
    //读地址通道
    .s_axi_arid                 (s_axi_arid                 ),//读地址ID      
    .s_axi_araddr               (s_axi_araddr               ),//低地址
    .s_axi_arlen                (s_axi_arlen                ),//读地址突发长度
    .s_axi_arsize               (s_axi_arsize               ),//一次传输字节数
    .s_axi_arburst              (s_axi_arburst              ),
    .s_axi_arvalid              (s_axi_arvalid              ),  
    .s_axi_arready              (s_axi_arready              ), 
    //读数据通道 
    .s_axi_rid                  (s_axi_rid                  ),          
    .s_axi_rdata                (s_axi_rdata                ),      
    .s_axi_rresp                (s_axi_rresp                ),      
    .s_axi_rlast                (s_axi_rlast                ),      
    .s_axi_rvalid               (s_axi_rvalid               ),    
    .s_axi_rready               (s_axi_rready               )
);

//------------------------------------------------------------
//------------------------------------------------------------

//------------------------------------------------------------
//------------------------------------------------------------
endmodule

仿真分析

AXI_FIFO写入数据。

 AXI_FIFO将数据读出。

 AXI_BRAM数据写入。

越使用,就越发现AXI总线的好用之处。再接再厉。 

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值