Overall, the results of this project was as we expected. We were able to fully generate a 1000x1000 grid world, and update both Wireworld and Conway's Game of Life automata at a max of 60Hz (the VGA update speed) with no visual glitches, and no switching to the wrong states (for all the cells we observed). Along with this, the group was able to use the HPS to fully save user created designs to files, and then subsequently load designs from these files back to memory.
Additionally, we achieved a high degree of usability; users are provided an intuitive mouse interface, with clicking for modifying state and dragging to pan on the output to the VGA screen. Our HPS interface additionally allows users to load and save designs, as well as updating state, without necessarily understanding the underlying mechanisms. This abstraction allows users to consider our hardware as a black-box for a more intuitive experience.
Results
Wireworld
Our project is primarily visual; the project is all about watching the cells update. Here are a couple of photos that display some things user are able to do in Wireworld, visually indicating the success of the project. Along with these images, the demo video found in Introduction fully covers the project in a video form.
One of the first things that the group did when a working Wireworld was implemented was to show working logic gates.
Here, three logic gats are implemented: OR, AND-NOT, and NAND. These logic gates work just as one would expect; instead of checking voltage levels, it is checking whether an electron head is present or not. For the first gate, the OR gate, it is constructed to allow the electrons to flow through regardless of whether both are present.
For the AND-NOT gate, if an electron head from the lower half (A) is present at the output cross, and no electron head from above, the electron head will be based without issue. However, if an electron head is present from the upper half (B), then the electrons will interfer, and the output will be empty.
Finally, the NAND gate works similar to the previous two. However, this gate has two clock generators internal to the gate which will output an electron by default. Only when both generators are destructively interfered with by incoming electrons (indicating both inputs are 1) will there be no output electron (indicating an output of 0).
Since we can construct logic gates, we can scale this up to an entire processor; specifically, we used the previously-implemented processor described in Background.
While this image only shows the seven segment display and their associated decoders, it demonstrates that we can load the entire processor into memory. The whole structure works and updates as intended, and is able to be run at 60 Hertz, the refresh rate of the monitor. In the case of this processor, it took up to 14 million cycles for the processor to reach the current state; to fully see this design "work" is therefore unfeasible to the scope of 60 Hertz; further optimizations would need to be made (perhaps having a period where only the solvers were able to read and write). To see this design updating, see the Demo on the Introduction page.
Conway's Game of Life
The second item that was added to the final project was Conway's Game of Life. While this task requires a different set of rules compared to Wireworld, the overall infrastructure for updating an automata is the same; we only need to modify the solver node to use a different set of update rules. With this, on the flip of a switch, the group is able to quickly change the ruleset from Wireworld to Game of Life and back again.
The first thing that this group did when Game of Life was implemented was to instantiate a "glider gun", a Game of Life structure that is comprised of both moving and static parts that will continuously produce "gliders" that run across the screen forever.
A glider gun was chosen to test this implementation because it is one of the classic Game of Life strucutures, and it shows that what should be static is static and what should be moving is moving, as well as that we are abiding by Game of Life's rules. This image depicts the glider gun producing gliders with two gliders already produced.
After making sure that Game of Life worked as intended, the next step was loading the Wireworld processor and then turning changing the rule set to Game of Life, purely to see what it might look like. The end result looked something like this:
This image shows the Processor after running a few cycles of Game of Life. A video of this design updating and transforming is in the Demo on the introduction page. Overall, switching from Wireworld to Conway's Game of Life operated as expected. On the flip of a switch, the FPGA seemlessly switched rules, and had no visual nor comuputational glitches associated with it.
Device Utilization
One result that suprised the group was the overall board utilization. Although there are no DSP blocks being uitlized on the board (as we don't need any multiplication/division), the project still uses a large amount of the available resources when updating a 1000x1000 grid.
The lower image shows that:
- Half of the on-chip memory is being used
- Three phase-locked loops are being used
- The relatively fast M10K block memory (200MHz)
- The VGA screen clock (~25MHz)
- The system PLL (100MHz)
- 86% of the logic units are being utilized
From this board utilization comes the question of what will run out first for a larger grid: memory or logic units. In this case, it strongly depends on how the grid is expanded. If each row were to be made longer, we need no more iterators but more memory, indicating memory will run out first. Instead, if each column were expanded (more rows), we would need more memory, but we would also need more iterators and expanded address size, indicating that either could run out.
Conclusions
Overall, the project was successful, met every expectation for implementing a cellular automata and even exceeded some of these expectations (such as the late inclusion of Game of Life). Even so, there are still items that would have been cool to implement into this project.
Since Conway's Game of Life is turing complete itself like Wireworld, if the group had more time in the final project, a nice addition would be either finding or constructing a Game of Life processor. To do so would probably require a much larger grid than the Wireworld processor, and may therefore not be feasible for our FPGA, given how resources were already nearly exhausted with our current implementation. One approach could be to utilize off-chip SRAM, which would require bus read and writes, making the overall design significantly slower.
Another item that would be cool to implement if we had more time in the lab would be to implement another cellular automata. As shown through the implementation of Wireworld and Game of Life, the memory accessing and infrastructure is already in place for a different set of rules to be used. If there was more time, finding further cool and interesting automota to implement would be a worthy inclusion.
External IP Used
In the process of completing this project, the group referenced three pieces of previously-implemented IP
- The PS2 Interface was used from the University of Washington's EE 271 class, which in of itself is a modified version of a Terasic PS2 Mouse example.
- The VGA Driver was created by Professor Adams for the ECE 5760 class, found here. This is the same driver used for Lab 2 of ECE 5760 with slight modifications, such as changing it to accept 24-bit colors instead of 8-bit colors.
- The Wireworld Processor, including the layout, were made by David Moore, Mark Owen, Julien Thevenon, and more from Quinapalus
Things Tried
Memory
One thing that was tried, but ended up not working, was how memory was being accessed by the iterators. Since we are storing the state of each cell (and not the color), the FPGA would only have to store 2 bits for each cell (2 bits for the four states a cell can take on). From this, the group determined from the available M10K memory itself that the board would be able to simulate up ~1,560,000 cells before on board memory ran out. Initally, each itertator was getting its own M10K memory block; when the group went to compile this design, it was done with a small number of cells, on the order of 100x100. The issue with this setup was found once we tried a large number of cells; having only 390 blocks limited us to 390 iterators. To overcome this, we adopted a more complex memory addressing scheme that allowed 8 iterators to use the same M10K block, allowing us to fully simulate our desired 1000x1000 grid size.
Zooming
While we currently have a zoom in and out feature, the current zooming is not the most elegant of solution. As it currently stands, zooming in and out of the grid causes the screen to always expand relative to the top left hand corner of the cell grid; thus, when zooming in the camera zooms up and left, and when zooming out the same happens but down and right, as described in the image below:
An item that the group tried to implement but ended up not doing, was trying to give the user a "better zoom". This zoom would work as one would expect, zooming in and out from the center of the screen. This fix falls under this category ,however, because upon implementing the "better" zoom, as soon as the new Verilog was compiled and ran, Wireworld would break. Some cells at the start of updating would go from conductor to electron tail, go from empty to conductor, or just disappear entirely. After the fact, this issue most probably was a timing path issue in fitter; the group is still unsure. The reason for this uncertainty is becasue one would expect that, if there is a timing issue, or even a memory access issue, that the problem would arise periodically in the same locations. For example, if cell x were having issues we would expect cell x + 10 to experience the same issues. In this case, this periodicity was not present; cell x would have issues and then cell x + 10 would be working as normal. This issue lead the group into discarding this "better" zoom in favor of an overall design that did not have this weird glitch.
Glitch From Zooming
On the topic of the glitch from zooming, some state didn't correctly update even with our "poor" version of zooming. The group was eventually able to fix this issue in a fashion that did not even attempt to address it. In the final week of the project, since the cellular automata infrastructure was already in place, the group decided to implement Conway's Game of Life along with Wireworld. To add Conway's into the solvers, a multiplexer was added so that depending on SW[1], the solvers would either be using Conway's rules or Wireworld's rules. By synthesizing this new Verilog, the glitch that arose from the better zoom was fixed. We currently hypothesize that this bug was a timing issue, as the multiplexer would have been a break in the design path and allowed the fitter to create a more optimal timing path (possibly adding delay to meet hold time requirements).