Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations57
    • Digital Logic for RTL Engineers
    • Number Systems for RTL Engineers
      • Representation Drives Behavior
      • Binary and Hexadecimal Conversion Habits
      • Two's Complement Intuition
      • Sign Extension, Zero Extension and Casting
      • SystemVerilog Signed Arithmetic Pattern
      • Overflow Detection Patterns
      • Unsigned and Signed Overflow Flags
      • Number Systems Summary
      • Worked Examples and Waveforms
    • Verilog Fundamentals
    • Verilog Operators and Types
    • SystemVerilog for RTL
    • Simulation and Testbenches
  • Combinational Design58
  • Sequential Design61
  • FSM & Control66
  • Timing & Clocking64
  • Reset & CDC58
  • Memory & Buses94
  • Advanced RTL60
  • Senior & Interview175
  • Glossary and Notation
Loading lesson

‹Number Systems for RTL Engineers
  1. Topics
  2. RTL Design
  3. RTL Foundations
  4. Number Systems for RTL Engineers
  5. Representation Drives Behavior

Part 1 · Foundations · Beginner

Representation Drives Behavior

How signedness changes comparison, shifts, and expression typing for the same bits.

On this page

    Why this matters

    The pattern 8'hF0 is 240 or -16, and nothing in the register says which. One unsigned operand in an expression makes the whole expression unsigned, so a compare that looks signed quietly goes the wrong way.

    After this lesson you can: state how a bit pattern is read as signed or unsigned, and predict the result of mixed-signedness expressions.

    One pattern, two meanings

    8'hF0 is 1111_0000. As an unsigned value it is 240.

    As a two's complement value the top bit has negative weight. The value is −16.

    Nothing in the register records which meaning was intended. The declaration and the operators decide.

    Operation

    Unsigned u

    Signed s

    Why

    Value of F0

    240

    −16

    MSB weight is +128 vs −128.

    x > 100

    true

    false

    −16 is less than 100.

    x >> 2

    60

    60 (!)

    >> is a logical shift even on a signed variable.

    x >>> 2

    60

    −4

    >>> shifts arithmetically only when the operand is signed.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    module tb_repr;
      logic [7:0]        u = 8'hF0;   // unsigned
      logic signed [7:0] s = 8'hF0;   // same bits, signed
      int errors = 0;
    
      initial begin
        $display("u=%0d  s=%0d", u, s);
        if (u !== 8'd240) errors++;
        if (s !== -8'sd16) errors++;
    
        if (!(u > 8'd100)) errors++;          // unsigned: 240 > 100
        if (  s > 8'sd100) errors++;          // signed:   -16 > 100 is false
    
        if ((u >> 2)  !== 8'd60)  errors++;   // logical shift
        if ((s >> 2)  !== 8'd60)  errors++;   // still logical, despite 'signed'
        if ((s >>> 2) !== -8'sd4) errors++;   // arithmetic shift keeps the sign
    
        if (errors == 0) $display("PASS: all behaviors as described");
        $finish;
      end
    endmodule

    The mixing rule

    For arithmetic, comparison and bitwise operators, an expression with any unsigned operand is evaluated as unsigned. One unsigned operand strips the sign from everything else.

    The shift amount is the exception. The right operand of <<, >>, <<< and >>> does not affect signedness, so a signed value shifted by an unsigned count stays signed (for example s >>> cnt with unsigned cnt still sign-extends).

    The sign-extension lesson shows the consequences.

    Tip

    Make intent visible: declare data that represents numbers as signed, declare raw bit patterns (addresses, masks, flags) as unsigned, and do not compare or add across the two without an explicit cast.

    Common mistakes

    Common pitfall

    >> never sign-extends, even if the variable is declared signed. If you want a divide-by-two that preserves sign, use >>> on a signed operand.

    Check yourself A counter is declared logic [3:0] count; and compared with if (count > -1). Will the branch ever be taken?

    Never: -1 becomes 4294967295 in the unsigned comparison, so a 4-bit value is never larger than it

    Remember

    • Any unsigned operand makes the whole arithmetic or comparison expression unsigned.

    • The shift amount is the exception: it does not change the signedness of the shifted value.

    • >> never sign-extends; >>> on a signed operand keeps the sign, but it rounds toward minus infinity: -5 >>> 1 is -3, while -5 / 2 is -2.

    Rule of thumb: declare numbers signed and raw bit patterns unsigned, and cast explicitly between them.

    How this was checked

    Exhaustive check of the compare against -1 on a 4-bit value: the branch is taken for none of the 16 values.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • Two's complement intuition

    Previous

    10 / 694

    Next: Binary and Hexadecimal Conversion Habits

    Up next

    Up nextBinary and Hexadecimal Conversion Habits

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Two's Complement Intuition
    • Sign Extension, Zero Extension and Casting
    • SystemVerilog Signed Arithmetic Pattern