如何在 VHDL 中使用端口映射实例化
模块是 VHDL 代码的独立单元。模块通过 entity 与外界通信 . 港口地图 是模块实例化的一部分,您可以在其中声明模块的输入和输出应连接到哪些本地信号。
在本系列之前的教程中,我们一直在主 VHDL 文件中编写所有代码,但通常我们不会这样做。我们创建逻辑的目的是在 FPGA 或 ASIC 设计中使用它,而不是用于模拟器。
为在模拟器中运行而创建的 VHDL 模块通常没有输入或输出信号。它是完全独立的。这就是为什么我们设计的实体是空的。 entity之间一直没有任何东西 标签和 end entity; 标记。
这篇博文是基本 VHDL 教程系列的一部分。
没有任何输入或输出信号的模块不能用于实际设计。它的唯一目的是允许我们在模拟器中运行 VHDL 代码。因此它被称为测试台 .要模拟具有输入和输出信号的模块,我们必须实例化 它在测试台中。
模块和测试平台通常成对出现,它们存储在不同的文件中。一种常见的命名方案是将测试平台称为模块名称,并附加“Tb”,并将架构命名为“sim”。如果模块被称为“MyModule”,则测试平台将被称为“MyModuleTb”。因此,文件名变为“MyModuleTb.vhd”和“MyModule.vhd”。
在测试台代码的帮助下,我们可以验证模块在模拟环境中是否正常工作。被测试的模块通常被称为被测设备 (被测物)。
模块也可以在其他模块中实例化。将代码划分为模块允许它被多次实例化。您可以在同一个设计中创建一个模块的多个实例,并且可以在多个设计中重复使用它。
VHDL 中带有端口的实体的语法是:entity <entity_name> is
port(
<entity_signal_name> : in|out|inout <signal_type>;
...
);
end entity;
在另一个 VHDL 文件中实例化此类模块的语法为:<label> : entity <library_name>.<entity_name>(<architecture_name>) port map(
<entity_signal_name> => <local_signal_name>,
...
);
<label> 可以是任何名称,它将显示在 ModelSim 的层次结构窗口中。 <library_name> 对于一个模块是在模拟器中设置的,而不是在 VHDL 代码中。默认情况下,每个模块都编译成 work 图书馆。 <entity_name> 和 <architecture_name> 必须与我们创建实例的模块相匹配。最后,每个实体信号必须映射到一个本地信号名称。
还有其他方法可以在 VHDL 中实例化模块,但这是显式实例化的基本语法。
运动
在本视频教程中,我们将学习如何在 VHDL 中创建和实例化模块:
MUX testbench 的最终代码 :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T15_PortMapTb is
end entity;
architecture sim of T15_PortMapTb is
signal Sig1 : unsigned(7 downto 0) := x"AA";
signal Sig2 : unsigned(7 downto 0) := x"BB";
signal Sig3 : unsigned(7 downto 0) := x"CC";
signal Sig4 : unsigned(7 downto 0) := x"DD";
signal Sel : unsigned(1 downto 0) := (others => '0');
signal Output : unsigned(7 downto 0);
begin
-- An instance of T15_Mux with architecture rtl
i_Mux1 : entity work.T15_Mux(rtl) 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 T15_Mux is
port(
-- Inputs
Sig1 : in unsigned(7 downto 0);
Sig2 : in unsigned(7 downto 0);
Sig3 : in unsigned(7 downto 0);
Sig4 : in unsigned(7 downto 0);
Sel : in unsigned(1 downto 0);
-- Outputs
Output : out unsigned(7 downto 0));
end entity;
architecture rtl of T15_Mux 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 的模块是我们打算在设计中使用的,而测试台的唯一目的是允许我们在模拟器中运行它。测试台中有一个进程使用wait 用于在模拟中创建人为时间延迟的语句。设计模块没有时间概念,只对外部刺激做出反应。
我们将测试平台的架构命名为 sim , 用于模拟。设计模块的架构命名为rtl ,代表寄存器传输级别。这些只是命名约定。当您看到具有这样名称的文件时,您会立即知道它是测试台还是设计模块。不同的公司可能有不同的命名约定。
外卖
- 输入和输出信号在模块的实体中指定
- 没有输入/输出信号的模块称为测试台 ,并且只能在模拟器中使用
- 带有输入/输出信号的模块通常不能直接在模拟器中运行
转到下一个教程 »
VHDL