VHDL中的类型不匹配错误?

VHDL中的类型不匹配错误?,vhdl,alu,Vhdl,Alu,我正在设计一个1位ALU,并使用结构化方法。出于某种原因,我不断得到一个类型不匹配的错误,即使我只使用std_逻辑_向量。我看不出有什么不对劲 代码如下: 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

我正在设计一个1位ALU,并使用结构化方法。出于某种原因,我不断得到一个类型不匹配的错误,即使我只使用std_逻辑_向量。我看不出有什么不对劲

代码如下: 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;
ieee库;
使用ieee.std_logic_1164.ALL;
使用ieee.std_logic_arith.ALL;
使用ieee.std_logic_unsigned.ALL;
使用ieee.numeric_std.all;
实体alu1是
港口(
a:标准逻辑向量;
b:标准逻辑向量;
op:标准逻辑向量(2到0);
结果:输出标准逻辑向量;
cout:输出标准逻辑;
零:输出标准(U逻辑);
末端alu1;
alu1的体系结构是
组件四通
港口(
andIn:标准逻辑向量;
orIn:标准逻辑向量;
addIn:IN标准逻辑向量;
bMuxIn:标准逻辑向量;
sel:标准逻辑向量;
muxOut:输出标准逻辑向量);
端部元件;
组件TwoToOneMux
港口(
bIn:标准逻辑向量;
bInvertedIn:标准逻辑向量;
sel:标准逻辑向量;
muxOut:输出标准逻辑向量);
端部元件;
分量全加器
港口(
a:标准逻辑向量;
b:标准逻辑向量;
cin:标准逻辑向量;
cout:输出标准逻辑向量;
输出:输出标准_逻辑_向量);
端部元件;
信号muxout、muxTwoOut、andOut、orOut、addOut、FMuxOut、carrout:STD_LOGIC_VECTOR:=(其他=>'0');
开始
M1:TwoToOneMux端口映射(b,不是b,op(0),MuxOut);
M2:TwoToOneMux端口图(a、b、op(0)、muxTwoOut);

andOut首先,您实际上没有给我们一个线索,类型不匹配适用于什么信号或实体,因此这将是一个解决代码问题的散点枪答案。但是有一个可能的候选人,所以请容忍我

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


第二,我很好奇你是从哪里得到这个使用列表的:请评论并让我知道

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.signed
unsigned
相同,这有助于造成混淆

有关使用数字\u std类型系统的快速教程: -使用
std\u logic\u vector
处理非类型化的值:例如,可以是有符号、无符号的字、指令、浮点或上下文中的任何其他内容 -如果值是有符号整数,则使用有符号 -如果值是usigned整数,则使用无符号 正确选择声明将减少这些类型之间的转换次数


第三,所有的
STD\u逻辑\u向量
端口和信号都是无约束的。在有些地方,无约束向量是合适的,但是。。。这个坏了

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

所以

声明两种不同类型的信号:都是
std\u logic\u 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的任何信号进行自我调整。如果mux在该信号上选择端口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\u logic\u vector
,以及
std\u logic

“sel”显然是一位信号,表达它的最清晰方式是
std_logic
。然而,一位
std_逻辑_向量
(正如您在这里使用的那样)是完全合法的,非常容易混淆(尽管
std_逻辑_向量
如果您也对例如4:1和8:1多路复用器使用相同的样式,则更有意义)


要提取1位
std_logic_vector
版本,只需使用正确的语法:
op(0到0)
提取一个在同一元素开始和结束的向量,而不是
op(0)
提取std_逻辑。

首先,您实际上没有给我们提供类型不匹配适用于什么信号或实体的线索,因此
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);