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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_lib/] [src/] [axi4_m_to_read_fifos.sv] - Rev 50

Go to most recent revision | 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
  axi4_m_to_read_fifos
  #(
    A, // address bus width
    N,  // data bus width in bytes
    I,  // ID width
    R_D,
    AR_D,
    WATERMARK = 0,
    USE_ADVANCED_PROTOCOL = 0
  )
  (
    axi4_if     axi4_m,
    axi4_if     axi4_read_fifo,

    output      ar_wr_full,
    input       ar_wr_en,
    output      r_rd_empty,
    input       r_rd_en,
    output      r_topped_off,
    output      r_watermark,

    input       aclk,
    input       aresetn
  );

  // --------------------------------------------------------------------
  //
  localparam UB = $clog2(R_D);


  // --------------------------------------------------------------------
  //
  localparam R_W =
    8*N + //  logic [(8*N)-1:0]  rdata;
    I +   //  logic [(I-1):0]    rid;
    1 +   //  logic              rlast;
    2;    //  logic [1:0]        rresp;

  localparam AX_BASIC_W =
    A +  // logic [(A-1):0]    axaddr;
    2 +  // logic [1:0]        axburst;
    I +  // logic [(I-1):0]    axid;
    8 +  // logic [7:0]        axlen;
    3;   // logic [2:0]        axsize;

  localparam AX_ADVANCED_W =
    4 +   // logic [3:0]        axcache;
    1 +   // logic              axlock;
    3 +   // logic [2:0]        axprot;
    4 +   // logic [3:0]        axqos;
    4;    // logic [3:0]        axregion;

  localparam AR_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W;


  // --------------------------------------------------------------------
  //
  wire [AR_W-1:0] ar_rd_data;
  wire [AR_W-1:0] ar_wr_data;

  generate
    begin: ar_data_gen
      if(USE_ADVANCED_PROTOCOL)
      begin
        assign ar_wr_data =
          {
            axi4_read_fifo.araddr,
            axi4_read_fifo.arburst,
            axi4_read_fifo.arid,
            axi4_read_fifo.arlen,
            axi4_read_fifo.arsize,
            axi4_read_fifo.arcache,
            axi4_read_fifo.arlock,
            axi4_read_fifo.arprot,
            axi4_read_fifo.arqos,
            axi4_read_fifo.arregion
          };

        assign
          {
            axi4_m.araddr,
            axi4_m.arburst,
            axi4_m.arid,
            axi4_m.arlen,
            axi4_m.arsize,
            axi4_m.arcache,
            axi4_m.arlock,
            axi4_m.arprot,
            axi4_m.arqos,
            axi4_m.arregion
          } = ar_rd_data;
      end
      else
      begin
        assign ar_wr_data =
          {
            axi4_read_fifo.araddr,
            axi4_read_fifo.arburst,
            axi4_read_fifo.arid,
            axi4_read_fifo.arlen,
            axi4_read_fifo.arsize
          };

        assign axi4_read_fifo.arcache  = 0;
        assign axi4_read_fifo.arlock   = 0;
        assign axi4_read_fifo.arprot   = 0;
        assign axi4_read_fifo.arqos    = 0;
        assign axi4_read_fifo.arregion = 0;

        assign
          {
            axi4_m.araddr,
            axi4_m.arburst,
            axi4_m.arid,
            axi4_m.arlen,
            axi4_m.arsize
          } = ar_rd_data;

        assign axi4_m.arcache  = 0;
        assign axi4_m.arlock   = 0;
        assign axi4_m.arprot   = 0;
        assign axi4_m.arqos    = 0;
        assign axi4_m.arregion = 0;

      end
    end
  endgenerate


  // --------------------------------------------------------------------
  //
  wire ar_rd_empty;
  wire ar_rd_en = axi4_m.arready & axi4_m.arvalid;
  assign axi4_m.arvalid = ~ar_rd_empty;

  sync_fifo #(.W(AR_W), .D(AR_D))
    ar_fifo
    (
      .wr_full(ar_wr_full),
      .wr_data(ar_wr_data),
      .wr_en(ar_wr_en),
      .rd_empty(ar_rd_empty),
      .rd_data(ar_rd_data),
      .rd_en(ar_rd_en),
      .count(),
      .clk(aclk),
      .reset(~aresetn)
    );


  // --------------------------------------------------------------------
  //
  wire [R_W-1:0] r_rd_data;
  wire [R_W-1:0] r_wr_data;

  assign r_wr_data =
    {
      axi4_m.rid,
      axi4_m.rresp,
      axi4_m.rlast,
      axi4_m.rdata
    };

  assign
    {
      axi4_read_fifo.rid,
      axi4_read_fifo.rresp,
      axi4_read_fifo.rlast,
      axi4_read_fifo.rdata
    } = r_rd_data;


  // --------------------------------------------------------------------
  //
  wire [UB:0] r_count;

  generate
    begin: r_watermark_gen
      if(WATERMARK == 0)
      begin
        assign r_topped_off = 1;
        assign r_watermark = 0;
      end
      else
      begin
        reg r_topped_off_r;
        assign r_topped_off = r_topped_off_r;
        assign r_watermark = r_count > WATERMARK - 1;

        always_ff @(posedge aclk)
          if(~aresetn | r_rd_empty)
            r_topped_off_r <= 0;
          else if(r_watermark)
            r_topped_off_r <= 1;
      end
    end
  endgenerate


  // --------------------------------------------------------------------
  //
  wire r_wr_full;
  wire r_wr_en = axi4_m.rready & axi4_m.rvalid;
  assign axi4_m.rready = ~r_wr_full;

  sync_fifo #(.W(R_W), .D(R_D))
    r_fifo
    (
      .wr_full(r_wr_full),
      .wr_data(r_wr_data),
      .wr_en(r_wr_en),
      .rd_empty(r_rd_empty),
      .rd_data(r_rd_data),
      .rd_en(r_rd_en),
      .count(r_count),
      .clk(aclk),
      .reset(~aresetn)
    );


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

endmodule

Go to most recent revision | 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.