top of page

MicroZed Chronicles: Porting SpaceWire from Spartan-6 to Spartan-7

Updated: May 6, 2022

Space electronics is one of the main areas my consultancy is very active. SpaceWire is a differential high-speed communications protocol like firewire and one of the primary interfaces used in space electronics. As we know, it’s not just the flight FPGA that needs to implement SpaceWire, but also the test equipment. Several SpaceWire test equipment units use the Spartan-6 to implement the SpaceWire Codec. One example that provides high-speed SpaceWire communication targeted to a Spartan-6 LX45T is the 4 Links 400 Mbps Codec, currently available on open source (BSD license).

This is a RTL project and a new Vivado project can be created which targets the desired device. In this case, I created a project targeting a Spartan-7 XC7S50. However, the UCF which defines both the pin out and the timing requirements, will need migration to the XDC.

The main conversion from UCF used in ISE to XDC used in Vivado is very straightforward. The first element we need to convert is the timing constraints. In the UCF file, the timing constraints are defined by the TNM_NET and TIMESPEC constraints. For this project, they are defined as the following:

# Clock timing contraints

NET "iclock" TNM_NET = iclock;

TIMESPEC TS_iclock = PERIOD "iclock" 8 ns HIGH 50%;

In this definition, signal iclock is the output from an IBUFDS. Downstream, the design has DCM and global buffers but this is root clock.

We would use the XDC command in Vivado to create the following clock command:

create_clock -period 8.000 -name CLK_125MHz_p -waveform {0.000 4.000} [get_ports CLK_125MHz_p]

When I migrated the design to Vivado, I accounted for the slight difference in how Vivado analyzes clocks compared to ISE. Vivado assigns time zero to the point at which the clock is defined and ignores all delays upstream of the declaration point. As such, clocks should be defined at the primary input pins. If a clock is created in a design logic (e.g., counter, DCM etc.), that should be defined using the create generated clock constraint.

If you are concerned about which clock constraint to use, you do not need to write the constraint by hand in Vivado. You can use the timing wizard under the tools menu in Vivado once the synthesis has been completed. The timing wizard will walk you through the creation of a target constraint file (XDC) and the definition of constraints saved to the target constraints file.

With the timing issues addressed, the final stage of the design migration is to port the IO constraints from the UCF to the XDC file. The current definition in the UCF is as follows:





Again, we need to convert these to a XDC format suitable for use with Vivado. If desired, we can write a XDC file by hand in the existing XDC file created for the project.

set_property IOSTANDARD LVDS_25 [get_ports Din1_p]

set_property IOSTANDARD LVDS_25 [get_ports Din1_n]

set_property IOSTANDARD LVDS_25 [get_ports Din2_p]

set_property IOSTANDARD LVDS_25 [get_ports Din2_n]

set_property PACKAGE_PIN A3 [get_ports Din1_p]

set_property PACKAGE_PIN A5 [get_ports Din2_p]

Alternatively, if you are unsure of the exact format, you can use the I/O Ports tab in the synthesis view to define the pin allocation, IO standard, and any other IO features required. Like the timing information, this will be saved to the target XDC file which can be inspected to understand the XDC syntax.

We can now build and implement the project and generate the bit stream that is ready for porting to the new target Spartan-7 series device. Of course, this is a relatively straightforward port of a straightforward RTL design.

However, it gets us going in the right direction and provides us with a nice example of the steps involved, illustrating that conversion is nothing to be afraid of. We will come back to look at porting more complex features in a Spartan-6 design in another blog soon.



bottom of page