Dies ist ein Wishbone zu SPI Bridge, der Wishbone-Transaktionen von einem Wirt in SPI-Memory-Transaktionen umwandelt. Es kann verwendet werden, um einen SPI -Blitz, EEPROM oder RAM in den Adressraum eines Prozessors abzubilden. Die Brücke arbeitet transparent und verhält sich wie ein Speicher des Speichergebiets, der das SPI -Protokoll auf Kosten einer zusätzlichen Latenz versteckt. Daher unterstützt die Bridge die Ausführungsform (XIP) ausführend, sodass ein Prozessor direkt auf Anweisungen und Daten und Daten im SPI-Speicher zugreifen (und ausführen).
Dies ist ein weiteres "Spin-off" -Projekt des Neorv32 RISC-V-Prozessors. Die Brücke kann dem Prozessor eines Tages als XIP -Modul hinzugefügt werden.
Schlüsselmerkmale
Todos / ideen / hilfsgeweichen
Die Brücke basiert auf einer einzelnen VHDL -Datei rtl/wb_spi_bridge.vhd . Die oberste Entität ist wb_spi_bridge , die direkt ohne spezielle Bibliotheken instanziiert werden kann.
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 ;Die Top-Entität instanziiert zwei In-File -Unternehmen:
wb_spi_bridge_link behandelt das SPI-Speicherprotokoll (lesen, schreiben, schriftlich anbieten)wb_spi_bridge_phy behandelt das tatsächliche serielle periphere Schnittstellenprotokollwb_rstn_i ) und ein synchrones ( wb_srstn_i ), die beide niedrig aktiv sind. Der asynchrone Reset ist erforderlich , um die Brücke in einen definierten Zustand zu bringen. Der synchrone Reset ist optional und kann verwendet werden, um die Brücke aus der Anwendungslogik zurückzusetzen. Binden Sie diesen Zurücksetzen an 1 , wenn er nicht verwendet wird.
Die anwendungsspezifische Konfiguration der Wishbone-to-SPI-Brücke erfolgt mit den Generika der obersten Entität.
Die SPI -Taktfrequenz wird mithilfe des generischen SPI_CLK_DIV konfiguriert. Es definiert einen Scaler, der für die Takteingabe clk_i gilt, um die tatsächliche SPI -Uhr zu erhalten. Die SPI -Uhr wird durch f_spi = f_main / (2 * SPI_CLK_DIV) definiert. Der minimal zulässige Wert für den Taktskaler beträgt 2, was zu einer maximalen SPI -Taktrate von 1/4 der Eingangsaktuhrengeschwindigkeit führt.
Der tatsächliche Taktmodus wird über SPI_CPHA und SPI_CPOL konfiguriert. Die Kombination dieser beiden Generika ermöglicht es, einen der vier Standard -SPI -Taktmodi zu konfigurieren. Weitere Informationen zu den Taktmodi finden Sie im SPI -Wikipedia -Artikel.
Die Adressgröße des SPI -Speichers, der durch seine Kapazität definiert wird, wird durch die generischen SPI_ABYTES konfiguriert. Die zulässigen Werte SPI_ABYTES = 2 1, 2, 3 und 4. Viele Standard-SPI-Flash-Erinnerungen verwenden 24-Bit für die Adressierung, die zu SPI_ABYTES = 3 führt.
Die Brücke verwendet nur drei Standard -Speicherbefehle. Wenn die Befehle eines bestimmten SPI -Speichers unterschiedlich sind, können Sie sie in der VHDL -Quelldatei anpassen:
-- 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
-- ------------------------------------------------------------------------------ Die 32-Bit-Basisadresse der Brücke wird durch die Generikum WB_ADDR_BASE definiert. Die Größe des besetzten Adressraums, der die Kapazität des SPI -Speichers definiert ist, wird von der Generikum WB_ADDR_SIZE konfiguriert. Die Adressraumgröße muss eine Leistung von zwei sein und die Grundadresse muss natürlich auf diese Größe ausgerichtet sein.
Beispiel: SPI Blitz mit 64 KB (64*1024 Bytes):
WB_ADDR_BASE => 0 x"FFFF0000" ,
WB_ADDR_SIZE => 64 * 1024 In diesem Fall wäre eine Basisadresse von 0xFFFF8000 ungültig, da sie nicht auf eine 64 -KB -Grenze ausgerichtet ist.
Die Host -Schnittstelle basiert auf der Wishbone B4 -Spezifikation. Es unterstützt klassische und pipelierte Single-Access-Transfers. Burst -Transfer wird noch nicht unterstützt.
| Beispiel | Pipelined-Mode-Schreibzugriffsbeispiel |
|---|---|
stb und cyc bleiben bis zur Abschluss der Übertragung geltend.cyc bleibt bis zur Abschluss der Übertragung geltend. stb wird nur zu Beginn der Übertragung für einen Zyklus geltend gemacht. | Eine Übertragung wird abgeschlossen, wenn das ACK -ACK ack Signal eingestellt ist (aktiv für einen Zyklus). Dies weist auf eine erfolgreiche Beendigung hin. Eine Übertragung wird auch abgeschlossen, wenn das Fehlersignal err eingestellt ist (aktiv für einen Zyklus), der eine fehlerhafte Beendigung angibt. Die Brücke erhöht das Fehlersignal nur, wenn eine nicht unterstützte Byte-Engle-Maske festgelegt ist (siehe unten).
Die Brücke unterstützt 32-Bit-, 16-Bit- und 8-Bit-Schreibzugriffe. Read-Zugriffe geben immer ein volles 32-Bit-Wort zurück. Beachten Sie, dass die Brücke auf Speicherdaten in Little-Endian -Byte-Order zugreift. Das sel -Byte -Mask -Signal definiert die Datenmenge des Nachgriffs. Die folgenden Byte -Masken werden unterstützt:
sel | r/w | Datenmenge |
|---|---|---|
1111 | lesen | Volles 32-Bit-Wort |
1111 | schreiben | Volles 32-Bit-Wort |
1100 | schreiben | oberes 16-Bit-Halbwort |
0011 | schreiben | Unter 16-Bit-Halbwort |
0001 | schreiben | Byte 0 |
0010 | schreiben | Byte 1 |
0100 | schreiben | Byte 2 |
1000 | schreiben | Byte 3 |
Alle verbleibenden Byte -Masken -Kombination erhöhen einen Übertragungsfehler ( err wird für einen Zyklus anstelle von ack festgelegt).
Die Brücke sendet immer eine vollständige Befehlssequenz an den SPI -Speicher für jede Art von Wishbone -Übertragung (Bursts werden noch nicht unterstützt). Dies bedeutet, dass der Speicheropcode, die Adressbits und die tatsächlichen Daten für jede einzelne Transaktion übertragen werden. Die folgende Tabelle zeigt die Anzahl der zu übertragenden Bits über SPI für jeden Transaktionsart. Jedes Bit erfordert eine Uhr der SPI -Uhr.
| r/w | Datengröße | CMD -Bits | Adressbits | Datenbits | Gesamtbits |
|---|---|---|---|---|---|
| lesen | Wort (32-Bit) | 8 | 8*SPI_ABYTES | 32 | 8 + 8*SPI_ABYTES + 32 |
| schreiben | Wort (32-Bit) | 8 + 8 | 8*SPI_ABYTES | 32 | 8 + 8 + 8*SPI_ABYTES + 32 |
| schreiben | Halbwort (16-Bit) | 8 + 8 | 8*SPI_ABYTES | 16 | 8 + 8 + 8*SPI_ABYTES + 16 |
| schreiben | Byte (8-Bit) | 8 + 8 | 8*SPI_ABYTES | 8 | 8 + 8 + 8*SPI_ABYTES + 8 |
Beispielsweise erfordert ein wortweiter Schreibzugriff auf einen SPI-Blitz, der eine 24-Bit-Adressierung verwendet 8 + 8 + 8*3 + 32 = 72 SPI-Taktzyklen. Ein SPI -Taktzyklus ist gleich 2 * SPI_CLK_DIV -Zyklen der Haupttakt clk_i .
Für jede Art von Schreibzugriff muss der Schreibschutz des Speichers eingestellt werden, der ein einzelnes 8-Bit-Befehl gesendet wird.
Die Projekte bieten einen einfachen TestBench sim/wb_spi_bridge_tb.vhd , der über das Skript von GHDL simuliert werden kann:
wb_spi_bridge/sim$ sh ghdl.sh Die Simulation wird 1 ms mit einem 100 -MHz -Takt ausgeführt. Während dieser Zeit werden alle unterstützten (und ein illegaler) Wishbone -Zugriff ausgelöst. Beachten Sie, dass dieser Testbench für die manuelle Wellenforminspektion bestimmt ist - sie ist nicht selbst eintreibt! Die Wellenformdaten werden an sim/wb_spi_bridge.vcd gespeichert, das mit gtkwave angesehen werden kann:
wb_spi_bridge/sim$ gtkwave wb_spi_bridge.vcdDie Brücke ist FPGA-Proven . Es wurde getestet, indem es direkt an den Wishbone-Schnittstellenport des NEORV32 RISC-V-Prozessors (No Wishbone Interconnect) angeschlossen wird, das ein 25LC512-SPI-EEPROM unterstellt.
Die Software -Beispiele von Neorv32 bieten ein "Bus Explorer" -Programm, mit dem beliebige Wishbone -Zugriffe über ein UART -Terminal durchführen können. Die Brücke kann erfolgreich mit allen Lesen und Schreibvorgängen umgehen. Darüber hinaus kann der NeORV32 erfolgreich an Ort und Stelle aus dem SPI -Modul ausführen.
Beispiele für die folgende Konfiguration:
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)