Este é um osso da ponte SPI que converte transações de osso de desejos de um host em transações de memória SPI. Ele pode ser usado para mapear um flash SPI, EEPROM ou RAM no espaço de endereço de um processador. A ponte opera de forma transparente , por isso se comporta como uma memória de leitura/gravação mapeada de memória, pois oculta o protocolo SPI - ao custo de latência adicional. Portanto, a ponte suporta execução no local (XIP), permitindo que um processador acesse (e execute) instruções e dados localizados na memória SPI.
Este é outro projeto "spin-off" do processador NEORV32 RISC-V. A ponte pode ser adicionada como módulo XIP ao processador algum dia.
Principais recursos
Todos / Ideas / Help-Wanteded
A ponte é baseada em um único arquivo vhdl rtl/wb_spi_bridge.vhd . A entidade superior é wb_spi_bridge , que pode ser instanciada diretamente sem a necessidade de bibliotecas especiais.
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 ;A entidade superior instancia duas entidades no arquivo :
wb_spi_bridge_link lida com o protocolo de memória spi (leia, escreva, escreva)wb_spi_bridge_phy lida com o protocolo de interface periférica em sériewb_rstn_i ) e uma síncrona ( wb_srstn_i ), que são de baixa forma. A redefinição assíncrona é necessária para trazer a ponte para um estado definido. A redefinição síncrona é opcional e pode ser usada para redefinir a ponte a partir da lógica do aplicativo. Amarre esta redefinição para 1 se não for usado.
A configuração específica do aplicativo da ponte Wishbone-to-SPI é feita usando os genéricos da entidade superior.
A frequência do relógio SPI está configurada usando o SPI_CLK_DIV genérico. Ele define um scaler que se aplica à entrada do relógio clk_i para obter o relógio SPI real. O relógio SPI é definido por f_spi = f_main / (2 * SPI_CLK_DIV) . O valor mínimo permitido para o relógio Scaler é 2, resultando em uma velocidade máxima de relógio SPI de 1/4 da velocidade do relógio de entrada.
O modo de relógio real é configurado via SPI_CPHA e SPI_CPOL . A combinação desses dois genéricos permite configurar qualquer um dos quatro modos de relógio SPI padrão. Para obter mais informações sobre os modos do relógio, consulte o artigo da SPI Wikipedia.
O tamanho do endereço da memória SPI, que é definido por sua capacidade, é configurado pelo SPI_ABYTES GENIC. Os valores permitidos são 1, 2, 3 e 4. A maioria dos spi eeproms usa um tamanho de endereço de 16 bits, resultando em SPI_ABYTES = 2 . Muitas memórias padrão do SPI Flash usam 24 bits para o endereço, resultando em SPI_ABYTES = 3 .
A ponte usa apenas três comandos de memória padrão. Se os comandos de uma memória SPI específica forem diferentes, você poderá adaptá -los no arquivo de origem 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
-- ------------------------------------------------------------------------------ O endereço base de 32 bits da ponte é definido pelo WB_ADDR_BASE GENERIC. O tamanho do espaço de endereço ocupado, que é definido a capacidade da memória SPI, é configurado pelo WB_ADDR_SIZE GENERIC. O tamanho do espaço de endereço deve ser uma potência de dois e o endereço base deve estar naturalmente alinhado com esse tamanho.
Exemplo: SPI Flash com 64kb (64*1024 bytes):
WB_ADDR_BASE => 0 x"FFFF0000" ,
WB_ADDR_SIZE => 64 * 1024 Nesse caso, um endereço base de 0xFFFF8000 seria inválido, pois não está naturalmente alinhado a um limite de 64kb.
A interface do host é baseada na especificação Wishbone B4. Ele suporta transferências clássicas e de acesso único . A transferência de explosão ainda não foi suportada.
| Exemplo de acesso de leitura de modo clássico | Exemplo de acesso a gravação de modo de pipeline |
|---|---|
stb e cyc ficam afirmados até que a transferência seja concluída.cyc permanece afirmado até que a transferência seja concluída. stb é afirmado apenas para um ciclo logo no início da transferência. | Uma transferência é concluída quando o sinal de reconhecimento ack é definido (ativo para um ciclo). Isso indica um término bem -sucedido. Uma transferência também é concluída quando o sinal de err é definido (ativo para um ciclo) indicando uma terminação errônea. A ponte aumentará o sinal de erro somente se uma máscara não suportada que pode ser definida por byte (veja abaixo).
A ponte suporta acessos de gravação de 32 bits, 16 e 8 bits. Leia os acessos sempre retornam uma palavra completa de 32 bits. Observe que a ponte acessa dados de memória em ordem de byte pouco endiana . O sinal de máscara sel Byte define a quantidade de dados do ACCESS. As seguintes máscaras de byte são suportadas:
sel | r/w | Quantidade de dados |
|---|---|---|
1111 | ler | Palavra completa de 32 bits |
1111 | escrever | Palavra completa de 32 bits |
1100 | escrever | Half-Word superior de 16 bits |
0011 | escrever | Metade de 16 bits de 16 bits |
0001 | escrever | byte 0 |
0010 | escrever | byte 1 |
0100 | escrever | Byte 2 |
1000 | escrever | byte 3 |
Toda a combinação de máscara de bytes restante aumentará um erro de transferência ( err é definido para um ciclo em vez de ack ).
A ponte sempre envia uma sequência de comando completa para a memória SPI para qualquer tipo de transferência de osso de desejos (ainda não são suportados). Isso significa que o código de memória, os bits de endereço e os dados reais são transferidos para cada transação. A tabela a seguir mostra o número de bit para transferir via SPI para cada tipo de transação. Cada bit requer um relógio do relógio SPI.
| r/w | Tamanho dos dados | Bits cmd | Endereço bits | Bits de dados | Bits totais |
|---|---|---|---|---|---|
| ler | palavra (32 bits) | 8 | 8*SPI_ABYTES | 32 | 8 + 8*SPI_ABYTES + 32 |
| escrever | palavra (32 bits) | 8 + 8 | 8*SPI_ABYTES | 32 | 8 + 8 + 8*SPI_ABYTES + 32 |
| escrever | meia palavra (16 bits) | 8 + 8 | 8*SPI_ABYTES | 16 | 8 + 8 + 8*SPI_ABYTES + 16 |
| escrever | Byte (8 bits) | 8 + 8 | 8*SPI_ABYTES | 8 | 8 + 8 + 8*SPI_ABYTES + 8 |
Por exemplo, um acesso de gravação em toda a palavra a um flash SPI que usa endereçamento de 24 bits requer 8 + 8 + 8*3 + 32 = 72 ciclos de relógio SPI. Um ciclo de relógio SPI é igual 2 * SPI_CLK_DIV do relógio principal clk_i .
Qualquer tipo de acesso de gravação requer para definir a Latch Habil de gravação da memória, que é concluída enviando um único comando de 8 bits.
Os projetos fornecem um simples teste de teste sim/wb_spi_bridge_tb.vhd , que pode ser simulado pelo ghdl através do script fornece:
wb_spi_bridge/sim$ sh ghdl.sh A simulação será executada para 1ms usando um relógio de 100 MHz. Durante esse período, todos suportados (e um ilegal) acessos por ossos de desejos são acionados. Observe que este Testbench é destinado à inspeção manual da forma de onda - não é auto -verificação! Os dados da forma de onda são armazenados no sim/wb_spi_bridge.vcd , que podem ser visualizados usando gtkwave :
wb_spi_bridge/sim$ gtkwave wb_spi_bridge.vcdA ponte é comprovada por FPGA . Ele foi testado conectando-o diretamente à porta de interface do Wishbone do processador NEORV32 RISC-V (sem interconexão do osso de desejos) interface um spi eeprom 25LC512.
Os exemplos de software NEORV32 fornecem um programa "Bus Explorer" que permite executar acessos arbitrários de osso de desejos por meio de um terminal UART. A ponte pode lidar com sucesso em todas as operações de leitura e gravação. Além disso, o NEORV32 pode executar com sucesso programas no local do módulo SPI.
Resultados de mapeamento exemplares para a seguinte configuração:
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)