vhdlfpgavivado

expression has 16 elements; expected 17 elements


Vivado keeps notifying me about this issue of a mismatch between the two values at address <= address & std_logic_vector(to_unsigned(1, 1)), but I've checked and I shouldn't have an off-by-one error.
I don't try to access to address in any of the other lines of code.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

...

architecture behavioral of p1 is

    ...

    signal heading_bit                  :   std_logic_vector(1 downto 0);
    signal heading_counter              :   integer range 0 to 2 := 0;
    signal address                      :   std_logic_vector(15 downto 0);
    signal address_counter              :   integer range 0 to 16 := 0;

begin process(i_clk, i_rst)

       ...
                
                    if(i_start = '1' and heading_counter < 2) then
                    
                        if(i_w = '1') then
                            heading_bit <= heading_bit(heading_counter) & std_logic_vector(to_unsigned(1, 1));
                        else
                            heading_bit <= heading_bit(heading_counter) & std_logic_vector(to_unsigned(0, 1));
                        end if;

                        heading_counter <= heading_counter + 1;
                        
                    elsif(i_start = '1' and heading_counter >= 2) then
                    
                        if(i_w = '1' and address_counter < 16) then
                            address <= address & std_logic_vector(to_unsigned(1, 1));
                        elsif(i_w = '0' and address_counter < 16) then
                            address <= address & std_logic_vector(to_unsigned(0, 1));
                        end if;
                        
                        ...
            
    end process; 

I've already looked for previous queries about the same issue and then checked my code again, but I can't seem to find my source of the problem.


Solution

  • The left hand side (LHS) and the right hand side (RHS) of an assignment needs to have the same number of bits.

    You ask why this works for heading_bit. The assignment is:

            heading_bit <= heading_bit(heading_counter) & std_logic_vector(to_unsigned(1, 1)); -- or (0, 1)
    

    By indexing a single bit of heading_bit and concatenating it with the one-bit std_logic_vector the RHS is 2 bits wide. And the LHS is heading_bit that is 2 bits wide, too. Everything is fine, syntactically.

    But for this assignment you get an error:

            address <= address & std_logic_vector(to_unsigned(1, 1)); -- or (0, 1)
    

    Of course, because you append one bit to address on the RHS and then assign this to address on the LHS. The widths do not match.


    Let's assume, that you want to left-shift the bits in address and shift in the one-bit std_logic_vector on the right. Then the solution is to index the appropriate part of address:

            address <= address(15 downto 1) & std_logic_vector(to_unsigned(1, 1)); -- or (0, 1)
    

    Would initializing address to a vector of zeroes and then replace a certain digit with either '1' or '0' based on the value of the counter be equivalent as well?

    For this you "just" need to translate your statement into this assignment:

            address(heading_counter) <= std_logic_vector(to_unsigned(1, 1)); -- or (0, 1)