C Part II · Module 25 · Debugging DPI-C and Simulator Integration
Type, Width and Signedness Mismatches
Two different faults produce the same sentence in a bug report: correct for small values, wrong past a point. The method that separates them is one procedure and about four runs. Find the smallest input where the two sides disagree — measured, 0x80 for a signedness error and 0x8000 for a width error — and notice that it is always a power of two whose exponent names the width of the field involved. Then confirm with the shape: a sign flip keeps the magnitude, a truncation collapses it.
Expert22 min readCPart IIVerificationDPI-C
Part II · Module 25 · Chapter 25.3 · Type, Width and Signedness Mismatches
1. One Sentence, Two Faults
The bug report says: "it works for small values and goes wrong above some threshold."
That sentence is produced by two quite different faults — a signedness disagreement and a width disagreement — and nothing in the sentence distinguishes them. This chapter is the one procedure that does.
Measured, the same byte read two ways:
value | signed-8 | unsigned-8 | agree?
0x00 | 0 | 0 | yes
0x7E | 126 | 126 | yes
0x7F | 127 | 127 | yes
0x80 | -128 | 128 | NO
0xFF | -1 | 255 | NOThey diverge at exactly 0x80 and nowhere below it. Chapter 20.4 measured this as a property of the boundary; here it is a diagnostic.
2. Why Both Faults Look the Same
Both are a function of the top bit of some field.
A signedness disagreement changes nothing until a value has its field's top bit set, because below that point the signed and unsigned readings of the same bits are the same number.
A width disagreement changes nothing until a value needs more bits than the narrower field has — which is, again, the point at which that field's top bit would have to be set.
So both faults are invisible across the entire lower half of their field's range, and both become visible at a single sharp threshold. Hence one symptom.
3. The Method
Find the smallest input on which the two sides disagree. That value is the whole diagnosis.
Measured:
sign error first disagrees with the true value at 0x80 (128)
width error first disagrees at 0x8000 (32768)Both are powers of two, and that is not a coincidence — it is the threshold from §2. So:
The first disagreeing value is 2ⁿ, and n names the field.
0x80= 2⁷ → an 8-bit field, read with the wrong signedness0x8000= 2¹⁵ → a 16-bit field0x80000000= 2³¹ → a 32-bit field
An exponent of 7, 15 or 31 points at the top bit of a standard width, which means signedness. An exponent that is not one less than a standard width — 11, say, or 23 — points at a field boundary inside a packed value, which means truncation.
Finding that value takes about four runs by bisection: try the middle of the range, keep the half that still disagrees, repeat.
4. Confirming With the Shape
The threshold names the field. The shape of the wrong answer confirms which fault it is, and it is worth doing because the two can coincide on individual values.
Measured:
value | sign error (8-bit signed) | width error (16-bit kept)
0x000000FF | -1 | 255
0x00012345 | 69 | 9029
0x0001FFFF | -1 | -1A signedness error flips the sign and keeps the magnitude recognisable. 0xFF becomes -1, not 255 — but |−1| and 255 are both "the top of a byte", and the bits are unchanged. No information was lost, so the fault is reversible by reinterpreting.
A width error collapses the magnitude. 0x12345 becomes 9029 — a number with no obvious relationship to the input, because the high bits are gone. That one is not reversible.
And the third row is the warning: at 0x1FFFF both faults produce -1. One sample cannot distinguish them, which is why the method is "find the smallest disagreeing value" rather than "look at a failing case".
5. The Procedure
Four steps, about four runs:
One — bisect for the smallest disagreeing input. Drive the midpoint of the range; if it disagrees, search the lower half; if it agrees, the upper.
Two — read the value as a power of two. It will be one.
Three — map the exponent. 7, 15 or 31 → a signed/unsigned disagreement on an 8-, 16- or 32-bit field. Anything else → a field boundary at that bit position, i.e. truncation.
Four — confirm with the shape. Sign flip with the magnitude intact, or magnitude collapse.
Then the fix is Chapter 20.4's or Chapter 20.3's, and Chapter 24.8 §4's normalisation is where it belongs — both sides brought into one representation before any comparison, rather than patched at the point of failure.
6. The Misconception: Random Testing Would Have Found It
"We ran thousands of randomised transactions. A top-bit problem would have shown up."
It depends entirely on what was randomised, and the usual answer is not the field.
Randomising over a field's full range does find it, essentially at once — half of all values have the top bit set.
Randomising over a realistic range does not. A length "randomly chosen between 64 and 1500" never sets bit 15 of a 16-bit field. An address "randomly chosen within the buffer" never sets the top bit of a 32-bit one. A status code chosen from an enumeration of five never sets anything above bit 2. Each of those is a perfectly sensible constraint, and each one excludes exactly the value that would have failed.
So the thousands of transactions are evidence about the constrained range, which is the range the design was expected to see — and the fault is at the edge of the field, which is a different thing.
The accurate position:
A top-bit fault is found by a value, not by a volume. One deliberate case per field — its halfway value and its maximum — is worth more than any number of randomised transactions drawn from a realistic range, because the realistic range is defined by the same assumptions the fault hides behind.
7. What You Should Be Able to Say Now
- One sentence, two faults: "correct for small values, wrong past a point" describes both a signedness and a width disagreement.
- Both are functions of the top bit of a field, so both are invisible across the lower half of the range.
- Measured: signed-8 and unsigned-8 agree for
0x00–0x7Fand diverge at exactly0x80. - The method: find the smallest disagreeing input.
- It is always a power of two — measured,
0x80for a sign error and0x8000for a width error. - The exponent names the field: 7, 15, 31 → an 8-, 16- or 32-bit signedness disagreement; any other → a truncation boundary at that bit.
- Confirm with the shape: a sign flip keeps the magnitude (
0xFF→-1); a truncation collapses it (0x12345→9029). - One sample is not enough — measured, at
0x1FFFFboth faults give-1. - A signedness error is reversible (no information lost); a width error is not.
- Fix it by normalising both sides (24.8 §4), not by patching the failing case.
- Realistic stimulus is worse than random here — constrained ranges exclude exactly the value that fails.
- Drive each field's halfway value and maximum deliberately —
0x80/0xFF,0x8000/0xFFFF.
8. Exercises
- Tabulate a byte read as signed and as unsigned. At which value do they first differ, and why that one?
- Bisect for the smallest disagreeing input in a failing case you can construct. How many runs did it take?
- Your smallest disagreeing value is
0x800. What does that tell you, and what would you check next? - Produce a value where a sign error and a width error give the same wrong answer. What does that imply about single-sample diagnosis?
- Explain why a signedness error is reversible and a truncation is not, in terms of the bits.
- Take a constrained-random testbench you know. For each field, work out whether its constraint can produce the field's halfway value.
- Add one deliberate case per field at its halfway value. How many cases is that, and how long do they take to run?
- §6 says a fault is found by a value, not a volume. Give a second example from this track where that was measured.
9. Summary
- One symptom, two causes — both are functions of a field's top bit.
- Measured:
0x00–0x7Fagree;0x80diverges (-128against128). - The method: the smallest disagreeing input, which is always 2ⁿ.
- Measured:
0x80→ an 8-bit field;0x8000→ a 16-bit field. - The exponent names the field; 7/15/31 means signedness, anything else means truncation.
- Shape confirms: sign flip keeps the magnitude (
0xFF→-1); truncation collapses it (0x12345→9029). - One sample is ambiguous — at
0x1FFFFboth give-1. - Normalise both sides rather than patching the failing value (24.8 §4).
- Constrained-realistic stimulus hides it; drive each field's halfway value and maximum deliberately.
A width or a signedness fault is one value read wrongly. The next class is harder to localise because every value is read correctly and the fault is in which value was read.
Where this fits
Part of the C Programming curriculum.
