【问题标题】:getting error for VHDL shift_left operationVHDL shift_left 操作出错
【发布时间】:2017-03-29 18:40:14
【问题描述】:

我已经搜索了一段时间,但无法在网上复制任何发布的解决方案,所以我希望你们中的一些优秀的人可以帮助我。 我正在创建一个 ALU。我有两个 32 位输入和一个 32 位输出以及一个 5 位 shamt 和一个 4 位控制信号。我的代码如下,错误位置注释了。

library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;

Entity mips_alu IS
    PORT(ALUControl : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    inputA, inputB      : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    shamt                   : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
    Zero                    : OUT STD_LOGIC;
    ALU_Result          : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
    );
END mips_alu;

ARCHITECTURE behavior of mips_alu IS
BEGIN
    PROCESS(ALUControl)
    BEGIN
        CASE ALUControl is
        WHEN "0000" =>
            ALU_Result <= inputA AND inputB;
        WHEN "0001" =>
            ALU_Result <= inputA OR inputB;
        WHEN "0010" =>
            ALU_Result <= inputA + inputB;
        WHEN "0110" =>
            ALU_Result <= inputA - inputB;
        WHEN "0111" =>
            IF (inputA < inputB) THEN
                ALU_Result <= inputA;
            END IF;
        WHEN "1000" =>
            ALU_Result <= shift_left(inputB, to_integer(unsigned(shamt)));
            -- The line above is where i get my first error, The following lines will have the same issue
        WHEN "1001" =>
            ALU_Result <= shift_right(inputB, shamt);
        WHEN "1010" =>
            ALU_Result <= shift_left(inputB, inputA);
        WHEN "1011" =>
            ALU_Result <= shift_right(inputB, inputA);
        WHEN "1100" =>
            ALU_Result <= inputA NOR inputB;
        WHEN "1101" =>
            ALU_Result <= inputB(31 DOWNTO 16);
        WHEN OTHERS =>
            ALU_Result <= inputA;
        END CASE;
    END PROCESS;
END behavior;

我得到的错误是:

10511 mips_alu.vhd(33) 处的 VHDL 限定表达式错误:限定表达式中指定的 shift_left 类型必须与上下文表达式隐含的 std_logic_vector 类型匹配

我已经尝试了几种变体,所以如果我遗漏了什么,请告诉我,感谢所有帮助,因为我是 vhdl 的新手

【问题讨论】:

  • @user1155120 抱歉,我错过了错误代码的第一部分。我正在编辑以添加它。另外,我不确定您对混合 Synopsys 的意思。 ieee.numeric_std_unsigned.all 无法识别。
  • 要么使用 std_logic_arith (conv_integer) 要么使用 numeric_std 和疯狂的类型转换,或者让你的 mips_alu 端口类型为无符号,或者在过程中使用中间无符号变量与无符号类型转换。
  • Quartus II/Prime 不支持 IEEE 包 numeric_std_unsigned,截至 2016 年 3 月,它可以在此处替换 STD_LOGIC_UNSIGNED。(问题是您不能使用 std_logic_arith 中由 std_logic_unsigned 引用的未签名声明与函数numeric_std 使用它的无符号声明。VHDL 中的每个声明都是唯一的,这意味着两个无符号声明没有引用相同的类型/子类型)。

标签: vhdl bit-shift alu


【解决方案1】:

numeric_std 文档中,您可以找到函数shift_leftshift_right。在这两个描述中,您都可以看到function SHIFT_LEFT (ARG: UNSIGNED; COUNT: NATURAL) return UNSIGNED;。因此,您需要将std_logic_vector 转换为unsigned
在您的情况下,它看起来像:

ALU_Result <= std_logic_vector(shift_left(unsigned(inputB), to_integer(unsigned(shamt))));

对于您使用shift_leftshift_right 函数的其他行结束等。

【讨论】:

  • 是的,这就是我一直在寻找的,也感谢您提供指向 numeric_std 的链接。这实际上也解释了我的错误代码。它总是比我想象的要简单。
【解决方案2】:

我通常做的就是这样:

ALU_Result <= inputB(30 downto 0) & '0';

这为 ALU_Result 存储了一个向量,等于 InputB 移位了一次。 如果您想多次移动它,可以使用循环。

while (i<to_integer(unsigned(shamt))) loop
ALU_Result <= inputB(30 downto 0) & '0';
i:=i+1;
end loop;

这不是一个优雅的解决方案,但它可能会起作用。

右移:

ALU_Result <= '0' & inputB(31 downto 1);

【讨论】:

  • 很有趣的方法,而且很有意义,多亏了 Roman Matveev,我才能够使另一种方法工作。不过感谢您的意见!
  • 所以我认为 & 并不意味着逻辑与,它意味着添加到末尾? I.E.- 1010 & 0 => 10100 或 11 & 1010 => 111010 ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多