0

我正在设计一个 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 的新手,我感到很头疼,所以感谢您的帮助。

4

1 回答 1

3

首先,您实际上并没有向我们提供类型不匹配适用于哪个信号或实体的线索,因此这将是对您的代码问题的分散枪回答。但是有一个可能的候选人,所以请耐心等待...

有关更多信息,有很多不好的来源,也有一些好的来源。最好的之一是 Peter Ashenden 的“Designer's Guide to 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_vector32 位和 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_vector, 和std_logic.

"sel" 显然是一个位信号,最清晰的表达方式是std_logic. 然而,一位std_logic_vector(正如您在此处使用的)是完全合法的,只是令人困惑(尽管std_logic_vector如果您也对例如 4:1 和 8:1 多路复用器使用相同的样式,则更有意义)。

提取 1 位版本所需要做的std_logic_vector就是使用正确的语法:op(0 downto 0)提取在同一元素处开始和结束的向量,而不是op(0)提取 std_logic。

于 2014-02-03T10:34:47.250 回答