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

Average in VHDL..?

Altera_Forum
Honored Contributor II
2,950 Views

Hi everyone, can anyone please give me an idea about how to average the given data (for exampale say decimal 1 to 10). 

thank you.
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
1,681 Views

It's easy to average 2^n numbers - just apply numbers divided by 2^n (dividing by 2^n is just a binary shift by n bits) one by one to accumulator's input and after 2^n additions you'll get averaged value at accumulator's output. 

If the number of values to average isn't 2 raised into n-th power you can use binary shift and multiplication by coef<1. Let the number of values be 10 so we have to divide each value by 10 or multiply by 0.1. 0.1=0.8/8. Firstly we shift values by 3 bits (2^3=8) and then multipies results by 0.8. Of course you have to enlarge the resolution so as not to reduce accuracy of the final result.
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

I am not quite sure of VHDL. 

 

in case verilog HDL. 

you can just write as like software calculation. 

such as... 

 

avg <= sumdata / sumnum; 

 

or 

you can just use div megacore function. 

 

notice that. 

in both way. 

you need to pay attention for timing delay. 

it might take few clocks.depending on FPGA and bit width. 

 

I hope this information helps you. 

 

see you.
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

Hi, 

in VHDL you can also either use the Megacore function or use the workaround as given in first post (which might internally be compiled rather identical). 

 

The direct writing of a <= b/c will give an error as the compiler cannot resolve this to pure logic. Does this (in Verilog) really ends up with compiled code or is this syntax beind supported for simulation and/or testbench only (like Wait 500ms).
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

 

--- Quote Start ---  

Hi, 

in VHDL you can also either use the Megacore function or use the workaround as given in first post (which might internally be compiled rather identical). 

 

The direct writing of a <= b/c will give an error as the compiler cannot resolve this to pure logic. Does this (in Verilog) really ends up with compiled code or is this syntax beind supported for simulation and/or testbench only (like Wait 500ms). 

--- Quote End ---  

 

 

averaging in principle is add up all elements then divide by number of elements. 

if these elements are arriving in a sequential stream of samples and assuming your elements are 2^n then you add them up in an accumulator of suitable width and at the end divide by just truncating off n bits.
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

a <= b/c; is perfectly synthesisable. But, as with verilog, there will be 0 pipelining so the performance will be poor. So you still need to use the megafunction. 

 

Like carl said, its best to divide by 2^n, as this is just a bitshift and essentially free in terms of logic.
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

Thank-you all for your great replies, 

 

yes Mr.Sergey, i had already tried the averaging of 2^n numbers its working, but the actual problem is at present i'm n't able to use megacore function for floating point multiplication or either for division, so can you please suggest me the way to achieve the floatingpoint multiplication by writing program...! thankyou again.
0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

divide by 2^n doesnt work for floating point! it is for fixed point only.

0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

Azay, do you really need floating point operations or you just to multiply by fractional numbers with fixed point (for example 0.800, 0.625, 0.125)? I've never used floating point operations. If you just want to multiply by fractional number you have to increase number of digits you use to represent values you're going to average. For example, number 4 represented by 5 bits is "00100". Let's multiply 4 by 0.125 which can be represented by "0.001" - 4 bits. We can perform this multiplication by conv_std_logic_vector(signed(x)*signed(y),9), were x="00100", y="0001". The result will be "000000100" - the resolution of multiplication is 9 bits = 5bits+4bits. Get rid of 1 MSB (we add just 3 bits of fractional part and we don't need 1 extra bit) and take into account that 3 lower bits are representing fractional part and you'll get "00000100" or "00000.100". This is integer number=4, but we know that it's actually 0.5.

0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

thankyou all for your great suggestions, im now trying to average my requirement for 256 samples instead of 245 samples. And after final stage only i might know the difference by comparing the theoretical n practical values.

0 Kudos
Altera_Forum
Honored Contributor II
1,681 Views

Hi, 

you can - if you have logic cells to spend for this - still convert your values to float and use the ALTERA Megafunction to divide by any number. You just have to spend the cells for implementation :-D 

Ok... I see you wrote you aren't able to use the megacore functions - do to limited space or?
0 Kudos
Reply