The Golden Top File: Stop Fighting Your FPGA Pin Assignments

Stop assigning FPGA pins by hand. Use the board vendor’s Golden Top Board Configuration (GTBC) files. They already map the FPGA I/O to the hardware on the board, correctly. Drop them into your project and start coding instead of fighting the pin planner.

The mapping is done, tested, and boring—which is exactly what pin assignments should be.

To better understand the Golden Top Board Configuration:

  • The GTBC is not about logic; it’s about mapping FPGA pins to board hardware.
  • It serves as a pin map for the development board with descriptive vectors e.g., SW[9:0].
  • Hardware naming conventions follow the names used in the board’s user manual.
  • The configuration includes the board’s recommended pin drive voltages.
  • Gotcha: The simple names do not encode polarity e.g. an active-low LED.
  • The GTBC is provided by the board developer not the FPGA OEM.
  • The GTBC stops being important when you leave the development board.

What is contained in the Golden Top Board Configuration

The golden configuration consists of two time-saving files:

  • Top level Verilog code with prebuilt I/O vectors.

  • Pin assignment map. For Quartus, this is a .qsf file normally developed by the pin planner.

A snippet from each file is included as Listing 1 and Listing 2 respectively. Together, they describe what exists and where it exists on the FPGA development board. Yes, you could reconstruct the files manually, but it would take considerable time and effort. You could also make mistakes that are difficult to locate. One of the worst examples is an incorrect pin assignment to the DRAM. This is especially difficult to troubleshoot as there is no way to physically probe the DRAM or the FPGA pins.

You will troubleshoot for hours or days attempting to isolate the software errors from the hardware errors.

module top(

      ///////// CLOCK /////////
      input              CLOCK0_50,
      input              CLOCK1_50,

      ///////// KEY /////////
      input    [ 3: 0]   KEY, 

      ///////// SW /////////
      input    [ 9: 0]   SW,

      ///////// LED /////////
      output   [ 9: 0]   LEDR, 

Listing 1: Partial listing of top-level declarations.

#============================================================
# CLOCK
#============================================================
set_instance_assignment -name IO_STANDARD "1.2-V" -to CLOCK0_50
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK1_50
set_location_assignment PIN_K43  -to CLOCK0_50
set_location_assignment PIN_A8   -to CLOCK1_50

#============================================================
# KEY
#============================================================
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to KEY[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to KEY[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to KEY[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to KEY[3]
set_location_assignment PIN_K26  -to KEY[0]
set_location_assignment PIN_K27  -to KEY[1]
set_location_assignment PIN_BK10 -to KEY[2]
set_location_assignment PIN_W12  -to KEY[3]

Listing 2: Snippet of code from the top.qsf file mapping hardware names to FPGA pins.

Polarity Considerations

The GTBC descriptors are typically built as simple as possible. They use names such as LED and SW. It is up to you to identify the polarity (logic high vs logic low assignments).

The common misconception of negative logic is first revealed when initially programming the FPGA.

Recognize that all mapped (defined) output pins will be driven by logic. However, if not specifically driven by the FPGA, the synthesizer defaults to a logic low output. As a result, all undriven active-low LEDs will be turned on.

We have two solutions to deal with the polarity:

  • Use bit inversion. This is highly undesirable as the ~ operator is scattered across the program. These are future bugs and they increase the mental overhead to understand the design’s logic.

  • Invert the LED assignments in one location as shown in Listing 3. In this case, assignments are made to the LED_req (request) variable. A single 10-bit inversion does all the hard work.

    wire [9:0] LED_req;    
    assign LEDR = ~LED_req;

    assign LED_req[2] = SW[2];
    assign LED_req[1] = SW[1];
    assign LED_req[0] = SW[0];

Listing 3: Bit inversion for the active-low LEDs.

Do we need to keep all pin assignments if they are not used?

Time and clarity are the most important element to this discussion.

The top module and the .qsf are a matched pair. They have a one-to-one correspondence as Verilog symbols are mapped to physical I/O. If we change one, we must also take the time to edit the other.

Verilog is not sequential code! There is no penalty to keeping the pin mapping. The code length has very little to do with the final results. This is especially true for the mapping to unused I/O. In fact, the unused pins will simply be driven with a fixed logic-low signal.

Code Complexity. Clarity is one potential downside to retaining unused mapping. This is especially true as the top module fills up with instantiation. I recommend keeping the mapping intact (unmodified) as a single text. Also, consider moving some of the top instantiations to submodules. If it helps bound the golden code with Start: DO NOT MODIFY and END: DO NOT MODIFY.

When we consider the time commitment and the impact on code length, there is very little reason to change the symbol and pin mapping.

What are the limitations of the golden top board configuration?

As a rule of thumb, the GTBC file is perfect for on-board circuitry. However, things get complicated when connected to application specific external hardware. For example, the Terasic DE23-Lite features a 2x20 pin GPIO header (Figure 1). The external hardware will certainly contain a variety of inputs and outputs. The generic GPIO_D[35:0] is too abstract. It is preferable to use function appropriate names for the hardware; the abstraction hides mistakes. For example, a SPI-based sensor could be attached to the GPIO header. It is preferable to use self-documenting names such as MyProjectSCLK, MyProjectMOSI, etc.

Figure 1: Image of the Terasic DE23-Lite with 40 pin I/O header.

Parting Thoughts

While the examples in this article use Intel Quartus and a Terasic development board, the same principles apply to other FPGA toolchains (e.g., Xilinx or Lattice).

Best wishes,

APDahlen

Related Articles by this Author

If you enjoyed this article, you may also find these related articles helpful:

About This Author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians.

Dahlen has returned to his Northern Minnesota home, completing a decades-long journey that began as a search for capacitors. Read his story here.

1 Like