2012-08-15 3 views
4

양방향 데이터 버스 (ULPI)를 통해 칩과 통신해야합니다.양방향 데이터 버스 설계

내가 읽을 수있는 한, 데이터는 상승 클럭 에지에서 ULPI 버스로 이동하고, 클럭 에지가 떨어지는 시점에서 읽습니다. 내 문제를 참조하십시오 레지스터를 읽을 때, 나는 먼저 상승 에지 (데이터 버스의 칩에 명령을 쓰는 것)에 민감해야하고 칩에서 레지스터 출력을 읽을 때 하강 에지가 있어야합니다.

내가 가장 잘 디자인하는 방법을 찾는 데 많은 어려움을 겪고 있습니다.

케이스 문이있는 하나의 프로세스로 시도했지만이 작업을하려면 내 프로세스가 상승 및 하강 에지 모두에 민감해야합니다. 이는 좋지 않다고 생각합니까? 또는?

답변

4

양방향 버스는 일반적으로 3 상태 버퍼를 사용하여 구현됩니다. tristate 버퍼 출력이 "Z"일 때 inout 포트에서 읽을 수 있습니다. 버퍼가 라인을 구동 할 때 출력으로 작동합니다. VHDL에서는 기본 (예 : IOBUF, 자일링스 디바이스 용)을 직접 설치하거나 위에서 설명한대로 논리를 설명하여 합성 도구가 3 상태 버퍼를 추정하도록함으로써 VHDL에서 구현할 수 있습니다. 당신의 트라이 스테이트 컨트롤입니다

  • T :

    3 개 여기서 다루고있는 신호가 있습니다. 이 신호는 ULPI의 프로토콜을 알고있는 동기화 논리에서 파생됩니다. 버스가 공유되기 때문에 데이터 수신과 데이터 전송 중 어떤 방법을 알고 있어야합니다.

  • I 이것은 적절한 시계에 등록 된 후 버스를 통해 전송하려는 입력 데이터입니다.
  • O 이것은 등록/동기화 이전에 버스를 통해 수신하는 출력 데이터입니다.

키 : 트라이 스테이트 버퍼는 동기식이 아닙니다. 신호를 올바르게 동기화하는 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; 
+0

감사 남자! 바로 그 자리에. – JakobJ

관련 문제