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 //////// //////////////////////////////////////////////////////////////////////////moduleaxis_to_axi4_basic_dma#(A, // address bus widthN, // data bus width in bytesI, // ID widthBASE_ADDRESS, // must be on 4K boundryBUFFER_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_offlocalparam N_4K = 'h1000 / 'h8; // number of bytes in 4Kinitialbegina_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;elsew_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
