The same RTL can go into either. The decision is almost never about whether the
logic fits — it is about volume, schedule, and how sure you are that the design
is finished.
The cost crossover
Total cost is non-recurring engineering plus per-unit:
Ctotal=NRE+n⋅cunit
An ASIC has brutal NRE (masks, verification, packaging qualification — seven
figures at a modern node) and tiny unit cost. An FPGA has near-zero NRE and a
unit cost that never falls below the price of the part. Set them equal and the
break-even volume is
n∗=cFPGA−cASICNREASIC−NREFPGA
For most mid-complexity digital designs that lands somewhere in the tens of
thousands of units. Below it, the FPGA wins on arithmetic alone. Above it, the
ASIC does — provided you only pay the NRE once.
The part nobody budgets for
FPGA
ASIC
NRE
~0
very high, per respin
Unit cost
high, flat
very low at volume
Time to first silicon
minutes
months
Cost of a logic bug
rebuild the bitstream
another mask set
Power at equal function
5–10× worse
baseline
Max clock
lower
higher
That “cost of a logic bug” row is the one that moves projects. An FPGA respin is
a coffee break. An ASIC respin is a quarter and a mask set, which is why ASIC
verification budgets routinely exceed design budgets.
Which is why CDC discipline is not optional
Clock-domain crossings are the classic bug that simulates clean and fails in
silicon. On an FPGA you find it in the lab and fix it that afternoon. On an ASIC
you find it after tapeout. The rules are identical in both cases:
The two-flop synchronizer
Two flip-flops in series, both on the receiving clock. The first one is allowed
to go metastable; it gets a full clock period to resolve before the second one
samples it.
module sync_2ff #(parameter WIDTH = 1) ( input wire clk, input wire rst_n, input wire [WIDTH-1:0] async_in, output reg [WIDTH-1:0] sync_out); reg [WIDTH-1:0] meta; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin meta <= '0; sync_out <= '0; end else begin meta <= async_in; // may go metastable sync_out <= meta; // has had a full period to settle end endendmodule
Three rules that come with it:
Never fan out the first stage. If meta drives anything other than
sync_out, different loads can resolve to different values and you have
just built a circuit that disagrees with itself.
Only synchronize single bits this way. Two bits crossing together can
resolve on different clock edges, so a bus can transit through values it
never actually held. Use a handshake or an async FIFO with Gray-coded
pointers instead.
Tell the tools. Constrain the path as a false path or set_max_delay,
otherwise static timing analysis will report a violation it cannot fix and
you will be tempted to “solve” it by deleting the synchronizer.
The bug does not reproduce
Metastability failures are rare, temperature-dependent, and vanish under a
logic analyzer. If a design fails once a week in the field and never on the
bench, audit every clock-domain crossing before you audit anything else.
Prototype on an FPGA regardless. If the volume never materialises you have
shipped anyway; if it does, you tape out RTL that has been running in the field
instead of RTL that has only ever run in a simulator.