最近在关注的问题是怎么样从ps端丢数据到ram,

然后用ip核进行处理后再输送到ram,ps端可以读取。

参考文献:【OpenHW参赛手记】AXI-Stream接口开发详细流程

首先按照作者的探索思路在 VIVADO 2013.4 下实践了一下AXI-Stream-FIFO

bd:

standalone test:

#include "xparameters.h"
#include "platform.h"
#include "xllfifo.h"   //包含AXI-FIFO-Stream控制接口头文件
#define r1 t1           //收发都是一个模块完成的,所以。。。
XLlFifo t1;                 //AXI-FIFO Stream控制模块
int sendram[8] = {1,2,3,4,5,6,7,8};   //发送缓冲区
int recvram[8] = {0,0,0,0,0,0,0,0};    //接收缓冲区#define AXI_FIFO_BASE 0x7AA00000    //AXI-FIFO模块内存映射地址//下面都是寄存器偏移量(按字计,不是字节,因为这里使用unsigned int指针)
#define ISR 0
#define IER 1
#define TDFR 2
#define TDFV 3
#define TDFD 4
#define TLF 5
#define RDFR 6
#define RDFO 7
#define RDFD 8
#define RLF 9
#define LLR 10//用于调试,打印关键寄存器的值
void debug_register(unsigned int * p)
{printf("ISR = 0x%x\n",*(p+ISR));if(*(p+ISR)){unsigned int t = *(p+ISR);*(p+ISR)=t&0xffffffff;}printf("ISR = 0x%x\n",*(p+ISR));printf("IER = 0x%x\n",*(p+IER));printf("TDFR = 0x%x\n",*(p+TDFR));printf("TDFV = 0x%x\n",*(p+TDFV));printf("TDFD = 0x%x\n",*(p+TDFD));printf("TLF = 0x%x\n",*(p+TLF));printf("RDFR = 0x%x\n",*(p+RDFR));printf("RDFO = 0x%x\n",*(p+RDFO));
// printf("RDFD = 0x%x\n",*(p+RDFD));
// printf("RLF = 0x%x\n",*(p+RLF));   //千万别轻易读这个,会复位的!printf("LLR = 0x%x\n",*(p+LLR));
}
int main()
{int status=0;int rxlen;   //接收字节数init_platform();printf("Hello World\n\r");debug_register((unsigned int *)AXI_FIFO_BASE);XLlFifo_Initialize(&t1,AXI_FIFO_BASE);//初始化AXI-FIFO模块//   XLlFifo_Initialize(&r1,0x74200000);//由于收发一体,故只需初始化一次XLlFifo_Write(&t1,sendram,8*4);//写发送缓冲区的内容到发送FIFOXLlFifo_TxSetLen(&r1,8*4);//启动发送过程print("Transmit begin!\n\r");
//    debug_register((unsigned int *)AXI_FIFO_BASE);if(XLlFifo_RxOccupancy(&r1))   //如果接收FIFO中有内容{rxlen=XLlFifo_RxGetLen(&r1);//先获取其长度printf("Rcv Length:%d\n",rxlen);XLlFifo_Read(&r1, recvram,rxlen);//读取接收内容int sum=0,i;for(i = 0;i<8;i++){if(recvram[i]!=sendram[i])//如果接收不等于发送{printf("Error in index %d\n",i);//那么就报错,并报告接收内容sum++;//错误计数}}if(sum==0){printf("Success!\n");//无错,则成功}}print("Transmit done!\n\r");cleanup_platform();return 0;
}

然后把自己的ip核连接到axi-dma上去,实现STREAM到ps端的数据传输:

bd:

address:

暂时只是把博主的ip核复制过来测试,文件列表如下

顶层文件:

    module my_stream_ip_v1_0 #(// Users to add parameters here// User parameters ends// Do not modify the parameters beyond this line// Parameters of Axi Slave Bus Interface S01_AXISparameter integer C_S01_AXIS_TDATA_WIDTH  = 32,// Parameters of Axi Master Bus Interface M00_AXISparameter integer C_M00_AXIS_TDATA_WIDTH    = 32,parameter integer C_M00_AXIS_START_COUNT  = 32)(// Users to add ports here// User ports ends// Do not modify the ports beyond this line// Ports of Axi Slave Bus Interface S01_AXISinput wire  s01_axis_aclk,input wire  s01_axis_aresetn,output wire  s01_axis_tready,input wire [C_S01_AXIS_TDATA_WIDTH-1 : 0] s01_axis_tdata,input wire [(C_S01_AXIS_TDATA_WIDTH/8)-1 : 0] s01_axis_tstrb,input wire  s01_axis_tlast,input wire  s01_axis_tvalid,// Ports of Axi Master Bus Interface M00_AXISinput wire  m00_axis_aclk,input wire  m00_axis_aresetn,output wire  m00_axis_tvalid,output wire [C_M00_AXIS_TDATA_WIDTH-1 : 0] m00_axis_tdata,output wire [(C_M00_AXIS_TDATA_WIDTH/8)-1 : 0] m00_axis_tstrb,output wire  m00_axis_tlast,input wire  m00_axis_tready);my_stream_ip my_stream_ip_v1_0_S01_AXIS_inst (.ACLK(s01_axis_aclk),.ARESETN(s01_axis_aresetn),.S_AXIS_TREADY(s01_axis_tready),.S_AXIS_TDATA(s01_axis_tdata),.S_AXIS_TLAST(s01_axis_tlast),.S_AXIS_TVALID(s01_axis_tvalid),.M_AXIS_TVALID(m00_axis_tvalid),.M_AXIS_TDATA(m00_axis_tdata),.M_AXIS_TLAST(m00_axis_tlast),.M_AXIS_TREADY(m00_axis_tready));
// Instantiation of Axi Bus Interface S01_AXIS
//  my_stream_ip_v1_0_S01_AXIS # (
//      .C_S_AXIS_TDATA_WIDTH(C_S01_AXIS_TDATA_WIDTH)
//  ) my_stream_ip_v1_0_S01_AXIS_inst (
//      .S_AXIS_ACLK(s01_axis_aclk),
//      .S_AXIS_ARESETN(s01_axis_aresetn),
//      .S_AXIS_TREADY(s01_axis_tready),
//      .S_AXIS_TDATA(s01_axis_tdata),
//      .S_AXIS_TSTRB(s01_axis_tstrb),
//      .S_AXIS_TLAST(s01_axis_tlast),
//      .S_AXIS_TVALID(s01_axis_tvalid)
//  );// Instantiation of Axi Bus Interface M00_AXIS
//  my_stream_ip_v1_0_M00_AXIS # (
//      .C_M_AXIS_TDATA_WIDTH(C_M00_AXIS_TDATA_WIDTH),
//      .C_M_START_COUNT(C_M00_AXIS_START_COUNT)
//  ) my_stream_ip_v1_0_M00_AXIS_inst (
//      .M_AXIS_ACLK(m00_axis_aclk),
//      .M_AXIS_ARESETN(m00_axis_aresetn),
//      .M_AXIS_TVALID(m00_axis_tvalid),
//      .M_AXIS_TDATA(m00_axis_tdata),
//      .M_AXIS_TSTRB(m00_axis_tstrb),
//      .M_AXIS_TLAST(m00_axis_tlast),
//      .M_AXIS_TREADY(m00_axis_tready)
//  );// Add user logic here// User logic endsendmodule

ip核单个文件:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 06/17/2014 04:46:15 PM
// Design Name:
// Module Name: stream_ip
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module my_stream_ip  (  ACLK,  ARESETN,  S_AXIS_TREADY,  S_AXIS_TDATA,  S_AXIS_TLAST,  S_AXIS_TVALID,  M_AXIS_TVALID,  M_AXIS_TDATA,  M_AXIS_TLAST,  M_AXIS_TREADY,  );  input                                    ACLK;
input                                    ARESETN;
output                                   S_AXIS_TREADY;
input      [31 :0]                      S_AXIS_TDATA;
input                                    S_AXIS_TLAST;
input                                    S_AXIS_TVALID;
output                                   M_AXIS_TVALID;
output     [31 :0]                      M_AXIS_TDATA;
output                                   M_AXIS_TLAST;
input                                    M_AXIS_TREADY;  localparam NUMBER_OF_INPUT_WORDS  = 8;  localparam NUMBER_OF_OUTPUT_WORDS = 8;  localparam Idle  =3'b100;  localparam Read_Inputs = 3'b010;  localparam Write_Outputs  = 3'b001;  reg [2:0] state;  reg [31:0] sum;  reg [NUMBER_OF_INPUT_WORDS -1:0] nr_of_reads;  reg [NUMBER_OF_OUTPUT_WORDS - 1:0] nr_of_writes;  assign S_AXIS_TREADY  =(state == Read_Inputs);  assign M_AXIS_TVALID = (state == Write_Outputs);  assign M_AXIS_TDATA = sum;  assign M_AXIS_TLAST = (nr_of_writes == 1);  always @(posedge ACLK)  begin  // process The_SW_accelerator  if(!ARESETN)              // Synchronous reset (active low)  begin  state        <= Idle;  nr_of_reads <= 0;  nr_of_writes <=0;  sum          <= 0;  end  else  case (state)  Idle:  if (S_AXIS_TVALID== 1)  begin  state       <= Read_Inputs;  nr_of_reads <= NUMBER_OF_INPUT_WORDS - 1;  sum         <= 0;  end  Read_Inputs:  if(S_AXIS_TVALID == 1)  begin  sum         <= sum + S_AXIS_TDATA;  if (nr_of_reads == 0)  begin  state        <= Write_Outputs;  nr_of_writes <= NUMBER_OF_OUTPUT_WORDS - 1;  end  else  nr_of_reads <= nr_of_reads - 1;  end  Write_Outputs:  if(M_AXIS_TREADY == 1)  begin  if (nr_of_writes == 0)  state <= Idle;  else  nr_of_writes <= nr_of_writes - 1;  end  endcase  end  endmodule  

完成,generate bit stream

sdk测试也是用的博主的测试文件:

    #include <stdio.h>#include <stdlib.h>#include "platform.h"#include "xil_cache.h"          //必须包含该头文件,实现cache操作#define sendram ((int *)0x10000000)          //发送缓冲区#define recvram ((int *)0x10001000)          //接收缓冲区#define sizeofbuffer 32void print(char *str);#define WITH_SG 0#define AXI_DMA_BASE 0x40400000#define MM2S_DMACR 0#define MM2S_DMASR 1#if WITH_SG#define MM2S_CURDESC 2#define MM2S_TAILDESC 4#else#define MM2S_SA 6#define MM2S_LENGTH 10#endif#define S2MM_DMACR 12#define S2MM_DMASR 13#if WITH_SG#define S2MM_CURDESC14#define S2MM_TAILDESC16#else#define S2MM_DA 18#define S2MM_LENGTH 22#endifvoid debug_axi_dma_register(unsigned int *p){printf("MM2S_DMACR = 0x%x\n",*(p+MM2S_DMACR));printf("MM2S_DMASR = 0x%x\n",*(p+MM2S_DMASR));#if WITH_SGprintf("MM2S_CURDESC = 0x%x\n",*(p+MM2S_CURDESC));printf("MM2S_TAILDESC = 0x%x\n",*(p+MM2S_TAILDESC));#elseprintf("MM2S_SA = 0x%x\n",*(p+MM2S_SA));printf("MM2S_LENGTH = 0x%x\n",*(p+MM2S_LENGTH));#endifprintf("S2MM_DMACR =0x%x\n",*(p+S2MM_DMACR));printf("S2MM_DMACSR =0x%x\n",*(p+S2MM_DMASR));#if WITH_SGprintf("S2MM_CURDESC =0x%x\n",*(p+S2MM_CURDESC));printf("S2MM_TAILDESC= 0x%x\n",*(p+S2MM_TAILDESC));#elseprintf("S2MM_DA =0x%x\n",*(p+S2MM_DA));printf("S2MM_LENGTH =0x%x\n",*(p+S2MM_LENGTH));#endif}void init_axi_dma_simple(unsigned int * p){*(p+MM2S_DMACR) = 0x04;  //reset send axi dmawhile(*(p+MM2S_DMACR)&0x04);*(p+S2MM_DMACR) =0x04;  //reset send axi dmawhile(*(p+S2MM_DMACR)&0x04);*(p+MM2S_DMACR)=1;while((*(p+MM2S_DMASR)&0x01));*(p+S2MM_DMACR)=1;while((*(p+S2MM_DMASR)&0x01));*(p+MM2S_SA) = (unsigned int )sendram;*(p+S2MM_DA) =(unsigned int )recvram;Xil_DCacheFlushRange((u32)sendram,sizeofbuffer); //将cache内容同步到DDR2*(p+S2MM_LENGTH) =sizeofbuffer;//sizeof(recvram);*(p+MM2S_LENGTH) = sizeofbuffer;//sizeof(sendram);while(!(*(p+MM2S_DMASR)&0x1000)); //wait for send ok}void init_sendbuffer(){int i;for(i=0;i< sizeofbuffer/4;i++){sendram[i]=i*2;}}void show_recvbuffer(){int i;printf("Recv contents are:\n");for(i=0;i< sizeofbuffer/4;i++){printf("%d\t",recvram[i]);}printf("\r\n");}void show_sendbuffer(){int i;printf("Send contents are:\n");for(i=0;i< sizeofbuffer/4;i++){printf("%d\t",sendram[i]);}printf("\r\n");}int main(){unsigned int status=0;int rxlen;init_platform();init_sendbuffer();init_axi_dma_simple((unsigned int *)AXI_DMA_BASE);printf("Hello World\n\rPlease input data:");while(1){scanf("%x",&status);printf("Got 0x%x\n",status);debug_axi_dma_register((unsigned int *)AXI_DMA_BASE);if(status==0){break;}}show_sendbuffer();Xil_DCacheInvalidateRange((u32)recvram,sizeofbuffer);      //将DDR2内容同步到cacheshow_recvbuffer();cleanup_platform();return 0;}

测试结果如下:

下一步修改博主的逻辑到vivado自动生成的两个端口的verilog代码中。。。

ip核顶层文件my_stream_ip_v1_0.v

    module my_stream_ip_v1_0 #(// Users to add parameters here// User parameters ends// Do not modify the parameters beyond this line// Parameters of Axi Slave Bus Interface S00_AXISparameter integer C_S00_AXIS_TDATA_WIDTH  = 32,// Parameters of Axi Master Bus Interface M00_AXISparameter integer C_M00_AXIS_TDATA_WIDTH    = 32,parameter integer C_M00_AXIS_START_COUNT  = 32)(// Users to add ports here// User ports ends// Do not modify the ports beyond this line// Ports of Axi Slave Bus Interface S00_AXISinput wire  s00_axis_aclk,input wire  s00_axis_aresetn,output wire  s00_axis_tready,input wire [C_S00_AXIS_TDATA_WIDTH-1 : 0] s00_axis_tdata,input wire [(C_S00_AXIS_TDATA_WIDTH/8)-1 : 0] s00_axis_tstrb,input wire  s00_axis_tlast,input wire  s00_axis_tvalid,// Ports of Axi Master Bus Interface M00_AXISinput wire  m00_axis_aclk,input wire  m00_axis_aresetn,output wire  m00_axis_tvalid,output wire [C_M00_AXIS_TDATA_WIDTH-1 : 0] m00_axis_tdata,output wire [(C_M00_AXIS_TDATA_WIDTH/8)-1 : 0] m00_axis_tstrb,output wire  m00_axis_tlast,input wire  m00_axis_tready);wire [31 : 0] fifo_data;// Instantiation of Axi Bus Interface S00_AXISmy_stream_ip_v1_0_S00_AXIS # ( .C_S_AXIS_TDATA_WIDTH(C_S00_AXIS_TDATA_WIDTH)) my_stream_ip_v1_0_S00_AXIS_inst (.S_AXIS_ACLK(s00_axis_aclk),.S_AXIS_ARESETN(s00_axis_aresetn),.S_AXIS_TREADY(s00_axis_tready),.S_AXIS_TDATA(s00_axis_tdata),.S_AXIS_TSTRB(s00_axis_tstrb),.S_AXIS_TLAST(s00_axis_tlast),.S_AXIS_TVALID(s00_axis_tvalid),.fifo(fifo_data));// Instantiation of Axi Bus Interface M00_AXISmy_stream_ip_v1_0_M00_AXIS # ( .C_M_AXIS_TDATA_WIDTH(C_M00_AXIS_TDATA_WIDTH),.C_M_START_COUNT(C_M00_AXIS_START_COUNT)) my_stream_ip_v1_0_M00_AXIS_inst (.M_AXIS_ACLK(m00_axis_aclk),.M_AXIS_ARESETN(m00_axis_aresetn),.M_AXIS_TVALID(m00_axis_tvalid),.M_AXIS_TDATA(m00_axis_tdata),.M_AXIS_TSTRB(m00_axis_tstrb),.M_AXIS_TLAST(m00_axis_tlast),.M_AXIS_TREADY(m00_axis_tready),.fifo(fifo_data));// Add user logic here// User logic endsendmodule

ip核axi stream master口对应verilog文件my_stream_ip_v1_0_M00_AXIS.v

  module my_stream_ip_v1_0_M00_AXIS #(// Users to add parameters here// User parameters ends// Do not modify the parameters beyond this line// Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH.parameter integer C_M_AXIS_TDATA_WIDTH   = 32,// Start count is the numeber of clock cycles the master will wait before initiating/issuing any transaction.parameter integer C_M_START_COUNT    = 32)(// Users to add ports here// User ports ends// Do not modify the ports beyond this line// Global portsinput wire  M_AXIS_ACLK,// input wire  M_AXIS_ARESETN,// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. output wire  M_AXIS_TVALID,// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,// TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte.output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,// TLAST indicates the boundary of a packet.output wire  M_AXIS_TLAST,// TREADY indicates that the slave can accept a transfer in the current cycle.input wire  M_AXIS_TREADY,wire [31:0] fifo);//Total number of output data.// Total number of output data                                                 localparam NUMBER_OF_OUTPUT_WORDS = 8;                                               // function called clogb2 that returns an integer which has the                      // value of the ceiling of the log base 2.                                           function integer clogb2 (input integer bit_depth);                                   begin                                                                              for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                                      bit_depth = bit_depth >> 1;                                                    end                                                                                endfunction                                                                          // WAIT_COUNT_BITS is the width of the wait counter.                                 localparam integer WAIT_COUNT_BITS = clogb2(C_M_START_COUNT-1);                      // bit_num gives the minimum number of bits needed to address 'depth' size of FIFO.  localparam bit_num  = clogb2(NUMBER_OF_OUTPUT_WORDS);                                // Define the states of state machine                                                // The control state machine oversees the writing of input streaming data to the FIFO,// and outputs the streaming data from the FIFO                                      parameter [1:0] IDLE = 2'b00,        // This is the initial/idle state               INIT_COUNTER  = 2'b01, // This state initializes the counter, ones   // the counter reaches C_M_START_COUNT count,        // the state machine changes state to INIT_WRITE     SEND_STREAM   = 2'b10; // In this state the                          // stream data is output through M_AXIS_TDATA   // State variable                                                                    reg [1:0] mst_exec_state;                                                            // Example design FIFO read pointer                                                  reg [bit_num-1:0] read_pointer;                                                      // AXI Stream internal signals//wait counter. The master waits for the user defined number of clock cycles before initiating a transfer.reg [WAIT_COUNT_BITS-1 : 0]    count;//streaming data validwire    axis_tvalid;//streaming data valid delayed by one clock cyclereg    axis_tvalid_delay;//Last of the streaming data wire     axis_tlast;//Last of the streaming data delayed by one clock cyclereg   axis_tlast_delay;//FIFO implementation signalsreg [C_M_AXIS_TDATA_WIDTH-1 : 0]  stream_data_out;wire    tx_en;//The master has issued all the streaming data stored in FIFOreg      tx_done;// I/O Connections assignmentsassign M_AXIS_TVALID  = axis_tvalid_delay;assign M_AXIS_TDATA    = stream_data_out;assign M_AXIS_TLAST  = axis_tlast_delay;assign M_AXIS_TSTRB = {(C_M_AXIS_TDATA_WIDTH/8){1'b1}};// Control state machine implementation                             always @(posedge M_AXIS_ACLK)                                             begin                                                                     if (!M_AXIS_ARESETN)                                                    // Synchronous reset (active low)                                       begin                                                                 mst_exec_state <= IDLE;                                             count    <= 0;                                                      end                                                                   else                                                                    case (mst_exec_state)                                                 IDLE:                                                               // The slave starts accepting tdata when                          // there tvalid is asserted to mark the                           // presence of valid streaming data                               if ( count == 0 )                                                 begin                                                           mst_exec_state  <= INIT_COUNTER;                              end                                                             else                                                              begin                                                           mst_exec_state  <= IDLE;                                      end                                                             INIT_COUNTER:                                                       // The slave starts accepting tdata when                          // there tvalid is asserted to mark the                           // presence of valid streaming data                               if ( count == C_M_START_COUNT - 1 )                               begin                                                           mst_exec_state  <= SEND_STREAM;                               end                                                             else                                                              begin                                                           count <= count + 1;                                           mst_exec_state  <= INIT_COUNTER;                              end                                                             SEND_STREAM:                                                        // The example design streaming master functionality starts       // when the master drives output tdata from the FIFO and the slave// has finished storing the S_AXIS_TDATA                          if (tx_done)                                                      begin                                                           mst_exec_state <= IDLE;                                       end                                                             else                                                              begin                                                           mst_exec_state <= SEND_STREAM;                                end                                                             endcase                                                               end                                                                       //tvalid generation//axis_tvalid is asserted when the control state machine's state is SEND_STREAM and//number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS.assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < NUMBER_OF_OUTPUT_WORDS));// AXI tlast generation                                                                        // axis_tlast is asserted number of output streaming data is NUMBER_OF_OUTPUT_WORDS-1          // (0 to NUMBER_OF_OUTPUT_WORDS-1)                                                             assign axis_tlast = (read_pointer == NUMBER_OF_OUTPUT_WORDS-1);                                // Delay the axis_tvalid and axis_tlast signal by one clock cycle                              // to match the latency of M_AXIS_TDATA                                                        always @(posedge M_AXIS_ACLK)                                                                  begin                                                                                          if (!M_AXIS_ARESETN)                                                                         begin                                                                                      axis_tvalid_delay <= 1'b0;                                                               axis_tlast_delay <= 1'b0;                                                                end                                                                                        else                                                                                         begin                                                                                      axis_tvalid_delay <= axis_tvalid;                                                        axis_tlast_delay <= axis_tlast;                                                          end                                                                                        end                                                                                            //read_pointer pointeralways@(posedge M_AXIS_ACLK)                                               begin                                                                            if(!M_AXIS_ARESETN)                                                            begin                                                                        read_pointer <= 0;                                                         tx_done <= 1'b0;                                                           end                                                                          else                                                                           if (read_pointer <= NUMBER_OF_OUTPUT_WORDS-1)                                begin                                                                      if (tx_en)                                                               // read pointer is incremented after every read from the FIFO          // when FIFO read signal is enabled.                                   begin                                                                  read_pointer <= read_pointer + 1;                                    tx_done <= 1'b0;                                                     end                                                                    end                                                                        else if (read_pointer == NUMBER_OF_OUTPUT_WORDS)                             begin                                                                      // tx_done is asserted when NUMBER_OF_OUTPUT_WORDS numbers of streaming data// has been out.                                                         tx_done <= 1'b1;                                                         end                                                                        end                                                                              //FIFO read enable generation assign tx_en = M_AXIS_TREADY && axis_tvalid;   // Streaming output data is read from FIFO       always @( posedge M_AXIS_ACLK )                  begin                                            if(!M_AXIS_ARESETN)                            begin                                        stream_data_out <= 1;                      end                                          else if (tx_en)// && M_AXIS_TSTRB[byte_index]  begin
//            stream_data_out <= read_pointer + 32'b1;   stream_data_out <= fifo;end                                          end                                              // Add user logic here// User logic endsendmodule

ip核axi stream slave口对应的verilog文件my_stream_ip_v1_0_S00_AXIS.v

 module my_stream_ip_v1_0_S00_AXIS #(// Users to add parameters here// User parameters ends// Do not modify the parameters beyond this line// AXI4Stream sink: Data Widthparameter integer C_S_AXIS_TDATA_WIDTH  = 32)(// Users to add ports here// User ports ends// Do not modify the ports beyond this line// AXI4Stream sink: Clockinput wire  S_AXIS_ACLK,// AXI4Stream sink: Resetinput wire  S_AXIS_ARESETN,// Ready to accept data inoutput wire  S_AXIS_TREADY,// Data ininput wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA,// Byte qualifierinput wire [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB,// Indicates boundary of last packetinput wire  S_AXIS_TLAST,// Data is in validinput wire  S_AXIS_TVALID,wire [31:0] fifo);// function called clogb2 that returns an integer which has the // value of the ceiling of the log base 2.function integer clogb2 (input integer bit_depth);beginfor(clogb2=0; bit_depth>0; clogb2=clogb2+1)bit_depth = bit_depth >> 1;endendfunction// Total number of input data.localparam NUMBER_OF_INPUT_WORDS  = 8;// bit_num gives the minimum number of bits needed to address 'NUMBER_OF_INPUT_WORDS' size of FIFO.localparam bit_num  = clogb2(NUMBER_OF_INPUT_WORDS-1);// Define the states of state machine// The control state machine oversees the writing of input streaming data to the FIFO,// and outputs the streaming data from the FIFOparameter [1:0] IDLE = 1'b0,        // This is the initial/idle state WRITE_FIFO  = 1'b1; // In this state FIFO is written with the// input stream data S_AXIS_TDATA wire     axis_tready;// State variablereg mst_exec_state;  // FIFO implementation signalsgenvar byte_index;     // FIFO write enablewire fifo_wren;// FIFO full flagreg fifo_full_flag;// FIFO write pointerreg [bit_num-1:0] write_pointer;// sink has accepted all the streaming data and stored in FIFOreg writes_done;// I/O Connections assignments//**********  my  code   ***************************************************reg [31:0] sum;assign S_AXIS_TREADY  = axis_tready;// Control state machine implementationalways @(posedge S_AXIS_ACLK) begin  if (!S_AXIS_ARESETN) // Synchronous reset (active low)beginmst_exec_state <= IDLE;end  elsecase (mst_exec_state)IDLE: // The sink starts accepting tdata when // there tvalid is asserted to mark the// presence of valid streaming data if (S_AXIS_TVALID)beginmst_exec_state <= WRITE_FIFO;endelsebeginmst_exec_state <= IDLE;endWRITE_FIFO: // When the sink has accepted all the streaming input data,// the interface swiches functionality to a streaming masterif (writes_done)beginmst_exec_state <= IDLE;endelsebegin// The sink accepts and stores tdata // into FIFOmst_exec_state <= WRITE_FIFO;endendcaseend// AXI Streaming Sink // // The example design sink is always ready to accept the S_AXIS_TDATA  until// the FIFO is not filled with NUMBER_OF_INPUT_WORDS number of input words.assign axis_tready = ((mst_exec_state == WRITE_FIFO) && (write_pointer <= NUMBER_OF_INPUT_WORDS-1));//********************   MY CODE HERE ************************************
//  reg  [31 : 0] fifo_data;
//    assign fifo = fifo_data;always@(posedge S_AXIS_ACLK)beginif(!S_AXIS_ARESETN)beginwrite_pointer <= 0;writes_done <= 1'b0;
//        fifo_data <= 32'b0;//********************   MY CODE HERE ************************************
//          sum <= 0;end  elseif (write_pointer <= NUMBER_OF_INPUT_WORDS-1)beginif (fifo_wren)begin//******************************************************************
//                sum <= sum + S_AXIS_TDATA;
//                fifo_data <= sum;// write pointer is incremented after every write to the FIFO// when FIFO write signal is enabled.write_pointer <= write_pointer + 1;writes_done <= 1'b0;endif ((write_pointer == NUMBER_OF_INPUT_WORDS-1)|| S_AXIS_TLAST)begin// reads_done is asserted when NUMBER_OF_INPUT_WORDS numbers of streaming data // has been written to the FIFO which is also marked by S_AXIS_TLAST(kept for optional usage).
//                fifo_data <= sum;writes_done <= 1'b1;endend  end// FIFO write enable generationassign fifo_wren = S_AXIS_TVALID && axis_tready;// FIFO Implementationgenerate //开启3个线程,线程编号0~3,byte_indexfor(byte_index=0; byte_index<= (C_S_AXIS_TDATA_WIDTH/8-1); byte_index=byte_index+1)begin:FIFO_GEN//reg [7:0] stream_data_fifo [0:7]数组;reg  [(C_S_AXIS_TDATA_WIDTH/4)-1:0] stream_data_fifo [0 : NUMBER_OF_INPUT_WORDS-1];reg  [31 : 0] fifo_data;assign fifo = fifo_data;// Streaming input data is stored in FIFOalways @( posedge S_AXIS_ACLK )beginif (fifo_wren)// && S_AXIS_TSTRB[byte_index])begin
//            stream_data_fifo[write_pointer] <= S_AXIS_TDATA[(byte_index*8+7) -: 8];
//对于stream_data_fifo[i][8]的赋值,由write_pointer作为游标(在S_AXIS_ACLK和fifo_wren时递增1->8),
//取对于每个stream_data_fifo[write_pointer][8 down to 0]的赋值,取S_AXIS_TDATA的[(b_i*8+7):(b_i*8)]stream_data_fifo[write_pointer] <= S_AXIS_TDATA[(byte_index*8+7) -: 8];fifo_data <= fifo_data + S_AXIS_TDATA;end  end  end        endgenerate// Add user logic here// User logic endsendmodule

测试结果如下:

第二次则:

对于以下程序段的理解:

      generate for(byte_index=0; byte_index<= (C_S_AXIS_TDATA_WIDTH/8-1); byte_index=byte_index+1)begin:FIFO_GENreg  [(C_S_AXIS_TDATA_WIDTH/4)-1:0] stream_data_fifo [0 : NUMBER_OF_INPUT_WORDS-1];// Streaming input data is stored in FIFOalways @( posedge S_AXIS_ACLK )beginif (fifo_wren)// && S_AXIS_TSTRB[byte_index])beginstream_data_fifo[write_pointer] <= S_AXIS_TDATA[(byte_index*8+7) -: 8];end  end  end        endgenerate

理解(图):

重点:经过测试发现,只有generate 代码块中声明的reg才会将S_AXIS_TDATA的数据存好,并且在接到Master口中读取的时候才能够被读出,而如果将计算sum和存储改到如下段落,在Master端只能读到0:

 reg  [31 : 0] fifo_data;assign fifo = fifo_data;always@(posedge S_AXIS_ACLK)beginif(!S_AXIS_ARESETN)beginwrite_pointer <= 0;writes_done <= 1'b0;
//        fifo_data <= 32'b0;//********************   MY CODE HERE ************************************sum <= 0;end  elseif (write_pointer <= NUMBER_OF_INPUT_WORDS-1)beginif (fifo_wren)begin//******************************************************************sum <= sum + S_AXIS_TDATA;fifo_data <= sum;// write pointer is incremented after every write to the FIFO// when FIFO write signal is enabled.write_pointer <= write_pointer + 1;writes_done <= 1'b0;endif ((write_pointer == NUMBER_OF_INPUT_WORDS-1)|| S_AXIS_TLAST)begin// reads_done is asserted when NUMBER_OF_INPUT_WORDS numbers of streaming data // has been written to the FIFO which is also marked by S_AXIS_TLAST(kept for optional usage).fifo_data <= sum;writes_done <= 1'b1;endend  end

而且,在generate代码段中声明的寄存器值可以一直保留。

转载于:https://www.cnblogs.com/shenerguang/p/3793215.html

Learn ZYNC (6)相关推荐

  1. 【Kaggle Learn】Python 1-4

    [Kaggle Learn]Python https://www.kaggle.com/learn/python 一. Hello, Python A quick introduction to Py ...

  2. Blender赛车动画制作学习教程 Learn Race Car Animation with Blender

    使用Blender 2.93创建您自己的惊人汽车动画 你会学到什么 Blender的界面和导航 建模 UV制图 材料 动画 照明设备 渲染 合成 要求 下载并安装Blender.免费下载和免费用于任何 ...

  3. Blender3.0动画制作入门学习教程 Learn Animation with Blender (2021)

    要求 下载并安装Blender.免费下载和免费用于任何目的. 描述 加入我的动画课程. 在本课程中,我将从头开始讲述在Blender中创建动画场景的过程. 从第一步到最终渲染.在这个课程中,我们将使用 ...

  4. Unity与C#创建一个3D平台游戏 Learn to Create a 3D Platformer Game with Unity C#

    游戏开发变得容易了.使用Unity学习C#并创建您自己的3D平台! 你会学到什么 学习现代通用编程语言C#. 了解Unity中3D开发的功能 发展强大的可转移的解决问题的技能 了解游戏开发过程 了解面 ...

  5. 学会在Unity中创建一个Match-3益智游戏 Learn To Create a Match-3 Puzzle Game in Unity

    MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:48场讲座(6h 38m) |大小解压后:2.8 G ...

  6. Unity中创建本地多人游戏完整案例视频教程 Learn To Create A Local Multiplayer Game In Unity

    Unity中创建本地多人游戏完整案例视频教程 Learn To Create A Local Multiplayer Game In Unity MP4 |视频:h264,1280x720 |音频:A ...

  7. Unity 3D游戏代码编程学习教程 Full Guide To Unity 3D C#: Learn To Code Making 3D Games

    Unity 3D游戏代码编程学习教程 Full Guide To Unity 3D & C#: Learn To Code Making 3D Games Full Guide To Unit ...

  8. 读书笔记2013第10本:《学得少却考得好Learn More Study Less》

    <学得少却考得好Learn More Study Less>这本书最早是从褪墨网站上看到的,crowncheng翻译了全文.这本书介绍了不少学习方法,非常适合在校的学生,原文的作者Scot ...

  9. The Road to learn React书籍学习笔记(第三章)

    代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() constructor() 构造函数只有在组件实例化并插入到 DOM ...

  10. Scikit Learn: 在python中机器学习

    Warning 警告:有些没能理解的句子,我以自己的理解意译. 翻译自:Scikit Learn:Machine Learning in Python 作者: Fabian Pedregosa, Ga ...

最新文章

  1. different application signatures解决方法
  2. torchvision.transforms包的使用
  3. asp.net core 自定义 Content-Type
  4. 序列化加密字段_自动加密可序列化的类
  5. 20什么情况下会帮助他人的因素
  6. nasm实现的用vmware运行自做的linux启动盘的引导代码
  7. 关于对象和类的那些小事
  8. mql 查询多结果_详解Oracle分页查询概念、缘由及如何实现
  9. vue官方webpack模版多个打包环境搭建
  10. oracle join(比较全面的解释了join)
  11. Flash Remoting+ Visual Studio .NET学习总结
  12. 长沙理工大学c语言编程题,长沙理工大学2014年上期期末c语言编程题库.doc
  13. API函数简介 转自洪恩在线
  14. Smobiler中Poplist控件的用法
  15. 根据身份证判断男女(通用)
  16. JS定时器原理及案例
  17. 用html创建数独,数独做不出来怎么办
  18. html水晶按钮图片,PS按钮制作高级教程之网页常用水晶按钮
  19. 【经验贴】小汽车科目二科目三 经验
  20. 计算机网络体系批判,基于批判性思维的计算机网络概论课程改革.pdf

热门文章

  1. linux 离线 nfs,Linux 系统 NFS服务
  2. 【2018CPCP-Final G:】Pastoral Life in Stardew Valley
  3. 风控模型面试问题汇总
  4. 计算机房采用c02采灭火,[灭火器使用.doc
  5. 图像空域增强:卷积运算法
  6. 算法:螺旋矩阵算出N行N列的数组Spiral Matrix II
  7. tensorflow安装中踩到的坑protobuf、h5py、tensorboard、werkzeug
  8. 【机器学习系列】变分推断第三讲:基于随机梯度上升法SGD的变分推断解法
  9. a ppt of CRF
  10. matlab aug,H无穷控制中的augss命令和编写的程序