Search code examples
vhdlfpgaxilinx

Changing a single bit in array of std_logic_vector


In one of my designs I need to modify exactly one signal in an array of std_logic_vector.

I use generate to create several n-bit adders, the output of every such n-bit adder is an n-bit bus of std_logic_vector. All the sum values are stored in an array of std_logic_vector. After every addition I need to shift the sum vector 1 place to the right and modify the most significant bit.

MULTIPLIER: for i in 0 to DataWidth-2 generate

shifted_augend(i) <= std_logic_vector(shift_right(unsigned(augend(i)),1));
temp1(i) <= augend(i)(0);
shifted_augend(i)(DataWidth-1) <= carry_out(i);

ADDR: adder generic map(DataWidth => DataWidth)
            port map(A => addend(i+1),
                     B => shifted_augend(i),
                     Cin => cin ,
                     Cout => carry_out(i+1),
                     Sum => augend(i+1));
end generate;

I tried doing it as is shown above, and although Xilinx Vivado allows to do it, it definitely causes an issue. Whenever the value that is being assigned is '1' it resolves in 'X' on the simulation, however when it is '0', it is fine. The value I am trying to modify is most likely '0' by default (result of shifting).

I suppose it is either because I cannot do that, or because i am trying to concurrently assign a signal to an existing one, hence it causes 'X' value to appear?


Solution

  • The problem was that shifting the std_logic_vector and assigning a new value to a single bit was done concurrently, hence it caused a conflict.

    What I did is: I used a process inside generate to sequentially do these 2 operations, hence:

    MULTIPLIER: for i in 0 to DataWidth-2 generate
    temp1(i) <= augend(i)(0);
    process(augend)
    
    begin
    shifted_augend(i) <= std_logic_vector(shift_right(unsigned(augend(i)),1));
    shifted_augend(i)(DataWidth-1) <= carry_out(i);
    end process;
    
    ADDR: adder generic map(DataWidth => DataWidth)
                port map(A => addend(i+1),
                         B => shifted_augend(i),
                         Cin => cin ,
                         Cout => carry_out(i+1),
                         Sum => augend(i+1));
    end generate;