In my previous article on AI coding assistants, I arrived at a simple conclusion:
AI amplifies clarity. It does not create clarity.
That article generated more discussion than I expected — particularly from engineers working in hardware domains who recognised the FPGA and embedded examples.
Several readers asked for concrete examples. Over the past year, I have used AI coding assistants extensively across FPGA development, embedded Linux, SDR, networking, and build automation. In many situations they saved significant time. In others, they produced technically plausible answers that required careful review before they could be trusted.
The following three examples are drawn from actual engineering work and span build automation, embedded Linux, and SDR design. Each illustrates a different failure mode — and a different lesson about where engineering judgement remains essential.
Example 1 — Vivado Linux-to-Windows Migration
The Problem
A client required FPGA development to be performed on a Windows laptop. The existing Linux-based flow used Makefiles, TCL batch mode, Git, and scripted synthesis and implementation. The workflow was clean, reproducible, and almost never required opening the Vivado GUI.
Moving the flow to Windows introduced multiple issues immediately. Echo redirection corrupted generated TCL scripts — a TCL constraint file generated via echo redirection on Windows silently truncated a set_false_path directive — the file compiled without error but the constraint was not applied. Backslashes confused Vivado's path handling, and there were no direct equivalents for utilities such as touch and symbolic links.
How AI Helped
AI accelerated investigation and prototyping considerably. It helped identify echo quoting as the likely source of TCL corruption, designed a Python template engine to replace fragile echo redirection entirely, generated an initial PowerShell launcher structure, and worked through Vivado-specific path normalisation issues. The generated code was often usable with only minor corrections.
What AI Missed
AI did not proactively identify the echo quoting problem. The issue had to be isolated manually before AI could help confirm the diagnosis.
More significantly, the first PowerShell implementation duplicated substantial portions of the Linux build logic. The generated code worked. The architecture did not. AI naturally gravitated toward creating two separate build systems — one for Linux, one for Windows — which would have increased maintenance effort considerably over time.
AI also failed to identify Windows path-length limitations (260 characters) as a potential issue until specifically prompted.
What Required Engineering Judgement
The final architecture was driven by engineering considerations rather than code generation. Key decisions included creating a single Python orchestration layer, using thin platform-specific launchers, defining rebuild triggers correctly, designing the revision archiving mechanism, and ensuring reproducible builds without committing Vivado-generated project files to source control.
AI repeatedly generated working code — but not necessarily maintainable architecture. The code solved immediate problems. The architecture required deliberate engineering review.
Lesson
AI accelerated implementation significantly. The architectural decisions — single source of truth, thin launchers, template-driven TCL generation, reproducible builds — required engineering judgement. AI behaved like a fast implementer. The design still required an engineer.
Example 2 — Embedded Linux on an ARM Cortex-A15 Platform
The Problem
An embedded Linux platform based on an ARM Cortex-A15 SoC required integration of a USB WiFi adapter operating in IBSS ad-hoc mode. The work involved driver support, firmware loading, kernel configuration, and platform-specific integration within a vendor-supplied Linux SDK.
A separate but related issue involved GPS-based timing. The platform used GPS PPS as the authoritative time source for a time-sensitive protocol. However, systemd-timesyncd was periodically adjusting system time using internet NTP servers, creating conflicts that corrupted the microsecond-precision timing the protocol required.
How AI Helped
AI was extremely useful for Linux-level investigation. It correctly identified the Atheros AR9271 chipset as the strongest candidate for IBSS operation, provided relevant kernel configuration options, generated correct iw and ip commands for ad-hoc mode configuration, and explained systemd service management clearly — including the important distinction between stopping and disabling a service.
On the timing issue, AI correctly identified the conflict and provided the appropriate commands to disable the time synchronisation service permanently.
What AI Missed
Platform-specific details remained outside its knowledge. Vendor SDK kernel dependencies, SDK-specific build procedures, out-of-tree driver behaviour, firmware packaging details, and board-specific USB topology all required direct investigation and testing. The further the problem moved from generic Linux knowledge toward platform-specific implementation, the less AI output could be trusted without verification.
Similar behaviour appeared during kernel customisation work on the same platform. AI was useful in locating configuration options, explaining kernel subsystems, and suggesting build procedures. However, SDK-specific kernel modifications, board-support package interactions, and integration with the existing software stack required direct inspection of the source tree and build environment. The boundary between what AI knew and what required hands-on investigation was consistently the boundary between upstream Linux and the vendor-customised platform.
What Required Engineering Judgement
One particularly clear example involved the GPS and NTP conflict. AI correctly identified that the RTC battery state deserved attention — technically a valid observation. However, engineering judgement led to a different conclusion. Because GPS was the authoritative time source for the application, the RTC state was largely irrelevant. The real problem was preventing NTP from overriding GPS timing, which was a different issue entirely.
AI identified a genuine issue. Engineering determined that it was not the issue that mattered.
Lesson
AI is extremely effective for standard Linux administration, command generation, and initial investigation. Platform-specific behaviour, SDK integration, hardware-level details, and system-level trade-offs still require hands-on engineering work.
Example 3 — AD9363 TDD Timing Constraints
The Problem
A software-defined radio design required a TDD protocol with 7 ms frames, 24 slots per frame, and a slot duration of approximately 292 µs, with per-frame TX/RX slot allocation. Initial investigation suggested that the AD9363 hardware TDD controller — used in the ADALM Pluto SDR platform — could support the required behaviour.
How AI Helped
AI provided substantial and largely accurate assistance. It correctly explained the AD9363 register structure, described the TDD timing registers and their function, explained ENABLE and TXNRX pin behaviour, generated FPGA controller scaffolding, and clarified the differences between the AD9363 and AD9361 for this use case. The individual technical facts were largely correct.
What AI Missed — The Critical Failure
This example represents the most important failure mode I encountered, and the one most relevant to hardware engineers.
AI concluded that reprogramming TDD timing registers between frames was acceptable. The analysis was detailed. The explanation referenced correct register addresses. The conclusion was wrong.
The problem was not hallucination. The register descriptions, timing values, and capabilities were largely correct. The failure occurred because a critical engineering constraint was never reconciled against the actual timing budget. Reprogramming required approximately 500–1000 µs. Slot duration was approximately 292 µs. Those numbers were fundamentally incompatible — yet the analysis concluded the approach was acceptable.
The explanation looked correct. It was not.
What Required Engineering Judgement
The critical review involved something very simple: checking the numbers. Once the timing budget was examined directly, the incompatibility was obvious. The architecture had to change.
Rather than relying on per-frame reprogramming of the hardware TDD controller, the solution moved toward FPGA-based TDD control using the ENABLE and TXNRX pins directly — bypassing the hardware TDD controller entirely and implementing slot-level control in FPGA logic. That architectural shift did not emerge from the AI analysis. It emerged from engineering review.
Lesson
This is the clearest example of AI producing an answer that was technically plausible, internally consistent, and fundamentally wrong. Every important timing analysis should be independently verified. In FPGA, SDR, and real-time systems, correct individual facts do not automatically lead to correct conclusions. The numbers must be checked.
A Related FPGA Observation
A recurring pattern appeared during Vivado timing and constraint work throughout these projects. AI was often useful for TCL command syntax, XDC constraint structure, clock definition examples, and CDC methodology guidance. However, whether a constraint was actually correct for the design depended on understanding the timing intent — something that lives in the engineer's head, not in the prompt.
The syntax was often correct. The engineering intent still required verification.
Two smaller but instructive examples from RTL work illustrate the same pattern at a lower level.
In one case, AI correctly suggested replacing a mask-and-compare pattern for single-bit extraction — (signal & 8'h40) != 0, a style that reflects a common C-programming habit — with direct bit indexing: signal[6]. In a Vivado-based workflow, the indexed form produced simpler synthesized hardware than the mask-and-compare version. More importantly, it expressed the design intent directly: "use bit 6" rather than describing a sequence of software-style operations to reach the same result.
This is a small but instructive example of a broader point. When writing RTL, the primary mental model should be hardware rather than software. The synthesiser may be the compiler, but the output is ultimately logic, registers, and interconnect. AI identified this pattern correctly and consistently suggested the more hardware-oriented representation. Whether different synthesis tools or optimisation settings ultimately generate identical hardware is less important than the underlying lesson: RTL is describing hardware, not software execution.
In another case, a SystemVerilog module had an undeclared output signal that Vivado was silently treating as an implicit wire — standard Verilog-inherited behaviour that produces no error or warning. The design had been synthesised, implemented, and deployed without anyone noticing. AI correctly identified the issue, explained the risk (a typo in a signal name would create a second invisible floating wire rather than a compile error), and recommended adding `default_nettype none at module level to catch implicit declarations at compile time. This was genuinely useful — not something that would have been found without specifically looking for it.
Both cases illustrate AI at its most effective in RTL work: syntax-level and best-practice guidance where the domain knowledge required is general rather than project-specific.
The Common Pattern
Looking across all three examples, the pattern is remarkably consistent.
AI was excellent at finding documentation, explaining APIs, generating code, producing scripts, accelerating implementation, and suggesting starting points. It was much less reliable when architectural trade-offs dominated, when platform-specific constraints mattered, when timing budgets became critical, or when system-level decisions were required.
The more a task resembled implementation, the more useful AI became. The more a task resembled engineering judgement, the more important human review remained.
A similar pattern emerged across multi-subsystem integration work. AI was often useful when discussing individual subsystems — Linux networking, SDR configuration, FPGA interfaces, and protocol implementation. The challenge was rarely understanding the individual pieces. The challenge was understanding how those pieces interacted within the complete system. That integration responsibility remained firmly with the engineer.
If there is one lesson from a year of daily use: AI amplifies clarity. It does not create clarity.
What has your experience been in hardware or embedded domains? I am particularly interested in examples where AI-generated output looked correct but required careful review before deployment.
I regularly write about practical engineering trade-offs in FPGA design, embedded Linux, communications systems, and modern software development workflows.