Jump to content


Error while generating HDL


  • You cannot reply to this topic
2 replies to this topic

#1 twinkie

    Member

  • Members
  • PipPip
  • 6 posts

Posted 02 April 2008 - 07:04 PM

Hi,

I have a mpeg-2 decoder code in 'C'.
I wanted to generate HDL for the IDCT part of it.
There are around 20 C files and 6 header files.
I have added all the files to software and only the IDCT file to hardware.
When I click on generate HDL button, I get the following error.

Impulse C Transformations
Copyright 2002-2007, Impulse Accelerated Technologies, Inc.
All rights reserved.
Build Feb 23 2008.
processing mpeg.snt...
"C:/Impulse/CoDeveloper3/bin/impulse_porky" -iterate -fold -unused-syms -unused-types -Dmemcpys -const-prop -scalarize -loop-invariants mpeg.pk0 mpeg.pk1
"C:/Impulse/CoDeveloper3/bin/impulse_porky" -build-arefs mpeg.pk1 mpeg.pky
"C:/Impulse/CoDeveloper3/bin/impulse_impc" mpeg.pky mpeg.sic
Impulse C Preprocessor
Copyright 2003-2007, Impulse Accelerated Technologies, Inc.
All rights reserved.
Build Feb 23 2008.
---Software activated---
processing mpeg.pky...
Warning: co_initialize procedure not found.
"C:/Impulse/CoDeveloper3/bin/impulse_s2xml" mpeg.sic > mpeg.xic
Impulse C to XML
Copyright 2003-2007, Impulse Accelerated Technologies, Inc.
All rights reserved.
Build Feb 23 2008.
Assertion failure in file "main.cc" at line 3718:
Undefined function idctrow
make: *** [mpeg.xic] Error 1

======== Build of target 'build' complete ========


It shows undefinecd funstion idctrow. But this function is defined in the IDCT file.
I have cpy pasted the IDCT.c file for reference.
Can anybody help in solving this problem?

Thanks a lot for the help smile.gif


#include "config.h"

#ifdef STANDALONE
#include "stop_watch.h"
#endif

#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */

/* global declarations */
void Initialize_Fast_IDCT _ANSI_ARGS_((void));
void Fast_IDCT _ANSI_ARGS_((short *block));

/* private data */
static short iclip[1024]; /* clipping table */
static short *iclp;

/* private prototypes */
static void idctrow _ANSI_ARGS_((short *blk));
static void idctcol _ANSI_ARGS_((short *blk));

/* row (horizontal) IDCT
*
* 7 pi 1
* dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l )
* l=0 8 2
*
* where: c[0] = 128
* c[1..7] = 128*sqrt(2)
*/

static void idctrow(blk)
short *blk;
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;

x1 = blk[4]<<11;
x2 = blk[6];
x3 = blk[2];
x4 = blk[1];
x5 = blk[7];
x6 = blk[5];
x7 = blk[3];
x0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage

// shortcut
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
{
blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
return;
}
x0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage
// first stage
x8 = W7*(x4+x5);
x4 = x8 + (W1-W7)*x4;
x5 = x8 - (W1+W7)*x5;
x8 = W3*(x6+x7);
x6 = x8 - (W3-W5)*x6;
x7 = x8 - (W3+W5)*x7;

//second stage
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2);
x2 = x1 - (W2+W6)*x2;
x3 = x1 + (W2-W6)*x3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;

// third stage
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;



/* fourth stage */
blk[0] = (x7+x1)>>8;
blk[1] = (x3+x2)>>8;
blk[2] = (x0+x4)>>8;
blk[3] = (x8+x6)>>8;
blk[4] = (x8-x6)>>8;
blk[5] = (x0-x4)>>8;
blk[6] = (x3-x2)>>8;
blk[7] = (x7-x1)>>8;
}

/* column (vertical) IDCT
*
* 7 pi 1
* dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l )
* l=0 8 2
*
* where: c[0] = 1/1024
* c[1..7] = (1/1024)*sqrt(2)
*/
static void idctcol(blk)
short *blk;
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
// x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 =0;

x1 = (blk[8*4]<<8);
x2 = blk[8*6];
x3 = blk[8*2];
x4 = blk[8*1];
x5 = blk[8*7];
x6 = blk[8*5];
x7 = blk[8*3];


//shortcut
if (!((x1)|(x2)|(x3)|(x4)|(x5)|(x6)|(x7)))
{
blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
iclp[(blk[8*0]+32)>>6];
return;
}
x0 = (blk[8*0]<<8) + 8192;

// first stage
x8 = W7*(x4+x5) + 4;
x4 = (x8+(W1-W7)*x4)>>3;
x5 = (x8-(W1+W7)*x5)>>3;
x8 = W3*(x6+x7) + 4;
x6 = (x8-(W3-W5)*x6)>>3;
x7 = (x8-(W3+W5)*x7)>>3;

//second stage
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2) + 4;
x2 = (x1-(W2+W6)*x2)>>3;
x3 = (x1+(W2-W6)*x3)>>3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;

// third stage
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;



/* fourth stage */
blk[8*0] = iclp[(x7+x1)>>14];
blk[8*1] = iclp[(x3+x2)>>14];
blk[8*2] = iclp[(x0+x4)>>14];
blk[8*3] = iclp[(x8+x6)>>14];
blk[8*4] = iclp[(x8-x6)>>14];
blk[8*5] = iclp[(x0-x4)>>14];
blk[8*6] = iclp[(x3-x2)>>14];
blk[8*7] = iclp[(x7-x1)>>14];
}


/* two dimensional inverse discrete cosine transform */
void Fast_IDCT(block)
short *block;
{
//george : block* is a pointer to a 8x8 of short integers (2-byte)
int i;

for (i=0; i<8; i++)
idctrow(block+8*i);

for (i=0; i<8; i++)
idctcol(block+i);

}

void Initialize_Fast_IDCT()
{
int i;
iclp = iclip+512;
for (i= -512; i<512; i++)
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
}


#2 RalphBodenner

    Advanced Member

  • Admin
  • PipPipPip
  • 348 posts

Posted 03 April 2008 - 11:57 AM

The IDCT is an excellent candidate for acceleration with Impulse C, but you will need to do a little restructuring of the code to take best advantage of Impulse C and FPGA hardware. I would highly recommend first following the tutorials included with CoDeveloper, accessible from the Help > CoDeveloper User's Guide menu item.

Note this warning:

QUOTE (twinkie @ Apr 2 2008, 08:04 PM) <{POST_SNAPBACK}>
Impulse C Transformations
Copyright 2002-2007, Impulse Accelerated Technologies, Inc.
All rights reserved.
Build Feb 23 2008.
processing mpeg.snt...
"C:/Impulse/CoDeveloper3/bin/impulse_porky" -iterate -fold -unused-syms -unused-types -Dmemcpys -const-prop -scalarize -loop-invariants mpeg.pk0 mpeg.pk1
"C:/Impulse/CoDeveloper3/bin/impulse_porky" -build-arefs mpeg.pk1 mpeg.pky
"C:/Impulse/CoDeveloper3/bin/impulse_impc" mpeg.pky mpeg.sic
Impulse C Preprocessor
Copyright 2003-2007, Impulse Accelerated Technologies, Inc.
All rights reserved.
Build Feb 23 2008.
---Software activated---
processing mpeg.pky...
Warning: co_initialize procedure not found.
...


This indicates that the co_initialize function—a required component of every Impulse C app—is missing. The co_initialize function exists only to call the "configuration function", which is Impulse C's way of describing the high-level structure of an application. The configuration function describes each "process" and the streams, signals, or memories used to communicate between processes. An example of a process might be the IDCT component of the MPEG decode algorithm, expressed as a C function something like this:

CODE
void dct_run(co_stream strm_in_samples, co_stream strm_out_dct)
{
    //...
}


Both co_initialize and configuration function are boilerplate code. I'd recommend creating a new Impulse C project within CoDeveloper, selecting one of the General Application Templates in the New Project dialog box (e.g., "One-process testbench"). Each template will include both configuration and co_initialize functions for you to work from.

Now you've got the configuration function and a hardware and software process from the template. Insert Fast_IDCT's code into the hardware process, using 16-bit streams instead of a 'short *' for input/output. Once you've turned the IDCT code into a "process", connect that process to the software side of the application using streams. You can do this through the template's software process, a producer/consumer something like this:

CODE
void dct_prod_con(co_stream strm_out_samples, co_stream strm_in_results)
{
    g_strm_out_samples = strm_out_samples;
    g_strm_in_results = strm_in_results;
}


To simplify the porting process, this process can simply copy the co_stream pointers to global objects. Any existing software code that interacts with the IDCT can then refer to these global objects when sending/receiving data with the IDCT.

At this point, you'll have made the following changes:
  • Created a fresh application using the "One-process testbench" template
  • Added your source files
  • Turned Fast_IDCT into a hardware process
  • Modified your software producer/consumer to make the software-side streams globally accessible
  • Modified code that sends/receives to/from the IDCT to use the global streams
This should get you to the point where you can generate hardware for your design. You may have to investigate your use of function calls, since Impulse C supports function calls in hardware using "hardware primitives"—see the section "Hardware Primitive Functions" in the Help file for details.

In summary, your application is a good fit for Impulse C, but some changes are needed to get the compiler to recognize how the application is partitioned and connected between software and hardware.

Regards,
Ralph
Ralph Bodenner
Impulse Accelerated Technologies, Inc.

#3 twinkie

    Member

  • Members
  • PipPip
  • 6 posts

Posted 03 April 2008 - 05:52 PM

Thanks a lot for the support smile.gif
Will try this soon..

QUOTE (RalphBodenner @ Apr 3 2008, 11:57 AM) <{POST_SNAPBACK}>
The IDCT is an excellent candidate for acceleration with Impulse C, but you will need to do a little restructuring of the code to take best advantage of Impulse C and FPGA hardware. I would highly recommend first following the tutorials included with CoDeveloper, accessible from the Help > CoDeveloper User's Guide menu item.

Note this warning:
This indicates that the co_initialize function—a required component of every Impulse C app—is missing. The co_initialize function exists only to call the "configuration function", which is Impulse C's way of describing the high-level structure of an application. The configuration function describes each "process" and the streams, signals, or memories used to communicate between processes. An example of a process might be the IDCT component of the MPEG decode algorithm, expressed as a C function something like this:

CODE
void dct_run(co_stream strm_in_samples, co_stream strm_out_dct)
{
    //...
}


Both co_initialize and configuration function are boilerplate code. I'd recommend creating a new Impulse C project within CoDeveloper, selecting one of the General Application Templates in the New Project dialog box (e.g., "One-process testbench"). Each template will include both configuration and co_initialize functions for you to work from.

Now you've got the configuration function and a hardware and software process from the template. Insert Fast_IDCT's code into the hardware process, using 16-bit streams instead of a 'short *' for input/output. Once you've turned the IDCT code into a "process", connect that process to the software side of the application using streams. You can do this through the template's software process, a producer/consumer something like this:

CODE
void dct_prod_con(co_stream strm_out_samples, co_stream strm_in_results)
{
    g_strm_out_samples = strm_out_samples;
    g_strm_in_results = strm_in_results;
}


To simplify the porting process, this process can simply copy the co_stream pointers to global objects. Any existing software code that interacts with the IDCT can then refer to these global objects when sending/receiving data with the IDCT.

At this point, you'll have made the following changes:
  • Created a fresh application using the "One-process testbench" template
  • Added your source files
  • Turned Fast_IDCT into a hardware process
  • Modified your software producer/consumer to make the software-side streams globally accessible
  • Modified code that sends/receives to/from the IDCT to use the global streams
This should get you to the point where you can generate hardware for your design. You may have to investigate your use of function calls, since Impulse C supports function calls in hardware using "hardware primitives"—see the section "Hardware Primitive Functions" in the Help file for details.

In summary, your application is a good fit for Impulse C, but some changes are needed to get the compiler to recognize how the application is partitioned and connected between software and hardware.

Regards,
Ralph






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users