cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Versal Advanced IO Wizard : Walk-through on using the Wizard and how to simulate

sandrao
Community Manager
Community Manager
1 0 864

This Blog entry is intended for new users of the Versal™ Advanced IO Wizard. It gives an introduction to setting up the Wizard and some insights into running a simulation. 

The Advanced IO Wizard must be used for the XPHY primitives in Versal (assuming you are not using the Hard or Soft Memory Controller).

  • (PG320) is the Advanced IO Wizard Product Guide and covers each of the options and how to use them.
  • (AM010) is the SelectIO Architecture Manual and has further details on the XPHY and on Clocking the XPHY.

In this blog entry we will walk through a simple example of setting up a Wizard and running a simulation.

 

 

Setting Up the Project:

 

Create a Project in Vivado targeting a Versal device. 

Create a block design.

Add the Advanced IO Wizard to the canvas.

Double Click on the IP to Customize it.

 

Setting up the Advanced IO Wizard

 

Basic Tab

 

By default, the Advanced IO Wizard Basic tab is set up for Source Synchronous RX Only with a default speed of 1000Mbps, PLL Input of 100MHz and a Serialization factor of 8. 

sandrao_0-1605012680139.png

We will continue with the default options in this example.

If you are choosing different options for Interface Speed, PLL Input, or Serialization you will need to make changes in the testbench. We will discuss how to do this later. 

 

Advanced Tab: 

 

Select Reduce Control signals to reduce the number of FIFO Control signals.

Select Enable Delay Control Signals to expose the Delay controls.

Leave Enable BLI Logic selected as this helps with meeting timing from the XPIO to fabric. 

Add the IO Std of your choosing. In this example I chose LVDS15.

We are leaving the Number of Banks as 1 as the I/O will be placed in one bank. 

sandrao_0-1605012788234.png

 

Pin Configuration Tab

 

On the Pin Configuration Tab I set the Number of Data Channels to 8 and the testbench is set for 8 differential pairs.  

The Strobe and Data signals can be changed but we are leaving them at their defaults. 

sandrao_0-1605012930347.png

 
 

Select OK and Generate Output products:

 

sandrao_0-1605013082051.png

Connecting the Wizard

 

The Advanced IO Wizard requires a CTRL_CLK that can be sourced from the PLL in the core.  Connect the bank0_pll_clkout0 to the ctrl_clk.

The FIFO_RD_EN can be derived from NOT FIFO_EMPTY. In the following code, we take both the Interface Ready signal (INTF_RDY) and the FIFO_EMPTY to wait until the Interface is ready and the FIFO is not empty to assert the FIFO_RD_EN. 

Add the Verilog code to a file and select it in Vivado. If you are not familiar with IP Integrator you can add the RTL into the BD by selecting the file, right clicking and selecting Add Module to Block Design.

sandrao_0-1605013661127.png

 

Example Code :

 

 

 

 

module FIFO_CTRL(
    input FIFO_EMPTY,
    input INT_RDY,
	input clk,
    output reg FIFO_RD_EN
    );
  
    reg not_empty;
    

    always @(posedge clk) begin
        not_empty <= ~FIFO_EMPTY;
		FIFO_RD_EN <= INT_RDY & not_empty;
	end
endmodule

 

 

 

 

Now connect the CLK, INTF_RDY, FIFO_EMPTY and FIFO RD_EN. We are driving the FIFO_RD_EN with this piece of code so use the same clock as the the FIFO_RD_CLK.

In our design it is bank0_pll_clkout0.

We will not be changing the Delay values of the Strobe so tie these off to a constant 0.

 

 

 

 

set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ]
 set_property -dict [ list \
  CONFIG.CONST_VAL {0} \
  CONFIG.CONST_WIDTH {9} \
] $xlconstant_0
set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ]
 set_property -dict [ list \
  CONFIG.CONST_VAL {0} \
  CONFIG.CONST_WIDTH {1} \
] $xlconstant_1
connect_bd_net [get_bd_pins xlconstant_0/dout] [get_bd_pins advanced_io_wizard_0/rxtx_cntvaluein_Strobe_0]
connect_bd_net [get_bd_pins advanced_io_wizard_0/rxtx_ce_Strobe_0] [get_bd_pins xlconstant_1/dout]
connect_bd_net [get_bd_pins advanced_io_wizard_0/rxtx_inc_Strobe_0] [get_bd_pins xlconstant_1/dout]
connect_bd_net [get_bd_pins advanced_io_wizard_0/rxtx_ld_Strobe_0] [get_bd_pins xlconstant_1/dout]
connect_bd_net [get_bd_pins advanced_io_wizard_0/rxtx_sel_Strobe_0] [get_bd_pins xlconstant_1/dout]
connect_bd_net [get_bd_pins advanced_io_wizard_0/rxen_vtc_Strobe_0] [get_bd_pins xlconstant_1/dout]
connect_bd_net [get_bd_pins advanced_io_wizard_0/txen_vtc_Strobe_0] [get_bd_pins xlconstant_1/dout]

 

 

 

 

 

Make the Data, Strobe, RST, EN_VTC, INTF_RDY and delay line signals External.

Make the data_to_fabric_data_pin External.

Add a Utility Buffer which defaults to IBUFDS, connect the IBUF_OUT to the bank0_pll_clkin port, and make the input of the Utility Buffer External. 

Validate the Block Design and fix any warnings.

sandrao_0-1605015748803.png

 

Attached at the bottom of this Blog entry is a bd.tcl for your reference.

Note: all Versal designs must have a Control, Interface and Processing Systems IP in order for the device to boot properly. We are only simulating this design so we are not including a CIPS. If you intend to put the design on hardware you must include the CIPS. 

Now create the HDL Wrapper.

Simulation Steps 

 

We need to add the testbench to the project and the wave configuration file.

Save the testbench and script to the one location and source the script. Alternatively you can add the testbench in the GUI and change the Elaborate Level to all, then add the WFCG.

 

The inputs to the DUT are the input clock, strobe and data.

When simulating the Advanced IO Wizard we need to wait for BISC to complete i.e. for INTF_RDY to assert.

 

 

 

 

 

  design_1_wrapper design_1_i
       (.CLK_IN_D_0_clk_n(clk),
        .CLK_IN_D_0_clk_p(clk_n),
       .Data_pins_0_n_0(~data_p),
        .Data_pins_0_p_0(data_p),
        .Strobe_0_n_0(strobe_n),
        .Strobe_0_p_0(strobe_p),
        .data_to_fabric_Data_pins_0_0(rx_data),
        .en_vtc_0(en_vtc),
        .intf_rdy_0(core_intf_rdy),
        .rst_0(rst),
         .rxen_vtc_Data_pins_0_p_0(rx_en_vtc),
        .rxtx_ce_Data_pins_0_p_0(ce),
        .rxtx_cntvaluein_Data_pins_0_p_0(cntvaluein),
        .rxtx_cntvalueout_Data_pins_0_p_0(cntvalueout),
        .rxtx_inc_Data_pins_0_p_0(inc),
        .rxtx_ld_Data_pins_0_p_0(ld),
        .rxtx_sel_Data_pins_0_p_0(sel),
        .txen_vtc_Data_pins_0_p_0(tx_en_vtc)
        );

 

 

 

 

The testbench has Clock and Strobe stimulus so if you changed the Speed of the Interface or PLL Input frequency on the Basic Tab of the Wizard you will need to adjust the testbench accordingly. 

We set the initial value for the other signals and wait for BISC to Complete.

When the rst releases, the PLL will achieve LOCKED. Then the CLKOUTPHYEN asserts and the XPHY will start BISC. 

sandrao_0-1605018677840.png

Next we wait for for the Interface Ready and record the time.

Note: this will probably take longer than you expect.

sandrao_0-1605018767108.png

In the simulation you can see that the DLY_RDY asserts and then the PHY_RDY asserts, then the core_intf_rdy asserts.

sandrao_0-1605019178116.png

Now that BISC is complete and the interface is ready, we set the data into the IO = AA and check that the output of the data matches the output of the SERDES.

sandrao_0-1605019312770.png

Now we will move on to looking into the IDELAY.

Table 6: Controlling Input and Output Delays and Table 7: Delay Control Signals NIBBLESLICE Mapping in (AM010) are good references here. 

sandrao_0-1605019402698.png

We are only using an RX so we set the RXTX_SEL = 0 to look at IDELAY.

For rxtx_cntvalueout_Data_pins_0[71:0], we have 8 Data Channel and each rxtx_cntvalueout is 9 bits. 

XPHY has one CNTVALUEIN and CNTVALUEOUT [53:0]. We are only using the P side so when looking at the XPHY primitives you should look at the P side.

P_0 0:8

N_0 9:17

P_1 18:26

N_1 27:35

P_2 36:44

N_2 45:53

We read each of the IDELAY CNTVALUEOUT and in simulation we see that BISC has found 3C / 60 as the number of taps. 

 

sandrao_0-1605019943268.png

To incrementally change the IDELAY value, RX/TX_EN_VTC should be pulled low.

The INC and CE should be pulsed for one CTRL CLK cycle to Increment by one tap. We are only going to change the Tap of Channel 0 so we set CE and INC to 8'b01.

In the testbench we use the following:

 

 

 

 

// Lets INCREMENT Data Channel 0 only 
  rx_en_vtc = 8'h00;
  tx_en_vtc= 8'h00;
  # (bit_period*160);
  ce= 8'b01;
  inc= 8'b01;
  #(bit_period*16);
  ce= 8'b00;
  inc= 8'b00;
   # (bit_period*160);

 

 

 

 

In the Console we read the CNTVALUEOUTs and can see that Channel 0 has incremented from 3C to 3D and that the others remain unchanged:

sandrao_0-1605019730613.png

Next we will LOAD a value into CNTVALUEIN for Channel 1.

In the testbench we do the following:

 

 

 

 

// Next we will load into Data Channel 1
   # (bit_period*160);
   
  cntvaluein = 72'h633198CC6633195CC6;
  ld= 8'b00000010;
 # (bit_period*16);
  ld= 8'b00;

 

 

 

 

In the Console and the waveform we can see change in the CNTVALUEOUT for Channel 1, corresponding to what we loaded into the CNTVALUEIN:

sandrao_0-1605020055384.png

 

Conclusion 

 

In this quick walk-through we have set up an RX interface with the Delay line control signals enabled for user control.

We have hooked up the signals so that we can use them in simulation and have seen how to control the Delay lines. 

Tags (2)