# SPIスレーブ（VHDL）

**URL:** <https://forum.digikey.com/t/spi-vhdl/25157>\
**Category:** 電子部品ペディア　～基礎、応用、実践～\
**Created:** [September 8, 2022, 12:08pm UTC](https://forum.digikey.com/t/spi-vhdl/25157 "2022-09-08T12:08:41Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tsuneharu\_Fuji](https://avatars.discourse-cdn.com/v4/letter/t/54ee81/32.png) [@Tsuneharu\_Fuji](https://forum.digikey.com/u/Tsuneharu_Fuji)\
**Post date:** [September 8, 2022, 12:08pm UTC](https://forum.digikey.com/t/spi-vhdl/25157/1 "2022-09-08T12:08:41Z")

</div>

[Logic Home](https://forum.digikey.com/t/logic-home-table-of-contents/12507)

# コードのダウンロード

バージョン1.2：[spi\_slave.vhd](https://forum.digikey.com/uploads/short-url/Aecibm24TQ5cKZNLuKr6UzTdfMu.vhd) (8.1 KB)  
より多くのツールで合成できるようにアーキテクチャを若干変更

バージョン1.1：[spi\_slave\_v1\_1.vhd](https://forum.digikey.com/uploads/short-url/qx0dpeIgrdujyFEmpTFSdKsIFAm.vhd) (8.0 KB)  
非同期アクティブローリセットの追加

バージョン1.0：[spi\_slave\_v1\_0.vhd](https://forum.digikey.com/uploads/short-url/h2GLwKkbHVoYJp3q5pOjOBS9muj.vhd) (7.5 KB)  
初版リリース

# 特長

- ユーザー定義可能なSPIモード
- ユーザー定義可能なデータ幅
- 送信レディ、受信レディ、および受信オーバーランエラービット付きステータスレジスタ
- SPIトランザクションおよび/または個々のピン割り込みを介してマスターが利用可能なステータスレジスタビット
- ユーザーロジックで使用可能なステータスレジスタビット

# はじめに

ここではVHDLで記述されたCPLDやFPGAで使用されるSPIスレーブコンポーネントについて詳しく説明します。このコンポーネントはQuartus II, バ－ジョン 11.1を使用して設計されました。リソース要件はインプリメンテーション（データ幅など）によって異なります。図1は、SPIスレーブをシステムに組み込んだ典型的な例を示しています。

 ![block_diagram](https://global.discourse-cdn.com/digikey/original/2X/6/678e41108e9000470188646a76f6e943cf5f5a43.jpeg)

**図1．** アプリケーション例

# 背景

SPI通信方式は、4本のワイヤを使用する全二重データリンクです。マスターはスレーブセレクト（SS）ワイヤをローにすることにより、トランザクションを開始します。シリアルクロック（SCLK）ラインは、マスターによって駆動され、同期クロック源となります。マスターは、マスターアウトスレーブイン（MOSI）ラインを介してデータを送信し、マスターインスレーブアウト（MISO）ラインを介してデータを受信します。

マスターは、さまざまな手法で複数のスレーブと通信することができます。最も一般的な構成は、各スレーブが独立したSSラインを持ち、SCLK、MISOおよびMOSIラインを他のスレーブと共有するものです。各スレーブは、自分のSSラインがローにプルダウンされていないときは、共有ラインを無視します。

SPIには、クロック極性（CPOL）とクロック位相（CPHA）の2つのパラメータに基づく4つの動作モードがあります。マスターとスレーブは、同じモードを使用しなければ、正常な通信はできません。CPOLが0の場合、SCLKは通常ローとなり、最初のクロックエッジは立ち上がりエッジとなります。CPOLが1の場合、SCLKは通常ハイであり、最初のクロックエッジは立ち下がりエッジとなります。CPHAはデータアライメントを定義します。CPHA が0の場合、最初のデータビットはSSの立ち下がりエッジで書き込まれ、SCLKの最初のエッジで読み出され ます。CPHAが1の場合、データは最初のSCLKエッジで書き込まれ、2番目のSCLKエッジで読み込まれます。図2のタイミング図は、4つのSPIモードを表しています。

 ![spi_timing_diagram](https://global.discourse-cdn.com/digikey/original/2X/8/8cf1910277283f7b2125542b96812aa55be14daa.jpeg)

**図 2．** SPIタイミング図

# ポートの説明

表1に、SPIスレーブのポートを示します。スレーブが動作するモードは、GENERICパラメータの_cpol_および_cpha_で定義されます。送信および受信データバス幅は、_d\_width_で宣言します。

**表1．** ポートの説明

 ![port_descriptions](https://global.discourse-cdn.com/digikey/original/2X/5/5ef3cac443eeeb171e4fd82d2a448be3363c95ee.jpeg)

# 機能の説明

スレーブコンポーネントのSPIモードは、VHDLのENTITYで_cpol_と_cpha_（GENERICパラメータ）でユーザーが設定します。

このSPIスレーブコンポーネントとSPIマスターとの間のトランザクションは、8ビットのコマンドとそれに続くNビットのデータ転送で構成されなければなりません。データ転送のサイズNは、VHDLのENTITY内のGENERIC _d\_width_パラメータで決定され、ユーザーが設定することになります。図3は、_cpol_ = 0、_cpha_ = 0、_d\_width_ = 8のトランザクションを表しています。

 ![spi_transaction_diagram](https://global.discourse-cdn.com/digikey/original/2X/3/381ee739ec85e9648bcd249a159f3cf06935e4c4.jpeg)

**図 3．** トランザクションの構成

## 8ビットコマンド

表2 は、マスターが MOSIで送信する8ビットコマンドを定義したものです。マスターはコマンドMSBを最初に送信しなければなりません。

**表2．** 8ビットコマンドのフォーマット

![8_bit_command_format](https://global.discourse-cdn.com/digikey/original/2X/4/4bed29eb6c7c89057d23e369022071fab9d25fe4.jpeg)

SPIスレーブコンポーネントは、受信、送信およびステータスの3つのレジスタを含んでいます。_wr\_addr_ビットは、データ転送中にMOSIラインがどのスレーブレジスタに書き込むかを示し、_rd\_addr_ビットは、MISOラインがマスターに送り返すレジスタを識別します。表3に各レジスタのアドレスを示します。

**表3．** レジスタのアドレス

![register_addresses](https://global.discourse-cdn.com/digikey/original/2X/5/5212ad9388029122a5a34aad2c38205cdfc4b4c3.jpeg)

## 受信レジスタ

受信レジスタは、マスターからMOSIラインで受信したデータを保持するバッファです。ユーザーロジックが結果のデータにアクセスするには、コンポーネントがトランザクションを実行していない時（つまり、_busy_出力がローの時）に_rx\_req_にパルス信号を加える必要があります。その後、スレーブは受信レジスタの内容を_rx\_data_ポートに出力します。

## 送信レジスタ

送信レジスタは、スレーブからマスターへMISOラインで送信されるデータを保持するバッファです。ユーザーロジックは、コンポーネントがトランザクションを実行していない（すなわち、_busy_出力がロー）時、_tx\_load\_data_ポートにデータを提示し、_tx\_load\_en_にパルス入力することにより、このレジスタに書き込みます。

## ステータスレジスタ

SPIスレーブは、ステータスレジスタを使用せずに動作させることができます。このレジスタは、スレーブコンポーネントのステータスに関する情報をユーザーに提供しますが、コンポーネントを使用するために必要なものではありません。

ステータスレジスタには3つのステータスビットがあります。マスターは、このレジスタにアドレス指定されたトランザクションで、これらのビットの読み出し、設定およびクリアを行うことができます。ステータスレジスタの読み出し、または書き込みを行うトランザクション中、最初に送られる3つのデータビットはそれぞれ_trdy_、_rrdy_および_roe_に対応します。スレーブコンポーネントは、トランザクション中に送受信される残りのビットを無視します。ユーザーロジックは、これらのビットに名前をつけたポートを介してアクセスします。ユーザーロジックは、コンポーネントが動作していない（すなわち、_busy_出力がローになっている）ときに、_st\_load\_trdy_、_st\_load\_rrdy_および_st\_ load\_roe_入力に必要な値を入力して_st\_load\_en_にパルス入力をし、これらのビットを設定またはクリアできます。

### trdy

_trdy_（transmit ready 送信準備完了）ビットは、最後のSPIトランザクションが実行された後にユーザーロジックが送信レジスタに新しいデータを書き込んだことを示しており、そのためマスターが現在のデータをまだ読み出していません。このコンポーネントは、次にマスターが送信レジスタを読み出すと、_trdy_ビットをクリアします。

### rrdy

_rrdy_（receive ready 受信準備完了）ビットは、ユーザーロジックが最後に受信レジスタを読み出した後に、マスターが新しいデータを受信レジスタに書き込んだことを示しており、そのためユーザーロジックが最新のデータをまだ受信していません。このコンポーネントは、ユーザーロジックがデータを要求すると、_rrdy_ビットをクリアします。

### roe

_roe_（receive overrun error 受信オーバーランエラー）ビットは、ユーザーロジックがデータを読み出す前に、マスターが最後に受信したデータを上書きしたことを示します。マスターは、SPIトランザクションでステータスレジスタに書き込むことにより、_roe_ビットをクリアすることができます。また、ユーザーロジックは、上記のように_st\_load_入力でステータスレジスタに書き込むことにより、ビットをクリアすることができます。

### 割り込み

また、_trdy_、_rrdy_および_roe_ポートは、SPIトランザクションを必要とせず、SPIスレーブの状態変化によるSPIマスターデバイスやユーザーロジックへの割り込み手段を提供します。ユーザーはこれらのポートをSPIマスターまたはユーザーロジックのいずれか、もしくは両方に接続可能、またはどちらにも接続する必要はありません。

# トランザクションの例

図4は、トランザクションの例を示しています（ModelSim Altera Starter Edition 10.0cでシミュレーション）。スレーブは、モード「00」で動作するように設定されています。スレーブがビジー状態でないとき、ユーザーロジックは_tx\_load\_data_バスにデータ「10101010」を提示しながら、_tx\_load\_en_にパルスを入力します。_trdy_ 信号が直ちにハイになり、送信すべき新しいデータが存在することを示します。次に、マスターは、「00000000」コマンドでトランザクションを開始し、スレーブに後続のMOSIデータを受信レジスタにロードし、送信レジスタの内容をMISOに出力するように指示します。最後のデータビットが送信されると、_trdy_信号がローになり、送信レジスタの現在の値がマスターに送信されたことを示します。同様に、スレーブが最後のデータビットを受信レジスタに読み込むと、_rrdy_信号がアサートされ、新しいデータを受信したことが示されます。その後、ユーザーロジックが_rx\_req_にパルス入力すると、スレーブは受信データ「10110001」を_rx\_data_バスに出力して応答します。その後、_rrdy_出力がディアサートされ、受信レジスタに含まれるデータがユーザーロジックによって既に読み取られたことを示します。

 ![sim_transaction_example](https://global.discourse-cdn.com/digikey/original/2X/0/059e1d282a21718463c8d6a8cdecf514c68f5688.jpeg)

**図4．** トランザクションの例

# リセット

SPIスレーブコンポーネントが動作するためには、_reset\_n_入力ポートが論理値ハイである必要があります。このポートにロー信号を入力すると、非同期でコンポーネントをリセットします。リセット中は、_miso_出力はハイインピーダンスになり、 _rx\_data_出力ポートはクリアされます。送信、受信、送信レディ、受信レディおよび受信オーバーランエラーのすべてのレジスタはクリアされます。

# まとめ

このVHDL SPIスレーブは、ユーザー定義可能なモードとデータ幅を提供します。また送信レディ、受信レディ、受信オーバーランエラーのステータス情報も含みます。

# 関連するトピック

[SPIマスター（VHDL）](https://forum.digikey.com/t/topic/25158)

[SPI 3-Wire Master (VHDL)](https://forum.digikey.com/t/spi-3-wire-master-vhdl/12743)

[SPI to I2C Bridge (VHDL)](https://forum.digikey.com/t/spi-to-i2c-bridge-vhdl/12749) - このデザインは、このページで説明されているSPIスレーブを使用して、SPI ～I2Cブリッジを実装しています。

 
  
  
  

[オリジナル・ソース（English）](https://forum.digikey.com/t/spi-slave-vhdl/12721)
