在VHDL中输入不匹配错误?

时间:2014-02-03 04:28:12

标签: vhdl alu

我正在设计一个1位ALU并使用结构方法。出于某种原因,即使我只使用std_logic_vectors来处理所有内容,我仍然会遇到类型不匹配错误。我不明白会出现什么问题?

这是代码: 1位ALU:

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

ENTITY alu1 is

PORT(
    a        : IN STD_LOGIC_VECTOR; 
    b        : IN STD_LOGIC_VECTOR; 
    op       : IN STD_LOGIC_VECTOR(2 DOWNTO 0); 
    result   : OUT STD_LOGIC_VECTOR; 
    cout     : OUT STD_LOGIC; 
    zero     : OUT STD_LOGIC); 
END alu1;

ARCHITECTURE structure OF alu1 IS 

    COMPONENT FourToOneMux 
    PORT(
        andIn   : IN STD_LOGIC_VECTOR;
        orIn    : IN STD_LOGIC_VECTOR;
        addIn   : IN STD_LOGIC_VECTOR;
        bMuxIn  : IN STD_LOGIC_VECTOR;
        sel     : IN STD_LOGIC_VECTOR;
        muxOut  : OUT STD_LOGIC_VECTOR);
    END COMPONENT;

    COMPONENT TwoToOneMux 
    PORT(
        bIn         : IN STD_LOGIC_VECTOR;
        bInvertedIn : IN STD_LOGIC_VECTOR;
        sel         : IN STD_LOGIC_VECTOR;
        muxOut      : OUT STD_LOGIC_VECTOR);
    END COMPONENT;

    COMPONENT FullAdder
    PORT(
        a       :IN STD_LOGIC_VECTOR;
        b       :IN STD_LOGIC_VECTOR;
        cin     :IN STD_LOGIC_VECTOR;
        cout    :OUT STD_LOGIC_VECTOR;
        output  :OUT STD_LOGIC_VECTOR);
    END COMPONENT;

    signal muxOneOut, muxTwoOut, andOut, orOut, addOut, FMuxOut, carryOut : STD_LOGIC_VECTOR := (others => '0');

BEGIN

    M1: TwoToOneMux port map(b, NOT b, op(0), muxOneOut);
    M2: TwoToOneMux port map(a, b, op(0), muxTwoOut);
    andOut <= a AND muxOneOut;
    orOut <= a OR muxOneOut;
    A1: FullAdder port map(a, muxOneOut, cout, carryOut, addOut);
    F1: FourToOneMux port map(andOut, orOut, addOut, muxTwoOut, op(1) & op(2), result); 

END structure;

和TwoToOneMux代码:

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

ENTITY TwoToOneMux is

PORT(
    in1     : IN STD_LOGIC_VECTOR;
    in2     : IN STD_LOGIC_VECTOR;
    sel     : IN STD_LOGIC_VECTOR;
    output  : OUT STD_LOGIC_VECTOR);
END TwoToOneMux;

ARCHITECTURE behavioral OF TwoToOneMux IS BEGIN

    WITH sel select
        output <= in1 when "0",
                  in2 when "1",
                  null when others;

END behavioral;

我是VHDL的新手,我感觉很开心,所以感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

首先,您实际上并没有告诉我们类型不匹配适用的信号或实体的线索,因此这将是对代码问题的分散解决方案。但是有一个可能的候选人,所以请耐心等待......

有关更多信息,有很多不良消息来源,还有一些好的消息来源。其中最好的是Peter Ashenden的“VHDL设计师指南”。


其次,我很好奇你“获得”这个USE名单:请评论并告诉我

USE ieee.std_logic_1164.ALL; 
USE ieee.std_logic_arith.ALL; 
USE ieee.std_logic_unsigned.ALL;
USE ieee.numeric_std.all;

有很多来源教授这种风格或在示例代码中使用它,我想知道哪些来源引导初学者远离......

USE ieee.std_logic_1164.ALL; 
USE ieee.numeric_std.all;

是你想要或需要的;其他库是非标准的(由一家大公司强制进入VHDL,符合他们的商业利益,并违背VHDL理念)。他们引入了不同类型的多个定义,其名称与ieee.numeric_std.signedunsigned相同,这有助于造成混淆。

使用numeric_std类型系统的快速教程:   - 使用std_logic_vector,其中您处理的值是无类型的:例如:一个可以签名,无符号,一条指令,一个浮点数或其他来自上下文的单词   - 使用signed,其值为有符号整数   - 使用unsigned,其中值是一个有符号整数 正确选择声明将减少这些类型之间的转换次数。


第三,所有STD_LOGIC_VECTOR端口和信号都不受约束。有些地方不受约束的向量是合适的,但......这是破碎的。

VHDL是强类型的,不会推断类型,但它为您提供了有限形式的内省类型的工具。使用它很容易和安全(因为编译器捕获了大多数错误!)但通常被认为是相当高级的,因为它对初学者来说可能是令人沮丧的。

所以

Signal A_BUS : std_logic_vector(31 downto 0);
Signal B_BUS : std_logic_vector(7 downto 0);

声明两种不同类型的信号:std_logic_vector,但分别为32和8位。现在给出一个带端口的组件

PORT(
    a        : IN STD_LOGIC_VECTOR; 
    b        : IN STD_LOGIC_VECTOR );

可以连接为

PORT MAP(
    a => a_bus,
    b => b_bus );

......看到问题? a和b不兼容,因为它们具有不同的长度。你可以在Python中侥幸逃脱,其中动态类型可以尝试在运行时清理混乱,也可能在C中,类型不匹配会导致溢出导致其他内容崩溃。但是在你正在设计硬件的VHDL中却没有,你实际上希望它能够工作。

最简单的(初学者)解决方案是明确声明所有信号和端口长度

PORT(
    a        : IN STD_LOGIC_VECTOR(31 downto 0); 
    b        : IN STD_LOGIC_VECTOR(31 downto 0));

现在编译器将捕获端口映射中的错误。

这样做的缺点是它会阻止你以多态方式使用同一个模块,例如:在8位,16位和32位CPU中。通常这并不重要,但它在哪里,更先进的技术进来......

查看一个内部信号声明:

signal muxOneOut : STD_LOGIC_VECTOR;

想象一下,您希望muxOneOut与端口A具有相同的范围...您可以通过声明:

signal muxOneOut : STD_LOGIC_VECTOR(A'range);

它现在可以根据外部连接到端口A的任何信号进行自我调整。如果多路复用器在此信号上选择端口A或B,则可以正常工作 - 假设端口A和B的宽度相同。那么让我们检查一下这个假设:

assert A'length = B'length report "Port width mismatch" severity FAILURE;

如果外部信号的大小不正确,现在构建设计将失败。 等等...


但是我们仍然没有找到你的类型不匹配的罪魁祸首。就是这样:

    COMPONENT TwoToOneMux 
    PORT(
        bIn         : IN STD_LOGIC_VECTOR;
        bInvertedIn : IN STD_LOGIC_VECTOR;
        sel         : IN STD_LOGIC_VECTOR;
        muxOut      : OUT STD_LOGIC_VECTOR);
    END COMPONENT;
...
    M2: TwoToOneMux port map(a, b, op(0), muxTwoOut);

(同上M1)。事实证明,您使用的是多种类型:您同时使用std_logic_vectorstd_logic

“sel”显然是一位信号,最明确的表达方式是std_logic。然而,一位std_logic_vector(正如你在这里使用的)是完全合法的,只是令人困惑的地狱(尽管std_logic_vector更有意义,如果你也使用相同的风格,例如4:1和8: 1个多路复用器)。

提取1位std_logic_vector版本所需要做的就是使用正确的语法:op(0 downto 0)提取一个以相同元素开头和结尾的向量,而不是{{1}提取std_logic。