ECO on Optimized Away Wires

Abstract

This use case shows how to use Gates On the Fly to find optimized away wires in netlist and do ECO on them. Wire names in RTL codes are normally optimized away in synthesis process. It makes manual ECO very difficult even the ECO changes in RTL codes are very small. One method GOF provides is to use the fully interactive incremental schematic which makes it easy to trace fanin fanout of logic. In this use case, we demonstrate how to use the build-in Logic Equivalence Check engine to find the renamed wires in the netlist.

Manual ECO scenario

An ECO changes a case statement in RTL code as following,

RTL code before ECO

always @(*) begin
  if(enable)begin
    case (ctrl_bits[11:0])
      12'h01f : next_data[8:0] = cnt_0[8:0];
      12'h03f : next_data[8:0] = cnt_1[8:0];
      12'h07f : next_data[8:0] = cnt_2[8:0];
      12'h0ff : next_data[8:0] = cnt_3[8:0];
      12'h1ff : next_data[8:0] = cnt_4[8:0];
      12'h3ff : next_data[8:0] = cnt_5[8:0];
      12'h7ff : next_data[8:0] = cnt_6[8:0];
      12'hfff : next_data[8:0] = cnt_7[8:0];
      default : next_data[8:0] = 9'h0;
    endcase
  end
  else begin
    next_data[8:0] = start ? cnt_8[8:0] : 9'h0;
  end
end

RTL code after ECO

always @(*) begin
  if(enable)begin
    case (ctrl_bits[11:0])
      12'h21f : next_data[8:0] = cnt_0[8:0];
      12'h03f : next_data[8:0] = cnt_1[8:0];
      12'h27f : next_data[8:0] = cnt_2[8:0];
      12'h0ff : next_data[8:0] = cnt_3[8:0];
      12'h1ff : next_data[8:0] = cnt_4[8:0];
      12'h3ff : next_data[8:0] = cnt_5[8:0];
      12'h7ff : next_data[8:0] = cnt_6[8:0];
      12'hfff : next_data[8:0] = cnt_7[8:0];
      default : next_data[8:0] = 9'h0;
    endcase
  end
  else begin
    next_data[8:0] = start ? cnt_8[8:0] : 9'h0;
  end
end

Pinpoint ECO location

The ECO is to find the two specific cases and manually change the logic with minium gate number. So we have to find the wires that represent the two cases.

Create a new RTL to have specific wire names to represent the cases

...
 // Put the specific net in output port, so that it won't be optimized away
 output reg [9:0] preserve_nets;
 always @(*) begin
  preserve_nets = 'h0;
  case (state)
    `COUNT: begin
      case (packet_ctrl[11:0])
        12'h21f : preserve_nets[0] = 1;
        12'h03f : preserve_nets[1] = 1;
        12'h27f : preserve_nets[2] = 1;
        12'h0ff : preserve_nets[3] = 1;
        12'h1ff : preserve_nets[4] = 1;
        12'h3ff : preserve_nets[5] = 1;
        12'h7ff : preserve_nets[6] = 1; 
        12'hfff : preserve_nets[7] = 1;
        default : preserve_nets[8] = 1;
        endcase
      end
    default: begin
      preserve_nets[9] = 1;
    end
 end
 ...
 

Bringup Schematic with gates driving 'preserve_nets' in the reference RTL

   #Example code to bringup GUI window and schematic
   read_library("hvt.lib", "svt.lib");
   read_rtl("-ref", "reference.v");
   read_design("-imp", "implement.v");
   set_top("topmod");
   preserve_modules("-all");
   elaborate;
   start_gui;

Figure 1. Find equivalent nets

Activate Finding Logic Equivalent Nets

Select pin that drives 'preserve_nets', click mouse-right-button to popup menu, select 'List Logic Equivalent Nets' command. A popup window displays the nets in implementation netlist that are equal or inverted to the net in comparison

Figure 2. List Equivalent and Inverted nets for 'preserve_nets[2]'

Figure 3. List Equivalent and Inverted nets for 'preserve_nets[0]'

Analyze and do ECO correspondingly

From the RTL change above, net 'packet_ctrl[9]' should be inverted to driven instance 'p76429A'. However, after fanin/fanout tracing, we find that the instance drives two other instances 'p54164A' and 'p76597A' who should keep 'packet_ctrl[9]' NOT inverted. So three instances, 'p76429A', 'p54192A' and 'p76420A' should be cloned and drive 'p54164A' and 'p76597A'.

Figure 4. Incremental schematic for related ECO logic

ECO Script

The ECO can be done in GUI mode, see this GUI ECO example.

GofCall Script to do the ECO is listed below, click the ECO API for detail API usage

# GofCall ECO script to fix case statement ECO, ECO Name: eco_9877 File Name: fix_case.pl
undo_eco;
setup_eco("eco_9877");
new_gate("n_21_eco_9877_clone", "INR3XD0H", "p76429A_eco_9877_clone", 
         ".A1(p76429A/A1),.B1(p76429A/B1),.B2(p76429A/B2)");
new_gate("n_24_eco_9877_clone", "IIND4D1H", "p76420A_eco_9877_clone", 
         ".A1(p76420A/A1),.A2(p76420A/A2),.B1(n_21_eco_9877_clone),.B2(p76420A/B2)");
new_gate("n_29_eco_9877_clone", "ND2XD0H", "p54192A_eco_9877_clone", 
         ".A1(p54192A/A1),.A2(n_21_eco_9877_clone)");
change_pin("p54164A/A1", "n_29_eco_9877_clone");
change_pin("p76597A/I", "n_24_eco_9877_clone");
change_pin("p76429A/B2", "INVD1H", "", "-");
write_verilog("implementation_eco_9877.v");

Apply the script

Verify the ECO

After the script is applied, in GOF shell command entry, enter 'sch("p76429A")'. When the schematic window is up, do fanin/fanout trace. We can see from Figure 5 that the ECO is done correctly

Figure 4. Incremental schematic for related ECO logic'

Check another exmaple here


Follow us:
NanDigits.com US | NanDigits.cn China
© 2024 NanDigits Design Automation. All rights reserved.