March 19, 200830 minutes
Overview In this tutorial we will create a peripheral containing the Aurora core to implement a high speed serial transceiver with a RocketIO MGT. The peripheral can be used to connect two XUPV2P boards using the SATA connectors and transfer data between them at 1.5Gbps. To test the design using only one XUPV2P board, we will instantiate two Aurora peripherals, assign them to different RocketIO MGTs and place a SATA cable between them to create a loop-back connection. The PowerPC will transfer data between the two Aurora peripherals simply by reading and writing to the read and write FIFOs. To test the design, the test application will write data to the write FIFO of the first Aurora peripheral and read it back from the read FIFO of the second Aurora peripheral. The Aurora peripheral will also have outputs indicating the status of the link. These outputs will be connected to the LEDs on the XUPV2P board.
The diagram above illustrates the design of the Aurora peripheral. It uses a read and write FIFO to transfer data between the PowerPC and the user logic. It also uses a second pair of FIFOs called the RX and TX FIFOs. The RX and TX FIFOs create a buffered link between the read/write FIFOs and the Aurora core. This buffered link is necessary because the OPB clock and the RocketIO clock are independent on the XUPV2P board. The OPB clocks data in and out of the read/write FIFOs at 100MHz while the user logic clocks data in and out of the Aurora core at 75MHz. For this reason, we use RX and TX FIFOs with independent read and write clock inputs.
As in the MGT Oscillator project, we will also create a Digital Clock Manager (DCM) peripheral for the RocketIO MGTs. The DCM peripheral will only contain two clock buffers and will not require registers or FIFOs.
This tutorial starts the user from scratch, assuming that the Aurora core license has been installed, and contains screenshots to guide the user through the entire implementation process. You can click on the images to view a higher resolution when necessary.
Requirements Apart from the obvious requirements (XPS software and XUPV2P board) this project requires the following:
Create the Basic Project Follow these steps to create the basic project:
C:\XUPV2P\lib folder using “Browse”. Click “OK”.




onewire_0 and RS232_Uart_1. Untick everything else. We will not actually use the onewire_0 interface in this project, but leaving it in has shown to be important. For an explanation, refer to “The Onewire Problem” on the
Known Issues page.

plb_bram_if_cntlr_1 and click “Next”.

RS232_Uart_1 for both STDIN and STDOUT. Un-tick “Memory Test” and leave “Peripheral Test” ticked. Click “Next”.

plb_bram_if_cntlr_1 for the Instruction, Data, Stack and Heap memories. Click “Next”.

Create the DCM Peripheral Follow these steps to create the DCM peripheral:

mgt_dcm for the peripheral name. Click “Next”.


Modify the DCM Peripheral Now we will add code in our peripheral template to instantiate two clock buffers that will generate the clock sources REF_CLK and USER_CLK for the RocketIO MGTs. This DCM example originates from the Xilinx RocketIO Transceiver User Guide (ug024), see section “Digital Clock Manager (DCM) Examples”.
pcores\mgt_dcm_v1_00_a\hdl\vhdl.mgt_dcm.vhd.-- ADD USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK_P : in std_logic;
TOP_BREF_CLK_N : in std_logic;
TOP_BREF_CLK : out std_logic;
USER_CLK : out std_logic;-- MAP USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK_P => TOP_BREF_CLK_P,
TOP_BREF_CLK_N => TOP_BREF_CLK_N,
TOP_BREF_CLK => TOP_BREF_CLK,
USER_CLK => USER_CLK,pcores\mgt_dcm_v1_00_a\hdl\vhdl.user_logic.vhd.-- ADD USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK_P : in std_logic;
TOP_BREF_CLK_N : in std_logic;
TOP_BREF_CLK : out std_logic;
USER_CLK : out std_logic;--USER signal declarations added here and add the following lines of code just below.component IBUFGDS_LVDS_25
port(
O : out std_ulogic;
I : in std_ulogic;
IB : in std_ulogic
);
end component;
component BUFG
port(
O : out std_ulogic;
I : in std_ulogic
);
end component;
signal top_bref_clk_i : std_logic;
signal user_clk_i : std_logic;--USER logic implementation added here and add the following lines of code just below.-- Differential Clock Buffer for top BREF_CLK
diff_clk_buff_top_i : IBUFGDS_LVDS_25
port map(
I => TOP_BREF_CLK_P,
IB => TOP_BREF_CLK_N,
O => top_bref_clk_i
);
-- BUFG used to drive USER_CLK on global clock net
user_clock_bufg_i : BUFG
port map(
I => top_bref_clk_i,
O => user_clk_i
);
TOP_BREF_CLK <= top_bref_clk_i;
USER_CLK <= user_clk_i;Import the DCM Peripheral Now we will use the Peripheral Wizard to import the DCM peripheral.

mgt_dcm. Tick “Use version” and select the same version number that we originally created. Click “Next”. It will ask if we are willing to overwrite the existing peripheral and we should answer “Yes”.

pcores\mgt_dcm_v1_00_a\data and select the mgt_dcm_v2_1_0.pao file. Click “Next”.


The DCM peripheral should now be accessible through the “IP Catalog->Project Repository” in the XPS interface.
Create an Instance of the DCM Peripheral Follow these steps to create an instance of the peripheral in the project.
mgt_dcm IP core in the “Project Repository” group. Right click on the core and select “Add IP”.

mgt_dcm_0 to the OPB bus.

mgt_dcm_0 to view its ports.TOP_BREF_CLK_P port. Type TOP_BREF_CLK_P in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”.TOP_BREF_CLK_N port. Type TOP_BREF_CLK_N in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”.TOP_BREF_CLK port. Type TOP_BREF_CLK in this field and press “Enter”.USER_CLK port. Type USER_CLK in this field and press “Enter”. The result should look like the image below.

TOP_BREF_CLK_P_pin and TOP_BREF_CLK_N_pin, with nets called TOP_BREF_CLK_P and TOP_BREF_CLK_N respectively.mgt_dcm_0 to 64K. Then click “Generate Addresses”.

Now we have an instance of the DCM peripheral in the project. The single DCM peripheral will supply the reference clock to all the MGTs accessible on the XUPV2P board.
Create the Aurora Peripheral Now we will start the creation of the Aurora peripheral by using the Peripheral Wizard. The Wizard will create a template for us with the read and write FIFOs fully implemented. We will then modify the template to include the Aurora core and RX/TX FIFOs. Follow these steps to create the Aurora peripheral.
aurora_mgt for the peripheral name. Click “Next”.



Now the template is created, we now need to use CORE Generator to create our RX/TX FIFOs and the Aurora core.
Create the FIFO Component in CORE Generator The read and write FIFOs of our Aurora peripheral were created by the Peripheral Wizard and they are ready for us to use in the user_logic.vhd file. The TX and RX FIFOs however must be created by us and placed into the user_logic.vhd file manually. Fortunately, the CORE Generator provides a good FIFO component that suits our needs. Follow these steps to create the FIFO component that we will use to implement the TX and RX FIFOs.






fifo_generator_v3_2_fifo_generator_v3_2_xst_1.ngc. Rename the file to fifo_generator_v3_2.ngc. This is the file that we will use in our Aurora peripheral to implement the TX and RX FIFOs.You can leave the CORE Generator open, because in the next section we will use it again to generate the Aurora core. The FIFO will now be listed under the tab “Generated IP”.
Create the Aurora core in CORE Generator Once you have a license to use the Aurora core and you have gone through the instructions provided by Xilinx, you should be able to use the CORE Generator to produce an Aurora core. The CORE Generator can generate VHDL code for the Aurora core with many variations as you will see in the creation wizard. Follow these steps to create an Aurora core:



BREF_CLK. For “Row 1 Clock” select “none”. To select the MGT, put a “1” in Row 0, Column 0, and place an “X” in all the other squares. Click “Finish”.

Exploring the Generated Files Now if you explore the contents of the “coregen” project folder that CORE Generator created, you should find the files as shown below:
The FIFO files of importance to us are the netlist (.ngc) file and the fifo_generator_v3_2.vho file. The latter file gives us an example of the FIFO component declaration and instantiation. We will use these examples in the user_logic.vhd of our Aurora peripheral code later.
In the aurora_201 folder you will find useful documentation and examples for using the Aurora core. The user guide for the Aurora core is the file called “ug061.pdf” and it is recommended that you read this file to better understand the work in this tutorial. Another interesting document is the Getting Started Guide in the file aurora_gs_ug173.pdf. This guide explains the example that was generated by the CORE Generator and how to simulate and implement it. In the aurora_201\examples folder, you will find the aurora_sample.vhd file which is the top-level of the example design. It is important to understand the example because in this tutorial, we will use the example code in our Aurora peripheral user_logic.vhd file.
Copy the Aurora core source files We need to copy the Aurora core source files into the Aurora peripheral source folder. We just generated the source files for the Aurora core with CORE Generator and they should be found in the “coregen” project folder. The image below shows two explorer windows browsing the source code files.

coregen\aurora_201\src. Copy all the files in that folder and paste them into the pcores\aurora_mgt_v1_00_a\hdl\vhdl folder within your XPS project. You will be copying these files into the same folder as your user_logic.vhd file for the Aurora peripheral is contained.coregen\aurora_201\cc_manager. Copy the file standard_cc_module.vhd in that folder and paste it into the pcores\aurora_mgt_v1_00_a\hdl\vhdl folder within your XPS project.aurora_201.vhd
aurora_lane.vhd
aurora_pkg.vhd
channel_error_detect.vhd
channel_init_sm.vhd
chbond_count_dec.vhd
error_detect.vhd
global_logic.vhd
idle_and_ver_gen.vhd
lane_init_sm.vhd
phase_align.vhd
rx_stream.vhd
sym_dec.vhd
sym_gen.vhd
tx_stream.vhd
standard_cc_module.vhdModify the .PAO file The .pao file contains a list of all the source files that compose our peripheral. We use this list when we run the Peripheral Wizard in Import mode. Now that we have added the Aurora core source files to the project, we must include them in the .pao file. Note that files must be listed in the .pao file in hierarchical order. The components at the top of the hierarchy are listed at the bottom of the file.
pcores\aurora_mgt_v1_00_a\data folder. Select the file aurora_mgt_v2_1_0.pao and click “Open”.lib aurora_mgt_v1_00_a user_logic vhdl
lib aurora_mgt_v1_00_a aurora_mgt vhdllib aurora_mgt_v1_00_a aurora_pkg vhdl
lib aurora_mgt_v1_00_a channel_error_detect vhdl
lib aurora_mgt_v1_00_a idle_and_ver_gen vhdl
lib aurora_mgt_v1_00_a channel_init_sm vhdl
lib aurora_mgt_v1_00_a error_detect vhdl
lib aurora_mgt_v1_00_a sym_dec vhdl
lib aurora_mgt_v1_00_a sym_gen vhdl
lib aurora_mgt_v1_00_a chbond_count_dec vhdl
lib aurora_mgt_v1_00_a lane_init_sm vhdl
lib aurora_mgt_v1_00_a rx_stream vhdl
lib aurora_mgt_v1_00_a tx_stream vhdl
lib aurora_mgt_v1_00_a global_logic vhdl
lib aurora_mgt_v1_00_a phase_align vhdl
lib aurora_mgt_v1_00_a aurora_lane vhdl
lib aurora_mgt_v1_00_a standard_cc_module vhdl
lib aurora_mgt_v1_00_a aurora_201 vhdlNow we can use this .pao file with the Peripheral Wizard when we import the Aurora peripheral.
Modify the Aurora Peripheral Now we will add code to our peripheral template to instantiate an Aurora core and the TX and RX FIFOs. The TX and RX FIFOs will be wired to the write and read FIFOs respectively. The FIFO connections are made such that data is automatically passed along when any of the FIFOs receives data.
pcores\aurora_mgt_v1_00_a\hdl\vhdl.aurora_mgt.vhd.-- ADD USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK : in std_logic;
USER_CLK : in std_logic;
HARD_ERROR : out std_logic;
SOFT_ERROR : out std_logic;
LANE_UP : out std_logic;
CHANNEL_UP : out std_logic;
RXP : in std_logic;
RXN : in std_logic;
TXP : out std_logic;
TXN : out std_logic;-- MAP USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK => TOP_BREF_CLK,
USER_CLK => USER_CLK,
HARD_ERROR => HARD_ERROR,
SOFT_ERROR => SOFT_ERROR,
LANE_UP => LANE_UP,
CHANNEL_UP => CHANNEL_UP,
RXP => RXP,
RXN => RXN,
TXP => TXP,
TXN => TXN,pcores\aurora_mgt_v1_00_a\hdl\vhdl.user_logic.vhd. We will need to modify this source code to instantiate the Aurora core and TX/RX FIFOs.-- ADD USER PORTS BELOW THIS LINE and add the following lines of code just below. TOP_BREF_CLK : in std_logic;
USER_CLK : in std_logic;
HARD_ERROR : out std_logic;
SOFT_ERROR : out std_logic;
LANE_UP : out std_logic;
CHANNEL_UP : out std_logic;
RXP : in std_logic;
RXN : in std_logic;
TXP : out std_logic;
TXN : out std_logic;--USER signal declarations added here and add the following lines of code just below. You will recognize this code from the aurora_sample.vhd file. -- External Register Declarations --
signal HARD_ERROR_Buffer : std_logic;
signal SOFT_ERROR_Buffer : std_logic;
signal LANE_UP_Buffer : std_logic;
signal CHANNEL_UP_Buffer : std_logic;
signal TXP_Buffer : std_logic;
signal TXN_Buffer : std_logic;
-- Wire Declarations --
-- Stream TX Interface
signal tx_d_i : std_logic_vector(0 to 15);
signal tx_src_rdy_n_i : std_logic;
signal tx_dst_rdy_n_i : std_logic;
-- Stream RX Interface
signal rx_d_i : std_logic_vector(0 to 15);
signal rx_src_rdy_n_i : std_logic;
-- Error Detection Interface
signal hard_error_i : std_logic;
signal soft_error_i : std_logic;
-- Status
signal channel_up_i : std_logic;
signal lane_up_i : std_logic;
-- Clock Compensation Control Interface
signal warn_cc_i : std_logic;
signal do_cc_i : std_logic;
--TX & RX FIFO signals
signal tx_fifo_empty : std_logic;
signal rx_fifo_empty : std_logic;
signal tx_fifo_we : std_logic := '0';
signal rx_fifo_we : std_logic := '0';
signal tx_fifo_re : std_logic := '0';
signal rx_fifo_re : std_logic := '0';
signal tx_fifo_valid : std_logic;
signal rx_fifo_valid : std_logic;
signal tx_fifo_almost_full : std_logic;
signal rx_fifo_almost_full : std_logic;
signal tx_fifo_dout : std_logic_vector(31 downto 0);
signal rx_fifo_dout : std_logic_vector(31 downto 0);
signal tx_fifo_din : std_logic_vector(31 downto 0);
signal rx_fifo_din : std_logic_vector(31 downto 0);
-- Component Declarations --
component aurora_201
generic (
EXTEND_WATCHDOGS : boolean := FALSE
);
port (
-- LocalLink TX Interface
TX_D : in std_logic_vector(0 to 15);
TX_SRC_RDY_N : in std_logic;
TX_DST_RDY_N : out std_logic;
-- LocalLink RX Interface
RX_D : out std_logic_vector(0 to 15);
RX_SRC_RDY_N : out std_logic;
-- MGT Serial I/O
RXP : in std_logic;
RXN : in std_logic;
TXP : out std_logic;
TXN : out std_logic;
-- MGT Reference Clock Interface
TOP_BREF_CLK : in std_logic;
-- Error Detection Interface
HARD_ERROR : out std_logic;
SOFT_ERROR : out std_logic;
-- Status
CHANNEL_UP : out std_logic;
LANE_UP : out std_logic;
-- Clock Compensation Control Interface
WARN_CC : in std_logic;
DO_CC : in std_logic;
-- System Interface
DCM_NOT_LOCKED : in std_logic;
USER_CLK : in std_logic;
RESET : in std_logic;
POWER_DOWN : in std_logic;
LOOPBACK : in std_logic_vector(1 downto 0)
);
end component;
component STANDARD_CC_MODULE
port (
-- Clock Compensation Control Interface
WARN_CC : out std_logic;
DO_CC : out std_logic;
-- System Interface
DCM_NOT_LOCKED : in std_logic;
USER_CLK : in std_logic;
CHANNEL_UP : in std_logic
);
end component;
-- FIFO component from CORE Generator
component fifo_generator_v3_2
port (
din : IN std_logic_VECTOR(31 downto 0);
rd_clk : IN std_logic;
rd_en : IN std_logic;
rst : IN std_logic;
wr_clk : IN std_logic;
wr_en : IN std_logic;
almost_full : OUT std_logic;
dout : OUT std_logic_VECTOR(31 downto 0);
empty : OUT std_logic;
full : OUT std_logic;
valid : OUT std_logic
);
end component;--USER logic implementation added here and add the following lines of code just below. HARD_ERROR <= HARD_ERROR_Buffer;
SOFT_ERROR <= SOFT_ERROR_Buffer;
LANE_UP <= LANE_UP_Buffer;
CHANNEL_UP <= CHANNEL_UP_Buffer;
TXP <= TXP_Buffer;
TXN <= TXN_Buffer;
-- Register User I/O --
-- Register User Outputs from core.
process (USER_CLK)
begin
if (USER_CLK 'event and USER_CLK = '1') then
HARD_ERROR_Buffer <= hard_error_i;
SOFT_ERROR_Buffer <= soft_error_i;
LANE_UP_Buffer <= lane_up_i;
CHANNEL_UP_Buffer <= channel_up_i;
end if;
end process;
-- Aurora core instantiation
aurora_module_i : aurora_201
port map (
-- LocalLink TX Interface
TX_D => tx_d_i,
TX_SRC_RDY_N => tx_src_rdy_n_i,
TX_DST_RDY_N => tx_dst_rdy_n_i,
-- LocalLink RX Interface
RX_D => rx_d_i,
RX_SRC_RDY_N => rx_src_rdy_n_i,
-- MGT Serial I/O
RXP => RXP,
RXN => RXN,
TXP => TXP_Buffer,
TXN => TXN_Buffer,
-- MGT Reference Clock Interface
TOP_BREF_CLK => TOP_BREF_CLK,
-- Error Detection Interface
HARD_ERROR => hard_error_i,
SOFT_ERROR => soft_error_i,
-- Status
CHANNEL_UP => channel_up_i,
LANE_UP => lane_up_i,
-- Clock Compensation Control Interface
WARN_CC => warn_cc_i,
DO_CC => do_cc_i,
-- System Interface
DCM_NOT_LOCKED => '0',
USER_CLK => USER_CLK,
RESET => Bus2IP_Reset,
POWER_DOWN => '0',
LOOPBACK => "00"
);
standard_cc_module_i : STANDARD_CC_MODULE
port map (
-- Clock Compensation Control Interface
WARN_CC => warn_cc_i,
DO_CC => do_cc_i,
-- System Interface
DCM_NOT_LOCKED => '0',
USER_CLK => USER_CLK,
CHANNEL_UP => channel_up_i
);
-----------------------------------------
-- FIFOs:
-- Write FIFO -> TX FIFO -> Aurora TX
-- Read FIFO <- RX FIFO <- Aurora RX
--
-- Write FIFO: Single CLK: Bus2IP_Clk
-- Read FIFO: Single CLK: Bus2IP_Clk
-- TX FIFO: In CLK: Bus2IP_Clk, Out CLK: USER_CLK
-- RX FIFO: In CLK: USER_CLK, Out CLK: Bus2IP_Clk
--
tx_fifo_i : fifo_generator_v3_2
port map (
din => tx_fifo_din,
rd_clk => USER_CLK,
rd_en => tx_fifo_re,
rst => Bus2IP_Reset,
wr_clk => Bus2IP_Clk,
wr_en => tx_fifo_we,
almost_full => tx_fifo_almost_full,
dout => tx_fifo_dout,
empty => tx_fifo_empty,
full => open,
valid => tx_fifo_valid);
rx_fifo_i : fifo_generator_v3_2
port map (
din => rx_fifo_din,
rd_clk => Bus2IP_Clk,
rd_en => rx_fifo_re,
rst => Bus2IP_Reset,
wr_clk => USER_CLK,
wr_en => rx_fifo_we,
almost_full => rx_fifo_almost_full,
dout => rx_fifo_dout,
empty => rx_fifo_empty,
full => open,
valid => rx_fifo_valid);
-----------------------------------------
-- FIFO Connections:
-- Write Enable <= Valid Data
-- Data In <= Data Out
-- Read Enable <= (not Empty) and (not Almost Full)
-- Connection between Write FIFO and TX FIFO
tx_fifo_we <= WFIFO2IP_RdAck;
tx_fifo_din <= WFIFO2IP_Data;
IP2WFIFO_RdReq <= (not WFIFO2IP_empty) and (not tx_fifo_almost_full);
-- Connection between Read FIFO and RX FIFO
IP2RFIFO_WrReq <= rx_fifo_valid;
IP2RFIFO_Data <= rx_fifo_dout;
rx_fifo_re <= (not rx_fifo_empty) and (not RFIFO2IP_AlmostFull);
-- Connection between TX FIFO and Aurora TX
tx_src_rdy_n_i <= not tx_fifo_valid;
tx_d_i <= tx_fifo_dout(15 downto 0);
tx_fifo_re <= not tx_fifo_empty;
-- Connection between RX FIFO and Aurora RX
-- (the Aurora RX has no read request signal)
rx_fifo_we <= not rx_src_rdy_n_i;
rx_fifo_din(31 downto 16) <= (others => '0');
rx_fifo_din(15 downto 0) <= rx_d_i;user_logic.vhd file is always generated with code that connects the read and write FIFOs in loop-back. It is intended to provide an example of usage of the FIFOs and also allows for easy testing of a new peripheral. In our design, we have connected the read and write FIFOs to the RX and TX FIFOs respectively, so we must remove the example code. Comment out, or delete all the lines of code from the line that reads FIFO_CNTL_SM_COMB : process(... to the line that reads IP2RFIFO_Data <= WFIFO2IP_Data; inclusively.Import the Aurora Peripheral Now we will use the Peripheral Wizard in Import mode.
aurora_mgt. Tick “Use version” and select the same version number that we originally created. Click “Next”. It will ask if we are willing to overwrite the existing peripheral and we should answer “Yes”.


pcores\aurora_mgt_v1_00_a\data and select the aurora_mgt_v2_1_0.pao file. Click “Next”.

fifo_generator_v3_2.ngc and click “Open”. The .ngc file should be listed as shown in the image below. Click “Next”.

The peripheral wizard will make a copy of the .ngc file we specified and place it in the pcores\aurora_mgt_v1_00_a\netlist in our project folder. It will also create a file called aurora_mgt_v2_1_0.bbd in pcores\aurora_mgt_v1_00_a\data which is a text file that lists the .ngc files used by the peripheral. The Aurora peripheral should now be accessible through the “IP Catalog->Project Repository” in the XPS interface.
Create two Instances of the Aurora Peripheral We will create two instances of the Aurora peripheral in this project so that we can connect them with a loop-back SATA cable and transfer data between them. Follow these steps to create two instances of the peripheral in the project.
aurora_mgt IP core in the “Project Repository” group. Right click on the core and select “Add IP”. Do this a second time to add another Aurora peripheral.

aurora_mgt_0 and aurora_mgt_1 to the OPB bus.

aurora_mgt_0 and aurora_mgt_1 to view their ports.TOP_BREF_CLK port. Type TOP_BREF_CLK in this field and press “Enter”. Do this for both aurora_mgt_0 and aurora_mgt_1.USER_CLK port. Type USER_CLK in this field and press “Enter”. Do this for both aurora_mgt_0 and aurora_mgt_1.aurora_mgt_0 ONLY, click on the “Net” field for the HARD_ERROR port. Type HARD_ERROR in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”.aurora_mgt_0 ONLY, click on the “Net” field for the SOFT_ERROR port. Type SOFT_ERROR in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”.aurora_mgt_0 ONLY, click on the “Net” field for the LANE_UP port. Type LANE_UP in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”. The ports should now look as shown in the image below.aurora_mgt_0 ONLY, click on the “Net” field for the CHANNEL_UP port. Type CHANNEL_UP in this field and press “Enter”. Now click again the same field and open the drop down menu. Select “Make External” and press “Enter”.

aurora_mgt_0 and aurora_mgt_1 to 64K. Then click “Generate Addresses”.

Now we have two instances of the Aurora peripheral in the project. Both Aurora peripherals have status outputs (CHANNEL_UP, HARD_ERROR, SOFT_ERROR and LANE_UP) which we would like to connect to the LEDs. We only externalized those ports for the aurora_mgt_0 peripheral because we only have 4 LEDs to use on the XUPV2P board. As we are going to connect the Aurora peripherals to each other with a loop-back SATA cable, the status outputs of both peripherals should be the same anyway.
Modify the UCF Constraints File Now we must add some lines to the project’s .ucf file to tell XPS: (1) which physical RocketIO MGT to use, (2) where the external reference clock pins are, (3) the frequency or period of the reference clock, and (4) where the external LED pins are to connect our status outputs.
##### Timing Contraints for the MGT Recovered clock ######
NET aurora_mgt_0/aurora_mgt_0/USER_LOGIC_I/aurora_module_i/lane_0_mgt_i/RXRECCLK PERIOD=75 MHz;
NET aurora_mgt_1/aurora_mgt_1/USER_LOGIC_I/aurora_module_i/lane_0_mgt_i/RXRECCLK PERIOD=75 MHz;
##### Timing Contraints for the MGT reference clock ######
NET USER_CLK PERIOD = 75 MHz;
NET TOP_BREF_CLK PERIOD = 75 MHz;
###### Connect the external MGT clock inputs #######
NET TOP_BREF_CLK_P_pin LOC=F16;
NET TOP_BREF_CLK_P_pin IOSTANDARD = LVDS_25;
NET TOP_BREF_CLK_N_pin LOC=G16;
NET TOP_BREF_CLK_N_pin IOSTANDARD = LVDS_25;
###### MGT Locations #######
# X0Y1 (SATA 0 HOST) aurora_mgt_0
INST aurora_mgt_0/aurora_mgt_0/USER_LOGIC_I/aurora_module_i/lane_0_mgt_i LOC=GT_X0Y1;
# X1Y1 (SATA 1 TARGET) aurora_mgt_1
INST aurora_mgt_1/aurora_mgt_1/USER_LOGIC_I/aurora_module_i/lane_0_mgt_i LOC=GT_X1Y1;
###### Connect LEDs to the Aurora Status outputs ########
# LED 0
NET CHANNEL_UP_pin LOC = AC4;
Net CHANNEL_UP_pin IOSTANDARD = LVTTL;
Net CHANNEL_UP_pin SLEW = SLOW;
Net CHANNEL_UP_pin DRIVE = 12;
# LED 1
NET HARD_ERROR_pin LOC = AC3;
Net HARD_ERROR_pin IOSTANDARD = LVTTL;
Net HARD_ERROR_pin SLEW = SLOW;
Net HARD_ERROR_pin DRIVE = 12;
# LED 2
NET SOFT_ERROR_pin LOC = AA6;
Net SOFT_ERROR_pin IOSTANDARD = LVTTL;
Net SOFT_ERROR_pin SLEW = SLOW;
Net SOFT_ERROR_pin DRIVE = 12;
# LED 3
NET LANE_UP_pin LOC = AA5;
Net LANE_UP_pin IOSTANDARD = LVTTL;
Net LANE_UP_pin SLEW = SLOW;
Net LANE_UP_pin DRIVE = 12;Modify the Software Application Now all we need to do is modify the software application to test our Aurora peripherals.
Project: TestApp_Peripheral tree. Open the TestApp_Peripheral.c source file.#include "xparameters.h"
#include "xbasic_types.h"
#include "xstatus.h"
#include "aurora_mgt.h"
Xuint32 *aurora_mgt_0_baseaddr_p =
(Xuint32 *) XPAR_AURORA_MGT_0_BASEADDR;
Xuint32 *aurora_mgt_1_baseaddr_p =
(Xuint32 *) XPAR_AURORA_MGT_1_BASEADDR;
Xuint32 aurora_mgt_0_baseaddr;
Xuint32 aurora_mgt_1_baseaddr;
int main (void)
{
Xuint32 i;
Xuint32 data[10];
Xuint32 temp;
// Check that the Aurora peripherals exist
XASSERT_NONVOID(aurora_mgt_0_baseaddr_p != XNULL);
aurora_mgt_0_baseaddr = (Xuint32) aurora_mgt_0_baseaddr_p;
XASSERT_NONVOID(aurora_mgt_1_baseaddr_p != XNULL);
aurora_mgt_1_baseaddr = (Xuint32) aurora_mgt_1_baseaddr_p;
// Reset read and write FIFOs to initial state
AURORA_MGT_mResetWriteFIFO(aurora_mgt_0_baseaddr);
AURORA_MGT_mResetReadFIFO(aurora_mgt_0_baseaddr);
AURORA_MGT_mResetWriteFIFO(aurora_mgt_1_baseaddr);
AURORA_MGT_mResetReadFIFO(aurora_mgt_1_baseaddr);
// Clear screen
xil_printf("%c[2J",27);
xil_printf("Test 1: Transmit data from ");
xil_printf("AURORA_MGT_0 to AURORA_MGT_1\n\r");
xil_printf("---------------------------");
xil_printf("----------------------------\n\r");
// set data for transmission
data[0] = (Xuint32) 0x0123;
data[1] = (Xuint32) 0x4567;
data[2] = (Xuint32) 0x89AB;
data[3] = (Xuint32) 0xCDEF;
data[4] = (Xuint32) 0x0123;
data[5] = (Xuint32) 0x4567;
data[6] = (Xuint32) 0x89AB;
data[7] = (Xuint32) 0xCDEF;
data[8] = (Xuint32) 0x0123;
data[9] = (Xuint32) 0x4567;
// Push data to write packet FIFO
xil_printf(" Writing data to the AURORA_MGT_0 peripheral:");
xil_printf("\n\r ");
for(i = 0; i < 10; i++){
xil_printf("0x%04x ", data[i]);
AURORA_MGT_mWriteToFIFO(aurora_mgt_0_baseaddr, data[i]);
}
// pop data out from read packet FIFO
xil_printf("\n\r\n\r ");
xil_printf("Reading data from the AURORA_MGT_1 peripheral:");
xil_printf("\n\r ");
while(!AURORA_MGT_mReadFIFOEmpty(aurora_mgt_1_baseaddr)){
temp = AURORA_MGT_mReadFromFIFO(aurora_mgt_1_baseaddr);
xil_printf("0x%04x ", temp);
}
xil_printf("\n\r\n\rTest 2: Transmit text from ");
xil_printf("AURORA_MGT_1 to AURORA_MGT_0\n\r");
xil_printf("----------------------------");
xil_printf("---------------------------\n\r");
// set data for transmission
data[0] = (Xuint32) 'H';
data[1] = (Xuint32) 'e';
data[2] = (Xuint32) 'l';
data[3] = (Xuint32) 'l';
data[4] = (Xuint32) 'o';
data[5] = (Xuint32) ' ';
data[6] = (Xuint32) 'M';
data[7] = (Xuint32) 'G';
data[8] = (Xuint32) 'T';
data[9] = (Xuint32) '!';
// Push data to write packet FIFO
xil_printf(" Writing data to the AURORA_MGT_1 peripheral:");
xil_printf("\n\r ");
for(i = 0; i < 10; i++){
xil_printf("%c ", data[i]);
AURORA_MGT_mWriteToFIFO(aurora_mgt_1_baseaddr, data[i]);
}
// pop data out from read packet FIFO
xil_printf("\n\r\n\r ");
xil_printf("Reading data from the AURORA_MGT_0 peripheral:");
xil_printf("\n\r ");
while(!AURORA_MGT_mReadFIFOEmpty(aurora_mgt_0_baseaddr)){
temp = AURORA_MGT_mReadFromFIFO(aurora_mgt_0_baseaddr);
xil_printf("%c ", temp);
}
xil_printf("\n\r\n\r");
while(1){
}
}Download and Test the Project
The Hyperterminal output will show the results of two data transfer tests between aurora_mgt_0 and aurora_mgt_1. In the first test we transfer arbitrary data from aurora_mgt_0 to aurora_mgt_1. In the second test we transfer text from aurora_mgt_1 to aurora_mgt_0. The Hyperterminal output should look as shown in the image below:
The LEDs should display the status outputs: LED 0 - CHANNEL_UP, LED 1 - HARD_ERROR, LED 2 - SOFT_ERROR and LED 3 - LANE_UP. Note that due to the wiring of the LEDs on the XUPV2P, a logic high (“1”) turns the LED OFF, while a logic low (“0”) turns the LED ON. Try disconnecting the SATA cable and see how the status outputs change. The CHANNEL_UP and LANE_UP LEDs should turn ON. If we re-connect the SATA cable, the channel should be re-established and the CHANNEL_UP and LANE_UP LEDs should turn OFF.
The data rate of our MGT in this example is 1.5Gbps because we are using a reference clock of 75MHz which gets multiplied by 20. The effective data rate however would be much less than that because our data comes from the PowerPC. The PowerPC must send data to the Aurora peripheral through the OPB which uses a clock of 100MHz. The best way to make full use of the 1.5Gbps bandwidth is to source the data from the FPGA fabric or another high-speed interface. If however we must source our data from the PowerPC, we could improve this design by connecting the Aurora peripheral through the PLB and using Direct Memory Access (DMA) transfers. This improved version of the Aurora peripheral is developed in the next tutorial Aurora Transceiver for the PLB.