A TPM does not have to be a separate chip. wolfTPM‘s firmware-TPM (fwTPM) is the full TPM 2.0 command engine running as firmware, speaking the same protocol a discrete TPM would. On an FPGA that is a powerful idea: you can place a real root of trust inside the programmable logic you are already building, with no extra part on the board.
The target: Spartan UltraScale+
The AMD Spartan UltraScale+ SCU35 (xcsu35p) is a cost-optimized, pure-FPGA device with no hardened CPU. You compose the system you need in the fabric: for this example, a MicroBlaze V (RISC-V rv32imc) soft core, AXI UARTLite, AXI Timer, block RAM, and the device’s on-die SYSMONE4 System Monitor. The fwTPM runs on that soft core as just another block in your design, co-located with your application logic. A host drives it over UART with the same raw swtpm/mssim framing as our other ports, so the stock wolfTPM swtpm client works against it unmodified.
The problem it solves
Plenty of FPGA designs want a TPM’s services (device identity, attestation and measured boot, sealed keys, monotonic counters), but the board carries no TPM chip, and a pure FPGA has no hardened processor to run one. The fwTPM answers that by putting a standards-compliant TPM 2.0 directly in the fabric on a soft core: a root of trust you integrate into your own bitstream instead of sourcing, placing, and routing a discrete device.
The SCU35 even supplies its own entropy. Instead of a software jitter source, the example seeds the TPM’s DRBG from the on-die SYSMONE4 System Monitor, read as an AXI peripheral – real thermal and supply-rail noise from the silicon. It is hardware-validated: reading the monitor over JTAG shows the low bits jittering, and the TPM’s GetRandom returns different output on every cold boot.
What is in the example
A self-contained bare-metal MicroBlaze V HAL (UART, timer, RV32 startup, retarget), the fwTPM server with its clock / NV / TRNG HALs, and two small wolfSSL-authored Tcl scripts that add the System Monitor to AMD’s reference design without modifying any AMD source. TPM2_Startup and GetRandom pass on the board.
Size, algorithms, and speed
The SCU35 is memory-limited (192 KB of block RAM, no DDR), so this example is a minimal ECC-P256 TPM, about 190 KB, tuned to fit. Adding RSA or post-quantum (ML-DSA / ML-KEM) needs a larger Spartan UltraScale+ part, or one paired with DDR – the same firmware scales up unchanged. Measured on the soft core (MicroBlaze V, 225 MHz, portable-C math):
| Operation | Result |
|---|---|
| ECC P-256 keygen | 9.0 ops/sec |
| ECDHE P-256 agree | 9.0 ops/sec |
| ECDSA P-256 sign | 8.1 ops/sec |
| ECDSA P-256 verify | 4.4 ops/sec |
| SHA-256 | 2.0 MiB/s |
Unhurried next to a hardened core, but well matched to a TPM’s occasional key, sign, and attestation work – with no chip and no CPU on the die. See the example (Xilinx/fwtpm-scu35-microblazev) and PR #6.
If you have questions about any of the above, please contact us at facts@wolfssl.com or call us at +1 425 245 8247.
Download wolfSSL Now

