Now, reading thousands of binary digits in text becomes rather unwieldy quite fast, so I also wrote a simple program that converts the text output to BMP, for easier comparison. An added bonus here, is that the hardware implementation is itself simulated in ModelSim, which allows me to output the intermediate states in text form. (Following some helpfull hints from this forum thread.) The format that my C++ simulator outputs is designed to mimic the same file format that ModelSim uses, this way I can create BMPs from both, for comparison.
In my last post I mentioned Rule 30, now, let's see how my simulator-output looks for Rule 30:
Here time flows from top to bottom, and each line represents a generation of the CA. |
Note the line at the top, this stems from the solution I've chosen for loading initial data into the grid of CA's:
I put the column I want to load as the neighbours of the left-most cells (in this case we're working one-dimensionally, so the column is actually a single value. Then the rules for the grid are held to be "take on the value that your left-hand neighbour has", thus essentially shifting the values into the grid.
When the values are finally shifted into the grid (roughly 1/3 from the top), the grid starts to follow the Rule 30-ruleset, with the edges of the grid being set to 0.
This way of representing the CAs allows for a quick visual inspection that it tends to follow the intended behaviour, and thus allows for easy comparison with the hardware implementation.
It's worth mentioning though, that the CA-system does not really allow reading from anything but the edges, but for testing purposes we cheat a little, both in C++, and in ModelSim, so that we can read the actual values. In a proper setup, we would have to work only based on what we can read from the edges, but even then, we can actually read the entire grid, given that we do the following:
- Allow the grid's rightmost cells to be read
- Make the grid "wrap", so that the rightmost cells have the leftmost cells as their neighbours and vice verca
- Use the same "shift rule" as for loading
- Read every column, and apply the rule to get the next column.
Thus, the entire grid can actually be read, even in a proper "non-cheating" implementation.