Your first injection
This first example injects a fault into a simple counter displayed on the seven-segment display of a Digilent Basys3 board. The SoC runs at 75 MHz and a clock divider increments the counter about once per second. The files are in examples/poc_basys3_counter.
The design
Section titled “The design”The counter value goes through LiteInjector before being incremented, so the emulator can modify it:
# Counter --------------------------------------------------------------------------------------count_result = Signal(16)count_clk_divider = Signal(26)injector_output = Signal(16)
self.sync += count_clk_divider.eq(count_clk_divider + 1)self.sync += If(count_clk_divider == 0b11111111111111111111111111, count_result.eq(injector_output + 1))
self.submodules.sseg = SSEG(platform, count_result)
# LiteInjector ---------------------------------------------------------------------------------injector_signals = [count_result, count_clk_divider]
self.submodules.injector = LiteInjector(injector_signals, depth = 16, csr_csv = "injector.csv")self.add_csr("injector")
self.comb += injector_output.eq(self.injector.o_count_result)
self.add_uartbone("liteinjector")- The probed signals are passed as a list. LiteInjector exposes a faulted copy of each one:
o_<signal name>, hereo_count_result. depthis the number of triggers that can be queued.csr_csvis the configuration file written during the build, used by the host tools.add_uartbone("liteinjector")adds the UART bridge used to control the emulator, on dedicated pins.
Try it
Section titled “Try it”-
Build and load the SoC.
Terminal window $ cd liteinjector/examples/poc_basys3_counter$ ./digilent_basys3.py --csr-csv=csr.csv --build --loadThe build writes
csr.csv(register map),injector.csv(LiteInjector configuration) andanalyzer.csv(LiteScope). -
Connect a USB-UART adapter to the UARTBone pins and start
litex_serverin its own terminal.Terminal window $ litex_server --uart --uart-port /dev/ttyUSB1 -
Look at the emulator.
Terminal window $ liteinjector_cli info$ liteinjector_cli list -
Inject the fault. When the clock divider reaches its last value, force the counter signal to
0xFFFF. The counter logic adds one before storing it, so the display goes back to0.Terminal window $ liteinjector_cli run --when count_clk_divider=0x3FFFFFF \--fault bit-value:count_result=0xFFFF --wait 5--waitwaits for the fault and prints the status: hit and fault counters, the cycle of the fault since arming, and the probed data before and after injection.
What’s next
Section titled “What’s next”- See the injection on a waveform with LiteScope.
- Learn how the trigger system and the fault injector work.
- Attack a CPU in the tutorials.