Velocity Reviews > VHDL > VHDL, Big RGB-generator - needs shortening, algorithms

# VHDL, Big RGB-generator - needs shortening, algorithms

rik.wilmer@kpnplanet.nl
Guest
Posts: n/a

 06-28-2013
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<20 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-14 ));
index := 7;
elsif(2y >=322 AND 2y<33 then
image := getalvec(0) (63-((x-7) + 8*(y-161) ));
index := 8;
else
image := '0';
index := 0;
end if;
elsif(next) %etc..

goouse99@gmail.com
Guest
Posts: n/a

 07-02-2013
Am Freitag, 28. Juni 2013 23:31:03 UTC+2 schrieb (E-Mail Removed):
> 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<20 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-14 ));
>
> index := 7;
>
> elsif(2y >=322 AND 2y<33 then
>
> image := getalvec(0) (63-((x-7) + 8*(y-161) ));
>
> index := 8;
>
> else
>
> image := '0';
>
> index := 0;
>
> end if;
>
> elsif(next) %etc..

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

kevin.neilson@xilinx.com
Guest
Posts: n/a

 07-02-2013
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.

HT-Lab
Guest
Posts: n/a

 07-03-2013
On 28/06/2013 22:31, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> 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.

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

> 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<20 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-14 ));
> index := 7;
> elsif(2y >=322 AND 2y<33 then
> image := getalvec(0) (63-((x-7) + 8*(y-161) ));
> index := 8;
> else
> image := '0';
> index := 0;
> end if;
> elsif(next) %etc..
>