Physical Design of Async FIFO Hub

Place and route a dual-clock FIFO hub from netlist to GDSII using Cadence Innovus.

Introduction

30 Second Summary

Every chip in your phone started as a list of logic gates connected by wires. Turning that abstract netlist into physical metal layers on silicon is where designs either meet their clock targets or fail at manufacturing.

In this project, you will take a synthesized dual-clock FIFO hub netlist and run it through the complete Cadence Innovus place-and-route flow, producing a tapeout-ready GDSII layout on the SCL 90nm process.

What You'll Build

You will watch your 4434-cell netlist transform into a fully routed chip layout in the Innovus GUI, with balanced clock trees, a power grid on upper metals, and a final verification report showing zero violations.

By the end of this project, you'll have:

  • A floorplanned chip with power rings on M8/M9 and power stripes delivering VDD/VSS to all 4434 standard cells, visible in the Innovus physical view.
  • Two independent clock trees (wclk at 500MHz, rclk at 333MHz) built by CCOpt with balanced skew, viewable in the clock tree debugger.
  • A DRC-clean, timing-closed GDSII file with zero routing violations and positive slack on both setup and hold paths across both clock domains.
  • Secret Mission: Run post-route STA with OCV (on-chip variation) analysis to prove your design handles manufacturing variation across clock domain crossings.

Are there any prerequisites?

Yes. You need a completed Genus synthesis run with the gate-level netlist of multi_channel_fifo_hub, the SDC constraints for both wclk and rclk, and access to the SCL 90nm LEF and timing libraries on your college server.

You also need a Red Hat Linux workstation with Cadence Innovus access through your college license.

Before We Start

Before diving into physical design, let's commit to what you're building and why it matters. Your dual-clock FIFO hub has clock domain crossings that make every physical implementation decision, from floorplanning to clock tree balance, critical to producing a working chip.

Design Import and Floorplanning

Your synthesized netlist is a logical description of 4434 gates. Cadence Innovus cannot do anything useful with it until you map those gates onto a physical canvas with dimensions, power delivery, and timing constraints.

In this step, you will import the multi_channel_fifo_hub netlist into Innovus, create a floorplan sized for your 4434 cells, and build the power distribution network that delivers VDD and VSS to every standard cell row.

In this step, get ready to:
  • Import the synthesized netlist and configure multi-mode multi-corner (MMMC) timing analysis.
  • Create a square floorplan at 70% utilization and place I/O pins.
  • Build power rings and stripes on the upper metal layers.
Set up the Innovus project and import design

Innovus needs four things before it can initialize your design: the gate-level netlist, the cell physical descriptions (LEF), the timing library, and the SDC constraints that define your two clocks.

  • Navigate to your pnr working directory and launch Innovus in 64-bit mode by running this command:
cd pnr
innovus -64

What does this command do?

The -64 flag launches the 64-bit version of Innovus, which can address more memory. For your 4434-cell design this is not strictly necessary, but it is best practice for any production flow.

The Innovus GUI opens with a TCL console at the bottom. You will enter all subsequent commands in that console.

Innovus not launching?

Confirm your Cadence environment is sourced (your college setup script). Verify the license server is reachable with lmstat -a.

help me troubleshoot why Innovus won't launch on my college Linux workstation

  • Set up the design import variables in the Innovus TCL console by entering the following commands:
# Point to the synthesized netlist from Genus
set init_verilog {[[SYNTH_DIR="path to your Genus synthesis output directory"]]/multi_channel_fifo_hub.v}
set init_top_cell multi_channel_fifo_hub

# Load the SCL 90nm physical cell descriptions
set init_lef_file {[[PDK_DIR="path to your SCL 90nm PDK directory"]]/scl90nm_tech.lef [[PDK_DIR="path to your SCL 90nm PDK directory"]]/scl90nm_stdcell.lef}

# Define global power and ground net names
set init_pwr_net {VDD}
set init_gnd_net {VSS}

What do these variables configure?

  • init_verilog points Innovus to your gate-level netlist (the 4434-cell design output by Genus).
  • init_top_cell tells Innovus which module is the top of the hierarchy.
  • init_lef_file provides the technology LEF (layer definitions, via rules) and the standard cell LEF (pin shapes, cell dimensions).
  • init_pwr_net and init_gnd_net name the global supply nets so Innovus can connect standard cell power pins automatically.
  • Configure the MMMC (Multi-Mode Multi-Corner) timing environment and initialize the design by entering these commands:
# Create a library set pointing to the slow-corner timing library
create_library_set -name slow_lib -timing {[[PDK_DIR="path to your SCL 90nm PDK directory"]]/slow.lib}

# Load SDC constraints (defines wclk at 2ns and rclk at 3ns)
create_constraint_mode -name func_mode -sdc_files {[[SYNTH_DIR="path to your Genus synthesis output directory"]]/multi_channel_fifo_hub.sdc}

# Set up RC extraction corner with capacitance table
create_rc_corner -name rc_typ -cap_table {[[PDK_DIR="path to your SCL 90nm PDK directory"]]/scl90nm.captable}

# Combine library set and RC corner into a delay corner
create_delay_corner -name slow_corner -library_set slow_lib -rc_corner rc_typ

# Create an analysis view for setup timing
create_analysis_view -name setup_view -constraint_mode func_mode -delay_corner slow_corner
set_analysis_view -setup {setup_view} -hold {setup_view}

# Initialize the design (loads netlist, LEF, and constraints)
init_design

What is MMMC?

MMMC stands for Multi-Mode Multi-Corner. It lets Innovus analyze timing under different operating conditions (fast corner, slow corner) and functional modes simultaneously.

Here you define one analysis view (setup_view) combining the slow timing library with your SDC constraints. Innovus uses this view to check setup and hold timing throughout the flow.

After init_design completes, the Innovus main window shows standard cell placement rows inside the default die boundary. The console log confirms the netlist was read without errors.

Seeing file-not-found errors?

Double-check that every path in your set init_verilog, set init_lef_file, and create_library_set commands matches the actual file locations on your college server. Use ls in a separate terminal to verify the files exist at those paths.

help me debug Innovus init_design file-not-found errors for my SCL 90nm PDK setup

Define floorplan and place I/O pins

With the design loaded, you need to define the physical dimensions of the chip. Your 4434 cells have a total area of 48791.288 square units. At 70% utilization, Innovus will size the core to fit all cells with room for routing channels.

  • Create the floorplan and place I/O pins by entering these commands:
# Create a square floorplan: aspect ratio 1.0, 70% utilization, 10-unit margins
floorPlan -r 1.0 0.70 10 10 10 10

# Place input pins on the left edge (edge 0) using metal layer 3
editPin -pin [all_inputs] -edge 0 -spreadDirection clockwise -layer M3

# Place output pins on the right edge (edge 2) using metal layer 3
editPin -pin [all_outputs] -edge 2 -spreadDirection clockwise -layer M3

What do these parameters mean?

  • floorPlan -r 1.0 0.70 10 10 10 10 creates a square die (aspect ratio 1.0), targets 70% core utilization, and adds 10-unit margins on left, bottom, right, and top edges.
  • editPin spreads all input pins evenly along the left edge and all output pins along the right edge, placed on M3 for signal access.
  • Verify the floorplan by looking at the Innovus GUI. Switch to Physical View using the toolbar. You should see the core outline with I/O pins placed around the left and right boundaries and standard cell rows visible inside the core area.

Pins not visible in the GUI?

Make sure you are in Physical View mode (not Floorplan view). Toggle layer visibility by pressing e to open the layer panel and ensure M3 is checked.

help me see I/O pins in the Innovus GUI after running editPin

Power planning (rings and stripes)

Standard cells need VDD and VSS delivered through a robust power grid. For the SCL 90nm 9-metal-layer process, best practice is to use the top two metals (M8 and M9) for power distribution, keeping M1 through M7 free for signal routing.

  • Connect the global power nets and build the power distribution network by entering these commands:
# Connect all standard cell VDD/VSS pins to global nets
globalNetConnect VDD -type pgpin -pin VDD -all
globalNetConnect VSS -type pgpin -pin VSS -all

# Add power rings around the core on M8 (horizontal) and M9 (vertical)
addRing -nets {VDD VSS} -type core_rings -follow core -center 1 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1 -layer {bottom M8 top M8 right M9 left M9} -width 2 -spacing 1

What do the power rings do?

Power rings form a closed loop of wide metal around the core perimeter. They collect current from the external pads and distribute it inward. The -stacked_via_top_layer M9 -stacked_via_bottom_layer M1 options ensure vias connect the ring metal all the way down to M1, where standard cell power rails live.

  • Add power stripes for internal distribution and route the special nets by entering these commands:
# Vertical power stripes on M9, repeating every 40 units
addStripe -nets {VDD VSS} -layer M9 -direction vertical -width 2 -spacing 1 -set_to_set_distance 40 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1

# Horizontal power stripes on M8, repeating every 40 units
addStripe -nets {VDD VSS} -layer M8 -direction horizontal -width 2 -spacing 1 -set_to_set_distance 40 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1

# Route special nets: connect standard cell rails to rings/stripes
sroute -connect {corePin} -layerChangeRange {M1 M9} -nets {VDD VSS} -allowLayerChange 1 -allowJogging 1

What does sroute do?

The sroute command connects the M1 power rails inside each standard cell row to the rings and stripes on the upper metals. Without this step, your cells would have no power supply path.

The -allowLayerChange 1 flag lets the router use vias to traverse from M1 up to M9, and -allowJogging 1 permits small lateral jogs to avoid routing congestion around the vias.

  • Look at the Physical View in the Innovus GUI. You should now see the power rings forming a rectangle around the core boundary and vertical/horizontal stripes crossing through the core area.

Power stripes not visible?

Toggle the M8 and M9 layers on in the layer visibility panel (press e). The stripes are on the upper metals and may be hidden by default. Also confirm the commands completed without errors in the TCL console log.

help me debug missing power stripes in my Innovus floorplan view

Before you predict the result of the next check, think about what check_timing should report. Your SDC defines two clocks (wclk and rclk) and constrains all flip-flop endpoints. Do you expect any unconstrained endpoints?

  • Verify that all timing endpoints are properly constrained by running this command:
check_timing

The output should report no unconstrained endpoints for either wclk or rclk. If your SDC from Genus is correct, every register clock pin is covered by one of the two clock definitions.

  • Capture a screenshot of the Physical View showing the complete floorplan with power rings, stripes, and I/O pins. This is your floorplan documentation for the project report.

✔️ Awesome, I've got everything!

Great. Confirm you have saved nothing yet (Innovus holds the design in memory). Your TCL console log should show all commands completed without errors.

ⓧ I'd like to double check the full commands

Here are all the commands you should have entered in the Innovus TCL console during this step, in order:

# Design import variables
set init_verilog {<path_to_synthesis>/multi_channel_fifo_hub.v}
set init_top_cell multi_channel_fifo_hub
set init_lef_file {<path_to_pdk>/scl90nm_tech.lef <path_to_pdk>/scl90nm_stdcell.lef}
set init_pwr_net {VDD}
set init_gnd_net {VSS}

# MMMC setup
create_library_set -name slow_lib -timing {<path_to_pdk>/slow.lib}
create_constraint_mode -name func_mode -sdc_files {<path_to_synthesis>/multi_channel_fifo_hub.sdc}
create_rc_corner -name rc_typ -cap_table {<path_to_pdk>/scl90nm.captable}
create_delay_corner -name slow_corner -library_set slow_lib -rc_corner rc_typ
create_analysis_view -name setup_view -constraint_mode func_mode -delay_corner slow_corner
set_analysis_view -setup {setup_view} -hold {setup_view}
init_design
# Floorplan and pin placement
floorPlan -r 1.0 0.70 10 10 10 10
editPin -pin [all_inputs] -edge 0 -spreadDirection clockwise -layer M3
editPin -pin [all_outputs] -edge 2 -spreadDirection clockwise -layer M3

# Power planning
globalNetConnect VDD -type pgpin -pin VDD -all
globalNetConnect VSS -type pgpin -pin VSS -all
addRing -nets {VDD VSS} -type core_rings -follow core -center 1 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1 -layer {bottom M8 top M8 right M9 left M9} -width 2 -spacing 1
addStripe -nets {VDD VSS} -layer M9 -direction vertical -width 2 -spacing 1 -set_to_set_distance 40 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1
addStripe -nets {VDD VSS} -layer M8 -direction horizontal -width 2 -spacing 1 -set_to_set_distance 40 -stacked_via_top_layer M9 -stacked_via_bottom_layer M1
sroute -connect {corePin} -layerChangeRange {M1 M9} -nets {VDD VSS} -allowLayerChange 1 -allowJogging 1

# Verification
check_timing

Your floorplan is established with a solid power grid. Next up, you will place all 4434 standard cells and run pre-CTS timing optimization to prepare for clock tree synthesis.

Placement and Pre-CTS Timing Optimization

Your floorplan and power grid are in place, but the 4434 standard cells are still unplaced.

Before building clock trees, every cell needs a legal position on the silicon canvas. Naive placement often violates timing, so this step runs timing-driven placement followed by pre-CTS optimization. The goal is to position cells for minimal wirelength and clean setup timing, giving CCOpt a solid starting point in the next step.

In this step, get ready to:
  • Set routing layer constraints to reserve M8/M9 for power and place all standard cells with timing-driven optimization.
  • Analyze pre-CTS timing and run incremental optimization to close setup slack on both clock domains.
  • Verify zero placement violations and capture a cell density screenshot for your project report.
Place standard cells with timing-driven optimization

Signal routing needs to happen on M1 through M7, while M8 and M9 stay reserved for your power rings and stripes. Setting these constraints before placement ensures Innovus accounts for available routing resources when deciding where to put cells.

  • In the Innovus console, set the routing layer constraints and run placement by entering these commands:
# Reserve M8/M9 for power, use M1-M7 for signal routing
setDesignMode -bottomRoutingLayer 1
setDesignMode -topRoutingLayer 7

# Run timing-driven placement with integrated optimization
place_opt_design

What do these commands do?

The two setDesignMode commands tell Innovus that signal wires can only use Metal 1 through Metal 7. This prevents signal routes from competing with your VDD/VSS power grid on M8 and M9.

The place_opt_design command performs timing-driven placement with integrated optimization. It considers your SDC constraints for both wclk and rclk when deciding cell positions, minimizing wirelength while meeting setup timing targets.

  • Wait for placement to complete. For 4434 cells, this should finish in under 2 minutes.
  • Once placement finishes, switch to Physical View in the Innovus GUI (the amoeba/density view). You should see all 4434 cells distributed across the core area, with the density view showing color-coded regions.

Placement taking much longer than expected?

  • If placement exceeds 5 minutes, check your system resources. Innovus may be competing with other processes for memory on the shared college server.
  • If you see density or overlap errors in the console output, your utilization target may be too aggressive. The 70% target from Step 1 should leave enough room, but verify with checkDesign -all after placement finishes.

Why is my placement failing or taking too long?

Run pre-CTS timing analysis

With cells placed, you can now measure how well the design meets timing with ideal (zero-skew) clocks. This pre-CTS analysis reveals any setup violations that need fixing before CCOpt builds the real clock trees.

  • Run timing analysis and generate a report of the worst paths by entering these commands:
# Analyze timing with ideal clocks (pre-CTS stage)
timeDesign -preCTS -outDir reports/preCTS

# Save the top 5 worst timing paths to a report file
report_timing -max_paths 5 > reports/preCTS_timing.rpt

What do these reports tell you?

The timeDesign -preCTS command analyzes all timing paths using ideal clocks (no skew or insertion delay). It reports WNS (Worst Negative Slack) and TNS (Total Negative Slack) for each clock group.

The report_timing command saves detailed path information to reports/preCTS_timing.rpt. Look at the console summary for WNS values on both wclk and rclk path groups.

  • Check the console output for the WNS summary. You want to see values close to zero or positive for both wclk (2ns period) and rclk (3ns period) path groups.

What if WNS is negative?

Small negative slack (within 200ps) at this stage is acceptable. CTS adds buffer delays that shift timing, and post-CTS optimization will handle remaining violations. If WNS is worse than -200ps, the next optimization command addresses it.

  • Run incremental pre-CTS optimization and verify design integrity by entering these commands:
# Run incremental pre-CTS optimization to fix timing violations
optDesign -preCTS

# Verify no placement violations remain
checkDesign -all

What does optDesign -preCTS do?

This command performs incremental optimization. It resizes cells, swaps cell variants, and adjusts placement to improve timing without disrupting the overall placement quality. It targets the worst violating paths first.

The checkDesign -all command reports any physical issues: overlapping cells, cells outside the core boundary, or unconnected pins. You want zero violations here.

Before you check the result, what do you expect checkDesign -all to report? Think about whether any cells would have placement issues after optimization.

  • Look at the Innovus console output from checkDesign -all. You should see no placement violations reported. If violations appear, Innovus lists the specific cells and violation types in the console.

Seeing placement violations after optimization?

  • Overlap violations can occur if optimization resized cells into neighbors. Run refinePlace to legalize any overlapping cells.
  • If you see cells placed outside the core boundary, your utilization may be too high. Verify the core area can hold all cells by checking the placement density in Physical View.

Help me fix placement violations after pre-CTS optimization.

  • Capture a screenshot of the cell placement density. In the Innovus GUI, switch to Physical View (amoeba/density view) showing the placed design. This screenshot goes into your project report as evidence of completed placement.

✔️ Awesome, I've got everything!

Great. Double check that your timing report shows WNS close to zero or positive for both clock groups, and that checkDesign -all returned zero violations.

ⓧ I'd like to double check the full command sequence

Here is the complete sequence of commands you should have run in this step, in order:

# Set routing layer constraints
setDesignMode -bottomRoutingLayer 1
setDesignMode -topRoutingLayer 7

# Run timing-driven placement
place_opt_design

# Pre-CTS timing analysis
timeDesign -preCTS -outDir reports/preCTS
report_timing -max_paths 5 > reports/preCTS_timing.rpt

# Incremental optimization
optDesign -preCTS

# Verify placement integrity
checkDesign -all

All 4434 cells are now legally placed with timing-driven optimization, and your pre-CTS timing is clean. Next up, you will build dual clock trees for wclk and rclk using CCOpt, giving your two independent clock domains the balanced skew they need for proper CDC operation.

Clock Tree Synthesis (Dual-Clock CCOpt)

Your design has two independent clock domains: wclk at 500MHz and rclk at 333MHz. Without proper clock trees, skew between flip-flops in the same domain causes hold violations, and insertion delay differences between domains corrupt CDC timing.

In this step, you will use CCOpt (Clock Concurrent Optimization) to build balanced clock trees for both domains simultaneously. CCOpt reads your SDC constraints, identifies both clocks, and inserts buffers to minimize skew across all registers in each domain.

In this step, get ready to:
  • Create a clock tree specification and run CCOpt to build balanced trees for wclk and rclk.
  • Analyze post-CTS timing and fix hold violations across both clock domains.
  • Capture the CTS diagram from the Clock Tree Debugger for your project report.
Create clock tree specification and run CTS

The create_ccopt_clock_tree_spec command reads your SDC file and auto-detects all clock definitions. For your design, it will find wclk with a 2ns period and rclk with a 3ns period, then create appropriate skew groups for each.

  • Extract the clock tree specification from your SDC constraints by running this command in the Innovus console:
create_ccopt_clock_tree_spec

What does this command do?

This command parses your SDC constraints and identifies every clock source in the design. It creates internal data structures that tell CCOpt how to build each tree: which clock pins to drive, what the target skew should be, and which flip-flops belong to each clock domain.

You should see console output listing two clocks detected: wclk (period 2ns) and rclk (period 3ns).

Not seeing both clocks listed?

Confirm your SDC file has create_clock definitions for both wclk and rclk. If the SDC only defines one clock, Innovus cannot build both trees.

help me debug why create_ccopt_clock_tree_spec only finds one clock in my dual-clock FIFO hub design

With the spec created, CCOpt knows exactly what trees to build. The next command performs the actual clock tree synthesis, inserting buffers and inverters to deliver balanced clock signals to all 4434 cells.

  • Run CCOpt to build both clock trees by running:
ccopt_design

What does ccopt_design do?

This is the main CTS engine. It simultaneously builds and optimizes clock trees for all detected clock domains. For your 4434-cell design with two clock domains, this should complete in 1-3 minutes.

CCOpt inserts clock buffers at calculated positions to balance the propagation delay from the clock source to every register. It handles both wclk and rclk trees independently, targeting minimum skew within each domain.

Watch the console output as CCOpt runs. You should see messages about buffer insertion, skew optimization iterations, and a completion summary for both clock trees.

CTS taking longer than 5 minutes?

For a 4434-cell design, CTS should not exceed 3 minutes. If it stalls, check that your placement completed cleanly in the previous step. CTS struggles when there is not enough whitespace to insert buffer cells.

help me debug why ccopt_design is running very slowly on my multi_channel_fifo_hub design

Post-CTS optimization and hold fixing

With clock trees in place, the timing picture changes. Clocks now have real propagation delay and skew instead of ideal behavior. You need to analyze timing with these propagated clocks and fix any hold violations that appear.

  • Analyze post-CTS setup timing by running:
timeDesign -postCTS -outDir reports/postCTS
  • Analyze post-CTS hold timing by running:
timeDesign -postCTS -hold -outDir reports/postCTS_hold

Why check both setup and hold?

Setup timing ensures data arrives before the next clock edge. Hold timing ensures data stays stable long enough after the current clock edge. CTS often introduces hold violations because buffer insertion changes the relative timing between data and clock paths.

For your dual-clock design, paths crossing between wclk and rclk domains are especially sensitive to hold violations because the two clock trees have different insertion delays.

The hold timing report will likely show negative slack on some paths. This is expected after CTS. The next command fixes these violations by inserting delay buffers on the short data paths.

  • Fix hold violations by running:
optDesign -postCTS -hold

What does hold fixing do?

This command inserts delay buffers on paths where data arrives too quickly relative to the clock. It targets specifically the hold-violating paths reported by the previous timeDesign command, adding just enough delay to meet hold constraints without breaking setup timing.

After hold fixing completes, generate the CTS quality reports to confirm both clock trees meet their skew targets.

  • Generate the clock tree summary report by running:
report_ccopt_clock_trees -summary > reports/cts_summary.rpt
  • Generate the skew groups report by running:
report_ccopt_skew_groups > reports/cts_skew.rpt

What do these reports tell you?

The clock tree summary shows the number of buffers inserted, total wire length, and achieved skew for each clock domain. The skew groups report breaks this down per clock group, showing which sets of registers CCOpt balanced together.

Confirm that both wclk and rclk appear in the summary with their target skew values met.

Now capture the visual CTS diagram for your project report. The Clock Tree Debugger gives you a schematic view of buffer stages and fan-out for each tree.

  • In the Innovus GUI, go to Clock in the menu bar.
  • Select CCOpt Clock Tree Debugger.
  • Select wclk to view the write-clock tree schematic showing buffer stages and fan-out.
  • Take a screenshot of the wclk clock tree diagram.
  • Select rclk to view the read-clock tree schematic.
  • Take a screenshot of the rclk clock tree diagram.

Alternative CTS visualization

You can also view the clock tree topology by running gui_select_clock wclk in the console, then going to View > Clock Tree Browser for a graphical topology view.

Before you verify the final timing, predict what you expect to see. Do you think setup WNS will be positive for both clock domains after CTS and hold fixing?

  • Confirm both clock trees pass their targets by running:
report_ccopt_clock_trees -summary

You should see both wclk and rclk listed with target skew met. The post-CTS setup WNS should be positive, and hold WNS should be close to zero or positive after optimization.

Seeing negative WNS after hold fixing?

If setup WNS went negative after hold fixing, the inserted delay buffers may have affected setup paths. Run optDesign -postCTS (without -hold) to re-optimize setup timing. Small remaining violations will be addressed during post-route optimization in the next step.

help me debug negative WNS after post-CTS hold fixing in my dual-clock FIFO design

Both clock trees are built and balanced. Your design now has real, propagated clocks driving all 4434 cells with controlled skew across both domains. Next up, you will route all the signal connections and verify the design is DRC-clean and ready for GDSII export.

Routing, Verification, and GDSII Export

Your dual clock trees are balanced and hold violations are fixed. The cells know where they live and the clocks arrive on time.

But every signal between those cells is still floating in air. NanoRoute will draw the actual metal wires that connect them. Without clean DRC and verified connectivity, your layout cannot be manufactured. This step takes you from a placed design to a tapeout-ready GDSII file.

In this step, get ready to:
  • Route all signals with NanoRoute and run post-route optimization.
  • Verify DRC and connectivity with zero violations.
  • Export the tapeout-ready GDSII file and save all design artifacts.
Configure NanoRoute and route all signals

NanoRoute needs to know which metal layers are available for signal wires. You already reserved M8 and M9 for power in Step 1. Now you constrain the router to M1 through M7 and enable antenna rule fixing to prevent charge damage during fabrication.

  • In the Innovus console, configure NanoRoute and run the global and detailed routing by entering these commands:
# Constrain routing to signal layers only (M1-M7)
setNanoRouteMode -routeTopRoutingLayer 7
setNanoRouteMode -routeBottomRoutingLayer 1

# Fix antenna violations during routing
setNanoRouteMode -drouteFixAntenna true

# Run global and detailed routing
routeDesign -globalDetail

What do these commands do?

The setNanoRouteMode commands tell the router to only use M1 through M7 for signals. M8 and M9 are already occupied by your power rings and stripes.

The -drouteFixAntenna true flag tells NanoRoute to automatically insert antenna diodes or jog wires when a long metal run would accumulate charge during manufacturing. Without this, static charge can destroy gate oxides.

The routeDesign -globalDetail command performs both global routing (coarse path planning) and detailed routing (exact track assignment) in one pass. For 4434 cells, this typically completes in 1-3 minutes.

  • Wait for routing to complete. You should see a summary in the console showing the number of routed nets, any remaining violations, and total wirelength.

Routing taking too long or showing errors?

  • If routing fails with layer errors, confirm your top routing layer is 7 (not 9). Layers 8 and 9 must stay reserved for power.
  • If you see a large number of DRC violations reported during routing, that is normal at this stage. Post-route optimization in the next chunk will resolve most of them.

Why is NanoRoute reporting violations after routing?

Run post-route optimization

Routing introduces real parasitics that shift timing. On-chip variation (OCV) means cells on the same die run at slightly different speeds. You need to enable OCV analysis and let Innovus re-optimize both setup and hold timing with the actual routed parasitics.

  • Run post-route optimization with OCV enabled by entering these commands:
# Enable on-chip variation for realistic timing analysis
setAnalysisMode -analysisType onChipVariation

# Optimize setup timing with routed parasitics
optDesign -postRoute

# Fix hold violations introduced by routing
optDesign -postRoute -hold

What does OCV analysis do?

On-chip variation accounts for the fact that two identical cells on the same die may run at different speeds due to manufacturing imperfections. By enabling onChipVariation mode, Innovus applies pessimistic derating to timing paths, making its optimization more conservative and your design more robust.

The optDesign -postRoute pass fixes setup violations by resizing cells or rebuffering. The optDesign -postRoute -hold pass inserts delay buffers to fix hold violations. This is especially important for your CDC paths between wclk and rclk domains.

  • Wait for both optimization passes to complete. The console will report how many violations were fixed and the updated WNS (Worst Negative Slack) values.

Still seeing negative WNS after optimization?

  • Small negative slack (within 50ps) may be acceptable depending on your timing margin. The verification step below confirms whether timing is truly closed.
  • If WNS is significantly negative (more than 200ps), try running optDesign -postRoute a second time. Incremental optimization can catch paths the first pass missed.

Help me debug negative slack after post-route optimization.

Verify DRC, connectivity, and timing signoff

A routed design is meaningless if it violates manufacturing rules or has broken connections. This is the moment of truth. You will run physical verification and generate the timing reports that prove your design is silicon-ready.

Before you run the verification commands, what do you expect to see? If your routing and optimization succeeded, both DRC and connectivity should report zero violations.

  • Run DRC and connectivity verification by entering these commands:
# Check for design rule violations
verify_drc -report reports/drc.rpt

# Verify all signals are properly connected
verify_connectivity -type all -report reports/conn.rpt

What are DRC and connectivity checks?

DRC (Design Rule Check) verifies that your metal wires meet the foundry's manufacturing rules. These include minimum spacing between wires, minimum metal width, and via enclosure requirements. A single DRC violation can make a chip unfabricable.

Connectivity check confirms that every pin on every cell is connected to the correct net. An open connection means a signal never arrives. A short means two signals collide.

  • Check the console output. Both commands should report zero violations. You can also inspect reports/drc.rpt and reports/conn.rpt for the detailed results.

Seeing DRC or connectivity violations?

  • A small number of DRC violations (1-5) can often be fixed by running optDesign -postRoute once more, then re-running verify_drc.
  • Connectivity violations usually indicate a routing blockage or missing special net connection. Check that your sroute from Step 1 completed without errors.

Help me fix DRC violations in my routed design.

  • Generate post-route timing and power reports by entering these commands:
# Post-route setup timing analysis
timeDesign -postRoute -outDir reports/postRoute

# Post-route hold timing analysis
timeDesign -postRoute -hold -outDir reports/postRoute_hold

# Detailed report of top 10 critical paths
report_timing -max_paths 10 > reports/final_timing.rpt

# Power consumption report
report_power > reports/power.rpt

What should the timing reports show?

The timeDesign -postRoute report shows setup timing. WNS (Worst Negative Slack) should be positive for both wclk and rclk path groups, meaning all setup constraints are met.

The timeDesign -postRoute -hold report shows hold timing. Positive WNS here confirms that no data arrives too early at any flip-flop. This is critical for your CDC paths between the 500MHz wclk and 333MHz rclk domains.

  • Check the timing summary printed in the console. Confirm that WNS is positive (or zero) for both setup and hold across the wclk and rclk path groups.
Export GDSII and save design artifacts

With zero DRC violations and positive timing slack, your design is ready for tapeout. The GDSII file is the industry-standard format that the foundry uses to create photomasks. You will also save the Innovus database, the post-route netlist, and the SDF timing file for gate-level simulation.

  • Export all design artifacts by entering these commands:
# Export GDSII layout for tapeout
streamOut outputs/multi_channel_fifo_hub.gds -mapFile /path/to/scl90nm_gds.map -libName DesignLib -units 2000 -mode ALL

# Save Innovus design database for future edits
saveDesign outputs/multi_channel_fifo_hub_final.enc

# Export post-route netlist for gate-level simulation
saveNetlist outputs/multi_channel_fifo_hub_routed.v

# Export timing annotation for simulation
write_sdf outputs/multi_channel_fifo_hub.sdf

What are these output files?

  • The .gds file contains the physical geometry of every metal layer and via. This is what the foundry reads to make your chip.
  • The .enc database is Innovus's native format. You can reopen it anytime for ECO fixes or further analysis.
  • The _routed.v netlist and .sdf file work together for post-layout gate-level simulation. The SDF annotates real delays onto each cell and net so your simulation reflects actual silicon timing.
  • Confirm the exports completed by checking the console output. You should see confirmation messages for each file written to the outputs/ directory.

StreamOut failing or file not written?

  • If streamOut fails with a map file error, verify that the path to scl90nm_gds.map matches your college server's PDK installation path.
  • If the outputs/ directory does not exist, create it first with exec mkdir -p outputs in the Innovus console, then re-run the export commands.

Help me fix my GDSII export in Innovus.

Now capture the final screenshot for your project report.

  • In the Innovus GUI, switch to Physical View with all layers visible.
  • Press f to zoom to fit the entire design.
  • Take a screenshot showing the fully routed layout with power grid, placed cells, and signal routing all visible. This is your "physical design completed" image for the report.

✔️ Awesome, I've got everything!

Great. Confirm you have saved all files and that your Innovus console shows no errors from the export commands.

ⓧ I'd like to double check the full command sequence

Here is the complete sequence of commands you ran in this step. Scroll up and confirm each group is present in your Innovus console history, in order:

  • NanoRoute configuration: setNanoRouteMode commands (top layer 7, bottom layer 1, antenna fix true) followed by routeDesign -globalDetail.
  • Post-route optimization: setAnalysisMode -analysisType onChipVariation, then optDesign -postRoute and optDesign -postRoute -hold.
  • Physical verification: verify_drc -report reports/drc.rpt and verify_connectivity -type all -report reports/conn.rpt.
  • Timing reports: timeDesign -postRoute, timeDesign -postRoute -hold, report_timing, and report_power.
  • GDSII export: streamOut, saveDesign, saveNetlist, and write_sdf.

Your multi-channel async FIFO hub is now a tapeout-ready GDSII layout. You took 4434 cells from a flat netlist to a DRC-clean, timing-closed chip with dual clock trees and a complete power grid. If you want to push further, the Secret Mission challenges you to run post-route STA with OCV derating and prove timing robustness across your clock domain crossings.

Secret mission

Post-Route STA with OCV Analysis

Your design passes timing with ideal assumptions, but real silicon is messier. Cells on the same die run at slightly different speeds due to manufacturing variation. Can your dual-clock CDC design survive that?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely on your college's Cadence license with local files, so there are no ongoing costs.

Resources you used:

  • GDSII layout file: outputs/multi_channel_fifo_hub.gds
  • Saved Innovus design database: outputs/multi_channel_fifo_hub_final.enc
  • Post-route gate-level netlist: outputs/multi_channel_fifo_hub_routed.v
  • Standard Delay Format file: outputs/multi_channel_fifo_hub.sdf
  • Timing and verification reports in the reports/ directory.
  • Innovus temporary files (timingReports/, *.logv files) in the working directory.

Keep everything running

No action needed. Choose this if you are still actively working on your physical design or plan to perform ECO fixes.

  • Your saved .enc database can be reopened in Innovus anytime for further analysis or incremental changes.
  • Reopen the design by running:
innovus -64 -init outputs/multi_channel_fifo_hub_final.enc
  • All reports, netlists, and the GDSII file remain in place for your project report.

Pause - I'll come back to this later

Archive the essential output files to your home directory and remove large temporary files to free disk space.

  • Copy the outputs/ directory to your home folder for safekeeping:
cp -r outputs/ ~/multi_channel_fifo_hub_outputs/
  • Copy the key reports you need for your project submission:
cp -r reports/ ~/multi_channel_fifo_hub_reports/
  • Remove Innovus temporary files that consume disk space:
rm -rf timingReports/
rm -f *.logv
  • Your design outputs are safe in your home folder. You can restore the full working directory from the .enc database when you return.

Delete - I don't want to use this again

Remove all project files from the working directory. Only do this after you have submitted your report and no longer need the design data.

  • Navigate up to the parent of your pnr/ working directory:
cd ..
  • Remove the entire PnR working directory, including all outputs, reports, and temporary files:
rm -rf pnr/
  • Confirm the directory is gone:
ls pnr/
  • You should see a "No such file or directory" message, confirming the removal.
  • This removes the GDSII file, the saved Innovus database, the post-route netlist, the SDF file, all reports, and all Innovus temp files.

That's a Wrap!

That's a Wrap!

Nice work! You have taken a dual-clock, 4-channel asynchronous FIFO hub from a synthesized netlist all the way to a tapeout-ready GDSII layout using Cadence Innovus and the SCL 90nm process.

You've learned how to:

  • Import a gate-level netlist into Innovus, create a floorplan with 70% utilization, and build a power distribution network with rings and stripes on M8/M9.
  • Build two independent clock trees (wclk at 500MHz, rclk at 333MHz) using CCOpt with balanced skew across both domains and fix hold violations on CDC paths.
  • Route all signals with NanoRoute, achieve zero DRC violations and clean connectivity, and export a tapeout-ready GDSII file for your multi-channel asynchronous FIFO hub.
  • Secret Mission: Performed post-route OCV analysis with early/late derating and signal integrity, proving timing robustness across clock domain crossings.

Ready to quiz yourself?