VHDL, Big RGB-generator - needs shortening, algorithms

Discussion in 'VHDL' started by rik.wilmer, Jun 28, 2013.

  1. rik.wilmer

    rik.wilmer Guest

    So. I got this big lump of code. It generates up to 75 numbers (2
    digits) on a screen. Now I have 8 rows of "stupid" code (no algorithms),
    and I'm sure there must be some easier way.
    (Notes:
    getalvec is an array (15 downto 0) of 8x8 ram for characters
    image is what I project on the screen (to be filtered with some
    rgb-values)
    index is the current number being drawn. It is used to read from a (75
    downto 0) vector if that number should be highlighted or not
    )

    Any thoughts would be much appreciated.
    It's purpose: to put on a FPGA attached to any RGB-monitor and
    game around.
    Here's a bit of the code:

    if(2x>=14 AND 2x<30) then
    if(2y >=140 AND 2y<156) then
    image := getalvec(0) (63-((x-7) + 8*(x-70) ));
    index := 1;
    elsif(2y >=166 AND 2y <182) then
    image := getalvec(0) (63-((x-7) + 8*(y-83) ));
    index := 2;
    elsif(2y >=192 AND 2y<208) then
    image := getalvec(0) (63-((x-7) + 8*(y-96) ));
    index := 3;
    elsif(2y >=218 AND 2y<234) then
    image := getalvec(0) (63-((x-7) + 8*(y-109) ));
    index := 4;
    elsif(2y >=244 AND 2y<260) then
    image := getalvec(0) (63-((x-7) + 8*(y-122) ));
    index := 5;
    elsif(2y >=270 AND 2y<286) then
    image := getalvec(0) (63-((x-7) + 8*(y-135) ));
    index := 6;
    elsif(2y >=296 AND 2y<312) then
    image := getalvec(0) (63-((x-7) + 8*(y-148) ));
    index := 7;
    elsif(2y >=322 AND 2y<338) then
    image := getalvec(0) (63-((x-7) + 8*(y-161) ));
    index := 8;
    else
    image := '0';
    index := 0;
    end if;
    elsif(next) %etc..
     
    rik.wilmer, Jun 28, 2013
    #1
    1. Advertisements

  2. rik.wilmer

    goouse99 Guest

    Am Freitag, 28. Juni 2013 23:31:03 UTC+2 schrieb :
    Hi,
    there seems to be a typo in the third line.
    I think it should be (y-70) there.

    One thing that you can do to increase readability is replacing the inner if/elsif tree with a case-statement

    case 2y is
    when 140 to 155 => getalvec...
    index...
    when 166 to 181 => getalvec...
    index...
    --and so on

    another way would be to write some functions that do the calculation of the
    (y-offset) and index number parts.
    For that you need to develop some formula that does the calculations.
    Might be tricky because of the gaps but not impossible.
    It might be interesting to see which approach uses less ressources and runs faster. (comparators versus arithmetic blocks)

    One other solution would be another 9-bit adressable ROM that creates index and offset.
    This might be done with the case statement like shown above.
    If the synthesis tool does not do it that way immediately, you might separate the case for calculationg index and offset to create the ROM and then you just have a single getalvec assignment behind it.

    Similar thing s can be done with the 2x selection.
    Separate this into some process with the case statement, generating enable signals for the 2y ROMs

    That way you will have one Processes for the 2x rom
    N Processes for the 2y roms
    (or less if there are identical ones)

    And a final assignment
    image := getalvec(0) (63-((x-7) + 8*(y-y_offset) ));

    There may be even more usable approaches.
    But mainly you are handling and converting a huge number of constants.
    This "code converting" is done best with ROMs. you just have to decide how to structure them intelligently to make best use of the ressources.

    A number of small ROMs can be more efficient than one big thing that is 90% empty in the end.
    Look for further restrictions.
    e.g. if like in the example the 2y range is between 140 and 338 you just need a 8 bit-adressable ROM. just subtract 140 from y2 to eliminate the 9th bit.
    (maybe you need to disable the ROMs if 2y gets beyond 512-140)

    So there's a lot you can do to get rid of that nasty if-elsif tree.
    Just think about a good logic structure and let the ROM contents be calculated by some functions.

    Have a nice synthesis
    Eilert
     
    goouse99, Jul 2, 2013
    #2
    1. Advertisements

  3. What is "2y"? That doesn't appear to be a legal expression.

    Are x and "2y" counters? If so, you could count modulo-13 or -26 so you don't need all these comparators. Otherwise, you should reorganize everything so things are stored on multiple-of-power-of-2 boundaries, not multiple-of-13 boundaries.
     
    kevin.neilson, Jul 2, 2013
    #3
  4. rik.wilmer

    HT-Lab Guest

    If you have the original algorithm in C/C++ then I would suggest you
    look into using a High Level Synthesis tool like Vivado-HLS. With HLS
    you can take your algorithm and do some architectural exploration
    (select number of pipeline stages, resource sharing etc) without
    changing the source. This might be easier than trying different
    strategies in VHDL.

    Good luck,
    Hans
    www.ht-lab.com
     
    HT-Lab, Jul 3, 2013
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.