This post is a documentation of the final version of automated test benches created to verify our IO cores. The test benches have been created for the our GPIO, Master SPI, Slave SPI, UART & I2C master and slave. The test benches verify only the behavior of those devices within their specs. It doesn’t have any random tests or tests for their behavior out of their specs. Here is an overall explanation of how the test benches work

First, each core is engulfed by a wrapper. The job of the wrapper is to simply instantiate the core and change it’s various ports and parameter names to standard ones which are dev_out#, dev_in#, dev_param# for the cores inputs, outputs and parameters respectively. This allows the top module and macro definitions to be generic.

Then a tester is connected to this IP wrapper. The tester does only two jobs, read the test vectors from a memory file then load them into the core and write the output obtained into a file to be compared with the reference output previously verified. The tester and the wrapper are connected in a top module.

As for script wise, each device has two scripts, and tvgen is the script which I used to first generate the test vectors chosen by me, run them through the test bench and print the output. After the waveform generated is verified to match specs, the generated outputs are saved as reference outputs. The test vector files and reference outputs are saved in a folder called test under the names of tv# & exp# respectively. is the script that should be run to verify the performance of the core. Here is how this script it works:

  1. It creates a temporary directory with a random name in /tmp .
  2. Moves the testvector and expected output files to the temporary directory. Following this step, all files produced are kept in the temporary directory.
  3. Counts the number of testvectors and runs the test bench to generate the output of the current design.
  4. After the actual output is generated, it is compared against the reference, expected, output using cmp.
  5. If no differences exist between the files the test is considered Pass and then it repeats this process for the rest of the tests.
  6. If a difference occurs, A fail message is printed that points the user to the different line number in the reference output. and terminates testing.after saving the waveform only for this run in a random name displayed with the exit message.
  7. If the tests pass the script returns a 0. If it fails, the script returns the test vector number that failed divided by 4. This is because the maximum number of test vectors we have so far is 1024 tests and the exit status can only hold an 8 bit integer.

Here is a list of all the Macros in the current designs that are passed to the iverilog command by

  1. Wishbone bus size.
  2. Test Vector file name.
  3. Actual output file name.
  4. Number of test vectors.
  5. Name of waveform dump file
  6. Device parameters that will be changed during testing

That’s how it works for all IO cores. In the next post I’ll list down the tests conducted for each device.