OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_stream_lib/] [src/] [axis_to_axi4_basic_dma.sv] - Rev 31

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

module
  axis_to_axi4_basic_dma
  #(
    A, // address bus width
    N, // data bus width in bytes
    I, // ID width
    BASE_ADDRESS,       // must be on 4K boundry
    BUFFER_SIZE,
    BURST_LENGTH,
    MAX_BURSTS,
    BYTES_PER_TUSER = 0 //  bytes per tuser bit. Set to 0 for transfer based.
  )
  (
    axi4_if axi4_m,
    axis_if axis_in,    // tuser[0] indicates first words of buffer. The rest of tuser is not used.
    input   dma_enable,
    input   aclk,
    input   aresetn
  );

  // --------------------------------------------------------------------
  //
  localparam W_D = BURST_LENGTH * MAX_BURSTS;
  localparam AW_D = 2;
  localparam WATERMARK = BURST_LENGTH;
  localparam STRIDE = N * BURST_LENGTH;
  localparam ADDRESS_END = BASE_ADDRESS + BUFFER_SIZE;
  localparam ADDRESS_STOP = (ADDRESS_END % STRIDE == 0) ? ADDRESS_END : ADDRESS_END + STRIDE;
  // localparam U = N / BYTES_PER_TUSER;


// --------------------------------------------------------------------
// synthesis translate_off
  localparam N_4K = 'h1000 / 'h8; // number of bytes in 4K
  initial
  begin
    a_4k_mod_base_address: assert(BASE_ADDRESS % 'h1000 == 0) else $fatal;
    a_4k_gt_eq_stride: assert(N_4K >= STRIDE) else $fatal;
    a_4k_mod_stride: assert('h1000 % STRIDE == 0) else $fatal;
    a_burst_length: assert(BURST_LENGTH > 1) else $fatal;
    // a_bytes_per_tuser: assert(N % BYTES_PER_TUSER == 0) else $fatal;
  end

// synthesis translate_on
// --------------------------------------------------------------------


  // --------------------------------------------------------------------
  //
  axi4_if #(.A(A), .N(N), .I(I))  axi4_write_fifo(.*);


  // --------------------------------------------------------------------
  //
  wire axis_data_en = axis_in.tready  & axis_in.tvalid;
  wire start        = axis_data_en    & axis_in.tuser[0];


  // --------------------------------------------------------------------
  //
  reg [(A-1):0] awaddr_r;
  wire send_waddr;
  wire awaddr_en = (awaddr_r < ADDRESS_STOP);
  wire aw_wr_full;
  wire aw_wr_en = ~aw_wr_full & dma_enable & awaddr_en & send_waddr;
  wire w_wr_full;
  wire w_wr_en = axis_in.tready & axis_in.tvalid;
  wire w_topped_off;
  wire w_watermark;
  wire b_rd_empty;
  wire b_rd_en = ~b_rd_empty;


  // --------------------------------------------------------------------
  //
  reg [$clog2(W_D + 1):0] w_wr_counter;
  wire burst_ready = (w_wr_counter > BURST_LENGTH - 1);
  wire wlast = (w_wr_counter == BURST_LENGTH - 1);

  always_ff @(posedge aclk)
    if(~aresetn)
      w_wr_counter <= 0;
    else if(aw_wr_en)
      if(w_wr_en)
        w_wr_counter <= w_wr_counter - BURST_LENGTH + 1;
      else
        w_wr_counter <= w_wr_counter - BURST_LENGTH;
    else if(w_wr_en)
      w_wr_counter <= w_wr_counter + 1;


  // --------------------------------------------------------------------
  //
  // reg [$clog2(AW_D + 1):0] aw_wr_counter;
  // assign send_waddr = (aw_wr_counter > 0);
  assign send_waddr = burst_ready;

  // always_ff @(posedge aclk)
    // if(~aresetn)
      // aw_wr_counter <= 0;
    // else if(aw_wr_en & ~burst_ready)
      // aw_wr_counter <= aw_wr_counter - 1;
    // else if(~aw_wr_en & burst_ready)
      // aw_wr_counter <= aw_wr_counter + 1;


  // --------------------------------------------------------------------
  //
  always_ff @(posedge aclk)
    if(~aresetn | ~awaddr_en | start)
      awaddr_r <= BASE_ADDRESS;
    else if(aw_wr_en)
      awaddr_r <= awaddr_r + STRIDE;


  // --------------------------------------------------------------------
  //
  axi4_m_to_write_fifos
    #(
      .A(A),
      .N(N),
      .I(I),
      .W_D(W_D),
      .B_D(AW_D),
      .AW_D(AW_D),
      .WATERMARK(WATERMARK)
    )
    axi4_m_to_write_fifos_i(.*);


  // --------------------------------------------------------------------
  //
  assign axi4_write_fifo.awaddr    = awaddr_r;
  assign axi4_write_fifo.awid      = 0;
  assign axi4_write_fifo.awburst   = 2'b01;
  assign axi4_write_fifo.awsize    = $clog2(N);
  assign axi4_write_fifo.awlen     = BURST_LENGTH - 1;


  // --------------------------------------------------------------------
  //
  assign axi4_write_fifo.wdata  = axis_in.tdata;
  assign axi4_write_fifo.wid    = 0;
  assign axi4_write_fifo.wlast  = wlast;
  assign axi4_write_fifo.wstrb  = {N{1'b1}};


  // --------------------------------------------------------------------
  //
  assign axis_in.tready = ~w_wr_full & ~burst_ready;

  // --------------------------------------------------------------------
  //
  assign axi4_m.arvalid   = 0;
  assign axi4_m.rready    = 0;
  assign axi4_m.awcache   = 0;
  assign axi4_m.awlock    = 0;
  assign axi4_m.awprot    = 0;
  assign axi4_m.awqos     = 0;
  assign axi4_m.awregion  = 0;


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

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.