In some cases, the MicroBlaze GNU Compiler is not able to optimize code to completely avoid data hazards. However, it is often possible to change the source code to achieve this, mainly by better utilization of the general purpose registers.
Two C code examples are shown here:
- Multiplication of a static array in
memory.
static int a[4], b[4], c[4]; register int a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3; a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3]; b0 = b[0]; b1 = b[1]; b2 = b[2]; b3 = b[3]; c0 = a0 * b0; c1 = a1 * b1; c2 = a2 * b2; c3 = a3 * b3; c[3] = c3; c2 = c[2]; c1 = c[1]; c0 = c[0];
This code ensures that load instructions are first executed to load operands into separate registers, which are then multiplied and finally stored. The code can be extended up to 8 multiplications without running out of general purpose registers.
- Fetching a data packet from an AXI4-Stream
interface.
#include <mb_interface.h> static int a[4]; register int a0, a1, a2, a3; getfsl(a0, 0); getfsl(a1, 0); getfsl(a2, 0); getfsl(a3, 0); a[3] = a3; a[1] = a1; a[2] = a2; a[0] = a0;
This code ensures that get instructions using different registers are first executed, and then data is stored. The code can be extended to up to 16 accesses without running out of general purpose registers.