0 votes
in VHDL by (240 points)

How do you do a resize in VHDL?

3 Answers

0 votes
by (1.8k points)

Resize In VHDL

Quick Syntax

There's a function in the ieee.numeric_std library called "resize", which is used like this:
new_size <= resize(unsigned(old_size_std_logic_vector), 16);
new_size <= resize(signed(old_size_std_logic_vector), 16);
However, it may not do exactly what you want based on most significant or least significant bit behavior (read more below). I always prefer to do things manually here so that you know exactly what you are getting, especially since it doesn't take many lines of code:
-- go from 8 to 16 bits, pad most significant bits with 0's
new_size <= x"00" & old_size;

-- go from 8 to 16 bits, pad least significant bits with 0's new_size <= old_size & x"00";

-- go from 16 to 8 bits, use most significant bits new_size <= old_size(15 downto 8);

-- go from 16 to 8 bits, use least significant bits new_size <= old_size(7 downto 0);
The above examples were for std_logic_vector types.

Purpose

The need to resize things comes up often in VHDL. As mentioned earlier, you do have a function avaiable in the numeric_std library. However, it may not do exactly what you want.

From the documentation on the numeric_std library, here's the description of the resize function:

"-- Id: R.1
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
-- Result subtype: SIGNED(NEW_SIZE-1 downto 0)
-- Result: Resizes the SIGNED vector ARG to the specified size.
-- To create a larger vector, the new [leftmost] bit positions
-- are filled with the sign bit (ARG'LEFT). When truncating,
-- the sign bit is retained along with the rightmost part.

-- Id: R.2
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED(NEW_SIZE-1 downto 0)
-- Result: Resizes the SIGNED vector ARG to the specified size.
-- To create a larger vector, the new [leftmost] bit positions
-- are filled with '0'. When truncating, the leftmost bits
-- are dropped."

Notice that the input must be signed or unsigned, so you will need to cast a std_logic_vector as those first. You can do this by signed(my_signal) or unsigned(my_signal).

Best Practices

1. I rarely see pros use the resize function. It doesn't give you much savings on code lines, and most people don't know exactly if it pads left or pads right, so they have to waste time to look it up when they come across it in code.

2. I prefer to manually resize std_logic_vector types so that I can quickly and easily see exactly what is happening.
0 votes
by (500 points)

The most convenient and recommended method for resizing vector elements in VHDL is the 'resize' function.
This function takes a vector and resizes according to the requested length. The function is sign aware. I.E : if the operand is a signed vector number it will do an MSB bit extension to maintain the correct sign for the result.

Example :

signal x : unsigned ( 7 downto 0 ) ;
signal y : unsigned ( 11 downto 0 ) ;

-- y is 12 bits long so we explicitly write 12 as the second operand for the resize function.
y <= resize ( x , 12 ) ;

-- This is a more generic way to do the same operation. -- We don't explicitly write the length of y but instead use an attribute to extract it. -- This way, the code wouldn't have to be re-written if the length of y changes.
y <= resize ( x , y ' length ) ;
0 votes
by (500 points)

There are 2 functions from numeric_std package. One for signed and another - for unsigned:

function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;

data_new_size <= resize(data_old_size, new_size);
data_new_size <= std_logic_vector(resize(unsigned(data_old_size), new_size)

But there are other ways. If the new size is bigger I can type this:

data_new_size <= (others => '0');
data_new_size(old_size-1 downto 0) <= data_old_size;

If less:

data_new_size <= data_old_size(new_size-1 downto 0);

Also I can control it using conditional generate statements. One more way is to use loop and/or my own functions if I need some other kind of resizing. For example:

function my_resize (arg : std_logic_vector; new_size : natural; value_to_field : std_logic) return std_logic_vector is
variable arg_size : natural := arg'length;
variable effective_size : natural := new_size;
variable tmp : std_logic_vector(new_size-1 downto 0);
begin
if new_size > arg_size then
effective_size := arg_size;
for i in effective_size to new_size-1 loop
tmp(i) := value_to_field;
end loop;
end if;
for i in 0 to effective_size-1 loop
tmp(i) := arg(i);
end loop;

end function;
Hardware Coder Community

© 2022 by Hardware Coder. User contributions are licensed under cc by-sa 4.0 with attribution required. Attribution means a link to the question, answer, user, etc on this site.

This site is owned and operated by Hardware Coder in McKinney, Texas.

Send Us A Message
About Us

By using this site, you agree to the following:

Privacy Policy
Terms and Conditions
DMCA Policy
Earnings Disclaimer
Legal Disclaimer

...