| Customize Help

Steps to develop a function that performs an operation using a Processing FPGA



To perform a processing operation using your Processing FPGA when there is no equivalent MIL function, you must at least create a primitive function that uses the functions of the MIL Mfpga module to set up and dispatch all appropriate commands to the Processing FPGA. Also, you must include the MIL FPGA header file milfpga.h to make a call to any function of the Mfpga module.

To create the primitive function:

  1. Inquire the handle of your source and destination buffers using MfuncInquire() with M_BUFFER_INFO. MIL FPGA functions do not take buffer identifiers; instead, they take the handle of the buffers.

  2. To enable basic parameter checking when using Mfpga functions, use MfpgaControl() with M_ERROR and M_PRINT_ENABLE. Note that this will also report errors when attempting to link the target PU with a PU not in the FPGA configuration, and when attempting to use an invalid interrupt.

  3. Allocate an FPGA command context for the target PU of the Processing FPGA using MfpgaCommandAlloc(). The FPGA command context is used to contain the necessary command information to perform the required operation using the specified PU.

  4. Specify the source image buffer(s) using MfpgaSetSource().

  5. Specify the destination image buffer(s) using MfpgaSetDestination().

  6. Set other processing information in the PU's user-specific registers using MfpgaSetRegister().

  7. To route the stream output of one PU to the stream input port of another PU (that is, to cascade the PUs) repeat steps 2 through 5, creating and setting up a FPGA command context for each PU that you need to cascade. Then, link the command contexts, using MfpgaSetLink().

  8. Queue the command(s) defined by the command context(s), using MfpgaCommandQueue().

  9. Retrieve non-image results from the PU's registers using MfpgaGetRegister().

  10. Free the command context using MfpgaCommandFree().

The following code snippet is an example of the type of code that should be included within your primitive function to set up and dispatch a command to a Processing FPGA.

/* Inquire the buffer info object for the source and destination buffers. */
MfuncInquire(MilSourceImage, M_BUFFER_INFO, &Src);
MfuncInquire(MilDestinationImage, M_BUFFER_INFO, &Dest);

/* Allocate an asynchronous command context on the AddConstant processing unit.
*/
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_ADDCONST_FID,
                     M_DEFAULT,M_DEV0, M_ASYNCHRONOUS, M_DEFAULT,
                     &AddConstantContext))
  {
  /* Initialize the shadow register structure. */
  InitializeShadowRegisters(&ShadowRegisters, Src, ConstantValue, ControlFlag);

  /* Input0 of AddConstant processing unit is connected to the Src buffer. */
  MfpgaSetSource(AddConstantContext, Src, M_INPUT0, M_DEFAULT);

  /* Output0 of AddConstant processing unit is connected to the Dest buffer. */
  MfpgaSetDestination(AddConstantContext, Dest, M_OUTPUT0, M_DEFAULT);

  /* Pass the initialized shadow register structure, it will be programmed   */
  /* when the processing operation is dispatched (before processing starts). */
  MfpgaSetRegister(AddConstantContext, M_USER, 0, sizeof(ShadowRegisters),
                    (void*)(&ShadowRegisters), M_WHEN_DISPATCHED);

  /* Queue the processing operation, because this context is asynchronous, */
  /* MfpgaComamndQueue will return before the operation is completed. */
  MfpgaCommandQueue(AddConstantContext, M_DEFAULT, M_DEFAULT);

  /* Free the allocated context. */
  MfpgaCommandFree(AddConstantContext, M_DEFAULT);
  }

Note that to run the primitive function on a board with an on-board processor, you must call your primitive function from the slave function of a user-defined MIL function. The slave and primitive functions must be precompiled and preloaded into the shell of the on-board processor. For more information on creating a user-defined MIL function, see Chapter 53: The MIL function development module. Note that even without an on-board processor, it is useful to call your primitive function from a user-defined MIL function. This not only makes your code more portable, but also takes advantage of the parameter checking and error reporting capabilities that are integrated in MIL.

Whenever you want to associate an FPGA command context with a PU, you must make sure the PU is actually present in the FPGA configuration loaded in the FPGA. In addition, when implementing cascaded or parallel processing operations, it is necessary to make sure that the PUs are interconnected properly in the FPGA configuration. Matrox FPGA configurations are documented in the Matrox FPGA Configurations help file.