【问题标题】:Width mismatch in assignment: VHDL分配中的宽度不匹配:VHDL
【发布时间】:2021-01-08 01:06:01
【问题描述】:

我的代码:

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 行它报告了以下错误:

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

如果 i=2:[Synth 8-690] 分配中的宽度不匹配;目标有 10 位,源有 5 位 ["...Multiplier.vhd":66]

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

注意如图所示,我确保通过添加零来转移到右侧:

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

尺寸看起来一样。

【问题讨论】:

  • 请不要将代码发布为图片,这样任何人都无法复制您的代码来尝试修复它。
  • 我在 2 1/2 年前演示了一个 VHDL adder tree with recursive instantiation in generate statements。我使用报告语句来确定界限。您可能会看到报告每个生成块的左右边界的问题。提供minimal reproducible example,模拟并向我们展示这些错误。
  • 在我看来,通过将所有内容都塞进一个巨大的信号中,您(以及其他任何可以看到此代码的人)的生活变得非常艰难。如果您在发布的图纸之后对其进行更多建模,则该代码将更具可读性并且不易出错。 IE。而不是 PP_0to6 创建一个包含 7 个元素的数组 PPPPPP 相同)。我敢打赌,调试会容易得多。
  • @Darhuuk 谢谢,我知道这是最好的解决方案。我想将 generate 用于教育目的,为此我创建了一个独特的数组。但你是对的,确实你说的代码更具可读性。所以正如图中所说,我为 PPP 创建了多个数组 PP1、PP2、PP3 ……等等?
  • @MarcoGreco 我不会创建多个信号PP1, PP2, ...。创建一个实际的数组,即PP(0), PP(1), ...。这样,您仍然可以使用生成块并根据您为其生成逻辑的索引进行计算。例如。对于 PP 的元素 0,您在 LSB 处添加 0 个零,对于元素 1,您添加 1 个零元素,等等。对于 MSB 侧,要添加的零数量为 8 - index。 (根据原理图。)

标签: vhdl


【解决方案1】:

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

正如我在 cmets 中提到的,如果您正确拆分信号,您的代码将变得更加清晰和易于调试。 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 值。

【讨论】:

  • 你是对的,也许我应该指定我如何选择使用这些索引(我会在这个项目的报告中这样做)。我认为问题出在 vhdl 的语法上。感谢您提供替代解决方案。它们使代码更具可读性和简单性。
  • 很遗憾,我在大学上的 vhdl 课程学分很少,我们还没有详细处理几个结构。您的解决方案对我个人有帮助,因为老师不接受课程中未教授的结构。最后,我使用了一个不灵活的解决方案(另一方面,赛道不需要它)但正确。谢谢,对于个人项目,我一定会使用您的解决方案。
  • @MarcoGreco 啊,听到老师/教授不允许客观上更好的解决方案,我总是很难过。无论哪种方式,很高兴听到你想通了。如果我必须使用您教授要求的解决方案,我会计算所有位偏移的常量,并以这种方式分配。 IE。类似c_PP0_LSB = 0c_PP1_LSB = c_PP0_LSB + c_PP_Width 等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
相关资源
最近更新 更多