VHDL: Когда порты можно использовать в качестве сигналов?

Пожалуйста, помогите мне понять, когда порты могут использоваться как сигналы в 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

person Nigel Davies    schedule 27.09.2018    source источник
comment
Порты объекта являются сигналами и могут использоваться как внутренние сигналы объекта. Компонентные порты сообщают вам, к чему вы можете подключиться - они похожи на розетку - вам все еще нужны сигналы (провода) для подключения их к другим объектам.   -  person Jim Lewis    schedule 27.09.2018


Ответы (1)


Я буду ссылаться на ваши примеры кодов как 1, 2, 3 и 4.

1) Пример 1 верен. Это эффективный способ иерархического подключения порта.

2) Наверняка у вас будут ошибки компиляции / синтеза, особенно для выходных портов. Фактически у вас будет несколько драйверов (каждый из портов вывода экземпляров компонентов), влияющих на один и тот же сигнал / порт верхнего объекта. Это будет легко увидеть и при моделировании, так как вы увидите, что на этом порте появятся 'X' (что указывает на то, что один и тот же сигнал подключен к нескольким драйверам). Обратите внимание, что к одному драйверу можно подключить несколько входных портов (например, один и тот же входной порт верхнего объекта, один и тот же сигнал и т. Д.)

3) Частично правильно! У вас та же проблема, что и в примере 2, когда несколько драйверов действуют на один и тот же сигнал.

4) Это точно неверно !. Вы не определили ни порты, ни сигналы для привязки к

ОБНОВЛЕНИЕ после изменений в сущности:

1) Это все еще верно, порт объекта может использоваться как (неявный) сигнал таким образом. Вы можете представить верхний объект как контейнер для 2 субкомпонентов, где вы «припаяли» штырьки компонентов к контактам верхнего объекта / контейнера (материал для пайки обеспечивает электрическую непрерывность)

2) Это может быть нормально, если порты inout используются как входные, но когда вы пытаетесь использовать их как выходы, могут возникнуть проблемы. Существует сильная зависимость от того, как описываются их компоненты. Если компоненты используют слабые логические значения ('L' и 'H'), тогда, если вы используете сильные значения ('0' и '1'), тогда он может вести себя нормально. Было бы лучше использовать промежуточный конец сигнала, вероятно, какой-то мультиплексор / демультиплексор для выбора / направления данных в / из надлежащего внутреннего компонента.

3) С точки зрения чисто межкомпонентного соединения это нормально. Однако с функциональной точки зрения вы должны быть уверены, что всегда есть один компонент, который действует как драйвер, а другой как приемник. В противном случае у вас будет либо неопределенное значение для внутреннего сигнала, либо «X» из-за нескольких драйверов. Однако для адресного сигнала им никто не управляет, поэтому он всегда будет «U» (не определен). Вам нужно что-то (порт в верхней сущности, процесс и т. Д.), Что приводит к какой-то ценности.

4) Как и раньше, это неверно. Порт компонента ни к чему не подключен. Обратите внимание, что VHDL (но то же самое верно и для Verilog) является языком описания; вы пытаетесь описать реальную схему (например, микросхему на печатной плате). Как и в реальной схеме, вам нужен какой-то провод для соединения одного вывода микросхемы с другим выводом другой микросхемы, тогда также в VHDL / verilog вам понадобится эквивалентный «объект» для включения межсоединения. Таким образом, вам необходимо определить объект (в данном случае сигнал), а затем описать его поведение (в этом случае свяжите вместе 2 порта из 2 компонентов).

Надеюсь, на этот раз будет немного яснее

person Jackkilby    schedule 27.09.2018
comment
Я изменил выходные порты на входящие, поэтому мой вопрос имеет больше смысла. - person Nigel Davies; 27.09.2018