191 lines
7.8 KiB
Markdown
191 lines
7.8 KiB
Markdown
# 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 versioned Efinity installations under
|
|
`/tools/efinix/efinity`, `/tools/Efinix/efinity`, `/opt`, the current user's
|
|
home directory, and `tools/local/efinity`. Override discovery when required:
|
|
|
|
```bash
|
|
make FPGA_BOARD=ti375c529 fpga-bitstream \
|
|
EFINITY_HOME=/path/to/efinity/<version>
|
|
```
|
|
|
|
`fpga-rtl` does not require Efinity. The `interface`, `bitstream`, and
|
|
programming targets require a complete Efinity installation containing
|
|
`bin/setup.sh` and `scripts/efx_run.py`; they now stop before hardware
|
|
elaboration with a direct diagnostic when it is absent.
|
|
Concurrent Ti375 `map` or `bitstream` invocations are rejected because they
|
|
share generated FIRRTL, SystemVerilog, and Efinity work directories.
|
|
Efinity is run with unbuffered Python output so `map`, `pnr`, and `pgm`
|
|
progress remains visible in the terminal and `out/logs/full.log`.
|
|
|
|
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 |
|