VHDL代码没有正确地与testbench连接

时间:2013-03-01 02:38:44

标签: floating-point vhdl

我试图用组合逻辑制作一个32位浮点乘法器。 据我所知,我已经这样做了,除非我试图模拟我的测试台。 如果我用我的代码模拟,我得到所有值的U.如果我拿出我的代码并模拟我得到我的输入向量。我知道我还没有完全规范我的尾数。 我根本无法理解为什么。一切都完美融合。我唯一的问题是在模拟我的测试台时获得价值...... 一切都正确地呼唤一切。 任何帮助将不胜感激。

请注意测试平台确实有效,我用其他VHDL模拟它确实返回了正确的值

以下是我的乘数代码:

library IEEE                   ;
use IEeE.std_logic_1164.all    ;
use ieee.std_logic_arith.all   ;
use ieee.numeric_std.all       ;
Use Ieee.std_logic_unsigned.all; 

entity FP_MULTIPLIER is
    port( A_VAL, B_VAL : in std_logic_vector (31 downto 0);
            F_VAL : out std_logic_vector (31 downto 0));
end FP_MULTIPLIER;--

architecture Behavioral of FP_MULTIPLIER is
signal exponant : std_logic_vector (8 downto 0);
signal holder : std_logic_vector (47 downto 0);
signal PPA1 : std_logic_vector (47 downto 0);
signal PPA2 : std_logic_vector (47 downto 0);
signal PPA3 : std_logic_vector (47 downto 0);
signal PPA4 : std_logic_vector (47 downto 0);
signal PPA5 : std_logic_vector (47 downto 0);
signal PPA6 : std_logic_vector (47 downto 0);
signal PPA7 : std_logic_vector (47 downto 0);
signal PPA8 : std_logic_vector (47 downto 0);
signal PPA9 : std_logic_vector (47 downto 0);
signal AD1  : std_logic_vector (47 downto 0);
signal AD2  : std_logic_vector (47 downto 0);
signal AD3  : std_logic_vector (47 downto 0);
signal almost:std_logic_vector (23 downto 0);
signal F0:std_logic_vector (47 downto 0);
signal F1:std_logic_vector (47 downto 0);
constant ZERO : std_logic_vector := "000000000000000000000000000000000000000000000000";     --zero vektir for imputs

type temp_MP is array (6 downto 1) of std_logic_vector (47 downto 0);
signal MP :temp_MP;
type temp_PPA is array (23 downto 0) of std_logic_vector (47 downto 0);                         --creates 24 vectir array of 49 length
signal temp :temp_PPA := (others => (others => '0'));
begin

exponant(8) <= A_VAL(31) xor B_VAL(31);                                                         --gets sign bit
exponant (7 downto 0) <= ((A_VAL (30 downto 23) + B_VAL (30 downto 23)) - 127 );                --gets exponant

partial : for I in 0 to 23 generate
    temp(I) (23+I downto I) <= '1'& A_VAL(22 downto 0) WHEN B_VAL(I)='1' ELSE                   --fills vector array and shifts it properly
                                    (others => '0');
end generate partial;


RRU1 : entity work.RRU7_3 port map (temp(0),temp(1),temp(2),temp(3),temp(4),temp(5),temp(6),PPA1,PPA2,PPA3);
RRU2 : entity work.RRU7_3 port map (temp(7),temp(8),temp(9),temp(10),temp(11),temp(12),temp(13),PPA4,PPA5,PPA6);
RRU3 : entity work.RRU7_3 port map (temp(14),temp(15),temp(16),temp(17),temp(18),temp(19),temp(20),PPA7,PPA8,PPA9);
RRU4 : entity work.RRU7_3 port map (temp(21),temp(22),temp(23),ZERO,PPA7,PPA8,PPA9,MP(1),MP(2),MP(3));
RRU5 : entity work.RRU7_3 port map (PPA1,PPA2,PPA3,PPA4,PPA5,PPA6,ZERO,MP(4),MP(5),MP(6));
RRU6 : entity work.RRU7_3 port map (MP(1),MP(2),MP(3),MP(4),MP(5),MP(6),ZERO,AD1,AD2,AD3);
RRU32: entity work.RRU3_2 port map (AD1,AD2,AD3,F1,F0);

holder <= F1+ F0;    --implement with CSA?

almost <=   holder(46 downto 22) WHEN holder(47)='1' ELSE  --fix for rounding and radix point
                holder(45 downto 21);

F_VAL <= exponant & almost;

end Behavioral;

以下是我的测试平台的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use STD.TEXTIO.all;
use IEEE.STD_LOGIC_TEXTIO.all;

entity ATB_FPM is
end entity ATB_FPM;

architecture ATB_FPM of ATB_FPM is

component FP_MULTIPLIER is
  port (
    A_VAL : in  STD_LOGIC_VECTOR ( 31 downto 0 );
    B_VAL : in  STD_LOGIC_VECTOR ( 31 downto 0 );
    F_VAL : out STD_LOGIC_VECTOR ( 31 downto 0 )
  );
end component FP_MULTIPLIER;

type F_VALS_ARRAY is array ( 0 to 15 ) of STD_LOGIC_VECTOR ( 31 downto 0 );
constant A_VALS : F_VALS_ARRAY := (
  X"3F800000", X"3F800000", X"3FA33333", X"38D1B717",
  X"41160000", X"41020831", X"43000000", X"40300000",
  X"47129320", X"41B80A3D", X"42C80000", X"46EC8E00",
  X"49791900", X"45800000", X"46733D52", X"390164EF"
);
constant B_VALS : F_VALS_ARRAY := (
  X"40000000", X"449F6000", X"42C80000", X"3951B717",
  X"460CAF00", X"42F61EB8", X"43800000", X"46210100",
  X"47000600", X"3B8B4396", X"43480000", X"4641BC00",
  X"3C4A42AF", X"46000000", X"44FC8666", X"3959945B"
);

signal X_A_VAL : STD_LOGIC_VECTOR ( 31 downto 0 );
signal X_B_VAL : STD_LOGIC_VECTOR ( 31 downto 0 );
signal X_F_VAL : STD_LOGIC_VECTOR ( 31 downto 0 );

begin
UUT: FP_MULTIPLIER
  port map (
    A_VAL => X_A_VAL,
    B_VAL => X_B_VAL,
    F_VAL => X_F_VAL
  );

process
variable DLAY : TIME;
constant T50N : TIME := 50 ns;
file OUT_FILE : TEXT open WRITE_MODE is "results.txt";
variable BUF  : LINE;
constant SP2  : STRING( 1 to 2 ) := "  ";
constant SP4  : STRING( 1 to 4 ) := "    ";
constant HDR  : STRING( 1 to 38 ) := "  A_VAL     B_VAL       F_VAL     TIME";
variable LNO  : INTEGER := 1;
begin
   for I in 0 to 15 loop
     if LNO = 1 then
       LNO := LNO + 1;
       write ( BUF, HDR );
       writeline ( OUT_FILE, BUF );
     elsif LNO = 25 then
       LNO := 1;
     else
       LNO := LNO + 1;
     end if;
     X_A_VAL <= A_VALS(I) ;    X_B_VAL <= B_VALS(I);
     wait for 50 ns;
     DLAY := T50N - X_F_VAL'LAST_EVENT; 
   hwrite ( BUF, X_A_VAL );  write ( BUF, SP2 );
   hwrite ( BUF, X_B_VAL );  write ( BUF, SP4 );
   hwrite ( BUF, X_F_VAL );  write ( BUF, SP4 );
   write  ( BUF, DLAY    );
   writeline ( OUT_FILE, BUF );
   end loop;
end process;

end architecture ATB_FPM;

根据大众需求,这是我的RRU7to3;

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity RRU7_3 is
  port (
    A_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    B_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    C_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    D_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    E_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    F_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    G_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    F2_VEC : out STD_LOGIC_VECTOR ( 47 downto 0 );
    F1_VEC : out STD_LOGIC_VECTOR ( 47 downto 0 );
    F0_VEC : out STD_LOGIC_VECTOR ( 47 downto 0 )
  );
end entity RRU7_3;

architecture WASTEFUL of RRU7_3 is

component WTA7_3 is
  port (
    A  : in  STD_LOGIC;
    B  : in  STD_LOGIC;
    C  : in  STD_LOGIC;
    D  : in  STD_LOGIC;
    E  : in  STD_LOGIC;
    F  : in  STD_LOGIC;
    G  : in  STD_LOGIC;
    F0 : out STD_LOGIC;
    F1 : out STD_LOGIC;
    F2 : out STD_LOGIC
  );
end component WTA7_3;

signal ROW2 : STD_LOGIC_VECTOR ( 65 downto 0 );
signal ROW1 : STD_LOGIC_VECTOR ( 65 downto 0 );
signal ROW0 : STD_LOGIC_VECTOR ( 65 downto 0 );

begin

GEN_LABEL: for I in 0 to 47 generate
  WTAUNIT: WTA7_3
    port map (
      A  => A_VEC(I),
      B  => B_VEC(I),
      C  => C_VEC(I),
      D  => D_VEC(I),
      E  => E_VEC(I),
      F  => F_VEC(I),
      G  => G_VEC(I),
      F0 => ROW0(I),
      F1 => ROW1(I+1),
      F2 => ROW2(I+2)
  );
end generate;

  F0_VEC <= ROW0( 47 downto 0 );
  F1_VEC <= ROW1( 47 downto 1 ) & '0';
  F2_VEC <= ROW2( 47 downto 2 ) & "00";

end architecture WASTEFUL;

现在这里是RRU3to2

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity RRU3_2 is
  port (
    A_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    B_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    C_VEC  : in  STD_LOGIC_VECTOR ( 47 downto 0 );
    F1_VEC : out STD_LOGIC_VECTOR ( 47 downto 0 );
    F0_VEC : out STD_LOGIC_VECTOR ( 47 downto 0 )
  );
end entity RRU3_2;

architecture WASTEFUL of RRU3_2 is

component CSADDER is
  generic (
    G_DELAY : TIME := 1 ns
  );
  port (
    A : in  STD_LOGIC;
    B : in  STD_LOGIC;
    C : in  STD_LOGIC;
    F0: out STD_LOGIC;
    F1: out STD_LOGIC
  );
end component CSADDER;

signal ROW1 : STD_LOGIC_VECTOR ( 48 downto 0 );
signal ROW0 : STD_LOGIC_VECTOR ( 48 downto 0 );

begin

GEN_LABEL: for I in 0 to 47 generate
  WTAUNIT: CSADDER
    port map (
      A  => A_VEC(I),
      B  => B_VEC(I),
      C  => C_VEC(I),
      F0 => ROW0(I),
      F1 => ROW1(I+1)
  );
end generate;

  F0_VEC <= ROW0( 47 downto 0 );
  F1_VEC <= ROW1( 47 downto 1 ) & '0';

end architecture WASTEFUL;

我还编辑了我上面的FP_Multiplier,以反映为便于阅读而建议的更改(测试并编译仍然很好,根本没有值。)

以下是模拟图片:

simulation produced U's only & refuses to run

3 个答案:

答案 0 :(得分:1)

这个实现不是为了易于理解而编写的,并且有许多可能的改进。

但我怀疑最重要的一点是:据我所知,你只是在名为“temp”的数组中分配每个部分产品的一部分,而剩下的每个部分产品都是“UUUU”。我们只保证RRU单元“工作”,无法告知他们是否将这些“UUU”输入值解析为输出中的“UUU”;它们似乎很可能。建议您为每个“temp”值的ALL分配定义的值。这可能足以解决困难,但除非您使用缺失的信息更新问题,否则只能告诉您。

进一步改进:

  1. 为什么不将部分产品数组称为partial_products而不是temp
  2. 为什么不拨打代号位sign而不是temp_man(8)? Ditto指数,而a_mantissa代替'1'& A_VAL(22 downto 0)
  3. 正如vermaete所说,使用标准库numeric_std而不是std_logic_arith和std_logic_unsigned(这可能相互矛盾)。然后将未签名的数量(如部分产品)声明为“unsigned”而不是slv。
  4. 除非您打算修改ZERO(!)的值,否则请将其声明为常量而不是信号((others => '0')表单会保存对所有这些数字的计数!)。
  5. 请注意,您分配给holder的{​​{1}}的两个切片大小不同。如果你说,在这种情况下“一切都完美编译”,请提交针对您正在使用的工具的错误报告,并在此处发布其名称和版本,以便我们可以避免使用它。

答案 1 :(得分:0)

您的测试平台应至少驱动FB_MULTIPIER组件的输入(a.k.a DUT)。 在更好的情况下,它还将读取DUT的输出并检查它们是否是预期的。

在您的测试平台中,我找不到为X_A_VAL和X_B_VAL指定值的位置。如果你没有驱动std_logic,它将处于未初始化状态('U')。

作为旁注:

use ieee.std_logic_arith.all   ;
use ieee.numeric_std.all       ;
Use Ieee.std_logic_unsigned.all; 

是旧式和新式库的混合体。您可以在VHDL FAQ中找到有关它的更多信息。但我建议你不要这样做,只使用use ieee.numeric_std.all

答案 2 :(得分:0)

有一个稍微复杂的问题,即矢量数组与它们正在处理的函数不匹配。解决这个问题,并找出向量被零填充的位置;代码现在有效。 请注意,它尚未对数字进行标准化,但 虽然它确实给出了一定程度上准确的数字。

对于那些好奇的人来说,这是一些有用的描述

library IEEE                   ;
use IEeE.std_logic_1164.all    ;
use ieee.std_logic_arith.all   ;
use ieee.numeric_std.all       ;
Use Ieee.std_logic_unsigned.all; 

entity FP_MULTIPLIER is
    port( A_VAL, B_VAL : in std_logic_vector (31 downto 0);
            F_VAL : out std_logic_vector (31 downto 0));
end FP_MULTIPLIER;--

architecture Behavioral of FP_MULTIPLIER is
signal exponant : std_logic_vector (8 downto 0);
signal holder : std_logic_vector (47 downto 0);
signal PPA1 : std_logic_vector (47 downto 0);
signal PPA2 : std_logic_vector (47 downto 0);
signal PPA3 : std_logic_vector (47 downto 0);
signal PPA4 : std_logic_vector (47 downto 0);
signal PPA5 : std_logic_vector (47 downto 0);
signal PPA6 : std_logic_vector (47 downto 0);
signal PPA7 : std_logic_vector (47 downto 0);
signal PPA8 : std_logic_vector (47 downto 0);
signal PPA9 : std_logic_vector (47 downto 0);
signal AD1  : std_logic_vector (47 downto 0);
signal AD2  : std_logic_vector (47 downto 0);
signal AD3  : std_logic_vector (47 downto 0);
signal almost:std_logic_vector (23 downto 0);
signal there: std_logic_vector (23 downto 0);
signal F0:std_logic_vector (47 downto 0);
signal F1:std_logic_vector (47 downto 0);
constant ZERO : std_logic_vector := "000000000000000000000000000000000000000000000000";     --zero vektir for imputs

type temp_MP is array (6 downto 1) of std_logic_vector (47 downto 0);
signal MP :temp_MP;
type temp_PPA is array (23 downto 0) of std_logic_vector (47 downto 0);                         --creates 24 vectir array of 49 length
signal temp :temp_PPA := (others => (others => '0'));
begin

exponant(8) <= A_VAL(31) xor B_VAL(31);                                                         --gets sign bit
exponant (7 downto 0) <= ((A_VAL (30 downto 23) + B_VAL (30 downto 23)) - 127 );                --gets exponant

partial : for I in 0 to 23 generate
    temp(I) (23+I downto I) <= '1'& A_VAL(22 downto 0) WHEN B_VAL(I)='1' ELSE                   --fills vector array and shifts it properly
                                    (others => '0');
end generate partial;


RRU1 : entity work.RRU7_3 port map (temp(0),temp(1),temp(2),temp(3),temp(4),temp(5),temp(6),PPA1,PPA2,PPA3);
RRU2 : entity work.RRU7_3 port map (temp(7),temp(8),temp(9),temp(10),temp(11),temp(12),temp(13),PPA4,PPA5,PPA6);
RRU3 : entity work.RRU7_3 port map (temp(14),temp(15),temp(16),temp(17),temp(18),temp(19),temp(20),PPA7,PPA8,PPA9);
RRU4 : entity work.RRU7_3 port map (temp(21),temp(22),temp(23),ZERO,PPA7,PPA8,PPA9,MP(1),MP(2),MP(3));
RRU5 : entity work.RRU7_3 port map (PPA1,PPA2,PPA3,PPA4,PPA5,PPA6,ZERO,MP(4),MP(5),MP(6));
RRU6 : entity work.RRU7_3 port map (MP(1),MP(2),MP(3),MP(4),MP(5),MP(6),ZERO,AD1,AD2,AD3);
RRU32: entity work.RRU3_2 port map (AD1,AD2,AD3,F1,F0);

holder <= F1+ F0;

almost <=   holder(46 downto 23) WHEN holder(47)='1' ELSE
                holder(47 downto 24);

F_VAL <= exponant & almost (22 downto 0);

end Behavioral;