ADCをFPGAに接続します。 機能、困難、実装


みなさんこんにちは! この記事では、ADCチップとFPGAクリスタルの接続について説明します。 回路ノードの接続の主な特徴が考慮され、最新のADCとその特性が提示されます。 この記事では、最小限の時間コストでADCをFPGAに迅速かつ正しく接続する方法に関する実用的なヒントを提供します。 さらに、1つまたは別のADCを接続する原理について説明します。入力FPGAバッファーとその基本コンポーネント(トリガー、IODELAY遅延ノード、ISERDESシリアライザーなど)を検討します。 より詳細には、VHDLのプログラムコードの例を使用して、ADCからのデータの高品質受信に必要な基本要素の概要を実行します。 これは、入力バッファ、シングルチャネルおよびマルチチャネルシステム用のデータパッキングノード、FIFOベースのデータ同期およびデータ送信モジュール、SPIインターフェイスを使用するADCプログラミングノード、およびデータ周波数合成ノード-MMCM / PLLです。 また、この記事では、アナログおよびデジタル回路の主要な外国および国内メーカーの完成したデバイス(FMC規格)の概要を説明します。 記事の最後に、マルチチャネルADC回路からのデータの受信機のユニバーサルノードのソースコードへのリンクがあります。 コードはシンプルで構成が柔軟で、VHDL言語で表示され、Xilinx 7シリーズ以上のFPGAでシャープになりますが、他のFPGAでも使用できます。

記事の概要



A / Dコンバーター


ADCは、幅広い種類の無線エンジニアリングタスクに使用されます。アナログ信号をデジタル形式に変換する必要があるすべてのデバイスで使用されます。 オーディオおよびビデオシステム、水音響学および水通信の問題(低サンプリング周波数、高ビット深度)、無線周波数範囲を変換するデバイス(DDC / DUC回路)、レーダーおよび無線ナビゲーション(高サンプリング周波数、中ビット)で使用できますデータ)。 ADCは、デジタル電圧計およびマルチメーター、コンピューターのビデオ入力ボード、ビデオカメラ、音声認識システム、サウンドデバイスで使用されます。 高速ADCは、オシロスコープおよびスペクトルアナライザーで使用され、実験装置および医療機器で使用されます。 多くの場合、ADCは高速でデータを収集および処理するタスクで使用されます。

ご覧のとおり、ADCチップはA / Dデバイスの不可欠な部分です。 現代の世界では、ADCがないデバイスを見つけることは非常に困難です。 ADCの古典的な外観を次の図に示します。


これは、AD9684チップのデータシートから取られた簡略図です。 2つの差動アナログ入力VINAおよびVINBCLKクロック入力、SPI制御、パラレル出力バスD0-D13 、マイクロ回路のさまざまなコンポーネントの電圧ポイント、同期ブロックSYNCおよびその他の制御信号が含まれています。

ADCのマイクロ回路は、ユーザーの最終的な選択に依存し、ADCの範囲を決定する特定のパラメーターのセットによって特徴付けられることは明らかです。 デジタル部では 、これはデータ転送速度(有効クロック周波数)であり、数十kHzから数GHzの範囲です。 ADCの出力でのデータ容量-最新のデバイスでは8〜32ビットのデータ。 アナログ側では、これらは信号対雑音比( SNR )とスプリアスフリーダイナミックレンジ( SFDR )であり、通常はデシベルで表されます(通常のSNRレベルの範囲は70〜80 dB、SFDRレベルは約90 dBc)。 ADCを選択する際の重要なパラメーターは、消費電力(W)、1つのハウジング内のチャンネル数、デジタルノードとのインターフェイス、そしてもちろんコンポーネントのコストです。

あらゆる種類のADCおよびDACチップの製造分野の巨人である有名なサイトAnalog Devicesから抜粋した表の例を使用して、最新の高速ADCとその特性を検討してください。 便宜上、表には、マイクロ回路の最も重要な特性が要約されています。これらは、デジタルデバイスとの通信インターフェイスのタイプによって分けられ、情報転送の速度(クロック周波数)に応じて大きな値から小さな値に配置されます。


この表は、LVDS規格に従ってデータを並列形式で送信する4つのトップエンドマイクロチップを示しています。 データの容量は14〜16、チャネル1〜2、最大サンプリング周波数は500 MHzです。 平均SNRとSFDRは、それぞれ70 dBFSと90 dBcです。 シリアルデータバス(シリアル)を使用する一部の回路では、特性はほぼ同じです。 JESD204B伝送インターフェイスを使用し、ギガビットラインを介してFPGAに接続する最新のADCチップの場合、クロック周波数ははるかに高くなりますが、アナログ特性はわずかに悪くなります(少なくともデジタルデータ容量が低いため、12ビットと14ビットです)。 この記事で 、ギガビット回線を介したADCのFPGAクリスタルへの接続については説明しません 。 超小型回路を接続するためのシンプルで十分に研究されたオプションに焦点を当てます-LVTTL、LVDS、LVCMOS、LVPECLなどのデータ転送インターフェースを備えたシリアルおよびパラレルバス。 特に、LVDSバスでデータを転送する興味深い方法は、PCBトレースの単純さ、低コストパフォーマンス、低ノイズおよび電力損失、および高速データ転送速度によって区別されます。 FPGAは、シリアライザ/デシリアライザを使用してシリアルバスデータを受信します。 パラレルバスの場合、すべてがはるかに単純であり、データはそのまま受け入れられます。

アナログデバイスとデジタルデバイスのペアリングの過程で、次のADCチップを習得する必要がありました。 これらはすでに廃止されていますが、まだ使用されています-AD9224、AD6644ST-65、AD9244、LCT2207、ADS5474、AD9432BST-105、AD7475BR 、最新レベルのマイクロチップ-AD9430BSV、ADS54RF、AD9467、ADC12D1800、AD9680など 私の仕事の領域はアナログ回路に部分的にしか関係していないため、完成したアナログデジタルモジュールのパフォーマンスを改善する方法についてお話しすることはできません。 また、アナログパスの定性的な構成や、最良のアナログ性能(SNR、SFDR)を達成するための1つまたは別の回路コンポーネントを選択するための方法論についてアドバイスすることはできません。 しかし、この記事のフレームワーク内でADCをFPGAクリスタルに接続し、さらにデータを処理するという質問に答えようとします。

ADCモジュールの例


次の図は、ロシアおよび海外のメーカーからのアナログからデジタルへのデータ変換用の完成した高品質モジュールの最新の例を示しています。 それらはすべて、1つまたは複数のアナログ接続入力と、データプロセッサがインストールされているキャリアボード(通常はFPGA)に接続するためのFMC(FPGAメザニンカード)アダプターコネクタを備えています。 FMCは、モジュールアーキテクチャで製品を接続するための主要な標準の1つです。 多くの場合、アナログ部分はメザニンボード(メザニンボード)にインストールされ、データ処理を実行する中央ユニットはキャリアモジュール(キャリアボード)にインストールされます。これは1つ以上のFPGAおよび/またはシグナルプロセッサです。 デバイスの外国メーカーのうち、2つの主要な製造会社を区別する必要があります-これらは4dspとhitechglobalです。 検索の最初の行にあるGoogleの国内メーカーのうち、CJSC Scan Engineering Telecom、CJSC Instrumental Systemsなど。 記事の著者は提示されたモジュールについて責任負わ 、特定の会社の製品を宣伝するために記事を使用しません

HTG-ADC16 。 次の特性があります(公式サイトから取得)。



FMC104:4チャンネル250 MSPS @ 14ビット 特性(情報の冗長性のために削除されたもの):



このモジュールは、4つのADCチャネルと1.8V電源を備えています(HP Xilinx FPGAが使用されています)。

FMC120:4チャンネル250 MSPS @ 14ビット 特徴:



FMC140:4チャンネル16ビット370MSPS A / D 次の特性があります。



このモジュールは、4つの高速ADCチャネル、16ビットのデータ容量、およびJESB204B通信を備えています。

SFM-4A1000モジュール 特徴:



モジュールの特徴は、国内開発、4つの高速ADCチャネル、2 GHz帯域、およびJESB204Bインターフェイス交換です。

FMC212x4GDAモジュール 特徴:



このモジュールは、2つの高速ADCチャンネル、最大2 GHzの信号帯域幅、JESB204Bインターフェイスでの交換、ビルトインDDCチップ、4つのDACチャンネルを備えています。

FMC816x250Mモジュール 特徴:



このモジュールは、8つのADCチャネル、デュアルモジュールを備えています。

ご覧のとおり、FMC規格のアナログ-デジタル変換モジュールの多くは類似しており、ほとんど同じ特性を持っています。これらの特性は、取り付けられたADCおよびDACチップによって決まります。 モジュールの最終的な選択は、エンドユーザーが解決する必要のあるタスクによって決まります。

ADCをFPGAに接続する


この記事のメインセクションであるADCチップをFPGAクリスタルに接続することに進みましょう。 データ転送インターフェース( LVTTL、LVCMOS、LVDS)を使用して、ADCをパラレルおよびシリアルバスに接続することを検討してください。 この記事でJESD204Bインターフェースを介したADCの接続については考慮しません。これは、複数の本格的な記事を取り上げる別のトピックの資料であるためです。 さらに、JESD204Bは、ADCチップを接続するための「クラシック」オプションと実装が大きく異なるため、より詳細な検討が必要です。

既知のように、FPGA I / Oバンク(ピングループ)は、水晶メーカーによって境界が決定されるさまざまな供給電圧に設定できます。 最新のザイリンクスFPGAでは、適用される電圧範囲はバンクのタイプによって異なります。 銀行には2つの主なタイプ(ザイリンクス)があります-HP (高性能)とHR (標準と食品の選択肢が豊富な銀行)。 たとえば、Xilinx Series 7チップでは、HRバンクの電圧範囲は1.2〜3.3Vであり、HPバンクの電圧範囲は1.2〜1.8Vです。 さらに、さまざまな標準データ転送インターフェイス用にバンクピンをプログラムできますが、標準の最終的な選択は、FPGAバンクの電圧とリモートデバイスとFPGAの接続方法という2つのルールによって決まります。 一方、FPGAバンクの供給電圧を選択する際には、水晶のファミリが重要な要素です。 したがって、Kintex-7では、LVDS 25規格を使用して2.5Vの電圧でバンクに電力を供給することができ、多くのVirtex-7 FPGAでは、接続規格は排他的にLVDS 18であり、バンクは1.8Vの電圧で駆動されます。 この点で、いくつかのアナログモジュールとキャリアボードを異なるFPGAファミリとペアリングする問題があります。 そのため、サードパーティのメーカーからADCモジュールやキャリアボードを購入する場合は、それらが標準および供給電圧と互換性があることを確認する必要があります。 原則として、データ転送インターフェイスはプロジェクトソースコードではなく、制限ファイル( UCFまたはXDC )に書き込まれます。これにより、構成の柔軟性と他のプロジェクトでのソースコードファイルの再利用が可能になります。

プロジェクトの最上位ファイルの構造図(およびLVTTL / LVCMOS / LVDS標準に従ってADCチップからデータを受信するために使用される内部ユニット)を次の図に示します。


次の要素が含まれます。


これらのノードに加えて、上位レベルでは、MMCMに基づく周波数合成モジュール(標準FPGAリソース)が使用されます。 また、IDELAYCTRLコンポーネントは、IODELAYノードの遅延を制御するために使用されます。

FPGAの回路の構成が依存する最上位ファイルの主なパラメーター:


その他のオプション。

ADCレシーバーのトップレベルファイルのコードの一部は次のようになります。

xFIFO: CTRL_FIFO_CONFIG generic map ( DATA_WIDTH => PACK_OUT, ADDR_WIDTH => FIFO_ADDR ) port map ( reset => reset, wr_clk => clk_pack, rd_clk => sys_clk, data_i => do_pack, data_o => do_fifo, rd_en => cs_fifo, wr_en => dv_pack, empty => ef_fifo, full => ff_fifo ); 

これにより、FIFOノードが接続され、デバイスのシステムバスとデータが同期されます。 マルチチャネルおよびマルチビットバッファ回路でのIODELAYのプログラミング遅延は次のとおりです。

 ---- Data delays ---- x_dat_dd <= x_dat_do(conv_integer(unsigned(dl_chan))) when rising_edge(dl_clk); x_dat_in(conv_integer(unsigned(dl_chan)))(conv_integer(unsigned(dl_muxs))) <= dl_dat_in when rising_edge(dl_clk); x_dat_ce(conv_integer(unsigned(dl_chan)))(conv_integer(unsigned(dl_muxs))) <= dl_dat_ce when rising_edge(dl_clk); x_dat_ld(conv_integer(unsigned(dl_chan)))(conv_integer(unsigned(dl_muxs))) <= dl_dat_ld when rising_edge(dl_clk); 

dl_chanは選択されたADCチャネルであり、 dl_muxsはADCの選択されたビットです。 これは、データの各ビットを個別にプログラムするために行われます。

各ノードを詳細に検討してください。

注: FPGAとDAC(デジタル-アナログコンバーター)を接続する場合、状況は反映されます。 同じことを行う必要がありますが、順番は逆です。 この記事では、FPGAのDACへの接続は考慮されていません。

入力レシーバー


外部PCB信号とFPGAロジック間の接続の主要な要素が含まれています。 これは、FPGAピンからIOBUF入力バッファロジックへのIPADバッファです。 データ転送インターフェイスに応じて、バッファは差動(IBUFDS)およびユニポーラ(IBUF)になります。 多くのバッファでは、必要な標準への厳密なバインドが可能です。または、属性を介して出力信号のタイプを設定することができます。 たとえば、 IOBUFD属性を使用してIBUFDSの場合 、ソースコードで標準の「 LVDS_25 」を事前定義および設定できます。

バッファに続いて、 IODELAY信号遅延遅延制御ユニットがインストールさパラレルデータバスのエッジを揃え、最初にADCのマルチチャネルノードをFPGA接続に調整します。 IODELAYはプログラム可能なFPGAリソースであり、遅延値はデフォルト設定で固定して決定するか、0〜31の従来の時間値の範囲でプログラムできます(図はFPGAチップのデータシートによって決定されます)。 プログラミングは、いくつかの信号を使用して基本的な方法で行われます。 プログラミングアルゴリズムの詳細な分析については説明しませんが、詳細については、この記事の最後にある参照リストのドキュメントを参照してください。 IODELAYノードの場合 、各FPGAクロック領域の遅延をリアルタイムで較正する特別なIDELAYCTRL遅延制御ノードを接続する必要があります 。 水晶の温度、電源電圧、FPGA負荷の影響を排除するために、IDELAYCTRLノードは独立したREFCLK信号によってクロックされます。 このクロック信号は、各FPGAクロック領域のすべてのIODELAYノードで同量の遅延( TAP )を提供します。 各クロック領域に独自のチューニング値が必要な場合、いくつかのIDELAYCTRLノードがFPGAチップで初期化されます。 REFCLKクロック信号は、FPGAの外部にインストールされた外部ジェネレーターから供給するか、 FPGAチップのMMCMノードで周波数を合成することで取得できます。


IODELAY遅延ノードに続いて、データ転送モードがDATA_RATE = " SDR "の場合、 FDトリガーを設定できます。 このトリガーは、オプションで入力バッファに配置され、アナログモジュールからのデータに付随するADCの周波数によってクロックされます。 DATA_RATE =“ DDR ”モードでは、トリガーが1つのデータ入力と2つの出力を持つIDDRの洗練されたバージョンに置き換えられます。 出力からいくつかのモードでデータを出力することは可能ですが、実際には1つだけを使用しました。「 SAME_EDGE_PIPELINED 」では、出力Q1およびQ2からのデータがクロック信号の同じエッジで出力されます。


最後に、最も興味深いオプションは、IODELAYノードをISERDESデータ逆シリアル化モジュールに接続することです 。 シリアライザノードは、FPGA入力バッファの複雑な要素であり、次のオプションが含まれています。


ノードは、いくつかの信号によってクロックされます。これは、受信したCLKデータの高い周波数の信号と、DATA_WIDTHパラメーターによって決定された数で割ったCLKDIV信号です。 分割はFPGAの外部で発生する可能性がありますが、実際には、MMCMと呼ばれるFPGAチップ自体で周波数シンセサイザーが使用されます。 したがって、CLK周波数のシリアル信号がISERDESノードに入力され、低減された周波数CLKDIV = CLK / DATA_WIDTHのパラレルデータストリームがISERDESノードの出力で取得されます。 クロック周波数は、リージョナルバッファーBUFR 、分係数BUFR_DIVIDE = 1-8の値、または広範囲にプログラムされた周波数シンセサイザーMMCMのノードを使用して分周できます。


クロックエッジとデータの一致の影響を排除するには、MMCMのIODELAYノードと周波数調整だけでは必ずしも十分ではありません。 多くの場合、この問題の代替ソリューションを探す必要があります。 幸いなことに、この解決策は私の同僚によって発見されました。彼は最近、彼の記事( Useful Properties of Jitter )でそれについて話しました。

上記のすべてのノード(MMCMを除く)は入力FPGAバッファーの一部であり、チップの論理リソースを占有しません。 FD / IDDR / ISERDES出力から、データは既にロジックエレメントに送られます。これは、MMCMノードでADCサンプリング周波数を通過した後に得られた周波数にデータをプライマリ再同期するための小さなトリガーまたはFIFOです。 場合によっては、再同期は使用されず、データはADCのサンプリング周波数と直接同期されます。 次の図は、ISERDESデバイスのADCチップからのシリアルデータを処理するタイミング図を示しています。 入力クロック周波数、入力データのシリアル形式、およびパラレルコードに変換されたデータが表示されます。


したがって、構成に応じて、図に示すように、入力バッファーで3つの信号パスが可能です。


A) SDRモード-データはパラレルバスで受信され、各FPGAは独自のFPGAバッファーを使用し、
B) DDRモード-データはパラレルバスで受信され、データは2倍の周波数でクロックされます。
C) SERDESモード-データはシリアルバスで受信されます

データパッカー


このノードは、ADCからデータを受信するためのシングルチャネルおよびマルチチャネル方式で使用されます。 その主な目的は、FPGA内で使用される内部バスに適した形式でデータパックすることです。 内部バスの容量は、開発者または企業標準によって決定されます。 パッカーの出力での一般的なビット値は、32、64、128、256、512ビットのデータです。 場合によっては、パッカーが構成されていない可能性があります。 入力チャネルの数、入力および出力データバスパッカーの幅によって異なります。 たとえば、入力ビット深度= 16ビットの4チャネルソースの場合、出力バスビットがWOUT = WIN * NCHAN = 16 * 4 = 64ビット未満のリパッカーを編成することはできません。 入力と出力のビット深度が同じ単一チャネルデータソースの場合、データは16ビットのパックで64ビットのビットグリッドに順次パックされます。 つまり、ADCの最初のサンプルはビットフィールド[15:0]、2番目のサンプル-[31:16]、3番目-[47:32]、4番目-[63:48]を取ります。 さらに、サンプルは出力データグリッドの最下位から最上位にビットフィールドを周期的に占有します。 別の例。 2つのデータチャネルが使用され、入力と出力のビット幅は同じままです(それぞれ16ビットと64ビット)。 リモートデバイスのデータ収集システムに含まれるチャネルが1つだけの場合、上記の例に示すようにパッキングが行われ、どのチャネルがオンになっているかは関係ありません。 集録システムに両方のチャネルが含まれている場合、データはビットグリッドの若い部分から古い部分にペアでパッケージ化されます。 最初のチャンネルの最初のカウントダウンは位置[15:0]に、2番目のチャンネルの最初のカウントダウンは位置[31:16]に、最初のチャンネルの2番目のカウントダウン-[47:32]、2番目のチャンネルの2番目のカウントダウン-[63:48]になります。 実践が示しているように、これは、特定の伝送チャネルが切断された場合に、マルチチャネル処理でデータをパックするための最も便利なオプションです。 注:チャネルの数は、2の累乗の倍数-1、2、4、8などでなければなりません。 このノードを実装して理解するのは難しいように思えるかもしれませんが、プロジェクトでいくつかのアプリケーションを実行した後、ここには複雑で珍しいものは何もないことがわかります。

次の図に、モードでのデータパッカーノードの動作のタイミング図を示します。NCHAN = 1、 WIN = 8、 WOUT = 32。


赤い線は、出力バスにデータをパックするプロセスを示しています。これには、4つのデータサンプルを受信した後の解像度信号DVAL = 1が伴います。

データストリームシンクロナイザー


このノードは、プリミティブFIFOスキームに基づいて構築されており、1つの重要で単純な目的があります。データストリームをサンプリング周波数CLK_ADCから処理周波数またはSYS_CLKデバイスの内部バスの動作周波数(システムクロック周波数)に変換します。 簡単にするために、 Xilinx Core GeneratorでFIFOノードを作成できますが、理想的には、任意のバス幅( FIFO_WIDTH )およびメモリの深さ( FIFO_DEPTH )に対して柔軟に構成できる独自のモジュールを作成する方が良いでしょう。 次の図は、FIFOノードの動作のタイミング図、入力データと出力データ、および空( empty )およびfull( full )FIFOのフラグを示しています。 FIFO ADCの通常動作では、FULLフラグは常に0である必要があります。これは、ADCからのデータ受信の正確さとオーバーフローがないことを示します。 フラグFULL = 1の場合、リモートハンドラーによるデータ受信の速度が不十分であるか、ADCの速度が選択したシステムに対して速すぎます。


次の図は、Plan Ahead環境のFIFOノードの概略図を示しています。


FIFOはデュアルポートメモリに基づいて構築されていることがわかります。 グレーコードのデータはメモリアドレスバスに送信されます。図では、これらは読み取りと書き込みの2つのノードです。 これにより、高周波でのビットエラーを減らすことができます。 グレイコード内の隣接する値は、1ビット位置のみが異なります。 FIFOフラグのロジックは、グレーカウンターのモジュールの値によって決定され、レジスターは出力でのノードのクロック周波数を上げるために使用されます。

インナータイヤ


質問が発生します- 収集およびパッケージ化されたデータは次にどこに行きますか? 答えは簡単です。PCI/ PCIe、USB、イーサネット、SRIO、SATAインターフェースの助けを借りてデータは最終目標に到達し、そこで処理され、すべての情報が収集されます。 このリンクの前に、FPGA内にデジタル信号処理ユニット(DSP)、たとえばDDC、DUC、FFT / IFFTなどがあります。さらに、データはDDR3 / DDR4などの大きな外部メモリにバッファリングできます。 これは、大量の情報フローを高速で処理するために使用される頻繁な手法です。 この場合、外部メモリは大きなFIFOをシミュレートします。 外部メモリを使用してFPGAを制御するには、特別なコントローラーを使用します。これらのコントローラーは、原則としてアクセス可能で、使用するために開いています。 ザイリンクスの場合、それらはIPコアジェネレーターにあります。

特に、開発者はADCレシーバーのすべてのリソースを管理するための独自の有限状態マシンを作成する必要があります:これはIODELAYの遅延構成、MMCM周波数シンセサイザーのプログラミング、ADCおよびDACモジュールへのSPIコマンドの送信、ADCからのデータ収集の開始と終了の制御、アクティブチャネルの数の制御、外部DDRメモリなどの使用。 誰もが独自のアーキテクチャを持っていますが、基本的な原則は変わりません。 私が働いている会社では、 ノートブックと呼ばれるコントロールノードを使用しています。 それらの詳細は私の同僚がここで話しまし

ADCモジュール制御


原則として、アナログモジュールはSPIのようなインターフェイスを介して制御されます。 プログラムにプログラマブルロジックとFPGAの学習が含まれる上級生にSPIインターフェイスを実装します。 SPIノードには焦点を合わせません。 記事の最後に、 MIL-STD-1553形式のメッセージを処理するリモートマイクロサーキットHI-6131を制御するためのソースコードの例を示します。 コードはパラメータ化できず、選択したチップに合わせて特別に調整されています。 ウォームアップするために、SPIパラメーターを作成して、さまざまなパラメーター用に構成できます。 SPI制御のタイミング図は次のとおりです。


ソースコード


すべてのコンポーネントおよびアセンブリのソースコードはVHDL言語で表示され、ザイリンクス7シリーズFPGAチップ(およびそれ以降)用です。 ソースコードは公開されており、 githubのリンクから入手できますこちらをご覧ください 。 すべてのコンポーネントは、構成で可能な限り柔軟に作られており、ソースコードへの大幅な介入を必要としません(SPIノードを除き、 申し訳ありませんが、怠でした )。 残念ながら、既存のすべてのソリューションに適応することは不可能ですが、この例は、使用したすべてのアナログモジュールで正常に機能しました。

たとえば、FIFOでの読み取りおよび書き込み操作、およびバイナリコードをグレイコードに変換するためのノードの接続は次のとおりです。

FIFO R / W
 ---- Read data ---- pr_rd: process(rd_clk) begin if (rising_edge(rd_clk)) then if (rd_en = '1' and xempty = '0') then data_o <= Mem(conv_integer(pNextWordToRead)); end if; end if; end process; ---- Write data ---- pr_wr: process (wr_clk) begin if (rising_edge(wr_clk)) then if (wr_en = '1' and xfull = '0') then Mem(conv_integer(pNextWordToWrite)) <= data_i; end if; end if; end process; ---- Gray counters ---- xGray_WR : rtl_gray_count generic map ( COUNTER_WIDTH => ADDR_WIDTH ) port map ( cnt => pNextWordToWrite, ena => NextWriteAddressEn, rst => reset, clk => wr_clk ); xGray_RD : rtl_gray_count generic map ( COUNTER_WIDTH => ADDR_WIDTH ) port map ( cnt => pNextWordToRead, ena => NextReadAddressEn, rst => reset, clk => rd_clk ); 


参照資料


など

継続するには...

Source: https://habr.com/ru/post/J313692/


All Articles