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

Are only MSBs outputted if bits are restricted?

Altera_Forum
Honored Contributor II
1,899 Views

Hi, 

 

Suppose I have a complex multiplier from the MegaWizard with inputs having 16 bits each and the outputs also having 16 bits. Because 16*16 equals 32 bits, would restricting the output to 16 bits output the Most Significant Bits (MSBs), i.e. would it output [31 downto 16] bits of the total 32 bits? 

 

Also, would the above reasoning be the same for the altmult_add MegaWizard block too? 

 

Is it common for all the Quartus arithmetic in general (to output the MSBs)? 

 

If not, how can I force only the MSBs to be outputted? 

 

Thank you.
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
1,096 Views

The arithmetic functions should discard LSBs if it allows you less than maximum width. If in doubt, you may keep it maximum width then choose by hand the bits you want to keep and discard other bits.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

Alright, I will go with the second option....Thank you.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

lpm_mult does discard the LSB.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

Suppose the 32-bit output is "00000011010100100000111100001010"...how would you ignore the first 6 0-bits and then output the 16 MSB "1101010010000011"?

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

When discarding most significant bits, you should use saturation logic to avoid overflow. For unsigned multiply, if any of the 6 bits on the left is set, the output should be forced to maximum value. For signed multiply, to min- or maxint, depending on the sign.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

Unfortunately, I am relatively new to VHDL and Altera Quartus, so I couldn't really comprehend your statement above... 

 

I was actually coding something along these lines: 

 

BEGIN 

PROCESS (clock) 

BEGIN 

IF (clock = '1') THEN 

FOR i IN 31 DOWNTO 0 LOOP 

IF datain(i) /= '0' THEN 

out_msb <= datain(i DOWNTO (i-15)); -->line 41 

END IF; 

END LOOP; 

END IF; 

END PROCESS; 

END rtl; 

 

But compiling this gives me an error:  

"error (10453): vhdl error at msb_output.vhd(41): right bound (-1) of slice must belong to range (31 downto 0) of corresponding object

 

What I was trying to do is loop until I get the first '1' from the left, then take the 16-bits starting from the first '1' as my 16-MSB output. 

 

Help and guidance will be highly appreciated.
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

You cannot easily drop a selective number of 0's, you usually just drop a fixed N bits and do the saturation logic as FvM describes, maybe even adding an overflow bit to let other things know that a number has saturated and not actually come out to max. The big problem would be knowing what power of 2 the MSB represents if you tried that, along with all the extra logic required to count the number of 0s and output the next 16.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

 

--- Quote Start ---  

Unfortunately, I am relatively new to VHDL and Altera Quartus, so I couldn't really comprehend your statement above... 

 

I was actually coding something along these lines: 

 

BEGIN 

PROCESS (clock) 

BEGIN 

IF (clock = '1') THEN 

FOR i IN 31 DOWNTO 0 LOOP 

IF datain(i) /= '0' THEN 

out_msb <= datain(i DOWNTO (i-15)); -->line 41 

END IF; 

END LOOP; 

END IF; 

END PROCESS; 

END rtl; 

 

But compiling this gives me an error:  

"error (10453): vhdl error at msb_output.vhd(41): right bound (-1) of slice must belong to range (31 downto 0) of corresponding object

 

What I was trying to do is loop until I get the first '1' from the left, then take the 16-bits starting from the first '1' as my 16-MSB output. 

 

Help and guidance will be highly appreciated. 

--- Quote End ---  

 

 

 

In HDL, for loops are unrolled at synthesis time - loops do not exist on hardware. Whats happening here is that it's getting to i = 14 and then it tries to take the slice 14 downto -1. What the synthesisor is creating is a 32 to 1 mux with all the different inputs (31 downto 16), (30 downto 15) etc available, and then all the bits are put through logic gates to create select lines that select the appropriate 16 bit word. But as you've seen, your code tries to create and input to this MUX with an invalid range.
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

Then what would be a better way to code this? Could I stop the loop once I come across the first '1'? 

 

Or would a while-loop be better here? How would I implement it? 

 

Appreciate all your valuable help.
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

 

--- Quote Start ---  

Unfortunately, I am relatively new to VHDL and Altera Quartus, so I couldn't really comprehend your statement above... 

--- Quote End ---  

 

My answer isn't particularly related to VHDL nor Quartus. It's a general statement about mathematical operations. Instead of trying to explain the matter further, let me say: Get you a pencil and paper (or may be a pocket calculator for convenience) and try to figure it out. 

 

To turn your above code into legal VHDL and also perform the apparently intended operation in all cases, you would change it like this: 

FOR i IN 31 DOWNTO 15 LOOP IF datain(i) /= '0' OR i =15 THEN out_msb <= datain(i DOWNTO (i-15)); -->line 41 EXIT; END IF; END LOOP; 

It takes not less than 185 Cyclone III logic cells, but gets a result in one cycle. By designing a sequential shift, you can considerably reduce the effort, but have to wait up to 16 cycles. 

 

You'll find a similar logic in a floating pointer normalizer. In addition, you would output the actual shift that's used for the exponent. In fixed point arithmethic, you try to avoid variable scaling, saturation logic, as mentioned above, may be necessary however.
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

 

--- Quote Start ---  

Suppose the 32-bit output is "00000011010100100000111100001010"...how would you ignore the first 6 0-bits and then output the 16 MSB "1101010010000011"? 

--- Quote End ---  

 

 

I think the thread has gone off track. 

It is very unrealistic supposition. Why multiply then discard 6 MSBs. 

 

It is more realistic to discard one or two bits. 

-- discarding two MSBs if data(31) = data(30) and data(31) = data(29) then data_out <= data(29 downto 14); elsif data(31) = '0' then data_out <= x"7FFF"; else data_out <= x"8001"; end if;
0 Kudos
Reply