Search code examples
vhdlvivado

VHDL error in Vivado states "target has 17 bits, source has 33 bits"


I am receiving an error that says my target is 17 bits but the source is 33 bits. I don't understand how this is the case when the two things being added together are each 16 bits. This should result in a 17-bit sum. I am unsure as to how it comes to 33 bits.

I have tried converting each addend into an sfixed value because that is what the target is. I have tried without this conversion. I have tried using the resize function on each addend in order to guarantee each is 16 bits. This method worked but created an incorrect circuit.

N and I are both generic integers of value 4.

This is the problem statement:

wx12 <= wx(1*(4*N)-1 downto 0*(4*N)) + wx(2*(4*N)-1 downto 1*(4*N));

This is wx and how it is defined/populated:

signal wx : sfixed (4*N*I-1 downto 0);

wx(1*(4*N)-1 downto 0*(4*N)) <= x(1*(2*N)-1 downto 0*(2*N)) * w(1*(2*N)-1 downto 0*(2*N));                                                                       
wx(2*(4*N)-1 downto 1*(4*N)) <= x(2*(2*N)-1 downto 1*(2*N)) * w(2*(2*N)-1 downto 1*(2*N));                                                                       
wx(3*(4*N)-1 downto 2*(4*N)) <= x(3*(2*N)-1 downto 2*(2*N)) * w(3*(2*N)-1 downto 2*(2*N));                                                                       
wx(4*(4*N)-1 downto 3*(4*N)) <= x(4*(2*N)-1 downto 3*(2*N)) * w(4*(2*N)-1 downto 3*(2*N));

This is w and how it is defined:

 constant w : sfixed ((2*N*I)-1 downto 0) := to_sfixed(1, N-1, -N) 
                                             & to_sfixed(1, N-1, -N)
                                             & to_sfixed(1, N-1, -N)
                                             & to_sfixed(1, N-1, -N);

This is x and how it is defined:

x : in sfixed ((2*N*I)-1 downto 0);

I expected a result of 17 bits but the error below shows the result is actually 33 bits.

[Synth 8-690] width mismatch in assignment; target has 17 bits, source has 33 bits ["C:/Users/devon/project_1/project_1.srcs/sources_1/new/neural_network.vhd":104]


Solution

  • If N and I are 4, then you have this: wx12 <= wx(15 downto 0) + wx(31 downto 16);

    The fixed_point libraries, by default, behave differently to numeric_std.

    1. Both operands are re-shaped to be (max(a,b) downto (min(a,b))
    2. The result has bit growth.

    Because max(a,b) = 31, and min(a,b) = 0, both operands are bit extended to (31 downto 0) - 32 bit. It then has a single bit of growth, giving the result.

    This is all because the fixed point libraries respects the index as the 2^n. to do what you want, you need to re-align the 2nd operand to (15 downto 0) yourself.