นี่คือสะพาน Wishbone to SPI ที่แปลงธุรกรรม Wishbone จากโฮสต์เป็นธุรกรรม SPI Memory สามารถใช้ในการแมป SPI Flash, EEPROM หรือ RAM ลงในพื้นที่ที่อยู่ของโปรเซสเซอร์ สะพานทำงาน อย่างโปร่งใส ดังนั้นมันจึงทำงานเหมือนหน่วยความจำอ่าน/เขียนหน่วยความจำที่ซ่อนอยู่ในขณะที่มันซ่อนโปรโตคอล SPI - ด้วยค่าใช้จ่ายเพิ่มเติมในเวลาแฝงเพิ่มเติม ดังนั้นบริดจ์รองรับ การดำเนินการในสถานที่ (XIP) ช่วยให้โปรเซสเซอร์สามารถเข้าถึงคำแนะนำ (และดำเนินการ) โดยตรงและข้อมูลที่อยู่ ใน หน่วยความจำ SPI
นี่เป็นอีกโครงการ "สปินออฟ" ของโปรเซสเซอร์ NEORV32 RISC-V สะพานอาจถูกเพิ่มเป็นโมดูล XIP ไปยังโปรเซสเซอร์สักวันหนึ่ง
คุณสมบัติที่สำคัญ
Todos / Ideas / Help-Wanted
บริดจ์ขึ้นอยู่กับไฟล์ 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 ทั่วไป มันกำหนดเครื่องปรับสเกลที่ใช้กับอินพุตนาฬิกา clk_i เพื่อรับนาฬิกา SPI จริง นาฬิกา SPI ถูกกำหนดโดย f_spi = f_main / (2 * SPI_CLK_DIV) ค่าต่ำสุดที่อนุญาตสำหรับนาฬิกา Scaler คือ 2 ส่งผลให้ความเร็วนาฬิกา SPI สูงสุด 1/4 ของความเร็วสัญญาณนาฬิกาอินพุต
โหมดนาฬิกาจริงได้รับการกำหนดค่าผ่าน SPI_CPHA และ SPI_CPOL การรวมกันของสองสามัญนี้อนุญาตให้กำหนดค่าโหมดนาฬิกา SPI มาตรฐานใด ๆ ของสี่โหมด สำหรับข้อมูลเพิ่มเติมเกี่ยวกับโหมดนาฬิกาโปรดดูบทความ SPI Wikipedia
ขนาดที่อยู่ของหน่วยความจำ SPI ซึ่งกำหนดโดยความจุของมันถูกกำหนดค่าโดย SPI_ABYTES ทั่วไป ค่าที่อนุญาตคือ 1, 2, 3 และ 4 ส่วนใหญ่ใช้ขนาดที่อยู่ 16 บิตส่งผลให้ SPI_ABYTES = 2 ความทรงจำ SPI Flash มาตรฐานจำนวนมากใช้ 24 บิตสำหรับที่อยู่ที่เกิดขึ้นใน SPI_ABYTES = 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 ทั่วไป ขนาดของพื้นที่ที่อยู่ที่ถูกครอบครองซึ่งกำหนดความจุของหน่วยความจำ SPI นั้นได้รับการกำหนดค่าโดย WB_ADDR_SIZE ทั่วไป ขนาดพื้นที่ที่อยู่จะต้องเป็นพลังของสองและที่อยู่พื้นฐานจะต้องจัดเรียงตามธรรมชาติตามขนาดนี้
ตัวอย่าง: SPI Flash ด้วย 64KB (64*1024 ไบต์):
WB_ADDR_BASE => 0 x"FFFF0000" ,
WB_ADDR_SIZE => 64 * 1024 ในกรณีนี้ที่อยู่พื้นฐานของ 0xFFFF8000 จะไม่ถูกต้องเนื่องจากไม่ได้จัดเรียงตามธรรมชาติตามขอบเขต 64KB
อินเทอร์เฟซโฮสต์ขึ้นอยู่กับข้อกำหนดของ Wishbone B4 รองรับการถ่ายโอนการเข้าถึง แบบคลาสสิก และการถ่ายโอนแบบคลาสสิ ก การถ่ายโอน Burst ยังไม่ได้รับการสนับสนุน
| ตัวอย่างการเข้าถึงโหมดคลาสสิกอ่าน | ตัวอย่างการเข้าถึงการเขียนโหมด pipelined |
|---|---|
stb และ cyc ทั้งคู่ยังคงถูกกล่าวหาจนกว่าการถ่ายโอนจะเสร็จสมบูรณ์cyc ยังคงยืนยันจนกว่าการถ่ายโอนจะเสร็จสมบูรณ์ stb ได้รับการยืนยันเพียงรอบเดียวที่จุดเริ่มต้นของการถ่ายโอน - การถ่ายโอนจะเสร็จสมบูรณ์เมื่อตั้งค่าสัญญาณ Action ack (ใช้งานสำหรับหนึ่งรอบ) สิ่งนี้บ่งบอกถึงการเลิกจ้างที่ประสบความสำเร็จ การถ่ายโอนจะเสร็จสมบูรณ์เมื่อมีการตั้งค่าข้อผิดพลาด err (ใช้งานสำหรับหนึ่งรอบ) ซึ่งระบุว่ามีการยกเลิกที่ผิดพลาด บริดจ์จะเพิ่มสัญญาณข้อผิดพลาดเฉพาะในกรณีที่มีการตั้งค่าหน้ากากที่ไม่ได้รับการสนับสนุนไบต์ (ดูด้านล่าง)
สะพานรองรับการเข้าถึงการเขียนแบบ 32 บิต 16 บิตและ 8 บิต อ่านการเข้าถึงมักจะส่งคืนคำ 32 บิตเต็ม โปรดทราบว่าบริดจ์เข้าถึงข้อมูลหน่วยความจำในการสั่งซื้อไบต์ น้อย สัญญาณหน้ากาก sel BYTE กำหนดปริมาณข้อมูลของการเข้าถึงตาม รองรับหน้ากากไบต์ต่อไปนี้:
sel | r/w | ปริมาณข้อมูล |
|---|---|---|
1111 | อ่าน | คำ 32 บิตเต็ม |
1111 | เขียน | คำ 32 บิตเต็ม |
1100 | เขียน | ครึ่งคำบน 16 บิต |
0011 | เขียน | ครึ่งคำที่ต่ำกว่า 16 บิต |
0001 | เขียน | ไบต์ 0 |
0010 | เขียน | ไบต์ 1 |
0100 | เขียน | ไบต์ 2 |
1000 | เขียน | ไบต์ 3 |
การรวมกันของ Byte Mask ที่เหลือทั้งหมดจะเพิ่มข้อผิดพลาดการถ่ายโอน ( err ถูกตั้งค่าสำหรับหนึ่งรอบแทนที่จะเป็น ack )
บริดจ์ จะ ส่งลำดับคำสั่งที่สมบูรณ์ไปยังหน่วยความจำ SPI สำหรับการถ่ายโอน wishbone ทุกชนิด (ยังไม่รองรับการระเบิด) ซึ่งหมายความว่า opcode หน่วยความจำบิตที่อยู่และข้อมูลจริงจะถูกถ่ายโอนสำหรับการทำธุรกรรมทุกครั้ง ตารางต่อไปนี้แสดงจำนวนบิตที่จะถ่ายโอนผ่าน SPI สำหรับธุรกรรมแต่ละประเภท แต่ละบิตต้องการนาฬิกา SPI หนึ่งนาฬิกา
| r/w | ขนาดข้อมูล | บิต CMD | บิตที่อยู่ | บิตข้อมูล | บิตทั้งหมด |
|---|---|---|---|---|---|
| อ่าน | Word (32 บิต) | 8 | 8*SPI_ABYTES | 32 | 8 + 8*SPI_ABYTES + 32 |
| เขียน | Word (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 |
ตัวอย่างเช่นการเข้าถึงการเขียนแบบกว้างของคำไปยังแฟลช SPI ที่ใช้ที่อยู่ 24 บิตต้องใช้ 8 + 8 + 8*3 + 32 = 72 รอบนาฬิกา SPI วงจรนาฬิกา SPI หนึ่งรอบเท่ากับ 2 * SPI_CLK_DIV รอบของนาฬิกาหลัก clk_i
การเข้าถึงการเขียนทุกประเภทจำเป็นต้องตั้งค่า การเปิดใช้งานการเขียน ของหน่วยความจำซึ่งเสร็จสิ้นการส่งคำสั่ง 8 บิตเดียว
โครงการนี้มี Simple TestBench sim/wb_spi_bridge_tb.vhd ซึ่งสามารถจำลองได้โดย GHDL ผ่านสคริปต์ที่ให้ไว้:
wb_spi_bridge/sim$ sh ghdl.sh การจำลองจะทำงานเป็นเวลา 1ms โดยใช้นาฬิกา 100MHz ในช่วงเวลานี้ทั้งหมดได้รับการสนับสนุน (และหนึ่งที่ผิดกฎหมาย) การเข้าถึง wishbone จะถูกเรียกใช้ โปรดทราบว่า testbench นี้มีไว้สำหรับการตรวจสอบรูปคลื่นด้วยตนเอง - มันไม่ได้ตรวจสอบตัวเอง! ข้อมูลรูปคลื่นจะถูกเก็บไว้ใน sim/wb_spi_bridge.vcd ซึ่งสามารถดูได้โดยใช้ gtkwave :
wb_spi_bridge/sim$ gtkwave wb_spi_bridge.vcdสะพานได้ รับการพิสูจน์ FPGA มันได้รับการทดสอบโดยการเชื่อมต่อโดยตรงกับพอร์ตอินเตอร์เฟส Wishbone ของโปรเซสเซอร์ NEORV32 RISC-V (ไม่มีการเชื่อมต่อระหว่างกันของ Wishbone) เชื่อมต่อกับ 25LC512 SPI EEPROM
ตัวอย่างซอฟต์แวร์ NEORV32 ให้โปรแกรม "Bus Explorer" ที่อนุญาตให้ทำการเข้าถึง Wishbone โดยพลการผ่านทางเทอร์มินัล 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)