VHDL: Когда порты могут использоваться в качестве сигналов? - PullRequest
0 голосов
/ 27 сентября 2018

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

Я не уверен, что это допустимо.Требуются ли дополнительные сигналы для соединения компонентов или могут быть использованы порты объекта?(Я понимаю, что может быть проблема присоединения к входящим портам вместе, но этот вопрос о том, когда порты могут использоваться в качестве сигналов).

-- 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 голосов
/ 27 сентября 2018

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

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

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

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

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

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

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

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

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

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

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

...