Having reached the point where we have designed the Adafruit NeoPixel LED driver, integrated it into the Vivado block diagram, and connected it to the remainder of the system, we now need to think a little about the verification strategy we will use. That is, what tests do we need to demonstrate that the design works successfully? Typically this stage can be more involved than the design itself.
This is a fairly simple design example so the verification strategy I will be undertaking is:
Verify the hardware interfaces between the MicroZed, I/O Carrier Card, and the NeoPixel array.
Simulate the NeoPixel driver using a VHDL simulator.
Develop test software to read and write from all BRAM addresses, ensuring that the PS (Processor System) can correctly address the memory.
Develop test software to drive the first NeoPixel in the array, to verify the functioning of the NeoPixel driver, and then verify the timing waveforms sent to the NeoPixel array using an oscilloscope.
Develop test software to drive a number of pixels located at different points on the NeoPixel array (e.g. second pixel, mid pixel and final pixel in the array).
Use a terminal program to verify that the final software can respond properly to correct commands, incorrect commands, out of sequence commands, etc.
Perform final functional verification using a developed GUI to prove the final design works as specified originally.
The above steps may seem complicated. However in many instances such as this simple application, they can be performed with relative ease.
Normally the first element of any testing is to ensure that the hardware is operating correctly. (See my articles in Xcell Journal issue 82, “Nuts and Bolts of Designing an FPGA into Your Hardware,” and issue 85, “A Pain-Free Way to Bring Up Your Hardware Design.”) However one benefit of the MicroZed’s system of modules approach is that the underlying hardware in the Zynq SoC, the MicroZed board, and the MicroZed I/O Carrier Card is provided as known good hardware. This reduces the time it will take to commission our system and start verifying our functional requirements. (However, it does not mean we will correctly implement our SoC.)
We still need to verify the following at the hardware level before we can progress (point 1 above):
The correct pin-out from the IO Carrier Card’s PMOD connector to the NeoPixel connections: this is best done using a multimeter when the power is not applied to the MicroZed board. We certainly want to ensure the VCC and GND supplies to the Neo Pixel array are correct.
Correct voltage setting for the IO bank driving and powering the NeoPixel array: this can be as simple as using a multi meter to observe that the voltage is 3.3V.
Once we have proved the physical interconnect and power connections, it is a good idea to power up the MicroZed board and check that the power supply to the attached NeoPixel array is stable using the multimeter.
Test Point for the 3v3 Bank 35 supply
In my previous blog, we looked at the design and simulation of the NeoPixel driver using ModelSim, which addresses point 2 in the verification strategy and helpfully allows me to move on to point 3: verifying the functional performance of the Zynq SoC’s PS and PL side of the design and the interaction between the two of them.
As we have been using the MicroZed design in the PS for a number of weeks—35 weeks, as I make it—I am pretty confident that the PS is correctly configured to boot from the SD card and execute the program from the DDR RAM. However this is the first time in this series of blogs that I have used the BRAM controller and the BRAM, which is why I developed test software to ensure I could read and write the memory from the PS side correctly.
The testing of the system’s ability to drive the NeoPixel array begins to take shape during points 4 and 5 in the verification strategy. Both are closely linked and are a natural evolution from one test to the next. The first test software enabled me to write to just one NeoPixel and check the timing. What I see on the oscilloscope correlates with that from the VHDL simulation and the NeoPixel lights in the correct color. Test successful.
I then modified this test code to drive the one pixel to full scale red, green, and blue, ensuring that the driver can correctly set the pixel color. Once one pixel has been driven, the program is easily adapted to drive specific pixels to different colors. This verifies that the controller can correctly drive a specified pixel in the string. The final change to the test software is to drive all pixels in the string at the same time to the same color. For this test, I chose white because this color turns on all of the red, green, and blue LEDs in the NeoPixel array and therefore allows me to ensure that the maximum current can be driven from the I/O Carrier Card to support this string.
Once this series of tests is complete, we are confident we can drive the attached NeoPixel array. However, we have not yet verified the command interface that we will use to control the setting of the NeoPixel colors. I will address the final two points in the verification strategy regarding the serial interface and GUI in the next blog, where I will introduce the simple serial communications protocol I have implemented to control the Zynq SoC’s PS and thus in turn the PL NeoPixel driver.