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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_stream_lib/] [src/] [axis_upsizer.sv] - Rev 35

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_upsizer
  #(
    N,              // data bus width in bytes
    I = 1,          // TID width
    D = 1,          // TDEST width
    U,              // TUSER width
    S,              // tdata size multiplier
    USE_TSTRB = 0,  //  set to 1 to enable, 0 to disable
    USE_TKEEP = 0,  //  set to 1 to enable, 0 to disable
    BYTES_PER_TUSER //  bytes per tuser bit. Set to 0 for transfer based.
  )
  (
    axis_if axis_in,
    axis_if axis_out,
    input   aclk,
    input   aresetn
  );

// --------------------------------------------------------------------
// synthesis translate_off

  initial
  begin
    a_multiplier: assert((S > 1) & (S % 2 == 0))else $fatal;
    a_tstrb_unsuported: assert(USE_TSTRB == 0) else $fatal;
    a_tkeep_unsuported: assert(USE_TKEEP == 0) else $fatal;
    a_bytes_per_tuser: assert((BYTES_PER_TUSER == 0) | (N % BYTES_PER_TUSER == 0)) else $fatal;
    // a_tuser: assert((BYTES_PER_TUSER == 0) | (U % S == 0)) else $fatal;
  end

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


  // --------------------------------------------------------------------
  //
  localparam A = $clog2(S);
  localparam ED = 2 ** A;


  // --------------------------------------------------------------------
  //
  axis_if #(.N(N*S), .U(U*S)) axis_upsizer_bus(.*);
  wire last_word;


  //---------------------------------------------------
  //  state machine binary definitions
  enum reg [1:0]
    {
      GET_WORDS_IN  = 2'b01,
      WORD_OUT      = 2'b10
    } state, next_state;


  //---------------------------------------------------
  //  state machine flop
  always_ff @(posedge aclk)
    if(~aresetn)
      state <= GET_WORDS_IN;
    else
      state <= next_state;


  //---------------------------------------------------
  //  state machine
  always_comb
    case(state)
      GET_WORDS_IN:         if(axis_in.tvalid & last_word)
                              next_state <= WORD_OUT;
                            else
                              next_state <= GET_WORDS_IN;

      WORD_OUT:             if(axis_upsizer_bus.tready)
                              next_state <= GET_WORDS_IN;
                            else
                              next_state <= WORD_OUT;

      default:              next_state <= GET_WORDS_IN;

    endcase


  // --------------------------------------------------------------------
  //
  reg [A-1:0] index;
  wire roll_over = ~(index < S - 1) & axis_in.tready & axis_in.tvalid;

  always_ff @(posedge aclk)
    if(~aresetn | roll_over)
      index <= 0;
    else if(axis_in.tready & axis_in.tvalid)
      index <= index + 1;


  // --------------------------------------------------------------------
  //
  wire [ED-1:0] encoded;
  assign last_word = encoded[S-1];

  one_hot_encoder #(A)
    one_hot_encoder_i(index, encoded);


  // --------------------------------------------------------------------
  //
  reg tlast_in[S];
  reg [U-1:0] tuser_in[S];
  reg [(8*N)-1:0] tdata_in[S];
  wire [S-1:0] tlast_out_w;
  wire [(U*S)-1:0] tuser_out_w;
  wire [(8*N*S)-1:0] tdata_out_w;
  genvar j;

  generate
    for(j = 0; j < S; j++)
    begin: tdata_gen
      always_ff @(posedge aclk)
        if(encoded[j] & axis_in.tready & axis_in.tvalid)
        begin
          tdata_in[j] <= axis_in.tdata;
          tuser_in[j] <= axis_in.tuser;
          tlast_in[j] <= axis_in.tlast;
        end

      assign tlast_out_w[j]             = tlast_in[j];
      assign tuser_out_w[j*U +: U]      = tuser_in[j];
      assign tdata_out_w[j*N*8 +: N*8]  = tdata_in[j];
    end
  endgenerate


  // --------------------------------------------------------------------
  //
  assign axis_in.tready = (state == GET_WORDS_IN) | (next_state == GET_WORDS_IN);
  assign axis_upsizer_bus.tvalid  = (state == WORD_OUT);
  assign axis_upsizer_bus.tdata = tdata_out_w;
  assign axis_upsizer_bus.tuser = tuser_out_w;
  assign axis_upsizer_bus.tlast = tlast_out_w[S-1];


  // --------------------------------------------------------------------
  //
  axis_register_slice #(.N(N*S), .U(U*S))
    axis_register_slice_i(.axis_in(axis_upsizer_bus), .*);


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


Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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