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

  • Logic Synthesis Glossary
  • Logic Synthesis Cheatsheet
  • Synthesis Foundations14
  • Logic Optimisation and Mapping20
  • Constraints and Timing15
  • Sequential, FSM and Memory19
    • Flops, Resets and Enables
    • FSM Synthesis
    • Memory and Macro Inference
      • Flop Arrays or RAM Macros
      • Read and Write Port Styles
      • Byte Enables and Bypass Wrappers
      • Compilers, Macros and Wrappers
    • Retiming and Pipelining
  • Datapath Synthesis14
  • Area, Power and Test14
  • Verification, ECO and Handoff15
  • Flows and Debugging15
  • Interview and Judgment11
Loading lesson

‹Memory and Macro Inference
  1. Topics
  2. Logic Synthesis
  3. Sequential, FSM and Memory
  4. Memory and Macro Inference
  5. Read and Write Port Styles

Part 4 · Sequential, FSM and Memory · Intermediate

Read and Write Port Styles

Sync and async reads, write ports, and read-during-write behavior.

On this page

    Sync read and async read

    A sync read registers the data: the address goes in one cycle and the data comes out the next. An async read is combinational: the data follows the address in the same cycle.

    Most compiled SRAM macros offer sync read only. An async read usually forces a flop implementation, so the read style picks the technology.

    design.sv
    1
    2
    3
    4
    5
    // not-run: illustrative excerpt, not a complete testbench
    // sync read: data appears one cycle after the address
    always @(posedge clk) rdata <= mem[raddr];
    // async read: data follows the address in the same cycle
    always @(*) rdata = mem[raddr];

    The two listings above are illustrative excerpts, not runnable testbenches.

    Style

    Latency

    Macro fit

    Typical use

    Sync read

    One cycle

    Fits compiled macros

    Tables, buffers, caches

    Async read

    Same cycle

    Usually flops only

    Register files, bypass paths

    Write ports

    A write port takes an address, data and enable each cycle. One write port plus one read port is the common single-port shape; extra ports serve more accesses per cycle.

    Each added port widens the bit cell and the access muxing. Port count therefore moves the flop-versus-macro boundary toward flops while the memory (depth times width) is small.

    Read during write

    A read and a write to the same address in the same cycle is read-during-write. The read can return the old data, the new data, or an undefined value.

    Which one appears varies by macro and mode. Portable RTL assumes none of them and handles the case explicitly.

    Behavior

    Meaning

    Safe handling

    Read-old

    Read returns the previous contents

    Add bypass when the new data is needed

    Read-new

    Read returns the data being written

    Still add bypass for macros that differ

    Undefined

    Read returns neither reliably

    Avoid the collision or register around it

    Seeing the inference in Yosys

    The script below collects a 16-entry sync-read memory into one memory cell, then maps it to 20 flop cells plus the read muxes. The assertions pin each stage.

    yosys
    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
    read_verilog <<EOV
    module top (
      input wire clk,
      input wire we,
      input wire [3:0] waddr,
      input wire [3:0] raddr,
      input wire [7:0] wdata,
      output reg [7:0] rdata
    );
      reg [7:0] mem [0:15];
      always @(posedge clk) begin
        if (we)
          mem[waddr] <= wdata;
        rdata <= mem[raddr];
      end
    endmodule
    EOV
    hierarchy -check -top top
    proc
    memory_collect
    select -assert-count 1 t:$mem*
    memory_map
    select -assert-none t:$mem*
    select -assert-count 20 t:$dff
    select -assert-count 146 t:$mux
    log PASS: 16x8 sync-read memory collects to one memory cell and maps to a flop array

    Common pitfall

    Coding an async read and expecting a compiled macro is the classic miss. The macro supports sync read, so the tool builds flops and the area report surprises the team late.

    Interview

    Likely probes: latency of each style and the collision rule.

    • Sync read adds one cycle of latency; async read is combinational.

    • Read-during-write returns old, new or undefined data depending on macro and mode.

    • Yosys shows the inference as one memory cell after collection and 20 flop cells after mapping.

    Check yourself The address changes and the data must be valid in the same cycle. Which read style, and what does it cost?

    Async read. It costs macro fit: most compiled macros cannot do it, so the table becomes flops.

    Check yourself A read and a write hit the same address in the same cycle. What may the read return?

    Old data, new data, or an undefined value, depending on the macro and mode. The design must not rely on any one of them.

    Related topics

    • Next: Byte Enables and Bypass Wrappers

    • SRAM and ROM

    • Synthesizable RTL and Inference

    Previous

    63 / 139

    Next: Byte Enables and Bypass Wrappers

    Up next

    Up nextByte Enables and Bypass Wrappers

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Compilers, Macros and Wrappers