AMBA - AXI Stream DataWidth and Clock Converter IP (Xilinx)

AXI4-Stream DataWidth Converter (1.1): Ports Shown Below
FIG: Datawidth converter IP ports.

  • The meaning of this IP is just to make Width translation - to translate data width between TWO AXI Streams.
  • Left side: Slave AXI Stream with data width = 1 Byte.
  • Right Side: Master AXI stream with data width = 2 Bytes.
  • This IP supports DataWidth translation in both directions (both increase and decrease of data width).

Example Design:

Slave (.v):

//  (c) Copyright  2013 - 2019 Xilinx, Inc. All rights reserved.
//
//  This file contains confidential and proprietary information
//  of Xilinx, Inc. and is protected under U.S. and
//  international copyright and other intellectual property
//  laws.
//
//  DISCLAIMER
//  This disclaimer is not a license and does not grant any
//  rights to the materials distributed herewith. Except as
//  otherwise provided in a valid license issued to you by
//  Xilinx, and to the maximum extent permitted by applicable
//  law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
//  WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
//  AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
//  BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
//  INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
//  (2) Xilinx shall not be liable (whether in contract or tort,
//  including negligence, or under any other theory of
//  liability) for any loss or damage of any kind or nature
//  related to, arising under or in connection with these
//  materials, including for any direct, or any indirect,
//  special, incidental, or consequential loss or damage
//  (including loss of data, profits, goodwill, or any type of
//  loss or damage suffered as a result of any action brought
//  by a third party) even if such damage or loss was
//  reasonably foreseeable or Xilinx had been advised of the
//  possibility of the same.
//
//  CRITICAL APPLICATIONS
//  Xilinx products are not designed or intended to be fail-
//  safe, or for use in any application requiring fail-safe
//  performance, such as life-support or safety devices or
//  systems, Class III medical devices, nuclear facilities,
//  applications related to the deployment of airbags, or any
//  other applications that could lead to death, personal
//  injury, or severe property or environmental damage
//  (individually and collectively, "Critical
//  Applications"). Customer assumes the sole risk and
//  liability of any use of Xilinx products in Critical
//  Applications, subject only to applicable laws and
//  regulations governing limitations on product liability.
//
//  THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
//  PART OF THIS FILE AT ALL TIMES.
//-----------------------------------------------------------------------------

`timescale 1ps/1ps

`default_nettype none

module
axis_dwidth_converter_0_example_slave
(
  /**************** Stream Signals ****************/
  input  wire                            s_axis_tvalid,
  output reg                             s_axis_tready,
  input  wire [16-1:0]     s_axis_tdata,
  /**************** System Signals ****************/
  input  wire                            aclk,
  input  wire                            aresetn,
  /**************** Idle Signal ****************/
  output reg                             idle = 1'b0
);

  /**************** Local Parameters ****************/
  localparam [8-1:0] P_S_AXIS_IDLE_NUM = 8'h64;

  /**************** Internal Wires/Regs ****************/
  reg [8-1:0]    icnt_i = {8{1'b0}};
  reg                          acco_i = 1'b0;
  reg                          accen_i = 1'b0;
  wire                         acci_i;
  reg [16-1:0]   tdata_i = {16{1'b0}};
  wire                         areset = ~aresetn;

  //**********************************************
  // TREADY
  //**********************************************
  always @(posedge aclk) begin
    if(areset) begin
      s_axis_tready <= 1'b0;
    end
    else
    begin
      // Toggle TREADY to demonstrate slave backpressure
      s_axis_tready <= ~s_axis_tready;
    end
  end

  //**********************************************
  // PROCESS INPUTS
  //**********************************************
  always @(posedge aclk) begin
    if(areset) begin
      acco_i <= 1'b0;
      accen_i <= 1'b0;
    end
    else
    begin
      accen_i <= (s_axis_tready && s_axis_tvalid) ? 1'b1 : 1'b0;

      tdata_i <= s_axis_tdata;
      acco_i <= accen_i ? (acco_i | acci_i) : acco_i;
    end
  end

assign acci_i =
                (|tdata_i) |
                1'b0;

  //**********************************************
  // IDLE
  //**********************************************
  always @(posedge aclk) begin
    if(areset) begin
      idle <= 1'b0;
      icnt_i <= {8{1'b0}};
    end
    else
    begin
      // Increment counters
      if(s_axis_tvalid) begin
        icnt_i <= {8{1'b0}};
      end
      else if(~s_axis_tvalid && (icnt_i < P_S_AXIS_IDLE_NUM)) begin
        icnt_i <= icnt_i + 1'b1;
      end
      else begin
        icnt_i <= icnt_i;
      end

      // Assert idle
      if(icnt_i == (P_S_AXIS_IDLE_NUM -1)) begin
        idle <= acco_i;
      end
      else if(icnt_i == P_S_AXIS_IDLE_NUM) begin
        idle <= 1'b1;
      end
      else begin
        idle <= 1'b0;
      end
    end
  end
endmodule

`default_nettype wire


Master (.v):

//  (c) Copyright  2013 - 2019 Xilinx, Inc. All rights reserved.
//
//  This file contains confidential and proprietary information
//  of Xilinx, Inc. and is protected under U.S. and
//  international copyright and other intellectual property
//  laws.
//
//  DISCLAIMER
//  This disclaimer is not a license and does not grant any
//  rights to the materials distributed herewith. Except as
//  otherwise provided in a valid license issued to you by
//  Xilinx, and to the maximum extent permitted by applicable
//  law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
//  WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
//  AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
//  BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
//  INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
//  (2) Xilinx shall not be liable (whether in contract or tort,
//  including negligence, or under any other theory of
//  liability) for any loss or damage of any kind or nature
//  related to, arising under or in connection with these
//  materials, including for any direct, or any indirect,
//  special, incidental, or consequential loss or damage
//  (including loss of data, profits, goodwill, or any type of
//  loss or damage suffered as a result of any action brought
//  by a third party) even if such damage or loss was
//  reasonably foreseeable or Xilinx had been advised of the
//  possibility of the same.
//
//  CRITICAL APPLICATIONS
//  Xilinx products are not designed or intended to be fail-
//  safe, or for use in any application requiring fail-safe
//  performance, such as life-support or safety devices or
//  systems, Class III medical devices, nuclear facilities,
//  applications related to the deployment of airbags, or any
//  other applications that could lead to death, personal
//  injury, or severe property or environmental damage
//  (individually and collectively, "Critical
//  Applications"). Customer assumes the sole risk and
//  liability of any use of Xilinx products in Critical
//  Applications, subject only to applicable laws and
//  regulations governing limitations on product liability.
//
//  THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
//  PART OF THIS FILE AT ALL TIMES.
//-----------------------------------------------------------------------------

`timescale 1ps/1ps

`default_nettype none

module
axis_dwidth_converter_0_example_master #(
  parameter integer C_MASTER_ID = 0
)
(
  /**************** Stream Signals ****************/
  output reg                             m_axis_tvalid = 0,
  input  wire                            m_axis_tready,
  output wire [8-1:0]     m_axis_tdata,
  /**************** System Signals ****************/
  input  wire                            aclk,
  input  wire                            aresetn,
  /**************** Done Signal ****************/
  output reg                             done = 0
);

  /**************** Local Parameters ****************/
  localparam integer  P_M_TDATA_BYTES = 8 / 8;
  localparam [16-1:0] P_M_SINGLES_NUM = 256;
  localparam [17-1:0] P_M_DONE_NUM = 256;

  /**************** Internal Wires/Regs ****************/
  genvar  i;
  reg [8*P_M_TDATA_BYTES-1:0]  tdata_i = {P_M_TDATA_BYTES{8'h00}};
  reg [16-1:0] pcnt_i = 16'h0000;
  reg [16-1:0] tcnt_i = 16'h0000;
  wire         done_i;
  wire         transfer_i;
  wire         areset = ~aresetn;
  reg [2-1:0]  areset_i = 2'b00;

  /**************** Assign Signals ****************/
  assign m_axis_tdata = tdata_i;
  assign transfer_i = m_axis_tready && m_axis_tvalid;

    assign done_i = (transfer_i && (tcnt_i == P_M_DONE_NUM - 1'b1));


  // Register Reset
  always @(posedge aclk) begin
    areset_i <= {areset_i[0], areset};
  end

  //**********************************************
  // TDATA
  //**********************************************
  generate
    for(i=0; i<P_M_TDATA_BYTES; i=i+1) begin: tdata_incr_g
      always @(posedge aclk) begin
        if(areset) begin
          tdata_i[8*i+:8] <= 8'h00;
        end
        else
        begin
          tdata_i[8*i+:8] <= (transfer_i) ? tdata_i[8*i+:8] + 1'b1 : tdata_i[8*i+:8];
        end
      end
    end
  endgenerate



  //**********************************************
  // TVALID
  //**********************************************
  always @(posedge aclk) begin
    if(areset) begin
      m_axis_tvalid <= 1'b0;
    end
    else
    begin
      // TVALID
      if(done_i) begin
        m_axis_tvalid <= 1'b0;
      end
      else if(areset_i == 2'b10) begin
        m_axis_tvalid <= 1'b1;
      end
      else begin
        m_axis_tvalid <= m_axis_tvalid;
      end
    end
  end



  //**********************************************
  // PCNT, TCNT, DONE
  //**********************************************
  always @(posedge aclk) begin
    if(areset) begin
      pcnt_i <= 16'h0000;
      tcnt_i <= 16'h0000;
      done <= 1'b0;
    end
    else
    begin
      // DONE
      done <= (done_i) ? 1'b1 : done;

      // Increment counters
      tcnt_i <= (transfer_i) ? (tcnt_i + 1'b1) : tcnt_i;
    end
  end

endmodule

`default_nettype wire


Clock (.v):

// file: clk_wiz_0.v
// 
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
// 
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
// 
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
// 
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
// 
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
// 
//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// None
//
//----------------------------------------------------------------------------
//  Output     Output      Phase    Duty Cycle   Pk-to-Pk     Phase
//   Clock     Freq (MHz)  (degrees)    (%)     Jitter (ps)  Error (ps)
//----------------------------------------------------------------------------
// clk_out1____10.000______0.000______50.0______280.649____133.882
//
//----------------------------------------------------------------------------
// Input Clock   Freq (MHz)    Input Jitter (UI)
//----------------------------------------------------------------------------
// __primary_________200.000____________0.010

`timescale 1ps/1ps

(* CORE_GENERATION_INFO = "clk_wiz_0,clk_wiz_v6_0_2_0_0,{component_name=clk_wiz_0,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,enable_axi=0,feedback_source=FDBK_AUTO,PRIMITIVE=MMCM,num_out_clk=1,clkin1_period=5.000,clkin2_period=10.0,use_power_down=false,use_reset=false,use_locked=true,use_inclk_stopped=false,feedback_type=SINGLE,CLOCK_MGR_TYPE=NA,manual_override=false}" *)

module clk_wiz_0 
 (
  // Clock out ports
  output        clk_out1,
  // Status and control signals
  output        locked,
 // Clock in ports
  input         clk_in1_p,
  input         clk_in1_n
 );

  clk_wiz_0_clk_wiz inst
  (
  // Clock out ports  
  .clk_out1(clk_out1),
  // Status and control signals               
  .locked(locked),
 // Clock in ports
  .clk_in1_p(clk_in1_p),
  .clk_in1_n(clk_in1_n)
  );

endmodule


Output Simulation Waveform(s):

Waveform: Zoomed Out view.

Waveform: Zoomed-in view.
Up-conversion features:

• Range: Input 1-256 Bytes, Output 2-512 Bytes
• Supports full range of 1:N byte ratio conversions
• Minimum latency of 2 + N clock cycles in 1:N byte ratio up-conversion.



Down-conversion features:

• Range: Input 2-512 bytes, output 256-1 bytes
• Supports full range of N:1 byte ratio conversions
• Minimum Latency: 2 clock cycles

FIG: Data Width Converter (Down Conversion) Module Block Diagram (Source: Xilinx Documentation)


Key Features: (Source: Xilinx IP Catalog)
  • Configurable Master and Slave (up to 16 X 16) capable cross-point switch.
  • TDATA byte width conversion.
  • Synch. and Asynch clock rate conversion.
  • Configurable data-path FIFO buffers.
  • Optional reg slice at boundaries to facilitate timing closure.
  • Support multiple Clock Domains.

Fig: Clock Conversion Module block diagram.

Functionality:
  • In this case, there is 2 times Clock difference. Slave Clock is 2 times slower than the Master one.
  • Here, it first collects the data from 01 till 06. Then, it enables TVALID saying hey, I have data and waits until Slave enables TREADY and starts sending the data.
  • The same data is sent with different Clock(s).
  • We can say it has the "Collect" phase and "Sending" phase. Very simple IP to use.



Comments