HPS Program Design
For this project, the group wanted to keep as much work as possible onto the FPGA (expecially the mouse interface), only using the HPS when necessary. When completing the project, we identified three things that the HPS should handle:
- Loading state from a file
- Save state to a file
- Telling the solvers to update
The first two items are crucial to the end project that we wanted to design (a project that would be able to load and save a Wireworld design). While the third item could have been implemented with the various switches on the DE1-SoC, the group decided it was easier and cleaner to specify update rate through the terminal.
To go implement these three features, 9 PIO ports were added to the system connecting the ARM HPS to the FPGA:
- Items going into the HPS from the FPGA
- resp_col
- resp_row
- resp_val
- Items going into the FPGA from the HPS
- req_col
- req_row
- req_val
- hps_init
- Bit 0 indicates whether the HPS is active or not
- Bit 1 indicates whether we are reading (0) or writing (1)
- cycle_val
- cycle_clk
These PIOs can be used to achieve the above goals:
- Loading a Value to the memory state
- Set req_val to the value you want to write
- Set req_row and req_col to the row and column you want to write to, respectively
- Set hps_init to 0x00000003 (we're active and writing)
- Wait until resp_row and resp_col from the interface match req_row and req_col, indicating that the value has been written.
- The HPS can iterate across all values in the file to load the entire state
- Storing a Value from the memory state
- Set req_row and req_col to the row and column you want to read from, respectively
- Set hps_init to 0x00000001 (we're active and reading)
- Wait until resp_row and resp_col from the interface match req_row and req_col, indicating that the value has been read.
- Read the value given in resp_val, and store it where desired
- The HPS can iterate across all values in the grid to save the entire state
- Updating State
- Set cycle_val to the number of updates you want the solvers to make
- Set cycle_clk high, then low to flop the update value into the relevant register in the FPGA (this will determine the value for go for the solvers)
- The HPS can periodically perform this action with a value of 1 to continuously update state at a variable frequency.
Even though the HPS is now able to access FPGA memory correctly the topic of how to format this data comes into play. To determine how to format the data properly the group looked towards the the Wireworld Processor. We used the same format scheme, for ease of re-using their file: state is stored in a text file with the .wi extension, which uses a special character to denote each one of the four possible states. The four characters determined based from the processor file are:
- " " for EMPTY
- "#" for CONDUCTOR
- "@" for HEAD
- "~" for TAIL
With this formatting scheme, it was then simple to convert the data from resp_val into the desired character to store in a file, as well as to translate a character into the state value to be put on req_val for writing.