Merge tdk_new and Ti375 Efinity support
Keep the current GPS software and Genesys2/VCU118 flows while integrating Ti375C529 Efinity, flash, programming, and debug support. Add board-specific SPI NOR profiles and persistent GPS flash layouts across all three boards.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
# Generated build outputs.
|
||||
/out/
|
||||
/soc/out/
|
||||
/hardware/generated/
|
||||
/soc/software/*/build/
|
||||
/soc/software/gps_system/tests/test_*
|
||||
!/soc/software/gps_system/tests/test_*.c
|
||||
@@ -21,6 +22,7 @@ clockInfo.txt
|
||||
/targets/fpga/*/out/logs/
|
||||
/targets/fpga/*/out/reports/
|
||||
/targets/fpga/*/out/build/checkpoints/
|
||||
/targets/fpga/vcu118/out/
|
||||
|
||||
# Python runtime caches and privacy-sensitive raw board captures.
|
||||
__pycache__/
|
||||
|
||||
@@ -10,8 +10,8 @@ FPGA_BOARD ?= vcu118
|
||||
endif
|
||||
FPGA_TARGET_DIR := targets/fpga/$(FPGA_BOARD)
|
||||
|
||||
.PHONY: help doctor soc-hw fpga-rtl fpga-bitstream fpga-elf-flash-image fpga-mcs fpga-flash-app fpga-flash fpga-flash-bitstream fpga-flash-mcs fpga-flash-all fpga-program fpga-debug-openocd fpga-debug-load fpga-uart fpga-config asic-rtl asic-sim clean
|
||||
.PHONY: fpga_rtl fpga_bitstream fpga_elf_flash_image fpga_mcs fpga_flash_app fpga_flash fpga_flash_bitstream fpga_flash_mcs fpga_flash_all fpga_program fpga_debug_openocd fpga_debug_load fpga_uart fpga_config
|
||||
.PHONY: help doctor soc-hw fpga-rtl fpga-bitstream fpga-elf-flash-image fpga-mcs fpga-flash-app fpga-flash fpga-flash-bitstream fpga-flash-mcs fpga-flash-all fpga-program fpga-detect fpga-debug-openocd fpga-debug-load fpga-uart fpga-config asic-rtl asic-sim clean
|
||||
.PHONY: fpga_rtl fpga_bitstream fpga_elf_flash_image fpga_mcs fpga_flash_app fpga_flash fpga_flash_bitstream fpga_flash_mcs fpga_flash_all fpga_program fpga_detect fpga_debug_openocd fpga_debug_load fpga_uart fpga_config
|
||||
|
||||
help:
|
||||
@printf '%s\n' \
|
||||
@@ -19,11 +19,12 @@ help:
|
||||
' make doctor # check local JDK/Mill/CIRCT and RISC-V tools' \
|
||||
' make soc-hw # emit shared SoC FIRRTL through FPGA config' \
|
||||
' make fpga-rtl # emit selected FPGA SystemVerilog and wrapper' \
|
||||
' make fpga-bitstream # run selected FPGA Vivado bitstream flow' \
|
||||
' make fpga-bitstream # run selected board vendor bitstream flow' \
|
||||
' make fpga-elf-flash-image' \
|
||||
' # build APP ELF and board flash-format app image' \
|
||||
' make fpga-mcs # generate combined bitstream + app MCS/BIN' \
|
||||
' make fpga-program # program selected FPGA SRAM' \
|
||||
' make fpga-detect # run selected board USB/JTAG detection target' \
|
||||
' make fpga-flash-app # build flash-format app image and program app flash region' \
|
||||
' make fpga-flash # alias for fpga-flash-app' \
|
||||
' make fpga-flash-bitstream' \
|
||||
@@ -39,7 +40,7 @@ help:
|
||||
' make asic-sim # run ASIC-style Questa sanity simulation' \
|
||||
'' \
|
||||
'Config:' \
|
||||
' FPGA_BOARD=$(FPGA_BOARD) # vcu118 or genesys2' \
|
||||
' FPGA_BOARD=$(FPGA_BOARD) # vcu118, genesys2, or ti375c529' \
|
||||
' UART_BAUD=460800 # FPGA firmware and host listener default' \
|
||||
' GPS_ESKF_ENABLE=1 # gps_system: 1 ESKF, 0 GPS-only' \
|
||||
' IMU_SENSOR=auto # gps_system: auto, tdk, st or stm' \
|
||||
@@ -49,6 +50,7 @@ help:
|
||||
' make -C hardware/soc help' \
|
||||
' make -C targets/fpga/vcu118 help' \
|
||||
' make -C targets/fpga/genesys2 help' \
|
||||
' make -C targets/fpga/ti375c529 help' \
|
||||
' make -C targets/asic/rocket help'
|
||||
|
||||
doctor:
|
||||
@@ -72,6 +74,9 @@ fpga-mcs:
|
||||
fpga-program:
|
||||
$(MAKE) -C $(FPGA_TARGET_DIR) program-fpga
|
||||
|
||||
fpga-detect:
|
||||
$(MAKE) -C $(FPGA_TARGET_DIR) detect
|
||||
|
||||
fpga-flash-app fpga-flash:
|
||||
$(MAKE) -C $(FPGA_TARGET_DIR) program-flash
|
||||
|
||||
@@ -106,6 +111,7 @@ fpga_flash_bitstream: fpga-flash-bitstream
|
||||
fpga_flash_mcs: fpga-flash-mcs
|
||||
fpga_flash_all: fpga-flash-all
|
||||
fpga_program: fpga-program
|
||||
fpga_detect: fpga-detect
|
||||
fpga_debug_openocd: fpga-debug-openocd
|
||||
fpga_debug_load: fpga-debug-load
|
||||
fpga_uart: fpga-uart
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Rocket Project
|
||||
|
||||
Bu agac VCU118/Genesys2 FPGA ve ASIC-style Rocket akislari icin sade proje duzenidir.
|
||||
Bu agac VCU118, Genesys2 ve Ti375C529 FPGA akislari ile ASIC-style Rocket
|
||||
akisi icin sade proje duzenidir.
|
||||
Upstream Rocket-Chip kaynaklari daginik kok klasorlerde tutulmaz; gerekli
|
||||
upstream kaynaklar `hardware/upstream/rocket-chip/` altindadir.
|
||||
|
||||
@@ -22,6 +23,7 @@ hardware/
|
||||
soc/software/ Bootloader, BSP, uygulamalar, flash image tool
|
||||
targets/fpga/vcu118/ VCU118 build/programlama akisi
|
||||
targets/fpga/genesys2/ Genesys2 build/programlama akisi
|
||||
targets/fpga/ti375c529/ Ti375C529 Efinity build/programlama akisi
|
||||
targets/asic/rocket/ ASIC wrapper/filelist/sim akisi
|
||||
setup_tools.sh /tools/soc-tools host araci kurulum betigi
|
||||
```
|
||||
@@ -209,6 +211,7 @@ make -C hardware/fpga/vcu118/rtl help
|
||||
make -C hardware/sim/fpga/vcu118 help
|
||||
make -C targets/fpga/vcu118 help
|
||||
make -C targets/fpga/genesys2 help
|
||||
make -C targets/fpga/ti375c529 help
|
||||
make -C targets/asic/rocket help
|
||||
```
|
||||
|
||||
@@ -219,6 +222,7 @@ FPGA karti kok Makefile'dan `FPGA_BOARD` ile secilir:
|
||||
```sh
|
||||
make FPGA_BOARD=vcu118 fpga-config
|
||||
make FPGA_BOARD=genesys2 fpga-config
|
||||
make FPGA_BOARD=ti375c529 fpga-config
|
||||
```
|
||||
|
||||
Top-level `BOARD=...` alias'i da desteklenir. Orneklerde Genesys2 kullanilir:
|
||||
@@ -232,7 +236,7 @@ Yanlislikla underscore kullanilmasi durumunda yaygin FPGA hedefleri icin
|
||||
alias'lar da vardir (`fpga_program`, `fpga_debug_openocd` gibi).
|
||||
|
||||
`fpga-config` secilen kartin clock, flash, UART, DTIM ve RF ayarlarini
|
||||
gosterir. RF kaynagi `RF_INPUT_MODE` ile secilir:
|
||||
gosterir. Genesys2 ve VCU118'de RF kaynagi `RF_INPUT_MODE` ile secilir:
|
||||
|
||||
```text
|
||||
RF_INPUT_MODE=pmod Varsayilan. Harici 4-bit RF data + RF clock PMOD'dan gelir.
|
||||
@@ -270,10 +274,19 @@ VCU118 icin ayrilan bos PMOD0/J52 pinleri:
|
||||
VCU118'in U41 level shifter'i PMOD header tarafini 3.3 V'a cevirir. Mevcut
|
||||
standart PMOD SPI pinleri degistirilmemistir:
|
||||
|
||||
Ti375C529, PMOD0/J13'te RF veri ve saatinden arta kalan uc pini kullanir:
|
||||
|
||||
| MAX2771 sinyali | FPGA yonu | Ti375C529 PMOD | FPGA pini | Elektrik standardi |
|
||||
|---|---|---|---|---|
|
||||
| `SCLK` | cikis | `J13.1` | `G15` | 3.3_V_LVCMOS |
|
||||
| `CSN` | cikis | `J13.8` | `A11` | 3.3_V_LVCMOS |
|
||||
| `SDATA` | yazmada cikis, okumada giris | `J13.9` | `A13` | 3.3_V_LVCMOS |
|
||||
|
||||
| Kart | Standart PMOD SPI CSN/MOSI/MISO/SCLK | MAX2771 CSN/SDATA/SCLK |
|
||||
|---|---|---|
|
||||
| Genesys2 | `JC1/JC2/JC3/JC4` | `JB3/JB4/JB2` |
|
||||
| VCU118 | `J53.1/J53.3/J53.5/J53.7` | `J52.6/J52.8/J52.4` |
|
||||
| Ti375C529 | `J14.1/J14.2/J14.3/J14.4` | `J13.8/J13.9/J13.1` |
|
||||
|
||||
MAX2771 register varsayilanlarini yazip tek-hat `SDATA` uzerinden geri okuyarak
|
||||
dogrulayan bare-metal uygulama:
|
||||
@@ -286,10 +299,14 @@ Test MAX2771 register `0x0`-`0xA` icerigini veri sayfasindaki degerlerle
|
||||
degistirir. EVKIT uzerindeki MAX32625 kontrolcusunun seri hatlari test boyunca
|
||||
high-Z olmali ve EVKIT GUI ayni anda kullanilmamalidir.
|
||||
|
||||
Ti375C529 Efinity wrapper'i su anda yalniz harici PMOD RF girisini kullanir;
|
||||
bu kartta `RF_INPUT_MODE=pmod` birakilmalidir. `generated` ve `ethernet`
|
||||
yollari Ti375C529 wrapper'ina henuz uygulanmamistir.
|
||||
|
||||
Top-level FPGA wrapper'lar elle yazilmaz; `targets/fpga/*/tools/gen_*_wrapper.py`
|
||||
scriptleri tarafindan uretilir. Bu yuzden RF secimi RTL `ifdef` ile degil,
|
||||
generator parametresi ile yapilir. `make rtl` ve Vivado `build.tcl` ayni
|
||||
`RF_INPUT_MODE` degerini wrapper generator'a gecirir.
|
||||
scriptleri tarafindan uretilir. Genesys2 ve VCU118'de RF secimi RTL `ifdef`
|
||||
ile degil, generator parametresi ile yapilir. `make rtl` ve Vivado `build.tcl`
|
||||
ayni `RF_INPUT_MODE` degerini wrapper generator'a gecirir.
|
||||
|
||||
Varsayilan `pmod` modunda Ethernet RF IP/RTL okunmaz ve top'ta Ethernet PHY
|
||||
portlari olusmaz. Ethernet RF akisi gerektiginde:
|
||||
@@ -321,11 +338,23 @@ uzerinden 1.8 V bank/LVCMOS18:
|
||||
rf_data_pmod[1] AW15 PMOD0_2 J52.5 LVCMOS18 3.3 V
|
||||
rf_data_pmod[2] AV15 PMOD0_3 J52.7 LVCMOS18 3.3 V
|
||||
rf_data_pmod[3] AV16 PMOD0_4 J52.2 LVCMOS18 3.3 V
|
||||
|
||||
Ti375C529 PMOD0/J13, connector ve FPGA tarafi 3.3 V:
|
||||
port FPGA pin PMOD pin FPGA resource FPGA I/O
|
||||
rf_clk A12 J13.10 GPIOR_95_CLK12 3.3_V_LVCMOS
|
||||
rf_data[0] G16 J13.2 GPIOR_89 3.3_V_LVCMOS
|
||||
rf_data[1] F16 J13.3 GPIOR_90 3.3_V_LVCMOS
|
||||
rf_data[2] F17 J13.4 GPIOR_91 3.3_V_LVCMOS
|
||||
rf_data[3] G17 J13.7 GPIOR_92 3.3_V_LVCMOS
|
||||
```
|
||||
|
||||
VCU118'de disaridan PMOD header'a 3.3 V seviye verilir. FPGA U1 package
|
||||
pinlerine dogrudan 3.3 V uygulanmaz; o tarafta XDC `LVCMOS18` kullanir.
|
||||
|
||||
Ti375C529'de AX2771 `rf_clk` hatti mutlaka J13 pin 10'a baglanmalidir. Bu pin
|
||||
global-clock girisidir. J13 pin 1 / G15 (`GPIOR_88_PLLIN1`) MAX2771 `SCLK`
|
||||
cikisidir; dedicated fabric GCLK olmadigi icin RF saati oradan alinmaz.
|
||||
|
||||
PMOD SPI portu her RF modunda aktiftir ve ayri MMIO register block olarak
|
||||
`0x10015000` adresindedir. Kart uzerindeki konfig flash SPI'si `0x10014000`
|
||||
adresinde kalir. Yazilim driver'i single/quad calisma modunu `ctrl.bit2`
|
||||
@@ -351,6 +380,15 @@ uzerinden 1.2 V bank/LVCMOS12:
|
||||
pmod_spi_sck P30 PMOD1_3 J53.7 SCK LVCMOS12 3.3 V
|
||||
pmod_spi_dq[2] P29 PMOD1_4 J53.2 LVCMOS12 3.3 V
|
||||
pmod_spi_dq[3] L31 PMOD1_5 J53.4 LVCMOS12 3.3 V
|
||||
|
||||
Ti375C529 PMOD1/J14, connector ve FPGA tarafi 3.3 V:
|
||||
port FPGA pin PMOD pin FPGA resource FPGA I/O
|
||||
pmod_spi_csn B12 J14.1 GPIOR_96_CLK13 3.3_V_LVCMOS
|
||||
pmod_spi_dq[0] C14 J14.2 MOSI GPIOR_97 3.3_V_LVCMOS
|
||||
pmod_spi_dq[1] C13 J14.3 MISO GPIOR_98 3.3_V_LVCMOS
|
||||
pmod_spi_sck C12 J14.4 SCK GPIOR_99 3.3_V_LVCMOS
|
||||
pmod_spi_dq[2] D12 J14.7 GPIOR_100 3.3_V_LVCMOS
|
||||
pmod_spi_dq[3] F12 J14.8 GPIOR_101_PLLIN1 3.3_V_LVCMOS
|
||||
```
|
||||
|
||||
Sensorden gelen external interrupt hatti SPI'dan bagimsizdir. `pmod_irq`
|
||||
@@ -365,8 +403,16 @@ Genesys2:
|
||||
VCU118:
|
||||
port FPGA pin PMOD pin FPGA I/O PMOD header level
|
||||
pmod_irq M31 PMOD1_6 J53.6 LVCMOS12 3.3 V
|
||||
|
||||
Ti375C529:
|
||||
port FPGA pin PMOD pin FPGA resource FPGA I/O
|
||||
pmod_irq D13 J14.9 GPIOR_102 3.3_V_LVCMOS
|
||||
gps_pps E13 J14.10 GPIOR_103 3.3_V_LVCMOS
|
||||
```
|
||||
|
||||
Ti375C529'de `gps_pps` J14.10 uzerinden cikan 3.3 V PPS sinyalidir;
|
||||
`pmod_irq` ise J14.9 uzerinden FPGA'ya girer.
|
||||
|
||||
Bu pinler mod bazli companion XDC dosyalarinda tutulur:
|
||||
`hardware/fpga/genesys2/constraints/genesys2_pmod_rf.xdc`,
|
||||
`hardware/fpga/vcu118/constraints/vcu118_pmod_rf.xdc`,
|
||||
@@ -375,13 +421,47 @@ Bu pinler mod bazli companion XDC dosyalarinda tutulur:
|
||||
`hardware/fpga/genesys2/constraints/genesys2_pmod_irq.xdc`,
|
||||
`hardware/fpga/vcu118/constraints/vcu118_pmod_irq.xdc`,
|
||||
`hardware/fpga/genesys2/constraints/genesys2_ethernet.xdc` ve
|
||||
`hardware/fpga/vcu118/constraints/vcu118_ethernet.xdc`.
|
||||
`hardware/fpga/vcu118/constraints/vcu118_ethernet.xdc`. Ti375C529 pinleri,
|
||||
I/O standartlari, PLL'ler ve hard-JTAG baglantisi tek Efinity interface
|
||||
scriptinde tutulur:
|
||||
`hardware/fpga/ti375c529/constraints/ti375c529_rocket.isf`.
|
||||
|
||||
### Ti375C529 kart uzeri baglantilar
|
||||
|
||||
Ti375C529 development kit'te Rocket sistem saati kart uzerindeki 100 MHz
|
||||
osilatorden, GPS isleme saatleri ise AX2771'in J13.10 uzerindeki
|
||||
16.367981 MHz RF saatinden uretilir. SW3 active-low Rocket resetidir. FTDI
|
||||
UART varsayilan olarak 460800 baud ve mevcut Linux enumeration'inda
|
||||
`/dev/ttyUSB2` kullanir. Birden fazla kart veya farkli enumeration icin
|
||||
`UART_PORT=...` ve `FTDI_URL=...` ile override edilebilir.
|
||||
|
||||
Lower 512-Mbit konfig flash'i kart icinde su pinlere baglidir; PMOD'a kablo
|
||||
cekilmez:
|
||||
|
||||
```text
|
||||
port FPGA pin FPGA resource
|
||||
flash_csn A7 GPIOB_N_38 / SSL_N
|
||||
flash_sck G6 GPIOB_P_39 / CCK
|
||||
flash_dq[0] H4 GPIOB_N_40 / CDI0
|
||||
flash_dq[1] H5 GPIOB_P_40 / CDI1
|
||||
flash_dq[2] G5 GPIOB_N_39 / CDI2
|
||||
flash_dq[3] B7 GPIOB_P_38 / CDI3
|
||||
```
|
||||
|
||||
Efinity `JTAG_USER1`, mevcut Rocket DMI tunnel protokolunu kullanir. Host
|
||||
OpenOCD build'inde `riscv set_bscan_tunnel_ir` destegi bulunmalidir; Efinity
|
||||
ile gelen OpenOCD yerine uyumlu host OpenOCD kullanilir. OpenOCD 0.12 icin
|
||||
gerekli host yamasi
|
||||
`targets/fpga/ti375c529/flow/debug/openocd-0.12-ti375-bscan.patch`
|
||||
dosyasindadir. Ayrintili Efinity, clock, JTAG ve dogrulama notlari icin
|
||||
`targets/fpga/ti375c529/README.md` dosyasina bakin.
|
||||
|
||||
## FPGA Flash ve MCS Akislari
|
||||
|
||||
Bu hedefler kok Makefile'dan secilen karta yonlenir. Genesys2 icin
|
||||
`BOARD=genesys2`, VCU118 icin `BOARD=vcu118` kullanilir. `APP` verilmezse
|
||||
varsayilan uygulama `hello_uart` olur.
|
||||
`BOARD=genesys2`, VCU118 icin `BOARD=vcu118`, Ti375C529 icin
|
||||
`BOARD=ti375c529` kullanilir. `APP` verilmezse varsayilan uygulama
|
||||
`hello_uart` olur.
|
||||
|
||||
Sadece ELF'i derleyip bootloader'in okuyacagi flash-format app imajina cevirmek:
|
||||
|
||||
@@ -478,6 +558,57 @@ flash size: 32 MiB
|
||||
interface: SPIx4
|
||||
```
|
||||
|
||||
### Ti375C529 Efinity build ve flash
|
||||
|
||||
Efinity varsayilan olarak `/tools/efinix/efinity` altinda aranir. Farkli bir
|
||||
kurulum `EFINITY_HOME=/path/to/efinity` ile secilebilir. Build, SRAM'e gecici
|
||||
programlama ve kart tespiti kokten su sekilde yapilir:
|
||||
|
||||
```sh
|
||||
make FPGA_BOARD=ti375c529 fpga-config
|
||||
make FPGA_BOARD=ti375c529 fpga-bitstream
|
||||
make -C targets/fpga/ti375c529 detect
|
||||
make FPGA_BOARD=ti375c529 fpga-program
|
||||
```
|
||||
|
||||
Ti375C529'de repository genelindeki `fpga-mcs` hedef adi korunur fakat cikti
|
||||
Xilinx MCS/BIN degil, Efinity raw HEX'tir. Lower 512-Mbit flash yerlesimi:
|
||||
|
||||
```text
|
||||
configuration offset: 0x00000000
|
||||
app offset: 0x00800000
|
||||
flash size: 64 MiB
|
||||
interface: active-x1 configuration / user-mode quad SPI
|
||||
```
|
||||
|
||||
Konfig ve uygulama imajlarini uretmek ve programlamak icin:
|
||||
|
||||
```sh
|
||||
make FPGA_BOARD=ti375c529 APP=hello_uart fpga-mcs
|
||||
make FPGA_BOARD=ti375c529 APP=hello_uart fpga-flash-app
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-bitstream
|
||||
make FPGA_BOARD=ti375c529 APP=hello_uart fpga-flash-mcs
|
||||
```
|
||||
|
||||
Ciktilar:
|
||||
|
||||
```text
|
||||
targets/fpga/ti375c529/out/bitstream/ti375c529_rocket.bit
|
||||
targets/fpga/ti375c529/out/bitstream/ti375c529_rocket.hex
|
||||
targets/fpga/ti375c529/out/flash/ti375c529_rocket.hex
|
||||
targets/fpga/ti375c529/out/flash/ti375c529_rocket.json
|
||||
```
|
||||
|
||||
Flash programlama Efinity'nin Ti375'e uygun JTAG-to-SPI bridge'ini gecici
|
||||
olarak yukler. Gercek persistent boot testi icin programlamadan sonra karta
|
||||
power-cycle uygulanmalidir. GDB ile DTIM'e yukleme ve UART dinleme:
|
||||
|
||||
```sh
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-openocd
|
||||
make FPGA_BOARD=ti375c529 APP=hello_uart fpga-debug-load
|
||||
make FPGA_BOARD=ti375c529 fpga-uart
|
||||
```
|
||||
|
||||
## GPS Reset Davranisi
|
||||
|
||||
OpenOCD/GDB `monitor reset` yolu Rocket debug module `ndmreset` sinyalini
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
# Efinity Interface Configuration for the Ti375C529 development kit.
|
||||
# Pin assignments follow the kit user guide and the Efinity 2025.2 device DB.
|
||||
|
||||
# Board I/O bank voltages. Keep these aligned with the Efinix out-of-box
|
||||
# Ti375C529 development-kit project.
|
||||
design.set_device_property("2A", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("2A", "2A_MODE_SEL", "2A")
|
||||
design.set_device_property("2A", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("2B", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("2B", "2B_MODE_SEL", "2B")
|
||||
design.set_device_property("2B", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("2C", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("2C", "2C_MODE_SEL", "2C")
|
||||
design.set_device_property("2C", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("2D", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("2D", "2D_MODE_SEL", "2D")
|
||||
design.set_device_property("2D", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("2E", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("2E", "2E_MODE_SEL", "2E")
|
||||
design.set_device_property("2E", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("4A_4B", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("4A_4B", "4A_4B_MODE_SEL", "4A_4B")
|
||||
design.set_device_property("4A_4B", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("4C", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("4C", "4C_MODE_SEL", "4C")
|
||||
design.set_device_property("4C", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("4D", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("4D", "4D_MODE_SEL", "4D")
|
||||
design.set_device_property("4D", "VOLTAGE", "1.8", "IOBANK")
|
||||
design.set_device_property("BL2_BL3", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("BL2_BL3", "BL2_MODE_SEL", "BL2")
|
||||
design.set_mode_sel_name("BL2_BL3", "BL3_MODE_SEL", "BL3")
|
||||
design.set_device_property("BL2_BL3", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("BR0", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("BR0", "BR0_MODE_SEL", "BR0")
|
||||
design.set_device_property("BR0", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("BR3_BR4", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("BR3_BR4", "BR3_MODE_SEL", "BR3")
|
||||
design.set_mode_sel_name("BR3_BR4", "BR4_MODE_SEL", "BR4")
|
||||
design.set_device_property("BR3_BR4", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("TL1_TL5", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("TL1_TL5", "TL1_MODE_SEL", "TL1")
|
||||
design.set_mode_sel_name("TL1_TL5", "TL5_MODE_SEL", "TL5")
|
||||
design.set_device_property("TL1_TL5", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("TR0", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("TR0", "TR0_MODE_SEL", "TR0")
|
||||
design.set_device_property("TR0", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("TR1", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("TR1", "TR1_MODE_SEL", "TR1")
|
||||
design.set_device_property("TR1", "VOLTAGE", "3.3", "IOBANK")
|
||||
design.set_device_property("TR2", "DYNAMIC_VOLTAGE", "0", "IOBANK")
|
||||
design.set_mode_sel_name("TR2", "TR2_MODE_SEL", "TR2")
|
||||
design.set_device_property("TR2", "VOLTAGE", "3.3", "IOBANK")
|
||||
|
||||
# External GPIO.
|
||||
design.create_input_gpio("reset_n")
|
||||
design.set_property("reset_n", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.create_input_gpio("uart_rx")
|
||||
design.create_output_gpio("uart_tx")
|
||||
# Lower 512-Mbit configuration flash. After active configuration completes,
|
||||
# these dedicated SPI pins become fabric GPIO and are driven by Rocket's MMIO
|
||||
# SPI controller so the BootROM can read the application region.
|
||||
design.create_output_gpio("flash_sck")
|
||||
design.create_output_gpio("flash_csn")
|
||||
design.create_inout_gpio("flash_dq", 3, 0)
|
||||
# The AX2771 sample clock is routed to J13 pin 10 / GPIOR_95_CLK12 so it
|
||||
# enters the fabric through a dedicated global-clock input instead of being
|
||||
# promoted from normal GPIO routing by the placer.
|
||||
design.create_input_clock_gpio("rf_clk")
|
||||
design.create_input_gpio("rf_data", 3, 0)
|
||||
design.create_output_gpio("pmod_spi_sck")
|
||||
design.create_output_gpio("pmod_spi_csn")
|
||||
design.create_inout_gpio("pmod_spi_dq", 3, 0)
|
||||
design.create_input_gpio("pmod_irq")
|
||||
design.create_output_gpio("max2771_spi_sclk")
|
||||
design.create_output_gpio("max2771_spi_csn")
|
||||
design.create_inout_gpio("max2771_spi_sdata")
|
||||
design.create_output_gpio("gps_pps")
|
||||
design.create_output_gpio("led", 4, 0)
|
||||
|
||||
# The two PMOD headers, FTDI UART, reset switch, 100 MHz oscillator, and
|
||||
# LED9/LED10 use the development kit's 3.3 V banks. GPIOs otherwise default
|
||||
# to 1.8 V LVCMOS, so state these assignments explicitly.
|
||||
design.set_property("reset_n", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("uart_rx", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("uart_tx", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("flash_sck", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_csn", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_dq[0]", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_dq[1]", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_dq[2]", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_dq[3]", "IO_STANDARD", "1.8_V_LVCMOS")
|
||||
design.set_property("flash_csn", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.set_property("flash_dq[0]", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.set_property("flash_dq[1]", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.set_property("flash_dq[2]", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.set_property("flash_dq[3]", "PULL_OPTION", "WEAK_PULLUP")
|
||||
design.set_property("rf_clk", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("rf_data[0]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("rf_data[1]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("rf_data[2]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("rf_data[3]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_sck", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_csn", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_dq[0]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_dq[1]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_dq[2]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_spi_dq[3]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("pmod_irq", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("max2771_spi_sclk", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("max2771_spi_csn", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("max2771_spi_sdata", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("gps_pps", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("led[0]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("led[1]", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
|
||||
# Rocket/fabric clock: 100 MHz board oscillator -> 100 MHz GCLK.
|
||||
design.create_block("fabric_pll", "PLL")
|
||||
design.gen_pll_ref_clock("fabric_pll", pll_res="PLL_BL0", refclk_src="EXTERNAL", refclk_name="board_clk_100", ext_refclk_no="1")
|
||||
design.set_property("board_clk_100", "IO_STANDARD", "3.3_V_LVCMOS")
|
||||
design.set_property("fabric_pll", "REFCLK_FREQ", "100", "PLL")
|
||||
design.set_property("fabric_pll", "CLKOUT0_PIN", "fabric_clk", "PLL")
|
||||
design.set_property("fabric_pll", "CLKOUT0_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("fabric_pll", "LOCKED_PIN", "fabric_pll_locked", "PLL")
|
||||
design.auto_calc_pll_clock("fabric_pll", {"CLKOUT0_FREQ": "100.0", "CLKOUT0_PHASE": "0"})
|
||||
|
||||
# RF-coherent GPS processing clocks. The AX2771's 16.367981 MHz clock enters
|
||||
# the fabric on J13 pin 10 / A12 (GPIOR_95_CLK12) and drives the same two-stage
|
||||
# clock chain used by the Xilinx targets:
|
||||
# RF -> ~55.55556 MHz -> 100 MHz acquisition / 125 MHz tracking.
|
||||
design.create_block("gps_ref_pll", "PLL")
|
||||
design.gen_pll_ref_clock("gps_ref_pll", pll_res="PLL_TR0", refclk_src="CORE")
|
||||
design.set_property("gps_ref_pll", "CORE_CLK_PIN", "rf_clk", "PLL")
|
||||
design.set_property("gps_ref_pll", "REFCLK_FREQ", "16.367981", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_EN", "1", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT0_PIN", "gps_ref_clk_gen", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT0_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_PIN", "gps_ref_feedback", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("gps_ref_pll", "LOCKED_PIN", "gps_ref_pll_locked", "PLL")
|
||||
design.set_property("gps_ref_pll", "FEEDBACK_MODE", "LOCAL", "PLL")
|
||||
design.set_property("gps_ref_pll", "FEEDBACK_CLK", "CLK1", "PLL")
|
||||
design.set_property("gps_ref_pll", "FRACTIONAL_MODE_EN", "1", "PLL")
|
||||
design.set_property("gps_ref_pll", "FRACTIONAL_COEFFICIENT", "10715375", "PLL")
|
||||
design.set_property("gps_ref_pll", "M", "4", "PLL")
|
||||
design.set_property("gps_ref_pll", "N", "1", "PLL")
|
||||
design.set_property("gps_ref_pll", "O", "1", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT0_DIV", "42", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_DIV", "35", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_PDIV", "5", "PLL")
|
||||
design.set_property("gps_ref_pll", "CLKOUT1_SDIV", "30", "PLL")
|
||||
design.calc_pll_clock("gps_ref_pll")
|
||||
|
||||
design.create_block("gps_domain_pll", "PLL")
|
||||
design.gen_pll_ref_clock("gps_domain_pll", pll_res="PLL_TR1", refclk_src="CORE")
|
||||
design.set_property("gps_domain_pll", "CORE_CLK_PIN", "gps_ref_clk_gen", "PLL")
|
||||
design.set_property("gps_domain_pll", "REFCLK_FREQ", "55.55555593", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT3_EN", "1", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT4_EN", "1", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT0_PIN", "gps_domain_feedback", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT0_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT3_PIN", "gps_acq_clk_gen", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT3_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT4_PIN", "gps_trck_clk_gen", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT4_CONN_TYPE", "gclk", "PLL")
|
||||
design.set_property("gps_domain_pll", "LOCKED_PIN", "gps_domain_pll_locked", "PLL")
|
||||
design.set_property("gps_domain_pll", "FEEDBACK_MODE", "LOCAL", "PLL")
|
||||
design.set_property("gps_domain_pll", "FEEDBACK_CLK", "CLK0", "PLL")
|
||||
design.set_property("gps_domain_pll", "M", "2", "PLL")
|
||||
design.set_property("gps_domain_pll", "N", "1", "PLL")
|
||||
design.set_property("gps_domain_pll", "O", "2", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT0_DIV", "18", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT3_DIV", "20", "PLL")
|
||||
design.set_property("gps_domain_pll", "CLKOUT4_DIV", "16", "PLL")
|
||||
design.calc_pll_clock("gps_domain_pll")
|
||||
|
||||
# Hard JTAG USER1 exposes the TAP handshake at the FPGA core boundary.
|
||||
design.create_block("rocket_jtag", "JTAG")
|
||||
design.set_property("rocket_jtag", "NAME", "rocket_jtag", "JTAG")
|
||||
design.set_property("rocket_jtag", "RESOURCE", "JTAG_USER1", "JTAG")
|
||||
design.set_property("rocket_jtag", "CAPTURE", "jtag_CAPTURE", "JTAG")
|
||||
design.set_property("rocket_jtag", "DRCK", "jtag_DRCK", "JTAG")
|
||||
design.set_property("rocket_jtag", "RESET", "jtag_RESET", "JTAG")
|
||||
design.set_property("rocket_jtag", "RUNTEST", "jtag_RUNTEST", "JTAG")
|
||||
design.set_property("rocket_jtag", "SEL", "jtag_SEL", "JTAG")
|
||||
design.set_property("rocket_jtag", "SHIFT", "jtag_SHIFT", "JTAG")
|
||||
design.set_property("rocket_jtag", "TCK", "jtag_TCK", "JTAG")
|
||||
design.set_property("rocket_jtag", "TDI", "jtag_TDI", "JTAG")
|
||||
design.set_property("rocket_jtag", "TMS", "jtag_TMS", "JTAG")
|
||||
design.set_property("rocket_jtag", "UPDATE", "jtag_UPDATE", "JTAG")
|
||||
design.set_property("rocket_jtag", "TDO", "jtag_TDO", "JTAG")
|
||||
design.assign_resource("rocket_jtag", "JTAG_USER1", "JTAG")
|
||||
|
||||
# Package assignments.
|
||||
design.assign_pkg_pin("board_clk_100", "U4")
|
||||
design.assign_pkg_pin("reset_n", "U19")
|
||||
design.assign_pkg_pin("uart_rx", "E10")
|
||||
design.assign_pkg_pin("uart_tx", "E9")
|
||||
|
||||
# Lower configuration flash U47: CDI0..3, CCK, and SSL_N. These assignments
|
||||
# match Efinix's Ti375C529 JTAG-to-SPI loader reference design.
|
||||
design.assign_pkg_pin("flash_dq[0]", "H4")
|
||||
design.assign_pkg_pin("flash_dq[1]", "H5")
|
||||
design.assign_pkg_pin("flash_dq[2]", "G5")
|
||||
design.assign_pkg_pin("flash_dq[3]", "B7")
|
||||
design.assign_pkg_pin("flash_sck", "G6")
|
||||
design.assign_pkg_pin("flash_csn", "A7")
|
||||
|
||||
# PMOD0/J13 RF input plus the independent MAX2771 three-wire control bus.
|
||||
# J13 pin 10 is the header's dedicated GCLK-capable RF-clock input.
|
||||
design.assign_pkg_pin("max2771_spi_sclk", "G15")
|
||||
design.assign_pkg_pin("max2771_spi_csn", "A11")
|
||||
design.assign_pkg_pin("max2771_spi_sdata", "A13")
|
||||
design.assign_pkg_pin("rf_clk", "A12")
|
||||
design.assign_pkg_pin("rf_data[0]", "G16")
|
||||
design.assign_pkg_pin("rf_data[1]", "F16")
|
||||
design.assign_pkg_pin("rf_data[2]", "F17")
|
||||
design.assign_pkg_pin("rf_data[3]", "G17")
|
||||
|
||||
# PMOD1/J14 SPI + interrupt + PPS.
|
||||
design.assign_pkg_pin("pmod_spi_csn", "B12")
|
||||
design.assign_pkg_pin("pmod_spi_dq[0]", "C14")
|
||||
design.assign_pkg_pin("pmod_spi_dq[1]", "C13")
|
||||
design.assign_pkg_pin("pmod_spi_sck", "C12")
|
||||
design.assign_pkg_pin("pmod_spi_dq[2]", "D12")
|
||||
design.assign_pkg_pin("pmod_spi_dq[3]", "F12")
|
||||
design.assign_pkg_pin("pmod_irq", "D13")
|
||||
design.assign_pkg_pin("gps_pps", "E13")
|
||||
|
||||
# User LEDs LED9..LED13.
|
||||
design.assign_pkg_pin("led[0]", "V4")
|
||||
design.assign_pkg_pin("led[1]", "U6")
|
||||
design.assign_pkg_pin("led[2]", "L18")
|
||||
design.assign_pkg_pin("led[3]", "R20")
|
||||
design.assign_pkg_pin("led[4]", "E19")
|
||||
@@ -0,0 +1,8 @@
|
||||
# AX2771 sample clock on PMOD J13. The 100/125 MHz GPS clocks generated by the
|
||||
# two Efinity PLLs are frequency-related to this input; the Rocket fabric clock
|
||||
# comes from the independent on-board 100 MHz oscillator.
|
||||
create_clock -period 61.09495 -name rf_clk [get_ports {rf_clk}]
|
||||
|
||||
# The FTDI adapter is normally run at 1 MHz. Constraining the hard-TAP fabric
|
||||
# interface to 10 MHz leaves margin if the debug adapter speed is increased.
|
||||
create_clock -period 100.000 -name jtag_TCK [get_ports {jtag_TCK}]
|
||||
@@ -0,0 +1,10 @@
|
||||
# Efinity's generated .pt.sdc is read before this file and defines the fabric
|
||||
# and PLL-output clocks. The Rocket oscillator, AX2771-derived GPS clocks, and
|
||||
# hard-TAP JTAG clock are independent domains.
|
||||
set_clock_groups -asynchronous \
|
||||
-group [get_clocks {fabric_clk}] \
|
||||
-group [get_clocks {rf_clk}] \
|
||||
-group [get_clocks {gps_ref_clk_gen}] \
|
||||
-group [get_clocks {gps_acq_clk_gen}] \
|
||||
-group [get_clocks {gps_trck_clk_gen}] \
|
||||
-group [get_clocks {jtag_TCK}]
|
||||
@@ -0,0 +1,18 @@
|
||||
.PHONY: help all shell generated clean
|
||||
|
||||
help:
|
||||
@echo "Ti375C529 RTL targets:"
|
||||
@echo " make shell # list hand-written FPGA shell RTL"
|
||||
@echo " make generated # generate Rocket SystemVerilog and Efinix wrapper"
|
||||
@echo " make clean # remove generated wrapper/verilog"
|
||||
|
||||
all: generated
|
||||
|
||||
shell:
|
||||
@find . -type f -name '*.sv' -print | sort
|
||||
|
||||
generated:
|
||||
@$(MAKE) -C ../../../../targets/fpga/ti375c529 rtl
|
||||
|
||||
clean:
|
||||
rm -rf ../../../generated/ti375c529-soc-verilog ../../../../targets/fpga/ti375c529/out/build/generated
|
||||
@@ -14,12 +14,15 @@ GPS_DEBUG_LEVEL ?= 1
|
||||
GPS_ESKF_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
|
||||
GPS_EPHEMERIS_FLASH_BASE ?= 0x01fe0000
|
||||
GPS_NAV_CONTEXT_ENABLE ?= 1
|
||||
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x01fc0000
|
||||
IMU_SENSOR ?= auto
|
||||
BSP_UART_CLOCK_HZ ?= 100000000
|
||||
BSP_UART_BAUDRATE ?= 460800
|
||||
GPS_SYSTEM_UART_BAUDRATE ?= 460800
|
||||
BSP_CLINT_TIMEBASE_HZ ?= 1000000
|
||||
BSP_SPI_FLASH_PROFILE ?= 1
|
||||
GPS_SYSTEM_CLINT_TIMEBASE_HZ ?= 500000
|
||||
GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES ?= 5
|
||||
# BSP_DTIM_* mirrors the FPGA DTIM_* knobs and is used by C code plus linker scripts.
|
||||
@@ -51,9 +54,12 @@ help:
|
||||
@echo " GPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE)"
|
||||
@echo " GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)"
|
||||
@echo " GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)"
|
||||
@echo " GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)"
|
||||
@echo " GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)"
|
||||
@echo " GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)"
|
||||
@echo " IMU_SENSOR=$(IMU_SENSOR)"
|
||||
@echo " BSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)"
|
||||
@echo " BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)"
|
||||
@echo " GPS_SYSTEM_CLINT_TIMEBASE_HZ=$(GPS_SYSTEM_CLINT_TIMEBASE_HZ)"
|
||||
@echo " GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES=$(GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES)"
|
||||
@echo " BSP_DTIM_BASE=$(BSP_DTIM_BASE)"
|
||||
@@ -62,7 +68,7 @@ help:
|
||||
all: bootloader hello
|
||||
|
||||
bootloader:
|
||||
@make -C bootloader TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/bootloader" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
@make -C bootloader TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/bootloader" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
|
||||
hello:
|
||||
@make -C hello_uart TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/hello_uart" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
@@ -77,11 +83,11 @@ steval-mki217v1-test:
|
||||
@make -C steval_mki217v1_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/steval_mki217v1_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
|
||||
gps-system:
|
||||
@make -C gps_system TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/gps_system" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(GPS_SYSTEM_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(GPS_SYSTEM_CLINT_TIMEBASE_HZ)" IMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES="$(GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
@make -C gps_system TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/gps_system" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(GPS_SYSTEM_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(GPS_SYSTEM_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" IMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES="$(GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
|
||||
app:
|
||||
@test -d "$(APP)"
|
||||
@make -C "$(APP)" TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/$(APP)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
@make -C "$(APP)" TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/$(APP)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all
|
||||
|
||||
flash-image: app
|
||||
@mkdir -p "$(FLASH_DIR)"
|
||||
|
||||
@@ -14,12 +14,14 @@ MARCH ?= rv64imafdc_zicsr_zifencei
|
||||
MABI ?= lp64d
|
||||
BSP_UART_CLOCK_HZ ?= 100000000
|
||||
BSP_UART_BAUDRATE ?= 460800
|
||||
BSP_CLINT_TIMEBASE_HZ ?= 1000000
|
||||
BSP_SPI_FLASH_PROFILE ?= 1
|
||||
BSP_DTIM_BASE ?= 0x80000000
|
||||
BSP_DTIM_SIZE ?= 0x00100000
|
||||
CONFIG_STAMP := $(BUILD_DIR)/build_config.txt
|
||||
|
||||
# C uses BSP_DTIM_* for bounds checks; linker uses __dtim_* for RAM origin/length.
|
||||
CFLAGS := -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany -Os -ffreestanding -fno-builtin -fno-common -Wall -Wextra -I$(BSP_DIR)/include -DAPP_FLASH_OFFSET=$(APP_FLASH_OFFSET)UL -DBSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)UL -DBSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)UL -DBSP_DTIM_BASE=$(BSP_DTIM_BASE)UL -DBSP_DTIM_SIZE=$(BSP_DTIM_SIZE)UL
|
||||
CFLAGS := -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany -Os -ffreestanding -fno-builtin -fno-common -Wall -Wextra -I$(BSP_DIR)/include -DAPP_FLASH_OFFSET=$(APP_FLASH_OFFSET)UL -DBSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)UL -DBSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)UL -DBSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)UL -DBSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE) -DBSP_DTIM_BASE=$(BSP_DTIM_BASE)UL -DBSP_DTIM_SIZE=$(BSP_DTIM_SIZE)UL
|
||||
LDFLAGS := -T linker.ld -nostdlib -static -Wl,--gc-sections -Wl,--defsym=__dtim_base=$(BSP_DTIM_BASE) -Wl,--defsym=__dtim_size=$(BSP_DTIM_SIZE) -Wl,-Map,$(BUILD_DIR)/$(TARGET).map
|
||||
|
||||
SRCS := start.S main.c
|
||||
@@ -42,6 +44,8 @@ $(CONFIG_STAMP): FORCE | $(BUILD_DIR)
|
||||
'MABI=$(MABI)' \
|
||||
'BSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)' \
|
||||
'BSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)' \
|
||||
'BSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)' \
|
||||
'BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
'BSP_DTIM_BASE=$(BSP_DTIM_BASE)' \
|
||||
'BSP_DTIM_SIZE=$(BSP_DTIM_SIZE)' > "$$tmp"; \
|
||||
if ! cmp -s "$$tmp" "$@"; then mv "$$tmp" "$@"; else rm "$$tmp"; fi
|
||||
|
||||
@@ -17,17 +17,27 @@
|
||||
#define FLASH_CMD_WRITE_DISABLE 0x04u
|
||||
#define FLASH_CMD_WRITE_ENABLE 0x06u
|
||||
#define FLASH_CMD_READ_CONFIG 0x35u
|
||||
#define FLASH_CMD_CLEAR_STATUS 0x30u
|
||||
#define FLASH_CMD_RESET 0xf0u
|
||||
#define FLASH_CMD_READ_4B 0x13u
|
||||
#define FLASH_CMD_PROGRAM_4B 0x12u
|
||||
#define FLASH_CMD_ERASE_4B 0xdcu
|
||||
|
||||
#define FLASH_STATUS_WIP (1u << 0)
|
||||
#define FLASH_STATUS_WEL (1u << 1)
|
||||
#define FLASH_STATUS_E_ERR (1u << 5)
|
||||
#define FLASH_STATUS_P_ERR (1u << 6)
|
||||
#define FLASH_STATUS_ERROR (FLASH_STATUS_E_ERR | FLASH_STATUS_P_ERR)
|
||||
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
#define FLASH_CMD_CLEAR_STATUS 0x30u
|
||||
#define FLASH_CMD_RESET 0xf0u
|
||||
#define FLASH_STATUS_ERROR ((1u << 5) | (1u << 6))
|
||||
#elif BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_MT25QU01G
|
||||
#define FLASH_CMD_RESET_ENABLE 0x66u
|
||||
#define FLASH_CMD_RESET_MEMORY 0x99u
|
||||
#define FLASH_CMD_READ_FLAG_STATUS 0x70u
|
||||
#define FLASH_CMD_CLEAR_FLAG_STATUS 0x50u
|
||||
#define FLASH_FLAG_STATUS_ERROR ((1u << 1) | (1u << 4) | (1u << 5))
|
||||
#elif BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_IS25WP512M
|
||||
#define FLASH_CMD_RESET_ENABLE 0x66u
|
||||
#define FLASH_CMD_RESET_MEMORY 0x99u
|
||||
#endif
|
||||
|
||||
#define FLASH_RESET_DELAY_US 300u
|
||||
#define FLASH_PROGRAM_TIMEOUT_US 100000u
|
||||
@@ -104,6 +114,7 @@ static bool flash_wait_complete(uint32_t timeout_us)
|
||||
|
||||
do {
|
||||
status = bsp_spi_flash_read_status();
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
if ((status & FLASH_STATUS_ERROR) != 0u) {
|
||||
/* S25FL-S deliberately holds WIP high after a program/erase error
|
||||
* until CLSR is issued. Clear the latched failure so a later request
|
||||
@@ -111,7 +122,15 @@ static bool flash_wait_complete(uint32_t timeout_us)
|
||||
flash_cmd(FLASH_CMD_CLEAR_STATUS);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if ((status & FLASH_STATUS_WIP) == 0u) {
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_MT25QU01G
|
||||
uint8_t flags = flash_read_register(FLASH_CMD_READ_FLAG_STATUS);
|
||||
if ((flags & FLASH_FLAG_STATUS_ERROR) != 0u) {
|
||||
flash_cmd(FLASH_CMD_CLEAR_FLAG_STATUS);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
} while ((bsp_read64(BSP_CLINT_MTIME) - start) < timeout_ticks);
|
||||
@@ -121,11 +140,20 @@ static bool flash_wait_complete(uint32_t timeout_us)
|
||||
|
||||
static bool flash_write_enable(void)
|
||||
{
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
flash_cmd(FLASH_CMD_CLEAR_STATUS);
|
||||
#elif BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_MT25QU01G
|
||||
flash_cmd(FLASH_CMD_CLEAR_FLAG_STATUS);
|
||||
#endif
|
||||
flash_cmd(FLASH_CMD_WRITE_ENABLE);
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
return (bsp_spi_flash_read_status() &
|
||||
(FLASH_STATUS_WIP | FLASH_STATUS_WEL | FLASH_STATUS_ERROR)) ==
|
||||
FLASH_STATUS_WEL;
|
||||
#else
|
||||
return (bsp_spi_flash_read_status() &
|
||||
(FLASH_STATUS_WIP | FLASH_STATUS_WEL)) == FLASH_STATUS_WEL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool flash_verify(uint32_t flash_addr, const uint8_t *expected,
|
||||
@@ -156,7 +184,12 @@ void bsp_spi_flash_init(void)
|
||||
void bsp_spi_flash_reset(void)
|
||||
{
|
||||
spi_select(0);
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
flash_cmd(FLASH_CMD_RESET);
|
||||
#else
|
||||
flash_cmd(FLASH_CMD_RESET_ENABLE);
|
||||
flash_cmd(FLASH_CMD_RESET_MEMORY);
|
||||
#endif
|
||||
flash_delay_us(FLASH_RESET_DELAY_US);
|
||||
}
|
||||
|
||||
@@ -179,7 +212,11 @@ uint8_t bsp_spi_flash_read_status(void)
|
||||
|
||||
uint8_t bsp_spi_flash_read_config(void)
|
||||
{
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
return flash_read_register(FLASH_CMD_READ_CONFIG);
|
||||
#else
|
||||
return 0u;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bsp_spi_flash_read(uint32_t flash_addr, void *dst, uint32_t len)
|
||||
@@ -202,9 +239,13 @@ void bsp_spi_flash_read(uint32_t flash_addr, void *dst, uint32_t len)
|
||||
bool bsp_spi_flash_erase_sector(uint32_t flash_addr)
|
||||
{
|
||||
if ((flash_addr & (BSP_SPI_FLASH_SECTOR_SIZE - 1u)) != 0u ||
|
||||
!flash_range_valid(flash_addr, BSP_SPI_FLASH_SECTOR_SIZE) ||
|
||||
!flash_range_valid(flash_addr, BSP_SPI_FLASH_SECTOR_SIZE)
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
||
|
||||
((flash_addr >= (BSP_SPI_FLASH_SIZE - (2u * BSP_SPI_FLASH_SECTOR_SIZE))) &&
|
||||
((bsp_spi_flash_read_config() & BSP_SPI_FLASH_CONFIG_TBPARM) != 0u))) {
|
||||
((bsp_spi_flash_read_config() & BSP_SPI_FLASH_CONFIG_TBPARM) != 0u))
|
||||
#endif
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (!flash_wait_complete(FLASH_PROGRAM_TIMEOUT_US) || !flash_write_enable()) {
|
||||
|
||||
@@ -4,10 +4,29 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BSP_SPI_FLASH_PROFILE_S25FL256S 1
|
||||
#define BSP_SPI_FLASH_PROFILE_MT25QU01G 2
|
||||
#define BSP_SPI_FLASH_PROFILE_IS25WP512M 3
|
||||
|
||||
#ifndef BSP_SPI_FLASH_PROFILE
|
||||
#define BSP_SPI_FLASH_PROFILE BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
#endif
|
||||
|
||||
#if BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_S25FL256S
|
||||
#define BSP_SPI_FLASH_SIZE 0x02000000UL
|
||||
#define BSP_SPI_FLASH_JEDEC_ID 0x00010219UL
|
||||
#elif BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_MT25QU01G
|
||||
#define BSP_SPI_FLASH_SIZE 0x08000000UL
|
||||
#define BSP_SPI_FLASH_JEDEC_ID 0x0020bb21UL
|
||||
#elif BSP_SPI_FLASH_PROFILE == BSP_SPI_FLASH_PROFILE_IS25WP512M
|
||||
#define BSP_SPI_FLASH_SIZE 0x04000000UL
|
||||
#define BSP_SPI_FLASH_JEDEC_ID 0x009d701aUL
|
||||
#else
|
||||
#error "Unsupported BSP_SPI_FLASH_PROFILE"
|
||||
#endif
|
||||
|
||||
#define BSP_SPI_FLASH_PAGE_SIZE 256UL
|
||||
#define BSP_SPI_FLASH_SECTOR_SIZE 0x00010000UL
|
||||
#define BSP_SPI_FLASH_JEDEC_ID 0x00010219UL
|
||||
#define BSP_SPI_FLASH_CONFIG_TBPARM (1u << 2)
|
||||
|
||||
void bsp_spi_flash_init(void);
|
||||
|
||||
@@ -15,12 +15,13 @@ MABI ?= lp64d
|
||||
BSP_UART_CLOCK_HZ ?= 100000000
|
||||
BSP_UART_BAUDRATE ?= 460800
|
||||
BSP_CLINT_TIMEBASE_HZ ?= 1000000
|
||||
BSP_SPI_FLASH_PROFILE ?= 1
|
||||
BSP_DTIM_BASE ?= 0x80000000
|
||||
BSP_DTIM_SIZE ?= 0x00100000
|
||||
CONFIG_STAMP := $(BUILD_DIR)/build_config.txt
|
||||
|
||||
# C sees BSP_DTIM_* while ld sees __dtim_*; both come from the same Makefile knobs.
|
||||
CFLAGS ?= -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany -Os -ffreestanding -fno-builtin -fno-common -Wall -Wextra -I$(BSP_DIR)/include -DBSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)UL -DBSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)UL -DBSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)UL -DBSP_DTIM_BASE=$(BSP_DTIM_BASE)UL -DBSP_DTIM_SIZE=$(BSP_DTIM_SIZE)UL
|
||||
CFLAGS ?= -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany -Os -ffreestanding -fno-builtin -fno-common -Wall -Wextra -I$(BSP_DIR)/include -DBSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)UL -DBSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)UL -DBSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)UL -DBSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE) -DBSP_DTIM_BASE=$(BSP_DTIM_BASE)UL -DBSP_DTIM_SIZE=$(BSP_DTIM_SIZE)UL
|
||||
LDFLAGS ?= -T $(LINKER_SCRIPT) -nostartfiles -static -Wl,--gc-sections -Wl,--defsym=__dtim_base=$(BSP_DTIM_BASE) -Wl,--defsym=__dtim_size=$(BSP_DTIM_SIZE) -Wl,-Map,$(BUILD_DIR)/$(TARGET).map
|
||||
LDLIBS ?= -Wl,--start-group -lc -lgcc -Wl,--end-group
|
||||
|
||||
@@ -47,6 +48,7 @@ $(CONFIG_STAMP): FORCE | $(BUILD_DIR)
|
||||
'BSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)' \
|
||||
'BSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)' \
|
||||
'BSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)' \
|
||||
'BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
'BSP_DTIM_BASE=$(BSP_DTIM_BASE)' \
|
||||
'BSP_DTIM_SIZE=$(BSP_DTIM_SIZE)' \
|
||||
'GPS_DEBUG=$(GPS_DEBUG)' \
|
||||
|
||||
@@ -102,7 +102,9 @@ GPS_EPHEMERIS_FLASH_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_STORE_MAX_SLOTS ?= 0
|
||||
GPS_EPHEMERIS_FLASH_FORCE_FORMAT ?= 0
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
|
||||
GPS_EPHEMERIS_FLASH_BASE ?= 0x01fe0000
|
||||
GPS_NAV_CONTEXT_ENABLE ?= 1
|
||||
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x01fc0000
|
||||
GPS_PPS_STATUS_LOG_INTERVAL ?= 10
|
||||
GPS_PPS_DOPPLER_PREDICTOR_ENABLE ?= 1
|
||||
GPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES ?= 0
|
||||
@@ -123,7 +125,9 @@ CFLAGS += $(IMU_BACKEND_CFLAG) \
|
||||
-DGPS_EPHEMERIS_STORE_MAX_SLOTS=$(GPS_EPHEMERIS_STORE_MAX_SLOTS)u \
|
||||
-DGPS_EPHEMERIS_FLASH_FORCE_FORMAT=$(GPS_EPHEMERIS_FLASH_FORCE_FORMAT) \
|
||||
-DGPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL) \
|
||||
-DGPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)UL \
|
||||
-DGPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE) \
|
||||
-DGPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)UL \
|
||||
-DGPS_PPS_STATUS_LOG_INTERVAL=$(GPS_PPS_STATUS_LOG_INTERVAL) \
|
||||
-DGPS_PPS_DOPPLER_PREDICTOR_ENABLE=$(GPS_PPS_DOPPLER_PREDICTOR_ENABLE) \
|
||||
-DGPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES=$(GPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES)
|
||||
|
||||
@@ -144,10 +144,9 @@
|
||||
* 20 ms navigation bit; at a few ppm the 15 minute bound leaves
|
||||
* roughly two orders of magnitude of margin, and broadcast
|
||||
* ephemeris validity caps reuse well before that anyway. */
|
||||
/* Persistent ephemeris cache. The Genesys2 image places the
|
||||
* bitstream at 0 and the application at 0x01800000 on a 32 MiB
|
||||
* S25FL256S, so the last two 64 KiB sectors are free. Keeping the
|
||||
* store at the very top leaves the application region free to grow. */
|
||||
/* Persistent ephemeris cache. Board Makefiles place this store in
|
||||
* two reserved 64 KiB sectors near the top of the selected flash.
|
||||
* The defaults describe the 32 MiB Genesys2 layout. */
|
||||
#ifndef GPS_EPHEMERIS_FLASH_ENABLE
|
||||
#define GPS_EPHEMERIS_FLASH_ENABLE 1
|
||||
#endif
|
||||
@@ -170,8 +169,8 @@
|
||||
/*
|
||||
* Persistent navigation context (almanac, ionosphere model, last
|
||||
* position) in the two 64 KiB sectors immediately below the
|
||||
* ephemeris store. The application image lives at 0x01800000 and
|
||||
* is far smaller than the gap.
|
||||
* ephemeris store. Board Makefiles override both bases together for
|
||||
* larger flash devices.
|
||||
*/
|
||||
#ifndef GPS_NAV_CONTEXT_FLASH_BASE
|
||||
#define GPS_NAV_CONTEXT_FLASH_BASE 0x01FC0000UL
|
||||
|
||||
@@ -16,6 +16,30 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (GPS_EPHEMERIS_FLASH_ENABLE == 1)
|
||||
_Static_assert((GPS_EPHEMERIS_FLASH_BASE % BSP_SPI_FLASH_SECTOR_SIZE) == 0u,
|
||||
"ephemeris flash base must be sector aligned");
|
||||
_Static_assert(GPS_EPHEMERIS_FLASH_BASE <=
|
||||
(BSP_SPI_FLASH_SIZE - (2u * BSP_SPI_FLASH_SECTOR_SIZE)),
|
||||
"ephemeris store exceeds selected flash");
|
||||
#endif
|
||||
#if (GPS_NAV_CONTEXT_ENABLE == 1)
|
||||
_Static_assert((GPS_NAV_CONTEXT_FLASH_BASE % BSP_SPI_FLASH_SECTOR_SIZE) == 0u,
|
||||
"navigation context flash base must be sector aligned");
|
||||
_Static_assert(GPS_NAV_CONTEXT_FLASH_BASE <=
|
||||
(BSP_SPI_FLASH_SIZE - (2u * BSP_SPI_FLASH_SECTOR_SIZE)),
|
||||
"navigation context store exceeds selected flash");
|
||||
#endif
|
||||
#if ((GPS_EPHEMERIS_FLASH_ENABLE == 1) && (GPS_NAV_CONTEXT_ENABLE == 1))
|
||||
_Static_assert((GPS_NAV_CONTEXT_FLASH_BASE +
|
||||
(2u * BSP_SPI_FLASH_SECTOR_SIZE) <=
|
||||
GPS_EPHEMERIS_FLASH_BASE) ||
|
||||
(GPS_EPHEMERIS_FLASH_BASE +
|
||||
(2u * BSP_SPI_FLASH_SECTOR_SIZE) <=
|
||||
GPS_NAV_CONTEXT_FLASH_BASE),
|
||||
"persistent flash stores overlap");
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
GPS_ISR_EVENT_ACQ_DONE = 0,
|
||||
GPS_ISR_EVENT_TRK_STATUS
|
||||
|
||||
@@ -72,7 +72,10 @@ GPS_DEBUG_LEVEL ?= 1
|
||||
GPS_ESKF_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
|
||||
GPS_EPHEMERIS_FLASH_BASE ?= 0x01fe0000
|
||||
GPS_NAV_CONTEXT_ENABLE ?= 1
|
||||
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x01fc0000
|
||||
BSP_SPI_FLASH_PROFILE ?= 1
|
||||
IMU_SENSOR ?= auto
|
||||
|
||||
FLASH_MCS ?= $(OUT_DIR)/flash/genesys2_rocket.mcs
|
||||
@@ -180,7 +183,10 @@ help:
|
||||
' GPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)' \
|
||||
' GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)' \
|
||||
' GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)' \
|
||||
' GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)' \
|
||||
' BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
' IMU_SENSOR=$(IMU_SENSOR)' \
|
||||
' UART_PORT=$(UART_PORT)' \
|
||||
' ETH_RF_IFACE=$(ETH_RF_IFACE)' \
|
||||
@@ -222,17 +228,20 @@ fpga-config:
|
||||
' GPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)' \
|
||||
' GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)' \
|
||||
' GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)' \
|
||||
' GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)' \
|
||||
' BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
' IMU_SENSOR=$(IMU_SENSOR)' \
|
||||
' ETH_RF_IFACE=$(ETH_RF_IFACE)' \
|
||||
' ETH_RF_INPUT=$(ETH_RF_INPUT)' \
|
||||
' ETH_RF_SAMPLE_FORMAT=$(ETH_RF_SAMPLE_FORMAT)'
|
||||
|
||||
software:
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" bootloader flash-image
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" bootloader flash-image
|
||||
|
||||
$(APP_ELF): FORCE
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" app
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" app
|
||||
|
||||
chisel: software
|
||||
@cd "$(REPO_DIR)"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#-----------------------------------------------------------
|
||||
# Vivado v2025.2 (64-bit)
|
||||
# SW Build 6299465 on Fri Nov 14 12:34:56 MST 2025
|
||||
# IP Build 6300035 on Fri Nov 14 10:48:45 MST 2025
|
||||
# SharedData Build 6298862 on Thu Nov 13 04:50:51 MST 2025
|
||||
# Start of session at: Tue Jul 7 01:14:33 2026
|
||||
# Process ID : 505349
|
||||
# Current directory : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream
|
||||
# Command line : vivado
|
||||
# Log file : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream/vivado.log
|
||||
# Journal file : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream/vivado.jou
|
||||
# Running On : onur
|
||||
# Platform : Ubuntu
|
||||
# Operating System : Ubuntu 22.04.5 LTS
|
||||
# Processor Detail : AMD Ryzen 7 7800X3D 8-Core Processor
|
||||
# CPU Frequency : 4199.900 MHz
|
||||
# CPU Physical cores : 12
|
||||
# CPU Logical cores : 12
|
||||
# Host memory : 22112 MB
|
||||
# Swap memory : 2147 MB
|
||||
# Total Virtual : 24260 MB
|
||||
# Available Virtual : 20472 MB
|
||||
#-----------------------------------------------------------
|
||||
start_gui
|
||||
@@ -1,118 +0,0 @@
|
||||
#-----------------------------------------------------------
|
||||
# Vivado v2025.2 (64-bit)
|
||||
# SW Build 6299465 on Fri Nov 14 12:34:56 MST 2025
|
||||
# IP Build 6300035 on Fri Nov 14 10:48:45 MST 2025
|
||||
# SharedData Build 6298862 on Thu Nov 13 04:50:51 MST 2025
|
||||
# Start of session at: Tue Jul 7 01:14:33 2026
|
||||
# Process ID : 505349
|
||||
# Current directory : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream
|
||||
# Command line : vivado
|
||||
# Log file : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream/vivado.log
|
||||
# Journal file : /home/onur/Desktop/tmp/rocket-chip/targets/fpga/genesys2/out/bitstream/vivado.jou
|
||||
# Running On : onur
|
||||
# Platform : Ubuntu
|
||||
# Operating System : Ubuntu 22.04.5 LTS
|
||||
# Processor Detail : AMD Ryzen 7 7800X3D 8-Core Processor
|
||||
# CPU Frequency : 4199.900 MHz
|
||||
# CPU Physical cores : 12
|
||||
# CPU Logical cores : 12
|
||||
# Host memory : 22112 MB
|
||||
# Swap memory : 2147 MB
|
||||
# Total Virtual : 24260 MB
|
||||
# Available Virtual : 20472 MB
|
||||
#-----------------------------------------------------------
|
||||
start_gui
|
||||
Sourcing tcl script '/home/onur/.Xilinx/Vivado/Vivado_init.tcl'
|
||||
Configured Digilent board repo: /home/onur/.local/share/digilent-vivado-boards/new/board_files
|
||||
WARNING: [Board 49-26] cannot add Board Part digilentinc.com:gzu_3eg:part0:1.0 available at /home/onur/.local/share/digilent-vivado-boards/new/board_files/genesys-zu-3eg/B.0/board.xml as part xczu3eg-sfvc784-1-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part digilentinc.com:gzu_3eg:part0:1.1 available at /home/onur/.local/share/digilent-vivado-boards/new/board_files/genesys-zu-3eg/D.0/board.xml as part xczu3eg-sfvc784-1-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part digilentinc.com:gzu_5ev:part0:1.1 available at /home/onur/.local/share/digilent-vivado-boards/new/board_files/genesys-zu-5ev/C.0/board.xml as part xczu5ev-sfvc784-1-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:emb-plus-vpr-4616:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/emb-plus-vpr-4616/1.0/board.xml as part xcve2302-sfva784-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:emb-plus-vpr-4616:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/emb-plus-vpr-4616/1.1/board.xml as part xcve2302-sfva784-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k24c:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k24c/1.0/board.xml as part xck24-ubva530-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k24c:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k24c/1.1/board.xml as part xck24-ubva530-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k24i:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k24i/1.0/board.xml as part xck24-ubva530-2lvi-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26c:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26c/1.2/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26c:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26c/1.3/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26c:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26c/1.4/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26i:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26i/1.2/board.xml as part xck26-sfvc784-2lvi-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26i:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26i/1.3/board.xml as part xck26-sfvc784-2lvi-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:k26i:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/k26i/1.4/board.xml as part xck26-sfvc784-2lvi-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kcu105:part0:1.6 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kcu105/1.6/board.xml as part xcku040-ffva1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kcu105:part0:1.7 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kcu105/1.7/board.xml as part xcku040-ffva1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kcu116:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kcu116/1.4/board.xml as part xcku5p-ffvb676-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kcu116:part0:1.5 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kcu116/1.5/board.xml as part xcku5p-ffvb676-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kcu1500:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kcu1500/1.2/board.xml as part xcku115-flvb2104-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kd240_som:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kd240_som/1.0/board.xml as part xck24-ubva530-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kd240_som:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kd240_som/1.1/board.xml as part xck24-ubva530-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kr260_som:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kr260_som/1.0/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kr260_som:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kr260_som/1.1/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kv260_som:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kv260_som/1.2/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kv260_som:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kv260_som/1.3/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:kv260_som:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/kv260_som/1.4/board.xml as part xck26-sfvc784-2lv-c specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:scu35:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/scu35/1.0/board.xml as part xcsu35p-sbvb625-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:v80:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/v80/1.0/board.xml as part xcv80-lsva4737-2mhp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:2.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/2.2/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:3.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/3.0/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:3.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/3.1/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:3.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/3.2/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:3.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/3.3/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190:part0:3.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190/production/3.4/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190_newl:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190_newl/production/1.0/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190_newl:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190_newl/production/1.1/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190_newl:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190_newl/production/1.2/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vck190_newl:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vck190_newl/production/1.3/board.xml as part xcvc1902-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu108:part0:1.6 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu108/1.6/board.xml as part xcvu095-ffva2104-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu108:part0:1.7 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu108/1.7/board.xml as part xcvu095-ffva2104-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu110:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu110/1.4/board.xml as part xcvu190-flgc2104-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu118:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu118/2.0/board.xml as part xcvu9p-flga2104-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu118:part0:2.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu118/2.3/board.xml as part xcvu9p-flga2104-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu118:part0:2.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu118/2.4/board.xml as part xcvu9p-flga2104-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu128:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu128/production/1.0/board.xml as part xcvu37p-fsvh2892-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu129:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu129/production/1.0/board.xml as part xcvu29p-fsga2577-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vcu1525:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vcu1525/1.3/board.xml as part xcvu9p-fsgd2104-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek280:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek280/production/1.0/board.xml as part xcve2802-vsvh1760-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek280:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek280/production/1.1/board.xml as part xcve2802-vsvh1760-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek280:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek280/production/1.2/board.xml as part xcve2802-vsvh1760-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek385:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek385/1.0/board.xml as part xc2ve3858-ssva2112-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek385:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek385/1.1/board.xml as part xc2ve3858-ssva2112-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vek385_1:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vek385_2/1.0/board.xml as part xc2ve3858-ssva2112-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vermeo_t1_mpsoc:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vermeo_t1_mpsoc/1.0/board.xml as part xczu19eg-ffvd1760-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vermeo_t1_rfsoc:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vermeo_t1_rfsoc/1.0/board.xml as part xczu21dr-ffvd1156-2l-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vhk158:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vhk158/production/1.0/board.xml as part xcvh1582-vsva3697-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vhk158:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vhk158/production/1.1/board.xml as part xcvh1582-vsva3697-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vhk158:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vhk158/production/1.2/board.xml as part xcvh1582-vsva3697-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180:part0:2.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180/production/2.2/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180:part0:3.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180/production/3.0/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180:part0:3.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180/production/3.1/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180:part0:3.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180/production/3.2/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180:part0:3.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180/production/3.3/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180_newl:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180_newl/production/1.0/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vmk180_newl:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vmk180_newl/production/1.1/board.xml as part xcvm1802-vsva2197-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk120:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk120/production/1.0/board.xml as part xcvp1202-vsva2785-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk120:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk120/production/1.1/board.xml as part xcvp1202-vsva2785-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk120:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk120/production/1.2/board.xml as part xcvp1202-vsva2785-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk180:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk180/production/1.0/board.xml as part xcvp1802-lsvc4072-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk180:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk180/production/1.1/board.xml as part xcvp1802-lsvc4072-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vpk180:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vpk180/production/1.2/board.xml as part xcvp1802-lsvc4072-2mp-e-s specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vrk160:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vrk160/1.0/board.xml as part xcvr1602-vsva2488-2mp-e-s-es1 specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:vrk160:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/vrk160/1.1/board.xml as part xcvr1602-vsva2488-2mp-e-s-es1 specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu102:part0:3.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu102/3.3/board.xml as part xczu9eg-ffvb1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu102:part0:3.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu102/3.4/board.xml as part xczu9eg-ffvb1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu104:part0:1.1 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu104/1.1/board.xml as part xczu7ev-ffvc1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu106:part0:2.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu106/2.4/board.xml as part xczu7ev-ffvc1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu106:part0:2.5 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu106/2.5/board.xml as part xczu7ev-ffvc1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu106:part0:2.6 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu106/2.6/board.xml as part xczu7ev-ffvc1156-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu111:part0:1.2 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu111/1.2/board.xml as part xczu28dr-ffvg1517-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu111:part0:1.3 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu111/1.3/board.xml as part xczu28dr-ffvg1517-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu111:part0:1.4 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu111/1.4/board.xml as part xczu28dr-ffvg1517-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu1275:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu1275/1.0/board.xml as part xczu29dr-ffvf1760-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu1285:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu1285/1.0/board.xml as part xczu39dr-ffvf1760-2-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu208:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu208/production/2.0/board.xml as part xczu48dr-fsvg1517-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu208ld:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu208ld/production/2.0/board.xml as part xczu58dr-fsvg1517-2-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu216:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu216/production/2.0/board.xml as part xczu49dr-ffvf1760-2-e specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu216ld:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu216ld/production/2.0/board.xml as part xczu59dr-ffvf1760-2-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu670:part0:2.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu670/2.0/board.xml as part xczu67dr-fsve1156-2-i specified in board_part file is either invalid or not available
|
||||
WARNING: [Board 49-26] cannot add Board Part xilinx.com:zcu670ld:part0:1.0 available at /tools/Xilinx/2025.2/data/xhub/boards/XilinxBoardStore/boards/Xilinx/zcu670ld/1.0/board.xml as part xczu57dr-fsve1156-2-i specified in board_part file is either invalid or not available
|
||||
exit
|
||||
INFO: [Common 17-206] Exiting Vivado at Tue Jul 7 01:14:42 2026...
|
||||
@@ -0,0 +1,12 @@
|
||||
/out/
|
||||
/flow/efinity/ti375c529_rocket.isf
|
||||
/flow/efinity/ti375c529_rocket.peri.xml
|
||||
/flow/efinity/ti375c529_rocket.pt.sdc
|
||||
/flow/efinity/ti375c529_rocket.pt.rpt
|
||||
/flow/efinity/ti375c529_rocket.pinout.*
|
||||
/flow/efinity/ti375c529_rocket.interface.csv
|
||||
/flow/efinity/ti375c529_rocket_template.v
|
||||
/flow/efinity/outflow/
|
||||
/flow/efinity/work_pnr/
|
||||
/flow/efinity/work_syn/
|
||||
/flow/efinity/RUNPNR_*
|
||||
@@ -0,0 +1,438 @@
|
||||
SHELL := /bin/bash
|
||||
.SHELLFLAGS := -euo pipefail -c
|
||||
.ONESHELL:
|
||||
|
||||
FPGA_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
REPO_DIR := $(abspath $(FPGA_DIR)/../../..)
|
||||
SOC_SW_DIR := $(REPO_DIR)/soc/software
|
||||
SOC_OUT_DIR := $(REPO_DIR)/soc/out
|
||||
HW_DIR := $(REPO_DIR)/hardware
|
||||
HW_GENERATED_DIR := $(HW_DIR)/generated
|
||||
GPS_SYSTEM_DIR ?= $(HW_DIR)/external/gps/rtl
|
||||
FLOW_DIR := $(FPGA_DIR)/flow/efinity
|
||||
DEBUG_DIR := $(FPGA_DIR)/flow/debug
|
||||
TOOL_SCRIPT_DIR := $(FPGA_DIR)/tools
|
||||
OUT_DIR := $(FPGA_DIR)/out
|
||||
LOG_DIR := $(OUT_DIR)/logs
|
||||
|
||||
include $(REPO_DIR)/tools/project.mk
|
||||
|
||||
BOARD ?= ti375c529
|
||||
DEVICE ?= Ti375C529
|
||||
TIMING_MODEL ?= C4
|
||||
SOC_CLK_HZ ?= 100000000
|
||||
GPS_ACQ_CLK_HZ ?= 100000000
|
||||
GPS_TRCK_CLK_HZ ?= 125000000
|
||||
GPS_RF_CLK_HZ ?= 16367981
|
||||
RF_INPUT_MODE ?= pmod
|
||||
UART_PORT ?= /dev/ttyUSB2
|
||||
UART_BAUD ?= 460800
|
||||
OPENOCD ?= $(shell command -v openocd)
|
||||
OPENOCD_ADAPTER_SPEED ?= 1000
|
||||
GDB_HOST ?= localhost
|
||||
GDB_PORT ?= 3333
|
||||
GDB ?= $(firstword $(wildcard /tools/toolchain/bin/riscv64-unknown-elf-gdb) $(CROSS)gdb)
|
||||
# Leave empty for Efinity's board-profile auto-detection. Boards without an
|
||||
# FTDI serial number require a bus/device-qualified URL, which changes after
|
||||
# re-enumeration; users with multiple boards can override this explicitly.
|
||||
FTDI_URL ?=
|
||||
BSP_UART_CLOCK_HZ ?= $(SOC_CLK_HZ)
|
||||
BSP_UART_BAUDRATE ?= $(UART_BAUD)
|
||||
BSP_CLINT_TIMEBASE_HZ ?= 1000000
|
||||
DTIM_BASE ?= 0x80000000
|
||||
DTIM_SIZE ?= 0x00100000
|
||||
# The compressed Ti375 configuration currently occupies about 5.2 MB.
|
||||
# Keep the application on a 64-KiB boundary with ample growth margin.
|
||||
APP_FLASH_OFFSET ?= 0x00800000
|
||||
FLASH_SIZE ?= 0x04000000
|
||||
GPS_DEBUG ?= 1
|
||||
GPS_DEBUG_LEVEL ?= 4
|
||||
GPS_ESKF_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
|
||||
GPS_EPHEMERIS_FLASH_BASE ?= 0x03fe0000
|
||||
GPS_NAV_CONTEXT_ENABLE ?= 1
|
||||
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x03fc0000
|
||||
BSP_SPI_FLASH_PROFILE ?= 3
|
||||
IMU_SENSOR ?= auto
|
||||
app ?=
|
||||
ifneq ($(strip $(app)),)
|
||||
APP ?= $(app)
|
||||
else
|
||||
APP ?= hello_uart
|
||||
endif
|
||||
|
||||
FIRRTL_DIR ?= $(HW_GENERATED_DIR)/ti375c529-soc
|
||||
VERILOG_DIR ?= $(HW_GENERATED_DIR)/ti375c529-soc-verilog
|
||||
WRAPPER := $(OUT_DIR)/build/generated/ti375c529_rocket_top.sv
|
||||
GPS_EFINITY_DIR := $(OUT_DIR)/build/generated/gps_efinity
|
||||
SOURCE_LIST := $(OUT_DIR)/build/efinity_sources.f
|
||||
PROJECT_XML := $(FLOW_DIR)/ti375c529_rocket.xml
|
||||
INTERFACE_SOURCE := $(HW_DIR)/fpga/ti375c529/constraints/ti375c529_rocket.isf
|
||||
INTERFACE_SCRIPT := $(FLOW_DIR)/ti375c529_rocket.isf
|
||||
BIT_FILE ?= $(OUT_DIR)/bitstream/ti375c529_rocket.bit
|
||||
CONFIG_HEX ?= $(OUT_DIR)/bitstream/ti375c529_rocket.hex
|
||||
APP_ELF ?= $(SOC_OUT_DIR)/software/$(APP)/$(APP).elf
|
||||
APP_FLASH_IMAGE ?= $(SOC_OUT_DIR)/flash/$(APP).flash.bin
|
||||
FLASH_DIR := $(OUT_DIR)/flash
|
||||
FLASH_REGION_DIR := $(FLASH_DIR)/regions
|
||||
APP_HEX ?= $(FLASH_REGION_DIR)/app.hex
|
||||
FLASH_HEX ?= $(FLASH_DIR)/ti375c529_rocket.hex
|
||||
FLASH_MANIFEST ?= $(FLASH_DIR)/ti375c529_rocket.json
|
||||
FLASH_LOADER ?= $(EFINITY_HOME)/pgm/fli/titanium/u006A0A79.bit
|
||||
FLASH_VERIFY ?= onchipx2
|
||||
OPENOCD_CFG ?= $(DEBUG_DIR)/openocd_ti375c529_bscan.cfg
|
||||
GDB_LOAD_SCRIPT ?= $(DEBUG_DIR)/gdb_load_and_run.gdb
|
||||
GDB_ATTACH_SCRIPT ?= $(DEBUG_DIR)/gdb_attach.gdb
|
||||
|
||||
.PHONY: help all fpga-config detect software chisel rtl soc interface map bitstream \
|
||||
program-fpga debug-openocd debug-load debug-gdb uart-listen \
|
||||
flash-image flash-regions program-flash program-flash-elf \
|
||||
program-flash-bitstream program-flash-regions program-flash-all \
|
||||
program-flash-combined program-flash-loader program-app program-bitstream \
|
||||
clean clean-sw clean-fpga FORCE
|
||||
|
||||
help:
|
||||
@printf '%s\n' \
|
||||
'Ti375C529 Efinity targets:' \
|
||||
' make detect Scan USB and read the Ti375 JTAG IDCODE' \
|
||||
' make software Build the Rocket boot ROM and selected RV64 app' \
|
||||
' make chisel Emit Rocket FIRRTL with the existing FPGA config' \
|
||||
' make rtl Emit split SystemVerilog, Efinix shell, and file list' \
|
||||
' make interface Generate Efinity pin/PLL/JTAG interface data' \
|
||||
' make map Run Efinity synthesis only' \
|
||||
' make bitstream Run the complete Efinity flow' \
|
||||
' make program-fpga Load BIT_FILE into Ti375 SRAM over JTAG' \
|
||||
' make flash-image Generate combined Lower-flash Efinity HEX' \
|
||||
' make program-flash Program only the application flash region' \
|
||||
' make program-flash-bitstream' \
|
||||
' Program only the configuration region' \
|
||||
' make program-flash-combined' \
|
||||
' Program configuration + application HEX' \
|
||||
' make debug-openocd Start Rocket DMI/GDB server through JTAG_USER1' \
|
||||
' make debug-load Load APP ELF into DTIM through GDB' \
|
||||
' make uart-listen Listen to FTDI UART interface 2' \
|
||||
' make fpga-config Print resolved tools, clocks, files, and USB config'
|
||||
|
||||
all: bitstream
|
||||
|
||||
fpga-config:
|
||||
@printf '%s\n' \
|
||||
'Ti375C529 FPGA config:' \
|
||||
' EFINITY_HOME=$(EFINITY_HOME)' \
|
||||
' EFX_RUN=$(EFX_RUN)' \
|
||||
' EFX_PGM=$(EFX_PGM)' \
|
||||
' OPENOCD=$(OPENOCD)' \
|
||||
' GDB=$(GDB)' \
|
||||
' DEVICE=$(DEVICE)' \
|
||||
' TIMING_MODEL=$(TIMING_MODEL)' \
|
||||
' SOC_CLK_HZ=$(SOC_CLK_HZ)' \
|
||||
' GPS_ACQ_CLK_HZ=$(GPS_ACQ_CLK_HZ)' \
|
||||
' GPS_TRCK_CLK_HZ=$(GPS_TRCK_CLK_HZ)' \
|
||||
' GPS_RF_CLK_HZ=$(GPS_RF_CLK_HZ)' \
|
||||
' RF_INPUT_MODE=$(RF_INPUT_MODE)' \
|
||||
' BIT_FILE=$(BIT_FILE)' \
|
||||
' CONFIG_HEX=$(CONFIG_HEX)' \
|
||||
' FLASH_HEX=$(FLASH_HEX)' \
|
||||
' APP_FLASH_OFFSET=$(APP_FLASH_OFFSET)' \
|
||||
' GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)' \
|
||||
' GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)' \
|
||||
' GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)' \
|
||||
' GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)' \
|
||||
' BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
' FLASH_LOADER=$(FLASH_LOADER)' \
|
||||
' FTDI_URL=$(FTDI_URL)' \
|
||||
' UART_PORT=$(UART_PORT)' \
|
||||
' UART_BAUD=$(UART_BAUD)'
|
||||
|
||||
detect:
|
||||
@set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
"$(EFX_PGM)" --scan_usb
|
||||
|
||||
software:
|
||||
@$(MAKE) -C "$(SOC_SW_DIR)" \
|
||||
TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" \
|
||||
APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" \
|
||||
BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" \
|
||||
BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" \
|
||||
GPS_SYSTEM_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" \
|
||||
BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" \
|
||||
BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" \
|
||||
GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" \
|
||||
GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" \
|
||||
GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" \
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" \
|
||||
GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" \
|
||||
GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" \
|
||||
GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" \
|
||||
BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" \
|
||||
IMU_SENSOR="$(IMU_SENSOR)" \
|
||||
bootloader flash-image
|
||||
|
||||
$(APP_ELF): FORCE
|
||||
@$(MAKE) -C "$(SOC_SW_DIR)" \
|
||||
TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" \
|
||||
BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" \
|
||||
BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" \
|
||||
GPS_SYSTEM_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" \
|
||||
BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" \
|
||||
BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" \
|
||||
GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" \
|
||||
GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" \
|
||||
GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" \
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" \
|
||||
GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" \
|
||||
GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" \
|
||||
GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" \
|
||||
BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" \
|
||||
IMU_SENSOR="$(IMU_SENSOR)" app
|
||||
|
||||
chisel: software
|
||||
@cd "$(REPO_DIR)"
|
||||
"$(MILL)" -i 'rocketchip[6.7.0].assembly'
|
||||
rm -rf "$(FIRRTL_DIR)"
|
||||
mkdir -p "$(FIRRTL_DIR)"
|
||||
"$(JAVA_HOME)/bin/java" \
|
||||
-DROCKET_DTIM_BASE="$(DTIM_BASE)" \
|
||||
-DROCKET_DTIM_SIZE="$(DTIM_SIZE)" \
|
||||
-DROCKET_SOC_CLOCK_HZ="$(SOC_CLK_HZ)" \
|
||||
-jar out/rocketchip/6.7.0/assembly.dest/out.jar \
|
||||
--dir "$(FIRRTL_DIR)" \
|
||||
--top freechips.rocketchip.fpga.VCU118RocketSystem \
|
||||
--config freechips.rocketchip.fpga.VCU118RocketConfig
|
||||
|
||||
rtl: chisel
|
||||
@cd "$(REPO_DIR)"
|
||||
rm -rf "$(VERILOG_DIR)"
|
||||
mkdir -p "$(VERILOG_DIR)" "$(dir $(WRAPPER))"
|
||||
$(FIRTOOL_ENV) "$(FIRTOOL)" \
|
||||
"$(FIRRTL_DIR)/VCU118RocketSystem.fir" \
|
||||
--split-verilog -o "$(VERILOG_DIR)" \
|
||||
--preserve-aggregate=none \
|
||||
--disable-annotation-unknown \
|
||||
--disable-all-randomization \
|
||||
--strip-debug-info
|
||||
find "$(VERILOG_DIR)" -maxdepth 1 -type f \( -name '*.sv' -o -name '*.v' \) \
|
||||
-printf './%f\n' | sort > "$(VERILOG_DIR)/filelist.f"
|
||||
perl -0pi -e 's/^([ \t]*)if \([^\n]*\)\n[ \t]*assert__[^\n]*:\s*assert\([^\n]*\);\n//mg; s/^[ \t]*assert__[^\n]*:\s*assert\([^\n]*\);\n//mg' "$(VERILOG_DIR)"/*.sv
|
||||
python3 "$(TOOL_SCRIPT_DIR)/prepare_efinity_rtl.py" \
|
||||
--verilog-dir "$(VERILOG_DIR)" \
|
||||
--gps-source-dir "$(GPS_SYSTEM_DIR)" \
|
||||
--gps-output-dir "$(GPS_EFINITY_DIR)"
|
||||
python3 "$(TOOL_SCRIPT_DIR)/gen_ti375c529_wrapper.py" \
|
||||
--rocket-top "$(VERILOG_DIR)/VCU118RocketSystem.sv" \
|
||||
--out "$(WRAPPER)"
|
||||
: > "$(SOURCE_LIST)"
|
||||
while IFS= read -r rel; do
|
||||
rel="$${rel#./}"
|
||||
printf '%s\n' "$(VERILOG_DIR)/$$rel" >> "$(SOURCE_LIST)"
|
||||
done < "$(VERILOG_DIR)/filelist.f"
|
||||
printf '%s\n' "$(HW_DIR)/upstream/rocket-chip/src/main/resources/vsrc/plusarg_reader.v" >> "$(SOURCE_LIST)"
|
||||
while IFS= read -r rel; do
|
||||
[[ -z "$$rel" || "$$rel" == \#* ]] && continue
|
||||
case "$$rel" in
|
||||
trck_src/xil_fifo.sv|trck_src/pulp_fifo/top.sv) continue ;;
|
||||
acq_src/acq_nco_carr.sv)
|
||||
printf '%s\n' "$(GPS_EFINITY_DIR)/acq_nco_carr.sv" >> "$(SOURCE_LIST)"
|
||||
continue ;;
|
||||
acq_src/twiddle_ram.sv)
|
||||
printf '%s\n' "$(GPS_EFINITY_DIR)/twiddle_ram.sv" >> "$(SOURCE_LIST)"
|
||||
continue ;;
|
||||
trck_src/NCO_carr.sv)
|
||||
printf '%s\n' "$(GPS_EFINITY_DIR)/NCO_carr.sv" >> "$(SOURCE_LIST)"
|
||||
continue ;;
|
||||
esac
|
||||
printf '%s\n' "$(GPS_SYSTEM_DIR)/$$rel" >> "$(SOURCE_LIST)"
|
||||
done < "$(GPS_SYSTEM_DIR)/filelist.f"
|
||||
printf '%s\n' "$(HW_DIR)/ip/max2771_spi/rtl/max2771_spi_engine.sv" >> "$(SOURCE_LIST)"
|
||||
# Efinix JTAG_USER1 has the same two-bit TDO lead-in as the Kintex-7
|
||||
# BSCANE2 path, so use the Genesys2-aligned Rocket DMI tunnel.
|
||||
printf '%s\n' "$(HW_DIR)/fpga/genesys2/rtl/rocket_bscan_dmi_tunnel.sv" >> "$(SOURCE_LIST)"
|
||||
$(MAKE) -C "$(FPGA_DIR)" "$(INTERFACE_SCRIPT)"
|
||||
|
||||
soc: rtl
|
||||
|
||||
$(INTERFACE_SCRIPT): $(INTERFACE_SOURCE)
|
||||
cp "$<" "$@"
|
||||
|
||||
interface: $(INTERFACE_SCRIPT)
|
||||
@mkdir -p "$(LOG_DIR)"
|
||||
cd "$(FLOW_DIR)"
|
||||
# Efinity prefers a matching generated .peri.xml over the source .isf.
|
||||
# Remove it so pin/PLL changes in the checked-in interface script are applied.
|
||||
rm -f "$(FLOW_DIR)/ti375c529_rocket.peri.xml"
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
python3 "$(EFX_RUN)" "$(PROJECT_XML)" --flow interface --un_flow \
|
||||
--pt_opts "peri_scripts=$(INTERFACE_SCRIPT)" 2>&1 | tee "$(LOG_DIR)/interface.log"
|
||||
|
||||
map: rtl interface
|
||||
@mkdir -p "$(LOG_DIR)"
|
||||
cd "$(FLOW_DIR)"
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
python3 "$(EFX_RUN)" "$(PROJECT_XML)" --flow map 2>&1 | tee "$(LOG_DIR)/map.log"
|
||||
|
||||
bitstream: rtl interface
|
||||
@mkdir -p "$(LOG_DIR)" "$(dir $(BIT_FILE))"
|
||||
cd "$(FLOW_DIR)"
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
: > "$(LOG_DIR)/full.log"
|
||||
python3 "$(EFX_RUN)" "$(PROJECT_XML)" --flow map 2>&1 | tee -a "$(LOG_DIR)/full.log"
|
||||
python3 "$(EFX_RUN)" "$(PROJECT_XML)" --flow pnr --work_dir work_pnr 2>&1 | tee -a "$(LOG_DIR)/full.log"
|
||||
python3 "$(EFX_RUN)" "$(PROJECT_XML)" --flow pgm --work_dir work_pnr 2>&1 | tee -a "$(LOG_DIR)/full.log"
|
||||
generated_bit="$$(find "$(FLOW_DIR)/outflow" "$(OUT_DIR)" -type f -name 'ti375c529_rocket.bit' 2>/dev/null | head -n 1)"
|
||||
if [[ -z "$$generated_bit" ]]; then
|
||||
echo "Efinity completed without a discoverable ti375c529_rocket.bit" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$$generated_bit" != "$(BIT_FILE)" ]]; then
|
||||
cp "$$generated_bit" "$(BIT_FILE)"
|
||||
fi
|
||||
generated_hex="$$(find "$(FLOW_DIR)/outflow" "$(OUT_DIR)" -type f -name 'ti375c529_rocket.hex' ! -path '$(FLASH_DIR)/*' 2>/dev/null | head -n 1)"
|
||||
if [[ -z "$$generated_hex" ]]; then
|
||||
echo "Efinity completed without a discoverable ti375c529_rocket.hex" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$$generated_hex" != "$(CONFIG_HEX)" ]]; then
|
||||
cp "$$generated_hex" "$(CONFIG_HEX)"
|
||||
fi
|
||||
printf 'Bitstream: %s\nConfiguration HEX: %s\n' "$(BIT_FILE)" "$(CONFIG_HEX)"
|
||||
|
||||
program-fpga:
|
||||
@if [[ ! -f "$(BIT_FILE)" ]]; then
|
||||
echo "Missing bitstream: $(BIT_FILE)" >&2
|
||||
echo "Run: make -C $(FPGA_DIR) bitstream" >&2
|
||||
exit 1
|
||||
fi
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
ftdi_args=()
|
||||
if [[ -n "$(FTDI_URL)" ]]; then
|
||||
ftdi_args+=(--url "$(FTDI_URL)")
|
||||
fi
|
||||
"$(EFX_PGM)" --mode jtag "$${ftdi_args[@]}" "$(BIT_FILE)"
|
||||
|
||||
debug-openocd:
|
||||
@"$(OPENOCD)" \
|
||||
-c "set ADAPTER_SPEED $(OPENOCD_ADAPTER_SPEED)" \
|
||||
-c "gdb_port $(GDB_PORT)" \
|
||||
-f "$(OPENOCD_CFG)"
|
||||
|
||||
debug-load: $(APP_ELF)
|
||||
@"$(GDB)" -q "$(APP_ELF)" \
|
||||
-ex "set confirm off" \
|
||||
-ex "set pagination off" \
|
||||
-ex "target extended-remote $(GDB_HOST):$(GDB_PORT)" \
|
||||
-x "$(GDB_LOAD_SCRIPT)"
|
||||
|
||||
debug-gdb: $(APP_ELF)
|
||||
@"$(GDB)" -q "$(APP_ELF)" \
|
||||
-ex "set confirm off" \
|
||||
-ex "set pagination off" \
|
||||
-ex "target extended-remote $(GDB_HOST):$(GDB_PORT)" \
|
||||
-x "$(GDB_ATTACH_SCRIPT)"
|
||||
|
||||
uart-listen:
|
||||
@stty -F "$(UART_PORT)" "$(UART_BAUD)" cs8 -cstopb -parenb -ixon -ixoff raw
|
||||
@cat "$(UART_PORT)"
|
||||
|
||||
flash-image: flash-regions
|
||||
|
||||
flash-regions: software
|
||||
@if [[ ! -f "$(CONFIG_HEX)" ]]; then
|
||||
echo "Missing Efinity configuration HEX: $(CONFIG_HEX)" >&2
|
||||
echo "Run: make -C $(FPGA_DIR) bitstream" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$(FLASH_DIR)" "$(FLASH_REGION_DIR)"
|
||||
python3 "$(TOOL_SCRIPT_DIR)/make_flash_hex.py" \
|
||||
--config-hex "$(CONFIG_HEX)" \
|
||||
--app-bin "$(APP_FLASH_IMAGE)" \
|
||||
--app-offset "$(APP_FLASH_OFFSET)" \
|
||||
--flash-size "$(FLASH_SIZE)" \
|
||||
--nav-context-offset "$(GPS_NAV_CONTEXT_FLASH_BASE)" \
|
||||
--ephemeris-offset "$(GPS_EPHEMERIS_FLASH_BASE)" \
|
||||
--combined-hex "$(FLASH_HEX)" \
|
||||
--app-hex "$(APP_HEX)" \
|
||||
--manifest "$(FLASH_MANIFEST)"
|
||||
|
||||
program-flash-loader:
|
||||
@if [[ ! -f "$(FLASH_LOADER)" ]]; then
|
||||
echo "Missing Ti375 JTAG-to-SPI loader: $(FLASH_LOADER)" >&2
|
||||
exit 1
|
||||
fi
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
ftdi_args=()
|
||||
if [[ -n "$(FTDI_URL)" ]]; then
|
||||
ftdi_args+=(--url "$(FTDI_URL)")
|
||||
fi
|
||||
"$(EFX_PGM)" --mode jtag "$${ftdi_args[@]}" "$(FLASH_LOADER)"
|
||||
|
||||
program-flash program-flash-elf program-app: flash-regions
|
||||
@$(MAKE) -C "$(FPGA_DIR)" program-flash-loader
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
ftdi_args=()
|
||||
if [[ -n "$(FTDI_URL)" ]]; then
|
||||
ftdi_args+=(--url "$(FTDI_URL)")
|
||||
fi
|
||||
"$(EFX_PGM)" --mode jtag_bridge --jtag_bridge_mode all \
|
||||
--verify_method "$(FLASH_VERIFY)" --address "$(APP_FLASH_OFFSET)" \
|
||||
"$${ftdi_args[@]}" "$(APP_HEX)"
|
||||
|
||||
program-flash-bitstream program-bitstream:
|
||||
@if [[ ! -f "$(CONFIG_HEX)" ]]; then
|
||||
echo "Missing Efinity configuration HEX: $(CONFIG_HEX)" >&2
|
||||
echo "Run: make -C $(FPGA_DIR) bitstream" >&2
|
||||
exit 1
|
||||
fi
|
||||
$(MAKE) -C "$(FPGA_DIR)" program-flash-loader
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
ftdi_args=()
|
||||
if [[ -n "$(FTDI_URL)" ]]; then
|
||||
ftdi_args+=(--url "$(FTDI_URL)")
|
||||
fi
|
||||
"$(EFX_PGM)" --mode jtag_bridge --jtag_bridge_mode all \
|
||||
--verify_method "$(FLASH_VERIFY)" --address 0 \
|
||||
"$${ftdi_args[@]}" "$(CONFIG_HEX)"
|
||||
|
||||
program-flash-regions program-flash-all program-flash-combined: flash-image
|
||||
@$(MAKE) -C "$(FPGA_DIR)" program-flash-loader
|
||||
set +u
|
||||
source "$(EFINITY_SETUP)" >/dev/null 2>&1
|
||||
set -u
|
||||
ftdi_args=()
|
||||
if [[ -n "$(FTDI_URL)" ]]; then
|
||||
ftdi_args+=(--url "$(FTDI_URL)")
|
||||
fi
|
||||
"$(EFX_PGM)" --mode jtag_bridge --jtag_bridge_mode all \
|
||||
--verify_method "$(FLASH_VERIFY)" --address 0 \
|
||||
"$${ftdi_args[@]}" "$(FLASH_HEX)"
|
||||
|
||||
clean-sw:
|
||||
@$(MAKE) -C "$(SOC_SW_DIR)" clean
|
||||
|
||||
clean-fpga:
|
||||
rm -rf "$(OUT_DIR)" "$(FIRRTL_DIR)" "$(VERILOG_DIR)"
|
||||
rm -f "$(INTERFACE_SCRIPT)" \
|
||||
"$(FLOW_DIR)/ti375c529_rocket.peri.xml" \
|
||||
"$(FLOW_DIR)/ti375c529_rocket.pt.sdc" \
|
||||
"$(FLOW_DIR)/ti375c529_rocket.pt.rpt"
|
||||
|
||||
clean: clean-fpga
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,175 @@
|
||||
# Ti375C529 Rocket FPGA flow
|
||||
|
||||
This target keeps the project's RV64 Rocket/GPS subsystem in FPGA fabric and
|
||||
replaces only the Xilinx board shell and build flow with Efinix equivalents.
|
||||
It does not use the Ti375 hardened RV32 subsystem.
|
||||
|
||||
Detailed porting, synthesis, clocking, JTAG, and verification notes are in
|
||||
[`flow/efinity/README.md`](flow/efinity/README.md).
|
||||
|
||||
## Build and program
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-config
|
||||
make FPGA_BOARD=ti375c529 fpga-rtl
|
||||
make FPGA_BOARD=ti375c529 fpga-bitstream
|
||||
make FPGA_BOARD=ti375c529 fpga-program
|
||||
```
|
||||
|
||||
The Makefile auto-discovers Efinity under `/tools/efinix/efinity`. Override
|
||||
`EFINITY_HOME` when another installation is required.
|
||||
|
||||
Programming auto-selects the connected Ti375 development kit. If more than
|
||||
one compatible FTDI device is attached, run `make FPGA_BOARD=ti375c529
|
||||
fpga-detect` to list the bus-qualified URLs and pass the selected one as
|
||||
`FTDI_URL=...`.
|
||||
|
||||
Volatile JTAG programming and GDB loading into Rocket DTIM remain available.
|
||||
Persistent boot uses the board's Lower 512-Mbit SPI flash with this map:
|
||||
|
||||
| Region | Flash offset | Contents |
|
||||
|---|---:|---|
|
||||
| FPGA configuration | `0x00000000` | Efinity active-mode configuration HEX |
|
||||
| Rocket application | `0x00800000` | Boot header and ELF-derived payload |
|
||||
| Navigation context | `0x03FC0000` | Two 64-KiB journal sectors |
|
||||
| Ephemeris cache | `0x03FE0000` | Two 64-KiB journal sectors |
|
||||
|
||||
The application starts at 8 MiB because the compressed Ti375 configuration is
|
||||
currently about 5.19 MB; the previous 4 MiB trial offset would overlap it.
|
||||
Generate or program the Efinity raw HEX images with:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-mcs APP=hello_uart
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-app APP=hello_uart
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-bitstream
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-mcs APP=hello_uart
|
||||
```
|
||||
|
||||
`fpga-mcs` is the repository-wide compatibility target name. For this Efinix
|
||||
board it produces `.hex`, not Xilinx `.mcs`. `fpga-flash-app` changes only the
|
||||
application region; `fpga-flash-mcs` erases/programs configuration plus the
|
||||
application through Efinity's pre-built JTAG-to-SPI bridge and verifies the
|
||||
readback. Cold boot from this layout was verified by a complete board power
|
||||
cycle: Ti375 configured from flash and Rocket loaded and completed
|
||||
`hello_uart` from the application region without a JTAG/GDB load.
|
||||
|
||||
## Debug and load
|
||||
|
||||
Use the host OpenOCD build, not the OpenOCD shipped with Efinity. The build
|
||||
must include `riscv set_bscan_tunnel_ir`; Ti375 uses a 5-bit outer TAP and
|
||||
selects `JTAG_USER1` with instruction `0x08`.
|
||||
OpenOCD 0.12 can be given that upstream-compatible command with
|
||||
`flow/debug/openocd-0.12-ti375-bscan.patch`.
|
||||
|
||||
Apply it from a clean OpenOCD 0.12 source tree before configuring and building
|
||||
the host tool:
|
||||
|
||||
```bash
|
||||
git apply --check /path/to/gps/targets/fpga/ti375c529/flow/debug/openocd-0.12-ti375-bscan.patch
|
||||
git apply /path/to/gps/targets/fpga/ti375c529/flow/debug/openocd-0.12-ti375-bscan.patch
|
||||
```
|
||||
|
||||
Place the resulting `openocd` in `PATH`, or pass its absolute path with
|
||||
`OPENOCD=/path/to/openocd`.
|
||||
|
||||
In one terminal:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-openocd
|
||||
```
|
||||
|
||||
In a second terminal:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-load APP=hello_uart
|
||||
make FPGA_BOARD=ti375c529 fpga-uart
|
||||
```
|
||||
|
||||
The target deliberately selects `/tools/toolchain/bin/riscv64-unknown-elf-gdb`
|
||||
when it exists. The medany compiler toolchain is still used to build software,
|
||||
but it is not expected to contain GDB.
|
||||
|
||||
Efinity 2025.2 leaves Rocket's block-local packed store-data array undriven
|
||||
(`VDB-1002`). `tools/prepare_efinity_rtl.py` rewrites that generated RTL
|
||||
expression as an equivalent explicit `case`. Without the rewrite, DMI itself
|
||||
works, but GPR/CSR values stored into Debug Module data registers read as zero;
|
||||
OpenOCD consequently reports a misleading `misa=0`.
|
||||
|
||||
The patch is deliberately post-generation: Chisel and `firtool` first emit the
|
||||
Ti375 SystemVerilog tree, then `prepare_efinity_rtl.py` modifies only the
|
||||
generated Ti375 `Rocket.sv` before Efinity synthesis. It does not edit Rocket's
|
||||
native/upstream Chisel sources.
|
||||
|
||||
Two equivalent four-entry packed temporaries in the generated pbus/cbus
|
||||
`TLAtomicAutomata` modules are rewritten for the same reason, preserving the
|
||||
four atomic-operation mappings while removing their `VDB-1002` risk.
|
||||
|
||||
The same script generates Ti375-only copies of the acquisition carrier NCO,
|
||||
tracking carrier NCO, and FFT twiddle ROM under
|
||||
`out/build/generated/gps_efinity/`. This avoids Efinity 2025.2
|
||||
whole-array/`initial`/`$sin` elaboration failures without editing the shared GPS
|
||||
RTL. Only the Ti375 source list selects these copies; Genesys2 and VCU118 still
|
||||
use the originals. Detailed source paths, warning interpretation, and Questa
|
||||
RTL/post-map equivalence results are in the Efinity flow notes.
|
||||
|
||||
The affected generated source is
|
||||
`hardware/generated/ti375c529-soc-verilog/Rocket.sv`; Efinity records the
|
||||
original diagnostic in
|
||||
`targets/fpga/ti375c529/flow/efinity/outflow/ti375c529_rocket.warn.log`.
|
||||
The checked-in repair is
|
||||
`targets/fpga/ti375c529/tools/prepare_efinity_rtl.py` and runs after every
|
||||
`firtool` invocation, before Efinity synthesis.
|
||||
|
||||
## Board connections
|
||||
|
||||
PMOD0/J13 carries the GPS RF sampler:
|
||||
|
||||
| Signal | PMOD pin | FPGA resource | Package pin |
|
||||
|---|---:|---|---|
|
||||
| `rf_clk` | 10 | GPIOR_95_CLK12 | A12 |
|
||||
| `rf_data[0]` | 2 | GPIOR_89 | G16 |
|
||||
| `rf_data[1]` | 3 | GPIOR_90 | F16 |
|
||||
| `rf_data[2]` | 4 | GPIOR_91 | F17 |
|
||||
| `rf_data[3]` | 7 | GPIOR_92 | G17 |
|
||||
| `max2771_spi_sclk` | 1 | GPIOR_88_PLLIN1 | G15 |
|
||||
| `max2771_spi_csn` | 8 | GPIOR_93_PLLIN1 | A11 |
|
||||
| `max2771_spi_sdata` | 9 | GPIOR_94 | A13 |
|
||||
|
||||
`rf_clk` must be wired to J13 pin 10. Pin 10 is the PMOD0 header's dedicated
|
||||
3.3 V global-clock input. J13 pin 1 is used as the MAX2771 serial clock output;
|
||||
using it as the raw AFE clock would make Efinity promote normal GPIO routing
|
||||
into a GBUF and issue an extra-clock-insertion-delay warning.
|
||||
|
||||
As on Genesys2 and VCU118, the AX2771 clock is both the raw AFE sample clock
|
||||
and the source of the GPS processing-clock chain. Two Titanium PLLs generate
|
||||
an intermediate 55.5556 MHz clock, then 100 MHz acquisition and 125 MHz
|
||||
tracking clocks. The Rocket fabric uses the independent on-board 100 MHz
|
||||
oscillator.
|
||||
|
||||
PMOD1/J14 carries the sensor SPI, interrupt, and PPS:
|
||||
|
||||
| Signal | PMOD pin | FPGA resource | Package pin |
|
||||
|---|---:|---|---|
|
||||
| `pmod_spi_csn` | 1 | GPIOR_96_CLK13 | B12 |
|
||||
| `pmod_spi_dq[0]` | 2 | GPIOR_97 | C14 |
|
||||
| `pmod_spi_dq[1]` | 3 | GPIOR_98 | C13 |
|
||||
| `pmod_spi_sck` | 4 | GPIOR_99 | C12 |
|
||||
| `pmod_spi_dq[2]` | 7 | GPIOR_100 | D12 |
|
||||
| `pmod_spi_dq[3]` | 8 | GPIOR_101_PLLIN1 | F12 |
|
||||
| `pmod_irq` | 9 | GPIOR_102 | D13 |
|
||||
| `gps_pps` | 10 | GPIOR_103 | E13 |
|
||||
|
||||
The FTDI UART is `/dev/ttyUSB2` on the current Linux enumeration. SW3 is the
|
||||
active-low Rocket reset. JTAG uses Efinix `JTAG_USER1` and the existing Rocket
|
||||
DMI tunnel protocol.
|
||||
|
||||
The Lower flash user-mode connection is internal to the development kit:
|
||||
|
||||
| Signal | FPGA resource | Package pin |
|
||||
|---|---|---|
|
||||
| `flash_csn` | GPIOB_N_38 / SSL_N | A7 |
|
||||
| `flash_sck` | GPIOB_P_39 / CCK | G6 |
|
||||
| `flash_dq[0]` | GPIOB_N_40 / CDI0 | H4 |
|
||||
| `flash_dq[1]` | GPIOB_P_40 / CDI1 | H5 |
|
||||
| `flash_dq[2]` | GPIOB_N_39 / CDI2 | G5 |
|
||||
| `flash_dq[3]` | GPIOB_P_38 / CDI3 | B7 |
|
||||
@@ -0,0 +1,12 @@
|
||||
Board name: Efinix Titanium Ti375 C529 Development Kit
|
||||
Official link: https://www.efinixinc.com/products-devkits-titaniumti375c529.html
|
||||
|
||||
FPGA device: Ti375C529
|
||||
Efinity family: Titanium
|
||||
Efinity timing model: C4
|
||||
|
||||
Initial soft-Rocket flow clocks:
|
||||
SoC/fabric: 100 MHz from the on-board 100 MHz oscillator
|
||||
GPS RF: external AX2771 PMOD0/J13 clock, nominally 16.367981 MHz
|
||||
GPS acquisition: 100 MHz, PLL-derived from the GPS RF clock
|
||||
GPS tracking: 125 MHz, PLL-derived from the GPS RF clock
|
||||
@@ -0,0 +1 @@
|
||||
monitor halt
|
||||
@@ -0,0 +1,13 @@
|
||||
monitor halt
|
||||
monitor reset halt
|
||||
set $mie = 0
|
||||
set $mstatus = 0x6000
|
||||
set {unsigned long long}0x02004000 = 0xffffffffffffffff
|
||||
load
|
||||
set $mie = 0
|
||||
set $mstatus = 0x6000
|
||||
set $sp = (unsigned long)&_stack_top
|
||||
set $pc = _start
|
||||
monitor resume
|
||||
disconnect
|
||||
quit
|
||||
@@ -0,0 +1,62 @@
|
||||
--- a/src/target/riscv/riscv.c
|
||||
+++ b/src/target/riscv/riscv.c
|
||||
@@ -127,6 +127,7 @@
|
||||
|
||||
static bscan_tunnel_type_t bscan_tunnel_type;
|
||||
int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
|
||||
+static int bscan_tunnel_ir_id; /* outer TAP IR used to access the tunnel */
|
||||
|
||||
static const uint8_t bscan_zero[4] = {0};
|
||||
static const uint8_t bscan_one[4] = {1};
|
||||
@@ -451,8 +452,12 @@
|
||||
select_idcode.num_bits = target->tap->ir_length;
|
||||
|
||||
if (bscan_tunnel_ir_width != 0) {
|
||||
- assert(target->tap->ir_length >= 6);
|
||||
- uint32_t ir_user4_raw = 0x23 << (target->tap->ir_length - 6);
|
||||
+ uint32_t ir_user4_raw = bscan_tunnel_ir_id;
|
||||
+ /* Preserve the legacy Xilinx USER4 default when no IR was supplied. */
|
||||
+ if (ir_user4_raw == 0) {
|
||||
+ assert(target->tap->ir_length >= 6);
|
||||
+ ir_user4_raw = 0x23 << (target->tap->ir_length - 6);
|
||||
+ }
|
||||
h_u32_to_le(ir_user4, ir_user4_raw);
|
||||
select_user4.num_bits = target->tap->ir_length;
|
||||
bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;
|
||||
@@ -2859,6 +2864,21 @@
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
+COMMAND_HANDLER(riscv_set_bscan_tunnel_ir)
|
||||
+{
|
||||
+ int ir_id = 0;
|
||||
+
|
||||
+ if (CMD_ARGC > 1)
|
||||
+ return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
+
|
||||
+ if (CMD_ARGC == 1)
|
||||
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], ir_id);
|
||||
+
|
||||
+ LOG_INFO("Bscan tunnel IR 0x%x selected", ir_id);
|
||||
+ bscan_tunnel_ir_id = ir_id;
|
||||
+ return ERROR_OK;
|
||||
+}
|
||||
+
|
||||
COMMAND_HANDLER(riscv_set_enable_virt2phys)
|
||||
{
|
||||
if (CMD_ARGC != 1) {
|
||||
@@ -3072,6 +3092,14 @@
|
||||
"1: DATA_REGISTER}"
|
||||
},
|
||||
{
|
||||
+ .name = "set_bscan_tunnel_ir",
|
||||
+ .handler = riscv_set_bscan_tunnel_ir,
|
||||
+ .mode = COMMAND_ANY,
|
||||
+ .usage = "[value]",
|
||||
+ .help = "Specify the outer JTAG TAP IR used to access the BSCAN tunnel. "
|
||||
+ "The default remains the Xilinx FPGA USER4 instruction."
|
||||
+ },
|
||||
+ {
|
||||
.name = "set_enable_virt2phys",
|
||||
.handler = riscv_set_enable_virt2phys,
|
||||
.mode = COMMAND_ANY,
|
||||
@@ -0,0 +1,32 @@
|
||||
# Rocket debug through the Ti375 hard TAP, JTAG_USER1, and the project's DMI tunnel.
|
||||
|
||||
adapter driver ftdi
|
||||
ftdi vid_pid 0x0403 0x6011
|
||||
ftdi channel 1
|
||||
ftdi layout_init 0x08 0x0b
|
||||
|
||||
if {![info exists ADAPTER_SPEED]} {
|
||||
set ADAPTER_SPEED 1000
|
||||
}
|
||||
adapter speed $ADAPTER_SPEED
|
||||
|
||||
jtag newtap ti375 fpga -expected-id 0x006A0A79 -irlen 5 -ircapture 0x5 -irmask 0xF
|
||||
target create rocket.cpu riscv -chain-position ti375.fpga -coreid 0
|
||||
|
||||
# The outer Ti375 USER1 instruction is 0x08. The inner tunnel implements the
|
||||
# same 5-bit Rocket DTM IR and framing used by the Xilinx targets.
|
||||
riscv set_ir dtmcs 0x10
|
||||
riscv set_ir dmi 0x11
|
||||
riscv use_bscan_tunnel 5 0
|
||||
# Ti375 requires an OpenOCD build with the upstream configurable outer BSCAN
|
||||
# instruction support. Keep the catch only so older builds produce a readable
|
||||
# diagnostic before their legacy Xilinx-specific BSCAN path rejects this TAP.
|
||||
if {[catch {riscv set_bscan_tunnel_ir 8}]} {
|
||||
echo "OpenOCD lacks 'riscv set_bscan_tunnel_ir'; Ti375 requires that command"
|
||||
}
|
||||
|
||||
riscv set_reset_timeout_sec 10
|
||||
riscv set_command_timeout_sec 10
|
||||
|
||||
init
|
||||
halt
|
||||
@@ -0,0 +1,328 @@
|
||||
# Ti375C529 Efinity flow notes
|
||||
|
||||
This directory contains the Efinity project for the Ti375C529 development kit.
|
||||
The port keeps the same RV64 Rocket/GPS subsystem used by the Genesys2 and
|
||||
VCU118 targets. Only the FPGA shell, clocks, pin constraints, programming flow,
|
||||
and JTAG transport are vendor-specific. The hardened RV32 subsystem in the
|
||||
Ti375 device is not used.
|
||||
|
||||
## What was added
|
||||
|
||||
- Added `ti375c529` to the root FPGA board selection and build targets.
|
||||
- Added Efinity 2025.2 discovery through `EFINITY_HOME`; the current installation
|
||||
is `/tools/efinix/efinity/2025.2`.
|
||||
- Added a generated Ti375 wrapper around `VCU118RocketSystem` so the existing
|
||||
Rocket, DTIM, UART, GPS acquisition, tracking, PPS, and SPI logic is reused.
|
||||
- Added the Efinity XML project, interface script, SDC constraints, PLLs, pin
|
||||
assignments, and JTAG programming target.
|
||||
- Added FTDI UART operation at 460800 baud. On the current host it enumerates as
|
||||
`/dev/ttyUSB2`.
|
||||
- Added host OpenOCD/GDB debug through the Ti375 hard TAP and `JTAG_USER1`.
|
||||
- Added Efinity-specific generated-RTL rewrites for Rocket's store-data path and
|
||||
the GPS acquisition/tracking lookup tables that Efinity 2025.2 mis-elaborates.
|
||||
|
||||
## Clock structure
|
||||
|
||||
The Rocket fabric and GPS processing clocks have separate sources:
|
||||
|
||||
- The on-board 100 MHz oscillator drives the fabric PLL and the 100 MHz Rocket
|
||||
system clock.
|
||||
- AX2771 `rf_clk` enters through the dedicated global-clock input at J13 pin 10
|
||||
/ package pin A12 (`GPIOR_95_CLK12`). It is the raw AFE sample clock and feeds
|
||||
the GPS PLL chain. J13 pins 1, 8, and 9 carry the MAX2771 control bus; pin 1
|
||||
/ G15 is a PLL input, not a dedicated fabric GCLK input.
|
||||
- The GPS PLL chain generates 100 MHz acquisition and 125 MHz tracking clocks.
|
||||
- Acquisition and tracking reset release is gated by the relevant PLL lock
|
||||
signals.
|
||||
|
||||
The four AX2771 data bits use J13 pins 2, 3, 4, and 7, corresponding to package
|
||||
pins G16, F16, F17, and G17. The AX2771 clock must be jumpered to J13 pin 10.
|
||||
|
||||
## Efinity synthesis adaptation
|
||||
|
||||
This adaptation does **not** modify Rocket's native/upstream Chisel sources or
|
||||
the shared GPS SystemVerilog. The normal Chisel and `firtool` stages run first
|
||||
and emit SystemVerilog into `hardware/generated/ti375c529-soc-verilog/`.
|
||||
Immediately afterward,
|
||||
`targets/fpga/ti375c529/tools/prepare_efinity_rtl.py` patches the generated
|
||||
Ti375 `Rocket.sv` and writes Efinity-only GPS replacements under
|
||||
`targets/fpga/ti375c529/out/build/generated/gps_efinity/`. The Ti375 source-list
|
||||
recipe substitutes those generated copies for exactly these three shared GPS
|
||||
files:
|
||||
|
||||
- `acq_src/acq_nco_carr.sv`
|
||||
- `trck_src/NCO_carr.sv`
|
||||
- `acq_src/twiddle_ram.sv`
|
||||
|
||||
All other GPS RTL remains shared. Efinity consumes the replacements; Genesys2
|
||||
and VCU118 continue to consume the original GPS files. Deleting either
|
||||
generated directory and running `make FPGA_BOARD=ti375c529 fpga-rtl` repeats
|
||||
the same deterministic generation and substitution.
|
||||
|
||||
### Rocket store-data path
|
||||
|
||||
The CIRCT-generated `Rocket.sv` contains this block-local packed temporary for
|
||||
store-data byte-lane replication:
|
||||
|
||||
```systemverilog
|
||||
automatic logic [3:0][63:0] _GEN_24 = ...;
|
||||
mem_reg_rs2 <= _GEN_24[ex_reg_mem_size];
|
||||
```
|
||||
|
||||
Vivado synthesizes this construct correctly. Efinity 2025.2 reports `_GEN_24`
|
||||
as `VDB-1002: net does not have a driver`, leaving Rocket store data at zero.
|
||||
This initially looked like a Debug Module failure because abstract GPR/CSR
|
||||
reads execute a hart instruction that stores the result into Debug Module data
|
||||
registers. DMI was working, but OpenOCD received zeros and reported the
|
||||
misleading result `misa=0`.
|
||||
|
||||
`../../tools/prepare_efinity_rtl.py` replaces only that generated expression
|
||||
with an equivalent explicit `case` for byte, half-word, word, and double-word
|
||||
stores. The script runs automatically after `firtool`; generated RTL is not
|
||||
edited by hand. After the rewrite, the Rocket `VDB-1002` warning disappears
|
||||
from the current synthesis run. `ti375c529_rocket.warn.log` is reused by
|
||||
Efinity and can contain entries from older runs, so the generated source and
|
||||
the final warning block should be checked together.
|
||||
|
||||
The same Efinity limitation also affected the four-entry packed atomic-operation
|
||||
LUT emitted into generated `TLAtomicAutomata_pbus.sv` and
|
||||
`TLAtomicAutomata_cbus.sv`. Those `_GEN_4`/`_GEN_13` temporaries select the
|
||||
TileLink atomic ALU operation; they are unrelated to GPS acquisition but could
|
||||
break software atomics. The post-generation script rewrites both to an
|
||||
equivalent four-way `case`. Questa confirmed all four index mappings, and their
|
||||
`VDB-1002` diagnostics disappear from the current single-run `map.out`.
|
||||
|
||||
The exact paths are:
|
||||
|
||||
- Generated failing/fixed source:
|
||||
`hardware/generated/ti375c529-soc-verilog/Rocket.sv`
|
||||
- Generated TileLink atomic sources:
|
||||
`hardware/generated/ti375c529-soc-verilog/TLAtomicAutomata_pbus.sv` and
|
||||
`hardware/generated/ti375c529-soc-verilog/TLAtomicAutomata_cbus.sv`
|
||||
- Efinity synthesis warning log:
|
||||
`targets/fpga/ti375c529/flow/efinity/outflow/ti375c529_rocket.warn.log`
|
||||
- Deterministic repair:
|
||||
`targets/fpga/ti375c529/tools/prepare_efinity_rtl.py`
|
||||
- Invocation point:
|
||||
`targets/fpga/ti375c529/Makefile`, in the `rtl` recipe immediately after
|
||||
`firtool`
|
||||
|
||||
### GPS lookup-table paths
|
||||
|
||||
The original acquisition carrier NCO is
|
||||
`hardware/external/gps/rtl/acq_src/acq_nco_carr.sv`. It initializes the
|
||||
frequency and pull-in arrays with whole-package-array assignments and builds
|
||||
its sine table in an `initial` loop using `$sin`. Efinity 2025.2 reports the
|
||||
loop variable as never assigned and the three arrays as undriven. Stand-alone
|
||||
post-map comparison confirmed that this is functional, not cosmetic: the
|
||||
unpatched Efinity netlist produced incorrect sine/cosine samples in all 18,040
|
||||
tested production-parameter cycles.
|
||||
|
||||
The generated Ti375 copy replaces the frequency, pull-in, sine, and cosine
|
||||
reads with constant functions generated from `definitions.sv`. Questa compared
|
||||
41 frequency bins, 11 pull-in bins, and 40 cycles per combination: all 18,040
|
||||
RTL samples and all 18,040 Efinity post-map samples matched the original RTL.
|
||||
The current full-project synthesis no longer reports the acquisition arrays or
|
||||
its `$sin` loop as undriven.
|
||||
|
||||
The separate tracking carrier NCO is
|
||||
`hardware/external/gps/rtl/trck_src/NCO_carr.sv`. Its
|
||||
`sinwav_lut = TRCK_SINWAV_LUT` package-array initializer triggers the same
|
||||
Efinity `VDB-1002` behavior. The Ti375 copy uses an exact 128-entry constant
|
||||
function generated from `TRCK_SINWAV_LUT`. Questa matched every table entry at
|
||||
RTL and then matched 5,000 Efinity post-map cycles while visiting all 128
|
||||
addresses.
|
||||
|
||||
The acquisition FFT twiddle source is
|
||||
`hardware/external/gps/rtl/acq_src/twiddle_ram.sv`. Its whole-array
|
||||
`COS_ROM_ARRAY` and `SIN_ROM_ARRAY` assignments are converted only for Ti375 to
|
||||
two generated, exactly 15-bit-wide `$readmemb` files. Efinity infers 30
|
||||
`EFX_RAM10` blocks with embedded INIT data. Efinity still emits its generic
|
||||
`sin_rom/cos_rom does not have a driver` elaboration warning for this recognized
|
||||
ROM form, but this one is demonstrably benign: Questa matched all 8,192 RTL
|
||||
addresses and all 8,192 addresses in the Efinity post-map RAM netlist. Check
|
||||
the current `ti375c529_rocket.map.out` for a single run; the `.warn.log` and
|
||||
`.info.log` files retain records from older builds and can otherwise make fixed
|
||||
source paths look current.
|
||||
|
||||
## JTAG and OpenOCD
|
||||
|
||||
Ti375 and the Xilinx boards expose the same inner Rocket DTM protocol, but the
|
||||
outer FPGA TAP is different:
|
||||
|
||||
| Item | Xilinx flow | Ti375 flow |
|
||||
|---|---|---|
|
||||
| Outer TAP IR width | Xilinx-specific | 5 bits |
|
||||
| User instruction | legacy USER4 handling | `JTAG_USER1 = 0x08` |
|
||||
| Inner DTM IR width | 5 bits | 5 bits |
|
||||
| DTMCS / DMI IR | `0x10` / `0x11` | `0x10` / `0x11` |
|
||||
|
||||
The host OpenOCD must therefore implement:
|
||||
|
||||
```text
|
||||
riscv set_bscan_tunnel_ir 8
|
||||
```
|
||||
|
||||
A fixed OpenOCD pathname is **not** required. The target Makefile evaluates
|
||||
`command -v openocd`, so the first compatible patched host binary in `PATH` is
|
||||
used. Another compatible build can be selected without changing files:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-openocd OPENOCD=/path/to/openocd
|
||||
```
|
||||
|
||||
The original `/usr/local/bin/openocd` 0.12 build assumes the Xilinx USER4
|
||||
instruction and asserts that the outer TAP IR is at least six bits. It cannot
|
||||
drive the Ti375 5-bit TAP unchanged. `../debug/openocd-0.12-ti375-bscan.patch`
|
||||
adds the configurable outer instruction to OpenOCD 0.12. The OpenOCD shipped
|
||||
with Efinity is not required by this flow.
|
||||
|
||||
Apply the patch from a clean OpenOCD 0.12 source tree before configuring and
|
||||
building the host tool:
|
||||
|
||||
```bash
|
||||
git apply --check /path/to/gps/targets/fpga/ti375c529/flow/debug/openocd-0.12-ti375-bscan.patch
|
||||
git apply /path/to/gps/targets/fpga/ti375c529/flow/debug/openocd-0.12-ti375-bscan.patch
|
||||
```
|
||||
|
||||
The selected paths can be checked with:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-config
|
||||
command -v openocd
|
||||
strings "$(command -v openocd)" | grep set_bscan_tunnel_ir
|
||||
```
|
||||
|
||||
The line `Disabling abstract command reads/writes from CSRs` is informational,
|
||||
not a failure. OpenOCD falls back to Rocket's Program Buffer for CSR access.
|
||||
|
||||
## GDB selection
|
||||
|
||||
Software is still compiled with the medany toolchain. That toolchain does not
|
||||
contain GDB, so the debug target deliberately selects:
|
||||
|
||||
```text
|
||||
/tools/toolchain/bin/riscv64-unknown-elf-gdb
|
||||
```
|
||||
|
||||
This can also be overridden with `GDB=/path/to/riscv64-unknown-elf-gdb`.
|
||||
|
||||
## Build, program, and debug
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-config
|
||||
make FPGA_BOARD=ti375c529 fpga-rtl
|
||||
make FPGA_BOARD=ti375c529 fpga-bitstream
|
||||
make FPGA_BOARD=ti375c529 fpga-program
|
||||
```
|
||||
|
||||
Start the host OpenOCD server in one terminal:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-openocd
|
||||
```
|
||||
|
||||
Load and run an application, then monitor UART, from another terminal:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-debug-load APP=hello_uart
|
||||
make FPGA_BOARD=ti375c529 fpga-uart
|
||||
```
|
||||
|
||||
## Persistent Lower-flash boot
|
||||
|
||||
The kit has Lower and Upper 512-Mbit SPI NOR devices. This port intentionally
|
||||
uses one MCS-like combined layout in the Lower ISSI IS25WP512 because Efinity's
|
||||
command-line `jtag_bridge` mode directly addresses that flash:
|
||||
|
||||
| Offset | Image |
|
||||
|---:|---|
|
||||
| `0x00000000` | Compressed, active-x1 FPGA configuration |
|
||||
| `0x00800000` | Rocket boot header followed by the application payload |
|
||||
| `0x03FC0000` | Persistent navigation context (two 64-KiB sectors) |
|
||||
| `0x03FE0000` | Persistent ephemeris cache (two 64-KiB sectors) |
|
||||
|
||||
The application offset is 64-KiB-sector aligned and leaves roughly 3.2 MB
|
||||
between the current 5,190,596-byte configuration and the firmware region.
|
||||
`spi_low_power_mode=off` is embedded in the configuration so the Lower flash
|
||||
stays available when Rocket enters user mode.
|
||||
|
||||
Rocket's existing MMIO SPI controller is connected to the configuration pins
|
||||
after configuration completes:
|
||||
|
||||
```text
|
||||
spi_sck/spi_csn/spi_dq_* -> A7/G6/H4/H5/G5/B7 -> Lower flash U47
|
||||
```
|
||||
|
||||
Generate the configuration, per-application, and combined raw Efinity HEX
|
||||
files:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-bitstream
|
||||
make FPGA_BOARD=ti375c529 fpga-mcs APP=hello_uart
|
||||
```
|
||||
|
||||
Outputs are:
|
||||
|
||||
- `out/bitstream/ti375c529_rocket.hex`: configuration region
|
||||
- `out/flash/regions/app.hex`: application region
|
||||
- `out/flash/ti375c529_rocket.hex`: combined image
|
||||
- `out/flash/ti375c529_rocket.json`: offsets, sizes, and SHA-256 manifest
|
||||
|
||||
Program only the application, only the configuration, or the combined image:
|
||||
|
||||
```bash
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-app APP=hello_uart
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-bitstream
|
||||
make FPGA_BOARD=ti375c529 fpga-flash-mcs APP=hello_uart
|
||||
```
|
||||
|
||||
The Makefile first loads Efinity's device-matched bridge
|
||||
`/tools/efinix/efinity/2025.2/pgm/fli/titanium/u006A0A79.bit`, then uses
|
||||
`jtag_bridge` programming with on-chip verification. A fixed Efinity install
|
||||
path is not required; `FLASH_LOADER` is derived from `EFINITY_HOME` and can be
|
||||
overridden.
|
||||
|
||||
After bridge programming, the FPGA still contains the bridge design. Power
|
||||
cycle the kit for a true active-flash boot, or use `fpga-program` to load the
|
||||
normal design immediately and test the BootROM/application flash path.
|
||||
|
||||
## On-board verification
|
||||
|
||||
The completed flow was checked on the connected Ti375C529 kit with AX2771
|
||||
attached:
|
||||
|
||||
- Efinity interface, map, PNR, and programming-image stages passed.
|
||||
- Final patched timing passed with WNS `+0.101 ns` and WHS `+0.021 ns`.
|
||||
- The Ti375 JTAG IDCODE was read as `0x006a0a79`.
|
||||
- OpenOCD found one RV64 hart and read `misa=0x800000000080112d`.
|
||||
- A raw Program Buffer GPR/store test returned `0x5a` through DMI.
|
||||
- `/tools/toolchain/bin/riscv64-unknown-elf-gdb` loaded 40,880 bytes into DTIM.
|
||||
- `hello_uart` printed the expected Rocket/DTIM/UART messages at 460800 baud.
|
||||
- The persistent image passed with setup slack `+0.094 ns` and hold slack
|
||||
`+0.021 ns`.
|
||||
- The Lower flash was detected as ISSI IS25WP512, JEDEC `0x9d701a`.
|
||||
- The combined 8,429,552-byte HEX completed erase, write, readback, and verify.
|
||||
- BootROM read the payload at `0x00800040`, verified CRC `0xed3bbdf5`, copied
|
||||
40,880 bytes into DTIM, and ran `hello_uart` without GDB.
|
||||
- A full board power cycle then configured Ti375 from Lower flash. Host OpenOCD
|
||||
found the RV64 hart through `JTAG_USER1`; its PC was at
|
||||
`0x8000017e <_exit>` after `hello_uart` returned, and GDB `compare-sections`
|
||||
matched the complete ELF `.text` range in DTIM. This confirms cold boot of
|
||||
both hardware and software without a volatile JTAG/GDB load.
|
||||
|
||||
## Relevant files
|
||||
|
||||
- `ti375c529_rocket.xml`: Efinity project definition.
|
||||
- `ti375c529_rocket.isf`: generated/copy of the checked-in interface script.
|
||||
- `../../../../../hardware/fpga/ti375c529/constraints/`: source interface and SDC
|
||||
constraints.
|
||||
- `../../tools/gen_ti375c529_wrapper.py`: Efinix board-shell generator.
|
||||
- `../../tools/prepare_efinity_rtl.py`: deterministic Rocket and GPS
|
||||
Efinity-only RTL generation/rewrite.
|
||||
- `../../tools/make_flash_hex.py`: validated Efinity raw-HEX image builder.
|
||||
- `../debug/openocd_ti375c529_bscan.cfg`: Ti375 hard-TAP/OpenOCD configuration.
|
||||
- `../debug/openocd-0.12-ti375-bscan.patch`: host OpenOCD 0.12 compatibility
|
||||
patch.
|
||||
@@ -0,0 +1,71 @@
|
||||
<efx:project xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="ti375c529_rocket" description="RV64 Rocket and GPS on the Ti375C529 development kit" sw_version="2025.2.288.2.10" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd" last_run_state="pass" last_run_flow="bitstream" last_change="1785370142" config_result_in_sync="sync" design_ood="sync" place_ood="sync" route_ood="sync">
|
||||
<efx:device_info>
|
||||
<efx:family name="Titanium" />
|
||||
<efx:device name="Ti375C529" />
|
||||
<efx:timing_model name="C4" />
|
||||
</efx:device_info>
|
||||
<efx:design_info def_veri_version="verilog_2k" def_vhdl_version="vhdl_2008" unified_flow="true">
|
||||
<efx:top_module name="ti375c529_rocket_top" />
|
||||
<efx:design_file name="../../out/build/generated/ti375c529_rocket_top.sv" version="default" library="default" />
|
||||
<efx:design_file name="../../out/build/efinity_sources.f" version="na" library="default" />
|
||||
<efx:top_vhdl_arch name="" />
|
||||
</efx:design_info>
|
||||
<efx:constraint_info>
|
||||
<efx:sdc_file name="../../../../../hardware/fpga/ti375c529/constraints/ti375c529_rocket.sdc" />
|
||||
<efx:sdc_file name="outflow/ti375c529_rocket.pt.sdc" />
|
||||
<efx:sdc_file name="../../../../../hardware/fpga/ti375c529/constraints/ti375c529_rocket_clock_groups.sdc" />
|
||||
<efx:inter_file name="" />
|
||||
</efx:constraint_info>
|
||||
<efx:isf_info>
|
||||
<efx:isf_file name="ti375c529_rocket.isf" />
|
||||
</efx:isf_info>
|
||||
<efx:sim_info />
|
||||
<efx:misc_info />
|
||||
<efx:ooc_info />
|
||||
<efx:ip_info />
|
||||
<efx:synthesis tool_name="efx_map">
|
||||
<efx:param name="work_dir" value="../../out/build/work_syn" value_type="e_string" />
|
||||
<efx:param name="write_efx_verilog" value="on" value_type="e_bool" />
|
||||
<efx:param name="blackbox-error" value="1" value_type="e_option" />
|
||||
<efx:param name="hdl-compile-unit" value="1" value_type="e_option" />
|
||||
<efx:param name="infer-clk-enable" value="3" value_type="e_option" />
|
||||
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option" />
|
||||
<efx:param name="mode" value="speed" value_type="e_option" />
|
||||
<efx:param name="retiming" value="1" value_type="e_option" />
|
||||
<efx:param name="seq_opt" value="1" value_type="e_option" />
|
||||
<efx:param name="use-logic-for-small-mem" value="64" value_type="e_integer" />
|
||||
<efx:param name="use-logic-for-small-rom" value="64" value_type="e_integer" />
|
||||
<efx:param name="max_threads" value="-1" value_type="e_integer" />
|
||||
<efx:param name="include" value="../../../../../hardware/external/gps/rtl/trck_src/pulp_fifo" value_type="e_string" />
|
||||
<efx:param name="include" value="../../out/build/generated/gps_efinity" value_type="e_string" />
|
||||
</efx:synthesis>
|
||||
<efx:place_and_route tool_name="efx_pnr">
|
||||
<efx:param name="work_dir" value="work_pnr" value_type="e_string" />
|
||||
<efx:param name="seed" value="2" value_type="e_integer" />
|
||||
<efx:param name="placer_effort_level" value="2" value_type="e_option" />
|
||||
<efx:param name="max_threads" value="-1" value_type="e_integer" />
|
||||
<efx:param name="beneficial_skew" value="on" value_type="e_option" />
|
||||
<efx:param name="print_critical_path" value="10" value_type="e_integer" />
|
||||
</efx:place_and_route>
|
||||
<efx:bitstream_generation tool_name="efx_pgm">
|
||||
<efx:param name="mode" value="active" value_type="e_option" />
|
||||
<efx:param name="width" value="1" value_type="e_option" />
|
||||
<efx:param name="enable_roms" value="smart" value_type="e_option" />
|
||||
<efx:param name="bitstream_compression" value="on" value_type="e_bool" />
|
||||
<efx:param name="spi_low_power_mode" value="off" value_type="e_bool" />
|
||||
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool" />
|
||||
<efx:param name="generate_bit" value="on" value_type="e_bool" />
|
||||
<efx:param name="generate_hex" value="on" value_type="e_bool" />
|
||||
<efx:param name="jtag_usercode" value="0x52564B54" value_type="e_string" />
|
||||
</efx:bitstream_generation>
|
||||
<efx:debugger>
|
||||
<efx:param name="work_dir" value="../../out/build/work_dbg" value_type="e_string" />
|
||||
<efx:param name="auto_instantiation" value="off" value_type="e_bool" />
|
||||
<efx:param name="profile" value="NONE" value_type="e_string" />
|
||||
</efx:debugger>
|
||||
<efx:security>
|
||||
<efx:param name="enable_bitstream_encrypt" value="off" value_type="e_bool" />
|
||||
<efx:param name="enable_bitstream_auth" value="off" value_type="e_bool" />
|
||||
<efx:param name="randomize_iv_value" value="on" value_type="e_bool" />
|
||||
</efx:security>
|
||||
</efx:project>
|
||||
@@ -0,0 +1,276 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate the Efinix Ti375 board shell around the shared Rocket subsystem."""
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def width_bits(width):
|
||||
if not width:
|
||||
return 1
|
||||
match = re.fullmatch(r"\[(\d+):(\d+)\]", width.strip())
|
||||
if not match:
|
||||
raise ValueError(f"unsupported width: {width}")
|
||||
return abs(int(match.group(1)) - int(match.group(2))) + 1
|
||||
|
||||
|
||||
def parse_ports(verilog_path):
|
||||
text = Path(verilog_path).read_text()
|
||||
module_name = Path(verilog_path).stem
|
||||
start = text.index(f"module {module_name}(")
|
||||
end = text.index(");", start)
|
||||
header = re.sub(r"//.*", "", text[start:end])
|
||||
pieces = re.split(r"\b(input|output)\b", header)[1:]
|
||||
ports = []
|
||||
for direction, body in zip(pieces[0::2], pieces[1::2]):
|
||||
body = body.replace("\n", " ")
|
||||
body = re.split(r"\b(input|output)\b", body)[0]
|
||||
default_width = ""
|
||||
width_match = re.match(r"\s*(\[[^\]]+\])\s*(.*)", body)
|
||||
if width_match:
|
||||
default_width = width_match.group(1)
|
||||
rest = width_match.group(2)
|
||||
else:
|
||||
rest = body
|
||||
for item in rest.split(","):
|
||||
item = item.strip()
|
||||
if not item:
|
||||
continue
|
||||
item_match = re.match(r"(\[[^\]]+\])\s*(\w+)$", item)
|
||||
if item_match:
|
||||
width, name = item_match.groups()
|
||||
else:
|
||||
width = default_width
|
||||
name = item.split()[-1]
|
||||
if re.fullmatch(r"\w+", name):
|
||||
ports.append((direction, width, name))
|
||||
return ports
|
||||
|
||||
|
||||
def const_for(width):
|
||||
bits = width_bits(width)
|
||||
return "1'b0" if bits == 1 else f"{bits}'d0"
|
||||
|
||||
|
||||
def is_clock(name):
|
||||
return name.endswith("_clock") or name == "debug_clock"
|
||||
|
||||
|
||||
def is_reset(name):
|
||||
return name.endswith("_reset") or name == "debug_reset"
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--rocket-top", required=True)
|
||||
parser.add_argument("--out", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
ports = parse_ports(args.rocket_top)
|
||||
port_by_name = {name: (direction, width) for direction, width, name in ports}
|
||||
|
||||
required = {
|
||||
"uart_rxd", "uart_txd",
|
||||
"spi_sck", "spi_csn", "spi_dq_i", "spi_dq_o", "spi_dq_oe",
|
||||
"pmod_spi_sck", "pmod_spi_csn",
|
||||
"pmod_spi_dq_i", "pmod_spi_dq_o", "pmod_spi_dq_oe",
|
||||
"max2771_spi_sclk", "max2771_spi_csn",
|
||||
"max2771_spi_sdata_i", "max2771_spi_sdata_o",
|
||||
"max2771_spi_sdata_oe",
|
||||
"pmod_irq", "gps_acq_clk", "gps_trck_clk",
|
||||
"gps_rf_clk", "gps_rf_data", "gps_pps",
|
||||
}
|
||||
missing = sorted(required - port_by_name.keys())
|
||||
if missing:
|
||||
raise RuntimeError(f"Rocket top is missing required Ti375 ports: {', '.join(missing)}")
|
||||
|
||||
passthrough = {
|
||||
"pmod_spi_sck", "pmod_spi_csn",
|
||||
"max2771_spi_sclk", "max2771_spi_csn",
|
||||
"pmod_irq", "gps_pps",
|
||||
}
|
||||
|
||||
def decl(width, name):
|
||||
return f" wire {width + ' ' if width else ''}{name};"
|
||||
|
||||
assigns = []
|
||||
for direction, width, name in ports:
|
||||
if direction != "input" or name in passthrough:
|
||||
continue
|
||||
if name.startswith("debug_clockeddmi_dmi_req"):
|
||||
continue
|
||||
if name in {
|
||||
"debug_clockeddmi_dmi_resp_ready",
|
||||
"debug_clockeddmi_dmiClock",
|
||||
"debug_clockeddmi_dmiReset",
|
||||
}:
|
||||
continue
|
||||
if name == "resetctrl_hartIsInReset_0":
|
||||
value = "soc_reset"
|
||||
elif name == "debug_reset":
|
||||
value = "fabric_reset"
|
||||
elif is_reset(name):
|
||||
value = "soc_reset"
|
||||
elif name == "gps_acq_clk":
|
||||
value = "gps_acq_clk_gen"
|
||||
elif name == "gps_trck_clk":
|
||||
value = "gps_trck_clk_gen"
|
||||
elif name in {"gps_rf_clk", "gps_afe_clk"}:
|
||||
value = "rf_clk"
|
||||
elif name == "gps_rf_data":
|
||||
value = "rf_data"
|
||||
elif is_clock(name):
|
||||
value = "fabric_clk"
|
||||
elif name == "debug_dmactiveAck":
|
||||
value = "debug_dmactive"
|
||||
elif name == "uart_rxd":
|
||||
value = "uart_rx"
|
||||
elif name == "spi_dq_i":
|
||||
value = "flash_dq_IN"
|
||||
elif name == "pmod_spi_dq_i":
|
||||
value = "pmod_spi_dq_IN"
|
||||
elif name == "max2771_spi_sdata_i":
|
||||
value = "max2771_spi_sdata_IN"
|
||||
elif name == "interrupts":
|
||||
value = "2'b00"
|
||||
else:
|
||||
value = const_for(width)
|
||||
assigns.append(f" assign {name} = {value};")
|
||||
|
||||
port_map = ",\n".join(f" .{name}({name})" for _, _, name in ports)
|
||||
internal_decls = "\n".join(
|
||||
decl(width, name) for _, width, name in ports if name not in passthrough
|
||||
)
|
||||
|
||||
content = f"""`timescale 1ns/1ps
|
||||
|
||||
module ti375c529_rocket_top (
|
||||
(* syn_peri_port = 0 *) input wire fabric_clk,
|
||||
(* syn_peri_port = 0 *) input wire fabric_pll_locked,
|
||||
(* syn_peri_port = 0 *) input wire board_clk_100,
|
||||
(* syn_peri_port = 0 *) input wire gps_ref_clk_gen,
|
||||
(* syn_peri_port = 0 *) input wire gps_acq_clk_gen,
|
||||
(* syn_peri_port = 0 *) input wire gps_trck_clk_gen,
|
||||
(* syn_peri_port = 0 *) input wire gps_domain_feedback,
|
||||
(* syn_peri_port = 0 *) input wire gps_ref_pll_locked,
|
||||
(* syn_peri_port = 0 *) input wire gps_domain_pll_locked,
|
||||
(* syn_peri_port = 0 *) input wire reset_n,
|
||||
(* syn_peri_port = 0 *) input wire uart_rx,
|
||||
(* syn_peri_port = 0 *) output wire uart_tx,
|
||||
(* syn_peri_port = 0 *) output wire flash_sck,
|
||||
(* syn_peri_port = 0 *) output wire flash_csn,
|
||||
(* syn_peri_port = 0 *) input wire [3:0] flash_dq_IN,
|
||||
(* syn_peri_port = 0 *) output wire [3:0] flash_dq_OUT,
|
||||
(* syn_peri_port = 0 *) output wire [3:0] flash_dq_OE,
|
||||
(* syn_peri_port = 0 *) input wire rf_clk,
|
||||
(* syn_peri_port = 0 *) input wire [3:0] rf_data,
|
||||
(* syn_peri_port = 0 *) output wire pmod_spi_sck,
|
||||
(* syn_peri_port = 0 *) output wire pmod_spi_csn,
|
||||
(* syn_peri_port = 0 *) input wire [3:0] pmod_spi_dq_IN,
|
||||
(* syn_peri_port = 0 *) output wire [3:0] pmod_spi_dq_OUT,
|
||||
(* syn_peri_port = 0 *) output wire [3:0] pmod_spi_dq_OE,
|
||||
(* syn_peri_port = 0 *) input wire pmod_irq,
|
||||
(* syn_peri_port = 0 *) output wire max2771_spi_sclk,
|
||||
(* syn_peri_port = 0 *) output wire max2771_spi_csn,
|
||||
(* syn_peri_port = 0 *) input wire max2771_spi_sdata_IN,
|
||||
(* syn_peri_port = 0 *) output wire max2771_spi_sdata_OUT,
|
||||
(* syn_peri_port = 0 *) output wire max2771_spi_sdata_OE,
|
||||
(* syn_peri_port = 0 *) output wire gps_pps,
|
||||
(* syn_peri_port = 0 *) input wire jtag_CAPTURE,
|
||||
(* syn_peri_port = 0 *) input wire jtag_DRCK,
|
||||
(* syn_peri_port = 0 *) input wire jtag_RESET,
|
||||
(* syn_peri_port = 0 *) input wire jtag_RUNTEST,
|
||||
(* syn_peri_port = 0 *) input wire jtag_SEL,
|
||||
(* syn_peri_port = 0 *) input wire jtag_SHIFT,
|
||||
(* syn_peri_port = 0 *) input wire jtag_TCK,
|
||||
(* syn_peri_port = 0 *) input wire jtag_TDI,
|
||||
(* syn_peri_port = 0 *) input wire jtag_TMS,
|
||||
(* syn_peri_port = 0 *) input wire jtag_UPDATE,
|
||||
(* syn_peri_port = 0 *) output wire jtag_TDO,
|
||||
(* syn_peri_port = 0 *) output wire [4:0] led
|
||||
);
|
||||
wire gps_clock_locked = gps_ref_pll_locked & gps_domain_pll_locked;
|
||||
wire pll_ready_async = fabric_pll_locked & gps_clock_locked & reset_n;
|
||||
(* async_reg = "true" *) reg [2:0] pll_ready_sync = 3'b000;
|
||||
reg [15:0] reset_shift = 16'hffff;
|
||||
|
||||
always @(posedge fabric_clk) begin
|
||||
pll_ready_sync <= {{pll_ready_sync[1:0], pll_ready_async}};
|
||||
if (!pll_ready_sync[2])
|
||||
reset_shift <= 16'hffff;
|
||||
else
|
||||
reset_shift <= {{reset_shift[14:0], 1'b0}};
|
||||
end
|
||||
|
||||
wire fabric_reset = reset_shift[15];
|
||||
reg [31:0] heartbeat = 32'd0;
|
||||
always @(posedge fabric_clk) begin
|
||||
if (fabric_reset)
|
||||
heartbeat <= 32'd0;
|
||||
else
|
||||
heartbeat <= heartbeat + 32'd1;
|
||||
end
|
||||
|
||||
{internal_decls}
|
||||
|
||||
wire soc_reset = fabric_reset | debug_ndreset;
|
||||
|
||||
rocket_bscan_dmi_tunnel u_rocket_dmi_tunnel (
|
||||
.tck(jtag_TCK),
|
||||
.reset(fabric_reset | jtag_RESET),
|
||||
.bscan_capture(jtag_CAPTURE),
|
||||
.bscan_sel(jtag_SEL),
|
||||
.bscan_shift(jtag_SHIFT),
|
||||
.bscan_tdi(jtag_TDI),
|
||||
.bscan_update(jtag_UPDATE),
|
||||
.bscan_tdo(jtag_TDO),
|
||||
.dmi_clock(debug_clockeddmi_dmiClock),
|
||||
.dmi_reset(debug_clockeddmi_dmiReset),
|
||||
.dmi_req_ready(debug_clockeddmi_dmi_req_ready),
|
||||
.dmi_req_valid(debug_clockeddmi_dmi_req_valid),
|
||||
.dmi_req_addr(debug_clockeddmi_dmi_req_bits_addr),
|
||||
.dmi_req_data(debug_clockeddmi_dmi_req_bits_data),
|
||||
.dmi_req_op(debug_clockeddmi_dmi_req_bits_op),
|
||||
.dmi_resp_ready(debug_clockeddmi_dmi_resp_ready),
|
||||
.dmi_resp_valid(debug_clockeddmi_dmi_resp_valid),
|
||||
.dmi_resp_data(debug_clockeddmi_dmi_resp_bits_data),
|
||||
.dmi_resp_resp(debug_clockeddmi_dmi_resp_bits_resp)
|
||||
);
|
||||
|
||||
assign pmod_spi_dq_OUT = pmod_spi_dq_o;
|
||||
assign pmod_spi_dq_OE = pmod_spi_dq_oe;
|
||||
assign max2771_spi_sdata_OUT = max2771_spi_sdata_o;
|
||||
assign max2771_spi_sdata_OE = max2771_spi_sdata_oe;
|
||||
assign flash_sck = spi_sck;
|
||||
assign flash_csn = spi_csn;
|
||||
assign flash_dq_OUT = spi_dq_o;
|
||||
assign flash_dq_OE = spi_dq_oe;
|
||||
assign uart_tx = uart_txd;
|
||||
|
||||
// The kit LEDs are active-low. Show heartbeat, PLL locks, reset release,
|
||||
// and debug-module activity from LED13 down to LED9.
|
||||
assign led = ~{{heartbeat[25], gps_clock_locked, fabric_pll_locked,
|
||||
~fabric_reset, debug_dmactive}};
|
||||
|
||||
{chr(10).join(assigns)}
|
||||
|
||||
(* syn_preserve = 1 *)
|
||||
{Path(args.rocket_top).stem} u_rocket (
|
||||
{port_map}
|
||||
);
|
||||
|
||||
// These hard-TAP outputs are intentionally unused by the DMI framing logic.
|
||||
wire _unused_hard_signals = jtag_DRCK ^ jtag_RUNTEST ^ jtag_TMS ^
|
||||
board_clk_100 ^ gps_ref_clk_gen ^
|
||||
gps_domain_feedback;
|
||||
endmodule
|
||||
"""
|
||||
|
||||
output = Path(args.out)
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
output.write_text(content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build Efinity raw-HEX images for Ti375C529 persistent Rocket boot."""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
HEX_BYTE = re.compile(r"[0-9a-fA-F]{2}")
|
||||
|
||||
|
||||
def parse_int(value):
|
||||
return int(value, 0)
|
||||
|
||||
|
||||
def read_raw_hex(path):
|
||||
data = bytearray()
|
||||
with path.open() as source:
|
||||
for line_number, line in enumerate(source, 1):
|
||||
value = line.strip()
|
||||
if not HEX_BYTE.fullmatch(value):
|
||||
raise SystemExit(
|
||||
f"{path}:{line_number}: expected one hexadecimal byte per line"
|
||||
)
|
||||
data.append(int(value, 16))
|
||||
return bytes(data)
|
||||
|
||||
|
||||
def write_raw_hex(path, chunks):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with path.open("w") as output:
|
||||
for chunk in chunks:
|
||||
for value in chunk:
|
||||
output.write(f"{value:02X}\n")
|
||||
|
||||
|
||||
def sha256(data):
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Combine an Efinity configuration HEX and Rocket app image"
|
||||
)
|
||||
parser.add_argument("--config-hex", type=Path, required=True)
|
||||
parser.add_argument("--app-bin", type=Path, required=True)
|
||||
parser.add_argument("--app-offset", type=parse_int, required=True)
|
||||
parser.add_argument("--flash-size", type=parse_int, default=0x04000000)
|
||||
parser.add_argument("--nav-context-offset", type=parse_int, required=True)
|
||||
parser.add_argument("--ephemeris-offset", type=parse_int, required=True)
|
||||
parser.add_argument("--combined-hex", type=Path, required=True)
|
||||
parser.add_argument("--app-hex", type=Path, required=True)
|
||||
parser.add_argument("--manifest", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
config = read_raw_hex(args.config_hex)
|
||||
app = args.app_bin.read_bytes()
|
||||
app_end = args.app_offset + len(app)
|
||||
|
||||
if args.app_offset & 0xFFFF:
|
||||
raise SystemExit("application offset must be aligned to a 64-KiB sector")
|
||||
if len(config) > args.app_offset:
|
||||
raise SystemExit(
|
||||
f"configuration image (0x{len(config):x} bytes) overlaps application "
|
||||
f"at 0x{args.app_offset:x}"
|
||||
)
|
||||
if app_end > args.flash_size:
|
||||
raise SystemExit(
|
||||
f"application ends at 0x{app_end:x}, beyond flash size 0x{args.flash_size:x}"
|
||||
)
|
||||
reserved_size = 2 * 0x10000
|
||||
if args.nav_context_offset + reserved_size > args.ephemeris_offset:
|
||||
raise SystemExit("navigation context overlaps ephemeris flash region")
|
||||
if args.ephemeris_offset + reserved_size > args.flash_size:
|
||||
raise SystemExit("ephemeris flash region exceeds device capacity")
|
||||
if app_end > args.nav_context_offset:
|
||||
raise SystemExit(
|
||||
f"application ends at 0x{app_end:x}, overlapping persistent data at "
|
||||
f"0x{args.nav_context_offset:x}"
|
||||
)
|
||||
|
||||
padding_size = args.app_offset - len(config)
|
||||
write_raw_hex(args.app_hex, (app,))
|
||||
write_raw_hex(args.combined_hex, (config, bytes([0xFF]) * padding_size, app))
|
||||
|
||||
manifest = {
|
||||
"format": "Efinity raw HEX (one byte per line)",
|
||||
"flash": "Ti375C529 lower SPI NOR (U47)",
|
||||
"flash_size": f"0x{args.flash_size:08x}",
|
||||
"configuration": {
|
||||
"source": str(args.config_hex),
|
||||
"offset": "0x00000000",
|
||||
"size": len(config),
|
||||
"sha256": sha256(config),
|
||||
},
|
||||
"application": {
|
||||
"source": str(args.app_bin),
|
||||
"offset": f"0x{args.app_offset:08x}",
|
||||
"size": len(app),
|
||||
"sha256": sha256(app),
|
||||
},
|
||||
"navigation_context": {
|
||||
"offset": f"0x{args.nav_context_offset:08x}",
|
||||
"size": reserved_size,
|
||||
},
|
||||
"ephemeris_cache": {
|
||||
"offset": f"0x{args.ephemeris_offset:08x}",
|
||||
"size": reserved_size,
|
||||
},
|
||||
"combined": {
|
||||
"image": str(args.combined_hex),
|
||||
"programmed_length": app_end,
|
||||
},
|
||||
}
|
||||
args.manifest.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.manifest.write_text(json.dumps(manifest, indent=2) + "\n")
|
||||
|
||||
print(f"configuration: 0x00000000..0x{len(config) - 1:08x}")
|
||||
print(f"application: 0x{args.app_offset:08x}..0x{app_end - 1:08x}")
|
||||
print(f"combined HEX: {args.combined_hex}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,316 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Apply small, deterministic Efinity synthesis adaptations to generated RTL."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import math
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROCKET_STORE_DATA = """ else begin
|
||||
automatic logic [3:0][63:0] _GEN_24 =
|
||||
{{ex_rs_1}, {{2{ex_rs_1[31:0]}}}, {{4{ex_rs_1[15:0]}}}, {{8{ex_rs_1[7:0]}}}};
|
||||
mem_reg_rs2 <= _GEN_24[ex_reg_mem_size];
|
||||
end"""
|
||||
|
||||
EFINITY_STORE_DATA = """ else begin
|
||||
// Efinity 2025.2 leaves the block-local packed automatic array above
|
||||
// undriven (VDB-1002). Spell out the byte-lane replication instead.
|
||||
case (ex_reg_mem_size)
|
||||
2'h0: mem_reg_rs2 <= {8{ex_rs_1[7:0]}};
|
||||
2'h1: mem_reg_rs2 <= {4{ex_rs_1[15:0]}};
|
||||
2'h2: mem_reg_rs2 <= {2{ex_rs_1[31:0]}};
|
||||
default: mem_reg_rs2 <= ex_rs_1;
|
||||
endcase
|
||||
end"""
|
||||
|
||||
ATOMIC_LUT_DECLARATION = re.compile(
|
||||
r"^(?P<indent>\s*)automatic logic \[3:0\]\[3:0\] (?P<name>_GEN_[0-9]+) "
|
||||
r"= '\{4'hC, 4'h8, 4'hE, 4'h6\};$",
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
||||
NCO_ROM_START = '(*rom_style = "distributed" *) logic [PH_ACC_WL-1 : 0] freq_word_arr'
|
||||
NCO_ROM_END = "logic [PH_ACC_WL-1 : 0] sin_phase, cos_phase;"
|
||||
|
||||
|
||||
def parse_integer_parameter(text: str, name: str) -> int:
|
||||
match = re.search(rf"\bparameter\s+{re.escape(name)}\s*=\s*([0-9]+)\s*;", text)
|
||||
if match is None:
|
||||
raise RuntimeError(f"could not find integer parameter {name}")
|
||||
return int(match.group(1))
|
||||
|
||||
|
||||
def parse_sv_integer(token: str) -> tuple[int, int | None]:
|
||||
token = token.strip().replace("_", "")
|
||||
match = re.fullmatch(r"(-)?([0-9]+)'([dDhHbB])([0-9a-fA-F]+)", token)
|
||||
if match is not None:
|
||||
sign, width_text, radix_text, digits = match.groups()
|
||||
radix = {"d": 10, "h": 16, "b": 2}[radix_text.lower()]
|
||||
value = int(digits, radix)
|
||||
if sign:
|
||||
value = -value
|
||||
return value, int(width_text)
|
||||
if re.fullmatch(r"-?[0-9]+", token):
|
||||
return int(token), None
|
||||
raise RuntimeError(f"unsupported SystemVerilog integer literal: {token!r}")
|
||||
|
||||
|
||||
def parse_array_parameter(text: str, name: str) -> list[tuple[int, int | None]]:
|
||||
match = re.search(
|
||||
rf"\bparameter\s+\[[^\]]+\]\s+{re.escape(name)}\s*\[[^\]]+\]\s*=\s*\{{(.*?)\}}\s*;",
|
||||
text,
|
||||
re.DOTALL,
|
||||
)
|
||||
if match is None:
|
||||
raise RuntimeError(f"could not find array parameter {name}")
|
||||
return [parse_sv_integer(token) for token in match.group(1).split(",") if token.strip()]
|
||||
|
||||
|
||||
def sv_case_function(
|
||||
name: str,
|
||||
input_width: str,
|
||||
output_width: str,
|
||||
values: list[int],
|
||||
literal_width: int,
|
||||
) -> str:
|
||||
lines = [
|
||||
f"function automatic logic [{output_width}-1 : 0] {name};",
|
||||
f" input logic [{input_width}-1 : 0] index;",
|
||||
" begin",
|
||||
" case (index)",
|
||||
]
|
||||
for index, value in enumerate(values):
|
||||
literal = f"-{literal_width}'sd{-value}" if value < 0 else f"{literal_width}'d{value}"
|
||||
lines.append(f" {index}: {name} = {literal};")
|
||||
lines.extend(
|
||||
[
|
||||
f" default: {name} = '0;",
|
||||
" endcase",
|
||||
" end",
|
||||
"endfunction",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def round_sv_real(value: float) -> int:
|
||||
"""Match real-to-integral assignment rounding used by SystemVerilog."""
|
||||
return math.floor(value + 0.5) if value >= 0 else math.ceil(value - 0.5)
|
||||
|
||||
|
||||
def build_nco_rom_functions(definitions: str) -> str:
|
||||
phase_width = parse_integer_parameter(definitions, "ACQ_NCO_PH_ACC_WL")
|
||||
sine_integer_bits = parse_integer_parameter(definitions, "ACQ_SIN_IL")
|
||||
sine_fraction_bits = parse_integer_parameter(definitions, "ACQ_SIN_FL")
|
||||
lut_address_width = parse_integer_parameter(definitions, "ACQ_SIN_LUT_DEPTH_WL")
|
||||
freq_values = [value for value, _ in parse_array_parameter(definitions, "FREQ_WORD_ARRAY")]
|
||||
pullin_values = [value for value, _ in parse_array_parameter(definitions, "PULLIN_FREQ_WORD_ARRAY")]
|
||||
sine_width = sine_integer_bits + sine_fraction_bits
|
||||
sine_values = [
|
||||
round_sv_real(
|
||||
math.sin(2.0 * math.pi * index / (1 << lut_address_width))
|
||||
* (1 << sine_fraction_bits)
|
||||
)
|
||||
for index in range(1 << lut_address_width)
|
||||
]
|
||||
return "\n\n".join(
|
||||
[
|
||||
"// Efinity 2025.2 mis-elaborates the original initial/$sin ROMs.\n"
|
||||
"// These constant functions are generated from definitions.sv for Ti375 only.",
|
||||
sv_case_function(
|
||||
"efinity_freq_word", "FREQ_BIN_WL", "PH_ACC_WL", freq_values, phase_width
|
||||
),
|
||||
sv_case_function(
|
||||
"efinity_pullin_word", "NUM_PULLIN_WL", "PH_ACC_WL", pullin_values, phase_width
|
||||
),
|
||||
sv_case_function(
|
||||
"efinity_sine", "LUT_DEPTH_WL", "ACQ_SIN_IL + ACQ_SIN_FL", sine_values, sine_width
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def rewrite_acquisition_nco(source: Path, destination: Path, definitions: str) -> None:
|
||||
text = source.read_text(encoding="utf-8")
|
||||
start = text.find(NCO_ROM_START)
|
||||
end = text.find(NCO_ROM_END, start)
|
||||
if start < 0 or end < 0:
|
||||
raise RuntimeError(f"could not locate acquisition NCO ROM block in {source}")
|
||||
text = text[:start] + build_nco_rom_functions(definitions) + "\n\n" + text[end:]
|
||||
old_sum = (
|
||||
"freq_word_arr[freq_bin_idx_i] + "
|
||||
"pullin_freq_word_arr[pullin_freq_bin_idx_i]"
|
||||
)
|
||||
new_sum = (
|
||||
"efinity_freq_word(freq_bin_idx_i) + "
|
||||
"efinity_pullin_word(pullin_freq_bin_idx_i)"
|
||||
)
|
||||
if text.count(old_sum) != 2:
|
||||
raise RuntimeError(f"expected two NCO phase increments in {source}")
|
||||
text = text.replace(old_sum, new_sum)
|
||||
if text.count("sinwav_lut[truncated_sin_phase]") != 1:
|
||||
raise RuntimeError(f"expected one sine ROM read in {source}")
|
||||
if text.count("sinwav_lut[truncated_cos_phase]") != 1:
|
||||
raise RuntimeError(f"expected one cosine ROM read in {source}")
|
||||
text = text.replace("sinwav_lut[truncated_sin_phase]", "efinity_sine(truncated_sin_phase)")
|
||||
text = text.replace("sinwav_lut[truncated_cos_phase]", "efinity_sine(truncated_cos_phase)")
|
||||
destination.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def rewrite_tracking_nco(source: Path, destination: Path, definitions: str) -> None:
|
||||
text = source.read_text(encoding="utf-8")
|
||||
declaration = (
|
||||
'(*rom_style = "distributed" *) logic [SIN_IL-1 : -SIN_FL] '
|
||||
"sinwav_lut [0 : 2**LUT_DEPTH_WL-1];"
|
||||
)
|
||||
values = [value for value, _ in parse_array_parameter(definitions, "TRCK_SINWAV_LUT")]
|
||||
expected_entries = parse_integer_parameter(definitions, "NUM_TRCK_SINWAV_LUT")
|
||||
if len(values) != expected_entries:
|
||||
raise RuntimeError(
|
||||
f"expected {expected_entries} tracking sine entries, got {len(values)}"
|
||||
)
|
||||
function = (
|
||||
"// Efinity 2025.2 leaves the original package-array initialized ROM undriven.\n"
|
||||
"// This Ti375-only constant function preserves the exact definitions.sv values.\n"
|
||||
+ sv_case_function(
|
||||
"efinity_tracking_sine",
|
||||
"LUT_DEPTH_WL",
|
||||
"SIN_IL + SIN_FL",
|
||||
values,
|
||||
parse_integer_parameter(definitions, "TRCK_CARR_NCO_SIN_WL"),
|
||||
)
|
||||
)
|
||||
if text.count(declaration) != 1:
|
||||
raise RuntimeError(f"expected one tracking sine ROM declaration in {source}")
|
||||
text = text.replace(declaration, function)
|
||||
initializer = """initial begin
|
||||
sinwav_lut = TRCK_SINWAV_LUT;
|
||||
end
|
||||
|
||||
"""
|
||||
if text.count(initializer) != 1:
|
||||
raise RuntimeError(f"expected one tracking sine ROM initializer in {source}")
|
||||
text = text.replace(initializer, "")
|
||||
if text.count("sinwav_lut[accum_truncated_sin]") != 1:
|
||||
raise RuntimeError(f"expected one tracking sine ROM read in {source}")
|
||||
if text.count("sinwav_lut[accum_truncated_cos]") != 1:
|
||||
raise RuntimeError(f"expected one tracking cosine ROM read in {source}")
|
||||
text = text.replace(
|
||||
"sinwav_lut[accum_truncated_sin]", "efinity_tracking_sine(accum_truncated_sin)"
|
||||
)
|
||||
text = text.replace(
|
||||
"sinwav_lut[accum_truncated_cos]", "efinity_tracking_sine(accum_truncated_cos)"
|
||||
)
|
||||
destination.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def write_mem_file(path: Path, entries: list[tuple[int, int | None]], width: int) -> None:
|
||||
mask = (1 << width) - 1
|
||||
path.write_text(
|
||||
# Binary keeps each row exactly TWIDDLE_WIDTH bits. A hexadecimal row
|
||||
# would round 15 bits up to four digits and Efinity warns about a
|
||||
# spurious 16-to-15-bit truncation even though the value is correct.
|
||||
"".join(f"{value & mask:0{width}b}\n" for value, _ in entries),
|
||||
encoding="ascii",
|
||||
)
|
||||
|
||||
|
||||
def rewrite_twiddle_rom(source: Path, destination: Path) -> None:
|
||||
text = source.read_text(encoding="utf-8")
|
||||
old = """initial begin
|
||||
cos_rom = COS_ROM_ARRAY;
|
||||
sin_rom = SIN_ROM_ARRAY;
|
||||
end"""
|
||||
new = """initial begin
|
||||
// Generated Ti375 files are resolved through Efinity's memory-init include path.
|
||||
$readmemb("ti375_twiddle_cos_15.mem", cos_rom);
|
||||
$readmemb("ti375_twiddle_sin_15.mem", sin_rom);
|
||||
end"""
|
||||
if text.count(old) != 1:
|
||||
raise RuntimeError(f"expected one twiddle ROM initializer in {source}")
|
||||
destination.write_text(text.replace(old, new), encoding="utf-8")
|
||||
|
||||
|
||||
def prepare_gps_rtl(source_dir: Path, output_dir: Path) -> None:
|
||||
definitions_path = source_dir / "common" / "definitions.sv"
|
||||
definitions = definitions_path.read_text(encoding="utf-8")
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
rewrite_acquisition_nco(
|
||||
source_dir / "acq_src" / "acq_nco_carr.sv",
|
||||
output_dir / "acq_nco_carr.sv",
|
||||
definitions,
|
||||
)
|
||||
rewrite_tracking_nco(
|
||||
source_dir / "trck_src" / "NCO_carr.sv",
|
||||
output_dir / "NCO_carr.sv",
|
||||
definitions,
|
||||
)
|
||||
rewrite_twiddle_rom(
|
||||
source_dir / "acq_src" / "twiddle_ram.sv",
|
||||
output_dir / "twiddle_ram.sv",
|
||||
)
|
||||
cos_entries = parse_array_parameter(definitions, "COS_ROM_ARRAY")
|
||||
sin_entries = parse_array_parameter(definitions, "SIN_ROM_ARRAY")
|
||||
expected_entries = parse_integer_parameter(definitions, "NUM_TWIDDLE_ROM_IDX")
|
||||
if len(cos_entries) != expected_entries or len(sin_entries) != expected_entries:
|
||||
raise RuntimeError(
|
||||
f"expected {expected_entries} twiddle entries, got "
|
||||
f"cos={len(cos_entries)} sin={len(sin_entries)}"
|
||||
)
|
||||
write_mem_file(output_dir / "ti375_twiddle_cos_15.mem", cos_entries, 15)
|
||||
write_mem_file(output_dir / "ti375_twiddle_sin_15.mem", sin_entries, 15)
|
||||
|
||||
|
||||
def rewrite_rocket_store_data(path: Path) -> None:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if EFINITY_STORE_DATA in text:
|
||||
return
|
||||
if text.count(ROCKET_STORE_DATA) != 1:
|
||||
raise RuntimeError(f"expected one Rocket store-data array in {path}")
|
||||
path.write_text(text.replace(ROCKET_STORE_DATA, EFINITY_STORE_DATA), encoding="utf-8")
|
||||
|
||||
|
||||
def rewrite_tilelink_atomic_lut(path: Path) -> None:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if "// Avoid Efinity VDB-1002 on the block-local packed LUT." in text:
|
||||
return
|
||||
match = ATOMIC_LUT_DECLARATION.search(text)
|
||||
if match is None:
|
||||
raise RuntimeError(f"expected one TileLink atomic packed LUT in {path}")
|
||||
if ATOMIC_LUT_DECLARATION.search(text, match.end()) is not None:
|
||||
raise RuntimeError(f"expected only one TileLink atomic packed LUT in {path}")
|
||||
indent = match.group("indent")
|
||||
temporary = match.group("name")
|
||||
old_read = f"{indent}cam_a_0_lut <= {temporary}[auto_in_a_bits_param[1:0]];"
|
||||
new_read = f"""{indent}// Avoid Efinity VDB-1002 on the block-local packed LUT.
|
||||
{indent}case (auto_in_a_bits_param[1:0])
|
||||
{indent} 2'h0: cam_a_0_lut <= 4'h6;
|
||||
{indent} 2'h1: cam_a_0_lut <= 4'hE;
|
||||
{indent} 2'h2: cam_a_0_lut <= 4'h8;
|
||||
{indent} default: cam_a_0_lut <= 4'hC;
|
||||
{indent}endcase"""
|
||||
if text.count(old_read) != 1:
|
||||
raise RuntimeError(f"expected one TileLink atomic packed LUT read in {path}")
|
||||
text = text[: match.start()] + text[match.end() + 1 :]
|
||||
text = text.replace(old_read, new_read)
|
||||
path.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--verilog-dir", type=Path, required=True)
|
||||
parser.add_argument("--gps-source-dir", type=Path, required=True)
|
||||
parser.add_argument("--gps-output-dir", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
rewrite_rocket_store_data(args.verilog_dir / "Rocket.sv")
|
||||
rewrite_tilelink_atomic_lut(args.verilog_dir / "TLAtomicAutomata_pbus.sv")
|
||||
rewrite_tilelink_atomic_lut(args.verilog_dir / "TLAtomicAutomata_cbus.sv")
|
||||
prepare_gps_rtl(args.gps_source_dir, args.gps_output_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -69,6 +69,12 @@ FLASH_FORCE ?= 0
|
||||
GPS_DEBUG ?= 1
|
||||
GPS_DEBUG_LEVEL ?= 4
|
||||
GPS_ESKF_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
|
||||
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
|
||||
GPS_EPHEMERIS_FLASH_BASE ?= 0x07fe0000
|
||||
GPS_NAV_CONTEXT_ENABLE ?= 1
|
||||
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x07fc0000
|
||||
BSP_SPI_FLASH_PROFILE ?= 2
|
||||
IMU_SENSOR ?= auto
|
||||
|
||||
FLASH_MCS ?= $(OUT_DIR)/flash/vcu118_rocket.mcs
|
||||
@@ -213,13 +219,19 @@ fpga-config:
|
||||
' UART_PORT=$(UART_PORT)' \
|
||||
' UART_BAUD=$(UART_BAUD)' \
|
||||
' GPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)' \
|
||||
' GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)' \
|
||||
' GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)' \
|
||||
' GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)' \
|
||||
' GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)' \
|
||||
' BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)' \
|
||||
' IMU_SENSOR=$(IMU_SENSOR)'
|
||||
|
||||
software:
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" bootloader flash-image
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" bootloader flash-image
|
||||
|
||||
$(APP_ELF): FORCE
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" IMU_SENSOR="$(IMU_SENSOR)" app
|
||||
@$(MAKE_BIN) -C "$(SOC_SW_DIR)" TOOLCHAIN="$(TOOLCHAIN)" APP="$(APP)" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(DTIM_BASE)" BSP_DTIM_SIZE="$(DTIM_SIZE)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" app
|
||||
|
||||
chisel: software
|
||||
@cd "$(REPO_DIR)"
|
||||
|
||||
@@ -16,6 +16,10 @@ FIRTOOL ?= $(firstword $(wildcard $(SOC_TOOLS_ROOT)/circt-current/bin/firtool) $
|
||||
Z3_LIB_DIR ?= $(firstword $(wildcard $(SOC_TOOLS_ROOT)/z3-current/bin) $(wildcard $(PROJECT_TOOLS_DIR)/z3/*/bin))
|
||||
CIRCT_LIB_DIR ?= $(patsubst %/bin/firtool,%/lib,$(FIRTOOL))
|
||||
VIVADO ?= $(lastword $(sort $(wildcard /tools/Xilinx/*/Vivado/bin/vivado) $(shell command -v vivado 2>/dev/null)))
|
||||
EFINITY_HOME ?= $(lastword $(sort $(wildcard /tools/efinix/efinity/*)))
|
||||
EFINITY_SETUP ?= $(EFINITY_HOME)/bin/setup.sh
|
||||
EFX_RUN ?= $(EFINITY_HOME)/scripts/efx_run.py
|
||||
EFX_PGM ?= $(EFINITY_HOME)/pgm/bin/ftdi_pgm.sh
|
||||
|
||||
# RISCV_TOOLCHAIN may point either to the toolchain root or its bin directory.
|
||||
# TOOLCHAIN keeps compatibility with the existing software Makefiles.
|
||||
|
||||
Reference in New Issue
Block a user