VHDL代码混乱

Confusion in VHDL code

我正在尝试在 VHDL 中为 32 位乘法器实现重新编码逻辑。此外,要重新编码的输入位向量(x_in),多了一个输入"one"。目的是当 "one" 是 '1' 时输出应该是 x_in 否则如果 "one" 是 '0',它应该是两倍 x_in。如果 "neg" 为高电平,则输出必须反转。这是我的 VHDL 代码:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

package sum_vector_pkg is
    type partial_sum_array is array (0 to 15) of std_logic_vector(32 downto 0);
end package;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
use work.sum_vector_pkg.all;
use work.test.all;

entity multipleGenerator is 
    generic(
           constant WIDTH : integer := 32
    );
    port(
        x_in      : in std_logic_vector(WIDTH - 1 downto 0);
        one       : in std_logic_vector(WIDTH/2 - 1 downto 0);
        multiple  : out partial_sum_array
    );
end entity multipleGenerator;

architecture logic of multipleGenerator is
    signal sum  : std_logic_vector(WIDTH downto 0);

begin
    gen : for i in 0 to WIDTH/2 - 1 generate
        process (one,sum,x_in) is begin
            case one(i) is
                when '0' => sum <= x_in & '0'; -- twice x_in
                when '1' => sum <= '0' & x_in; -- same as x_in
                when others => sum <= x"00000000" &'0';
            end case;
            multiple(i) <= sum;
            report "The sum is " & toString(sum) & " one(i) is " & toString(one(i)) & " x_in is " & toString(x_in);
        end process;
    end generate;
end architecture logic;

我正在运行使用以下测试平台对其进行测试:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.sum_vector_pkg.all;

entity tb_multipleGenerator is

end entity tb_multipleGenerator;

architecture logic of tb_multipleGenerator is

    component multipleGenerator
        generic(
           constant WIDTH : integer := 32
        );
        port(
            x_in      : in std_logic_vector(31 downto 0);
            one       : in std_logic_vector(15 downto 0);
            multiple  : out partial_sum_array
        );
    end component;

    signal x_tb        : std_logic_vector(31 downto 0);
    signal one_tb      : std_logic_vector(15 downto 0);
    signal multiple_tb : partial_sum_array;

begin
    process begin
        x_tb <= x"00000000";
        one_tb <= x"0000";
        wait for 200 ns;
        x_tb <= x"00001111";
        one_tb <= x"0011";
        wait;
    end process;

    u_mult: multipleGenerator
        generic map (
           WIDTH => 32
        )
        port map (
            x_in     => x_tb,   
            one      => one_tb,
            multiple => multiple_tb
        );
end architecture logic;

为了检查输出,我使用了以下包:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

package test is
    function toString(v : std_logic_vector) return string;
    function toString(b : std_logic) return string;
end package;

package body test is 
    function toString(b : std_logic) return string is
        variable str : string(1 to 3);
        begin
            str := std_logic'image(b);
            return "" & str(2);
    end toString;

    function toString(v : std_logic_vector) return string is
        variable str    : string(1 to 1);
        variable strOut : string(1 to v'length);
        begin
            for i in 1 to v'length  loop
                str := toString(v(i-1));
                strOut(v'length - i + 1) := str(1);
            end loop;
            return strOut;
    end toString;
end test;

当我运行上面的代码时,我在输出中得到'X'。这是示例输出:

    Time: 200 ns  Iteration: 2  Region: /tb_multiplegenerator/u_mult/gen(12)
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001
#    Time: 200 ns  Iteration: 2  Region: /tb_multiplegenerator/u_mult/gen(13)
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001
#    Time: 200 ns  Iteration: 2  Region: /tb_multiplegenerator/u_mult/gen(14)
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001
#    Time: 200 ns  Iteration: 2  Region: /tb_multiplegenerator/u_mult/gen(15)

有人可以解释为什么这段代码不起作用吗?

问题已经存在于您的 multipleGenerator 实体中。您定义信号 sum,您在 generate 语句中不断重复使用它。但是,这些分配在 VHDL 中并行发生。所以实际上,您正在为 16 个驱动程序分配 sum

但实际上你不需要sum

清理您的代码(并使其成为 vhdl 2008)

std_logic_vector_vector_pkg.vhd:

library ieee;
use ieee.std_logic_1164.all;

package std_logic_vector_vector_pkg is
    type std_logic_vector_vector is array (natural range <>) of std_logic_vector;
end package;

converter_pkg.vhd

library ieee;
use ieee.std_logic_1164.all;

package converter_pkg is
    function to_string(slv : std_logic_vector) return string;
end package;

package body converter_pkg is
    function to_string(slv : std_logic_vector) return string is
        variable output : string(1 to slv'length) := (others => 'X');
        variable i_o : positive := 1;
    begin
        for i_s in slv'high downto slv'low loop
            output(i_o) := std_logic'image(slv(i_s))(2);
            i_o := i_o + 1;
        end loop;
        return output;
    end function;
end package body;

multipleGenerator.vhd

library ieee;
use ieee.std_logic_1164.all;
use work.std_logic_vector_vector_pkg.all;
use work.converter_pkg.all;

entity multipleGenerator is 
    generic(
        WIDTH : integer := 32
    );
    port(
        x_in      : in std_logic_vector(WIDTH - 1 downto 0);
        one       : in std_logic_vector(WIDTH/2 - 1 downto 0);
        multiple  : out std_logic_vector_vector(0 to WIDTH/2 - 1)(WIDTH downto 0)
    );
end entity;

architecture rtl of multipleGenerator is
begin
    gen : for i in 0 to WIDTH/2 - 1 generate
        multiple(i) <= '0' & x_in when one(i)='1' else x_in & '0';
    end generate;

    process(one)
    begin
        for i in 0 to WIDTH/2 - 1 loop 
            report "The sum is " & to_string(multiple(i)) &
                " one(" & integer'image(i) & ") is " & std_logic'image(one(i)) &
                " x_in is " & to_string(x_in);
        end loop;
    end process;
end architecture;

multipleGenerator_tb.vhd

library ieee;
use ieee.std_logic_1164.all;
use work.std_logic_vector_vector_pkg.all;

entity multipleGenerator_tb is end entity;

architecture behavioral of multipleGenerator_tb is
    signal b        : std_logic_vector(31 downto 0);
    signal one      : std_logic_vector(15 downto 0);
    signal multiple : std_logic_vector_vector(0 to one'length-1)(x'length downto 0);
begin
    process
    begin
        x <= (others => '0');
        one <= (others => '0');
        wait for 200 ns;
        x <= x"00001111";
        one <= x"0011";
        wait;
    end process;

    u_mult: entity work.multipleGenerator
        generic map (
            WIDTH => x'length
        )
        port map (
            x_in     => x,   
            one      => one,
            multiple => multiple
        );
end architecture;