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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_stream_lib/] [src/] [axis_downsizer.sv] - Diff between revs 31 and 35

Only display areas with differences | Details | Blame | View Log

Rev 31 Rev 35
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
////                                                              ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
//// later version.                                               ////
////                                                              ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
//// details.                                                     ////
////                                                              ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
module
module
  axis_downsizer
  axis_downsizer
  #(
  #(
    N,              // data bus width in bytes
    N,              // data bus width in bytes
    I = 1,          // TID width
    I = 1,          // TID width
    D = 1,          // TDEST width
    D = 1,          // TDEST width
    U,              // TUSER width
    U,              // TUSER width
    S,              // tdata size divisor
    S,              // tdata size divisor
    USE_TSTRB = 0,  //  set to 1 to enable, 0 to disable
    USE_TSTRB = 0,  //  set to 1 to enable, 0 to disable
    USE_TKEEP = 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.
    BYTES_PER_TUSER //  bytes per tuser bit. Set to 0 for transfer based.
  )
  )
  (
  (
    axis_if axis_in,
    axis_if axis_in,
    axis_if axis_out,
    axis_if axis_out,
    input   aclk,
    input   aclk,
    input   aresetn
    input   aresetn
  );
  );
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// synthesis translate_off
// synthesis translate_off
  initial
  initial
  begin
  begin
    a_divisor: assert(S > 1) else $fatal;
    a_divisor: assert(S > 1) else $fatal;
    a_tdata_mod: assert(N % S == 0) else $fatal;
    a_tdata_mod: assert(N % S == 0) else $fatal;
    a_tstrb_unsuported: assert(USE_TSTRB == 0) else $fatal;
    a_tstrb_unsuported: assert(USE_TSTRB == 0) else $fatal;
    a_tkeep_unsuported: assert(USE_TKEEP == 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_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;
    a_tuser: assert((BYTES_PER_TUSER == 0) | (U % S == 0)) else $fatal;
  end
  end
// synthesis translate_on
// synthesis translate_on
// --------------------------------------------------------------------
// --------------------------------------------------------------------
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  localparam M_A = $clog2(S);
  localparam M_A = $clog2(S);
  localparam M_D = 2 ** M_A;
  localparam M_D = 2 ** M_A;
  localparam M_NW = (N*8)/ S;
  localparam M_NW = (N*8)/ S;
  localparam M_UW = U / S;
  localparam M_UW = U / S;
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  localparam U_OUT = (BYTES_PER_TUSER == 0) ? U : U / (N / BYTES_PER_TUSER);
  localparam U_OUT = (BYTES_PER_TUSER == 0) ? U : U / (N / BYTES_PER_TUSER);
  axis_if #(.N(N/S), .U(U_OUT)) axis_downsizer_bus(.*);
  axis_if #(.N(N/S), .U(U_OUT)) axis_downsizer_bus(.*);
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  wire almost_last_word;
  wire almost_last_word;
  //---------------------------------------------------
  //---------------------------------------------------
  //  state machine binary definitions
  //  state machine binary definitions
  enum reg [2:0]
  enum reg [2:0]
    {
    {
      GET_WORD_IN   = 3'b001,
      GET_WORD_IN   = 3'b001,
      MUX_WORD_OUT  = 3'b010,
      MUX_WORD_OUT  = 3'b010,
      LAST_WORD_OUT = 3'b100
      LAST_WORD_OUT = 3'b100
    } state, next_state;
    } state, next_state;
  //---------------------------------------------------
  //---------------------------------------------------
  //  state machine flop
  //  state machine flop
  always_ff @(posedge aclk)
  always_ff @(posedge aclk)
    if(~aresetn)
    if(~aresetn)
      state <= GET_WORD_IN;
      state <= GET_WORD_IN;
    else
    else
      state <= next_state;
      state <= next_state;
  //---------------------------------------------------
  //---------------------------------------------------
  //  state machine
  //  state machine
  always_comb
  always_comb
    case(state)
    case(state)
      GET_WORD_IN:          if(axis_in.tvalid)
      GET_WORD_IN:          if(axis_in.tvalid)
                              next_state <= MUX_WORD_OUT;
                              next_state <= MUX_WORD_OUT;
                            else
                            else
                              next_state <= GET_WORD_IN;
                              next_state <= GET_WORD_IN;
      MUX_WORD_OUT:         if(almost_last_word & axis_downsizer_bus.tready)
      MUX_WORD_OUT:         if(almost_last_word & axis_downsizer_bus.tready)
                              next_state <= LAST_WORD_OUT;
                              next_state <= LAST_WORD_OUT;
                            else
                            else
                              next_state <= MUX_WORD_OUT;
                              next_state <= MUX_WORD_OUT;
      LAST_WORD_OUT:        if(~axis_downsizer_bus.tready)
      LAST_WORD_OUT:        if(~axis_downsizer_bus.tready)
                              next_state <= LAST_WORD_OUT;
                              next_state <= LAST_WORD_OUT;
                            else if(axis_in.tvalid)
                            else if(axis_in.tvalid)
                              next_state <= MUX_WORD_OUT;
                              next_state <= MUX_WORD_OUT;
                            else
                            else
                              next_state <= GET_WORD_IN;
                              next_state <= GET_WORD_IN;
      default:              next_state <= GET_WORD_IN;
      default:              next_state <= GET_WORD_IN;
    endcase
    endcase
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  reg [(8*N)-1:0] tdata_r;
  reg [(8*N)-1:0] tdata_r;
  reg [I-1:0]     tid_r;
  reg [I-1:0]     tid_r;
  reg [D-1:0]     tdest_r;
  reg [D-1:0]     tdest_r;
  reg             tlast_r;
  reg             tlast_r;
  reg [U-1:0]     tuser_r;
  reg [U-1:0]     tuser_r;
  always_ff @(posedge aclk)
  always_ff @(posedge aclk)
    if(axis_in.tvalid & axis_in.tready)
    if(axis_in.tvalid & axis_in.tready)
    begin
    begin
      tdata_r <= axis_in.tdata;
      tdata_r <= axis_in.tdata;
      tid_r   <= axis_in.tid;
      tid_r   <= axis_in.tid;
      tdest_r <= axis_in.tdest;
      tdest_r <= axis_in.tdest;
      tlast_r <= axis_in.tlast;   // packet width % S == 0 else tlast becomes invalid
      tlast_r <= axis_in.tlast;   // packet width % S == 0 else tlast becomes invalid
      tuser_r <= axis_in.tuser;
      tuser_r <= axis_in.tuser;
    end
    end
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  reg [M_A-1:0] select;
  reg [M_A-1:0] select;
  assign almost_last_word = (select == S - 2);
  assign almost_last_word = (select == S - 2);
  always_ff @(posedge aclk)
  always_ff @(posedge aclk)
    if(~aresetn | (state == GET_WORD_IN))
    if(~aresetn | (state == GET_WORD_IN))
      select <= 0;
      select <= 0;
    else if(axis_downsizer_bus.tvalid & axis_downsizer_bus.tready)
    else if(axis_downsizer_bus.tvalid & axis_downsizer_bus.tready)
      select <= select + 1;
      select <= select + 1;
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  wire [M_NW-1:0] mux_in_tdata [M_D-1:0];
  wire [M_NW-1:0] mux_in_tdata [M_D-1:0];
  wire [M_NW-1:0] mux_out_tdata;
  wire [M_NW-1:0] mux_out_tdata;
  recursive_mux #(.A(M_A), .W(M_NW))
  recursive_mux #(.A(M_A), .W(M_NW))
    tdata_mux_i(.data_in(mux_in_tdata), .data_out(mux_out_tdata), .*);
    tdata_mux_i(.data_in(mux_in_tdata), .data_out(mux_out_tdata), .*);
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
 
  genvar j;
 
 
  generate
  generate
 
    for(j = 0; j < M_D; j++)
    begin: tdata_gen
    begin: tdata_gen
      for(genvar j = 0; j < M_D; j++)
 
        assign mux_in_tdata[j] = tdata_r[j*M_NW +: M_NW];
        assign mux_in_tdata[j] = tdata_r[j*M_NW +: M_NW];
    end
      end
  endgenerate
  endgenerate
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  generate
  generate
    begin: tuser_gen
    begin : tuser_gen
      if(BYTES_PER_TUSER != 0)
      if(BYTES_PER_TUSER != 0)
      begin
      begin : tuser_tuser_0_gen
        wire [M_UW-1:0] mux_in_tuser [M_D-1:0];
        wire [M_UW-1:0] mux_in_tuser [M_D-1:0];
        recursive_mux #(.A(M_A), .W(M_UW))
        recursive_mux #(.A(M_A), .W(M_UW))
          tuser_mux_i(.data_in(mux_in_tuser), .data_out(axis_downsizer_bus.tuser), .*);
          tuser_mux_i(.data_in(mux_in_tuser), .data_out(axis_downsizer_bus.tuser), .*);
 
 
        for(genvar j = 0; j < M_D; j++)
        for(j = 0; j < M_D; j++)
 
        begin : tuser_j_gen
          assign mux_in_tuser[j] = tuser_r[j*M_UW +: M_UW] & {M_UW{axis_downsizer_bus.tvalid}};
          assign mux_in_tuser[j] = tuser_r[j*M_UW +: M_UW] & {M_UW{axis_downsizer_bus.tvalid}};
      end
      end
 
      end
      else
      else
 
      begin : tuser_tuser_gen
        assign axis_downsizer_bus.tuser = tuser_r & {U{axis_downsizer_bus.tvalid}};
        assign axis_downsizer_bus.tuser = tuser_r & {U{axis_downsizer_bus.tvalid}};
    end
    end
 
    end
  endgenerate
  endgenerate
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  assign axis_in.tready   = (state == GET_WORD_IN) |
  assign axis_in.tready   = (state == GET_WORD_IN) |
                            ((state == LAST_WORD_OUT) & (next_state == MUX_WORD_OUT));
                            ((state == LAST_WORD_OUT) & (next_state == MUX_WORD_OUT));
  assign axis_downsizer_bus.tvalid  = (state != GET_WORD_IN);
  assign axis_downsizer_bus.tvalid  = (state != GET_WORD_IN);
  assign axis_downsizer_bus.tdata  = mux_out_tdata;
  assign axis_downsizer_bus.tdata  = mux_out_tdata;
  assign axis_downsizer_bus.tid    = tid_r;
  assign axis_downsizer_bus.tid    = tid_r;
  assign axis_downsizer_bus.tdest  = tdest_r;
  assign axis_downsizer_bus.tdest  = tdest_r;
  assign axis_downsizer_bus.tlast  = (select == S - 1) ? tlast_r : 1'b0;
  assign axis_downsizer_bus.tlast  = (select == S - 1) ? tlast_r : 1'b0;
  // --------------------------------------------------------------------
  // --------------------------------------------------------------------
  //
  //
  axis_register_slice #(.N(N), .U(U))
  axis_register_slice #(.N(N), .U(U))
    axis_register_slice_i(.axis_in(axis_downsizer_bus), .*);
    axis_register_slice_i(.axis_in(axis_downsizer_bus), .*);
// --------------------------------------------------------------------
// --------------------------------------------------------------------
//
//
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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