Typically, in a metal only ECO, the available spare gate types include INV, AND, NAND, OR, NOR, XOR, XNOR, MUX, and Flop. In some cases, certain ECO may require the conversion of overflowed gate types to other spare types. Additionally, there are designs where only INV, MUX, and Flop types are available as spare gates. However, mapping random ECO logic to MUX-only logic can be a challenge for the synthesis engine. Thankfully, GOF offers a solution to this issue.
By reconnecting the input pins, it is possible to map AND, OR, and XOR gate types to MUX. Similarly, NAND, NOR, and XNOR can also be mapped to MUX gate types.
The conversion is demonstrated in Figure 1.
Figure 1: Convert AND/OR/XOR spare gates to MUX
To convert ECO logic to MUX-only logic using GOF, two rounds of spare gates mapping are employed. In the first round, the automatic functional ECO patch is initially mapped to AND, OR, XOR, and MUX types. Subsequently, GOF replaces the AND, OR, and XOR types with MUX, based on the mapping technique illustrated in the above figure. This generates a patch with MUX-only logic.
In the second round, the LEF/DEF files are read, and spare gate instances with INV, MUX, and Flop types are extracted from the netlist. The MUX-only patch is then mapped to the actual physical spare MUX gates, and all MUXs are replaced with the appropriate spare MUX gates.
The flow is shown in Figure 2.
Figure 2: Metal Only ECO Flow with MUX Spare Gates
The detail script for spare gates conversion:
read_library("stdlib.lib"); 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("-imp", "netlist_under_eco.v"); read_design("-ref", "netlist_reference.v"); set_top("chip_top"); fix_design; report_eco; # First round of spare gates mapping set_constraints("-type", "TIELO_X1M,AND2_X0P5M,OR2_X0P5B,XOR2_X0P5M,MX2_X4B,INV_X0P5B"); map_spare_cells(); report_eco; # Convert AND/OR/XOR to MUX my @cells = get_cells("-new", "-hier"); foreach my $cell (@cells){ my $ref = get_ref($cell); print "Change $cell $ref to mux\n"; if($ref =~ m/^AND/){ change_gate($cell, "MX2_X4B", ".A(1'b0),.B(B),.S0(A)"); }elsif($ref =~ m/^OR/){ change_gate($cell, "MX2_X4B", ".A(B),.B(1'b1),.S0(A)"); }elsif($ref =~ m/^XOR/){ my $inv = new_gate("", "INV_X0P5B", "", "$cell/B"); # invert B input change_gate($cell, "MX2_X4B", ".A(B),.B($inv/Y),.S0(A)"); } } report_eco; # Second round of spare gates mapping read_lef("$cdir/h40.lef"); read_def("$depth/def/chip_top.def"); get_spare_cells("Spare_*/*_SPARE_GATE*"); map_spare_cells; report_spares; report_eco; write_verilog("eco_chip_top.v");