CORDIC (Coordinate Rotation Digital Computer) is a small and efficient algorithm to compute functions like spheric and hyperbolic trigonometry, square roots and more. Not as popular today as it was in the past but it still finds a place in the FPGA developer's toolbox.
In this project I'm implementing the CORDIC IP block included in Vivado to perform calculation of sin and cos functions over an array of values. Because CORDIC 6.0 has AXI Stream input and output, I will be using a DMA (Direct Memory Access) to stream data and receive results meanwhile the CPU is free to do other tasks, so the trigonometric computations are effectively accelerated in the FPGA.
Software used here will be baremetal (no OS) but others like FreeRTOS or Linux could equally be used.A mention to E3 Designers LLC and Dan Binnum who kindly provided the board used in this project. Also to mention it's an Ultra 96 v2 board with an Adiuvo 'hat' designed by Adam Taylor, who works with FPGA and doesn't know him?
Creating the hardware projectStart a new Vivado project, RTL type and select the board Ultra96_V2
Then create block diagram and add a Zynq Ultrascale+ MPSoS block. Click on Run Automation.
Select Apply board preset and click Next. Now the PS is configured for the Ultra 96 board.
Now add a CORDIC block and double click to configure it. In the first tab, select Sin and cos and disable the Coarse rotation.
In the AXIstream tab, select 'Has TLAST', change Flow control to 'Blocking' and also tick 'Output has TREADY'. TLAST is necessary for the DMA.
We have this so far.
Now let's change the AXI ports in the PS, we only need one master to control the CORDIC but need a slave one to receive data, so double click on the PS block and navigate to the PS-PL configuration tab. Here select just Master AXI HPM0 FPD and Slave AXI HP0 FPD.
Next add an AXI Direct Memory Access block (don't be confused by other similar names), double click on it to configure it. Disable the scatter-Gather feature and change the Read channel data width to 16 while leaving the write channel as 32. This is because CORDIC takes one value (16 bit) and produces two values (sin and cos) as 2x16 bits.
Connect the MM2S and S2MM ports in the DMA to the CORDIC as below.
Now ad an AXI interconnect block, double click on it and change the master ports to 1. Connect its ports to the PS and DMA as shown with purple lines.
Add an AXI SmartConnect block. No need to change the configuration. Connect its ports to the DMA and PS slave ports as shown with green lines:
For the rest, click on Run Connection Automation and select All automation.
In the Address Editor tab next to the Diagram, right click and exclude the OCM memory and right click then select 'Assign all'
For some reason the connection automation didn't connect the SmartConnect reset so I did it manually.
Once it's all done, validate the diagram and generate a wrapper for it. Then go straight to Generate Bitstream.
It should take some minutes. Notice it uses a small percentage of FPGA resources.
Next click File > Export > Export Hardware, and select 'Include bitstream'. Select the file name and location:
Done with Vivado! Now it's time to move to software development.
Creating the softwareStart Vitis and create a workspace in an empty folder. Then click on Create Platform Project.
Name your platform (whatever name will do) and browse for the XSA created and exported in Vivado. No need to change the settings in the next window.
Now in Vitis select the zynqmp_fsbl> Board Support Package and click Modify BSP Settings
Change stdin and stdout to psu_uart1. click OK.
And do the same change for the Board support Package under the standalone domain.
After that, select the platform project and click Build. That was the platform, now we need to create the Application software.
Click on File > New > Application project and select the created platform for it.
Next give it a name and select a template, the Hello World one will be fine.
Either replace the helloworld.c file with the one attached here or copy paste its contents into the existing one.
A couple of tweaks are needed, one of them is to increase the heap size. Right click on the application project and select Generate Linker Script, then change the Heap size to 16 KB.
The other is to include math libraries. Again right click on the application project and select C/C++ Build Settings. Then in Libraries just add an 'm'. This is because I'm using trigonometric functions like sin and cos to check the CORDIC results.
After these tweaks, build the application and system projects. A BOOT.bin file should be generated in the sd card folder:
Copy it and paste it into a micro SDcard FAT formatted. Insert it on the Ultra96 socket and connect a USB to Serial cable (3V3) to the 3-pin pinheader next to the power jack. Check the signals on the schematic. Remember that RX connects to TX and TX to RX.
Start a terminal application on your PC and connect it to the COM port of the serial cable. Baud rate is 115200 bps. Power the board and press the POWER button to start it. You should see this:
The software prepares an array of 32 values for the input angle between -pi/4 and +pi/4 (the range can be extended to a full circle if coarse rotation is selected in CORDIC). This values are converted to fix16_13 format, where the MSB is sign, 2 bits represent the integer part and 13 bits are the fractional part.
The DMA is kicked to send these values to the CORDIC and receive the results. In the meantime the CPU is waiting for it but in a real application it would be doing other tasks. The received values are printed out (converted from fix16_14 to float) along with the calculated values using math functions sin and cos, to note the accuracy.
Old stuff usually has an amazing story behind and CORDIC is one of these. It is also called Volder algorithm (after Jack Volder) although its origins go back to 1624, before Isaac Newton was born! Volder created the modern digital form in 1956 when at Convair for the B-58 bomber to replace analog real-time resolvers. After 1959, the algorithm was adopted for a number of other applications and proposed for calculations other that spherical trigonometry. Read more at Wikipedia.
More about the Logicore CORDIC 6.0The CORDIC IP is quite configurable. Not only the function can be chosen but also the architecture, pipelining model, data format, input/ output data width, rounding, number of iterations and precision. Obviously all these details are in the CORDIC product guide.
Comments
Please log in or sign up to comment.