You will again be working in groups for this project.
Turn in the project using the e-learning website (1 submission per group, make sure all names are in each file). Please zip all files (DimeTalk project, C files, VHDL, readme.txt explaining the status of the lab, bitfile, screenshot of output) and attach it to your submission. Please do not turn in other files that are generated during synthesis. Feel free to turn in any files used for testing (testbenches, etc.).
In this lab, you will be implementing the Fibonacci calculator you did in a previous lab on the Nallatech board. Specfically, you will be using the host processor to send inputs to the Fibonacci calculator circuit in the FPGA, and also to read back outputs that should be output on the screen.
Feel free to use the provided code for the Fibonacci calculator. The top level entity is called xilinx_wrapper. I highly recommend using this code initially, and then replacing it with your own code later if you have extra time.
For the first part of the lab, you will be extending your previous Fibonacci calculator by creating a new glue logic entity that stores input values (and optionally output values) for the Fibonacci circuit. The Fibonacci circuit has 2 inputs (go and n) and 2 outputs (result and done). Do not make the glue logic the top level entity. You will instead use DIMETalk to connect the Fibonacci entity with the glue logic entity. You will be using the glue logic to transfer data from the host processor.
To be able to read/write to a register in the FPGA from the host processor, you need some way of assigning the targeted register/signal an address. DIMETalk provides the memory map node for exactly this purpose. For each transfer, a memory map node specifies the address that is being accessed, and whether or not the access is a read or a write (but of course it is not quite that simple).
To use a memory map node, you must first assign an address to each register/signal that you want to access from the host processor. For the Fibonacci calculator, you will need to access the inputs n and go, and the outputs done and result. You may use any 32-bit address for each signal, although something like go=0, n=1, result=2, done=3 will probably be the easiest to code.
Now that you have assigned an address to each signal in the FPGA you need to access from software, you need to design the glue logic entity to decode the signals from the memory map node and read/write the appropriate signal/register. For example, if the memory map specifies address 0 is being written to, the glue logic should write to the signal mapped to address 0 (in the above example, 0 corresponded to go). Likewise, when the memory map specifies a read is taking place, the glue logic should read data from the appropriate signal and send it to the memory map.
One tricky issue is that the memory map does not have a signal that specifies a read or write. Instead, it uses 2 signals, enable and write enable. Part of the assignment is to figure out how to interface with these signals to perform reads and writes. All the information you need is on page 28 of the DIMETalk Reference Guide.
After creating the glue logic in VHDL (and hopefully testing it with a testbench), you will connect the memory map, glue logic, and Fibonacci entity in DIMETalk. Previously, you just dragged signals from one pin to another. However, in this lab you will need to provide more specific connections. Each "pin" in DIMETalk actually represents a large group of signals. To get to individual inputs/outputs, you need to use a "breakout". You can create a breakout by right clicking on the pin, and then selecting create->breakout. The top pin of the breakout should be connected to the pin that you want to divide into individual inputs/outputs. Each following pin is a single input or output. If you don't like using breakouts, there is a way to group signals into pins, but I'll let you figure this out.
The connections between components should look something like this:
After you have completed the DIMETalk project, which essentially connects the memory map with glue logic and the Fibonacci calculator, you will be writing C code to run on the host processor that tests your circuit.
Memory maps can be accessed exactly the same way as blockRAMs in the previous lab. All you need is a node ID (provided by DIMETalk, most likely 1), and an address to access. For example, you could write data into a register n (assuming n is stored at address 1) in the FPGA using code similar to the following:
#define N_ADDR 1 #define GO_ADDR 1 #define MEMORY_MAP_ID 1 ....... int some_variable = 1; FPGA_write( &some_variable, 1, N_ADDR, MEMORY_MAP_ID, 1000); FPGA_write( &some_variable, 1, GO_ADDR, MEMORY_MAP_ID, 1000); ....
The C program should calculate the first 30 Fibonacci numbers (by using the FPGA circuit) and output them to the screen. To verify correctness, you should also calculate each Fibonacci number using software. The output of the program should look something like this:
SW Fib(1): 1, FPGA Fib(1): 1 SW Fib(2): 1, FPGA Fib(2): 1 SW Fib(3): 2, FPGA Fib(3): 2 SW Fib(4): 3, FPGA Fib(4): 3 SW Fib(5): 5, FPGA Fib(5): 5 SW Fib(6): 8, FPGA Fib(6): 8 SW Fib(7): 13, FPGA Fib(7): 13 SW Fib(8): 21, FPGA Fib(8): 21 SW Fib(9): 34, FPGA Fib(9): 34 SW Fib(10): 55, FPGA Fib(10): 55 SW Fib(11): 89, FPGA Fib(11): 89 SW Fib(12): 144, FPGA Fib(12): 144 SW Fib(13): 233, FPGA Fib(13): 233 SW Fib(14): 377, FPGA Fib(14): 377 SW Fib(15): 610, FPGA Fib(15): 610 SW Fib(16): 987, FPGA Fib(16): 987 SW Fib(17): 1597, FPGA Fib(17): 1597 SW Fib(18): 2584, FPGA Fib(18): 2584 SW Fib(19): 4181, FPGA Fib(19): 4181 SW Fib(20): 6765, FPGA Fib(20): 6765 SW Fib(21): 10946, FPGA Fib(21): 10946 SW Fib(22): 17711, FPGA Fib(22): 17711 SW Fib(23): 28657, FPGA Fib(23): 28657 SW Fib(24): 46368, FPGA Fib(24): 46368 SW Fib(25): 75025, FPGA Fib(25): 75025 SW Fib(26): 121393, FPGA Fib(26): 121393 SW Fib(27): 196418, FPGA Fib(27): 196418 SW Fib(28): 317811, FPGA Fib(28): 317811 SW Fib(29): 514229, FPGA Fib(29): 514229 SW Fib(30): 832040, FPGA Fib(30): 832040