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 Foundations36
    • Digital Logic for RTL Engineers
    • Number Systems for RTL Engineers
    • Verilog Fundamentals
    • Verilog Operators and Types
    • SystemVerilog for RTL
      • Why SystemVerilog Improves RTL Quality
      • The `logic` Type and Assignment Model
      • always_ff and always_comb
      • typedef, enum and Robust FSM Coding
      • Interfaces and Modports
      • SystemVerilog RTL Cheat Sheet
    • Simulation and Testbenches
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹SystemVerilog for RTL
  1. Topics
  2. RTL Design
  3. RTL Foundations
  4. SystemVerilog for RTL
  5. Interfaces and Modports

Part 1 · Foundations · Beginner

Interfaces and Modports

Grouping related signals into an interface, with directions fixed by modports.

On this page

    Why this matters

    A bus of valid, ready and data repeats on every module it touches, so one new signal means editing every port list and instance. An interface groups the signals once, and a modport fixes which side drives each.

    After this lesson you can: decide when an interface is worth it, pick the modport at the module boundary, and use a scalar-port fallback when a tool lacks support.

    The problem interfaces solve

    A bus such as valid, ready and data repeats on every module it touches. Adding a signal then means editing every port list and every instance.

    An interface groups the signals once. A modport states which side drives and which side receives each signal.

    Without an interface

    With an interface

    Every module lists valid/ready/data.

    Both sides connect to one bus_if bundle; master and slave fix who drives what.

    A new signal changes every port list.

    Add the signal once in the interface.

    Direction mistakes show up late.

    The modports state who may drive each signal, so a connection against them is a compile error where the tool supports interface ports.

    One interface, two views

    The interface below declares the three signals once and two modports. The producer's port has type lesson_bus_if.master, the consumer's lesson_bus_if.slave, and the top level connects one interface instance b to both.

    lesson_bus_if.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    interface lesson_bus_if;
      logic valid, ready;
      logic [7:0] data;
      modport master (output valid, data, input ready);
      modport slave (input valid, data, output ready);
    endinterface
    
    module bundled_producer (lesson_bus_if.master b);
      assign b.valid = 1'b1;
      assign b.data = 8'hA5;
    endmodule
    
    module bundled_consumer (lesson_bus_if.slave b, output logic [7:0] got);
      assign b.ready = 1'b1;
      assign got = b.valid ? b.data : 8'h00;
    endmodule
    
    module modport_connections (output wire [7:0] got);
      lesson_bus_if b();
      bundled_producer p (.b(b));
      bundled_consumer c (.b(b), .got(got));
    endmodule
    The producer, through the master modport, drives valid and data into the interface instance b, which carries them to the consumer. The consumer, through the slave modport, drives ready into b, which carries it back to the producer.
    One interface instance, two modport views: the master view drives valid and data, the slave view drives ready

    Read each arrow as one signal group and the direction its driver is allowed to push it.

    • master: output valid, data, input ready, so the producer may assign valid and data and may only read ready.

    • slave: the mirror image, so the consumer may assign only ready.

    • One instance: both modules see the same b, so a value the producer drives is the value the consumer reads.

    A connection against the modport

    Driving a signal that the view declares as an input is a compile error in a tool that enforces modports:

    wrong_direction.sv
    1
    2
    3
    4
    // snippet: intentionally illegal direction, using lesson_bus_if above
    module wrong_direction (lesson_bus_if.slave b);
      assign b.valid = 1'b1; // illegal: valid is an input in the slave view
    endmodule

    Keep a fragment like this out of the legal example; compile it on its own with the interface declaration to confirm your tool rejects it.

    Check yourself What does a modport add beyond grouping the signals?

    Direction. It declares which side drives each signal, so a connection against it is caught by the compiler in tools with full interface support instead of showing up as an x in simulation.

    When to use them

    • Buses with many signals shared by several modules (memory ports and AXI-like links).

    • Verification environments, where one interface also connects the testbench to the DUT.

    • For a 2- or 3-signal link used in one place, a plain port list is simpler and works with every tool.

    Warning

    Limits. Interface support in synthesis, lint, equivalence and CDC tools varies, so test the whole flow on a small example before adopting interfaces broadly. Modports restrict only interface-typed ports; they do not check ordinary scalar ports wired to the same signals.

    Tip

    Use .* or .name (for example .clk) implicit connections sparingly. Explicit named connections remain easier to review.

    Scalar fallback

    Where a tool does not accept interface ports, give each module scalar ports that mirror the modport directions and connect them through an interface instance, as below. Directions are then kept by review and lint, not by the compiler. If the tool lacks interfaces entirely, replace b.valid, b.ready and b.data with ordinary wires.

    bus_if.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    interface bus_if;
      logic        valid, ready;
      logic [7:0]  data;
    
      modport master (output valid, data, input  ready);
      modport slave  (input  valid, data, output ready);
    endinterface
    
    // Port directions mirror the modports: the master side drives
    // valid/data, the slave side drives ready.
    module producer (output logic valid, output logic [7:0] data, input logic ready);
      assign valid = 1'b1;
      assign data  = 8'hA5;
    endmodule
    
    module consumer (input logic valid, input logic [7:0] data, output logic ready, output logic [7:0] got);
      assign ready = 1'b1;
      always_comb got = valid ? data : 8'h00;
    endmodule
    
    module tb_interface;
      bus_if b();
      logic [7:0] got;
      producer p (.valid(b.valid), .data(b.data), .ready(b.ready));
      consumer c (.valid(b.valid), .data(b.data), .ready(b.ready), .got(got));
      initial begin
        #1;
        if (got === 8'hA5) $display("PASS: interface connection works");
        else               $display("FAIL got=%h", got);
        $finish;
      end
    endmodule

    Remember

    • A modport states direction: a connection against it is a compile error in a tool that enforces it.

    • For a link of two or three signals used in one place, a plain port list is simpler.

    • Interface support in synthesis, lint and CDC tools varies. Test the whole flow on a small example first.

    Rule of thumb: bring in interfaces last, after the team agrees on connection and verification.

    How this was checked

    The listing is a connectivity illustration, not a buffered stream. The repository snippet checker routes interface examples to Verilator.

    The fallback testbench checks wiring values only. It does not check modport enforcement or a full stream protocol.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • AXI-Lite — a real interface in use

    • SystemVerilog RTL cheat sheet

    Previous

    29 / 350

    Next: SystemVerilog RTL Cheat Sheet

    Up next

    Up nextSystemVerilog RTL Cheat Sheet

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Why SystemVerilog Improves RTL Quality
    • The `logic` Type and Assignment Model
    • always_ff and always_comb