Search code examples
vhdl

Width mismatch in assignment: VHDL


My code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.costanti.all;

entity Multiplier is
    generic(nbA:integer:=nbA;
            nbB:integer:=nbB);
    port (
        A: in STD_LOGIC_VECTOR(nbA-1 downto 0);
        B: in STD_LOGIC_VECTOR(nbB-1 downto 0);
        clk: in STD_LOGIC;
        R: out STD_LOGIC_VECTOR(nbA+nbB-1 downto 0));

end Multiplier;

architecture Behavioral of Multiplier is

component AdderTree is
    generic(nbit: integer:=nbA+nbB);
    port (
          IN1: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN2: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN3: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN4: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN5: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN6: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN7: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN8: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          IN9: in STD_LOGIC_VECTOR(nbit-1 downto 0);
          S: out STD_LOGIC_VECTOR(nbit-1 downto 0)
          );
end component;

signal V : STD_LOGIC_VECTOR(nbA-1 downto 0);
signal P : STD_LOGIC_VECTOR((nbA*nbB)-1 downto 0);
signal PP_0to6 : STD_LOGIC_VECTOR( (nbA)+(nbA+1)+(nbA+2)+(nbA+3)+(nbA+4)+(nbA+5)+(nbA+6)-1 downto 0); --(dim(pp0+PP1+PP2+PP3+PP4+PP5+PP6) downto 0 )
signal PP7 : STD_LOGIC_VECTOR(nbA+nbB-1 downto 0);
signal P7 : STD_LOGIC_VECTOR(nbA downto 0);
signal PPP : STD_LOGIC_VECTOR((nbA+nbB)*(nbB+1)-1 downto 0);


begin

for_g: for i in 0 to nbB-1 generate
        V <= (others => B(i));
        P((nbB)*(i)+(nbB-1) downto (nbB)*(i)) <= V and A;
end generate for_g;

P7 <= '0' & P((nbA*nbB)-1 downto (nbA*nbB)-1-(nbB-1));

PP_0to6(nbB-1 downto 0)  <= P(nbB-1 downto 0); --PP0

for_g2: for i in 0 to nbB-3 generate
         PP_0to6((nbB+1)*(i+1)+(i*(i+1)/2)+7 downto (nbB+1)*(i+1)+(i*(i+1)/2)) <= P(nbB*(i+1)+(nbB-1) downto nbB*(i+1)); --PP1 to PP6
         PP_0to6((nbB+1)*(i+1)+(i*(i+1)/2)-1 downto (nbB+1)*(i)+((i-1)*(i)/2)+7+1) <= (others => '0');
end generate for_g2;

PP7(nbA+nbB-1 downto nbA-1) <= P7;
PP7(nbA-2 downto 0) <= (others => '0');

PPP_0to6: for i in 3 to nbB-2 generate
            PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2); --PP0 to PP6
            PPP(((i+1)*(nbA+nbB-1)+i) downto ((i+1)*(nbA+nbB-1)+i)-(8-i)+1)<= (others => '0');
end generate PPP_0to6;

-- Fill last 32 bits of PPP
--Insert ADDER TREE
 
end Behavioral;

Portion of the error code: portion of code

PPP_0to6: for i in 0 to nbB-2 generate

        PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2); --PP0 to PP6

        PPP(((i+1)*(nbA+nbB-1)+i) downto ((i+1)*(nbA+nbB-1)+i)-(8-i)+1)<= (others => '0');

end generate PPP_0to6;

Hi, I'm making a multiplier on vhdl, but on line 66 it reports me the following error:

if i=1: [Synth 8-690] width mismatch in assignment; target has 9 bits, source has 7 bits ["...Multiplier.vhd":66]

if i=2: [Synth 8-690] width mismatch in assignment; target has 10 bits, source has 5 bits ["...Multiplier.vhd":66]

if i=3: [Synth 8-690] width mismatch in assignment; target has 11 bits, source has 2 bits ["...Multiplier.vhd":66]

and so on..

I can't understand why, they seem to be the same size ..

my constant are:

nbA=8 nbB=8

and the signal P, PP_0to6 and PPP:

signal P : STD_LOGIC_VECTOR((nbA*nbB)-1 downto 0);
signal PP_0to6 : STD_LOGIC_VECTOR( (nbA)+(nbA+1)+(nbA+2)+(nbA+3)+(nbA+4)+(nbA+5)+(nbA+6)-1 downto 0);
signal PPP : STD_LOGIC_VECTOR((nbA+nbB)*(nbB+1)-1 downto 0);

N.B. I make sure to shift to the rigth by adding zeros as in the figure:

schema

The error is here:

PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2);

but if I tried to replace the value of i:

i=0: PPP(7 downto 0) <= PP_0to6(7 downto 0);
i=1: PPP(24 downto 16)<=PP_0to6(16 downto 8)
i=2: PPP(41 downto 32)<=PP_0to6(26 downto 17)
i=3: PPP(58 downto 48)<=PP_0to6(37 downto 27)
...
...

the dimensions look the same.


Solution

  • I guess strictly speaking this answer doesn't really answer your question, since I'm not trying to figure out where your error is. But I'm convinced that if you change your coding style you won't encounter such difficult to debug errors any more.

    As mentioned in my comments, your code will become must clearer and easier to debug if you split the signal up properly. I.e. don't create one giant signal for everything.

    VHDL has arrays and records, use them, they won't make your circuit any larger, but the code will be much easier to reason about.

    It's been a while since I actually wrote VHDL, so the syntax below might contain typo's, but hopefully the idea behind the code is clear:

    constant c_AllZeros : std_logic_vector(c_MaxZeros - 1 downto 0) := (others => '0');
    
    ...
    
    type t_P is std_logic_vector(c_SomeLength - 1 downto 0);
    subtype t_P_Array is array (natural range <>) of t_P;
    
    ...
    
    signal P : t_P_Array(0 to c_NumInputs - 1);
    
    ...
    
    PPP_0to6: for i in PPP'range generate
      PP(i)  <= P(i) & c_AllZeros(index downto 0);
      PPP(i) <= c_AllZeros(c_MaxZeros - index downto 0) & PP(i);
    end generate PPP_0to6;
    

    As you might notice, I also got rid of the explicit indices for the for-loop in the generate. There's still a magic number when indexing the all_zeroes signal to generate PPP. If I was writing this code, I'd replace that with some (calculated) constant with a meaningful name. This will make the code both more readable and trivial to change later on.

    Note that there's other ways to do this. E.g. you could first set all bits of all PP signals to 0 and then assign a slice of them the P value.