이것은 위시 본 트랜잭션을 호스트에서 SPI 메모리 거래로 변환하는 위시 본 SPI 브리지입니다. SPI 플래시, EEPROM 또는 RAM을 프로세서의 주소 공간에 매핑하는 데 사용할 수 있습니다. 브리지는 투명하게 작동하므로 추가 대기 시간 비용으로 SPI 프로토콜을 숨길 때 메모리 매핑 된 읽기/쓰기 메모리처럼 작동합니다. 따라서 브리지는 프로세서가 SPI 메모리 에 위치한 지침 및 데이터에 직접 액세스 (및 실행) 할 수 있도록하는 Execute-In-Place (XIP)를 지원합니다.
이것은 NeORV32 RISC-V 프로세서의 또 다른 "스핀 오프"프로젝트입니다. 브리지는 언젠가 프로세서에 XIP 모듈로 추가 될 수 있습니다.
주요 기능
Todos / Ideas / 도움말
브리지는 단일 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 ;최고 엔티티는 두 개의 파일 내 실체를 인스턴스화합니다.
wb_spi_bridge_link SPI 메모리 프로토콜을 처리합니다 (읽기, 쓰기, 쓰기 가능)wb_spi_bridge_phy 실제 직렬 주변 장치 인터페이스 프로토콜을 처리합니다wb_rstn_i )과 동기식 ( wb_srstn_i )의 두 가지리스가 있습니다. 다리를 정의 된 상태로 가져 오려면 비동기 재설정이 필요합니다 . 동기 재설정은 선택 사항이며 애플리케이션 로직에서 브리지를 재설정하는 데 사용할 수 있습니다. 이 재설정을 사용하지 않으면 1 에 묶으십시오.
Wishbone-to-SPI 브리지의 응용 프로그램 별 구성은 최고 엔티티의 제네릭을 사용하여 수행됩니다.
SPI 클록 주파수는 SPI_CLK_DIV GENERIC을 사용하여 구성됩니다. 실제 SPI 클록을 얻기 위해 클럭 입력 clk_i 에 적용되는 스케일러를 정의합니다. SPI 클록은 f_spi = f_main / (2 * SPI_CLK_DIV) 로 정의됩니다. 클럭 스케일러의 최소 허용 값은 2이므로 입력 클럭 속도의 최대 SPI 클럭 속도가 1/4입니다.
실제 클럭 모드는 SPI_CPHA 및 SPI_CPOL 통해 구성됩니다. 이 두 제네릭의 조합을 통해 4 개의 표준 SPI 클록 모드 중 하나를 구성 할 수 있습니다. 시계 모드에 대한 자세한 내용은 SPI Wikipedia 기사를 참조하십시오.
용량으로 정의 된 SPI 메모리의 주소 크기는 SPI_ABYTES GENERIC로 구성됩니다. 허용 값은 1, 2, 3 및 4입니다. 대부분의 SPI EEPROM은 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 (64*1024 바이트)가있는 SPI 플래시 :
WB_ADDR_BASE => 0 x"FFFF0000" ,
WB_ADDR_SIZE => 64 * 1024 이 경우 0xFFFF8000 의 기본 주소는 자연스럽게 64KB 경계에 정렬되지 않기 때문에 유효하지 않습니다.
호스트 인터페이스는 위시 본 B4 사양을 기반으로합니다. 클래식 및 파이프 라인 단일 액세스 전송을 지원합니다. 버스트 전송은 아직 지원되지 않습니다.
| 클래식 모드 액세스 예제 | 파이프 라인 모드 쓰기 액세스 예제 |
|---|---|
stb 와 cyc 는 전송이 완료 될 때까지 주장됩니다.cyc 전송이 완료 될 때까지 주장됩니다. stb 전송 시작시 1주기에 대해서만 주장됩니다. | 승인 신호 ack 설정되면 전송이 완료됩니다 (한주기 동안 활성). 이것은 성공적인 종료를 나타냅니다. 오류 신호 err 설정되면 (한주기에 대해 활성)가 잘못된 종료를 나타내는 전송도 완료됩니다. 브릿지는 지원되지 않는 바이트를 사용 가능한 마스크가 설정된 경우에만 오류 신호를 올립니다 (아래 참조).
이 브리지는 32 비트, 16 비트 및 8 비트 쓰기 액세스를 지원합니다. 읽기 액세스는 항상 전체 32 비트 단어를 반환합니다. 브리지는 리틀 엔드 바이트 주문에서 메모리 데이터에 액세스합니다. sel 바이트 마스크 신호는 해당 액세스의 데이터 수량을 정의합니다. 다음 바이트 마스크가 지원됩니다.
sel | r/w | 데이터 수량 |
|---|---|---|
1111 | 읽다 | 전체 32 비트 단어 |
1111 | 쓰다 | 전체 32 비트 단어 |
1100 | 쓰다 | 상단 16 비트 반 단어 |
0011 | 쓰다 | 16 비트 하프 워드 |
0001 | 쓰다 | 바이트 0 |
0010 | 쓰다 | 바이트 1 |
0100 | 쓰다 | 바이트 2 |
1000 | 쓰다 | 바이트 3 |
남은 모든 바이트 마스크 조합은 전송 오류가 발생합니다 ( err ack 대신 한 사이클에 대해 설정됩니다).
브리지는 항상 모든 종류의 위시 본 전송에 대해 SPI 메모리에 완전한 명령 시퀀스를 보냅니다 (버스트는 아직 지원되지 않음). 이는 메모리 OPCODE, 주소 비트 및 실제 데이터가 모든 단일 트랜잭션에 대해 전송됨을 의미합니다. 다음 표는 각 트랜잭션 유형에 대해 SPI를 통해 전송할 비트 수를 보여줍니다. 각 비트에는 SPI 시계의 한 시계가 필요합니다.
| 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 클록 사이클이 필요합니다. 하나의 SPI 클록 사이클은 메인 시계 clk_i 의 2 * SPI_CLK_DIV 사이클과 같습니다.
모든 종류의 쓰기 액세스를 위해서는 메모리의 쓰기 활성화 래치를 설정해야하며, 이는 단일 8 비트 명령을 전송합니다.
이 프로젝트는 간단한 TestBench sim/wb_spi_bridge_tb.vhd 제공하며 GHDL에서 제공하는 스크립트를 통해 시뮬레이션 할 수 있습니다.
wb_spi_bridge/sim$ sh ghdl.sh 시뮬레이션은 100MHz 시계를 사용하여 1ms의 경우 실행됩니다. 이 기간 동안 지원되는 모든 (그리고 불법적 인) 위시 본 액세스가 트리거됩니다. 이 테스트 벤치는 수동 파형 검사를위한 것입니다. 자체 점검이 아닙니다! 파형 데이터는 sim/wb_spi_bridge.vcd 에 저장되며 gtkwave 사용하여 볼 수 있습니다.
wb_spi_bridge/sim$ gtkwave wb_spi_bridge.vcd다리는 FPGA가 제공됩니다 . 25LC512 SPI EEPROM을 인터페이스하는 NEORV32 RISC-V 프로세서 (Wishbone Interconnect 없음)의 Wishbone 인터페이스 포트에 직접 연결하여 테스트되었습니다.
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)