Joseph’s Status Report for 4/24/21

My last progress report was posted on 4/10/21. A lot has happened in the meantime.

First, I fixed and tested the PPU DMA Engine using a new tool (Quartus SignalTap), which lets me probe various signals from the hardware while it was running. Very useful in helping me debug the DMA Engine while it was actually connected to the FPGA-to-SDRAM Bus.

I added buffering of PPU Control registers so that they sync whenever VRAM syncs (after a completed DMA transfer). This prevents screen tearing because background/foreground scrolling registers cannot be modified while a frame is being drawn, only in-between frame drawing. This wasn’t very visible over the Zoom live demo from last week, but it was there and is now fixed.

Next, I implemented the PPU Kernel Module. Andrew’s prior research and development in the APU and controller kernel modules streamlined my learning process. Unfortunately, while most of the kernel module worked okay, I ran into an issue with the FPGA-SDRAM bridge blocking DMA transfers from completing. Originally, we ran into this issue with the APU. Our solution back then was to simply move the APU to the FPGA-HPS bridge. However, I really wanted to use the SDRAM bus for PPU DMA transfers (especially since I spent significant time developing the DMA-Engine for that purpose). After long hours of debugging and trying out various things, I finally found a solution. It turned out that none of the bootloaders I had used enabled the SDRAM bridge, even though they were documented to. I had to make the PPU kernel module write to a hardware register on the HPS to enable the specific ports we were using on the SDRAM interface.

In the last few days, I’ve designed and partially implemented a User Library for interacting with the PPU kernel module. I’ve attached the WIP doxygen reference below. Feel free to take a look at the “Functions” section on the 1st or 2nd page, as they are the most legible in that PDF upload. Currently, enough of the library is written to enable a software version of the Interim Demo.

fpgame_ppu_user_library_doxygen_v1

Next week, I will

    • Test/Debug the remaining User Library functions.
    • Write an instructions document for modding an SNES Controller extension cable to work with FP-GAme GPIO.
    • Finalize an SD Card image with FPGA program file and Kernel modules.
    • Write a high-level guide to FP-GAme (FP-GAme user manual).
    • Work on Final Presentation Slides.

Team Status Report for 04/24/2021

We are entering the last few weeks of the project and we have made some significant progress so far. We only have a few tasks remaining. Instead of providing a Gantt Chart, we’ve condensed our remaining tasks into a small list.

Next week:

  • Joseph finalizes PPU User Library and gets started on the Demo Game.
  • Andrew works on Sprite Engine. We meet on the weekend to verify it works with our user library.

After this, the hardware and software components of the FP-GAme console are finished. There are only a few user-experience tasks to accomplish.

Things we want to do for the user experience:

  • Finalize an SD Card image with FPGA program file and Kernel modules.
  • Write an instructions document for modding an SNES Controller extension cable to work with FP-GAme GPIO.
  • High-level guide to FP-GAme (FP-GAme user manual).

For next week, we also have some course-related work to accomplish. In particular, we will need to work throughout the week on the final presentation.

Andy’s Status Report for 04/24/2021

These past two weeks, aside from the ethics assignment, I focused on fixing the APU (which happened very early in the first week) and designing and implementing the sprite engine.

I’ve attached a diagram of the internal logic of the sprite engine. It’s currently roughly 80% done, and I expect to finish the remainder over this weekend. On the diagram, everything is implemented except for the OAM scanner and memory port wrappers.

The sprite engine itself works as follows. The engine will receive a signal from the tile engines that they have finished buffering their data, and that the sprite engine may now access the M10K’s which function as VRAM. The OAM scanner will then begin to scan OAM (Object Attribute Memory) for sprite data that corresponds to the current scanline being rendered. The first sixteen pieces of this data found will be sent to the sprite manager.

The sprite manager, on receiving an Object Attribute, will ask the scanner to halt while it makes accesses to pattern memory for the sprites visual data. It will then send its data to the sprite file, which is drawn in the diagram as 16 sprite units and a sprite tournament mux.

The sprite units are linked in a chain, where the last unit in the chain is connected to the sprite manager. After receiving a valid sprite, each sprite unit will send the data down the chain until this is no longer possible. Having the sprite units connected in the chain means we don’t need a large number of muxes to allow the sprite manager to write to each unit individually, and the cycle delay of things moving down chain is invisible to the rest of the board, as the sprite tournament logic will hide it. The sprite tournament logic is simply a special mux that chooses a sprite based on its visual attributes.

The sprite engine is the last piece of hardware we need to implement. After it’s done, we’ll just need to do some more tests and finalize our documentation before working on the game. I expect work on the game to begin around the middle of this coming week.

Sprite Engine Diagram: Sprite Engine V2

Joseph’s Status Report for 4/10/21

My initial task for this week (finished on Sunday/Monday) was to fix the Tile-Engine scrolling and Y-Mirror issue. Last Saturday, Andrew helped me find the bug in the Y-Mirror feature of the Tile-Engine. Every tile entry in Tile-RAM has a Y-Mirror bit, which reverses the order in which rows of a tile are fetched from Tile-RAM when it is time to display that tile in the video output. This causes the final rendered tile to be vertically flipped. The bug was that the tiles were being reversed in chunks of 2 tile rows (instead of every tile row being reversed). As for the scrolling bug, I saw artifacts when scrolling in the horizontal direction, but the vertical scroll was working just fine. I found, after much simulation and debugging, that the way I had been applying the horizontal scroll needed to be rethought. The correct behaviour was to use the most-significant-bits of horizontal scroll to determine which tiles were fetched for a given row, and then use the least-significant-bits of that horizontal scroll to determine which pixels were fetched when it came time to render.

This week, I finished the video demo used for the interim demo. It features a scrollable pixelated world modeled after “The Mall” (at CMU), with the scroll inputs controlled by the SNES controller.

I also began the rework of the PPU-CPU communication, this time using DMA over SDRAM. So far, I’ve split the VRAM into a PPU-Facing VRAM (which is accessible only by the PPU) and CPU-Facing VRAM (accessible only to the DMA Engine). Note that there were always 2 VRAMs in our implementation, but their connections were not fixed as they are now. Most notably, the CPU-Facing VRAM has had its data-width extended to 128-bits to be more compatible with the SDRAM bus and DMA Engine. Next week, I will be finishing this implementation, and (hopefully) beginning some work on the PPU driver.

Team Status Report for 04/10

This week’s tasks included APU implementation, PPU bug-fixing, and redesign of the PPU-CPU communication.

For context on the PPU-CPU communication redesign, a team design-review meeting was held last Saturday, which resulted in a redesign to the PPU-CPU communication. During the design phase, Joseph and Andrew had differing ideas on how the PPU-CPU communication and eventual PPU driver should work. Joseph wrote his design in the design review report: The CPU sends video data to the PPU over the AXI BUS accessible via MMIO, following strict timings. However, last weekend the team decided to switch to Andrew’s design: The CPU sends an address to the PPU, which the PPU then uses to DMA-copy video data stored in SDRAM. The main benefits of this include less coupled timings between the CPU and PPU, as well as more intuitive PPU software (with a lot of reusable code from the APU kernel module). Joseph will be implementing this next week, so some scheduling changes needed to be made.

Here are the scheduling changes and brief reasons for their occurrence:

  • Moved task the “Row Buffers, VRAMs, CPU->VRAM Interface”. Joseph needed to modify the designs of the CPU-Facing VRAM Interface to be more compatible with the SDRAM. This task is mostly done, but needs to be verified along with the SDRAM DMA next week.
  • Added a new task for implementing PPU-SDRAM DMA. The goal is to accomplish this next week.
  • Joseph used 1 Slack Time for the Tile-Engine Implementation. Tile-Engine was difficult, and required setup and debug of a few other interdependent systems.
  • Created a new APU bug task. Andrew will be working on this next week.

Andy’s Status Report for 04/10

The plan for this week had been for me to finish up the APU and then work on the sprite engine. Unfortunately, I hit a hard wall with communication between the APU and the CPU. Some progress has been made on that front, and I’m now able to send a 1KHz sine wave from a C program through the APU driver to the APU. Unfortunately, some corruption issues are preventing non-static data from being sent through.

Still, this does mean that the APU is fully written, just not fully debugged. The user space library for the APU is complete and tested, sending signals to a user process as a kind of user-mode interrupt works great. The kernel module is mostly written with the aforementioned corruption issues. The hardware, after some intense debugging and scrutiny from both Joseph and myself, seems to be fully operational.

I suspect that the issue is with the kernel module, and not the user space library or test program. It seems likely that I haven’t set up the APU kernel buffer for DMA correctly, and so that will be where I investigate next. The running theory is that our level 1 cache isn’t being flushed, and so we’re only getting some of the samples out of the kernel buffer into the APU, and are thus seeing corruption.

Thanks to the slack time we allocated for the end of this semester, there’s still a good chance that we’ll be able to get everything done on time. The plan for this coming week is for me to fix the APU and then deal with the sprite engine in any remaining time I have. After that, I’ll have a week to finish the sprite engine and two to work on the test game.

Joseph’s Status Report 4/3/21

Early this week I integrated Andrew’s I/O Subsystem into the main project. This was incorporated into a work-in-progress scrolling demo on Saturday.

The majority of my week was spent on implementing the Tile-Engine and Pixel-Mixer.

The Tile-Engine is almost finished, there are just a few bugs remaining with the mirror and scroll features. Andrew helped me find the source of some of these, and I will be implementing the fixes tomorrow (Sunday 4/4/21).

The Pixel-Mixer module currently only has a background Tile-Engine attached to it, with a dummy Sprite-Engine and foreground Tile-Engine – which simply output transparent tiles.

On Saturday, I began to put together a hardware-only demo involving controller-input and scrolling of the background layer as a Minimum-Viable Interim Demo. The background tile-data, pattern-data, and color-palette-data are planned out using Tiled (https://www.mapeditor.org/), drawn using Piskel (https://www.piskelapp.com/), and then converted into .mif files via a few python scripts I wrote.

Next week I will primarily work on the video demo, fixing the remaining bugs with the Tile-Engine, and implement one of either the DMA or Sprite-Engine. Unfortunately, some of the time spent on the CPU-VRAM interface last week was misguided (my fault). The CPU interface I designed uses MMIO to write data to the PPU, which after a short discussion with Andrew, I learned was terribly inefficient. I will be doing some research to see if I can reuse one of Intel/Altera’s DMA IP blocks to copy VRAM data from DRAM.

Team Status Report for 04/03/2021

We’re in a slightly better spot than we were last week, as we made a lot of progress this week. We’re both optimistic about the future. As we’d currently consider ourselves roughly 2 days behind the schedule from last week, there are no official scheduling changes.

By the end of next week, we should have the controller and audio modules fully finished and most of a working hardware implementation for the PPU. A video and audio demo will also be prepared for the interim demo.

Andy’s Status Report for 04/03/2021

This week, I finished up the controller module (which now fully works) and made significant progress toward a finished audio implementation. Work on the sprite engine hasn’t begun yet, so we are still behind (arguably more so), but we’ve both increased the amount of time we’re spending on this project. All things considered, I’d still say this week went well and I’m optimistic that we’ll be able to catch up.

As I projected in my previous report, I was able to finish the controller kernel module over that weekend. The changes necessary to get the controller module were largely uninteresting, I simply had to build a new linux kernel and change the one the provided linux image used. Then, there were some bug fixes for the kernel module and the user space library functions. All of this was completed over the weekend, and the controller library works as intended.

For audio, so far the actual device is fully described in verilog and has undergone a reasonable amount of testing. I was successfully able to play a 1KHz sine wave using the APU. With the hardware itself working, my main focus now is on bringing up the software side of the apu. The communication between the CPU and the APU is setup, but untested. Around half the kernel module is done, and the user space portion of the APU library is specified but unwritten. All told, I’ve got ~400 lines of C code to look forward to, but I’m no stranger to that :). Hopefully, I can get most of it done over the weekend and dedicate some real time to bringing up the sprite engine next week. I’ve got some grading work to do for OS over the weekend, though, so that will probably eat up quite a bit of my time, unfortunately.

Don’t have anything super interesting to share this week. Next week, I should have a video of a working audio demo (that isn’t just a test sine wave). For now, here are the verilog files for the APU. Note that I wound up not using their premade I2S module because it was trash. I threw together something with a much nicer interface, instead.

APU + I2S files: https://drive.google.com/file/d/14EN3CveBKY3m0okfWgywr5-sRoCuts16/view?usp=sharing