6

双方向データバス (ULPI) を介してチップと通信する必要があります。

私が確認できる限り、データは立ち上がりクロック エッジで ULPI バス上にシフトアウトされ、立ち下がりクロック エッジで読み取られます。私の問題は、レジスタを読み取るときに、最初に立ち上がりエッジ (データバス上のチップにコマンドを書き込むため) に敏感である必要があり、次にレジスタ出力をチップからバスに読み取るときに立ち下がりエッジに敏感である必要があることです。

これを最適な方法で設計する方法がわかりません。

ケース ステートメントを持つ 1 つのプロセスで試してみましたが、これが機能するためには、プロセスが立ち上がりエッジと立ち下がりエッジの両方に敏感である必要があり、これは良くないと思います。それとも本当に大丈夫?

4

2 に答える 2

6

双方向バスは通常、トライステート バッファを使用して実装されます。inoutトライステート バッファ出力が "Z" の場合、ポートから読み取ることができます。バッファがラインを駆動している場合、出力として機能します。VHDL では、プリミティブ (IOBUFザイリンクス デバイスなど) を直接インスタンス化するか、上記のロジックを記述して合成ツールにトライステート バッファーを推論させることで、これを実装できます。

ここで扱っている信号は 3 つあります。

  • Tこれはあなたのトライステートコントロールです。この信号は、ULPI のプロトコルを知っている同期ロジックから派生します。これは、バスが共有されているため、データを受信するタイミングとデータを送信するタイミングを知る方法が必要です。
  • Iこれは、適切なクロックによって登録された後、バスを介して送信したい入力データです。
  • Oこれは、登録/同期の前に、バスを介して受信している出力データです。

キー: トライステート バッファは同期ではありません。信号を適切に同期させるのは、トライステート バッファーの前後で行うことです。この場合、クロックの立ち上がりエッジでトライステート バッファー (送信される) への入力を同期し、クロックの立ち下がりエッジでトライステート バッファー/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;
于 2012-08-15T16:06:53.720 に答える