Forum Discussion
Altera_Forum
Honored Contributor
14 years agoAdding and resizing in one step
Hi,
Is there a way to add two unsigned numbers and extract only the x most significant bits from it in one step? I want something like this: sum <= resize(number1 + number2,4) Instead of: temp <= number1 + number2 sum <= temp(7 downto 4) The existing resize function in numeric_std drops the msb's, I want the lsb's dropped. Thanks in advance!11 Replies
- Altera_Forum
Honored Contributor
If your tool understands and supports the following:
sum = (num1 + num2)/2**4; Then it is equivalent to discarding 4 bits from result unless it goes silly and creates a division module. alternatively if you can accept truncation errors then: sum <= num1(6 downto 4) + num2(6 downto 4); is almost equivalent but division is done on operands. - Altera_Forum
Honored Contributor
Thanks kaz for your reply!
--- Quote Start --- sum = (num1 + num2)/2**4; --- Quote End --- I guess that in this case sum must have the same size as num1 and num2? I would rather have that sum already has the smaller size. --- Quote Start --- alternatively if you can accept truncation errors then: sum <= num1(6 downto 4) + num2(6 downto 4); --- Quote End --- I think I will go with this one. If there would be a way to avoid truncation errors, please let me know. - Altera_Forum
Honored Contributor
--- Quote Start --- If there would be a way to avoid truncation errors, please let me know. --- Quote End --- Yes. The code you origionall posted: temp <= number1 + number2 sum <= temp(7 downto 4) - Altera_Forum
Honored Contributor
Yes I know, but that is in two steps (clocks). I would rather have it in one.
- Altera_Forum
Honored Contributor
If you want it in one clock, then make temp a variable rather than a signal.
- Altera_Forum
Honored Contributor
I forget if VHDL has a right shift operator but if it does you could use that to take the 8 bit value and only assign the upper 4 bits to the destination.
What Tricky said is how I typically do this in verilog even though >> would get the job done. - Altera_Forum
Honored Contributor
--- Quote Start --- Hi, Is there a way to add two unsigned numbers and extract only the x most significant bits from it in one step? I want something like this: sum <= resize(number1 + number2,4) Instead of: temp <= number1 + number2 sum <= temp(7 downto 4) The existing resize function in numeric_std drops the msb's, I want the lsb's dropped. Thanks in advance! --- Quote End --- assuming you are using type 'unsigned'
but this works even nicer :sum <= to_unsigned( (to_integer(number1)+to_integer(number2)) / 16 , 4) ;sum <= unsigned( number21 + number22 )(7 downto 4) ; - Altera_Forum
Honored Contributor
--- Quote Start --- but this works even nicer : sum <= unsigned( number21 + number22 )(7 downto 4) ; --- Quote End --- I have two problems with this construct - it doesn't refer to a defined VHDL syntax as far as I'm aware of - it leaves sum unconnected in Quartus V9.0, without generating an error - Altera_Forum
Honored Contributor
--- Quote Start --- I have two problems with this construct - it doesn't refer to a defined VHDL syntax as far as I'm aware of - it leaves sum unconnected in Quartus V9.0, without generating an error --- Quote End --- I verified it in 12.0 in the RTL-viewer. Both constructs generated the same 'schematic'. I almost sure it will also work in 9.1 as I have used similar constructs in 9.1-based projects. I have never looked at the offical VHDL specification and I am not a language expert but let's elaborate: if we write
we conclude that the sum of the two unsigned vectors is assigned to an unsigned vector. The VHDL compiler knows how to do this. Internally the compiler may represent the result of 'n1 + n2' in any format it thinks suited, but it will convert it into the unsigned representation of the LHS. Now consider a function --- Quote Start --- func( par : xxx) return unsigned ... --- Quote End --- we can do the following: --- Quote Start --- sum <= func( n1 + n2 ) --- Quote End --- assuming func handles the type of 'n1 + n2'. A function returns an (RHS) object of the specified type and as such we can write the following: --- Quote Start --- sum <= func(n1 + n2)(7 downto 4) ; --- Quote End --- A typecast is a kind of special function, so we can replace the function func() with the typecast unsigned() resulting insum <= n1 + n2 ;
So we can save some typing and can do with less 'intermediate' signals cluttering up the file. It also works with the dot-operator for functions returning a record type. You may have to enable VHDL 2008 support, I always do ...sum <= unsigned(n1 + n2)(7 downto 4) ; - Altera_Forum
Honored Contributor
I see, that the construct (slice of a type conversion function) is supported in Quartus 12, with or without VHDL 2008 activation.
In Quartus V9.0, the expression is accepted without throwing an error, but doesn't assign a value to the LHS. A slice of a regular function call works in Quartus 9. I don't think that the slice of a type conversion function is a VHDL 2008 feature. It's something that you can read into the general properties of a "globally static primary", although I never found it mentioned in literature. Thanks for suggesting the interesting construct.