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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
    • 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
    • Verilog Fundamentals
    • Verilog Operators and Types
    • SystemVerilog for RTL
    • Simulation and Testbenches
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • 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
On this page

    Part 1 of 9, lesson 7 of 36Part 1 of 9/Foundations/Lesson 7 of 36Beginner

    Representation Drives Behavior

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

    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.

    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

    >> 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

    • 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.

    • Interview: run a mock interview on this topic

    Related topics

    • Two's complement intuition

    Previous

    7 / 350

    Next: Binary and Hexadecimal Conversion Habits

    Up next

    Up nextBinary and Hexadecimal Conversion Habits

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

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