首页 文章

为什么VHDL不会让变速器工作?

提问于
浏览
0

我是VHDL的新手,我正在尝试编写一个带有32位值和5位值的左移位器 . 然后左移位器通过移出左边5位数指定的位数并在右边带来那么多零来尝试执行32位值的逻辑左移 . 我无法理解为什么数组符号不起作用 . 1 << 1的结果产生20000000而不是00000002.有人可以解释我哪里出错了吗?这是代码:

SIGNAL lshiftOutput : STD_LOGIC_VECTOR( 31 downto 0 );

COMPONENT Lshift32
    Port( a : in STD_LOGIC_VECTOR( 31 downto 0 );
          b : in STD_LOGIC_VECTOR( 4 downto 0 );
          lshiftOutput : out STD_LOGIC_VECTOR( 31 downto 0 ) );
END COMPONENT;

PROCESS(  a, b, opcode, adderOutput, subtractOutput, xorOutput, lshiftOutput, rshiftOutput )
BEGIN
    IF opcode = "0000" THEN
        result <= x"00000000";
    ELSIF opcode = "0001" THEN
        result <= adderOutput; 
    ELSIF opcode = "0010" THEN
        result <= subtractOutput; 
    ELSIF opcode = "0011" THEN
        result <= NOT a; 
    ELSIF opcode = "0100" THEN
        result <= a AND b; 
    ELSIF opcode = "0101" THEN
        result <= a OR b; 
    ELSIF opcode = "0110" THEN
        result <= xorOutput; 
    ELSIF opcode = "0111" THEN
        result <= lshiftOutput; 
    ELSIF opcode = "1000" THEN
        result <= rshiftOutput; 
    END IF;
END PROCESS;

LIBRARY ieee;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;


ENTITY Lshift32 IS
    Port( a : in STD_LOGIC_VECTOR ( 31 downto 0 );
          b : in STD_LOGIC_VECTOR ( 4 downto 0 );
          lshiftOutput : out STD_LOGIC_VECTOR ( 31 downto 0 ) );
END Lshift32;

ARCHITECTURE Lshift32Architecture of Lshift32 IS
BEGIN
    PROCESS( a, b )
    VARIABLE shiftAmount : INTEGER := 0;
    BEGIN
        shiftAmount := to_integer( b(4 downto 0) );
        -- Shift left
        lshiftOutput <= a( 31-shiftAmount downto 0 ) & ( shiftAmount-1 downto 0 => '0' ); 
    END PROCESS;
END Lshift32Architecture;

对此的测试平台是:

-- Shift Left -------------------------------------------------------
WAIT FOR 9 ns;
op <= "0111";
-- 1 << 1
input_a <= x"00000001";
input_b <= x"00000001";
WAIT FOR 1 ns;
IF (output /= x"00000002") THEN
    ASSERT false REPORT "1 << 1 has incorrect result" severity error;
END IF;

1 回答

  • 1

    Brian要求您提供一个Minimal, Complete, and Verifiable example,您编辑的代码不能创建一个围绕您最初提供的代码部分的mcve,它可以给出正确的答案:

    library ieee;  -- added
    use ieee.std_logic_1164.all;  -- added
    use ieee.numeric_std_unsigned.all; -- added
    
    entity lshift32 is
        port( a : in std_logic_vector ( 31 downto 0 );
              b : in std_logic_vector ( 4 downto 0 );
              lshiftoutput : out std_logic_vector ( 31 downto 0 ) );
    end entity lshift32;
    
    architecture lshift32architecture of lshift32 is
    begin
        process( a, b )
        variable shiftamount : integer := 0;
        begin
            shiftamount := to_integer( b(4 downto 0) );
            -- shift left
    
            lshiftoutput <= a( 31-shiftamount downto 0 ) & ( shiftamount-1 downto 0 => '0' ); 
        end process;
    end architecture lshift32architecture;
    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std_unsigned.all;
    
    entity lshift32_tb is
    end entity;
    
    architecture foo of lshift32_tb is
        signal a:   std_logic_vector (31 downto 0) := (others => '0');
        signal b:   std_logic_vector (4 downto 0)  := (others => '0');
        signal lshiftoutput: std_logic_vector (31 downto 0);
    begin
    
    DUT:
        entity work.lshift32
            port map (
                a => a,
                b => b,
                lshiftoutput => lshiftoutput
            );
    
    SIMULIS:
        process
        begin
            wait for 10 ns;
            a(0) <= '1';  -- 1
            b(0) <= '1';  -- 1
            wait for 10 ns;
            wait;
        end process;
    
    ANALYSIS:
        process (lshiftoutput)
        variable shiftamount:   integer;
        begin  
            if now > 0 ns then
                shiftamount := to_integer(b);
                report "ShiftAmount = " & integer'image(shiftamount);
                report "lshiftOutput = " & to_string(lshiftoutput);
            end if;
        end process;
    end architecture;
    

    运行上面的测试平台给出:

    ghdl -a --std = 08 lshift.vhdl ghdl -e --std = 08 lshift32_tb ghdl -r lshift32_tb lshift.vhdl:60:13:@ 10ns :(报告说明):ShiftAmount = 1 lshift.vhdl:61: 13:@ 10ns :(报告说明):lshiftOutput = 00000000000000000000000000000010

    并且您的执行失败表示您的上下文子句(使用子句)或者您的测试平台有问题 .

    请注意,您使用的是无标准软件包std_logic_unsigned和IEEE标准软件包numeric_std . 你真的不应该混合和匹配可能会有意想不到的后果 .

    numeric_std_unsigned包具有符合IEEE Std 1076-2008标准的VHDL实现 . 如果使用以前版本的VHDL标准,则可以使用包numeric_std并将convert b 类型转换为unsigned作为传递给 to_integer 的表达式 .

    对于本答案提供的测试平台,您还会发现未提供 to_string for std_logic_vector . 如果没有看到整个测试平台,它就可以正常运行 .

    如果您想证明所提供的答案,testbench可以在非-2008修订版环境中运行:

    function to_string (inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end function;
    

    该函数可以作为体系结构声明项提供 .

相关问题