rgt
rgt

Reputation: 21

Accessing part of std_logic_vector using variables as indexes

I am trying to access a part of std_logic_vector using variables as indexes.

The following process gets a shift_val result from a function and then uses it to calculate the indexes to extract the 6-bit data we need in shift_data_in_s

I am getting a simulation error on the last line:

shift_data_in_s <= data_in_e(to_integer(unsigned(msb_pos)) downto to_integer(unsigned(lsb_pos)))

saying "Array size of 6 on LHS does not match the array size of 1 on RHS"

I thought the initialization on lsb_pos and msb_pos would solve this problem but it didnt... not sure how it gets the same value for both these variables, if I am explicitly computing them by subtracting the same value from different constants.

signal shift_val_s      : std_logic_vector(3 downto 0);
signal shift_data_in_s  : std_logic_vector(5 downto 0);
shift_in_proc : process( data_in, num_zeros_s )

variable data_in_e      : std_logic_vector(15 downto 0);
variable msb_pos        : std_logic_vector(4 downto 0) := "01110";
variable lsb_pos        : std_logic_vector(4 downto 0) := "01001";
begin
  data_in_e := data_in & zeros_f(16 - data_in'length); 
  shift_val_s <= some_function(data_in_e);
  if ( to_integer(unsigned(shift_val)) >= 12) then
   -- all zeros
  shift_data_in_s <= ( others => '0');
  else
  -- we need only 6 significant bits from the data, 
  -- msb_pos <= 15 - num_zeros -1;
  msb_pos := std_logic_vector( "01110" - unsigned(('0' & shift_val_s))); 
  -- lsb_pos <= 15 - num_zeros -6;
  lsb_pos := std_logic_vector("01001" -  unsigned(('0' & shift_val_s))); 
  if ( lsb_pos(4) = '1') then -- if -ve
    shift_data_in_s <= data_in_e(to_integer(unsigned(msb_pos)) downto 0) & zeros_f( to_integer(unsigned(neg_f(lsb_pos))));
  else
    shift_data_in_s <= data_in_e(to_integer(unsigned(msb_pos)) downto to_integer(unsigned(lsb_pos)));
  end if;
 end if ; end process shift_in_proc;

Upvotes: 2

Views: 3456

Answers (2)

EML
EML

Reputation: 10281

The most likely explanation is that msb_pos and lsb_pos contain a metavalue (ie. non-01HL data), presumably because data_in is invalid. The to_integer calls would then both return 0, giving you a range of 1, not 6. In any event, you can find out quickly using your simulator.

EDIT

Quick fix, as per your comment: make sure that some_function always returns a non-metavalue 4-bit vector. There are lots of ways to do this, but you could simply do:

fixed_answer <= to_01(metaval_answer); -- remove metavals

There's a to_01 in numeric_std, which takes an unsigned and returns an unsigned. By default, metavalues are converted to zero. You'll still get the wrong answer at the breginning of simulation, but at least the sim will carry on.

Upvotes: 1

NIM
NIM

Reputation: 111

The value of your variable lsb_pos is dependent on shift_val_s, which is itself dependent on some_function - the code for which you have not provided. So it is not possible for anyone here to directly diagnose the problem.

Incidentally your code would be easier to read if you use integer variables, e.g.:

variable msb_pos        : integer range 0 to 31 := 14;
variable lsb_pos        : integer range 0 to 31 := 9;

The last line then becomes:

shift_data_in_s <= data_in_e(msb_pos downto lsb_pos);

If your some_function returns an integer you can calculate your msb_pos as such:

msb_pos := 14 - shift_val_s;
lsb_pos := 9 - shift_val_s; 

Upvotes: 0

Related Questions