Ethernet · Module 22
ADAS and Sensor Data
A sensor suite is 20 Gb/s raw and 1 compressed, the network is 1.7% of a braking reaction, and a rolling shutter's own 20 ms readout is twelve times everything the network does.
A sensor suite produces twenty gigabits per second raw and one compressed. That ratio is why the data moved to Ethernet, and it is also the whole architectural argument.
| Sensor | Count | Raw | Reduced |
|---|---|---|---|
| 2 MP surround cameras, 30 fps, 12-bit | 8 | 0.746 Gb/s each | 24.9 Mb/s at 30:1 |
| 8 MP forward cameras, 30 fps, 12-bit | 4 | 2.986 Gb/s each | 99.5 Mb/s at 30:1 |
| 77 GHz imaging radars, 20 Hz | 5 | 335.5 Mb/s each | 1.02 Mb/s as an object list |
| lidar, 2.6 Mpoint/s | 2 | 187.2 Mb/s each | — |
| suite total | 19 | 19.97 Gb/s | 976.7 Mb/s |
A factor of 20.4 between the two totals, and every architectural decision in a vehicle's sensor network is a choice of where on that scale to sit.
The reason Ethernet won is in one comparison.
| Bus | Rate | The suite needs |
|---|---|---|
| CAN | 1 Mb/s | 19 968× more |
| CAN-FD | 8 Mb/s | 2 496× |
| FlexRay | 10 Mb/s | 1 997× |
| 100BASE-T1 | 100 Mb/s | 200× |
| 1000BASE-T1 | 1 Gb/s | 20× |
| a 10 Gb/s backbone | 10 Gb/s | 2× |
No incremental improvement to a vehicle bus reaches three orders of magnitude. That is not a preference for Ethernet; it is the absence of an alternative, and it is the honest answer to why the industry changed.
And then the second result, which is the one people find surprising.
| Stage of a reaction | Time | Share | Distance at 30 m/s |
|---|---|---|---|
| exposure | 10.0 ms | 10.3% | 30 cm |
| readout and ISP | 5.0 ms | 5.2% | 15 cm |
| encode | 10.0 ms | 10.3% | 30 cm |
| transport, sensor to compute | 0.84 ms | 0.9% | 2.5 cm |
| decode | 10.0 ms | 10.3% | 30 cm |
| fusion and perception | 30.0 ms | 31.0% | 90 cm |
| planning | 10.0 ms | 10.3% | 30 cm |
| transport, compute to actuator | 0.84 ms | 0.9% | 2.5 cm |
| actuator response | 20.0 ms | 20.7% | 60 cm |
| total | 96.7 ms | 100% | 2.90 m |
The network is 1.7% of the reaction time — five centimetres of a 2.90 metre stopping distance.
So the network's job is not to be fast. It is to be bounded, which is Chapter 22.2's subject, and to carry a timestamp that is right, which is this chapter's — because Section 12 shows a one-millisecond timestamp error puts a tracked object three centimetres out of place, and a ten-millisecond one puts it thirty.
And one number that dwarfs everything the network does.
| At 30 m/s | |
|---|---|
| the network's whole contribution | 5.0 cm |
| a rolling-shutter camera's 20 ms readout skew | 60.0 cm |
The sensor's own acquisition interval is twelve times the network's entire latency budget, and Section 10 is about what that does to every property anyone wants to write about a frame.
1. Scope — Why Sensor Data Moved to Ethernet, in Numbers
Scope: what an ADAS sensor suite produces, what carrying it requires, where the data gets reduced, and what the network contributes to a decision.
Not in scope: perception. What a fusion stack does with the data is a different discipline with a different literature. This chapter stops at the point where a timestamped, bounded, correctly sized stream is delivered to it — and its claim is that everything before that point is an engineering problem with arithmetic answers.
Three questions, in the order they have to be answered.
| Question | Answered in | |
|---|---|---|
| 1 | how much data is there? | Sections 2 and 4 |
| 2 | where is it reduced, and what does reducing it cost? | Sections 6 and 14 |
| 3 | what does the network contribute to a deadline? | Sections 8, 10 and 12 |
Question 2 is the architectural one and it has only three answers.
| Reduce | Where | Link needed | Cost |
|---|---|---|---|
| not at all | — | 25 Gb/s | nothing lost |
| compress | at the sensor | 1.25 Gb/s | Section 14's lossy artefacts |
| detect and report objects | at the sensor | under 10 Mb/s | the raw data, permanently |
Row three is how radar has always worked and row two is how cameras mostly work, and the chapter's most useful practical result is Section 6's: the three rows are not interchangeable, because what is thrown away cannot be recovered by a better algorithm later.
And one framing that runs through the chapter. Chapter 22.2 showed that a vehicle network's hard problem is bounding latency rather than reducing it. This chapter shows why: the network is under two per cent of the chain, so making it faster is worth almost nothing and making it unpredictable is worth a great deal. The same argument applies to time: a network that delivers a frame 500 microseconds late costs 1.5 centimetres of position error, and a network that mis-timestamps it by 10 milliseconds costs 30.
2. The Sensor Suite, Derived
Every number in this section comes from four inputs: pixel count, frame rate, bit depth, and how many of them there are.
Cameras first, because they dominate.
raw rate = pixels × frames per second × bits per pixel
| 2 MP surround | 8 MP forward | |
|---|---|---|
| resolution | 1 920 × 1 080 | 3 840 × 2 160 |
| pixels | 2.07 × 10⁶ | 8.29 × 10⁶ |
| frame rate | 30 fps | 30 fps |
| bit depth | 12 | 12 |
| raw rate | 0.746 Gb/s | 2.986 Gb/s |
| one raw frame | 3.11 MB | 12.44 MB |
| at 30:1 compression | 24.9 Mb/s | 99.5 Mb/s |
Row four is the one that is often forgotten and it costs 50%. An automotive imager runs at 12 bits rather than 8, because the dynamic range of a scene containing both a tunnel mouth and direct sun needs it — and the raw rate is linear in bit depth. A design that budgeted 8-bit pixels is short by a third.
Radar, where the ratio between raw and reduced is extreme.
| Value | |
|---|---|
| receive channels | 4 |
| range samples per chirp | 1 024 |
| chirps per frame | 256 |
| sample width | 16 bits |
| frame rate | 20 Hz |
| raw ADC rate | 335.5 Mb/s |
| as an object list — 200 objects, 256 bits each, 20 Hz | 1.02 Mb/s |
| ratio | 327.7× |
Three hundred and twenty-eight to one is the largest reduction ratio in the vehicle and it is why radar has been sent over low-rate buses for decades: a radar that reports objects rather than samples fits on CAN. Section 6 is about what that costs when four radars' object lists disagree and there is no raw data to go back to.
Lidar.
| Value | |
|---|---|
| points per second | 2.6 × 10⁶ |
| bits per point — x, y, z at 16 bits, plus intensity and flags | 72 |
| rate | 187.2 Mb/s |
Lidar has no useful "object list" mode in the radar sense — the point cloud is the product — so its rate is what it is, and two units are 374.4 Mb/s before anything else is connected.
The suite.
| Configuration | Rate |
|---|---|
| everything raw | 19.97 Gb/s |
| cameras at 30:1, radar as objects, lidar raw | 976.7 Mb/s |
| ratio | 20.4× |
Two numbers, an order of magnitude apart, and the whole architecture is a choice between them.
3. RTL 1 — The ADAS Package and the Volume Model
// ---------------------------------------------------------------------
// adas_pkg -- a sensor suite as arithmetic.
//
// Every constant here is an input to a multiplication, and the whole
// chapter is that multiplication having consequences. The one number
// that is not derived is the compression ratio, and Section 14 is about
// why it is the most dangerous number in the package.
// ---------------------------------------------------------------------
package adas_pkg;
typedef enum logic [2:0] {
S_CAM_2MP = 3'd0,
S_CAM_8MP = 3'd1,
S_RADAR = 3'd2,
S_LIDAR = 3'd3,
S_ULTRA = 3'd4
} sensor_e;
// ---- cameras ---------------------------------------------------------
localparam int CAM2_PIXELS = 1920 * 1080; // 2 073 600
localparam int CAM8_PIXELS = 3840 * 2160; // 8 294 400
localparam int CAM_FPS = 30;
// An automotive imager is 12 bits, not 8: a scene with a tunnel mouth
// and direct sun needs the dynamic range, and the raw rate is linear
// in bit depth.
localparam int CAM_BITS = 12;
// ---- radar -----------------------------------------------------------
localparam int RAD_RX = 4;
localparam int RAD_SAMPLES = 1024;
localparam int RAD_CHIRPS = 256;
localparam int RAD_BITS = 16;
localparam int RAD_HZ = 20;
localparam int RAD_OBJECTS = 200;
localparam int RAD_OBJ_BITS = 256;
// ---- lidar -----------------------------------------------------------
localparam int LID_POINTS_S = 2_600_000;
localparam int LID_BITS_PT = 72; // x, y, z at 16 + intensity
// ---- the suite -------------------------------------------------------
localparam int N_CAM2 = 8;
localparam int N_CAM8 = 4;
localparam int N_RADAR = 5;
localparam int N_LIDAR = 2;
// ---- reduction -------------------------------------------------------
typedef enum logic [1:0] {
RED_NONE = 2'd0, // raw
RED_COMPRESS= 2'd1, // lossy, at the sensor
RED_OBJECTS = 2'd2 // detection at the sensor; raw discarded
} reduction_e;
localparam int COMPRESS_RATIO = 30;
// Rates in kilobits per second, to keep the integers in range.
function automatic int cam_kbps(int pixels, int ratio);
return (pixels / 1000) * CAM_FPS * CAM_BITS / ratio;
endfunction
function automatic int radar_raw_kbps();
return (RAD_RX * RAD_SAMPLES * RAD_CHIRPS * RAD_BITS * RAD_HZ) / 1000;
endfunction
function automatic int radar_obj_kbps();
return (RAD_OBJECTS * RAD_OBJ_BITS * RAD_HZ) / 1000;
endfunction
function automatic int lidar_kbps();
return (LID_POINTS_S / 1000) * LID_BITS_PT;
endfunction
// ---- time ------------------------------------------------------------
// Section 12: a timestamp error becomes a position error at the
// vehicle's speed. 30 m/s is 3 cm per millisecond.
localparam int SPEED_CM_PER_MS = 3;
// Section 10: a rolling shutter's readout interval, which is NOT
// represented anywhere in the frame's data.
localparam int ROLLING_READOUT_US = 20_000;
endpackageClassification: a package of measured quantities and four multiplications, with one constant that is a policy rather than a fact.
What it teaches: that COMPRESS_RATIO is the only number here that a design chooses. Pixel count, frame rate, bit depth, chirp count and point rate are all properties of a sensor somebody bought; 30:1 is a decision, it is not derived from anything, and Section 14 argues it is the most consequential number in the vehicle's sensor path because it is the only one whose cost is invisible in every measurement.
And it teaches that ROLLING_READOUT_US belongs in the package at all. A frame's readout interval is 20 milliseconds and it appears in no field of the frame — not in the pixel data, not in the container, and usually not in the stream's metadata. The package carries it as a constant because nothing else in the system carries it, which is precisely Section 20's rejected class.
Deliberately simplified: rates are in kilobits per second with integer division, so every function rounds down by up to 0.1%. COMPRESS_RATIO is a single number where a real encoder's ratio varies by an order of magnitude with scene content — a static scene compresses far better than a rainy motorway — which makes the peak rate, not the average, the one to size links against. SPEED_CM_PER_MS is 30 m/s as an integer, and a closing speed on a two-way road is double that. And S_ULTRA is declared and never used, which is honest: ultrasonic sensors exist, produce a few kilobits per second, and change no number in this chapter.
Production implication: the variable compression ratio is the one that breaks link budgets in the field. An encoder targeting 30:1 on average delivers 10:1 on a scene with rain, spray and moving foliage — exactly the conditions where the sensor matters most — so the 99.5 Mb/s forward camera becomes 299 Mb/s at the worst possible moment. Size the link against the worst-case ratio, and configure the encoder with a hard rate cap so the failure is degraded image quality rather than a link that overruns. A stream that exceeds its budget takes the whole schedule's non-express window with it, which is Chapter 22.2 §17's arithmetic run in reverse.
// ---------------------------------------------------------------------
// sensor_volume_model -- the suite's rate under a chosen reduction
// policy, and the link rate it implies.
//
// The block exists so that a configuration which cannot fit is
// rejected at elaboration rather than discovered on a test track.
// ---------------------------------------------------------------------
module sensor_volume_model
import adas_pkg::*;
(
input logic clk,
input logic rst_n,
input reduction_e cam_policy,
input reduction_e radar_policy,
input logic [31:0] link_kbps,
input logic [7:0] utilisation_cap_pct,
output logic [31:0] suite_kbps,
output logic [31:0] cam_kbps_total,
output logic [31:0] radar_kbps_total,
output logic [31:0] lidar_kbps_total,
output logic fits,
output logic [15:0] headroom_pct,
output logic [31:0] link_kbps_required
);
always_comb begin
cam_kbps_total =
(cam_policy == RED_NONE)
? 32'(N_CAM2 * cam_kbps(CAM2_PIXELS, 1)
+ N_CAM8 * cam_kbps(CAM8_PIXELS, 1))
: 32'(N_CAM2 * cam_kbps(CAM2_PIXELS, COMPRESS_RATIO)
+ N_CAM8 * cam_kbps(CAM8_PIXELS, COMPRESS_RATIO));
radar_kbps_total =
(radar_policy == RED_OBJECTS)
? 32'(N_RADAR * radar_obj_kbps())
: 32'(N_RADAR * radar_raw_kbps());
// Lidar has no object mode in the radar sense: the point cloud IS
// the product, so there is no policy input for it.
lidar_kbps_total = 32'(N_LIDAR * lidar_kbps());
suite_kbps = cam_kbps_total + radar_kbps_total + lidar_kbps_total;
link_kbps_required = (utilisation_cap_pct == 0) ? 32'hFFFF_FFFF
: (suite_kbps * 100) / 32'(utilisation_cap_pct);
fits = (suite_kbps * 100) <= (link_kbps * 32'(utilisation_cap_pct));
headroom_pct = (link_kbps == 0) ? 16'd0
: 16'(((link_kbps - suite_kbps) * 100) / link_kbps);
end
endmoduleClassification: a capacity check with two policy inputs and one missing one.
What it teaches: that lidar has no policy input and that absence is the interesting part of the block. A radar can report objects because detection is cheap and well-defined at the sensor; a camera can compress because the consumer is a perception stack that tolerates artefacts. A lidar's point cloud is already the reduced form of what the sensor measured, so there is nothing further to remove without deciding what the fusion stack is allowed to see — which is a perception decision made in a sensor.
And it teaches that utilisation_cap_pct is not optional. Sizing a link at 100% of the suite's rate leaves nothing for Chapter 22.2's guard band, the express window, control traffic, diagnostics, or the compression ratio's variance. At an 80% cap, a 976.7 Mb/s suite needs a 1.22 Gb/s link — so 1000BASE-T1 does not fit it, which is a result worth having before the harness is designed.
Deliberately simplified: the model is an average rate where Section 14 shows the peak is what matters. Policies are per sensor type rather than per sensor, so a suite mixing raw and compressed cameras is inexpressible — and real vehicles do exactly that, keeping the forward camera raw. And there is no notion of where the traffic goes, so a model that would reveal a congested zone uplink is not present.
Production implication: the missing per-sensor policy is how real architectures are built, and it changes the arithmetic materially. Keeping the four forward cameras raw and compressing the eight surround ones gives 11 944 + 199 = 12.14 Gb/s rather than 597 Mb/s — a factor of 20 — and that single decision is what separates a 1 Gb/s zone architecture from a 25 Gb/s one. Model the policy per sensor, price both, and make the decision explicitly, because it will otherwise be made implicitly by whoever specifies the first camera.
4. Twenty Gigabits Raw, One Compressed — and What That Decides
The suite's two totals are 19.97 Gb/s and 976.7 Mb/s. This section is the ladder between them and what each rung costs.
| Configuration | Rate | Link needed at 80% |
|---|---|---|
| everything raw | 19.97 Gb/s | 24.96 Gb/s |
| radar as objects, cameras and lidar raw | 18.29 Gb/s | 22.87 Gb/s |
| forward cameras raw, surround compressed, radar as objects | 12.52 Gb/s | 15.65 Gb/s |
| all cameras at 30:1, radar as objects, lidar raw | 976.7 Mb/s | 1.22 Gb/s |
| everything reduced as far as it goes | ≈ 600 Mb/s | ≈ 750 Mb/s |
Row four is the configuration most vehicles ship and row one is what a development vehicle records. The difference between them is 20.4×, and the whole of it is compression.
And the ladder has an awkward rung. Row four needs 1.22 Gb/s at an 80% utilisation cap, and 1000BASE-T1 delivers 1 Gb/s — so the commonest suite does not fit the commonest automotive link with sensible headroom. The available responses are three:
| Response | Consequence |
|---|---|
| push the compression ratio to 40:1 | suite falls to 827 Mb/s; artefacts worsen |
| split the suite across two zone uplinks | fits; doubles the uplink count |
| use a 2.5 Gb/s backbone | fits with 61% headroom; a different PHY |
Row two is what most zone architectures actually do and it is why Chapter 22.2 §2's topology has four zone controllers rather than one: the sensors are spread across the vehicle anyway, and spreading them across four uplinks divides the per-link rate by roughly four.
Now the comparison that explains the industry change.
| Bus | Rate | Suite / bus |
|---|---|---|
| CAN | 1 Mb/s | 19 968× |
| CAN-FD | 8 Mb/s | 2 496× |
| FlexRay | 10 Mb/s | 1 997× |
| LVDS point-to-point per camera | ≈ 3 Gb/s | fits one camera, and only one |
| 100BASE-T1 | 100 Mb/s | 200× |
| 1000BASE-T1 | 1 Gb/s | 20× |
Row four is the arrangement Ethernet replaced and it is worth being precise about. Before Ethernet, a raw camera went to its ECU over a dedicated point-to-point serial link — which works, carries 3 Gb/s, and does not switch. Twelve cameras meant twelve dedicated links to one box, and the moment two consumers wanted the same camera the arrangement had no answer.
Ethernet did not win on bandwidth. A point-to-point serial link had more. It won because the data had more than one consumer and a point-to-point link has exactly one.
That is the honest account and it matters for the architecture: a switched network lets a forward camera feed perception, recording and a driver display at once, which is the requirement that no dedicated link satisfies at any rate.
5. RTL 2 — The Raw-Versus-Object Selector
// ---------------------------------------------------------------------
// raw_vs_object_selector -- the architectural decision, as a block.
//
// A sensor that reports objects instead of samples reduces its rate by
// 327.7 to one. What it also does is move the detection decision into
// a part that cannot be changed later and whose input nobody can
// inspect afterwards.
//
// The block's job is to make that trade explicit and to count what is
// being discarded.
// ---------------------------------------------------------------------
module raw_vs_object_selector
import adas_pkg::*;
#(
parameter int OBJ_CAPACITY = RAD_OBJECTS // 200
)(
input logic clk,
input logic rst_n,
input reduction_e policy,
input logic frame_valid,
input logic [31:0] raw_bits_this_frame,
input logic [15:0] detections_this_frame,
input logic [15:0] detections_below_threshold,
output logic [31:0] emitted_bits,
output logic [31:0] discarded_bits,
output logic [15:0] reduction_ratio,
output logic object_list_overflowed,
output logic [15:0] objects_dropped,
output logic [31:0] c_frames,
output logic [31:0] c_overflow_frames,
output logic [31:0] c_subthreshold_discarded,
output logic raw_recoverable
);
logic [15:0] emitted_objects;
always_comb begin
object_list_overflowed = (detections_this_frame > 16'(OBJ_CAPACITY));
emitted_objects = object_list_overflowed ? 16'(OBJ_CAPACITY)
: detections_this_frame;
objects_dropped = object_list_overflowed
? (detections_this_frame - 16'(OBJ_CAPACITY))
: 16'd0;
case (policy)
RED_NONE: emitted_bits = raw_bits_this_frame;
RED_OBJECTS: emitted_bits = 32'(emitted_objects) * RAD_OBJ_BITS;
default: emitted_bits = raw_bits_this_frame / COMPRESS_RATIO;
endcase
discarded_bits = raw_bits_this_frame - emitted_bits;
reduction_ratio = (emitted_bits == 0) ? 16'hFFFF
: 16'(raw_bits_this_frame / emitted_bits);
// The output that names the architecture: only RED_NONE leaves the
// raw data available to a later algorithm.
raw_recoverable = (policy == RED_NONE);
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
c_frames <= '0; c_overflow_frames <= '0;
c_subthreshold_discarded <= '0;
end else if (frame_valid) begin
c_frames <= c_frames + 32'd1;
if (object_list_overflowed)
c_overflow_frames <= c_overflow_frames + 32'd1;
// Detections the sensor saw and did not report because they were
// below its own confidence threshold. This is the number nobody
// collects and it is the one that matters.
c_subthreshold_discarded <= c_subthreshold_discarded
+ 32'(detections_below_threshold);
end
end
endmoduleClassification: a reduction policy with three counters, two of which nobody normally keeps.
What it teaches: that c_subthreshold_discarded is the number that decides whether object-level reduction was safe. A radar reporting 200 objects at 20 Hz is discarding everything below its detection threshold, and that threshold was set by a supplier, in firmware, against a test suite that did not include the scene the vehicle is in now. A pedestrian at the edge of detectability is a sub-threshold detection, and in object mode there is no record that the sensor saw anything at all.
And it teaches that object_list_overflowed is a real and under-reported failure. Two hundred objects sounds generous until the vehicle is in dense traffic with roadside furniture, and an overflowing list discards by whatever order the detector emitted them, which is not by importance. The counter costs 32 flops and turns a silent truncation into a known one.
Deliberately simplified: the compression branch divides by a constant ratio where a real encoder's output varies by an order of magnitude with content — Section 3's production note. reduction_ratio is integer division, so a ratio of 327.7 reads as 327. detections_below_threshold is an input the sensor must provide and most do not. And raw_recoverable is a boolean where the useful form is for how long — a vehicle that buffers ten seconds of raw data and overwrites it is a different proposition from one that never stored it.
Production implication: the ten-second buffer is the practical middle path and it is worth naming, because it changes the trade in Section 6 from a permanent choice into a temporary one. A sensor that emits objects continuously and keeps a rolling raw buffer costs a few hundred megabytes of DRAM at the sensor, carries object-rate traffic in normal operation, and can be asked for the raw data after an event. The network's role is then a burst channel, not a continuous one — a 12.44 MB raw camera frame at 1 Gb/s is 99.5 milliseconds, which is unacceptable as a steady stream and entirely acceptable as a one-off after a triggered event. That single reframing is what makes object-level reduction defensible.
6. Where the Data Is Reduced Decides the Architecture
Three places to reduce, and the choice is not reversible.
| Reduce at | Suite rate | What is lost | Recoverable? |
|---|---|---|---|
| nowhere | 19.97 Gb/s | nothing | — |
| the sensor, by compression | 976.7 Mb/s | Section 14's artefacts | no |
| the sensor, by detection | ≈ 600 Mb/s | everything below the threshold | no |
| the central compute | 19.97 Gb/s on the wire | nothing on the wire | yes |
Row four is the configuration that makes every other problem easy and the network problem hard, and it is exactly the trade an architecture is choosing between. Reducing at the sensor makes the network cheap and the decision permanent; reducing at the compute keeps every option and needs 25 Gb/s of link.
Three consequences follow, and they are not obvious.
First: reduction at the sensor puts a safety-relevant algorithm in a part you did not design. A radar's detection threshold, a camera's encoder settings, and the object list's ordering are all supplier firmware, they are updated on the supplier's schedule, and their behaviour on the scene that matters was validated by somebody else. Chapter 21.2 §3's two-authority problem, arriving in a sensor: the vehicle's perception stack and the sensor's detector are two authorities on what was there, and only one of them has the data.
Second: reduction ratios are not comparable across sensors, so a fusion stack sees inconsistent evidence.
| Sensor | Reduction | What survives |
|---|---|---|
| radar in object mode | 327.7× | a list, with the sensor's confidence |
| camera at 30:1 | 30× | every pixel, degraded |
| lidar | 1× | every point |
Fusing those three is fusing a decision, an approximation and a measurement, and the fusion stack has no way to know that the radar's absence of a detection is an assertion by a supplier's threshold rather than an observation. That asymmetry is invisible in the data and is one of the harder problems in the field.
Third: the network's requirement is entirely determined by this choice and by nothing else.
| Architecture | Zone uplink | Backbone |
|---|---|---|
| sensor-side reduction | 1 Gb/s | 1 to 2.5 Gb/s |
| forward cameras raw | 2.5 to 10 Gb/s | 10 Gb/s |
| everything raw | 10 Gb/s | 25 Gb/s |
Read the rows as three different vehicles, because they are: the PHYs differ, the switch differs, the power budget differs, and the cost differs by a large multiple. The decision that produces them is made by whoever specifies the first sensor, usually years before anyone draws the network — and Section 3's per-sensor policy is the model that would have made it visible.
And one hybrid that gets the best of both.
Emit objects continuously; keep a rolling raw buffer at the sensor; carry raw only on request, after a trigger.
A 12.44 MB raw 8 MP frame at 1 Gb/s is 99.5 milliseconds — unusable as a stream, entirely usable as a one-off. The network becomes a burst channel, which is what Chapter 22.2 §17's non-express window is already for, and the permanent loss in rows two and three of the first table becomes a retention window instead. It costs DRAM at the sensor and a request path, and it is the only arrangement in this section that does not force a choice between bandwidth and evidence.
7. RTL 3 — The Deadline Chain
// ---------------------------------------------------------------------
// sensor_deadline_chain -- the whole reaction, from photons to
// actuator, with the network's contribution isolated.
//
// Chapter 22.2 priced the transport term. This block puts it in the
// company it actually keeps, and the answer is that it is under two
// per cent.
// ---------------------------------------------------------------------
module sensor_deadline_chain
import adas_pkg::*;
#(
parameter int SPEED_M_S = 30
)(
input logic clk,
input logic rst_n,
input logic [15:0] exposure_us,
input logic [15:0] readout_isp_us,
input logic [15:0] encode_us,
input logic [15:0] transport_up_us,
input logic [15:0] decode_us,
input logic [15:0] fusion_us,
input logic [15:0] planning_us,
input logic [15:0] transport_down_us,
input logic [15:0] actuator_us,
input logic [31:0] budget_us,
output logic [31:0] total_us,
output logic [31:0] network_us,
output logic [15:0] network_share_pct_x10,
output logic [31:0] distance_cm,
output logic [31:0] network_distance_cm,
output logic within_budget,
output logic [15:0] largest_term_idx,
output logic [31:0] largest_term_us
);
logic [31:0] terms [9];
always_comb begin
terms[0] = 32'(exposure_us);
terms[1] = 32'(readout_isp_us);
terms[2] = 32'(encode_us);
terms[3] = 32'(transport_up_us);
terms[4] = 32'(decode_us);
terms[5] = 32'(fusion_us);
terms[6] = 32'(planning_us);
terms[7] = 32'(transport_down_us);
terms[8] = 32'(actuator_us);
total_us = '0;
largest_term_us = '0;
largest_term_idx = 16'd0;
for (int i = 0; i < 9; i++) begin
total_us = total_us + terms[i];
if (terms[i] > largest_term_us) begin
largest_term_us = terms[i];
largest_term_idx = 16'(i);
end
end
network_us = terms[3] + terms[7];
network_share_pct_x10 = (total_us == 0) ? 16'd0
: 16'((network_us * 1000) / total_us);
// 30 m/s is 3 cm per ms, so cm = us * 3 / 1000.
distance_cm = (total_us * 32'(SPEED_M_S)) / 10_000;
network_distance_cm = (network_us * 32'(SPEED_M_S)) / 10_000;
within_budget = (total_us <= budget_us);
end
endmoduleClassification: a nine-term sum with two outputs that change how the system is optimised.
What it teaches: that largest_term_idx is index 5 — fusion and perception — at 31.0%, and network_us is 1.7%. A team asked to reduce reaction time will be offered a faster network, because the network is the part with a visible specification and an obvious dial. It is the second-smallest term in the chain, tied with nothing, and halving it saves 2.5 centimetres of a 2.90 metre stopping distance.
And it teaches that distance_cm is the right unit for this conversation. Milliseconds are abstract and a sales argument can be built on any of them; centimetres at the vehicle's speed are what a safety case is written in. Converting every term to distance makes the comparison unarguable: exposure is 30 cm, fusion is 90, the network is 5.
Deliberately simplified: every term is a constant where all of them are distributions with tails, and a deadline is a statement about the tail — Chapter 17.1 §13's argument. SPEED_M_S is the ego vehicle's speed where the quantity that matters is the closing speed, which on a two-way road is double. The chain is a straight line where a real fusion stack waits for several sensors and the deadline is set by the slowest, not the sum of one path. And there is no representation of a frame period, so a stage that only runs once per frame adds up to 33.3 ms of waiting that this model does not include.
Production implication: the missing frame-period quantisation is the biggest single omission and it usually dominates. A fusion stage that runs once per camera frame at 30 fps adds a wait of up to 33.3 milliseconds — more than a third of the entire chain — purely because the data arrived just after the last invocation. That is the same structure as Chapter 22.2 §10's schedule wait, one layer up: the periodic consumer, not the transport, is where the latency is, and the remedy is the same — align the sensor's capture to the consumer's period, which requires the synchronised clock Section 12 is about.
8. The Network Is 1.7% of the Reaction Time
Section 7's chain, run with plausible numbers, and then the conclusion it forces.
| Stage | Time | Share | At 30 m/s |
|---|---|---|---|
| exposure | 10.0 ms | 10.3% | 30 cm |
| readout and ISP | 5.0 ms | 5.2% | 15 cm |
| encode | 10.0 ms | 10.3% | 30 cm |
| transport, sensor to compute | 0.84 ms | 0.9% | 2.5 cm |
| decode | 10.0 ms | 10.3% | 30 cm |
| fusion and perception | 30.0 ms | 31.0% | 90 cm |
| planning | 10.0 ms | 10.3% | 30 cm |
| transport, compute to actuator | 0.84 ms | 0.9% | 2.5 cm |
| actuator response | 20.0 ms | 20.7% | 60 cm |
| total | 96.7 ms | 100% | 2.90 m |
The transport terms come from Chapter 22.2, and it is worth saying which part of them is which.
| Value | |
|---|---|
| three-hop mixed-rate transport with preemption | 35.94 µs |
| worst-case schedule wait, 1 ms cycle, 200 µs window | 800 µs |
| total | 0.84 ms |
| the wait as a fraction of the transport | 22.3× |
So even within the network's 1.7%, the link is 4% and the schedule's wait is 96% — which means a faster PHY changes nothing and a shorter cycle changes everything, and Chapter 22.2 §8 showed a shorter cycle is exactly what preemption buys.
Three conclusions, in increasing order of how much they change a programme.
One — optimising the network for speed is a rounding error. Replacing a 1 Gb/s backbone with 10 Gb/s reduces the transport term from 35.94 µs to roughly 20 µs, saving 16 microseconds of a 96 700 microsecond chain — 0.5 millimetres of stopping distance.
Two — optimising the network for bound is the whole job. An unbounded network turns the 0.84 ms into Chapter 22.2 §6's 8.33 milliseconds of camera burst, which is 25 centimetres and 8.6% of the chain — and a FIFO queue behind a congested uplink can be far worse. The difference between a bounded 0.84 ms and an unbounded queue is the only network decision in the table that matters.
Three — the largest terms are not network terms and they are not obviously reducible. Fusion at 30 ms is compute, exposure at 10 ms is physics, and the actuator's 20 ms is hydraulics and mechanics. A team that has already spent its effort on the network has spent it on 1.7% of the problem, and Section 22's procedure starts by asking where the time actually is.
One honest qualification. The table's terms are typical values, and a deadline is about the tail. Chapter 17.1 §13 made the general argument: latency is a distribution and a bound is a tail, so the interesting comparison is not the means above but the 99.99th percentiles — and the network is the only term in the table with a provable tail, because it is the only one with a scheduling mechanism. Fusion's tail is a software timing argument, the actuator's is a mechanical one, and neither has a guard band.
The network is the smallest contributor and the only one whose worst case can be proved. That is why it gets the scheduling machinery and why the machinery is worth its cost.
9. RTL 4 — The Rolling-Shutter Skew Model
// ---------------------------------------------------------------------
// rolling_shutter_skew -- a frame is not an instant, and nothing in
// the frame says so.
//
// A rolling-shutter imager exposes and reads out one row at a time.
// The last row of an 8 MP frame is acquired up to 20 ms after the
// first. At 30 m/s that is 60 cm of relative motion ACROSS ONE FRAME,
// which is twelve times the entire network's contribution to the
// reaction chain.
//
// The frame carries ONE timestamp. Section 20 is about what that does
// to any property written about it.
// ---------------------------------------------------------------------
module rolling_shutter_skew
import adas_pkg::*;
#(
parameter int ROWS = 2160,
parameter int READOUT_US = ROLLING_READOUT_US, // 20 000
parameter int SPEED_M_S = 30
)(
input logic clk,
input logic rst_n,
input logic frame_start,
input logic [63:0] frame_timestamp_ns,
input logic [15:0] row_index,
input logic row_valid,
output logic [63:0] row_true_time_ns,
output logic [31:0] row_time_error_ns,
output logic [31:0] row_position_error_mm,
output logic [31:0] worst_skew_us,
output logic [31:0] worst_skew_mm,
output logic timestamp_is_a_point_claim,
output logic [31:0] c_rows,
output logic [63:0] frame_mid_time_ns
);
localparam int ROW_PERIOD_NS = (READOUT_US * 1000) / ROWS;
always_comb begin
// The convention almost universally used: the frame's timestamp is
// the start of exposure of the FIRST row.
row_true_time_ns = frame_timestamp_ns
+ 64'(32'(row_index) * ROW_PERIOD_NS);
row_time_error_ns = 32'(row_index) * ROW_PERIOD_NS;
// 30 m/s is 30 mm per ms, so mm = ns * 30 / 1 000 000.
row_position_error_mm = (row_time_error_ns * 32'(SPEED_M_S))
/ 1_000_000;
worst_skew_us = 32'(READOUT_US);
worst_skew_mm = (32'(READOUT_US) * 32'(SPEED_M_S)) / 1000;
// The honest mid-frame reference, which is what a fusion stack
// should be given and almost never is.
frame_mid_time_ns = frame_timestamp_ns + 64'((READOUT_US * 1000) / 2);
// Always true, and it is the point: a single timestamp on a frame
// acquired over an interval is a claim the data cannot support.
timestamp_is_a_point_claim = 1'b1;
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) c_rows <= '0;
else if (row_valid) c_rows <= c_rows + 32'd1;
end
endmoduleClassification: a coordinate transform from row index to true acquisition time, and a permanently asserted warning.
What it teaches: that worst_skew_mm is 600 millimetres and the network's entire contribution is 50. A rolling-shutter 8 MP imager reading out over 20 milliseconds acquires its last row 20 milliseconds after its first, so at 30 m/s the top and bottom of a single frame are separated by 60 centimetres of relative motion — twelve times everything the network does, and it is inside one frame that is stamped with one time.
And it teaches that frame_mid_time_ns is what a fusion stack should receive. If a frame must carry one timestamp, the mid-readout instant is the one that minimises the worst-case error — halving it from 20 ms to 10, or from 60 cm to 30. The universal convention is the start of the first row's exposure, which is the worst available choice, and it is a convention rather than a requirement.
Deliberately simplified: exposure and readout are treated as one interval where a real imager's exposure per row can exceed its row period. ROW_PERIOD_NS is uniform, and a real sensor has blanking. SPEED_M_S is the ego speed rather than the relative speed of the object being measured, which for oncoming traffic is double. And nothing here can be applied by a consumer, because the consumer does not know READOUT_US — it is not in the frame, not in the container, and usually not in the stream's metadata.
Production implication: the missing readout interval is a one-field fix that essentially nobody ships, and it is worth pressing for. A stream that carried its readout duration alongside its timestamp would let a fusion stack compensate per row — the transform is the four lines above — turning a 60 cm systematic error into a residual of a few millimetres. Without it every consumer either ignores the skew, which puts the bottom of the frame 60 cm wrong, or guesses the interval from the sensor's part number. Ask for the field; it is 16 bits and it is the difference between a correctable error and an uncorrectable one.
10. A Frame Is Not an Instant
The single most consequential fact about camera data in a vehicle, and it appears in no field of the data.
Three acquisition models, and only one of them produces an instant.
| Shutter | Acquisition | One timestamp is |
|---|---|---|
| global | every pixel simultaneously | correct |
| rolling | row by row over the readout interval | correct for exactly one row |
| rolling with per-row exposure | each row over its own exposure | correct for no row at all |
Automotive imagers are overwhelmingly rolling, because a global shutter needs storage at every pixel and costs area, sensitivity and money. So row two is the normal case, and the consequences scale with speed.
| Readout interval | Skew at 30 m/s | Skew at 60 m/s closing |
|---|---|---|
| 20 ms | 60 cm | 120 cm |
| 10 ms | 30 cm | 60 cm |
| 5 ms | 15 cm | 30 cm |
A 120-centimetre systematic distortion across one frame is larger than a lane's worth of lateral position error and it is entirely deterministic — it is not noise, it does not average out over frames, and it is in exactly the same direction every time.
Four consequences worth stating separately.
One — the error is structured, not random. Objects at the top of the frame are timestamped too late relative to their true acquisition and objects at the bottom too early, by an amount linear in row index. An averaging filter does not remove it; it preserves it.
Two — it interacts with the fusion join. Section 12 shows fusing two sensors is a join on time. A camera's "time" is an interval and a radar's is a chirp frame, so the join's key is ill-defined on one side — and the error it introduces is up to the full 20 milliseconds, which is 30 centimetres.
Three — it dwarfs everything the network does and everything the schedule guarantees.
| At 30 m/s | |
|---|---|
| the network's entire contribution | 5.0 cm |
| Chapter 22.2's guard band, 5.168 µs | 0.016 cm |
| a rolling-shutter readout | 60.0 cm |
The guard band that Module 17 and Chapter 22.2 spent two chapters computing to nanosecond precision is 0.16 millimetres of position error. The sensor's own acquisition interval is 3 870 times larger. That is not an argument against the scheduling machinery — Chapter 22.2 §8 showed its purpose is bounding rather than precision — but it is a sharp corrective to the instinct that time precision in the network is where the accuracy comes from.
Four — and it is fixable, cheaply, by carrying one more field. Section 9's transform is four lines of arithmetic and needs one 16-bit number: the readout interval. With it, a consumer corrects per row to a residual of a few millimetres. Without it, the correction cannot be made at all, because nothing downstream knows how long the frame took to acquire.
The network's timestamp is accurate to nanoseconds. The thing it is a timestamp of took twenty milliseconds to happen, and nobody wrote that down.
11. RTL 5 — The Fusion Timestamp Join
// ---------------------------------------------------------------------
// fusion_timestamp_join -- two sensors observing the same object, and
// the problem of deciding that they did.
//
// This is Chapter 20.6 Section 4's join and Chapter 21.9 Section 5's
// two-point comparator for the third time, with a different key. There
// the key was a content digest; here it is TIME, and time is exactly
// the quantity Chapter 22.2 Section 12 showed a vehicle can lose.
// ---------------------------------------------------------------------
module fusion_timestamp_join
import adas_pkg::*;
#(
parameter int TOLERANCE_US = 1000, // how close is "the same moment"
parameter int SPEED_M_S = 30
)(
input logic clk,
input logic rst_n,
input logic a_valid, // e.g. a camera frame
input logic [63:0] a_time_ns,
input logic [31:0] a_acquire_span_ns, // 0 for a point sensor
input logic [15:0] a_object_x_cm,
input logic b_valid, // e.g. a radar frame
input logic [63:0] b_time_ns,
input logic [31:0] b_acquire_span_ns,
input logic [15:0] b_object_x_cm,
input logic clock_synchronised,
input logic [31:0] holdover_ns,
output logic paired,
output logic [31:0] time_gap_ns,
output logic [31:0] position_error_mm,
output logic [31:0] span_error_mm,
output logic span_dominates,
output logic join_unsafe,
output logic [31:0] c_paired,
output logic [31:0] c_rejected_time,
output logic [31:0] c_unsafe
);
logic [63:0] gap;
always_comb begin
gap = (a_time_ns > b_time_ns) ? (a_time_ns - b_time_ns)
: (b_time_ns - a_time_ns);
time_gap_ns = 32'(gap);
paired = a_valid && b_valid &&
(time_gap_ns <= (TOLERANCE_US * 1000));
// 30 m/s is 30 mm per ms, i.e. 30 mm per 1e6 ns.
position_error_mm = (time_gap_ns * 32'(SPEED_M_S)) / 1_000_000;
// The error from the ACQUISITION SPAN, which no timestamp records
// and which Section 10 showed is 60 cm for a rolling shutter.
span_error_mm = ((a_acquire_span_ns + b_acquire_span_ns)
* 32'(SPEED_M_S)) / 1_000_000;
span_dominates = (span_error_mm > position_error_mm);
// A join on time, performed by two nodes whose clocks may have
// diverged, is a join on a key neither of them can trust.
// Chapter 22.2 Section 12: 200 ppm eats a millisecond in 5 seconds.
join_unsafe = !clock_synchronised &&
(((holdover_ns / 1_000_000) * 200) >
(TOLERANCE_US * 1000));
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
c_paired <= '0; c_rejected_time <= '0; c_unsafe <= '0;
end else begin
if (paired) c_paired <= c_paired + 32'd1;
if (a_valid && b_valid && !paired) c_rejected_time <= c_rejected_time + 32'd1;
if (paired && join_unsafe) c_unsafe <= c_unsafe + 32'd1;
end
end
endmoduleClassification: a join on time, with two error terms and a verdict on whether the key can be trusted.
What it teaches: that span_dominates is almost always true and that is the finding. A one-millisecond timestamp gap contributes 30 millimetres of position error; a rolling shutter's 20-millisecond acquisition span contributes 600. So a fusion stack that tightens its time tolerance from 1 ms to 100 µs has reduced a 30 mm term to 3 and left a 600 mm term untouched — the optimisation is real, correct, and worth 4.3% of the total error.
And it teaches that join_unsafe is the third appearance of the same structure. Chapter 20.6 §4 joined on a content digest because no identifier existed; Chapter 21.9 §5 joined two capture points on the same digest and had to publish an ambiguity rate; here the key is time, and Chapter 22.2 §12 showed a node can lose the ability to know it. At 200 ppm a 1 ms tolerance is consumed in 5 seconds of holdover — after which the join pairs observations that are not of the same moment and says nothing.
Deliberately simplified: a single object per sensor per frame, where a real join is over sets of detections and needs a spatial as well as a temporal key. TOLERANCE_US is fixed where it should scale with the vehicle's speed — a tolerance that is right at 10 m/s is six times too loose at 60. The acquisition spans are inputs that Section 9 showed are not carried in the data. And position_error_mm uses the ego speed rather than the object's relative speed.
Production implication: the fixed tolerance is the one to make speed-dependent, and the reasoning is a single line of arithmetic. A fusion stack's time tolerance should be chosen so that the resulting position error stays inside the perception stack's spatial resolution — if a tracker's cell is 10 centimetres, the tolerance at 30 m/s is 3.3 milliseconds and at 60 m/s closing is 1.7. Fixing it at one value means the system is too strict at low speed, rejecting valid pairs and losing tracks, and too loose at high speed, pairing observations that are 20 centimetres apart. Scale it, and publish c_rejected_time so that an over-strict tolerance is visible as lost pairings rather than as mysteriously poor tracking.
12. Fusing Two Sensors Is a Join on Time
Three sensors, three different notions of when, and a fusion stack that has to reconcile them.
| Sensor | What "now" means | Span |
|---|---|---|
| global-shutter camera | one instant | the exposure, ≈ 10 ms |
| rolling-shutter camera | an interval, row by row | the readout, ≈ 20 ms |
| radar | a chirp frame | the frame, ≈ 50 ms at 20 Hz |
| lidar | a rotation, point by point | the rotation, ≈ 50 ms at 20 Hz |
Not one of the four is an instant, and three of the four have spans measured in tens of milliseconds — which at 30 m/s is tens of centimetres. A lidar's rotation is the extreme case: a point acquired at the start of a rotation and one at the end are 50 milliseconds and 1.5 metres apart, within a single "frame" that carries one timestamp.
So the join has three error terms and they are wildly unequal.
| Term | Magnitude at 30 m/s | Controlled by |
|---|---|---|
| network timestamp accuracy | < 0.1 mm | Chapter 16.3's hardware timestamping |
| clock synchronisation error | ≈ 0.1 to 3 mm | Chapter 16.4's servo |
| timestamp gap between sensors, 1 ms tolerance | 30 mm | the fusion stack's tolerance |
| acquisition span, rolling shutter | 600 mm | the sensor, and nobody reports it |
| acquisition span, lidar rotation | 1 500 mm | the sensor, and nobody reports it |
Rows one and two are the ones the network controls and they are four orders of magnitude below the ones it does not. That is the chapter's second corrective to a natural instinct: PTP's precision is not the limit on fusion accuracy and has never been close to it.
What PTP is actually for here is different and is worth naming precisely.
Synchronisation does not make the timestamps precise enough. It makes them comparable at all.
A vehicle's sensors sit on different ECUs with different oscillators. Without a common time base, two timestamps are two numbers from two unrelated counters and their difference is meaningless — Chapter 21.9 §6 made exactly this argument about two capture points. With PTP their difference is a real interval, accurate to well under a millisecond, and then the sensor's own acquisition span becomes the limit. The progression is: incomparable, then comparable, then limited by physics.
And Chapter 22.2 §12's failure lands here with full force.
| Holdover at 200 ppm | Timestamp divergence | Position error at 30 m/s |
|---|---|---|
| 25.8 ms | 5.2 µs | 0.16 mm |
| 1 s | 200 µs | 6 mm |
| 5 s | 1 ms | 30 mm |
| 60 s | 12 ms | 360 mm |
| 10 min | 120 ms | 3 600 mm |
Row three is where the join's 1 ms tolerance is consumed entirely — after five seconds of holdover the two sensors' timestamps differ by the whole tolerance, and every pairing is at the edge of rejection or wrongly accepted. Row five is a vehicle that has been running without synchronisation for ten minutes: objects are fused 3.6 metres out of position, which is a lane and a half.
The remedy is the one Chapter 22.2 §13 built: a holdover counter, a severity ladder, and a withdrawal of the fusion claim when the divergence exceeds the join's tolerance. join_unsafe in Section 11 is that verdict, and it costs one comparison — against a failure that puts tracked objects in the wrong lane with no other symptom.
13. RTL 6 — The Compression Budget
// ---------------------------------------------------------------------
// compression_budget -- the ratio is a policy, not a fact, and its
// variance is what breaks link budgets.
//
// Section 3's COMPRESS_RATIO of 30 is an average over benign scenes. A
// rainy motorway with spray and moving foliage compresses at 10:1 or
// worse -- and that is exactly the scene in which the sensor matters
// most, so the peak rate and the worst case coincide.
// ---------------------------------------------------------------------
module compression_budget
import adas_pkg::*;
#(
parameter int TARGET_RATIO = COMPRESS_RATIO, // 30
parameter int WORST_RATIO = 10,
parameter int RAW_KBPS = 2986000 // one 8 MP camera
)(
input logic clk,
input logic rst_n,
input logic frame_done,
input logic [31:0] frame_bits_emitted,
input logic [31:0] frame_bits_raw,
input logic [31:0] link_budget_kbps,
input logic rate_cap_enabled,
output logic [31:0] target_kbps,
output logic [31:0] worst_case_kbps,
output logic [31:0] instantaneous_kbps,
output logic [15:0] achieved_ratio,
output logic over_budget,
output logic would_overrun_link,
output logic quality_reduced,
output logic [31:0] c_frames,
output logic [31:0] c_over_budget_frames,
output logic [15:0] worst_ratio_seen
);
always_comb begin
target_kbps = 32'(RAW_KBPS / TARGET_RATIO);
worst_case_kbps = 32'(RAW_KBPS / WORST_RATIO);
instantaneous_kbps = (frame_bits_emitted * CAM_FPS) / 1000;
achieved_ratio = (frame_bits_emitted == 0) ? 16'hFFFF
: 16'(frame_bits_raw / frame_bits_emitted);
over_budget = (instantaneous_kbps > target_kbps);
would_overrun_link = (instantaneous_kbps > link_budget_kbps);
// Without a hard cap, the encoder emits what the scene demands and
// the LINK takes the consequence -- which in a scheduled network
// means the non-express window, and everything sharing it.
quality_reduced = rate_cap_enabled && over_budget;
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
c_frames <= '0; c_over_budget_frames <= '0;
worst_ratio_seen <= 16'hFFFF;
end else if (frame_done) begin
c_frames <= c_frames + 32'd1;
if (over_budget) c_over_budget_frames <= c_over_budget_frames + 32'd1;
if (achieved_ratio < worst_ratio_seen)
worst_ratio_seen <= achieved_ratio;
end
end
endmoduleClassification: a rate monitor whose interesting outputs are a worst case and a policy switch.
What it teaches: that rate_cap_enabled chooses which thing degrades and there is no third option. With the cap, a difficult scene produces worse image quality at a bounded rate; without it, it produces good image quality at an unbounded rate, and the excess lands on the link. In a scheduled network the excess takes the non-express window, which is shared with radar, lidar, diagnostics and everything else — so one camera's rainy motorway degrades every other sensor's stream.
And it teaches that worst_ratio_seen is a fleet field rather than a debug one. A design validated at 30:1 and running at 10:1 in rain is not broken; it is operating at a point nobody measured. The minimum ratio observed over a vehicle's life, binned by conditions, is what tells a programme whether its link budget was honest — and it costs 16 flops.
Deliberately simplified: instantaneous_kbps extrapolates one frame to a full second, which is the right conservative reading and is noisy. WORST_RATIO is a parameter where the true worst case is a property of the encoder, the scene and the sensor together, and is not knowable at elaboration. quality_reduced is a flag rather than a measure — how much quality was given up is the interesting quantity and needs a distortion metric the block does not have. And there is no notion of a group-of-pictures structure, so the large intra-coded frames that arrive periodically — often five to ten times an inter-coded frame — are not modelled at all.
Production implication: the missing group-of-pictures structure is the one that produces the actual link overruns, and it is periodic rather than random. An intra-coded frame every second, five to ten times the size of the frames around it, is a deterministic burst — it lands at a fixed period, and if that period is a harmonic of the schedule's cycle it lands in the same window every time. Chapter 22.2 §6's alignment argument, arriving in an encoder: two periodic processes with a common origin stay in phase. The remedy is to stagger the intra-frame phase across cameras, which is a one-line configuration and turns twelve simultaneous bursts into twelve spread ones.
14. What Compressing a Safety Sensor Costs
Compression is the single decision that turns 19.97 Gb/s into 976.7 Mb/s. This section prices what it takes in exchange.
Four costs, and only the first is usually discussed.
| Cost | Magnitude |
|---|---|
| latency — encode plus decode | 20 ms of a 96.7 ms chain — 20.7% |
| rate variance | 30:1 to 10:1, a factor of 3 at the worst moment |
| artefacts, in the spatial domain | blocking, ringing, and lost fine detail |
| a second authority on what was there | the encoder's rate-distortion decisions |
Row one is measurable and large. Section 8's chain gives 10 ms to encode and 10 to decode, together 20.7% of the whole reaction — 60 centimetres of stopping distance at 30 m/s, which is twelve times the network's entire contribution. Compression is the second-largest latency term in the vehicle after fusion, and it exists purely to make the network affordable.
So there is a real trade and it is quantifiable.
| Configuration | Link needed | Latency cost | Distance at 30 m/s |
|---|---|---|---|
| raw | 24.96 Gb/s | 0 ms | 0 cm |
| compressed at 30:1 | 1.22 Gb/s | 20 ms | 60 cm |
Twenty times less link for sixty centimetres of stopping distance, and which side of that trade is right depends on the vehicle. A development vehicle recording ground truth takes the first row; a production vehicle takes the second — and the chapter's point is that the trade should be made with those two numbers in front of the people making it.
Row two of the cost table is the one that breaks things in the field, and Section 13 has it: a 30:1 encoder delivers 10:1 on rain, spray and moving foliage, tripling the rate in exactly the conditions where the sensor matters most. A link sized for the average overruns when it matters, and in a scheduled network the overrun spills into a shared window.
Row four is the subtle one and it is the same structure as Section 6's radar threshold.
A lossy encoder makes rate-distortion decisions about what to keep. Those decisions were tuned against a corpus, by a supplier, for perceptual quality — and the consumer is a perception algorithm, not a person.
An encoder discards what a human would not notice. A neural network's features are not what a human notices — fine texture, high-frequency edges and small low-contrast objects are exactly what a perceptual encoder spends least on, and exactly what a distant-pedestrian detector depends on. The encoder is therefore a second authority on what was in the scene, tuned for a different consumer, and its decisions are invisible downstream. Chapter 21.2 §3's two-authority problem, for the second time in this chapter.
Which gives the practical rules.
| Rule | Why |
|---|---|
| size the link against the worst-case ratio, not the average | 10:1, not 30:1 — a factor of 3 |
| enable a hard rate cap | degrade quality, not the shared window |
| stagger intra-frame phase across cameras | twelve aligned bursts become twelve spread ones |
record worst_ratio_seen over the fleet | it tells you whether the budget was honest |
| keep the forward camera raw if the budget allows | 60 cm of latency and the encoder's authority, both removed |
Row five is the decision most production vehicles revisit, and Section 4's ladder is what it costs: keeping four forward cameras raw takes the suite from 976.7 Mb/s to 12.52 Gb/s and moves the backbone from 1 Gb/s to 10. That is a large cost for one row of the table, and it is the single most consequential architectural question in the chapter.
15. RTL 7 — ADAS Telemetry
// ---------------------------------------------------------------------
// adas_telemetry -- what a sensor path knows about itself, and the
// three fields that are worth more than the rest put together.
//
// Those three are: the achieved compression ratio, the acquisition
// span, and whether the fusion clock was trustworthy. None of them is
// in a normal sensor stream and all three are needed to interpret
// anything else.
// ---------------------------------------------------------------------
module adas_telemetry
import adas_pkg::*;
(
input logic clk,
input logic rst_n,
input logic snapshot,
input logic [31:0] i_frames,
input logic [31:0] i_over_budget_frames,
input logic [15:0] i_worst_ratio_seen,
input logic [31:0] i_instantaneous_kbps,
input logic [31:0] i_acquire_span_ns,
input logic [31:0] i_paired,
input logic [31:0] i_rejected_time,
input logic [31:0] i_unsafe_joins,
input logic [31:0] i_overflow_frames,
input logic [31:0] i_subthreshold_discarded,
input logic i_clock_synchronised,
input logic [31:0] i_holdover_ns,
input logic i_raw_recoverable,
output logic [31:0] o_frames,
output logic [15:0] o_over_budget_ppm,
output logic [15:0] o_worst_ratio_seen,
output logic [31:0] o_instantaneous_kbps,
output logic [31:0] o_acquire_span_ns,
output logic [15:0] o_pair_yield_pct,
output logic [15:0] o_unsafe_join_ppm,
output logic [15:0] o_overflow_ppm,
output logic [31:0] o_subthreshold_discarded,
output logic [3:0] o_caveats,
output logic o_fusion_result_interpretable
);
localparam int C_CLOCK = 0; // the join's key was not trustworthy
localparam int C_SPAN = 1; // acquisition span not reported
localparam int C_RATIO = 2; // compression fell below target
localparam int C_OVERFLOW = 3; // an object list was truncated
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
o_frames <= '0; o_over_budget_ppm <= '0;
o_worst_ratio_seen <= 16'hFFFF; o_instantaneous_kbps <= '0;
o_acquire_span_ns <= '0; o_pair_yield_pct <= '0;
o_unsafe_join_ppm <= '0; o_overflow_ppm <= '0;
o_subthreshold_discarded <= '0; o_caveats <= '0;
end else if (snapshot) begin
o_frames <= i_frames;
o_worst_ratio_seen <= i_worst_ratio_seen;
o_instantaneous_kbps <= i_instantaneous_kbps;
o_acquire_span_ns <= i_acquire_span_ns;
o_subthreshold_discarded <= i_subthreshold_discarded;
if (i_frames != 0) begin
o_over_budget_ppm <= 16'((i_over_budget_frames * 1_000_000)
/ i_frames);
o_overflow_ppm <= 16'((i_overflow_frames * 1_000_000)
/ i_frames);
end
if ((i_paired + i_rejected_time) != 0)
o_pair_yield_pct <= 16'((i_paired * 100)
/ (i_paired + i_rejected_time));
if (i_paired != 0)
o_unsafe_join_ppm <= 16'((i_unsafe_joins * 1_000_000) / i_paired);
o_caveats[C_CLOCK] <= !i_clock_synchronised;
o_caveats[C_SPAN] <= (i_acquire_span_ns == 32'd0);
o_caveats[C_RATIO] <= (i_worst_ratio_seen < 16'(COMPRESS_RATIO));
o_caveats[C_OVERFLOW] <= (i_overflow_frames != 32'd0);
end
end
assign o_fusion_result_interpretable = !o_caveats[C_CLOCK] &&
!o_caveats[C_SPAN];
endmoduleClassification: a snapshot bank with four caveat bits, two of which disqualify rather than qualify.
What it teaches: that o_caveats[C_SPAN] fires when the acquisition span is zero, and zero is what an unreported span looks like. A sensor that does not carry its readout interval presents as an instantaneous sensor, which Section 10 showed is wrong by up to 60 centimetres for a rolling shutter and 1.5 metres for a lidar rotation. The caveat does not detect a fault; it detects an absence, and an absence that every consumer will otherwise silently interpret as an instant.
And it teaches that o_pair_yield_pct is the fusion stack's own health in one number. A tolerance that is too strict rejects valid pairings and loses tracks without any error being reported; a tolerance that is too loose pairs observations 20 centimetres apart and degrades tracking without any error being reported. The yield distinguishes them: a falling yield is too strict, a stable yield with worsening track quality is too loose.
Deliberately simplified: no read-clear, so a fifteen-year vehicle needs external differencing. o_unsafe_join_ppm is normalised over pairings where the honest denominator is attempted pairings. o_caveats[C_RATIO] fires on any excursion below the target, which on a rainy drive is every frame — the useful form is a duration, not a flag. And there is no sticky maximum severity, which Chapter 22.2 §15 argued for and this block should have copied.
Production implication: o_subthreshold_discarded is the field with the strongest case for existing and the weakest chance of being supplied, and it is worth pressing a sensor vendor for. In object mode a radar reports what it decided was there and reports nothing about what it decided was not — Section 5. A count of detections that fell below the reporting threshold, per frame, is one 16-bit field, and it converts the radar saw nothing from an assertion into a measurement. Without it there is no way, ever, to distinguish an empty scene from a threshold set too high, and that distinction is the difference between a validated sensor and a trusted one.
16. RTL 8 — The ADAS Conformance Monitor
// ---------------------------------------------------------------------
// adas_conformance_monitor -- properties for a sensor path.
//
// Property 1 is the one worth arguing over: it forbids a frame from
// being treated as an instant unless its acquisition span is actually
// zero. Everything else is bookkeeping.
// ---------------------------------------------------------------------
module adas_conformance_monitor
import adas_pkg::*;
(
input logic clk,
input logic rst_n,
input logic frame_valid,
input logic [31:0] acquire_span_ns,
input logic treated_as_instant,
input logic [63:0] frame_timestamp_ns,
input logic [63:0] prev_frame_timestamp_ns,
input logic [31:0] emitted_bits,
input logic [31:0] raw_bits,
input logic [15:0] achieved_ratio,
input logic over_budget,
input logic rate_cap_enabled,
input logic object_list_overflowed,
input logic [15:0] objects_dropped,
input logic paired,
input logic [31:0] time_gap_ns,
input logic join_unsafe,
input logic clock_synchronised,
input logic fusion_result_interpretable,
input logic raw_recoverable,
input reduction_e policy
);
// 1. A frame is treated as an instant only if it WAS one.
p_adas_not_an_instant: assert property (@(posedge clk) disable iff (!rst_n)
treated_as_instant |-> (acquire_span_ns == 32'd0));
// 2. Timestamps are monotone within a stream.
p_adas_time_monotone: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (frame_timestamp_ns > prev_frame_timestamp_ns));
// 3. Emitted never exceeds raw.
p_adas_emit_bounded: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (emitted_bits <= raw_bits));
// 4. Raw policy emits exactly the raw bits.
p_adas_raw_exact: assert property (@(posedge clk) disable iff (!rst_n)
(frame_valid && (policy == RED_NONE)) |-> (emitted_bits == raw_bits));
// 5. Only the raw policy leaves the data recoverable.
p_adas_recoverable: assert property (@(posedge clk) disable iff (!rst_n)
raw_recoverable == (policy == RED_NONE));
// 6. With a rate cap, an over-budget frame must have been degraded.
p_adas_cap_acts: assert property (@(posedge clk) disable iff (!rst_n)
(rate_cap_enabled && over_budget) |=> !over_budget);
// 7. An overflowed object list reports how many were dropped.
p_adas_overflow_counted: assert property (@(posedge clk) disable iff (!rst_n)
object_list_overflowed |-> (objects_dropped != 16'd0));
// 8. A pairing is within the tolerance.
p_adas_pair_tolerance: assert property (@(posedge clk) disable iff (!rst_n)
paired |-> (time_gap_ns <= (TOLERANCE_US * 1000)));
// 9. An unsafe join is never counted as a clean pairing.
p_adas_unsafe_flagged: assert property (@(posedge clk) disable iff (!rst_n)
(paired && !clock_synchronised) |-> join_unsafe ||
(time_gap_ns < 32'd1000));
// 10. A fusion result is interpretable only with a trusted clock.
p_adas_fusion_gated: assert property (@(posedge clk) disable iff (!rst_n)
fusion_result_interpretable |-> clock_synchronised);
// 11. And only with a reported acquisition span.
p_adas_span_required: assert property (@(posedge clk) disable iff (!rst_n)
fusion_result_interpretable |-> (acquire_span_ns != 32'd0) ||
treated_as_instant);
// 12. Achieved ratio is consistent with the bits.
p_adas_ratio_consistent: assert property (@(posedge clk) disable iff (!rst_n)
(frame_valid && (emitted_bits != 0)) |->
(achieved_ratio == 16'(raw_bits / emitted_bits)));
endmoduleClassification: twelve properties, and the first one is unenforceable against most real sensors.
What it teaches: that property 1 fails immediately on a rolling-shutter camera that does not report its readout interval, because acquire_span_ns is zero and treated_as_instant is what every consumer does. That is the correct behaviour for the property — the system is doing something unsound — and it is why the property gets deleted from real testbenches rather than fixed. Section 20's rejected class is about the shape of the thing that gets written instead.
And it teaches that properties 10 and 11 gate a conclusion rather than a behaviour. Nothing in the sensor path misbehaves when the clock is in holdover or the span is unreported; what goes wrong is that a fusion result is produced and believed. Chapter 21.9 §20's structure exactly: the useful property constrains the claim, not the mechanism.
Deliberately simplified: property 6 asserts the cap acts within one cycle, where a real encoder responds over a frame or more. Property 8 uses TOLERANCE_US from a parameter the monitor does not declare, which is a binding the surrounding environment must supply. Property 9's escape clause — a gap under one microsecond — is arbitrary. And property 2 forbids equal timestamps, which a sensor with coarse timestamp resolution will violate legitimately.
Production implication: property 11's shape is the one worth exporting to other domains. It says a conclusion may be drawn only if a specific input field is present, which is unusual — most properties constrain values rather than presence. In a sensor path, absence is the commonest defect: no readout interval, no sub-threshold count, no encoder ratio, no timestamp-source identifier. Writing presence requirements as assertions puts them in front of an integrator at the point where they can still be asked for, which is the only time a vendor will add a field. After the sensor is selected, the absence is permanent.
17. What the Link Rate Has to Be
Four architectures, and the link rate is decided entirely by Section 6's reduction choice.
| Architecture | Suite | Zone uplink at 80% | Backbone at 80% |
|---|---|---|---|
| all reduced | 976.7 Mb/s | ≈ 305 Mb/s per zone | 1.22 Gb/s |
| forward cameras raw | 12.52 Gb/s | ≈ 3.9 Gb/s | 15.65 Gb/s |
| radar raw too | 14.20 Gb/s | ≈ 4.4 Gb/s | 17.75 Gb/s |
| everything raw | 19.97 Gb/s | ≈ 6.2 Gb/s | 24.96 Gb/s |
Row one's zone uplink figure assumes the nineteen sensors are spread evenly over four zones, which they are not — the forward-facing sensors cluster — but it establishes the order of magnitude: a fully reduced suite needs a 1 Gb/s uplink per zone and a 2.5 Gb/s backbone.
And the available automotive PHYs.
| PHY | Rate | Fits row 1? | Row 2? | Row 4? |
|---|---|---|---|---|
| 100BASE-T1 | 100 Mb/s | no | no | no |
| 1000BASE-T1 | 1 Gb/s | uplinks yes, backbone no | no | no |
| 2.5GBASE-T1 | 2.5 Gb/s | yes | no | no |
| 10GBASE-T1 | 10 Gb/s | yes | uplinks yes, backbone no | no |
| 25 Gb/s optical | 25 Gb/s | yes | yes | just |
Row two's second column is the awkward result of Section 4 and it is worth restating: the commonest suite configuration does not fit the commonest automotive backbone PHY with sensible headroom. 976.7 Mb/s at an 80% cap needs 1.22 Gb/s and 1000BASE-T1 delivers 1. The three responses were compression to 40:1, splitting across uplinks, or a 2.5 Gb/s backbone — and splitting is what the zone architecture already does, which is a large part of why it exists.
Then Chapter 22.2's schedule takes a share and it is not small.
| Of the link | |
|---|---|
| express window, 1 ms cycle, 20%, with preemption | 19.48% reserved |
| remaining for sensor traffic | 80.52% |
| the 80% utilisation cap already assumed | overlaps this |
The two budgets are not independent and it is easy to double-count or to miss the interaction entirely. A link carrying a 19.48% express reservation has 80.52% for everything else, of which the sensor suite should occupy no more than about 80% — so the honest sensor budget on a 1 Gb/s link is roughly 644 Mb/s, not 800. The fully reduced suite at 976.7 Mb/s does not fit on one such link and never did.
Which gives the sizing rule this chapter recommends.
link rate ≥ suite rate ÷ (1 − express reservation) ÷ utilisation cap
| Suite | Express reservation | Cap | Link required |
|---|---|---|---|
| 976.7 Mb/s | 19.48% | 80% | 1.52 Gb/s |
| 976.7 Mb/s | 19.48% | 90% | 1.35 Gb/s |
| 600 Mb/s, fully reduced | 19.48% | 80% | 0.93 Gb/s |
| 12.52 Gb/s | 19.48% | 80% | 19.44 Gb/s |
Row three is the only one that fits 1000BASE-T1, and it needs the suite reduced further than Section 2's figures — fewer cameras, lower frame rates, or a higher compression ratio. Row one, which is the realistic modern suite, needs 2.5 Gb/s. That is the chapter's headline architectural conclusion and it is a straightforward division.
18. What the Sensor Path Assumes
Seven premises. Two of them are about fields that do not exist.
| Assumption | If it is false |
|---|---|
| a frame's timestamp describes the whole frame | Section 10 — 60 cm for a rolling shutter, 150 for a lidar rotation |
| the compression ratio is the configured one | Section 13 — 10:1 in rain, a factor of 3 over budget |
| the sensors' clocks are comparable | Section 12 — 30 mm of position error after 5 s of holdover |
| an object list is complete | Section 5 — truncation at 200, and no sub-threshold record |
| "the radar saw nothing" is an observation | it is an assertion by a supplier's threshold |
| the encoder kept what the perception stack needs | Section 14 — it kept what a human would notice |
| the link has 80% of its rate available | Section 17 — the express reservation takes 19.48% first |
Rows one and four are the two that are about missing fields, and both have the same remedy and the same obstacle. The remedy is one 16-bit field each — an acquisition span and a sub-threshold count. The obstacle is that the sensor is selected before the network is designed, so by the time anyone needs the field the part is chosen, qualified and in a contract.
Row five deserves its own statement because it is the one that gets believed.
A radar in object mode does not report an empty scene. It reports that its detector, with its threshold, on its firmware version, emitted no objects. Those are not the same claim and nothing in the data distinguishes them.
Row six is the same shape, one sensor over. A lossy encoder tuned for perceptual quality spends its bits where a human looks, and a distant low-contrast pedestrian is where a human does not. The encoder and the perception stack are two authorities on what was in the scene — Chapter 21.2 §3's problem for the third time in three chapters — and the encoder's decisions are made first, by a supplier, against a corpus nobody in the vehicle programme chose.
Row seven is an arithmetic trap rather than a conceptual one and it is easy to fall into. A network engineer sizes the link at 80% utilisation; a TSN engineer reserves 19.48% for the express window. Neither is wrong and the two budgets multiply rather than add, so the actual sensor allowance is 0.8 × 0.8052 = 64.4% of the link. On a 1 Gb/s link that is 644 Mb/s, and the suite is 976.7.
19. The Cost, Accounted
Priced against Chapter 19.7 §19's 14 166-flop MAC receive datapath, for the fourth chapter running.
| Block | Flops | Share of 14 166 |
|---|---|---|
sensor_volume_model | 0 — combinational | — |
raw_vs_object_selector | 96 | 0.7% |
sensor_deadline_chain | 0 — combinational | — |
rolling_shutter_skew | 32 | 0.2% |
fusion_timestamp_join | 96 | 0.7% |
compression_budget | 80 | 0.6% |
adas_telemetry | 212 | 1.5% |
adas_conformance_monitor | 0 — assertions | — |
| total | 516 | 3.6% |
Three point six per cent, and the interesting observation is what it does not include.
| Not priced here | Because |
|---|---|
| the video encoder | it is a large fixed-function block or a DSP, not flops |
| the fusion stack | it is software on a compute cluster |
| the sensor's own detector | supplier firmware |
| the network | Chapter 22.2 §19's 584 flops plus Module 17's mechanisms |
Row one is the chapter's largest single piece of silicon and it does not appear in the table at all. A real-time 8 MP H.265 encoder is millions of gates, and pricing it in flip-flops against a MAC datapath would be meaningless — the same boundary Chapter 21.9 §19 hit with a capture buffer and Chapter 22.1 §19 hit with a delay line. The unit has now failed three times in four chapters, always at the same place: when a mechanism's size is set by the data rather than by the design.
The comparison that is worth making instead is in time and distance.
| Time | At 30 m/s | |
|---|---|---|
| the whole network, both directions | 1.68 ms | 5.0 cm |
| encode plus decode | 20.0 ms | 60.0 cm |
| fusion and perception | 30.0 ms | 90.0 cm |
| a rolling-shutter readout | 20.0 ms | 60.0 cm |
| the entire chain | 96.7 ms | 2.90 m |
Rows two and four are both 60 centimetres and both exist to make something else affordable — the encoder to make the network affordable, the rolling shutter to make the imager affordable. Together they are 41% of the reaction chain, against the network's 1.7%.
Two cost-reduction decisions made outside the network account for twenty-four times the network's entire latency contribution, and neither of them is usually in a latency budget at all.
20. Properties Worth Asserting, and One Worth Refusing
Six groups. The refused property is the one that every fusion stack contains and that no sensor's data can support.
Group A — volume and reduction.
// A1. Emitted never exceeds raw.
p_ad_emit_bounded: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (emitted_bits <= raw_bits));
// A2. The raw policy emits exactly the raw bits.
p_ad_raw_exact: assert property (@(posedge clk) disable iff (!rst_n)
(frame_valid && (policy == RED_NONE)) |-> (emitted_bits == raw_bits));
// A3. Only the raw policy leaves the data recoverable.
p_ad_recoverable: assert property (@(posedge clk) disable iff (!rst_n)
raw_recoverable == (policy == RED_NONE));
// A4. An object list never exceeds its capacity.
p_ad_obj_capacity: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (emitted_objects <= OBJ_CAPACITY));
// A5. Truncation is counted, never silent.
p_ad_truncation_counted: assert property (@(posedge clk) disable iff (!rst_n)
object_list_overflowed |-> (objects_dropped != 16'd0));
// A6. The suite's total is the sum of its parts.
p_ad_suite_sum: assert property (@(posedge clk) disable iff (!rst_n)
suite_kbps == (cam_kbps_total + radar_kbps_total + lidar_kbps_total));Group B — the compression budget.
// B1. The achieved ratio is consistent with the bits.
p_cb_ratio: assert property (@(posedge clk) disable iff (!rst_n)
(frame_done && (frame_bits_emitted != 0)) |->
(achieved_ratio == 16'(frame_bits_raw / frame_bits_emitted)));
// B2. With a cap, an over-budget frame is followed by a compliant one.
p_cb_cap_acts: assert property (@(posedge clk) disable iff (!rst_n)
(rate_cap_enabled && over_budget) |=> !over_budget);
// B3. The worst ratio seen is monotone downward.
p_cb_worst_monotone: assert property (@(posedge clk) disable iff (!rst_n)
worst_ratio_seen <= $past(worst_ratio_seen));
// B4. Overrunning the link is reported, not absorbed.
p_cb_overrun_flagged: assert property (@(posedge clk) disable iff (!rst_n)
(instantaneous_kbps > link_budget_kbps) |-> would_overrun_link);
// B5. Over-budget frames are counted.
p_cb_counted: assert property (@(posedge clk) disable iff (!rst_n)
(frame_done && over_budget) |=>
(c_over_budget_frames == $past(c_over_budget_frames) + 1));Group C — time and the acquisition span.
// C1. Timestamps are monotone within a stream.
p_ts_monotone: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (frame_timestamp_ns > prev_frame_timestamp_ns));
// C2. A row's true time is the frame time plus its row offset.
p_ts_row_time: assert property (@(posedge clk) disable iff (!rst_n)
row_valid |-> (row_true_time_ns ==
frame_timestamp_ns + (row_index * ROW_PERIOD_NS)));
// C3. The row offset never exceeds the readout interval.
p_ts_row_bounded: assert property (@(posedge clk) disable iff (!rst_n)
row_valid |-> (row_time_error_ns <= (READOUT_US * 1000)));
// C4. The mid-frame reference is the midpoint of the readout.
p_ts_mid: assert property (@(posedge clk) disable iff (!rst_n)
frame_valid |-> (frame_mid_time_ns ==
frame_timestamp_ns + ((READOUT_US * 1000) / 2)));
// C5. A frame is treated as an instant only if its span is zero.
p_ts_not_instant: assert property (@(posedge clk) disable iff (!rst_n)
treated_as_instant |-> (acquire_span_ns == 32'd0));
// C6. The worst skew is the readout interval, always.
p_ts_worst_skew: assert property (@(posedge clk) disable iff (!rst_n)
worst_skew_us == READOUT_US);Group D — the fusion join.
// D1. A pairing is inside the tolerance.
p_fj_tolerance: assert property (@(posedge clk) disable iff (!rst_n)
paired |-> (time_gap_ns <= (TOLERANCE_US * 1000)));
// D2. Pairing requires both inputs.
p_fj_both: assert property (@(posedge clk) disable iff (!rst_n)
paired |-> (a_valid && b_valid));
// D3. The position error follows from the gap and the speed.
p_fj_position: assert property (@(posedge clk) disable iff (!rst_n)
position_error_mm == ((time_gap_ns * SPEED_M_S) / 1_000_000));
// D4. The span error is computed from both sensors' spans.
p_fj_span: assert property (@(posedge clk) disable iff (!rst_n)
span_error_mm == (((a_acquire_span_ns + b_acquire_span_ns)
* SPEED_M_S) / 1_000_000));
// D5. An unsynchronised clock past the tolerance makes the join unsafe.
p_fj_unsafe: assert property (@(posedge clk) disable iff (!rst_n)
(!clock_synchronised &&
(((holdover_ns / 1_000_000) * 200) > (TOLERANCE_US * 1000)))
|-> join_unsafe);
// D6. Unsafe pairings are counted separately from clean ones.
p_fj_unsafe_counted: assert property (@(posedge clk) disable iff (!rst_n)
(paired && join_unsafe) |=> (c_unsafe == $past(c_unsafe) + 1));Group E — telemetry.
// E1. A fusion result is interpretable only with a trusted clock.
p_tl_fusion_clock: assert property (@(posedge clk) disable iff (!rst_n)
o_fusion_result_interpretable |-> !o_caveats[C_CLOCK]);
// E2. And only with a reported acquisition span.
p_tl_fusion_span: assert property (@(posedge clk) disable iff (!rst_n)
o_fusion_result_interpretable |-> !o_caveats[C_SPAN]);
// E3. A zero span sets the span caveat.
p_tl_zero_span: assert property (@(posedge clk) disable iff (!rst_n)
snapshot |=> (o_caveats[C_SPAN] == ($past(i_acquire_span_ns) == 0)));
// E4. The pair yield never exceeds 100%.
p_tl_yield: assert property (@(posedge clk) disable iff (!rst_n)
o_pair_yield_pct <= 16'd100);
// E5. Over-budget frames never exceed total frames.
p_tl_subset: assert property (@(posedge clk) disable iff (!rst_n)
o_over_budget_ppm <= 16'd1_000_000 / 16'd1);Group F — the deadline chain.
// F1. The total is the sum of the nine terms.
p_dc_sum: assert property (@(posedge clk) disable iff (!rst_n)
total_us == (exposure_us + readout_isp_us + encode_us +
transport_up_us + decode_us + fusion_us +
planning_us + transport_down_us + actuator_us));
// F2. The network term is the two transport terms.
p_dc_network: assert property (@(posedge clk) disable iff (!rst_n)
network_us == (transport_up_us + transport_down_us));
// F3. The network's share is a fraction of the total.
p_dc_share: assert property (@(posedge clk) disable iff (!rst_n)
network_share_pct_x10 <= 16'd1000);
// F4. Distance follows from time and speed.
p_dc_distance: assert property (@(posedge clk) disable iff (!rst_n)
distance_cm == ((total_us * SPEED_M_S) / 10_000));
// F5. The largest term's value matches its index.
p_dc_largest: assert property (@(posedge clk) disable iff (!rst_n)
largest_term_us >= transport_up_us);
// F6. The budget verdict agrees with the arithmetic.
p_dc_budget: assert property (@(posedge clk) disable iff (!rst_n)
within_budget == (total_us <= budget_us));Thirty-four properties, and one of them — C5 — fails on almost every real sensor. That failure is correct and Section 16 explained why it gets deleted. What gets written instead is the class below.
21. Verification Scenarios
Fifty-eight scenarios. Group 3 is the one that needs a moving object in the stimulus, and group 5 needs two sensors.
Group 1 — volume and reduction (10).
| # | Scenario | Expect |
|---|---|---|
| 1 | 8 surround + 4 forward cameras, raw | 17.92 Gb/s |
| 2 | the same at 30:1 | 597.2 Mb/s |
| 3 | 5 radars raw | 1.678 Gb/s |
| 4 | the same as object lists | 5.12 Mb/s — a 327.7× reduction |
| 5 | 2 lidars | 374.4 Mb/s, with no policy choice |
| 6 | full suite, all reduced | 976.7 Mb/s |
| 7 | full suite, all raw | 19.97 Gb/s |
| 8 | a 1 Gb/s link at an 80% cap | fits low — 976.7 needs 1.22 Gb/s |
| 9 | 8-bit pixels assumed instead of 12 | rates 33% low — the commonest budgeting error |
| 10 | suite_kbps forced off the sum | p_ad_suite_sum fires |
Group 2 — object-mode reduction (8).
| # | Scenario | Expect |
|---|---|---|
| 11 | 150 detections, capacity 200 | all emitted; no overflow |
| 12 | 250 detections | 200 emitted, 50 dropped, overflow counted |
| 13 | dense traffic plus roadside furniture | repeated overflow — the realistic case |
| 14 | 40 sub-threshold detections per frame | c_subthreshold_discarded climbs; nothing else moves |
| 15 | an empty scene | identical output to scenario 14 without the counter |
| 16 | policy RED_NONE | raw_recoverable high; 335.5 Mb/s per radar |
| 17 | policy RED_OBJECTS | raw_recoverable low — permanently |
| 18 | overflow with objects_dropped forced to zero | p_ad_truncation_counted fires |
Group 3 — the rolling shutter, which needs a moving object (10).
| # | Scenario | Expect |
|---|---|---|
| 19 | a static scene, 20 ms readout | no visible skew — the test that proves nothing |
| 20 | an object at 30 m/s, row 0 | zero time error |
| 21 | the same object, row 2 159 | 20 ms error — 600 mm |
| 22 | the same at 60 m/s closing | 1 200 mm |
| 23 | mid-frame reference used instead | worst case halves to 300 mm |
| 24 | a 5 ms readout imager | 150 mm |
| 25 | a global-shutter imager | zero — the only sensor where the point claim holds |
| 26 | acquire_span_ns = 0 with a rolling imager | p_ts_not_instant fires — correctly |
| 27 | the same, property deleted | the system runs, wrong by 600 mm, silently |
| 28 | a lidar rotation at 20 Hz | 50 ms span — 1 500 mm across one "frame" |
Group 4 — compression (10).
| # | Scenario | Expect |
|---|---|---|
| 29 | a benign scene, 8 MP camera | ≈30:1; 99.5 Mb/s |
| 30 | rain, spray, moving foliage | ≈10:1; 298.6 Mb/s — over budget by 3× |
| 31 | with rate_cap_enabled | quality falls; the rate holds |
| 32 | without it | the link overruns; the shared window suffers |
| 33 | an intra-coded frame every second | a 5–10× burst, at a fixed period |
| 34 | twelve cameras with aligned intra phase | twelve simultaneous bursts |
| 35 | the same with staggered phase | spread — a one-line configuration fix |
| 36 | a whole drive cycle | worst_ratio_seen is the honest budget number |
| 37 | an over-budget frame with the cap on | p_cb_cap_acts holds |
| 38 | worst_ratio_seen forced to rise | p_cb_worst_monotone fires |
Group 5 — the fusion join, which needs two sensors (12).
| # | Scenario | Expect |
|---|---|---|
| 39 | camera and radar, timestamps 100 µs apart | paired; 3 mm of position error |
| 40 | 1 ms apart | paired at the tolerance; 30 mm |
| 41 | 2 ms apart, tolerance 1 ms | rejected; c_rejected_time increments |
| 42 | both with 20 ms acquisition spans | span_dominates — 1 200 mm against 30 |
| 43 | tolerance tightened to 100 µs | error falls 27 mm of 630 — 4.3% |
| 44 | clock synchronised throughout | join_unsafe low |
| 45 | 5 s of holdover at 200 ppm | 1 ms divergence — the whole tolerance |
| 46 | 60 s of holdover | 360 mm of position error; join_unsafe high |
| 47 | 10 min of holdover | 3 600 mm — a lane and a half |
| 48 | an unsafe join counted as clean | p_fj_unsafe_counted fires |
| 49 | tolerance fixed at 1 ms, speed 10 m/s | too strict; yield falls, tracks lost |
| 50 | the same at 60 m/s | too loose; pairs 60 mm apart accepted |
Group 6 — the deadline chain and the link (8).
| # | Scenario | Expect |
|---|---|---|
| 51 | the nine-term chain with typical values | 96.7 ms; network 1.7% |
| 52 | the backbone upgraded 1 Gb/s → 10 | 16 µs saved — 0.5 mm |
| 53 | the network unbounded, camera burst | +8.33 ms — 25 cm, 8.6% of the chain |
| 54 | fusion at 60 ms instead of 30 | +30 ms — the largest term, doubled |
| 55 | a frame-period wait added | up to +33.3 ms — a third of the chain |
| 56 | 1 Gb/s link, 19.48% express, 80% cap | 644 Mb/s available; the suite is 976.7 |
| 57 | 2.5 Gb/s link, same reservations | 1.61 Gb/s available — fits with margin |
| 58 | total_us forced off the sum | p_dc_sum fires |
Scenario 19 is the test that proves nothing and scenario 27 is what happens when the property that would have caught it is deleted.
The directed test random stimulus will not produce
This test needs a static scene and a moving scene of the same object, run through the same pipeline, with the same property set — and the point is that the property passes on one and should fail on the other.
The arrangement:
| Step | Action |
|---|---|
| 1 | an 8 MP rolling-shutter model with a 20 ms readout and 2 160 rows |
| 2 | acquire_span_ns is 0, because the sensor does not report it — the realistic default |
| 3 | run A: a static scene with a target at a known position |
| 4 | run B: the identical scene with the target closing at 30 m/s |
| 5 | both runs assert p_object_position against the single frame timestamp |
| 6 | both runs also record the per-row true acquisition time |
Random stimulus will not produce this because a randomised image generator renders a frame, and a rendered frame is an instant by construction. Producing run B requires the stimulus to model the sensor's acquisition as a process over time — each row sampled at its own instant from a moving scene — which is a deliberate modelling decision, not a randomisation. A generator that randomises object positions, velocities, scene content and lighting will never produce a frame whose rows were taken at different times, because nothing in its model has rows with times.
The oracle is in four parts and part three is the finding.
| Part | Signal | Required value | Why alone it is not enough |
|---|---|---|---|
| 1 — run A passes | p_object_position | holds | it should; the scene is static |
| 2 — run B also passes | p_object_position | holds | and it should not |
| 3 — the true per-row error | row 2 159's position error | 600 mm | invisible to the property |
| 4 — the corrected property | p_row_position | holds in both, with the span supplied | needs a field the sensor lacks |
Part 2 is the assertion that makes the test worth writing and it is an assertion that something passes when it should not. The property compares a detection against a position derived from the frame's single timestamp, and the detector found the object where the rows it occupied saw it — so both sides of the comparison carry the same error and it cancels. The property is self-consistent and wrong, and that self-consistency is exactly why it survives review.
Part 3 is measured against ground truth the model has and the system does not: the object's true position at each row's true acquisition instant. The 600-millimetre discrepancy is real, systematic, and present in every frame — and no signal available to the design can see it.
Run the test a third time with acquire_span_ns set to 20 000 000 and property 3 of Section 20 enabled. The position uncertainty becomes 600 mm, the point claim is refused, and the tracker downstream behaves differently — which is the demonstration: the fix is not a better assertion, it is a field, and the field costs 16 bits.
22. Debugging a Sensor Path
A procedure, ordered so that the largest error terms are checked first — which puts the network near the bottom.
| Step | Do | Because |
|---|---|---|
| 1 | ask whether the sensors report an acquisition span | Section 10 — 600 mm for a rolling shutter, 1 500 for a lidar |
| 2 | read the clock's holdover state at both sensors | Section 12 — 30 mm after 5 s, 3 600 after 10 min |
| 3 | read worst_ratio_seen and o_over_budget_ppm | Section 13 — a 3× rate excursion in rain |
| 4 | read o_overflow_ppm and the sub-threshold count | Section 5 — a truncated object list looks like an empty scene |
| 5 | read o_pair_yield_pct | a falling yield is an over-strict tolerance, not a sensor fault |
| 6 | compute the chain's terms and rank them | Section 8 — fusion is 31%, the network is 1.7% |
| 7 | only then look at the network | it is the smallest term and the only one with a proof |
| 8 | check the link budget's two multiplied reservations | Section 18 — 0.8 × 0.8052 is 64.4%, not 80% |
Step 7 being seventh is the chapter's practical conclusion. A team investigating a missed reaction deadline will be offered a faster network first, because it is the component with a number on it. It is 1.7% of the chain, and steps 1 to 4 each address terms that are ten to a hundred times larger.
Four signatures.
| Signature | Cause |
|---|---|
| objects consistently mis-positioned, more at the frame's edges | rolling-shutter skew — Section 10 |
| fusion quality degrades slowly after start-up, recovers on restart | clock holdover — Section 12 |
| tracking degrades in rain, link counters show drops | compression rate excursion — Section 13 |
| a sensor reports nothing in a scene that has objects | object-list truncation or a threshold — Section 5 |
Row one's second clause is the diagnostic. A skew error is linear in row index, so it is zero at the top of the frame and maximal at the bottom — a systematic, position-dependent error is a rolling shutter and a uniform one is a clock. Distinguishing them costs nothing and saves a great deal of time.
Row four is the one with no instrument. A radar in object mode reporting an empty list is indistinguishable from an empty scene, and the only evidence that would separate them — the sub-threshold detection count — is a field the sensor does not carry. Section 15's production note is the whole remedy: ask for it before the part is qualified.
23. Misconceptions
Six, in wrong-model / what-it-costs / corrected-model form.
Misconception 1 — "sensor data moved to Ethernet because Ethernet is fast."
Wrong model: the suite needed more bandwidth than a vehicle bus had, and Ethernet had it.
What it costs: the actual reason, and therefore the architecture. A dedicated LVDS link to a camera carries about 3 Gb/s — more than 1000BASE-T1 — and cameras ran on exactly that for years. Bandwidth alone does not explain the change.
Corrected model: a point-to-point link has one consumer. The moment a forward camera has to feed perception, recording and a driver display at once, a dedicated link has no answer at any rate. Ethernet won because the data has multiple consumers and switching is the thing a serial link cannot do — the bandwidth comparison against CAN is real but it was never the deciding argument.
Misconception 2 — "a faster network reduces reaction time."
Wrong model: the network is in the critical path, so speeding it up speeds up the reaction.
What it costs: an engineering programme. Section 8's chain: the network is 0.84 ms of 96.7 — 1.7%, five centimetres of a 2.90 metre stopping distance. Upgrading a 1 Gb/s backbone to 10 saves 16 microseconds, which is half a millimetre.
Corrected model: the network's job is to be bounded, not fast. An unbounded network lets Chapter 22.2 §6's 8.33 ms camera burst into the path — 25 centimetres, 8.6% of the chain — and the difference between bounded and unbounded is the only network decision in the table that changes anything. Within the network's own 1.7%, the link is 4% and the schedule's wait is 96%.
Misconception 3 — "a frame's timestamp tells you when the frame was taken."
Wrong model: a timestamp is a time, and the frame has one.
What it costs: up to 60 centimetres of systematic position error, every frame, in the same direction. A rolling-shutter 8 MP imager reads out over 20 milliseconds, so its last row is acquired 20 ms after its first — 60 cm at 30 m/s, 120 at 60 m/s closing, and 150 cm for a lidar rotation.
Corrected model: a frame is acquired over an interval, not at an instant, and the interval is in no field of the data. The remedy is a 16-bit field carrying the readout duration; with it, Section 9's four-line transform corrects per row to a few millimetres. Without it, use the midpoint as the reference — it halves the worst case for free — and inflate the position uncertainty to match the span.
Misconception 4 — "PTP's sub-microsecond accuracy is what makes fusion accurate."
Wrong model: better synchronisation means better fusion.
What it costs: effort spent on a term four orders of magnitude below the binding one. Section 12's table: network timestamp accuracy contributes under 0.1 mm, the servo's error 0.1 to 3 mm, the fusion tolerance 30 mm, and the acquisition span 600 to 1 500.
Corrected model: synchronisation does not make timestamps precise enough — it makes them comparable at all. Without a common time base two sensors' timestamps are numbers from unrelated counters and their difference is meaningless. With it, the difference is a real interval, and then physics takes over. The progression is incomparable → comparable → limited by the sensor.
Misconception 5 — "the radar reported nothing, so there was nothing there."
Wrong model: an empty object list is an observation about the scene.
What it costs: the distinction between a validated sensor and a trusted one. An object list is what a supplier's detector, with its threshold, on its firmware version, decided to emit — 327.7 times smaller than the raw data, with everything below the threshold discarded and no record kept. A pedestrian at the edge of detectability is a sub-threshold detection, and in object mode nothing says the sensor saw anything at all.
Corrected model: object-mode reduction moves a safety-relevant decision into a part you did not design, and the fix is one 16-bit field — a count of detections below the reporting threshold. It converts the radar saw nothing from an assertion into a measurement. Ask for it before the part is qualified, because after that the absence is permanent.
Misconception 6 — "compression is a network cost."
Wrong model: compression exists to fit the link, so it is the network's problem and the network's saving.
What it costs: two large terms that never appear in a network budget. Encode plus decode is 20 milliseconds — 20.7% of the reaction chain, 60 centimetres — twelve times the network's entire contribution. And a lossy encoder is a second authority on what was in the scene, tuned for perceptual quality against a corpus, spending fewest bits on exactly the fine, low-contrast detail a distant-pedestrian detector needs.
Corrected model: compression buys a factor of 20.4 in link rate — 19.97 Gb/s to 976.7 Mb/s — for 60 centimetres of stopping distance, a 3× rate excursion in rain, and an encoder's judgement about what matters. The trade may well be right; it should be made with those four numbers in front of the people making it, and it is usually made implicitly by whoever specifies the first camera.
24. Interview Questions
Six, with what a strong answer contains.
1. What does an ADAS sensor suite actually produce?
About 20 Gb/s raw and 1 Gb/s reduced. Twelve cameras — eight 2 MP and four 8 MP, at 30 fps and 12 bits — are 17.92 Gb/s; five imaging radars are 1.68 Gb/s of raw ADC data; two lidars are 374 Mb/s. Reduced, the cameras compress 30:1 to 597 Mb/s, radar becomes object lists at 5.1 Mb/s, and lidar does not reduce — 976.7 Mb/s in total, a ratio of 20.4. A strong answer names the 12-bit depth as the commonly missed factor: assuming 8 bits understates every camera rate by a third.
2. Why did the industry move sensor data to Ethernet?
Not for bandwidth alone. A dedicated serial link to a camera carries ~3 Gb/s, more than 1000BASE-T1, and worked fine. It moved because the data has more than one consumer and a point-to-point link has exactly one. A strong answer still gives the bus comparison — the suite is 19 968× CAN, 2 496× CAN-FD, 1 997× FlexRay — and notes that no incremental improvement to a vehicle bus reaches three orders of magnitude, so switching plus rate, together, is the answer.
3. How much of a braking reaction is the network?
1.7% — 0.84 ms of 96.7, five centimetres of a 2.90 metre stopping distance at 30 m/s. The largest terms are fusion at 31%, actuation at 21%, and encode plus decode at 21%. A strong answer adds the decomposition within the network: the three-hop transport is 35.94 µs and the schedule's worst-case wait is 800 µs, so 96% of the network's own contribution is waiting for a window — meaning a faster PHY changes nothing and a shorter cycle changes everything.
4. Your fusion stack mis-positions objects, worse at the bottom of the frame. What is it?
Rolling-shutter skew. The error is linear in row index, which is the signature: zero at the first row, maximal at the last, 20 milliseconds and 600 millimetres apart at 30 m/s. A strong answer contrasts it with the alternative — a clock error is uniform across the frame — and names the fix: carry the readout interval as a field, correct per row, or failing that use the midpoint timestamp, which halves the worst case for nothing.
5. Why is PTP necessary for fusion if its accuracy is not the limiting term?
Because it makes the timestamps comparable, not because it makes them precise. Sensors sit on different ECUs with unrelated oscillators; without a common base, two timestamps are two numbers and their difference is meaningless. A strong answer gives the error budget — network timestamping under 0.1 mm, servo error 0.1 to 3 mm, join tolerance 30 mm, acquisition span 600 to 1 500 — and then Chapter 22.2 §12's failure: 5 seconds of holdover at 200 ppm consumes a 1 ms tolerance entirely, and ten minutes puts objects 3.6 metres out.
6. What does object-mode reduction cost?
The raw data, permanently, and a safety decision moved into supplier firmware. A radar's object list is 327.7× smaller than its ADC stream and discards everything below a threshold set elsewhere, with no record that anything was seen. A strong answer names the two remedies: a sub-threshold detection count, one 16-bit field, which converts an assertion into a measurement; and a rolling raw buffer at the sensor with a request path, which turns permanent loss into a retention window — a 12.44 MB raw frame at 1 Gb/s is 99.5 ms, unusable as a stream and fine as a one-off.
25. Questions and Answers
26. What's Next
Module 22 is complete. Three chapters, one physical layer, one schedule and one traffic class, and a consistent conclusion.
| Chapter | Its result |
|---|---|
| Chapter 22.1 | 3B2T's 1.5 bits per symbol puts 100 Mb/s on one pair; the price is an echo canceller sized by the cable's round trip |
| Chapter 22.2 | a 121.5 µs guard band at 100 Mb/s makes preemption mandatory, and a node that loses PTP keeps passing all its own assertions |
| Chapter 22.3 | the suite is 20 Gb/s raw and 1 compressed; the network is 1.7% of the reaction and the sensor's own acquisition interval is twelve times it |
The module's through-line is that the network is small and the things around it are large. A single-pair PHY's digital front end is 2 323 flops; the schedule's instrumentation is 584; this chapter's is 516. Together they are under a quarter of a MAC receive datapath, and they sit between a video encoder of millions of gates and a fusion stack running on a compute cluster. What the network contributes is not speed — it is a bound, a timestamp, and the ability to send one sensor's data to more than one consumer.
Module 23 changes setting completely. Where a vehicle's network is small, fixed, shallow and engineered years in advance, a data-centre fabric is large, uniform, deep and built to be extended. Chapter 23.1 starts with the topology — why a modern fabric is built from identical switches in two tiers, what its oversubscription model actually promises, and why a structure with no distinguished node is easier to scale, cheaper to buy, and harder to reason about than the hierarchy it replaced.
Continue learning
Related tutorials
- Related topic
One Frame, End to End
A frame's journey down the stack and back up the other side, stage by stage. The transmit path decides and the receive path must discover — at four layers, not one — and that asymmetry is why the receive half of every Ethernet design is the larger, later and buggier one.
- Related topic
Forward Error Correction
FEC converts a gradual degradation into a cliff and hides the gradient behind it. The pre-correction error rate is the link's health metric and gives months of warning; the corrected output reads zero until the moment it collapses, and can be silently wrong when a decoder miscorrects.
- Related topic
Serialization Delay
A frame's size divided by the line rate — trivial arithmetic whose significance changes by four orders of magnitude, inverting latency budgets so that at 100 Gb/s one metre of cable outweighs an entire minimum-size frame.
- Related topic
Propagation Delay
Length divided by velocity, about 5 ns per metre in copper and fibre alike, and completely independent of the data rate — which is why it survived four orders of magnitude untouched and now dominates the budgets it used to be invisible in.
Standards & specifications
- Governing standard
- IEEE Std 802.3 (Ethernet)(opens IEEE in a new tab)
Defines the Ethernet MAC, the media-independent interfaces and the physical-layer sublayers, including framing, access control, auto-negotiation and per-rate PHY specifications. VLAN tagging, priority and time-sensitive shaping are defined by IEEE 802.1, not by 802.3.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the Ethernet curriculum.
