User manual
Tutorial: Handel-C code optimization
struct _DivideStruct
{
unsigned 16 InputA;
unsigned 16 InputB;
unsigned 16 Result;
};
typedef struct _DivideStruct DivideStruct;
Now create a server process:
macro proc DivideServer(DividePtr)
{
/* perform divide operations forever */
while(1)
{
DividePtr->Result = DividePtr->InputA / DividePtr->InputB;
}
}
and a client API macro:
macro proc Divide(DividePtr, a, b, ResultPtr)
{
/* send data to the divide server */
par
{
DividePtr->InputA = a;
DividePtr->InputB = b;
}
/* wait one cycle for divide to be performed */
delay;
/* send back the result of the divide */
*ResultPtr = DividePtr->Result;
}
Note that because the server will take a cycle to calculate the result and store it in the data structure, a
delay is inserted in the client macro to allow for this. Other methods include using channels in the data
structure to transfer data in and out of the server, or using a shift register filled with "valid" bits in the
server, so the client macro can tell when the result is valid.
The server does not exit, so should be run in parallel with the main program, and the client macro can be
called as many times as required (sequentially) without imposing large hardware overheads. If more
than one divide needed to be carried out in parallel it is possible to run two servers, and explicitly call
them using the client macro in parallel. For this to operate correctly, two differently named data
structures must be used and passed to the respective server and client macros.
The
TutorialClientServer workspace contains two projects, the first using normal divide operators, and the
second using the client-server architecture described above. Compile them both for
EDIF output, with the
Technology Mapper and Logic Estimator enabled, and compare the output. The client-server version
takes significantly less hardware.
www.celoxica.com
Page 81