In the previous post, Testing like a Pro, I explained some general guidelines to thoroughly verify the behavior of an RTL design. I’ve been working on the test bench for the GPIO over the past week. In this post I’ll explain it’s features and give a block diagram to two ways that can be used to implement this design.
The GPIP new automated test bench have the following features:
- It’s basic testing sequence is it sets the GPIO direction, writes data to it then sets it’s direction again and reads it’s data then it reads the contents of the control register.
- The above sequence is repeated several times based on the size of the GPIO
- The testing is repeated for all possible widths of the GPIO
- Random values are used for the data written or read from the GPIO, setting the direction register and the wishbone sel_i signal.
- The test bench exits on the first error detected and dumps the waveform for the user to solve the error encountered.
- Data & Control register addresses are set by a local parameter, hence the test bench can be easily modified to test other GPIO cores.
- The test bench allows for a certain waiting time for the GPIO to acknowledge wishbone transactions or output the data passed to it. After this waiting time the slave is considered not responsive and testing halts.
There are two that are being considered to do this testing. The first is shown in the following figure. In this way two verilog modules are built using non-synthesizable constructs. The first block will generate the required tests and drive all the inputs of the GPIO core. The second module will monitor all the input fed to the core and compare the expected output against the response of the GPIO. The advantage of this approach is that everything will be done in verilog and it’s easier to edit any of the modules. However, this approach is more complex as it involves building the necessary modules.
The other approach is to simply load the required test vectors and their expected output into a text file using any scripting or programming algorithm then use Verilog to simply load the values to the core and record the produced outputs. The expected and actual outputs are compared and any differences are flagged as faults. This approach is much simpler as it doesn’t need any verilog design. However, it takes some effort to make sure the outputs are properly recorded to match their corresponding test vectors.
It was necessary for me to start with the first approach to understand the testing procedure and be able to observe the generated wave forms. I believe I will soon move to the second approach now that I have a proper understanding of the issues and concepts involved in testing.