양방향 버스는 일반적으로 3 상태 버퍼를 사용하여 구현됩니다. tristate 버퍼 출력이 "Z"일 때 inout
포트에서 읽을 수 있습니다. 버퍼가 라인을 구동 할 때 출력으로 작동합니다. VHDL에서는 기본 (예 : IOBUF
, 자일링스 디바이스 용)을 직접 설치하거나 위에서 설명한대로 논리를 설명하여 합성 도구가 3 상태 버퍼를 추정하도록함으로써 VHDL에서 구현할 수 있습니다. 당신의 트라이 스테이트 컨트롤입니다
키 : 트라이 스테이트 버퍼는 동기식이 아닙니다. 신호를 올바르게 동기화하는 tristate 버퍼 전후에 수행하는 작업입니다. 이 경우 상승 클럭 에지에서 입력을 삼중 버퍼 (전송할)에 동기화하고 하강 클록 에지에서 삼중 버퍼/IOBUF에서 수신 한 등록 된 데이터를 동기화해야합니다.
샘플 디자인.
library ieee;
use ieee.std_logic_1164.all;
library unisim; -- for xilinx IOBUF
use unisim.vcomponents.all;
entity iobuffer_example is
port (
I_CLK : in std_logic; -- synchronized with bidir bus
IO_DATA : inout std_logic; -- data to/from external pin on bidir bus
I_DIR_CTRL : in std_logic; -- from other VHDL logic, controlling bidir bus direction
O_DATA_FROM_EXTERNAL : out std_logic; -- data received over bidir bus
I_DATA_TO_EXTERNAL : in std_logic); -- data to send over bidir bus
end entity iobuffer_example;
architecture io_buffer_arch of iobuffer_example is
signal data_in : std_logic;
signal data_out : std_logic;
begin
IOBUF_Inst : IOBUF
port map (
O => data_in, -- data from bidir bus
IO => IO_DATA, -- data on bidir bus
I => data_out, -- data to bidir bus
T => I_DIR_CTRL); -- 3-state enable input, high=input, low=output
Register_Input : process (I_CLK) is
begin
if (falling_edge(I_CLK)) then
O_DATA_FROM_EXTERNAL <= data_in;
end if;
end process Register_Input;
Register_Output : process (I_CLK) is
begin
if (rising_edge(I_CLK)) then
data_out <= I_DATA_TO_EXTERNAL;
end if;
end process Register_Output;
end architecture io_buffer_arch;
노트.
크로스 클록 도메인 크로싱을 염두에 두십시오. 버스에서 오는 데이터와 버스에서 오는 데이터에 대한 가능한 많은 교차점이 있습니다. 특히 내부 논리가 버스 클럭과 다른 클럭으로 구동되는 경우 더욱 그렇습니다. 나는 세부 사항없이 제안을 할 수 없다.
당신이 트라이 스테이트 버퍼의 행동 표현 대신 unisim 도서관과 IOBUF
사용하여, 당신이 뭔가를 할 수 있습니다, 합성 툴에 의해 유추하려는 경우 :
PROCESS (I_DIR_CTRL, IO_DATA)
BEGIN
IF(I_DIR_CTRL = '1') THEN
IO_DATA <= 'Z';
ELSE
IO_DATA <= data_out;
END IF;
data_in <= IO_DATA;
END PROCESS;
감사 남자! 바로 그 자리에. – JakobJ