これは、ホストからSPIメモリトランザクションにウィッシュボーントランザクションを変換するSPIブリッジへのウィッシュボーンです。 SPIフラッシュ、EEPROM、またはRAMをプロセッサのアドレススペースにマッピングするために使用できます。ブリッジは透過的に動作するため、追加の遅延を犠牲にしてSPIプロトコルを隠す際に、メモリマップされた読み取り/書き込みメモリのように動作します。したがって、ブリッジは実行中の実行(XIP)をサポートし、プロセッサがSPIメモリにある命令とデータに直接アクセス(および実行)できるようにします。
これは、NEORV32 RISC-Vプロセッサの別の「スピンオフ」プロジェクトです。ブリッジは、いつかプロセッサにXIPモジュールとして追加される場合があります。
重要な機能
Todos / Ideas / helpwanted
ブリッジは、単一のVHDLファイルrtl/wb_spi_bridge.vhdに基づいています。トップエンティティはwb_spi_bridgeです。これは、特別なライブラリを必要とせずに直接インスタンス化できます。
entity wb_spi_bridge is
generic (
SPI_CLK_DIV : positive ; -- clock divider: f(spi_clk_o) = f(clk_i) / 2*SPI_CLK_DIV, min 2
SPI_ABYTES : positive ; -- number of address bytes in SPI protocol, 1..4
SPI_CPHA : std_ulogic ; -- clock phase
SPI_CPOL : std_ulogic ; -- idle polarity
WB_ADDR_BASE : std_ulogic_vector ( 31 downto 0 ); -- module base address, size-aligned
WB_ADDR_SIZE : positive -- module address space in bytes
);
port (
-- wishbone host interface --
wb_clk_i : in std_ulogic ; -- clock
wb_rstn_i : in std_ulogic ; -- reset, async, low-active
wb_srstn_i : in std_ulogic ; -- reset, SYNC, low-active
wb_adr_i : in std_ulogic_vector ( 31 downto 0 ); -- address
wb_dat_i : in std_ulogic_vector ( 31 downto 0 ); -- read data
wb_dat_o : out std_ulogic_vector ( 31 downto 0 ); -- write data
wb_we_i : in std_ulogic ; -- read/write
wb_sel_i : in std_ulogic_vector ( 03 downto 0 ); -- byte enable
wb_stb_i : in std_ulogic ; -- strobe
wb_cyc_i : in std_ulogic ; -- valid cycle
wb_ack_o : out std_ulogic ; -- transfer acknowledge
wb_err_o : out std_ulogic ; -- transfer error
-- SPI device interface --
spi_csn_o : out std_ulogic ; -- chip-select, low-active
spi_clk_o : out std_ulogic ; -- serial clock
spi_data_i : in std_ulogic ; -- device data output
spi_data_o : out std_ulogic -- controller data output
);
end wb_spi_bridge ;トップエンティティは、2つのインファイルエンティティをインスタンス化します。
wb_spi_bridge_link SPIメモリプロトコルを処理します(読み取り、書き込み、書き込みに対応)wb_spi_bridge_phy実際のシリアル周辺インターフェイスプロトコルを処理しますwb_rstn_i )と同期( wb_srstn_i )の2つのリセットがあります。どちらも低活動的です。非同期リセットは、橋を定義された状態にするために必要です。同期リセットはオプションであり、アプリケーションロジックからブリッジをリセットするために使用できます。使用されていない場合は、このリセットを1に結びます。
Wishbone-to-SPIブリッジのアプリケーション固有の構成は、TOPエンティティのジェネリックを使用して行われます。
SPIクロック周波数は、 SPI_CLK_DIVジェネリックを使用して構成されています。クロック入力clk_iに適用されるスケーラーを定義して、実際のSPIクロックを取得します。 SPIクロックはf_spi = f_main / (2 * SPI_CLK_DIV)で定義されます。クロックスケーラーの最小許容値は2であるため、入力クロック速度の1/4のSPIクロック速度が最大になります。
実際のクロックモードは、 SPI_CPHAおよびSPI_CPOLを介して構成されています。これら2つのジェネリックの組み合わせにより、4つの標準SPIクロックモードのいずれかを構成できます。クロックモードに関する詳細については、SPI Wikipediaの記事を参照してください。
容量によって定義されるSPIメモリのアドレスサイズは、 SPI_ABYTES genericによって構成されます。許可された値は1、2、3、および4です。ほとんどのSPI EEPROMSは16ビットのアドレスサイズを使用してSPI_ABYTES = 2になります。多くの標準SPIフラッシュメモリは、アドレス指定に24ビットを使用してSPI_ABYTES = 3になります。
ブリッジは、3つの標準メモリコマンドのみを使用します。特定のSPIメモリのコマンドが異なる場合は、VHDLソースファイルに適合できます。
-- spi memory opcodes -----------------------------------------------------------
constant cmd_write_c : std_ulogic_vector ( 7 downto 0 ) := x"02" ; -- write data
constant cmd_read_c : std_ulogic_vector ( 7 downto 0 ) := x"03" ; -- read data
constant cmd_wren_c : std_ulogic_vector ( 7 downto 0 ) := x"06" ; -- write enable
-- ------------------------------------------------------------------------------ブリッジの32ビットベースアドレスは、 WB_ADDR_BASE genericによって定義されます。 SPIメモリの容量を定義する占有アドレススペースのサイズは、 WB_ADDR_SIZE genericによって構成されます。アドレスのスペースサイズは2のパワーでなければならず、ベースアドレスはこのサイズに自然に整列する必要があります。
例:64kbのSPIフラッシュ(64*1024バイト):
WB_ADDR_BASE => 0 x"FFFF0000" ,
WB_ADDR_SIZE => 64 * 1024この場合、 0xFFFF8000のベースアドレスは無効になります。これは、64kbの境界に自然に整列されていないためです。
ホストインターフェイスは、ウィッシュボーンB4仕様に基づいています。クラシックおよびパイプラインのシングルアクセス転送をサポートします。バースト転送はまだサポートされていません。
| クラシックモード読み取りアクセスの例 | パイプラインモード書き込みアクセスの例 |
|---|---|
stbとcycどちらも、転送が完了するまで主張されています。cyc 、転送が完了するまで主張されたままです。 stb 、転送開始時の1つのサイクルのみで主張されます。 |確認信号ackが設定されたときに転送が完了します(1サイクルでアクティブ)。これは、終了が成功したことを示しています。また、エラー信号errが設定されている場合(1サイクルでアクティブ)、誤った終了を示す場合にも転送が完了します。ブリッジは、サポートされていないバイトに有効なマスクが設定されている場合にのみ、エラー信号を上げます(以下を参照)。
ブリッジは、32ビット、16ビット、8ビットの書き込みアクセスをサポートします。読み取りアクセスは常に32ビットの完全な単語を返してください。ブリッジは、リトルエンディアンバイトオーダーのメモリデータにアクセスすることに注意してください。 selバイトマスク信号は、Accessのデータ数量を定義します。次のバイトマスクがサポートされています。
sel | r/w | データ数量 |
|---|---|---|
1111 | 読む | 完全な32ビットワード |
1111 | 書く | 完全な32ビットワード |
1100 | 書く | 上部16ビットの半ワード |
0011 | 書く | 16ビットのハーフワードを下回っています |
0001 | 書く | バイト0 |
0010 | 書く | バイト1 |
0100 | 書く | バイト2 |
1000 | 書く | バイト3 |
残りのバイトマスクの組み合わせはすべて、転送エラーが発生します( ackではなく1サイクルにerrが設定されます)。
ブリッジは常に、あらゆる種類のウィッシュボーン転送のために完全なコマンドシーケンスをSPIメモリに送信します(バーストはまだサポートされていません)。これは、メモリオペコード、アドレスビット、および実際のデータが、単一のトランザクションごとに転送されることを意味します。次の表は、各タイプのトランザクションのSPIを介して転送するビット数を示しています。各ビットには、SPIクロックの1つのクロックが必要です。
| r/w | データサイズ | CMDビット | アドレスビット | データビット | 合計ビット |
|---|---|---|---|---|---|
| 読む | 単語(32ビット) | 8 | 8*SPI_ABYTES | 32 | 8 + 8*SPI_ABYTES + 32 |
| 書く | 単語(32ビット) | 8 + 8 | 8*SPI_ABYTES | 32 | 8 + 8 + 8*SPI_ABYTES + 32 |
| 書く | ハーフワード(16ビット) | 8 + 8 | 8*SPI_ABYTES | 16 | 8 + 8 + 8*SPI_ABYTES + 16 |
| 書く | バイト(8ビット) | 8 + 8 | 8*SPI_ABYTES | 8 | 8 + 8 + 8*SPI_ABYTES + 8 |
たとえば、24ビットアドレス指定を使用するSPIフラッシュへの単語全体の書き込みアクセスには8 + 8 + 8*3 + 32 = 72 SPIクロックサイクルが必要です。 1つのSPIクロックサイクルは、メインクロックclk_iの2 * SPI_CLK_DIVサイクルに相当します。
あらゆる種類の書き込みアクセスには、メモリの書き込みラッチを設定する必要があります。これは、単一の8ビットコマンドを送信します。
このプロジェクトは、Simple TestBench sim/wb_spi_bridge_tb.vhdを提供します。
wb_spi_bridge/sim$ sh ghdl.shシミュレーションは、100MHzクロックを使用して1MSで実行されます。この間、サポートされているすべての(および1つの違法な)ウィッシュボーンアクセスがトリガーされます。このテストベンチは、手動波形検査を目的としていることに注意してください - それはセルフチェックではありません!波形データは、 sim/wb_spi_bridge.vcdに保存されます。これは、 gtkwaveを使用して表示できます。
wb_spi_bridge/sim$ gtkwave wb_spi_bridge.vcdブリッジはFPGAが公開しています。 25LC512 SPI EEPROMをインターフェースするNEORV32 RISC-Vプロセッサ(ウィッシュボーン相互接続なし)のウィッシュボーンインターフェイスポートに直接接続することでテストされています。
NEORV32ソフトウェアの例は、UART端末を介して任意のウィッシュボーンアクセスを実行できる「バスエクスプローラー」プログラムを提供します。ブリッジは、すべての読み取りおよび書き込み操作を正常に処理できます。さらに、NEORV32はSPIモジュールからプログラムで正常に実行できます。
次の構成の模範的なマッピング結果:
SPI_CLK_DIV => 32 ,
SPI_ABYTES => 2 , -- 16-bit addressing
SPI_CPHA => '0' ,
SPI_CPOL => '0' , -- clock mode 0
WB_ADDR_BASE => x"F0000000" ,
WB_ADDR_SIZE => 64 * 1024 EP4CE22F17C6N @100MHz Hierarchy Logic Cells Logic Registers
----------------------------------------------------------------------------
wb_spi_bridge:wb_spi_bridge_inst 233 (115) 174 (88)
wb_spi_bridge_link:wb_spi_bridge_link_inst 118 (16) 86 (8)
wb_spi_bridge_phy:wb_spi_bridge_phy_inst 102 (102) 78 (78)