FT8U245AM (FTDI社) の制御方法 VHDL |
||||||||||||
|
||||||||||||
FTDI社のFT8U245AMはUSB-001-FIFO等に搭載されております。このチップをFPGAで制御できるように詳しく解説します。Verilog-HDLについてはこちらをご覧下さい. ▼タイミングチャートの抜粋
次に上記のタイミングチャートより、リードサイクルとライトサイクルの状態遷移図を作成します。作成するのはFPGA内部のUSBの調停回路です。USB信号は双方向なので、リードとライトを同時に行うことはできません。また、USB FIFOやターゲットのモジュールに無制限にデータを送れないようにするために、Busy信号などを考慮しなくてはなりません。 ▼リードサイクル
状態遷移図からVHDLを記述します。正論理と負論理には注意して下さい。状態遷移図をムーアマシンとして記述します。状態遷移図をHDLで記述する際には文法書等をを参照してください。 ▼USB調停回路のダウンロード USB_ARBITER.vhd ▼USBデータの方向です。通常はハイインピーダンスにしておきます。 USB_DATA <= USB_DATA_REG when( DIR = '1') else "ZZZZZZZZ"; ▼このモジュールが処理中であれば、BUSY信号を High にします。ステートマシンがライトとリード共にIDLE状態であれば、BUSYは Low です。 BUS_BUSY <= '0' when( WR_STATE="00" and RD_STATE="00" ) else '1'; ▼念のため、D-FFを入れておきます。このとき、RXF#とTXE#を負論理から正論理に変えます。D-FFを入れなくても動作します。 process( CLK, RST ) begin if ( RST ='1') then RXF_REG <= '0'; TXE_REG <= '0'; elsif( CLK'event and CLK='1') then RXF_REG <= not RXF_N; TXE_REG <= not TXE_N; else NULL; end if; end process; ▼リードサイクルのステートマシン process( CLK, RST ) begin ▼リセットはシミュレーション時に初期値を代入するためでもあります。 if ( RST ='1') then TG_DO <= "00000000"; TG_RD <= '0'; RD_N <= '1'; RD_STATE <= S0; elsif( CLK'event and CLK='1') then case RD_STATE is when S0 => ▼TG_READYとはターゲットの読み取り準備がOKという意味です。ライトサイクルと重ならないようにWR_STATE="00"としています。 if( RXF_REG='1' and TG_READY='1' and WR_STATE="00") then ▼この状態はS1時のRD_Nです。つまり、次の状態を記述しています。 RD_N <= '0'; RD_STATE <= S1; else RD_STATE <= S0; end if; when S1 => TG_DO <= USB_DATA; RD_STATE <= S2; when S2 => RD_N <= '1'; TG_RD <= '1'; RD_STATE <= S3; when S3 => TG_RD <= '0'; RD_STATE <= S0; when others => RD_STATE <= S0; end case; end if; end process; ▼ライトサイクル時のステートマシン process( CLK, RST ) begin if( RST ='1') then WR <= '1'; WR_STATE <= S0; DIR <= '0'; elsif( CLK'event and CLK='1') then case WR_STATE is when S0 => ▼ターゲットからのライト要求 if( TG_WR='1') then USB_DATA_REG <= TG_DI; WR_STATE <= S1; else WR_STATE <= S0; end if; when S1 => ▼FIFOに書込み可能 かつ リードサイクルと重ならない if( TXE_REG='1' and RD_STATE="00") then WR <= '1'; DIR <='1'; WR_STATE <= S2; else WR_STATE <= S1; end if; when S2 => WR <= '0'; DIR <= '1'; WR_STATE <= S3; when S3 => WR <= '1'; DIR <= '0'; WR_STATE <= S0; when others => WR_STATE <= S0; end case; end if; end process; エコー回路であれば、次のようなシミュレーション波形になります。
この調停回路を利用したエコー回路のページも御覧下さい。 |
||||||||||||
メールでのご質問はこちらへどうぞ | ||||||||||||
|