Lab 3 - Fibonacci Calculator using Nallatech


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.).

Introduction

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.

I have provided a code template to get you started, which includes the solution to lab1, but feel free to replace the relevant code with your Fibonacci calculator.

Part 1 - VHDL/DIMETalk

For the first part of the lab, you will be extending your previous Fibonacci calculator by creating a new glue logic entity that communicates with software using the Dimetalk memory map in order to store input values for the Fibonacci circuit. The glue logic must also be able to read outputs when requested by software. You should implement the glue logic in the provided glue_logic.vhd file.

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, you will connect the glue logic and Fibonacci calculator in the fib_h101 entity (fib_h101.vhd). This is the top-level entity for your design, which you will import into Dimetalk. To import your own VHDL, go to Utilities->Library Manager. Then select Add to Library->VHDL Component. Then, select the top-leve entity which is fib_h101.vhd. Next, click import. Dimetalk will then bring up a box that asks if you want to edit the component properites. Click Yes. On the dialog box, add a description to the the corresponding text boxes. Then, click the support files tab. Right click in the box and select Add->Design Source. Select all the vhd files for the project. Click OK. Now, on the User Components tab, there should be a component for fib_h101. Click this component and instantiate it in your project like you would for any other component.

You should then create a Dimetalk project that looks like this:


Assuming you did not change the interface to fib_h101, you should be able to connect these components with a single Dimetalk wire. Note that the actual Dimetalk project will contain the other standard components, including the edge and the clock module. Connect the red edge pin to the red memory map pin.

Before testing your design on the board, make sure to simulate with the provided testbench, which will report errors if your code is not correct. There might still be problems that the testbench does not expose, so your code still might not work on the board.

Part 2 - C Code

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 2
#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 exactly like this:

1: HW = 1, SW = 1
2: HW = 1, SW = 1
3: HW = 2, SW = 2
4: HW = 3, SW = 3
5: HW = 5, SW = 5
6: HW = 8, SW = 8
7: HW = 13, SW = 13
8: HW = 21, SW = 21
9: HW = 34, SW = 34
10: HW = 55, SW = 55
11: HW = 89, SW = 89
12: HW = 144, SW = 144
13: HW = 233, SW = 233
14: HW = 377, SW = 377
15: HW = 610, SW = 610
16: HW = 987, SW = 987
17: HW = 1597, SW = 1597
18: HW = 2584, SW = 2584
19: HW = 4181, SW = 4181
20: HW = 6765, SW = 6765
21: HW = 10946, SW = 10946
22: HW = 17711, SW = 17711
23: HW = 28657, SW = 28657
24: HW = 46368, SW = 46368
25: HW = 75025, SW = 75025
26: HW = 121393, SW = 121393
27: HW = 196418, SW = 196418
28: HW = 317811, SW = 317811
29: HW = 514229, SW = 514229
30: HW = 832040, SW = 832040

IMPORTANT: Make sure to test your output with this provided script. To use the script, first rename it to "grade.pl" and copy it to your directory on delta. Then, do the following when you run your application:

srun h100bist.exe > test.txt
grade.pl test.txt

Common Tool Problems

  1. To do post-place+route simultion in Xilinx ISE, the top level entity has to use std_logic or std_logic_vector for all i/o.
  2. Xilinx ISE does not like generic values in the top level entity
  3. VHDL files imported into DIMETalk need to use std_logic for all i/o.
  4. DIMETalk will mess up when importing VHDL unless you define each input/ output on a seperate line
  5. Unless you use the names dt_clk and reset for the clock and reset, you will need to manually specify which signal is the clock and which is the reset.
  6. If your code looks correct, but you are getting strange problems, try creating a new project. This applies to both ISE and DIMETalk. I personally went through 3 ISE projects for this lab, even though the code was completely correct.