Sunday, September 30, 2018

Where do we go from here

Initial Goal Reached - Stretch Goals TBD

My goal for the Retrochallenge 2018/09 was to get a retro CPU core running on my FPGA board.

Mission accomplished - I used:

  • The well-respected open-source Arlet 6502 core,
  • Verilog code to create 64K of RAM with pre-loaded contents,
  • Some other Verilog glue code to put those pieces together, and jump-start the 6502 with a reset pulse.

The pre-loaded contents, specified by a simple HEX file, made the 6502 perform a few easy operations (like load a direct value into the accumulator), then jump to an endless loop padded with NOPs. On start-up, the 6502 jumps to the address specified at $FFFC and $FFFD. I placed the address $0400 at those RAM locations, and the program itself at $0400.

Since I had no I/O, it was a challenge to validate the program was actually running. I was able to do this by watching the contents of the PC (program counter) using the built-in debugging tools of Xilinx Vivado, the development software used to program my FPGA.

Initial challenges, some of which were documented in my earlier blog entries, included the RAM not working right and my HEX file not being properly formatted. I did make it through those challenges, borrowing from work documented on the C64 on an FPGA blog.

However, my stretch goals were to expand that into something that looked like a retro computer. I didn't get very far down that road.

The 6502 chip uses memory-mapped I/O. In order to get data in or out of the 6502, it would be necessary for me to modify the RAM interface so that certain addresses would, instead of storing/loading to actual RAM, would transfer data to/from some other circuitry instead. I did get this working just a little bit - I created a Verilog register and connected it to the 4 LEDs on the Zybo board. Then, I modified the RAM interface so that, if location hex E000 was written to, the output (lower 4 bits) would appear on the LEDs. This was actually pretty awesome, and worked well. But it's not very much I/O :-)

Where From Here

Learning digital design by doing has a lot of challenges, but you can learn lots of great stuff. One thing I learned is how FIFO (first-in, first-out) blocks can be useful in an FPGA design. You write info into the goes-in side of the FIFO, and another circuit reads that value in the goes-out side. The FIFO will tell you when it's empty (nothing to read) and full (when the data that's been written has filled the available storage of the FIFO). The goes-in and goes-out sides can use different clocks, meaning that the FIFO can help when you cross clock domains. This is important. I'm still learning more about what this means, but it's super helpful when two disparate digital circuits need to give data to each other.

So, for I/O, what I want to do is have two FIFOs, one for 6502 input, the other for output. If you write a byte to whatever I pick for the output memory address on the 6502, it will push that byte to the output FIFO. If you read a corresponding input address on the 6502, it will read the byte from the input FIFO. In both cases, the full or empty indicators of the FIFO would be checked as appropriate.

On the other end of those FIFOs, I'd like to put a RS232 UART. This will enable the 6502 to send and receive via a standard serial connection. Bang, Bob's your uncle, I/O. It will take some Verilog glue logic to hook this all up, but when done, I don't see any reason it wouldn't work.

Even though Retrochallenge is over, I'm going to keep going with this. Now that I have a working 6502, I'm hungry for more.

Thanks for reading! Stay Tuned!

No comments: