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

How to use multiple megafunctions

Altera_Forum
Honored Contributor II
998 Views

Hi, 

 

I want to create a program where it reads in some values, divide the values by a certain coefficient, multiple them by another coefficient and then finally output them. 

 

I read in the values and store them using the flip-flip storage megafunction (lpm_ff). I divide the stored values by a certain coefficient using the divide megafunction (lpm_divide). But for some reason i can't multiple the results from the divide using the multiple megafunction (lpm_mult). I just get a plain 0 output. I can multiply the values stored in the flip flops and it works but not the result of the divide. 

 

I've tried putting in another storage block of flip-flips to store the values calculated from the divide but it doesn't work. 

 

I've also tried multiplying the values first and then dividing them but this doesn't work either. 

 

 

I have no other logic in the program other than the megafunctions. So i have no always block or anything. I've managed to successful create a moving average filter this way, so i assumed it would work for other programs. 

 

I've set it up so that none of the megafunctions have an enable line. So they should always be operating all of the time at the moment. 

 

I feel like i'm missing something fundamental but i just can't seem to work it out. 

 

Your help is much appreciated.
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
288 Views

Without seeing your actual design, my guess is you are not taking into account the dynamic range of the values. 

 

IE If you are considering the initial numbers as integers, but the results of the divide are only fractional, you'll get a result of zero plus a remainder.. If you are only using the resultant register in the multiply your answer will be zero. 

 

 

If you have control over the divide, in that you can limit the dividend to power's of 2, I would highly recommend you just use a programmable shift. 

 

Pete
0 Kudos
Altera_Forum
Honored Contributor II
288 Views

 

--- Quote Start ---  

Without seeing your actual design, my guess is you are not taking into account the dynamic range of the values. 

 

IE If you are considering the initial numbers as integers, but the results of the divide are only fractional, you'll get a result of zero plus a remainder.. If you are only using the resultant register in the multiply your answer will be zero. 

 

 

If you have control over the divide, in that you can limit the dividend to power's of 2, I would highly recommend you just use a programmable shift. 

 

Pete 

--- Quote End ---  

 

 

All of the megafunctions have been set to 14 bits because.... 

 

The value i am reading in is 14 bit (max unsigned int 16383). At the moment i've set the division coefficient to 4 to make things simple. So that reduces the number to a 12 bit value (max unsigned int 4095). I've set the multiply coefficient to 2 to make things simple. So this increases the number to a 13 bit value (max unsigned int 8191). 

 

I'm only using the quotient output of the dividing megafunction because i don't care for the precision of a decimal value for this application. The multiply only has a result output which i assume is an integer since i'm multiplying 2 integers together. All values have been set to unsigned ints for the inputs and megafunctions. 

 

Below is a sample of my code. I've set the variables to outputs so i can monitor them on the simulator. I get the correct values at the flip-flops and after the division but not after the multiply. Like i say i get a result of 0 after the multiply functions. 

 

input Clock; input In; output In0; output In1; output DivRes0; output DivRes1; output MultRes0; output MultRes1; //Storage. LPM_FF Value0(.data(In), .q(In0), .clock(Clock)); //Using default FF megafunction. defparam Value0.lpm_width = 14; LPM_FF Value1(.data(In0), .q(In1), .clock(Clock)); //Using default FF megafunction. defparam Value1.lpm_width = 14; //Divide with the divide coefficient. LPMDivide Div0(.clock(Clock), .clken(1'd1), .numer(In0), .denom(3'd4), .quotient(DivRes0)); //Custom divide megafunction. LPMDivide Div1(.clock(Clock), .clken(1'd1), .numer(In1), .denom(3'd4), .quotient(DivRes1)); //Custom divide megafunction. //Multiply with the multiply coefficient. FIR_Multiply Mult0(.clock(Clock), .dataa(DivRes0), .datab(1'd1), .result(MultRes0)); //Custom multiply megafunction. FIR_Multiply Mult1(.clock(Clock), .dataa(DivRes1), .datab(1'd1), .result(MultRes1)); //Custom multiply megafunction.
0 Kudos
Altera_Forum
Honored Contributor II
288 Views

I had the megafunctions in the program in the following order.  

 

Flip-flops before divide. 

Flip-flops after divide. 

Divide. 

Multiply. 

 

I put them like this because i thought it appeared neat and tidy in which they were grouped together. I've just changed it to the following.... 

 

Flip-flops before divide. 

Divide. 

Flip-flops after divide. 

Multiply. 

 

And now it bloody works! 

 

So has Quartus just decided to play nice or does the order in which the megafunctions are used in the program actually matter? I assumed that because they operate in parallel that it wouldn't matter.
0 Kudos
Reply