Reputation: 193
ok, what I would like to do is assign a smaller std_vector to a large one, padding out the upper bits with zeros. But, I want something generic and simple that doesn't involve knowing the size of each first.
for instance if I have:
signal smaller_vec: std_logic_vector(15 downto 0);
signal larger_vec: std_logic_vector(31 downto 0);
I could do:
larger_vec <= X"0000" & smaller_vec;
But what if I don't know the size of the smaller vector. Is there a was of specifying that all upper bits are zero.
I know about the others clause, but that would get messy as I'd need a couple of lines:
larger_vec(smaller_vec'high downto 0) <= smaller_vec;
larger_vec(31 downto smaller_vec'length) <= (others => '0');
I thought I could use:
larger_vec <= "" & smaller_vec;
but this didn't work. any ideas?
Upvotes: 17
Views: 37457
Reputation: 1910
Zero-Pad or Truncate any std_logic_vector or std_logic to exactly 16 bits:
function pad16(x: std_logic_vector)
return std_logic_vector is
constant ZERO : std_logic_vector(15 downto 0) := (others => '0');
begin
if (x'length < 16) then
return ZERO(15 downto x'length) & x;
else
return x(15 downto 0);
end if;
end function;
--overload function for single bit
function pad16(x: std_logic)
return std_logic_vector is
constant ZERO : std_logic_vector(15 downto 0) := (others => '0');
begin
return ZERO(15 downto 1) & x;
end function;
-- USAGE:
--
-- reg16 <= pad16(X"3");
Upvotes: 0
Reputation: 124
James0's 2nd post was close, but the <= is facing the wrong direction, see below for a working example from duolos. I would edit, but at the time of this post I did not have enough reputation.
In https://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/ in the Vectors in aggregates section it says:
variable V : std_logic_vector(7 downto 0);
begin
V := (others => '0'); -- "00000000"
V := ('1', '0', others => '0'); -- "10000000"
V := (4 => '1', others => '0'); -- "00010000"
V := (3 downto 0 => '0', others => '1'); -- "11110000"
-- V := ("0000", others => '1'); -- illegal!
larger_vec <= (smaller_vec'high downto 0 => smaller_vec, others => '0');
should work.
Upvotes: 4
Reputation: 1036
I have encountered similar issues and tried the following:
larger_vec <= (larger_vec'range => '0') + shorter_vec;
You need to use IEEE.std_logic_unsigned.all
for this approach.
Upvotes: 1
Reputation: 193
in my case I also like the following:
larger_vec <= (smaller_vec'high downto 0 <= smaller_vec, others => '0');
Which does my final answer in one line. This works, yes?
Upvotes: 2
Reputation: 3993
Have you tried:
larger_vec <= (31 downto smaller_vec'length => '0') & smaller_vec;
In the past I have had synthesis tool issues with code like that, so I have used:
constant ZERO : std_logic_vector(larger_vec'range) := (others => '0');
. . .
larger_vec <= ZERO(31 downto smaller_vec'length) & smaller_vec;
Upvotes: 10