代码之家  ›  专栏  ›  技术社区  ›  Nigel Davies

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

  •  2
  • Nigel Davies  · 技术社区  · 7 年前

    请帮助我理解端口何时可用作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 回复  |  直到 7 年前
        1
  •  1
  •   Jackkilby    7 年前

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

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

    2)确保您会有编译/合成错误,特别是输出端口的编译/合成错误。 实际上,您将有多个驱动程序(实例化组件的每个输出端口)影响顶级实体的同一个信号/端口。在模拟中也很容易看到,因为您将看到在该端口出现“X”(表示同一信号有多个驱动程序)。请注意,多个输入端口可以连接到单个驱动程序(例如,顶部实体的相同输入端口、相同信号等)

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

    4)这绝对是错误的!。您没有定义要绑定到的端口或信号

    实体更改后更新:

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

    2)当inout端口用作输入时,这可能是正常的,但当您尝试将其用作输出时,可能会出现问题。对于如何描述它们的组件有很大的依赖性。如果组件使用弱逻辑值('L'&'H'),那么如果驱动强逻辑值('0'&'1'),那么它可能表现正常。最好使用中间信号端(可能是某种mux/demux)来选择/引导数据到/从适当的内部组件。

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

    4)和以前一样,这是不正确的。组件的端口未连接到任何内容。请注意,VHDL(但对verilog同样有效)是 描述 语言;你试着描述一个实际的电路(就像一个电路板上的芯片)。就像在实际电路中,你需要某种电线将芯片的一个管脚连接到另一个集成电路的另一个管脚,然后在VHDL/verilog中,你需要一个等效的“对象”来实现互连。因此,你需要定义这个对象(在这种情况下是信号),然后描述它的行为(在这种情况下,将两个组件的两个端口绑定在一起)。

    我希望这次能清楚一点

    推荐文章