Synthesizable CRC64 (ECMA-182) and retry/ARQ (Go-Back-N) RTL blocks + a Synopsys Design Compiler sweep flow to extract area / power / timing for pathfinding.
This repo is designed to pair with ~/rs_codec (RS-FEC synthesis sweeps). In our link architecture we treat:
raw data → CRC64 (detect) → RS-FEC (correct) → wire → RS-FEC → CRC64 → ARQ retry
We use payload_bytes and rtt_ns as the primary sweep knobs; other sizing values (e.g., MAX_OUTSTANDING) are derived.
We use:
- Payload:
payload_bytesbytes of delivered data per ARQ frame. - Header:
header_bytesbytes required for ARQ/link bookkeeping (default 8B in configs). - CRC: 8B (CRC64/ECMA).
- RS-FEC parity: modeled/synthesized in
~/rs_codec(not in this repo).
Conceptually, a wire flit contains:
header_bits + payload_bits + crc_bits + fec_parity_bits
In this repo, the synthesized CRC/retry blocks operate on the pre-FEC portion (header+payload+crc), and parity is handled downstream by ~/rs_codec.
rtl/: synthesizable RTL for CRC64 and Go-Back-N retryscripts/: DC sweep Tcl + parallel runnerconfig/: sweep configuration lists (one run per line)link_crc64_rsfec_overhead.py: end-to-end reliability/overhead budgeting model (CRC + RS-FEC + retry)
- Synopsys Design Compiler (
dc_shell) to run sweeps (with a valid license;DCSH-1means DC is not enabled). - Standard-cell libraries:
- ASAP7: provide a path to compiled
.dbfiles (example:.../asap7sc7p5t_28/LIB/CCS/TT) - NanGate45: provide a path to
.dbfiles (example:.../NanGate45/db)
- ASAP7: provide a path to compiled
- SRAM macros (optional, tech-dependent):
- NanGate45:
fakeram45_*macros are in the sameNanGate45/dbdirectory. - ASAP7: SRAM
.libfiles exist inasap7_sram_0p0/generated/LIB/but may need compiling to.dband attribute fixes (seedocs/methodology.md).
- NanGate45:
We do not check any libraries/PDKs into this repo; all paths are passed via config/env vars.
We do not vendor fpganinja/taxi or alexforencich/verilog-lfsr; we cite them as useful reference implementations for AXI-stream utilities and CRC/LFSR generators:
fpganinja/taxi(CERN-OHL-S-2.0)alexforencich/verilog-lfsr(MIT)
Run the CRC+RS-FEC+retry budgeting model:
python3 link_crc64_rsfec_overhead.py --payload-bytes 64,128,256 --header-bytes 8 --ber-delivered-target 1e-27Run DC sweeps (examples):
# ASAP7: compile SRAM liberty to .db (optional, for retry buffer SRAM area)
source $SNPS/Library_Compiler/vT-2022.03-SP4/SETUP
python3 scripts/compile_lib_to_db.py --out-dir out/asap7_sram_db \
--lef-dir /path/to/asap7_sram_0p0/generated/LEF --set-time-unit 1ps --strip-output-voltage \
--lib /path/to/asap7_sram_0p0/generated/LIB/srambank_64x4x64_6t122.lib \
--lib /path/to/asap7_sram_0p0/generated/LIB/srambank_128x4x64_6t122.lib \
--lib /path/to/asap7_sram_0p0/generated/LIB/srambank_256x4x64_6t122.lib
# Run sweeps (config files use lib_dir "-" and require DEFAULT_LIB_DIR)
source $SNPS/Design_Complier/vS-2021.06-SP4/SETUP
# Smoke test (1 config per tech)
python3 scripts/run_sweep_parallel.py --config config/sweep_one_asap7.txt --out-root data/asap7_sweep --num-workers 1 \
--define TECH=asap7 --define DEFAULT_LIB_DIR=/path/to/asap7/TT:out/asap7_sram_db --define USE_SRAM=1
python3 scripts/run_sweep_parallel.py --config config/sweep_one_nangate45.txt --out-root data/nangate45_sweep --num-workers 1 \
--define TECH=nangate45 --define DEFAULT_LIB_DIR=/path/to/NanGate45/db --define USE_SRAM=1
# Full sweep
python3 scripts/run_sweep_parallel.py --config config/sweep_configs_asap7.txt --out-root data/asap7_sweep --num-workers 4 \
--define TECH=asap7 --define DEFAULT_LIB_DIR=/path/to/asap7/TT:out/asap7_sram_db --define USE_SRAM=1
python3 scripts/run_sweep_parallel.py --config config/sweep_configs_nangate45.txt --out-root data/nangate45_sweep --num-workers 4 \
--define TECH=nangate45 --define DEFAULT_LIB_DIR=/path/to/NanGate45/db --define USE_SRAM=1
# If dc_shell is not in PATH, pass it explicitly:
# python3 scripts/run_sweep_parallel.py ... --dc-bin /path/to/dc_shellPlot results (recommended via venv):
python3.11 -m venv .venv
. .venv/bin/activate
pip install -U pip pandas matplotlib
python scripts/plot_sweep.py --out-dir plotsIf you have a SystemVerilog simulator installed (e.g., iverilog):
cd tb
make tb_crc64
make tb_gbn_retryIf you have RS-FEC synthesis summaries from rs_codec, you can generate plots that compare:
- FEC-only (delivered BER target met by RS post-FEC BER alone)
- FEC+CRC(+ARQ) (delivered BER target met via CRC64 miss probability + ARQ retries)
. .venv/bin/activate
python scripts/plot_fec_crc_tradeoffs_vs_ber.py --out-dir plots \
--fec-summary-asap7 /path/to/rs_codec/paperdata/asap7_code_sweep/summary.csv \
--fec-summary-nangate45 /path/to/rs_codec/paperdata/nangate45_code_sweep/summary.csvThis repo also includes link_examples.csv (copied from ~/rs_codec) and a helper that augments it with modeled
ECC overhead:
. .venv/bin/activate
python scripts/link_examples_with_ecc.pyOutputs:
plots/link_examples_with_ecc.csvplots/xcvr_vs_ecc_energy_share_vs_ber.(png|pdf)
The output CSV can be read in groups:
-
Link inputs (from
link_examples.csv)Name: link example name.Link: source URL for the example row.Process_nm: transceiver process node (nm) from the source table.Reach_mm: reach used only for the “electrical” filter.BER_raw: assumed raw (pre-FEC) BER on the wire.Gbps_per_mm_wire: assumed wire throughput per mm.Gbps_per_mm2_wire: assumed wire throughput density (per transceiver area).pJ_per_wire_bit_xcvr: assumed transceiver (“xcvr”) energy per wire bit.
-
Energy scaling metadata
Chosen_ECC_dataset: which ECC synthesis dataset is used as the “base” (ASAP7for FinFET-ish nodes,NanGate45for planar-ish).Energy_scaling_source: which scaling rule was applied.Energy_scale_factor: multiplier applied to ECC energies to estimate this link’s node.
-
Uncoded metrics (payload only)
uncoded_Gbps_per_mm_payload: payload throughput per mm shoreline after discounting overhead (uncoded has no FEC/CRC/ARQ overhead).uncoded_Gbps_per_mm2_payload_useful: useful payload throughput density after discounting wrong bits.uncoded_pJ_per_payload_bit_useful: useful payload energy/bit after discounting wrong bits.
-
FEC-only (targets delivered BER directly via RS post-FEC BER)
fec_only_k,fec_only_t: chosen RS(86,k) parameters.fec_only_meets_target: 1 if the chosenkmeetsber_target.fec_only_goodput_rate: payload bits / wire bits after parity overhead (no retries).fec_only_BER_out: estimated post-FEC BER.fec_only_Gbps_per_mm_payload: payload throughput per mm shoreline after discounting RS parity overhead.fec_only_Gbps_per_mm_fec: throughput “spent” on RS parity bits (sopayload + fec = Gbps_per_mm_wire).fec_only_pJ_per_payload_bit_useful: payload energy/bit accounting only for RS parity overhead (we do not further scale by(1 - fec_only_BER_out)).fec_only_Gbps_per_mm2_payload_useful: payload throughput density (Gbps/mm^2) computed by inverse-summing (mm^2/Gbps) the transceiver and RS-FEC densities (no(1 - BER)discount).fec_only_Gbps_per_mm2_fec: RS-FEC effective payload throughput density term used in the inverse-sum (≈rs_fec_wire_density_gbps_per_mm2(k) * fec_only_goodput_rate).
-
FEC+CRC+ARQ (targets delivered BER after ARQ)
fec_crc_k,fec_crc_t: chosen RS(86,k) parameters.fec_crc_meets_target: 1 if the chosenkmeets the derived frame-fail budget (min of SDC and bounded-retry drop constraints).fec_crc_max_retries: maximum CRC-detected retransmissions (default 1 => 2 total attempts).fec_crc_p_frame_target: derived per-attempt frame-fail budgetp_frame_failused for code selection.fec_crc_p_frame_target_sdc: frame-fail budget implied by the CRC-miss (SDC) constraint alone.fec_crc_p_frame_target_drop: frame-fail budget implied by the bounded-retry drop constraint alone (1-bit-equivalent drop BER).fec_crc_p_frame_fail: per-attempt probability an ARQ frame is corrupted post-FEC (≈CRC fail probability absent a CRC miss).fec_crc_p_drop: probability a frame is dropped due to exhausting the retry limit.fec_crc_BER_drop_eff: effective drop “BER” defined asp_drop / payload_bits(1-bit-equivalent model).fec_crc_BER_pre_crc_target: derived post-FEC (pre-CRC) BER implied byfec_crc_p_frame_targetand the frame length.fec_crc_BER_pre_crc_effective: derived post-FEC (pre-CRC) BER implied by the achievedfec_crc_p_frame_failand the frame length.fec_crc_attempts: expected attempts1/(1 - p_det)wherep_det ≈ p_frame_fail(geometric retry model; per delivered frame).fec_crc_goodput_rate: payload bits / wire bits including retry overhead.fec_crc_BER_out: delivered BER after ARQ (CRC-miss model).fec_crc_Gbps_per_mm_payload: payload throughput per mm shoreline after discounting parity + CRC/header + retry overhead.fec_crc_Gbps_per_mm_fec: throughput “spent” on RS parity bits.fec_crc_Gbps_per_mm_crc: remaining overhead throughput (CRC/header + retries), sopayload + fec + crc = Gbps_per_mm_wire.fec_crc_pJ_per_payload_bit_useful: useful payload energy/bit.fec_crc_Gbps_per_mm2_payload_useful: useful payload throughput density (Gbps/mm^2) computed by inverse-summing (mm^2/Gbps) the transceiver, RS-FEC, CRC64, and retry densities.fec_crc_Gbps_per_mm2_fec: RS-FEC effective useful-payload throughput density term used in the inverse-sum.fec_crc_Gbps_per_mm2_crc: CRC+retry combined effective useful-payload throughput density term used in the inverse-sum.fec_crc_ecc_pJ_per_wire_bit: ECC energy per wire bit at line rate (useful for energy-share calculations withpJ_per_wire_bit_xcvr).
Variant/scenario columns (added as suffixes) are provided for ASAP7 fixed-at-7nm and ASAP7 scaled-to-3nm:
*_asap7_7nm, *_asap7_3nm (energy/area/density columns only).
- Filters
is_electrical_reach_filter: 1 ifReach_mm <= max_reach_mm_electrical(used to pick BER decades for the “trend” plot).
Inputs per link example row:
Gbps/mmandpJ/bitare treated as the wire throughput and wire energy/bit of the PHY+serdes xcvr.BERis the raw (pre-FEC) BER on the wire.
Common framing parameters (script defaults):
payload_bytes=256,header_bytes=8,crc_bytes=8,rtt_ns=10- Delivered BER target:
1e-27
Schemes:
- Uncoded: payload only (no ARQ header/CRC), no ECC.
- FEC-only: RS-FEC sized to meet the same delivered BER target (
1e-27) via RS post-FEC BER alone (no ARQ header/CRC). - FEC+CRC+ARQ: adds an ARQ header + CRC64 miss budget + Go-Back-N retries; RS-FEC sized to keep CRC-fail (retry) probability under the required budget.
- If
BER_raw <= ber_target, this path collapses to the uncoded (no-ARQ) case (no header/CRC/FEC overhead).
- If
Throughput / energy are reported for useful payload bits (discounting bits that are still wrong after protection):
Gbps/mm_payload_useful = (Gbps/mm_wire) * goodput_rate * (1 - BER_out)pJ/bit_payload_useful = pJ/bit_payload_total / (1 - BER_out)
Note: for the FEC-only columns (fec_only_*_payload_useful), we do not apply the (1 - BER_out) discount because the RS post-FEC BER model is used for sizing/pass-fail, not as a throughput penalty. The delivered BER is still reported in fec_only_BER_out.
Where:
goodput_rate = payload_bytes / (wire_bytes_per_attempt * E[attempts])- Uncoded:
wire_bytes_per_attempt = payload,E[attempts]=1,BER_out = BER_raw - FEC-only (streaming model):
wire_bytes_per_attempt = payload * (N/k),E[attempts]=1,BER_outis computed from the RS post-FEC BER approximation used inrs_codec - FEC+CRC+ARQ (streaming model):
wire_bytes_per_attempt = (payload+header+crc) * (N/k),E[attempts] = 1/(1-p_frame_fail),E[attempts] = 1/(1-p_det)withp_det = p_frame_fail * (1-2^-64), andBER_out ≈ f_wrong * (p_frame_fail * 2^-64) / (1 - p_det)withf_wrong=0.5(catastrophic CRC-miss model).
In addition, we derive the p_frame_target for the FEC+CRC+ARQ mode as:
p_frame_target_sdc: implied by the SDC-only (CRC-miss) constraint.p_frame_target_drop: implied by a bounded-retry drop budget usingmax_retries(default 1) and an effective-drop BER modelBER_drop_eff = p_drop / payload_bitswithp_drop = p_det^(max_retries+1).p_frame_target = min(p_frame_target_sdc, p_frame_target_drop).
Energy accounting (per payload bit before the (1 - BER_out) discount):
xcvr_pJ/bit_payload = (pJ/bit_wire_xcvr) / goodput_ratetotal_pJ/bit_payload = xcvr_pJ/bit_payload + ECC_pJ/bit_payload
ECC energy is taken from synthesis summaries:
- RS-FEC energies from
../rs_codec/paperdata/{asap7,nangate45}_code_sweep/summary.csv - CRC/retry energies from
paperdata/{asap7,nangate45}_sweep/summary.csv
ECC energy is scaled to each link’s process node using the same rs_codec polynomial scaling model (and the same
TSMC sub-7nm heuristic for 3/5nm).
plots/xcvr_vs_ecc_energy_share_vs_ber.(png|pdf) is a stylized trend plot:
- Uses BER decade bins observed in the “electrical” subset (filtered by reach; see script flag).
- Assumes a representative constant xcvr energy/bit (default
0.5 pJ/bit) and computes ECC energy/bit vs BER using the FEC+CRC+ARQ model at the configured(payload,header,crc,rtt). - Converts ECC energy from “per payload bit” to “per wire bit” via
ECC_pJ/bit_wire = ECC_pJ/bit_payload * goodput_rate. - Energy shares are then
xcvr_share = xcvr/(xcvr+ecc)andecc_share = ecc/(xcvr+ecc).
This is intended as an illustrative “where the power goes as BER worsens” plot rather than a measurement of any single published link’s exact power split.
MIT (see LICENSE).