I didn’t get the Replay board just to run recreations of arcade machines and computers of old, I also wanted to get my feet wet with FPGA programming and the Replay board seemed like a reasonable device to learn with. Unlike a dev-board, it also has a concrete use after I’m done learning about FPGAs.
In this post I’ll cover a few of the differences I encountered over the last few nights as I worked through the earlier chapters of a VHDL book and applied it to the Replay board.
If you’re not looking to learn a few FPGA basics with a replay board and you’ve not run out of sheep to count or sleeping pills, it’s safe to skip this post.
Please read the disclaimer at the end before attempting to run any of the code mentioned below on your replay hardware.
For programming the FPGA I bought the Waveshare XILINX JTAG Platform USB Cable which works with the WebPACK ISE IDE and is cheaper than the official Xilinx cable. It is also entirely optional as far as programming goes, you can transfer the generated .bit file to an SD card and make use of the OSD loader to configure the FPGA instead.
Having never done any FPGA dev before, learning the basics of VHDL is the first priority. A link on the FPGA forums led me to a free book called Introducing the Spartan 3E FPGA and VHDL.
The book is written in a tutorial style under the assumption you own either the Papillio One or the Digilent Basys2 and whilst it would certainly be easier going if you used one of those devices before moving onto the Replay, with a little extra effort you can still work through the majority of the book.
It’s also worth having a checkout of the Replay’s public SVN repo for reference. The cores for the replay are built using the ISE command line tools rather than the IDE itself, but imo it’s worth sticking with the IDE initially until you’ve worked through the eBook. Switching over to the cmd line later is relatively painless and there are example build scripts for both Linux and Windows in the SVN repo.
Keep in mind that not all parts of the eBook are possible to do directly on the replay board unless you are willing to add extra LEDs/interfaces to the aux/expansion port. The Aux port can be used with 2.54mm pitch headers and broken out to a breadboard easily enough but take care is using them as there is no protection on the IO pins, they go straight to the FPGA. Failing that, the odd chapter can always be tested using the ISIM simulator instead of on real hardware too (see chapter 12)
For the replay board you want the ISE WebPACK installation from Xilinx and not the newer Vivado. Debian Stretch users should skip cable driver installation and perform a few extra udev steps after installation.
The /opt/Xilinx/14.7/ISE_DS/common/bin/lib64/ directory contains a udev rules file which needs a few tweaks and then transferring into /etc/udev/rules.d/ The hex files it will attempt to load via fxload either need transferring to /usr/share or the udev rule path editing to point to the /opt/Xilinx/… location.
Refer to this techplustuff blog post for the changes needed to the udev rule on Debian Stretch.
Once configured, the cable should show up under lsusb as
"ID 03fd:0008 Xilinx, Inc. Platform Cable USB II"
Anytime you launch ISE (the IDE) or impact (the JTAG programmer) tools, you’ll also need to first source the /opt/Xilinx/14.7/ISE_DS/settings64.sh file. I added two wrapper scripts in ~/bin/ for ise.sh and impact.sh e.g.
#!/bin/bash source /opt/Xilinx/14.7/ISE_DS/settings64.sh /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/impact
Debian Stretch needs libXm4 and libstdc++5 installing in order to run the fpga-editor (see chapter 6.5.1) Unfortunately it also requires libXp which is no longer available in Stretch.
You don’t require this tool in order to build and program the Replay board but if you do want to run it, using the Jessie version of libxp6 appears to be a sufficient workaround. Hopefully the package will be re-introduced in sid/testing and a back-ported version can be used in stretch.
After all that you might receive the error:
"Wind/U X-toolkit Error: wuDisplay: Can't open display"
Before running, set DISPLAY=:0
Everything should now be ready to develop for the Replay board. The image below shows a very basic VHDL program that lights one of two LEDs depending on whether a joystick is pushed up or down.
Load from SD
If you choose to forgo the JTAG programmer you’ll need to transfer the resulting .bit file the ISE tool will generate (see chapter 6) to an SD card and load it via the normal replay board’s OSD menu.
Transfer output.bit to “/sdcard/tutorials/tutorial_1.bin” and create a minimal tutorial_1.ini file with the content:
[SETUP] bin = tutorial_1.bin [UPLOAD] verify = 1
Then load the ini file as you would any other core target via the OSD loader.
FPGA Replay Specific Notes
Having worked through the first half of the eBook, most of the changes you would need to make to implement the chapter’s examples/projects on the replay board boil down to using just two LEDs rather than 8 and using the joystick port for switches. Notes on a few of the differences are below:
6.1 New Project
The Sparten device on the replay board needs the following configuration:
- Family: Sparten3E
- Device: XCS1600E
- Package: FG320
- Speed: -4
In the FPGA Replay board SVN cores/replay_lib/common/replay_common.ucf you’ll find the constraints setup suitable for the replay board. I selected D17, D16, C12 and D8 to cover two LEDs (power and disk) and using joy up/down for switch 0 and 1.
With the Xilinx Programming cable, you use impact. Start a new project and let it auto-detect the cable. Then it’s a simple matter of assigning a configuration file (the .bit file generated by the ISE build step), skipping the SPI/PROM step and selecting program to download to the FPGA.
In case it’s not clear from the schematic, the JTAG pin order on the board starting with the pin closest to the RS232/DC Socket side of the board is:
When working with the LED and joystick inputs, remember the joystick pins are normally high and will be grounded when the joystick is pushed in a given direction. The LED is also lit when the pin is driven low.
8.2 More LEDs
With only two LEDs on the replay board for this project and related ones, you’ll need to either make use of the expansion (P3,P7) with 17x2 pin 1.25mm headers or skip to Chapter 12 to learn how to use the simulator and then work through 8-10 in ISIM.
One gotcha if the simulator displays “U” for your LED/Switches, check the test bench for <clock>_ lines. As this and the next chapter do not make use of a clock input all references to the unimplemented <clock> need removing.
For this chapter you need to know the base frequency for one of the clock pins routed to the FPGA. tl;dr it is 49.125MHz for the Aux/Sys line. If you want the details though, read on.
The replay uses a programmable CDCE906 PLL to generate 6 clock signals from a single 27MHz crystal. The SMBus for programming the PLL is under the control of the ARM chip and can be configured via an ini file that is processed by the ARM loader firmware, or accessible via R10 (SCL) and P10 (SDA) on the FPGA.
Currently when the ARM based bootloader starts up, it will initialize the FPGA with a built in default binary in case there is no SD card available. It also defaults the PLL to HD27 mode.
The ini file format for hd74 can be set using
CLOCK = HD74
However, the “full” format is
# M1 N1 M2 N2 M3 N3 | p0 p1 p2 p3 p4 p5 | d0 d1 d2 d3 d4 d5 | y0 y1 y2 y3 y4 y5 CLOCK = 33, 280, 2, 11, 225, 2048, 1, 0, 4, 0, 2, 0, 2, 0, 5, 1, 2, 1, 1, 0, 1, 0, 1, 0
Starting from the back, y0-5 signifies whether each of the 6 clock outputs are enabled. They are wired to the following parts on the board (See schematics page 8 - clock generator):
- y0 - CLK_GEN_A0 (FPGA DRAM)
- y1 - CLK_GEN_A1 (Composite video encoder)
- y2 - CLK_GEN_B0 (FPGA Aux/Sys)
- y3 - CLK_GEN_B1 (Expansion Main)
- y4 - CLK_GEN_C0 (FPGA Video)
- y5 - CLK_GEN_C1 (Expansion Small)
Three clock signals are thus exposed to the FPGA itself, clocks A0, B0 and C0 via LOC U10, B10 and D10.
d0-5 sets the divider factor and p selects the base frequency, either
0=27Mhz, 1=PLL1, 2=PLL2, 4=PLL3
Where each PLL frequency is determined by 27MHz * Nx / Mx e.g PLL2 uses M2 and N2
PLL1 = (27MHz * 280 / 33) = 229.09MHz PLL2 = (27MHz * 11 / 2) = 148.5MHz PLL3 = (27Mhz * 2048 / 225) = 245.76MHz
The final output frequency is the selected PLL divided by the divisor d. e.g for y2, p2 is 4 which selects PLL3 or 245.76MHz and the divisor d2 = 5.
output_freq = 245.76MHz / 5 = 49.152MHz
The aux/sys clock for HD74 (the default boot config) is thus 49.152MHz
With that all said, as long as you have no SD card present, the HD74 settings will be programmed by default. If you are loading the bin file via the ini file though be sure to set CLOCK = HD74 within the ini.
There is a lot more to using clocks with the replay board than this little overview covers. I’ve yet to dig into the replay framework yet so can remain blissfully ignorant of the details a while longer.
Also, it has been noted that modifying clock settings incorrectly can be harmful:
Developers should think twice when using e.g. non-standard PLL settings
Especially bad timing setups may cause overheating or bus collisions which could (even slowly) damage board components. Feel free to contact me or Mike if special setups are needed.
Ok, you have been warned
My advice, stick with the default clocks HD74, PAL or NTSC for experimentation.
As with earlier chapters, there are insufficient LEDs for this chapter too. You can however do a 2 bit counter or blink one led every second and the other every 60.
Another example to try is light up one LED only if the joystick is held up for 5 seconds or more and clear it on release.
The three FPGA exposed clock lines are:
# Replay Clocks NET "i_clk_a" LOC = "U10" | IOSTANDARD = LVTTL; NET "i_clk_b" LOC = "B10" | IOSTANDARD = LVTTL; NET "i_clk_c" LOC = "D10" | IOSTANDARD = LVTTL;
This chapter only needs one, I used the Sys/Aux clock line
# Renamed to match VHDL tutorial NET "clk" LOC = "B10" | IOSTANDARD = LVTTL;
As the ebook notes, IEEE.NUMERIC_STD.ALL should be used in place of IEEE.STD_LOGIC_UNSIGNED.ALL. The counter signal should then be declared as UNSIGNED rather than STD_LOGIC_VECTOR
I’ve worked through to chapter 16 so far which cannot be done as written, but there is a WM8729 DAC to experiment with instead. Or if you have an oscilloscope you can output to an aux pin and at least see the resulting signal.
From a skim of the remainder of the eBook it looks like most of the remaining chapters can be roughly followed with a little creativity.
I’m not sure how much further I’m going to go with the eBook. It has helped with learning the very basics of VHDL and the tools needed, but it may now be time to move on to a fresh project that makes use of the replay_lib with reference to the “loader” core to see how everything is hooked up.
Following any part of the above on an actual replay board is entirely at your own risk.
As a complete newbie as far as FPGA and the replay board hardware goes, I cannot be certain the above changes are all safe to do. There will be many non-configured FPGA pins for one, whether that could result in damage to your board or not, that’s not for me to say.
Don’t blame me if you find your board releases magic smoke :)