VHDL:什么时候可以将端口用作信号?

时间:2018-09-27 10:18:31

标签: vhdl fpga xilinx-ise

请帮助我了解何时可以将端口用作VHDL中的信号。

我之所以问这个问题,是因为我正在使用端口将数据从Xilinx ISim中的一个组件移动到另一个组件,但是数据在其目的地仍然是未定义的。如果我像下面的第一个和第三个示例中那样在没有显式分配语句的情况下通过端口到端口的连接来推断数据传输,可能会引起我的问​​题。

我相信这是对来自实体的端口的有效使用,作为连接到所包含组件的端口的信号。

-- Example 1 - Use ports instead of signals
entity user is
  port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: in    std_logic_vector(12 downto 0)
  );
end user;    
architecture Behavioral of user is
  -- Component Port Definitions
  component memory
    port(
    mem_data_bus   : inout std_logic_vector(15 downto 0);
    mem_address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory;
begin
  -- some logic
  -- Instantiate thing
  a_memory : memory
    port map(
      mem_data_bus     => data_bus,
      mem_address_bus  => address_bus
    );
end architecture;

我不确定这是否有效。是否需要额外的信号来将组件连接在一起,还是可以使用实体端口? (我意识到将inout端口连接在一起可能会出现问题,但这是关于何时可以将端口用作信号的问题。

-- Example 2 - connect ports to multiple components
entity user is
  port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: in    std_logic_vector(12 downto 0)
  );
end entity user;
architecture Behavioral of user is
  -- Component Port Definitions
  component memory_a
    port(
    ma_data_bus   : inout std_logic_vector(15 downto 0);
    ma_address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory_a;
  component memory_b
    port(
    mb_data_bus   : inout std_logic_vector(15 downto 0);
    mb_address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory_b;
begin
  -- some logic
  -- Instantiate memories
  a_memory_a : memory_a
    port map(
      ma_data_bus     => data_bus,       
      ma_address_bus  => address_bus
    );
  a_memory_b : memory_b
    port map(
      mb_data_bus     => data_bus,
      mb_address_bus  => address_bus 
    );
end architecture

如果实体端口定义不包括端口,则需要信号,并且不能从端口推断出信号。

-- Example 3 - Use signals for inteconnection as no suitable ports available
entity user is
end user;

architecture Behavioral of user is
  -- Component Port Definitions
  component memory_a
    port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory_a;
  component memory_b
    port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory_b;
  signal data_bus_sig  : std_logic_vector(15 downto 0);
  signal address_bus_sig  : std_logic_vector(12 downto 0);
begin
  -- some logic
  -- Instantiate memories
  a_memory_a : memory_a
    port map(
      data_bus     => data_bus_sig,
      address_bus  => address_bus_sig
    );
  a_memory_b : memory_b
    port map(
      data_bus     => data_bus_sig,
      address_bus  => address_bus_sig 
    );
end architecture

这是错误的,因为未定义信号或实体端口。

-- Example 4 - WRONG? - Try to infer ports
entity user is
end user;

architecture Behavioral of user is
  -- Component Port Definitions
  component memory_a
    port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: in    std_logic_vector(12 downto 0)
    );
  end component memory_a;

  component memory_b
    port(
    data_bus   : inout std_logic_vector(15 downto 0);
    address_bus: out   std_logic_vector(12 downto 0)
    );
  end component memory_b;
begin
  -- some logic
  -- Instantiate memories
  a_memory_a : memory_a
    port map(
      data_bus     => data_bus,  
      address_bus  => address_bus
    );
  a_memory_b : memory_b
    port map(
      data_bus     => data_bus,  
      address_bus  => address_bus
    );
end architecture

1 个答案:

答案 0 :(得分:1)

我将您的示例代码称为1、2 3和4。

1)示例1是正确的。这是一种以分层方式连接端口的可行方法。

2)确保您会遇到编译/合成错误,尤其是对于输出端口。 实际上,您将有多个驱动程序(实例化组件的每个输出端口)影响顶部实体的相同信号/端口。在仿真中也很容易看到,因为您会在该端口上看到“ X”(表明多个驱动器指向同一个信号)。请注意,多个输入端口可以连接到单个驱动器(例如,顶部实体的相同输入端口,相同的信号等)

3)部分正确!您遇到与示例2中相同的问题,其中多个驱动程序作用于同一信号。

4)这绝对是错误的!您尚未定义要绑定的端口或信号

实体更改后更新:

1)仍然正确,这样可以将实体端口用作(隐式)信号。您可以想象顶级实体就像一个用于2个子组件的容器,在其中您已将组件的引脚“焊接”到顶部实体/容器的引脚(焊接材料提供了电气连续性)

2)当将inout端口用作输入时,这可能是好的,但是当您尝试将then用作输出时,可能会出现问题。在很大程度上描述了它们的组成方式。如果组件使用弱逻辑值(“ L”和“ H”),则如果驱动强值(“ 0”和“ 1”),则可能表现正常。最好使用中间信号端(可能是某种多路复用器/多路分解器)来选择/引导来自适当内部组件的数据。

3)从纯互连的角度来看,这是可以的。但是,从功能角度来看,您必须确保始终有一个组件在充当驱动程序,另一个在充当接收程序。否则,由于多个驱动器,您将在内部信号上具有未定义的值或“ X”。但是,对于地址信号,没有人在驱动它,因此它将始终为“ U”(未定义)。您需要某种东西(顶级实体中的端口,流程等)来驱动某种价值。

4)和以前一样,这是不正确的。组件的端口未连接任何东西。请注意,VHDL(但对verilog同样有效)是一种描述语言;您尝试描述实际电路(例如由PCB上的芯片制成的电路)。就像在实际电路中一样,您需要某种导线将芯片的一个引脚连接到另一个IC中的另一个引脚,然后在VHDL / verilog中,您也需要一个等效的“对象”来实现互连。因此,您需要定义对象(在这种情况下为信号),然后描述其行为(在这种情况下,将2个组件的2个端口绑定在一起)。

我希望这次更加清晰