Part 4 - Up and Running
This article continues on from Part 3 - Signs of Life.
I've now got FPGABee up and running on the XuLA2.
SD Card Controller
In my last post I had everything in place to get FPGABee up and running - except for the SD card controller. Since the interface to the SD card is very simple and since I'd be using the same PmodSD as on the Nexys-3 and since writing test code wouldn't be simple I decided to just hookup FPGABee and see what happens. So not much to talk about there.
XuLA Too Small
After setting up a new project for the XuLA that brought in the entire FPGABee core it soon became apparent that it wasn't going to fit on the smaller XuLA board. Usage came out at about 190% of the XuLA's available space.
(In hindsight I should got back and check that more closely - it may just be the PCG block rams that are taking up too much space)
So I set the XuLA aside, soldered in the header pins to the XuLA2...
XuLA 2 Clocking Issues
Switching back to my Xula test project I modified the project for the XuLA 2 - changed the FPGA chip part number, changed the UCF pin assignments and added in the pin assignments for the SDRAM that weren't available on the smaller XuLA board. I also updated the SDRAM geometry from 4096 to 8192 rows to match the larger memory chip.
Getting the clocks setup however proved to be a little difficult. Trying to get a slow 3.375Mhz clock was the biggest problem since the clock management tiles on the Spartan LX25 don't like going below 5Mhz.
Coincidentally one of the MSPP members - tcdev - was encountering similar problems porting to an Altera board and suggested using a faster clock and a clock enable signal. So I've now updated the FPGABeeCore to support an arbitrary clock timebase which when combined with a supplied clock enable should yield 3.375Mhz.
-- CPU clock clktb_3_375 : in std_logic; -- CLocK Time Base, any freq clken_3_375 : in std_logic; -- CLocK ENable, when applied to clktb should produce 3.375Mhz
For the XuLA, I'm running the clock at 54Mhz with the clock enable dividing it down by 16.
Stalled CPU Core
On the first run, the VGA (including my status panel) and keyboard worked first go however the Z80 didn't seem to be running - the current PC address that I had displayed on the status panel was stuck at 0x0000.
After double-checking everything over a couple of times, I thought I'd try toggling the T80 core's reset line to see if that would kick it into action - it did. I still don't know why this is - neither the XuLA nor Nexys-3 boards required this.
The reset works similarly to the soft reset used by the PCU - a shift register that asserts the reset line for 8 clocks:
signal reset_shifter : std_logic_vector(7 downto 0) := "11111111"; signal reset : std_logic; -- Simulate a reset to get z80 running reset <= reset_shifter(0); process (clktb_3_375) begin if rising_edge(clktb_3_375) then if clken_3_375='1' then reset_shifter <= "0" & reset_shifter(7 downto 1); end if; end if; end process;
With the CPU now running and some simple memory tests working I decided to hook up the reset of FPGABeeCore. It sort of worked. The Microbee side of things didn't boot but the PCU menu appeared yet some characters were randomly corrupted. That said, it did show enough to see the disk image names so I could assume the SD card interface was basically working.
XuLA2 SDRAM Controller Issues
Taking a guess these issues were related to unreliable memory I switched back to my test project and wrote a more intensive memory tester in Z80 assembly language. To get it to run I needed to setup a small block of BRAM backed memory for the stack but once I got it up and running I found that read's immediately following a write to the SDRAM were failing fairly regularly.
This took several hours of testing and debugging to get to the bottom of but turned out to be a misinterpretation of how to use the Xess SDRAM controller. In my initial implementation to execute a memory read or write I simply asserted the controller's
wr_i line and then waited for the
done_o signal to go high. The documentation and timing diagrams in the controllers data sheet seem to indicate this should work.
What I found however is that the done_o signal by itself is not enough to detect the end of a memory operation. I needed to wait for the
opBegun_o signal to go high and then watching for
done_o. After making these changes all the memory related issues went away and the memory tester ran for several hours without a problem.
This change also fixed a previous issue I was having with the controller where memory reads/writes immediately after a reset were failing and let me remove some extra state management logic I had to handle that.
With the memory controller now working properly, FPGABee fired up and seems to be working perfectly:
Here's a close up of the Xula2, the Stick-It board, VGA Stick-It, PS2 Stick-It and PModSD.