Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20638 Discussions

compare multiple std_logic_vectors

Altera_Forum
Honored Contributor II
1,381 Views

Hi, 

I have several FIFO's and i need to read out, the one with the most data first. I use the byte counter of the fifo to compare.  

But what is the best way to compare those vectors?  

 

if A > B and A > C and A > D then  

input <= A 

elsif B > A ......  

 

You get the point* 

 

Or is there a better way ?  

For now i'm using above code but it is getting complex with allot of fifo's.
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
501 Views

Sounds excessive logic will be needed. I am not sure about the need to do that in your case (I assume your work is video based from previous posts). Consider waiting until all fifos have some minimum data size then read out all on same clock.

0 Kudos
Altera_Forum
Honored Contributor II
501 Views

 

--- Quote Start ---  

(I assume your work is video based from previous posts) 

--- Quote End ---  

True, 

 

But i need the images to be stored at the same time in one memory.  

Can't buffer a whole image in BlockRam, so i buffer in FIFO's first. Then  

i write the fifo with the most data into the memory untill that one is empty.  

Then i go one with the next one.  

 

Reading the fifo's at the same time (like u suggested) would imply  

parrallel writing to the memory what isn't possible in my case.  

(well it's possible to write 2 bytes at one time but it would be to the same adress)
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

consider setting a queue flag for each fifo; flag to be raised when it has a reached a given size then pass it to memory and lower flag followed by next fifo in the queue and so on.

0 Kudos
Altera_Forum
Honored Contributor II
501 Views

Thx i'll consider it. But also if there are two bytes in the fifo they need to be  

send to the memory (if all other fifo's are empty)
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

Another approach: 

Library IEEE; use IEEE.Std_Logic_1164.all; use IEEE.numeric_std.all; entity idxmaximum is port ( Clk : in std_logic ; A : in std_logic_vector(7 downto 0) ; B : in std_logic_vector(7 downto 0) ; C : in std_logic_vector(7 downto 0) ; D : in std_logic_vector(7 downto 0) ; MaximumValue : out std_logic_vector(7 downto 0) ; MaximumIndex : out std_logic_vector(1 downto 0) ) ; end idxmaximum ; architecture a of idxmaximum is type idxval is record isvalue : natural ; idx : natural ; end record idxval ; type array_idxval is array (natural range <>) of idxval ; function subarray_idxval( src : array_idxval ; idx_from , idx_downto : natural ) return array_idxval is variable r : array_idxval ( idx_from - idx_downto downto 0) ; begin for i in 0 to idx_from - idx_downto loop r(i) := src(idx_downto + i) ; end loop ; return r ; end function subarray_idxval ; function maximum ( src : array_idxval ) return idxval is variable a , b : idxval ; begin if (src'length = 2) then a := src(0) ; b := src(1) ; elsif (src'length = 3) then a := src(0) ; b := maximum(subarray_idxval(src , 2 , 1) ); else a := maximum(subarray_idxval(src , src'length / 2 - 1 , 0)) ; b := maximum(subarray_idxval(src , src'length - 1 , src'length / 2)) ; end if ; if (a.isvalue < b.isvalue ) then return b ; else return a ; end if ; end function ; signal la , lb , lc , ld : std_logic_vector(7 downto 0) ; signal abcd : array_idxval(3 downto 0) ; signal maxresult : idxval ; begin abcd(0).isvalue <= to_integer( unsigned( la )) ; abcd(0).idx <= 0 ; abcd(1).isvalue <= to_integer( unsigned( lb )) ; abcd(1).idx <= 1 ; abcd(2).isvalue <= to_integer( unsigned( lc )) ; abcd(2).idx <= 2 ; abcd(3).isvalue <= to_integer( unsigned( ld )) ; abcd(3).idx <= 3 ; process( Clk ) begin if rising_edge( Clk ) then la <= A ; lb <= B ; lc <= C ; ld <= D ; maxresult <= maximum( abcd ) ; end if ; end process ; MaximumValue <= std_logic_vector( to_unsigned( maxresult.isvalue , 8 ) ) ; MaximumIndex <= std_logic_vector( to_unsigned( maxresult.idx , 2 ) ) ; end a ;  

This scales easily to any number of fifo's, and will be faster than the if-then-elsif approach. You can use the MaximumIndex result to select the fifo to process. The MaximumValue tells you how many you can do for that fifo. I registered both the input and output of the module, just to find out how fast it will run, the function 'maximum' itself results in a fully combinatorial circuit.
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

Thx Josyb, 

I understand what your code is doing. But not what is happening inside  

the process. (If u understand what i mean) 

I'll take the time to analyse it!
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

 

--- Quote Start ---  

But not what is happening inside the process. 

--- Quote End ---  

 

 

The idea is 'recursive programing'. This topic is usually covered in computer programming classes. Most of the time the teacher / professor will then continue to explain that you have to 'unroll' it using a for-loop construct to avoid stack-overflow and to minimize running-time, but in VHDL the compiler makes the nicest logic from it. Just take a look at the schematic in the RTL Viewer, then double up the number of entries, re-compile and look again at the RTL Viewer. You will appreciate what the 'recursive' action does.
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

If you want exactly to compare n values (and not use an equivalent criterion for FIFO selection, as suggested by kaz), then a binary tree would be the most effective way to achieve it. I guess the FIFO depth and the number of FIFOs will be small numbers, both. So the effort is limited.

0 Kudos
Altera_Forum
Honored Contributor II
501 Views

 

--- Quote Start ---  

The idea is 'recursive programing'. This topic is usually covered in computer programming classes. Most of the time the teacher / professor will then continue to explain that you have to 'unroll' it using a for-loop construct to avoid stack-overflow and to minimize running-time, but in VHDL the compiler makes the nicest logic from it. Just take a look at the schematic in the RTL Viewer, then double up the number of entries, re-compile and look again at the RTL Viewer. You will appreciate what the 'recursive' action does. 

--- Quote End ---  

 

 

I would never recommend recursion in VHDL to a beginner. A recent example (http://alteraforum.com/forum/showthread.php?t=27911&highlight=recursion) showed someone trying to use recursion like they were writing software, and they caused a stack overflow in Quartus during synthesis. 

 

I agree it can be used when you know what's coming, but uncontrolled and misunderstood uses of it can lead to problems.
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

 

--- Quote Start ---  

I would never recommend recursion in VHDL to a beginner. 

--- Quote End ---  

 

A reasonable viewpoint. The suggested recursion is actually ending up in a binary tree. For a limited number of inputs (e.g. <= 8) the code text will be shorter when writing it enrolled. For a higer number of inputs, you possibly want a pipelined action, which unfortunately can't be provided by the recursive construct.
0 Kudos
Altera_Forum
Honored Contributor II
501 Views

 

--- Quote Start ---  

I would never recommend recursion in VHDL to a beginner. A recent example (http://alteraforum.com/forum/showthread.php?t=27911&highlight=recursion) showed someone trying to use recursion like they were writing software, and they caused a stack overflow in Quartus during synthesis. 

 

I agree it can be used when you know what's coming, but uncontrolled and misunderstood uses of it can lead to problems. 

--- Quote End ---  

 

You should give beginners some credit too, shouldn't you?  

I agree there are some pitfalls, but it is often very useful and elegant. Plus having a function makes it very little work adding (or deleting) inputs, (re-)writing the binary tree by hand can be tedious if you add or delete a member. 

 

 

--- Quote Start ---  

..., then a binary tree would be the most effective way to achieve it 

--- Quote End ---  

That is exactly what the recursive function achieves. 

 

 

--- Quote Start ---  

A reasonable viewpoint. The suggested recursion is actually ending up in a binary tree. For a limited number of inputs (e.g. <= 8) the code text will be shorter when writing it enrolled. For a higer number of inputs, you possibly want a pipelined action, which unfortunately can't be provided by the recursive construct. 

--- Quote End ---  

 

Yes for a small number of inputs initially it may quicker to write the code flat-out (unrolled), but if you later have to add an input or two you end up retyping the lot.  

A for-loop will be easier to write but ends up in a stair-case logic, which is a lot slower. 

The idea in VHDL should be to look for re-usability. Together with generics, functions help a lot. 

You are quite right that a recursive function cannot be pipelined (which is a real pity).
0 Kudos
Reply