分配中的宽度不匹配:VHDL

Width mismatch in assignment: VHDL

我的代码:

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 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;

你好,我在 vhdl 上做乘法器,但是在第 66 行它报告我以下错误:

if i=1: [Synth 8-690] 赋值宽度不匹配;目标有 9 位,源有 7 位 ["...Multiplier.vhd":66]

if i=2: [Synth 8-690] 赋值宽度不匹配;目标有 10 位,源有 5 位 ["...Multiplier.vhd":66]

if i=3: [Synth 8-690] 赋值宽度不匹配;目标有 11 位,源有 2 位 ["...Multiplier.vhd":66]

等等..

我不明白为什么,它们看起来大小一样..

我的常数是:

nbA=8 nbB=8

和信号P,PP_0to6和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。我确保通过添加零来移动到右边,如图所示:

schema

错误在这里:

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);

但是如果我尝试替换 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)
...
...

尺寸看起来一样。

我猜严格来说这个答案并没有真正回答你的问题,因为我并不是想找出你的错误在哪里。但我相信,如果你改变你的编码风格,你将不会再遇到如此难以调试的错误。

正如我在评论中提到的,如果您正确拆分信号,您的代码将变得更加清晰和易于调试。 IE。不要为所有事情创建一个巨大的信号。

VHDL有数组和记录,使用它们,它们不会使你的电路变大,但代码会更容易推理。

自从我真正编写 VHDL 以来已经有一段时间了,所以下面的语法可能包含拼写错误,但希望代码背后的想法是清楚的:

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;

您可能会注意到,我还删除了 generate 中 for 循环的显式索引。索引 all_zeroes 信号以生成 PPP 时仍然有一个幻数。如果我正在编写这段代码,我会用一些具有有意义名称的(计算的)常量替换它。这将使代码更具可读性,以后更改起来也很简单。

请注意,还有其他方法可以做到这一点。例如。您可以先将所有 PP 信号的所有位设置为 0,然后将其中的一部分分配给 P 值。