<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html><body>
<p>(sorry in advance if formatting breaks)</p>
<p>I have only played with it for hobby projects. It does what is on the label.... however....</p>
<p>The "tweak a bit" is an understatement. You need to use quite a few funky #pragmas and special datatypes, and magic interfaces. The understanding of what works and what is a complete fail is not obvious from the C language level.</p>
<p>It works pretty well for hierarchical data pipelines (e.g. a DSP data pipelines, with samples in and processed data out), as all the timing for latency and so on is encapsulated inside your function, but coordination between parallel modules as much of a nightmare (as always).</p>
<p>As everything is fully inferred seemingly trivial changes can suddenly cause dramatic H/W resource and performance differences, so is far less stable from build to build.</p>
<p>As an example that I haven't tried with HLS, but had to hand - here is three digit binary to BCD conversion as a C coder might do it:</p>
<p> </p>
<p><span style="font-family: 'courier new', courier;">unsigned my_module(unsigned input) {</span><br /><span style="font-family: 'courier new', courier;">  unsigned rtn = 0;</span><br /><span style="font-family: 'courier new', courier;">  rtn  = (input/100)%10;</span><br /><span style="font-family: 'courier new', courier;">  rtn *= 16;</span><br /><span style="font-family: 'courier new', courier;">  rtn += (input/10)%10;</span><br /><span style="font-family: 'courier new', courier;">  rtn *= 16;</span><br /><span style="font-family: 'courier new', courier;">  rtn += input%10;</span><br /><span style="font-family: 'courier new', courier;">  return rtn;</span><br /><span style="font-family: 'courier new', courier;">}</span></p>
<p>It would be absolutely horrific in HLS. It has three divide/modulus operators, the inputs and outputs don't have explicit sizes so will default to 32 bits (before static bits get optimized away), everything is done in one cycle, so will be a big mush of LUTs and no registers/pipelining. But it will work - you will get a working design that will work very slowly and take a good chunk of FPGA resources. It you set a target timing constraint Vivado HLS will insert registers as needed to trade of latency and clock rate.</p>
<p>This is how you might choose to implement it in a HLS friendly way (explicit sizes, explicit latency, avoiding '/' & '%', lots of bit shifts), converting one value every 1000 cycles (as maybe it is for a user display). Note that it is all standard 'C', but very odd 'C':</p>
<p><span style="font-family: 'courier new', courier;">unsigned_12bits my_module2(unsigned_10bits input) {</span><br /><span style="font-family: 'courier new', courier;">  static unsigned_12bits last = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned_10bits count = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned<span>_4bits</span> ones = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned<span>_4bits</span> tens = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned<span>_4bits</span> hundreds = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned<span>_10bits</span> converting = 0;</span><br /><span style="font-family: 'courier new', courier;">   static unsigned<span>_12bits</span> rtn = 0;</span></p>
<p><span style="font-family: 'courier new', courier;">  /* Set the outputs */</span><br /><span style="font-family: 'courier new', courier;">  if(count == converting) {</span><br /><span style="font-family: 'courier new', courier;">    last = (hundreds<<8) | (tens<<4) | ones;</span><br /><span style="font-family: 'courier new', courier;">    rtn = (hundreds<<8) | (tens<<4) | ones;</span><br /><span style="font-family: 'courier new', courier;">  } else {</span><br /><span style="font-family: 'courier new', courier;">    rtn = last;</span><br /><span style="font-family: 'courier new', courier;">  }</span></p>
<p><span style="font-family: 'courier new', courier;">  if(hundreds == 9 && tens == 9 && ones == 9) {</span><br /><span style="font-family: 'courier new', courier;">    /* Reset the counter */</span><br /><span style="font-family: 'courier new', courier;">    count = ones = tens = hundreds = 0;</span><br /><span style="font-family: 'courier new', courier;">    /* Sample the input, so it can't change mid conversion */</span><br /><span style="font-family: 'courier new', courier;">    converting = input;</span><br /><span style="font-family: 'courier new', courier;">  } else {</span><br /><span style="font-family: 'courier new', courier;">    count++;</span><br /><span style="font-family: 'courier new', courier;">    if(tens == 9 && ones == 9) {</span><br /><span style="font-family: 'courier new', courier;">      hundreds++;</span><br /><span style="font-family: 'courier new', courier;">      tens = ones = 0;</span><br /><span style="font-family: 'courier new', courier;">    } else if(ones == 9) {</span><br /><span style="font-family: 'courier new', courier;">      tens++;</span><br /><span style="font-family: 'courier new', courier;">      ones = 0;</span><br /><span style="font-family: 'courier new', courier;">    } else {</span><br /><span style="font-family: 'courier new', courier;">      ones++;</span><br /><span style="font-family: 'courier new', courier;">    }</span><br /><span style="font-family: 'courier new', courier;">  }</span><br /><span style="font-family: 'courier new', courier;">  return rtn;</span><br /><span style="font-family: 'courier new', courier;">}</span></p>
<p><span>But here is how you would most likely end up doing it, just for simplicity:</span></p>
<p><span style="font-family: 'courier new', courier;">unsigned_16bits my_module2(unsigned_10bits input) {</span><br /><span style="font-family: 'courier new', courier;">  static unsigned_16bits table[1024] = {0x0000, 0x00001.... 0x1023};</span><br /><span style="font-family: 'courier new', courier;">  return table[input]</span><br /><span style="font-family: 'courier new', courier;">}</span></p>
<p><span>That last code will work like a champ with HLS. :-)</span></p>
<p>It has lots of issues with shared resources (esp on-chip and off-chip memories) that require special incantations to work correctly.</p>
<p><span>You get exactly what you ask for, but if you are not very explicit you get junk. It still needs an FPGA-aware monkey on the keyboard for reasonable results.</span></p>
<p>It does allow for testing in S/W land, rather than in H/W simulation, which is far more productive. Just compile your code and run unit tests, then convert it to H/W</p>
<p><span>Mike</span></p>
<p> </p>
<p>On 10.08.2018 09:13, Charles Manning wrote:</p>
<blockquote type="cite" style="padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%"><!-- html ignored --><!-- head ignored --><!-- meta ignored -->
<div dir="ltr">
<div>Hello All</div>
<div> </div>
<div>Has anyone done any real work, or know of any real work, that has been done with the Xilinx HLS tools.</div>
<div> </div>
<div>This is the toolset that takes code written in C/C++ and munches it down to run on an FPGA.</div>
<div> </div>
<div>There is obvious appeal from a 50,000 ft perspective that you can write a program in C, tweak it a bit and re-compile it and voilà, you're an FPGA programmer!</div>
<div> </div>
<div>The sceptic in me says that nothing comes for free. You must be giving something away. C lacks the expressiveness for some CPU operations. It surely lacks the ability to convey concepts that Verilog and VHDL do.</div>
<div> </div>
<div>This suggests to me that an FPGA executing HLS is inherently going to need more resources (read bigger, more expensive FPGAs) and need more power (ie. bigger battery, heatsinks,...) than the same function implemented in Verilog.</div>
<div> </div>
<div>Has anyone experience to either refute my assertions or back them up?</div>
<div> </div>
<div>Thanks</div>
<div> </div>
<div>Charles</div>
<div> </div>
</div>
<br />
<pre>_______________________________________________
Chchrobotics mailing list <a href="mailto:Chchrobotics@lists.ourshack.com">Chchrobotics@lists.ourshack.com</a>
<a href="https://lists.ourshack.com/mailman/listinfo/chchrobotics">https://lists.ourshack.com/mailman/listinfo/chchrobotics</a>
Mail Archives: <a href="http://lists.ourshack.com/pipermail/chchrobotics/">http://lists.ourshack.com/pipermail/chchrobotics/</a>
Meetings usually 3rd Monday each month. See <a href="http://kiwibots.org">http://kiwibots.org</a> for venue, directions and dates.
When replying, please edit your Subject line to reflect new subjects.</pre>
</blockquote>
<p> </p>
<div> </div>
</body></html>