FPGARelated.com
Forums

FPGA C Compiler on sourceforge.net (TMCC derivative)

Started by Unknown November 2, 2005
Kolja Sulimma wrote:
> You are perfectly right. As I wrote in my post I think that you need > some features like explicit parallelism that none of the mainstream > languages offer, albeit there are languages available that would be > suitable.
The reality is that forms of parallelism emerge when using C as an HLL for FPGAs. The first is that the compiler is free to parallel statements as much as can be done. This alone is typically enough to bring the performance of a 300MHz fpga clock cycle near the performance of a several GHz RISC/CISC CPU for code bodies that have a significant inner loop. Second, explicit parallelism is available by replicating these inner loops by creating threads with the same code body and using established MPI code structures and libraries. Third the compiler is free to unroll inner loops. Fourth the compiler is free to flatten the netlists to gain additional parallelism. All this and more is obtained without abandoning stable mature development tools, without learning a new development environment that might add a few percent higher performance, and without significant unwarranted risks for many projects. After several decades of managing large development projects across multiple facility and platform evolutions we have learned to mitigate risks and maximize human potential across a large number of projects, teams, and technologies while repeatedly delivering results with acceptable tradeoffs judged by our experience. Many have also advocated radical changes in language and development styles. We have the gained the experience in this process after watching radical changes fail for human and technology elements not considered by the radical technologies as proposed. We do learn from those that do succeed and incorporate with reasoned process to mitigate risks. One critial risk not forseen by many of these brash proposed changes is observing that individuals have different degrees of ability to manage state in designs. Some with high natural ability can learn tosafely manage a very large amount of state with concurrency, and many more lack this ability and after the best training can only handle significantly smaller amounts of concurrency in a design. This is not a training issue, this is not an experience issues, this is natural ability that is developed with training and experience, but the maximum for each individual is independent of training and experience. Managing these differences in natural ability causes tradeoffs in complexity that may not be the best for some, but are best for organizations over time. It's not uncommon to see briallant designs to be completely unmaintainable by mortals. Time, and time alone, judges sucesses and failures. Not idealism and insults.
Kolja Sulimma wrote:
> But apparently all those highly trained clever software engineers can > not be bothered to learn another language. At least this argument > allways comes up at that point. (Maybe I can find an engineer in india > that is still capable of learning?) > So if your really need C-syntax as many believe - I don't - at least use > a modern C derived language that is easier to compile. > With java essentially only the "new" operated is a problem. With C, well > look at the System-C restrictions.
Open source know no boarders, no race, no religion, no ethnic, no political, no barriers to who can contribute to the world. Since you KNOW the answer, share it. We will be looking for your work on sourceforge, and your announcement here. Good ideas which are never realized, always ways worthless failures.
> On the other hand: What's so hard about dynamic allocation? Tell the > designer that it will be slow, and if he uses it simply synthesize to a > microblaze implementation. You will not meet the timing constraint, but > it can be synthesized.
Good designs have excellent space time tradeoffs. CPU cores are large, and take you right back to serial execution with poor parallelism, that in many cases would have been done better with a VLSI cpu, either as a hard core, or external device. Likewise, pointer based memory takes you right back to serial access of that memory as a critical path resource. Dynamic allocation is implicitly serial by design.
> Or even use profiling to find a typicall number of allocated objects and > create them in hardware. If more are used halt execution. That is > exeactly what a sequential processor would. You can't call malloc a > billion times in C and maybe you can not call it 16 times in hardware C. > It is the same type of constraint that is not imposed by the language > but by the implementation fabric and the designer needs to know the > capabilities of his system before implementing.
A language designed around dynamic allocation of objects and classes is implicitly unusable if limited to 16 such allocations, if only trivial code body invocations can be realized. The multiplexors to emulate a memory pool of statically allocated objects are both huge and implicitly serial once hazzard free for conncurrent access. This takes us right back to poor space time tradeoffs and a lack of implict parallism that static objects offer. Obviously you see right past these problems, and we are waiting for your magic to be realized as a much better language offering on sourceforge.net. Since the programmers in India are by your assertion superior, please show us by results, and time may prove you right.
air_bits@yahoo.com wrote:

> For those that haven't looked at this stuff, it's the next generation > HLL > FPGA environment, two steps above C with a cute GUI based system level > abstraction tool .... very cool :) > > http://www.nallatech.com/mediaLibrary/images/english/4063.pdf
Yes. All of the next-gen websites are cute. Why is a working code example so hard to find? -- Mike Treseler
Mike Treseler wrote:
> Yes. All of the next-gen websites are cute. > Why is a working code example so hard to find?
You can always ask the various sites, or some user. Robin seems to be using and happy with the DIME stuff, email him for some samples. Have you tried talking with the company? Impluse C offers a full featured 30 day trial, and they are pretty cool to talk with, and have done a good job of productizing Streams C. Streams C is free for non-commercial use, and is available from http://www.streams-c.lanl.gov/ SA-C by the Colostate team (Wimm Bohm) looks like they don't intend to make it publically available, except to companies funding their research projects. ASH by the CMU guys, isn't likely to get open source released either, and is likely to end up licensed to someone for a revenue stream from what I was told by one person last year ... but I haven't seen even that yet. Mihai Budiu appears to now be at Microsoft, and publishing papers from there on the technology, so maybe Microsoft will be licensing the technology, or working from Mihai's development independent or in partnership with CMU. The papers have been very cool, but until it's publicly available or a product it's hard to judge just how useful for others. The ASH team offered training at a conference earlier this year, and may do more. Celoxica isn't quite as easy to get a demo copy from, but some Xilinx reps seem to have a copy, and they were offering training seminars with Xilinx across the country. FpgaC has some examples in the download image, and is free to run your own tests with, and has no restrictions against commerical use. It seems pretty easy to get working examples simply by downloading or asking the sales guys ... who didn't respond to your asking?
air_bits@yahoo.com wrote:
> The reality is that forms of parallelism emerge when using C as > an HLL for FPGAs. The first is that the compiler is free to parallel > statements as much as can be done. This alone is typically enough > to bring the performance of a 300MHz fpga clock cycle near the > performance of a several GHz RISC/CISC CPU for code bodies that > have a significant inner loop. Second, explicit parallelism is > available > by replicating these inner loops by creating threads with the same > code body and using established MPI code structures and libraries.
An interesting point with this, of course, is that it's just splitting the work less - instead of going C -> object code -> Processor (with out of order execution), this would seem to be a case where the management of of-of-order execution type things is done statically at compile time, rather than dynamically by the processor. It could be interesting to see how far this could go - Compile to code+processor, where the processor architecture is implemented by the compiler subject to the requirements of the design. My 2c, Jeremy
Jeremy Stringer wrote:
> It could be interesting to see how far this could go - > Compile to code+processor, where the processor architecture is > implemented by the compiler subject to the requirements of the design.
I think that is being done already, tho at the simple end of the scale, it does prove it is possible. IIRC, it involved compiling the design twice. Once to generate the Core+Codes, and again to remove unused portions of the core. It can introduce other problems - if the CPU changes every time, that complicates things more, and what looks like a few lines of code, might enable a new block of the CPU, and have an unexpected hit on both % Usage, and speed. Cores themselves are not too large these days, the bigger bottleneck is on chip code memory. -jg
Jim Granville wrote:
> IIRC, it involved compiling the design twice. Once to generate the > Core+Codes, and again to remove unused portions of the core. > It can introduce other problems - if the CPU changes every time, that
That's interesting :) ... who's tools are doing that? The other extreme are Sarah's HarPE tools which even optimize away pretty much the whole core into logic.
In article <qhoe52lmhz.fsf@ruckus.brouhaha.com>,
Eric Smith  <eric@brouhaha.com> wrote:
>Rene Tschaggelar wrote: >> Why are those guys so keen on C ? Suggesting compatibility with >> something while having least readability ? > >air_bits@yahoo.com writes: >> The description at the project page pretty much says it all: >> >> "C provides an excellent alternative to VHDL/Verilog for algorithmic >> expression of tasks targeting FPGAs for reconfigurable computing." > >That doesn't explain *why* it's an excellent alternative. I can just >as easily state that "C provides a terrible alternative to VHDL/Verilog >for algorithmic expression of tasks targetting FPGAs for reconfigurable >computing". So why is their statement any more accurate than mine?
The main advantage that C has over the HDLs is that many software engineers know C, not many know VHDL/verilog. Perhaps the goal of targetting FPGAs with C is to allow lots of software engineers to be able to develop algorithms that can be accelerated in a FPGA. Of course a lot of software engineers do not prefer C these days.... Phil
OK, here's an example from a few months back. It's a functional block
that can carry out either an FFT, an IFFT or a complex multiply. The
ensemble makes a pulse compressor. The tool has changed a little since
then, so I wouldn't write it quite like this again. For example, there
was a problem with the % operator back then. Plus, now that I know a
little better what I'm doing, I'd work my index variables differently.
I'd also make it all one loop, so as to better exploit the pipelining.
I maybe add about 100log2(SIZE) cycles by not having it as one loop. I
seem to remember this compiled to around 16000 slices of an X2CV6000,
and I could clock it at 120MHz (slightly more than ISE said, but you
can get away with these sort of things in the lab).

#define FFT_FORWARD -1
#define FFT_BACKWARD 1
#define CMPLX_MULT   2
#define SIZE 4096
#define 2xSIZE 8192

void PC4096Opt(IEEE754 realA_result[SIZE],
               IEEE754 imagA_result[SIZE],
               IEEE754 realB[SIZE],
               IEEE754 imagB[SIZE],
               IEEE754 Root_u1[2xSIZE],
               IEEE754 Root_u2[2xSIZE],
               int shuffle[SIZE],
               int nn,
               int m,
               char mode,
               IEEE754 scale){

  int toggle;

  float c1,c2,scaleLocal,t1,t2,u1,u2,xi1,xi,xIn,yi1,yi,yIn,
        xA[SIZE],
        yA[SIZE],
        xB[SIZE],
        yB[SIZE];

  int w,z;

  int i,j,i1,l,l1,l2,count,index,offset,shuff;

  if ( (mode == FFT_FORWARD) || (mode == FFT_BACKWARD) ){

    if (mode == FFT_FORWARD) offset = 0;
    else offset = nn;

    scaleLocal = (float) scale;

    for (i = 0; i < nn; i++)
     {
         shuff = shuffle[i];
         xIn = (float)realA_result[shuff];
         xA[i] = xIn;
         yIn = (float)imagA_result[shuff];
         yA[i] = yIn;
     }

     // Compute the FFT

     c1 = -1.0;
     c2 = 0.0;
     l2 = 1;
     count = offset;
     toggle = 0;

     for (l=0;l<m;l++) {
        l1 = l2;
        l2 <<= 1;
        for (j=0;j<(nn>>1);j++) {
              // Pipelined Inner Loop
              index = count + (j>>((m-l)-1));
              u1 = (float) Root_u1[index];
              u2 = (float) Root_u2[index];
              w = l2*j;
              z = w / (nn-1);
              i = w - (nn-1) * z;
              // Really, should be: i = (l2*j) % (nn-1)
              i1 = i + l1;

              if (toggle == 0)
              {
                xi1 = xA[i1];
                xi = xA[i];
                yi1 = yA[i1];
                yi = yA[i];

                t1 = u1 * xi1 - u2 * yi1;
                t2 = u1 * yi1 + u2 * xi1;
                xB[i1] = xi - t1;
                yB[i1] = yi - t2;
                xB[i] = xi + t1;
                yB[i] = yi + t2;
              }
              else
              {
                xi1 = xB[i1];
                xi = xB[i];
                yi1 = yB[i1];
                yi = yB[i];

                t1 = u1 * xi1 - u2 * yi1;
                t2 = u1 * yi1 + u2 * xi1;
                xA[i1] = xi - t1;
                yA[i1] = yi - t2;
                xA[i] = xi + t1;
                yA[i] = yi + t2;
              }
        }
        count = (l2 - 1) + offset;
        toggle = toggle ^ 1;
     }
     // Scaling for forward transform
        for (i=0;i<nn;i++) {
           if (toggle == 0)
           {
               realA_result[i] = (IEEE754) ( scaleLocal * xA[i]);
               imagA_result[i] = (IEEE754) ( scaleLocal * yA[i]);
           }
           else
           {
               realA_result[i] = (IEEE754) ( scaleLocal * xB[i]);
               imagA_result[i] = (IEEE754) ( scaleLocal * yB[i]);
           }
      }
}

  else if (mode==CMPLX_MULT){
    for(i=0; i<nn; i++)
    {
      xA[i] = (float) realA_result[i];
      yA[i] = (float) imagA_result[i];
      xB[i] = (float) realB[i];
      yB[i] = (float) imagB[i];
    }
    for(i=0; i<nn; i++)
    {
      realA_result[i] = (IEEE754) ( (xA[i]*xB[i]) - (yA[i]*yB[i]) );
      imagA_result[i] = (IEEE754) ( (yA[i]*xB[i]) + (xA[i]*yB[i]) );
    }
  }
}

Phil Tomson wrote:
> The main advantage that C has over the HDLs is that many software > engineers know C, not many know VHDL/verilog. Perhaps the goal of > targetting FPGAs with C is to allow lots of software engineers to be able > to develop algorithms that can be accelerated in a FPGA.
When we look at FPGAs for reconfigurable computing, that is certainly the draw. When you look at C like offering for FPGAs from firms like Mitrionics and their product Mitrion-C which directly targets moving High Performance Computing (HPC) applications to FPGAs: http://news.taborcommunications.com/msgget.jsp?mid=461789&xsl=story.xsl http://www.mitrionics.com/index.shtml with the claim of 20 times faster execution on FPGAs, it's pretty clear that FPGA have a new volume market. If you google search reconfigurable computing, there are links to hundreds of firms and projects with this goal.
> Of course a lot of software engineers do not prefer C these days....
There are more different types of software engineers than there are hardware engineers. Most software engineers have never liked plain vanilla C, just as most hardware engineers don't like RF and power supply engineering. That has always been true. C has always been the systems programming language of choice for low level implementation as a direct substitute for assembly language. This has been true since the early days in the 1970s when C was designed from the "B programming Language" which was a threaded interpreter to a fully compiled language usable to replace almost all the assembly in the UNIX operating system and utilities during the V5, to V6, to V7 migrations. Higher level languages, with better database and GUI interfaces, and other applications development libraries have always been the language of choice for higher level applications. These days that is a large number of higher level object oriented or application specific languages, including C++ and Java. While C++ and Java resemble C syntax, that is about where the simularity ends. Much like Apples, Oranges, and Bananas all grow on plants known as trees, and that is where the simularity ends. C as a low level assembly language replacement, is primarily used by a subset of programmers doing systems level programming and a small group of applications programmers doing hardware interfacing and performance sensitive optimizations. These programmers frequently have the skill sets to understand interfacing to hardware at a high level, and are the target of many current C based reconfigurable computing development tools projects. While some high level applications programmers used to coding in C++, Java, and other production languages may be trainable to do low level C work on FPGAs, in general they will find C about as primative as a VHDL/Verilog designer will find Schematics. So, like it or not, there are two vary different markets for FPGA hardware and tools. Those building hardware, and those building applications for HPC platforms. And a lot of grey area in between.