NanDigits Design Automation

Multi-stages ECO: From Hours to Minutes with GOF's Single Script Approach

Large, complex functional netlist ECOs normally require several slow, full-scale fixes on the pre-layout, DFT, and post-layout netlists. This redundant and time consuming approach significantly extends project timelines.

The GOF Difference: A Single, Fast ECO Script

Diagram of a netlist ECO flow with three stages.
The GOF ECO flow, showing a single script applied to multiple netlists for fast execution.

The GOF platform introduces a paradigm shift by generating a single, intelligent ECO script after the initial functional ECO is run on re-synthesized netlist vs pre-layout netlist. This script is then used to perform a fast, efficient fix on the subsequent netlists, DFT netlist and post-layout netlist, rather than a full scale ECO from scratch. It only takes several minutes by applying the ECO script comparing several hours with the full scale ECO run by using reference netlist. This method is drastically faster, allowing the same script to be applied seamlessly to both the DFT and post-layout netlists.

The following script is an example of a GOF output ECO script. It reads in the reference and implementation netlists, performs the necessary fixes, and then saves the session and writes a final Perl script that can be applied to the post-layout netlist for a fast run.

use strict;
setup_eco("eco_example");# Setup ECO name
read_library("tsmc.lib");# Read in standard library
read_svf("-ref", "reference.svf.txt"); # Optional, must be loaded before read_design, must be in text format
read_svf("-imp", "implementation.svf.txt"); # Optional, must be loaded before read_design, must be in text format
read_design('-ref', 'mpu_block_new_syn.v');# Read in block level Reference Netlist, B0 in Figure 1
read_design('-imp', 'mpu_block_pre.v');# Read in prelayout block level Implementation Netlist, B1 in Figure 1
set_top('MPU');# Set the top module to MPU
set_ignore_output("scan_out*"); # The block level DFT signals may have different names
set_pin_constant("scan_enable", 0);
set_pin_constant("scan_mode", 0);
fix_design;
save_session("current_eco_name"); # Save a session for future restoration
write_perl('mpu_block.gpl'); # ECO script will apply to large post-layout netlist
exit;

AI-Powered Problem Solving

A major challenge arises when the post-layout netlist undergoes optimization, causing instances and nets to be renamed or removed. A standard ECO script referencing the original names would fail. GOF addresses this with an integrated AI agent that can read both the pre-layout and post-layout netlists. The AI identifies optimization locations and intelligently maps the original instance and net names from the ECO script to their new names in the post-layout netlist. This innovative AI assistance ensures that the ECO script remains effective and accurate.

AOI cell was optimized to AND and NOR gates in post-layout netlist.
The schematic shows AOI21X1 (U540) was optimized to AND2X2 (FE_IC_124) and NOR2X1 (FE_IC_123)

With this prompt to LLM and answer, it's easy to figure out the optimized instance/pin name in the post-layout netlist. GOF ECO can automatically find out the missing instance/pin names in the ECO script and update them with the right ones. The prompt can be copied and pasted in ChatGPT or Gemini to reproduce the result.

You are netlist expert. You are given a partial Reference Netlist and a partial Implementation 
Netlist. Figure out the mapping instance and pin among two netlists: ```Reference-Netlist { "instance": "U537e0", "module": "OAI32X1", "netlist_name": "REF", "function": "Y = (!((A0+A1+A2)*(B0+B1)));", "connections": {"A0":"n394", "A1":"n385", "A2":"n392", "B0":"state[0]", "B1":"n400", "Y":"n397e0"} } { "instance": "U531", "module": "AND2X1", "netlist_name": "REF", "function": "Y = (A*B);", "connections": {"A":"n392", "B":"n393", "Y":"n391"} } { "instance": "U540", "module": "AOI21X1", "netlist_name": "REF", "function": "Y = (!((A0*A1)+B0));", "connections": {"A0":"n403", "A1":"state[0]", "B0":"n395", "Y":"n392"} } { "instance": "U537", "module": "OAI32X1", "netlist_name": "REF", "function": "Y = (!((A0+A1+A2)*(B0+B1)));", "connections": {"A0":"n399", "A1":"n358", "A2":"n392", "B0":"state[0]", "B1":"n400", "Y":"n397"} } ``` ```Implementation-Netlist { "instance": "U537e0", "module": "OAI32X1", "netlist_name": "IMP", "function": "Y = (!((A0+A1+A2)*(B0+B1)));", "connections": {"A0":"n394", "A1":"n385", "A2":"FE_ND_789", "B0":"state[0]", "B1":"n400", "Y":"n397e0"} } { "instance": "FE_IC_123", "module": "NOR2X1", "netlist_name": "IMP", "function": "Y = (!(A+B));", "connections": {"A":"FE_NE_345", "B":"n395", "Y":"FE_ND_789"} } { "instance": "U531", "module": "AND2X1", "netlist_name": "IMP", "function": "Y = (A*B);", "connections": {"A":"FE_ND_789", "B":"n393", "Y":"n391"} } { "instance": "FE_IC_124", "module": "AND2X2", "netlist_name": "IMP", "function": "Y = (A*B);", "connections": {"A":"n403", "B":"state[0]", "Y":"FE_NE_345"} } { "instance": "U537", "module": "OAI32X1", "netlist_name": "IMP", "function": "Y = (!((A0+A1+A2)*(B0+B1)));", "connections": {"A0":"n399", "A1":"n358", "A2":"FE_ND_789", "B0":"state[0]", "B1":"n400", "Y":"n397"} } { "instance": "U551", "module": "NOR2X1", "netlist_name": "IMP", "function": "Y = (!(A+B));", "connections": {"A":"n407", "B":"n405", "Y":"n395"} } { "instance": "FE_DI_yt5670", "module": "AOI21X1", "netlist_name": "IMP", "function": "Y = (!((A0*A1)+B0));", "connections": {"A0":"FE_ND_789", "A1":"n393", "B0":"n397e0", "Y":"FE_DE_t78"} } ``` Find out the corresponding instance pin in the Implementation Netlist for U540/Y in the Reference Netlist.
Return in JSON format with 'map_to' field. For example ```json { 'map_to': 'U112233/Y'} ```

The answer from LLM is

{
  "map_to": "FE_IC_123/Y"
}