亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> VHDL

如何在 VHDL 中使用常量和通用映射

创建模块是重用代码的好方法,但您通常需要在整个设计中具有较小变化的相同模块。这就是泛型和泛型映射的用途。它允许您在编译时使模块的某些部分可配置。

当我们想避免一遍又一遍地输入相同的值时,就会使用常量。它们可用于在编译时定义信号向量的位宽,甚至还可以映射到通用常量。常量可以在代码中的任何地方代替信号和变量,但是它们的值在编译后不能改变。

这篇博文是基本 VHDL 教程系列的一部分。

在上一教程中,我们创建了一个总线宽度为 8 位的 4 输入多路复用器模块。但是,如果我们还需要具有不同总线宽度的类似 MUX 怎么办?将代码复制粘贴到新模块中并更改数字的唯一解决方案是吗?

幸好没有。

可以使用以下语法在 VHDL 中创建常量:
constant <constant_name> : <type> := <value>;

常量可以在VHDL文件的声明部分与信号一起声明,也可以在进程中与变量一起声明。

常量可以通过实体通过generic传入模块 关键词。为接受通用常量的模块创建实体的语法是:
entity <entity_name> is
generic(
    <entity_constant_name> : <type> [:= default_value];
    ...
);
port(
    <entity_signal_name> : in|out|inout <type>;
    ...
);
end entity;

在另一个 VHDL 文件中实例化通用模块的语法是:
<label> : entity <library_name>.<entity_name>(<architecture_name>)
generic map(
    <entity_constant_name> => <value_or_constant>,
    ...
)
port map(
    <entity_signal_name> => <local_signal_name>,
    ...
);

运动

在本视频教程中,我们将学习如何在 VHDL 中使用通用常量创建和实例化模块:

通用 MUX testbench 的最终代码 :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T16_GenericMapTb is
end entity;

architecture sim of T16_GenericMapTb is

    constant DataWidth : integer := 8;

    signal Sig1 : signed(DataWidth-1 downto 0) := x"AA";
    signal Sig2 : signed(DataWidth-1 downto 0) := x"BB";
    signal Sig3 : signed(DataWidth-1 downto 0) := x"CC";
    signal Sig4 : signed(DataWidth-1 downto 0) := x"DD";

    signal Sel : signed(1 downto 0) := (others => '0');

    signal Output : signed(DataWidth-1 downto 0);

begin

    -- An Instance of T16_GenericMux with architecture rtl
    i_Mux1 : entity work.T16_GenericMux(rtl)
    generic map(DataWidth => DataWidth)
    port map(
        Sel    => Sel,
        Sig1   => Sig1,
        Sig2   => Sig2,
        Sig3   => Sig3,
        Sig4   => Sig4,
        Output => Output);

    -- Testbench process
    process is
    begin
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= "UU";
        wait;
    end process;

end architecture;

通用 MUX 模块 的最终代码 :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T16_GenericMux is
generic(DataWidth : integer);
port(
    -- Inputs
    Sig1 : in signed(DataWidth-1 downto 0);
    Sig2 : in signed(DataWidth-1 downto 0);
    Sig3 : in signed(DataWidth-1 downto 0);
    Sig4 : in signed(DataWidth-1 downto 0);

    Sel  : in signed(1 downto 0);

    -- Outputs
    Output : out signed(DataWidth-1 downto 0));
end entity;

architecture rtl of T16_GenericMux is
begin

    process(Sel, Sig1, Sig2, Sig3, Sig4) is
    begin

        case Sel is
            when "00" =>
                Output <= Sig1;
            when "01" =>
                Output <= Sig2;
            when "10" =>
                Output <= Sig3;
            when "11" =>
                Output <= Sig4;
            when others => -- 'U', 'X', '-', etc.
                Output <= (others => 'X');
        end case;

    end process;

end architecture;

我们按下运行后 ModelSim 中的波形窗口,并在时间轴上放大:

分析

我们创建了一个具有可配置总线宽度的 MUX 模块。现在,总线宽度只在一个地方指定,在测试台文件中。我们可以轻松更改它以创建具有不同总线宽度的 MUX。

如果我们将波形与上一教程中的波形进行比较,我们可以看到行为是相同的。这是因为我们根本没有改变代码的行为。

外卖

转到下一个教程 »


VHDL

  1. 如何在 VHDL 中的进程中使用过程
  2. 如何在 VHDL 中使用不纯函数
  3. 如何在 VHDL 中使用函数
  4. 如何在 VHDL 中使用过程
  5. 如何在 VHDL 中使用常量和通用映射
  6. 如何在 VHDL 中使用端口映射实例化
  7. 如何在 VHDL 中使用 Case-When 语句
  8. 如何在 VHDL 中使用有符号和无符号
  9. 如何使用最常见的 VHDL 类型:std_logic
  10. 如何在 VHDL 中使用条件语句:If-Then-Elsif-Else
  11. 如何免费安装 VHDL 模拟器和编辑器
  12. PIC18 微控制器:它是什么以及如何使用它