尝试追踪模拟中“X”位的来源

问题描述 投票:0回答:1

环顾四周,逻辑中“X”位最常见的来源似乎是由于信号的多个驱动器造成的。据我所知,我的代码中没有针对任何信号的多个驱动程序。我使用一个函数将两个 32 位浮点值相加并返回结果以设置下一个中间信号,据我所知,我可以做到这一点。当我运行模拟时,我看到输出在复位过程停止后的第一个时钟周期重置为“000000000..”,但在下一个前沿,我开始在输出上获取符号和尾数位的“X”位。我觉得这可能是我所缺少的 VHDL 基础知识,但我不确定它是什么。谢谢!

代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity DM_module is
    Port ( clk_in   : in STD_LOGIC;
           reset    : in STD_LOGIC;
           v0       : in STD_LOGIC_VECTOR (31 downto 0);
           v1       : in STD_LOGIC_VECTOR (31 downto 0);
           v2       : in STD_LOGIC_VECTOR (31 downto 0);
           v3       : in STD_LOGIC_VECTOR (31 downto 0);
           v4       : in STD_LOGIC_VECTOR (31 downto 0);
           v5       : in STD_LOGIC_VECTOR (31 downto 0);
           v6       : in STD_LOGIC_VECTOR (31 downto 0);
           v7       : in STD_LOGIC_VECTOR (31 downto 0);
           v8       : in STD_LOGIC_VECTOR (31 downto 0);
           v9       : in STD_LOGIC_VECTOR (31 downto 0);
           v10      : in STD_LOGIC_VECTOR (31 downto 0);
           v11      : in STD_LOGIC_VECTOR (31 downto 0);
           v12      : in STD_LOGIC_VECTOR (31 downto 0);
           v13      : in STD_LOGIC_VECTOR (31 downto 0);
           v14      : in STD_LOGIC_VECTOR (31 downto 0);
           v15      : in STD_LOGIC_VECTOR (31 downto 0);
           v16      : in STD_LOGIC_VECTOR (31 downto 0);
           v17      : in STD_LOGIC_VECTOR (31 downto 0);
           v18      : in STD_LOGIC_VECTOR (31 downto 0);
           v19      : in STD_LOGIC_VECTOR (31 downto 0);
           v20      : in STD_LOGIC_VECTOR (31 downto 0);
           v21      : in STD_LOGIC_VECTOR (31 downto 0);
           v22      : in STD_LOGIC_VECTOR (31 downto 0);
           v23      : in STD_LOGIC_VECTOR (31 downto 0);
           v24      : in STD_LOGIC_VECTOR (31 downto 0);
           v25      : in STD_LOGIC_VECTOR (31 downto 0);
           v26      : in STD_LOGIC_VECTOR (31 downto 0);
           v27      : in STD_LOGIC_VECTOR (31 downto 0);
           v28      : in STD_LOGIC_VECTOR (31 downto 0);
           v29      : in STD_LOGIC_VECTOR (31 downto 0);
           v30      : in STD_LOGIC_VECTOR (31 downto 0);
           v31      : in STD_LOGIC_VECTOR (31 downto 0);
           sum_out  : out STD_LOGIC_VECTOR (31 downto 0));
end DM_module;

architecture Behavioral of DM_module is

--function to sum float values
function myFloatSum(A_in: std_logic_vector(31 downto 0);
                    B_in: std_logic_vector(31 downto 0)) return std_logic_vector is

    variable sum                : unsigned(31 downto 0) := (others => '0');
    variable sign, signA, signB : std_logic;
    variable expA, expB, intExp : integer;
    variable eshift             : natural;
    variable manA, manB, manNew : signed(25 downto 0);
    variable newExp             : std_logic_vector(7 downto 0);
   
    begin
        --signs extracted
        signA := A_in(31);
        signB := B_in(31);
        --exponents extracted
        expA := conv_integer(A_in(30 downto 23)) - 127;
        expB := conv_integer(B_in(30 downto 23)) - 127;
        --mantissas extracted and placed in oversized vectors to allow for implied bit, over flow, and signs
        manA(25) := '0';
        manA(24) := '0';
        manA(23) := '1';
        manA := signed(A_in(22 downto 0));
        ManB(25) := '0';
        manB(24) := '0';
        manB(23) := '1';
        manB := signed(B_in(22 downto 0));
        
   
        --tests for exponent cases, determines the shift required, and generates the intermediate exponent
        if expA = expB then
            eShift := 0;
            intExp := expA;
        elsif expA > expB then
            eShift := expA - expB;
            manB := signed(shift_right(unsigned(manB), eShift));
            intExp := expA;
        else
            eShift := expB - expA;
            manA := signed(shift_right(unsigned(manA), eShift));
            intExp := expB;
        end if;
        
         --signs checked and mantissas converted to 2's complement as needed
        if signA ='1' then
            manA := -manA;
        end if;
        if signB ='1' then
            manB := -manB;
        end if;
       
        -- sums the two values
        manNew := manA + manB;
        
        --processes the sum to determine whether or not the result is negative and if so, reverts to a positive format  and enables the float output sign bit
        sum(31) := manNew(25);
        
        if manNew(25) = '1' then
            manNew := -manNew;
        end if;
        
        --if the sum overflowed, a logical shift is performed and the exponent incremented
        if manNew(24) = '1' then
            manNew := signed(shift_right(unsigned(manNew), 1));
            intExp := intExp + 1;
        end if;
        
        --the output is assembled
        sum(22 downto 0) := unsigned(manNew(22 downto 0));
        sum(30 downto 23) := to_unsigned(intExp, 8);
        
    return(std_logic_vector(sum));
end myFloatSum;

--initial signals
signal v0sig, v1sig, v2sig, v3sig, v4sig, v5sig, v6sig, v7sig           : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal v8sig, v9sig, v10sig, v11sig, v12sig, v13sig, v14sig, v15sig     : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal v16sig, v17sig, v18sig, v19sig, v20sig, v21sig, v22sig, v23sig   : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal v24sig, v25sig, v26sig, v27sig, v28sig, v29sig, v30sig, v31sig   : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

--first stage sums
signal s1n0, s1n1, s1n2, s1n3, s1n4, s1n5, s1n6, s1n7                   : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal s1n8, s1n9, s1n10, s1n11, s1n12, s1n13, s1n14, s1n15             : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

--second stage sums
signal s2n0, s2n1, s2n2, s2n3, s2n4, s2n5, s2n6, s2n7                   : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

--third stage sums
signal s3n0, s3n1, s3n2, s3n3                                           : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

--fourth stage sums
signal s4n0, s4n1                                                       : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

--final sum
signal final_sum                                                        : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";

begin
    --reset process
   
    process(clk_in, reset)
    begin
        if reset = '1' then
        -- Reset logic: set all registers and signals to their initial values.
        -- For example, you can set all signals to '0'.
        v0sig <= (others => '0');
        v1sig <= (others => '0');
        -- Initialize other signals and variables as needed.
        
        elsif rising_edge(clk_in) then
            --inputs assigned to signals
            v0sig <= v0;
            v1sig <= v1;
            v2sig <= v2;
            v3sig <= v3;
            v4sig <= v4;
            v5sig <= v5;
            v6sig <= v6;
            v7sig <= v7;
            v8sig <= v8;
            v9sig <= v9;
            v10sig <= v10;
            v11sig <= v11;
            v12sig <= v12;
            v13sig <= v13;
            v14sig <= v14;
            v15sig <= v15;
            v16sig <= v16;
            v17sig <= v17;
            v18sig <= v18;
            v19sig <= v19;
            v20sig <= v20;
            v21sig <= v21;
            v22sig <= v22;
            v23sig <= v23;
            v24sig <= v24;
            v25sig <= v25;
            v26sig <= v26;
            v27sig <= v27;
            v28sig <= v28;
            v29sig <= v29;
            v30sig <= v30;
            v31sig <= v31;

           
            --first stage sums
            s1n0 <= myFloatSum(A_in => v0sig, B_in => v1sig);
            s1n1 <= myFloatSum(A_in => v2sig, B_in => v3sig);
            s1n2 <= myFloatSum(A_in => v4sig, B_in => v5sig);
            s1n3 <= myFloatSum(A_in => v6sig, B_in => v7sig);
            s1n4 <= myFloatSum(A_in => v8sig, B_in => v9sig);
            s1n5 <= myFloatSum(A_in => v10sig, B_in => v11sig);
            s1n6 <= myFloatSum(A_in => v12sig, B_in => v13sig);
            s1n7 <= myFloatSum(A_in => v14sig, B_in => v15sig);
            s1n8 <= myFloatSum(A_in => v16sig, B_in => v17sig);
            s1n9 <= myFloatSum(A_in => v18sig, B_in => v19sig);
            s1n10 <= myFloatSum(A_in => v20sig, B_in => v21sig);
            s1n11 <= myFloatSum(A_in => v22sig, B_in => v23sig);
            s1n12 <= myFloatSum(A_in => v24sig, B_in => v25sig);
            s1n13 <= myFloatSum(A_in => v26sig, B_in => v27sig);
            s1n14 <= myFloatSum(A_in => v28sig, B_in => v29sig);
            s1n15 <= myFloatSum(A_in => v30sig, B_in => v31sig);
           
            --second stage sums
            s2n0 <= myFloatSum(A_in => s1n0, B_in => s1n8);
            s2n1 <= myFloatSum(A_in => s1n1, B_in => s1n9);
            s2n2 <= myFloatSum(A_in => s1n2, B_in => s1n10);
            s2n3 <= myFloatSum(A_in => s1n3, B_in => s1n11);
            s2n4 <= myFloatSum(A_in => s1n4, B_in => s1n12);
            s2n5 <= myFloatSum(A_in => s1n5, B_in => s1n13);
            s2n6 <= myFloatSum(A_in => s1n6, B_in => s1n14);
            s2n7 <= myFloatSum(A_in => s1n7, B_in => s1n15);
           
            --third stage sums
            s3n0 <= myFloatSum(A_in => s2n0, B_in => s2n4);
            s3n1 <= myFloatSum(A_in => s2n1, B_in => s2n5);
            s3n2 <= myFloatSum(A_in => s2n2, B_in => s2n6);
            s3n3 <= myFloatSum(A_in => s2n3, B_in => s2n7);
           
            --fourth stage sums
            s4n0 <= myFloatSum(A_in => s3n0, B_in => s3n2);
            s4n1 <= myFloatSum(A_in => s3n1, B_in => s3n3);
           
            --final sum
            final_sum <= myFloatSum(A_in => s4n0, B_in => s4n1);
            sum_out <= final_sum;
           
        end if;
    end process;

end Behavioral;

测试台:

-- Libraries
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Entity declaration for the Test Bench
entity DM_TB is
end DM_TB;

-- Architecture for the Test Bench
architecture TB_ARCH of DM_TB is
    -- Constants
    constant CLOCK_PERIOD    : time := 10 ns;  -- Define your clock period here
    constant HALF_PERIOD     : time := 5 ns;
    constant TEST_CASE_DELAY : time := 100 ns;  -- Delay between test cases

    -- Signals
    signal clk, TBclk_en                                    : std_logic := '0';
    signal v0i, v1i, v2i, v3i, v4i, v5i, v6i, v7i           : STD_LOGIC_VECTOR (31 downto 0);
    signal v8i, v9i, v10i, v11i, v12i, v13i, v14i, v15i     : STD_LOGIC_VECTOR (31 downto 0);
    signal v16i, v17i, v18i, v19i, v20i, v21i, v22i, v23i   : STD_LOGIC_VECTOR (31 downto 0);
    signal v24i, v25i, v26i, v27i, v28i, v29i, v30i, v31i   : STD_LOGIC_VECTOR (31 downto 0);
    signal TBoutput                                         : std_logic_vector(31 downto 0) := (others => '0');

begin
    -- Instantiate the Unit Under Test (UUT)
    uut: entity work.DM_module
        port map (
            clk_in => clk,
            v0 => v0i,
            v1 => v1i,
            v2 => v2i,
            v3 => v3i,
            v4 => v4i,
            v5 => v5i,
            v6 => v6i,
            v7 => v7i,
            v8 => v8i,
            v9 => v9i,
            v10 => v10i,
            v11 => v11i,
            v12 => v12i,
            v13 => v13i,
            v14 => v14i,
            v15 => v15i,
            v16 => v16i,
            v17 => v17i,
            v18 => v18i,
            v19 => v19i,
            v20 => v20i,
            v21 => v21i,
            v22 => v22i,
            v23 => v23i,
            v24 => v24i,
            v25 => v25i,
            v26 => v26i,
            v27 => v27i,
            v28 => v28i,
            v29 => v29i,
            v30 => v30i,
            v31 => v31i,
            reset => TBclk_en,
            sum_out => TBoutput
            -- Map your design's ports here
        );

    -- Clock generation process
    clk_process: process
    begin
        while now < 2000 ns loop  -- Adjust simulation time as needed
            clk <= '0';
            wait for HALF_PERIOD;
            clk <= '1';
            wait for HALF_PERIOD;
        end loop;
        wait;
    end process clk_process;

    -- Reset process
    reset_process: process
    begin
        TBclk_en <= '1';
        wait for 500 ns;  -- Reset duration
        TBclk_en <= '0';
        wait;
    end process reset_process;
    
    --declare
    --variable expected_result : std_logic_vector (31 downto 0) := "01000000111111011111010101101001";

    -- Test cases
    test_process: process
    begin
        --input values applied to inputs
        v0i <= "00111110100100111101011100001010";
        v1i <= "00111001101000101000011101111111";
        v2i <= "10111011101000111101011100001010";
        v3i <= "00111111010111000100100110111010";
        v4i <= "00111111100111000011110010011111";
        v5i <= "10111110111001101000000010011101";
        v6i <= "10110111111010110010000111110111";
        v7i <= "00111111100000000000000000000000";
        v8i <= "00111111000111101011101001001001";
        v9i <= "10111011001001101110101110010010";
        v10i <= "00111110100000000000000000000000";
        v11i <= "10111110101100110011001100110011";
        v12i <= "00111111001010110000100010011010";
        v13i <= "10111100111110000110110000100010";
        v14i <= "00111011000100111011011111011000";
        v15i <= "00111110010011001100110011001101";
        v16i <= "10111011100001001011010111011101";
        v17i <= "00111111111011100001010001111010";
        v18i <= "10110111001001111100010110101100";
        v19i <= "00111110101001100010010011011101";
        v20i <= "00111111100111100000010000011001";
        v21i <= "10110110100101101111111010110101";
        v22i <= "00111011101010100110010011000011";
        v23i <= "00111111001110000111001010110000";
        v24i <= "00111111101010101110000101001000";
        v25i <= "10111111010000000011010001101110";
        v26i <= "00111100111110011101101100100011";
        v27i <= "00111110011000101101000011100101";
        v28i <= "00111101111000111011110011010011";
        v29i <= "00111101110011011111001001100111";
        v30i <= "10111000011000100111111000001111";
        v31i <= "00111100110111000100100001101011";
        

        -- Wait for a moment before checking the result
        wait for TEST_CASE_DELAY;


        -- End simulation
        wait;
    end process test_process;

模拟输出:

enter image description here

我尝试了各种初始化信号的方法,尝试重写求和函数,仔细检查潜在的多个驱动程序情况..

vhdl
1个回答
0
投票

我终于找到了另一个 FPGA 大脑可以交谈,我遇到问题的原因有几个。第一个主要问题——当我编写函数时,我的思维框架是基于我在 C 中的经验,并且不能像在 C 中那样对待变量。特别是当涉及到整数和自然值时,我不知道设置后您无法执行数学或更改它们的值。

第二——我选择使用函数,因为它似乎是简化代码的一种方法,但使用函数来执行我尝试执行的任务的问题是,它会产生很多松弛,因为它不是一个时钟进程或以某种方式同步到系统的其余部分。

© www.soinside.com 2019 - 2024. All rights reserved.