【问题标题】:Why won't VHDL left shifter work?为什么 VHDL 左移器不起作用?
【发布时间】:2016-01-26 19:23:07
【问题描述】:

我是 VHDL 新手,我正在尝试编写一个接受 32 位值和 5 位值的左移器。然后,左移器尝试通过移出左侧 5 位数指定的位数并在右侧带上那么多零来执行 32 位值的逻辑左移。我不明白为什么数组表示法不起作用。 1

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;

【问题讨论】:

  • 包括其余代码,包括库/使用子句和据称为您提供此结果的测试台。由于错误的移位距离可能会产生这种结果,因此您可能需要添加一个“报告”语句,显示shiftAmount
  • “testbench” (a) 不完整,(b) 测试与“Lshift32”实体完全不同的东西。为您抱怨的实体发布单元测试 - 完全不是别的东西。

标签: vhdl


【解决方案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 标准,您可以使用 package numeric_std 并键入 convert b to unsigned 作为传递给 to_integer 的表达式。

对于随此答案提供的测试平台,您还会发现 to_stringfor std_logic_vector 未提供。如果没有看到您的整个测试平台,它很可能会正常运行。

如果您想证明答案提供的测试平台在非 -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;

函数可以作为架构声明项提供。

【讨论】:

  • 是的,代码实际上是有效的。抱歉,我没有给出更清晰的描述。
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 2013-05-01
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多