350
Graduate eses and Dissertations Iowa State University Capstones, eses and Dissertations 2018 Design and verification approaches for reliability and functional safety of analog integrated circuits Zhiqiang Liu Iowa State University Follow this and additional works at: hps://lib.dr.iastate.edu/etd Part of the Electrical and Electronics Commons is Dissertation is brought to you for free and open access by the Iowa State University Capstones, eses and Dissertations at Iowa State University Digital Repository. It has been accepted for inclusion in Graduate eses and Dissertations by an authorized administrator of Iowa State University Digital Repository. For more information, please contact [email protected]. Recommended Citation Liu, Zhiqiang, "Design and verification approaches for reliability and functional safety of analog integrated circuits" (2018). Graduate eses and Dissertations. 17246. hps://lib.dr.iastate.edu/etd/17246

Design and verification approaches for reliability and

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Design and verification approaches for reliability and

Graduate Theses and Dissertations Iowa State University Capstones, Theses andDissertations

2018

Design and verification approaches for reliabilityand functional safety of analog integrated circuitsZhiqiang LiuIowa State University

Follow this and additional works at: https://lib.dr.iastate.edu/etd

Part of the Electrical and Electronics Commons

This Dissertation is brought to you for free and open access by the Iowa State University Capstones, Theses and Dissertations at Iowa State UniversityDigital Repository. It has been accepted for inclusion in Graduate Theses and Dissertations by an authorized administrator of Iowa State UniversityDigital Repository. For more information, please contact [email protected].

Recommended CitationLiu, Zhiqiang, "Design and verification approaches for reliability and functional safety of analog integrated circuits" (2018). GraduateTheses and Dissertations. 17246.https://lib.dr.iastate.edu/etd/17246

Page 2: Design and verification approaches for reliability and

Design and verification approaches for reliability and functional

safety of analog integrated circuits

by

Zhiqiang Liu

A dissertation submitted to the graduate faculty

in partial fulfillment of the requirements for the degree of

DOCTOR OF PHILOSOPHY

Major: Electrical Engineering

Program of Study Committee:

Degang Chen, Major Professor

Randall Geiger

Chris Chong-Nuen Chu

Jiming Song

Ratnesh Kumar

The student author, whose presentation of the scholarship herein was approved by the

program of study committee, is solely responsible for the content of this dissertation. The

Graduate College will ensure this dissertation is globally accessible and will not permit

alterations after a degree is conferred.

Iowa State University

Ames, Iowa

2018

Copyright © Zhiqiang Liu, 2018. All rights reserved.

Page 3: Design and verification approaches for reliability and

ii

DEDICATION

To my family

Page 4: Design and verification approaches for reliability and

iii

TABLE OF CONTENTS

Page

LIST OF FIGURES ................................................................................................................. vi

LIST OF TABLES ................................................................................................................... ix

ACKNOWLEDGMENTS ........................................................................................................ x

ABSTRACT ............................................................................................................................. xi

CHAPTER 1. INTRODUCTION ............................................................................................. 1

1.1 Background and Motivation .......................................................................................... 1 1.2 Organization of Dissertation .......................................................................................... 6

1.3 References ..................................................................................................................... 9

CHAPTER 2. DESIGN OF LOW TEMPERATURE-COEFFICIENT BANDGAP

REFERENCE .......................................................................................................................... 11 2.1 Introduction ................................................................................................................. 11 2.2 Curvature Compensation and General Concept of VGO extractor................................ 15

2.2.1 Temperature Characteristic of VBE ...................................................................... 15 2.2.2 Curvature Compensation Approaches ................................................................. 17

2.2.3 VGO Extraction in General ................................................................................. 20 2.2.4 Discussion ........................................................................................................... 22

2.3 One Implementation of Proposed Voltage Reference Generator ................................ 23 2.3.1 Generation of Nonlinear Term Containing TlnT ................................................ 23

2.3.2 VGO Extraction ................................................................................................... 25 2.4 Discussion of Non-Ideal Error Source ......................................................................... 28

2.4.1 Temperature dependence of resistors (TCR)....................................................... 28

2.4.2 Temperature dependence of BJT current gain .................................................... 29 2.4.3 Opamp offset ....................................................................................................... 30

2.5 Simulation Results ....................................................................................................... 33

2.6 Conclusion ................................................................................................................... 35 2.7 References ................................................................................................................... 37

CHAPTER 3. AUTO-IDENTIFICATION OF POSITIVE FEEDBACK LOOPS IN

MULTI-STATE VULNERABLE CIRCUITS ....................................................................... 40 3.1 Introduction ................................................................................................................. 40 3.2 Feedback Loops ........................................................................................................... 42 3.3 PFLs Identification ...................................................................................................... 45

3.3.1 Analyze the Netlist .............................................................................................. 45 3.3.2 Determine the Channel List ................................................................................. 46 3.3.3 Construct DDG .................................................................................................... 46 3.3.4 Identify Feedback Loops and Determine The Sign ............................................. 48

Page 5: Design and verification approaches for reliability and

iv

3.4 Simulation Results ....................................................................................................... 50

3.5 Conclusion ................................................................................................................... 53

3.6 References ................................................................................................................... 54

CHAPTER 4. SYSTEMATIC BREAKING-LOOP METHOD FOR VERIFICATION

AGAINST UNDESIRED OPERATING POINTS ................................................................. 56 4.1 Introduction ................................................................................................................. 56 4.2 Break-loop Homotopy Method .................................................................................... 59

4.3 A Multi-loop Example ................................................................................................. 61 4.4 Strongly-Connected Components ................................................................................ 63

4.4.1 Constructing the DDG ......................................................................................... 63 4.4.2 Strongly-Connected Components........................................................................ 65

4.5 Identify and Break PFLs .............................................................................................. 66

4.5.1 Identity Positive Feedback Loops ....................................................................... 66 4.5.2 Break Positive Feedback Loops .......................................................................... 67

4.6 Results ......................................................................................................................... 68 4.7 Conclusion ................................................................................................................... 69

4.8 References ................................................................................................................... 71

CHAPTER 5. IMPROVING TIME-EFFICIENCY OF FAULT-COVERAGE

SIMULATION FOR MOS ANALOG CIRCUIT .................................................................. 73

5.1 Introduction ................................................................................................................. 73 5.2 Overview of Proposed Method .................................................................................... 76

5.3 Directed Dependency Graph ....................................................................................... 79 5.3.1 Directed Dependency Graph ............................................................................... 79

5.3.2 Strongly-Connected Components........................................................................ 83 5.4 Fault Simulation with Sub-circuits .............................................................................. 85

5.4.1 SCC Sub-circuits ................................................................................................. 85 5.4.2 Time Efficiency ................................................................................................... 88

5.5 Fault Coverage Evaluation .......................................................................................... 89

5.5.1 Directed Acyclic Graph ....................................................................................... 90 5.5.2 Backward Sensitivity Analysis ............................................................................ 91

5.6 Case Study ................................................................................................................... 96

5.7 Discussion .................................................................................................................. 100 5.8 Conclusion ................................................................................................................. 101 5.9 References ................................................................................................................. 103

CHAPTER 6. IMPROVING ANALOG FAULT-COVERAGE WITH SYSTEMATIC

TEST-POINTS SELECTION AND CONCURRENT SAMPLING .................................... 106 6.1 Introduction ............................................................................................................... 106 6.2 Overview of Proposed Method .................................................................................. 108

6.3 Test-Points Set ........................................................................................................... 110 6.3.1 Directed Dependency Graph ............................................................................. 110 6.3.2 Recursive Backward Propagation Method ........................................................ 112

6.4 Concurrent Sampling with Local Digitization ........................................................... 115 6.5 Case Study ................................................................................................................. 118

Page 6: Design and verification approaches for reliability and

v

6.6 Conclusion ................................................................................................................. 121

6.7 References ................................................................................................................. 122

CHAPTER 7. CONCLUSION .............................................................................................. 124

APPENDIX A. PROGRAMS FOR IDENTIFYING AND BREADING FEEDBACK

LOOPS OF A CIRCUIT ....................................................................................................... 127

APPENDIX B. PROGRAMS FOR IMPROVING TIME EFFICIENCY OF FAULT-

COVERAGE SIMULATION ............................................................................................... 244

Page 7: Design and verification approaches for reliability and

vi

LIST OF FIGURES

Page

Figure 1.1 IoT/IoE of the New Ecosystem of the Electronics’ Industry (Modified from

2017 IRDS) ........................................................................................................... 1

Figure 2.1 Operation of a standard VBE-based bandgap reference ......................................... 12

Figure 2.2 Example of curvature in the GlobalFoudries 130nm process ............................... 17

Figure 2.3 Bermak’ curvature correction technique: bias a BJT base with a PTAT

current ................................................................................................................. 18

Figure 2.4 Curvature compensation by adding a logarithmic term (a) simplified

schematic R3-R4=Rtype1 and R5= Rtype2 (b) curvature compensation

illustration ........................................................................................................... 19

Figure 2.5 Curvature compensation by adding the piecewise linear current (a) simplified

schematic (b) curvature compensation illustration ............................................. 20

Figure 2.6 Illustration of using (a) three diodes (b) three BJT connected as diodes, to

extract the VGO .................................................................................................... 21

Figure 2.7 Generation of PTAT current using two BJTs ....................................................... 23

Figure 2.8 Generation of nonlinear term containing TlnT ..................................................... 24

Figure 2.9 Conceptual generation of temperature independent current ................................. 25

Figure 2.10 One implementation of the proposed method ..................................................... 27

Figure 2.11 Equivalent circuit when opamp offset of A2 is injected ..................................... 31

Figure 2.12 Equivalent circuit when opamp offset of A1 is injected ..................................... 32

Figure 2.13 Bandgap voltage versus absolute temperature and the tangent line for

Tr=300K .............................................................................................................. 33

Figure 2.14 Output voltage over process ................................................................................ 34

Figure 2.15 Output voltage over process with (a)one-point and (b)two-points calibration .... 34

Figure 3.1 A feedback structure .............................................................................................. 41

Figure 3.2 Inverse widlar (a) branch-current and controlling voltage (b) directed

dependency graph ............................................................................................... 43

Page 8: Design and verification approaches for reliability and

vii

Figure 3.3 Bootstrapped Vt reference circuit (a) schematic (b) netlist (c) channels list (d)

branches (e) directed dependency graph ............................................................ 45

Figure 3.4 Sign of dependencies for Figure 3.2(e) (a) the upper loop (b) the bottom loop .... 49

Figure 3.5 Voltage regulator (a) schematic (b) DDG ............................................................. 50

Figure 3.6 Sign of dependencies for each loop shown in Figure 3.5(b) ................................. 51

Figure 3.7 Schematic of self-biased bandgap reference ......................................................... 51

Figure 3.8 DDG of self-biased bandgap circuit shown in Figure 3.7 ..................................... 52

Figure 3.9 Sign of dependencies for each loop shown in Figure 3.8 ...................................... 52

Figure 4.1 Flow chart of proposed method ............................................................................. 58

Figure 4.2 Broken PFLs for Wilson bias generator (a) Break at the schematic (b) Break

at the DDG .......................................................................................................... 59

Figure 4.3 Return map for Wilson bias generator (a) Blue: curve for VA1= VA2 (b) Red:

return map when temperature is 25oC (c) Black: return map when

temperature is 125 oC ......................................................................................... 61

Figure 4.4 A full CMOS Voltage regulating circuit ............................................................... 62

Figure 4.5 (a) schematic (b) netlist (c) channels list (d) branches (e) directed

dependency graph ............................................................................................... 64

Figure 4.6 Example directed graph ........................................................................................ 66

Figure 4.7 Schematic of the Sub-Bandgap reference............................................................. 68

Figure 4.8 DDG showing SCCs of Figure 4.7 ........................................................................ 69

Figure 4.9 Widlar-banba circuit (a) schematic (b) DDG showing the strongly connected

components ......................................................................................................... 70

Figure 5.1 Flowchart of the proposed method ....................................................................... 78

Figure 5.2 A simple directed graph example ......................................................................... 80

Figure 5.3 Example circuit: Widlar bias generator, (a) schematic (b) DDG ......................... 81

Figure 5.4 The SCCs for the DDG shown in Figure 2.3(b) ................................................... 84

Figure 5.5 (a) SCC sub-circuits of example widlar circuit (b) a sub-circuit generated

from the combination of SCC2 and SCC3 ......................................................... 86

Page 9: Design and verification approaches for reliability and

viii

Figure 5.6 The directed acyclic graph for Figure 5.3 ............................................................ 91

Figure 5.7 (a)an artificial DAG where SCC1 has two output vertices N1 and N2; (b)

calculation of equivalent detection limits for N1 and N2 .................................... 94

Figure 5.8 A simplified graph where multiple paths exist from one vertex to a test point

vertex to a test point ........................................................................................... 94

Figure 5.9 Benchmark circuit ................................................................................................ 96

Figure 5.10 A ‘simplified’ graph of the benchmark circuit in Figure 5.9 ............................. 97

Figure 6.1 Flowchart of the proposed method ...................................................................... 109

Figure 6.2 Example circuit: Widlar bias generator, (a) schematic (b) DDG with with

SCCs ................................................................................................................. 112

Figure 6.3 The DAG for the DDG shown in Figure 6.2 ....................................................... 113

Figure 6.4 Recursive backward method (a) DAG with fault impacts in each SCC (b)

first iteration (c) second iteration ..................................................................... 114

Figure 6.5 Local Digitization ................................................................................................ 116

Figure 6.6 Architecture of the proposed Concurrent Sampling method ............................... 117

Figure 6.7 Benchmark circuit with the test-points highlighted with different color a)

Red: from iteration 0; b) Blue: from iteration 1; c) Green: from iteration 2;

d)Purple: from iteration 3 ................................................................................ 119

Page 10: Design and verification approaches for reliability and

ix

LIST OF TABLES

Page

Table 2.1 Error sources in a typical CMOS BGR ................................................................... 13

Table 2.2 Comparison with the state-of-the-art high-precision voltage reference

generators ........................................................................................................... 35

Table 3.1 The Sign of Different Dependencies ...................................................................... 49

Table 4.1 Simulation Results of Voltage Regulating Circuit ................................................. 63

Table 5.1 Performance Summary ........................................................................................... 99

Table 6.1 Differences between ATB and CS ........................................................................ 118

Table 6.2 Iterations of The Recursive Backward Method .................................................... 120

Table 6.3 Comparison with the state-of-the-art methods...................................................... 120

Page 11: Design and verification approaches for reliability and

x

ACKNOWLEDGMENTS

First and foremost, I wish to express my deepest gratitude to my advisor Dr. Degang

Chen for his guidance, support, and patience during my research study. In the past several

years, he has helped me to develop my background in Analog IC design, Mix-signal IC

design, and verification.

I would also like to thank my committee members, Dr. Randall Geiger, Dr. Chris

Chong-Nuen Chu, Dr. Jiming Song, and Dr. Ratnesh Kumar, for their guidance and

encouragement throughout the course of this research.

In addition, I would also like to express my thanks to Shravan Chaganti, Dr. You Li,

Xu Zhang, Chin-Wen Chen, Huanhuan Zhang, Hao Meng, Nanqi Liu, Dr. Bin Huang, Dr.

Minshun Wu and my other friends, especially Songlin Hu, Yang He and Yifei Li who helped

me with various aspects of conducting this Ph.D. work. I want to also offer my appreciation

to my colleagues, the department faculty, and staff for making my time at Iowa State

University a wonderful experience.

I thank my parents: Xianbao Liu and Yinfeng Luo, for their unconditional love and

support throughout my Ph.D. study abroad. I would also like to thank my sisters and

brothers-in-law: Shufei Liu, Ming Liu, Shujuan Liu, and Kun Zhang for providing me with

encouragement and any necessary supports during my study.

Page 12: Design and verification approaches for reliability and

xi

ABSTRACT

New breakthroughs in semiconductor design have enabled a rapid integration of

semiconductor chips into systems that affect all aspects of the society. Examples of emerging

systems include spacecraft, Internet of Things (IoT), intelligent automotive, and bio-

implantable devices. Many of these systems are mission-critical or safety-critical, meaning

that failure or malfunction may lead to severe economic losses, environmental damages or

risks to human lives [1]. In addition to performances improvement, the reliability and

functional safety of the underlying integrated circuit (IC) have attracted more and more

attention and have posed grand challenges for semiconductor industries. This dissertation

introduces an approach for high performance voltage reference design and investigates two

subjects that improve the reliability and functional safety of analog circuits.

The first part of this dissertation studies design strategies of a low temperature-

coefficient voltage reference generator, which is a fundamental building block and

determines the maximum achievable performance of almost all analog/mixed-signal systems.

The proposed method is targeted at extracting a physical quantity of the silicon bandgap, and

has the potential of designing a voltage reference that has qualitatively better temperature

dependence. An implementation of the proposed approach in GlobalFoundries 130nm

process shows that the design can achieve temperature coefficients as low as 0.7ppm/°C over

a temperature range of -40°C to 125°C over all process corners.

The second part of this dissertation focuses on multi-states verification of analog

circuits. The multiple DC equilibrium points or multi-states problem traces back to IC

design. It is a well-known problem in many basic self-stabilized analog circuits because of

the existence of positive feedback loops (PFLs). This work proposes systematic and

Page 13: Design and verification approaches for reliability and

xii

automatic approaches for locating all PFLs to identify circuits vulnerable to undesired

equilibrium states and methods for automatically identifying break-points to break all PFLs

in the vulnerable circuits. The proposed methods make it possible to efficiently identify a

circuit’s vulnerability to undesired operating points by considering circuit topology only,

without the need for finding all possible solutions to a set of simultaneous nonlinear

equations which is an open problem with no solution. Moreover, the automatic break-points

identification enables easy use of homotopy analysis to guarantee absence of undesired

states.

The third part of this dissertation focuses on fault coverage simulation of analog

circuits. This work describes two methods, one is to reduce the fault coverage estimation

time and the other is to improve the fault coverage for analog circuits. The first method

incorporates graph theory and sensitivity analysis and leads to a dramatic reduction in fault

coverage simulation time by 10’s of times for a moderately sized analog circuit. The second

method discusses a systematic test-points selection technique to improve the analog fault

coverage with simple DC tests and a concurrent sampling technique for monitoring these

points. This work could be applied to manufacturing testing or for real-time fault detection.

Page 14: Design and verification approaches for reliability and

1

CHAPTER 1. INTRODUCTION

1.1 Background and Motivation

During the past 50 years, the semiconductor industry has marched at the pace of

Moore’s Law. Transistor scaling associated with doubling the number of transistors every

two years on the average has been and continues to be the unique feature of the

semiconductor industry[2]. As the manufacturer technology and design innovation advance,

both the complexity and the number of ICs embedded in systems that affect all aspects of the

society have grown rapidly. Figure 1.1 gives an overview of the well-known topic, Internet

of Things/Internet of Everything (IoT/IoE) which is simplified from the new ecosystem of

the electronics’ industry in the 2017 International roadmap for devices and systems (IRDS)

[2]. It is worth to point out that analog circuits play major and irreplaceable roles in the core

hardware of IoT/ToE. Specifically, in Figure 1.1, the Radio Frequency (RF), Analog Front

End (AFE) and sensors are essentially analog circuits; inside all other sub-systems (e.g., bio-

medical devices, intelligent automotive), there are also various analog components

Figure 1.1 IoT/IoE of the New Ecosystem of the Electronics’ Industry (Modified from 2017 IRDS)

Page 15: Design and verification approaches for reliability and

2

such as reference generators, analog-to-digital converters (ADC), digital-to-analog

converter(DAC), power management ICs, and et al.

Performance improvement, such as high speed, high accuracy, low power and small

area are still an important goal for current and future semiconductor industries. The IRDS

technology roadmap (More Moore) targets bringing PPAC value for node scaling every 2-3

years [3], [4]:

• (P)erformance:> 15% more operating frequency at scaled supply voltage

• (P)ower: >35% less energy per switching at a given performance

• (A)rea: >35% less chip area footprint

• (C)ost:<30% more wafer cost-20% less die cost for scaled die.

In addition to continuous performance improvements, the reliability and functional

safety of the underlying ICs have attracted more and more attention and have posed grand

challenges for both academia and industry. On the one hand, this is because failure or

malfunction of those safety-critical systems, e.g., automotive or medical devices, may

directly or indirectly lead to severe economical losses, environmental damages or risks to

human lives. On the other hand, the shrunk geometries, higher operating frequency, and

scaled supply voltage bring negative impacts on functional safety and reliability to a circuit.

In particular, such technology advances have the potential to increase the rate of occurrence

of a fault. For example, smaller interconnect features will increase the likelihood of

intermittent faults, resulting from process variations and manufacturing residuals[5]. Smaller

transistors and lower supply voltages lead to higher sensitivity to neutron and alpha particles,

which in turn significantly increase rates of particle-induced transients[5]. Moreover, as the

complexity, as well as the number of ICs in a system, grows, the impacts of some hidden or

Page 16: Design and verification approaches for reliability and

3

negligible problems may manifest and become critical. One example of such problems is

multiple DC equilibrium points problem.

This dissertation will first introduce an approach for high-performance voltage

reference design and then investigate two subjects that improve the reliability and functional

safety of analog circuits, multi-state verification and fault coverage analysis. The first subject

traces back to IC design itself and the second results from the manufacturing process.

The first part of this dissertation studies design strategies of low temperature-

coefficient voltage reference generator. The accuracy of voltage reference determines the

maximum achievable performance of nearly all mixed-signal and radio-frequency systems

[6], [7]. Increasing demands of modern high-performance circuits such as voltage regulators,

high-resolution data converters, and precision measurement systems, pose a need for the

design of high-accuracy, low temperature coefficient (TC) voltage reference. Over the past

few years, efforts in high-precision reference study have emerged in both industry [8]–[10]

and academia [11]–[15]. These precision reference generators utilize the base-emitter voltage

(VBE) of a bipolar junction transistor since VBE contains a physical constant voltage VGO

which is independent of temperature, supply, and process over a very wide temperature

range. In most exiting high-order compensation techniques, low temperature drift is achieved

by canceling the temperature nonlinearity of VBE and making the temperature coefficient zero

at a given reference temperature Tr, resulting in an output voltage with a constant term equal

or proportional to VGO plus a high order term of Tr. In another word, there is no exiting work

that reports exact VGO extraction. Therefore, it is very meaningful to investigate techniques to

exactly extract the VGO such that a voltage reference with qualitatively better temperature

dependence can be created.

Page 17: Design and verification approaches for reliability and

4

Many basic analog circuits, such as self-stabilized bias generators, voltage and

current references, and Schmitt-triggers [1,2,3], frequently utilized as subcircuits in large-

scale circuit, are well known to sometimes possess multiple DC operating points or multiple

states. This is due to the existence of positive feedback loops (PFLs) []. These PFLs can be

inherently in the circuit, e.g., self-stabilized bias generators or intentionally introduced by the

designer for stabilization or performance enhancement. Moreover, these PFLs can also be

unintentionally introduced when the circuit becomes complex. The presence of multiple

states sometimes causes these circuits to fail to function as designed [4]. Therefore it is

worthwhile to verify the presence of such multiple states before the fabrication of circuits.

Unfortunately, according to [5], the commonly used simulators such as spectre and ultraism,

provide only one solution even though multiple states may be present. Start-up circuits have

been introduced to make a circuit work at the desired states. However, there are several

concerns: a) there is no systematical way to identify the potential multiple states problem of a

circuit. It is typically achieved by inspection or by the designers’ experience, which might be

possible for a small circuit but it becomes difficult or impracticable as the circuit size

becomes complex and large. b) the introduction of a start-up circuit for a target design is

usually heuristic and there is no systematical method to verify that the added start-up circuit

has successfully removed the undesired states over process or temperature variation. Break-

loop homotopy methods [16] have been investigated to guarantee freedom of undesired states

of a circuit. However, these methods require the knowledge of all feedback loops and how to

break all positive feedback loops in the circuit. Therefore, systematic and automatic

approaches are needed for locating all PFLs to identify circuits vulnerable to undesired

Page 18: Design and verification approaches for reliability and

5

equilibrium states. In addition, methods for automatically identifying break-points to break

all PFLs in the vulnerable circuits are also needed.

A defect introduced by an unintended physical change during the manufacturing

fabrication may result in dramatic performance loss and possibly even system failure. Fault

simulation is a technique for estimating the coverage by injecting hypothetical physical

defects into a design and verifying that a manufacturing test or verification suite can detect

them. The increasingly stringent quality requirements for modern safe/mission-critical

systems have posed grand challenges to improve fault coverage, i.e., to prevent

malfunctioning ICs from being shipped to customers. After decades of innovation, fault

coverage simulation for digital circuits has achieved great success, with test escape rates

reaching below 0.1 defective parts per million (dppm) [17], [18]. However, fault simulation

for analog circuits lags far behind, and there is a lack of existing commercially-available

analog fault simulators [19]. Although analog circuits typically constitute only a small

fraction of modern mixed-signal ASICs, they represent a major cause of customer returns in

the industry [17], [20]. Therefore, there is an urgent need to develop practical and efficient

methods for improving fault coverage for analog circuits at reasonable cost and time.

In analog fault simulation, there are two major challenges the number one challenge

is that simulation time could grow rapidly and become prohibitive as circuit size becomes

large. Therefore, practical methods for improving time efficiency in estimating the fault

coverage of analog fault simulation is needed. Another challenge is that the primary outputs

provide very limited observability, making it virtually impossible to achieve high fault

coverage for analog circuits without observing internal nodes [21]. Although researchers tend

to believe that observing some internal nodes is one effective technique for improving fault

Page 19: Design and verification approaches for reliability and

6

coverage, exactly where and how to access these nodes still remains challenging in reality.

Hence, systematic methods for selecting the test-points and monitoring these points are

needed as well.

1.2 Organization of Dissertation

The rest of this dissertation is arranged in the following order:

Chapter 2. This chapter describes a precision voltage reference generator targeting a

sub-ppm temperature coefficient over a wide temperature range. Unlike conventional

curvature-correction techniques that attempt to cancel the temperature nonlinearity of VBE,

the proposed method is specifically targeted at extracting VGO from the temperature

characteristic of VBE. Analytical constraints that lead to strategies for creating an output

voltage proportional to VGO when certain mismatches and offsets are accurately trimmed are

carefully investigated. The proposed method is implemented in the GlobalFoundries 130nm

process. Simulation results show that the design can achieve temperature coefficients as low

as 0.7ppm/°C from -40°C to 125°C over process corners.

Chapter 3. A systematic method is proposed for automatically identifying positive

feedback loops (PFLs) in analog/mixed-signal circuits. The method first converts the netlist

of a circuit into a directed dependency graph (DDG) that captures the critical relationships

among branch currents and node voltages. It then utilizes graph theory techniques to find all

feedback loops from the DDG and, finally, a criterion for determining the PFLs is developed.

Since multiple states are caused by the PFLs, this method could identify a circuit’s

vulnerability to undesigned operating points only by considering only its structure and

without the computation of DC solutions. The proposed approach is implemented in a

program, and simulation results show that it can identify all PFLs very robustly.

Page 20: Design and verification approaches for reliability and

7

Chapter 4. A method for breaking PFLs in Multi-states vulnerable circuits is

proposed in this Chapter. At determined breaking points, a break-loop homotopy sweep

method can be applied to verify the presence or absence of undesired operating points. It will

be shown that questions of how and where to break PFLs is challenging for many circuits,

particularly as a circuit becomes large and feedback structures become complex. To

overcome such difficulty, graph theory techniques are employed to partition a complex

circuit graph into disjoint Strongly Connected Components (SCCs). Based on this approach,

detection of PFLs and locating break-points can be conducted for every SCC. This limits the

sweep dimension of the break-loop homotopy sweep method to within one or two even for a

large-scale circuit. Sub-Bandgap reference and widlar-Banba examples will be used to show

that the proposed approach can effectively identify all the SCCs and corresponding

breakpoints. methods for automatically identifying break-points to break all PFLs in the

vulnerable circuits are also proposed.

Chapter 5. This chapter proposes a systematic method for significantly improving

time efficiency in estimating the fault coverage for analog fault simulation. In analog fault

simulation, the number one challenge is that, the overall simulation time could grow rapidly

and become prohibitively high as circuit size becomes large. In the proposed method, a

circuit under test (CUT) is first partitioned into independent sub-circuits. This is

accomplished through mapping the circuit into a graph, decomposing the graph into strongly

connected components (SCCs), and generating a sub-circuit for each SCC. The impacts of

potential faults directly entering a sub-circuit are then simulated and recorded using the sub-

circuits, an activity expected to be much more time-efficient than fault simulation using the

much larger whole circuit. Finally, fault detectability at the given test-points is evaluated

Page 21: Design and verification approaches for reliability and

8

based on fault impacts and sensitivity among the different sub-circuits. As a first step toward

quick estimation of fault coverage, this chapter focuses on DC tests. Simulation results show

that the fault coverage of DC tests can be estimated sufficiently accurately, with simulation

time reduced by 10X, or by approximately the number of SCCs, for the benchmark circuit.

For a much larger circuit, the number of SCCs is expected to be much larger and the

corresponding time-saving factor would also be much larger.

Chapter 6. A novel Test-Points selection And Concurrent sampling method(TPAC)

is introduced for significantly improving fault coverage of analog circuits. The method

consists of two major parts. The first part is to select a set of test-points with a recursive

backward method such that the knowledge of values of the selected test-points is sufficient to

tell whether a fault has occurred in the circuit. Since the selected test-points could be internal,

we propose concurrent sampling with local digitization for observing the values at these test-

points. The proposed concurrent sampling method allows multi-bit resolution and thus

enables detection of both catastrophic(hard) faults and parametric faults. As part of

concurrent sampling, the measurement results are sent out as digital values. The proposed

TPAC method could be used for off-line manufacturer tests as well as for real-time fault

detection.

Chapter 7 concludes the dissertation.

Page 22: Design and verification approaches for reliability and

9

1.3 References

[1] M. Bozzano and A. Villafiorita, Design and safety assessment of critical systems.

Auerbach Publications, 2010.

[2] “The 2017 International roadmap for devices and systems, Executive Summary.”

[Online]. Available: https://irds.ieee.org/images/files/pdf/2017/2017IRDS_ES.pdf.

[Accessed: 09-Apr-2018].

[3] “The 2017 International roadmap for devices and systems, More Moore,” IRDS, 2017.

[Online]. Available: https://irds.ieee.org/images/files/pdf/2017/2017IRDS_MM.pdf.

[Accessed: 09-Apr-2018].

[4] W. T. J. Chan, A. B. Kahng, S. Nath, and I. Yamamoto, “The ITRS MPU and SOC

system drivers: Calibration and implications for design-based equivalent scaling in the

roadmap,” in 2014 IEEE 32nd International Conference on Computer Design (ICCD),

2014, pp. 153–160.

[5] C. Constantinescu, “Trends and challenges in VLSI circuit reliability,” IEEE Micro, vol.

23, no. 4, pp. 14–19, Jul. 2003.

[6] P. K. T. Mok and K. N. Leung, “Design considerations of recent advanced low-voltage

low-temperature-coefficient CMOS bandgap voltage reference,” in Custom Integrated

Circuits Conference, 2004. Proceedings of the IEEE 2004, 2004, pp. 635–642.

[7] J.-H. Li, X. Zhang, and M. Yu, “A 1.2-V Piecewise Curvature-Corrected Bandgap

Reference in 0.5 m CMOS Process,” IEEE Trans. Very Large Scale Integr. VLSI Syst.,

vol. 19, no. 6, pp. 1118–1122, Jun. 2011.

[8] “LTC6655 - 0.25ppm Noise, Low Drift Precision References - Linear Technology.”

[Online]. Available: http://www.linear.com/product/LTC6655.

[9] “REF5050 | Series Voltage Reference | Voltage Reference | Description & parametrics.”

[Online]. Available: http://www.ti.com/product/REF5050.

[10] “MAX6126 Ultra-High-Precision, Ultra-Low-Noise, Series Voltage Reference -

Maxim.” [Online]. Available: http://datasheets.maximintegrated.com/en/ds/3623.pdf.

[11] C. M. Andreou, S. Koudounas, and J. Georgiou, “A Novel Wide-Temperature-Range,

3.9 ppm/°C CMOS Bandgap Reference Circuit,” IEEE J. Solid-State Circuits, vol. 47,

no. 2, pp. 574–581, Feb. 2012.

[12] R. Oberhuber, R. Prakash, and V. Ivanov, “A 1 ppm/°C bandgap voltage reference with

new second-order Taylor curvature compensation,” in 23rd IEEE International SOC

Conference, 2010, pp. 71–76.

Page 23: Design and verification approaches for reliability and

10

[13] B. Wang, M. K. Law, and A. Bermak, “A Precision CMOS Voltage Reference

Exploiting Silicon Bandgap Narrowing Effect,” IEEE Trans. Electron Devices, vol. 62,

no. 7, pp. 2128–2135, Jul. 2015.

[14] Z. Zhou et al., “A 1.6-V 25-µA 5-ppm/ C Curvature-Compensated Bandgap Reference,”

IEEE Trans. Circuits Syst. Regul. Pap., vol. 59, no. 4, pp. 677–684, Apr. 2012.

[15] B. Ma and F. Yu, “A Novel 1.2–V 4.5-ppm/°C Curvature-Compensated CMOS Bandgap

Reference,” IEEE Trans. Circuits Syst. Regul. Pap., vol. 61, no. 4, pp. 1026–1035, Apr.

2014.

[16] Y. Li, Z. Liu, and D. Chen, “Efficient Verification Against Undesired Operating Points

for MOS Analog Circuits,” IEEE Trans. Circuits Syst. Regul. Pap., vol. 64, no. 8, pp.

2134–2145, Aug. 2017.

[17] A. Coyette, G. Gielen, R. Vanhooren, and W. Dobbelaere, “Optimization of analog fault

coverage by exploiting defect-specific masking,” in Test Symposium (ETS), 2014 19th

IEEE European, 2014, pp. 1–6.

[18] R. Gordon and A. Sadok, “An Overview of Mixed-Signal Production Test from a

Measurement Principle Perspective,” IEEE Des. Test, no. 99, pp. 1–1.

[19] S. Sunter, K. Jurga, P. Dingenen, and R. Vanhooren, “Practical random sampling of

potential defects for analog fault simulation,” in Test Conference (ITC), 2014 IEEE

International, 2014, pp. 1–10.

[20] L. Fang, M. Lemnawar, and Y. Xing, “Cost Effective Outliers Screening with Moving

Limits and Correlation Testing for Analogue ICs,” in Test Conference, 2006. ITC ’06.

IEEE International, 2006, pp. 1–10.

[21] A. Coyette, B. Esen, R. Vanhooren, W. Dobbelaere, and G. Gielen, “Automatic

generation of autonomous built-in observability structures for analog circuits,” in 2015

20th IEEE European Test Symposium (ETS), 2015, pp. 1–6.

Page 24: Design and verification approaches for reliability and

11

CHAPTER 2. DESIGN OF LOW TEMPERATURE-COEFFICIENT BANDGAP

REFERENCE

Abstract

This chapter presents a precision voltage reference generator targeting sub-ppm

temperature coefficient over a wide temperature range. Unlike conventional curvature

correction techniques that attempt to cancel the temperature nonlinearity of VBE, the proposed

method is specifically targeted at extracting VGO from the temperature characteristic of VBE.

VGO is the band gap voltage of silicon extrapolated at zero Kevin and is temperature

independent over a very wide temperature range. Analytical constraints that lead to strategies

for creating an output voltage proportional to VGO when certain mismatches and offsets are

accurately trimmed. The proposed method is implemented in the GlobalFoundries 130nm

process. Simulation results show that the design can achieve temperature coefficients as low

as 0.7ppm/°C ranging from -40°C to 125°C over process corners.

2.1 Introduction

The accuracy of voltage reference determines the maximum achievable performance

of nearly all mixed-signal and radio-frequency systems [1], [2]. Increasing demands of

modern high-performance circuits such as voltage regulators, high-resolution data converters,

and precision measurement systems, pose a need for the design of high-accuracy, low

temperature coefficient (TC) voltage reference.

Although some approaches make use of gate-source voltage of MOSFETs operating

in weak inversion[3], most precision reference generators utilize the base-emitter voltage

(VBE) of a bipolar junction transistor (BJT). The reason is that the VBE is better characterized

over temperature and varies less than the threshold voltage and mobility of a MOSFET [4],

[5]. A standard VBE-based bandgap reference generator is implemented using a weighted

Page 25: Design and verification approaches for reliability and

12

summation of a proportional-to-absolute-temperature (PTAT) voltage and the VBE, a

complementary-to-absolute-temperature (CTAT). However, because of the nonlinearity of

VBE over a temperature range, curvature compensation is usually required in order to

achieve a low temperature coefficient.

T36T35

Q1 Q2

Vr

R2

R1

VDD

First order BGR

VPTAT

VBE

V

T

Figure 2.1 Operation of a standard VBE-based bandgap reference

Challenges for designing precision bandgap reference generators have been

investigated, and various approaches to overcome these challenges have been developed

since the 1980s [6]–[9]. Over the past few years, efforts in high-precision reference study

have emerged in both industry [10]–[12] and academia [5], [13]–[16] and the TC values

achieved approach the ppm level. Makinwa, et al., in [17] pointed out that opamp offset and

nonlinear temperature dependency of VBE are the two dominant limiting factors for

achievable precision of a typical CMOS bandgap reference. This is because these two error

sources are non-PTAT and cannot be removed by a single temperature trim [17]. They

achieved high accuracy by eliminating these two non-PTAT errors with the use of chopping

and higher-order curvature correction techniques.

Page 26: Design and verification approaches for reliability and

13

Table 2.1 Error sources in a typical CMOS BGR

Many high-order temperature compensation approaches for reducing the TC have

been investigated. Ivanov, et al., [13] proposed a second-order Taylor curvature

compensation, and A. Bermak, et al., [14] explored the silicon bandgap-narrowing effect of

BJT curvature reduction to perform residual curvature correction. Structures based on

piecewise-linear curvature compensation have also been investigated [2], [15]. The

piecewise compensation proposed in [15] added one more logarithmic curvature term to the

conventional exponential curvature for further reduction of TC at higher temperature. Some

researchers propose canceling high-order nonlinearities by generating a curve with high-

order temperature coefficient characteristics opposite to those of bipolar transistors. For

example, [16] utilized MOS transistors operating in weak inversion and [18] utilized a

current mirror to create a curvature-up bandgap reference, then added it to a conventional

curvature-down bandgap reference.

In most high-order compensation techniques, low temperature drift is achieved by

canceling the temperature nonlinearity of VBE and making the temperature coefficient zero at

Page 27: Design and verification approaches for reliability and

14

a given reference temperature Tr , resulting in an output voltage with constant term equal or

proportional to VGO plus a term of Tr, where VGO is the band gap voltage of the silicon

extrapolated at 0K. In this chapter, we will present a voltage reference generator targeted at

extracting the silicon bandgap VGO from the temperature characteristic of the base-emitter

voltage in a bipolar transistor. Since VGO is a well-characterized, temperature independent

components [19], the proposed reference generator can achieve a temperature coefficient

smaller than 1ppm (termed sub-ppm) when certain mismatches and offsets are accurately

trimmed using existing methods. The essence of the proposed VGO extraction is to create a

voltage proportional to Tln(T) since it contains all the high-order nonlinearity in the VBE.

Even though many people have recognized this, there is no existing research showing that a

pure Tln(T) term was generated. In this work, we created a self-stabilized bootstrap structure

and when a set of equations are satisfied, we simultaneously obtain the nonlinear Tln(T) term

and have the voltage and current to be constant over a wide temperature range which means

the VGO extraction is achieved.

This research is focusing on investigating the fundamental theoretical efficacy of

realizing the VGO extraction. Analytical constraints for generating a reference voltage

proportional to the VGO are derived when the non-ideal error sources are ignored. Then the

effects of several non-ideal error sources on the proposed VGO extraction are discussed. It is

shown that the VGO extraction is still theoretical achievable when these practical error sources

are taking into considerations. The proposed method is implemented in a CMOS 130nm

process. Simulation results show that the design achieves a temperature coefficient as low as

0.7ppm/°C over a temperature range from -40°C to 125°C.

Page 28: Design and verification approaches for reliability and

15

The remainder of this chapter is organized as follows: Section 2.2 reviews several

state-of-the-art high-order temperature compensation approaches and presents the general

concept of the proposed VGO extractor. Section 2.3 explains the proposed method through

one example structure and derives analytical constraints for VGO extraction. Section 2.4

discusses the effects of several error sources on the proposed method. Section 2.5

demonstrates the effectiveness of the method by implementing the design in a 130nm

process. Finally, conclusions are drawn in Section 2.6 .

2.2 Curvature Compensation and General Concept of VGO extractor

In this section, the analytical expression of the temperature characteristic of VBE will

be introduced first. Then, several state-of-the-art high-order temperature compensation

approaches for reducing the temperature coefficient of a reference generator will be reviewed

to motivate the VGO extraction. Finally, the general concept of the proposed VGO extractor

will be presented.

2.2.1 Temperature Characteristic of VBE

As an effective way to reducing the temperature coefficient of a VBE-based reference

generator, high-order curvature compensation has been widely investigated and employed in

the high-precision reference. In these high-order compensation techniques, low temperature

drift is achieved by canceling the temperature nonlinearity of VBE. To better understand the

details of the different types of curvature compensation and motivate the proposed method,

let us discuss the temperature characteristic of VBE first.

In 1980, Tsividis [4] proposed a well-recognized analytical expression for predicting

the temperature behavior of the IC-VBE characteristics of a BJT. Derived from the collector

current expression, the 𝑉𝐵𝐸 of a BJT transistor can be expressed as

Page 29: Design and verification approaches for reliability and

16

( )( ) ( ) ln ln

( )

CBE GOr BE r GOr

r r C r

I TT kT T kTV T V V T V

T q T q I T

= + − − +

(2-1)

and if the collector current is proportional to 𝑇𝛿, (2-1) can be simplified as

( )( ) ( ) lnBE GOr BE r GOr

r r

T kT TV T V V T V

T q T

= + − − −

(2-2)

where 𝜂 is a process-dependent parameter and the typical value of 𝜂 is around 2~4. T is the

absolute temperature in Kelvin and 𝑇𝑟 is a reference temperature. Room temperature is

usually used as the reference, but it is not necessary. It should be pointed out that 𝑉𝐺𝑂𝑟 is the

extrapolated bandgap voltage of silicon at 0K which is the quantity we would like to extract.

IC is the collector current of the BJT.

Apply Taylor expansion to equation (2-2) at 𝑇 = 𝑇𝑟, we can express the VBE as (2-3),

( )( ) ( )rBE GOr

kTV T V T c T

q

= + − − +

(2-3)

where ( ) rGOr

kTV

q + − is the constant term, 𝜆 is the linear term and 𝑐(𝑇) is the curvature

term in which the curvature 𝑐(𝑇) is

( )( ) ( ln )r

r

k Tc T T T T

q T = − − − (2-4)

Figure 2.2 gives an example curvature in the GlobalFoudries 130nm process where

the prototype circuit is implemented in this research. Note that the curvature leads to about

10ppm/oC temperature coefficient from -40oC to 125oC in the conventional first-order BGR.

Therefore, this is a need to reduce or cancel the curvature for high precision reference

generator in general.

Page 30: Design and verification approaches for reliability and

17

Figure 2.2 Example of curvature in the GlobalFoudries 130nm process

2.2.2 Curvature Compensation Approaches

To compensate the curvature in the VBE, many high-order temperature compensation

approaches have been studied. Three of them are used as an example for the purpose of

illustration.

In Bermak’ method, [14] the silicon bandgap-narrowing effect of BJT was explored

for curvature reduction. A simplified structure is illustrated in Figure 2.3. The main point of

this method is to bias the base of a BJT Q0 with a PTAT current. With the known Gummel-

Pool model, the temperature characteristic of the BJT current gain can be expressed as

0( )

XTB

r

TT

T

=

(2-5)

where 0 is the current gain at the reference temperature and XTB is the beta temperature

exponent.

-50 0 50 100 150-3

-2.5

-2

-1.5

-1

-0.5

0

Temperature(oC)

Curv

atu

re(m

V)

Curvature for = 3.282 and =1

Page 31: Design and verification approaches for reliability and

18

Vce0

Vbe0(T)

Ib0(T)

Mp0

(T)Ib0(T)

Q0

Figure 2.3 Bermak’ curvature correction technique: bias a BJT base with a PTAT current

As a result, the collector current of Q0 will be proportional to 𝑇𝑋𝑇𝐵+1 . Applying

equations (2-2) and (2-5), the curvature of this structure can be written as

( )( ) ( ln )1 TB r

r

k Tc T T T T

qX

T − −−= − (2-6)

In (2-6), if 𝜂 and (1+XTB) are close to zero, the curvature will be approaching zero

and thus curvature reduction is accomplished. However, the effectiveness of the method will

be depended on process since both 𝜂 and XTB are process parameters. Furthermore, for the

purpose of VGO extraction, it requires the term (𝜂 − 1 − 𝑋𝑇𝐵) to be equal to zero which is

not easy due to the lack of the controbility of 𝜂 and XTB.

Structures based on piecewise-linear curvature compensation have also been

investigated [2], [15]. The piecewise compensation method proposed by M. Yu in [2] can be

illustrated with the simplified schematic of Figure 2.4(a). The major idea is to add a

logarithmic curvature term to first-order BGR for high-order curvature compensation. In this

method, the resistor R5 is biased with a PTAT current. The voltage across R5 is used to bias

the VGS of a PMOS transistor M1. Different types of resistor are used for R5 from the resistors

of the BRG core (R3, R4 are shown).

Page 32: Design and verification approaches for reliability and

19

ICTAT IPTAT

IPTAT

INLR3

R4

R5

M1

VDD

VREF

First-order BRG CorePiecewise curvature

generator

First order BGR

V

T

Curvature corrected BGR

T1

Piecewise nonlinear

curvature corrected

voltage

(a) (b)

Figure 2.4 Curvature compensation by adding a logarithmic term (a) simplified schematic R3-R4=Rtype1 and

R5= Rtype2 (b) curvature compensation illustration

As a result, a nonlinear current INL will be generated at the drain of M1:

_ 1

_ 1

2

_ 1

0

exp( )

SG M THP

NL SG M THP

SG M THP

V V

I T V V

T V V

=

(2-7)

The generated nonlinear current INL will then be summed with the PTAT and CTAT

at node VREF. A curvature-corrected reference will be created at VREF and the compensation

effect is shown in Figure 2.4(b).

A similar method was developed by Renesas Electronics Corporation [24]. The

simplified schematic is shown in Figure 2.5 (a). In this method, the nonlinear current INL for

compensation is generated through a voltage to current converter (A2, Q3 and R6). INL can be

expressed as

2

32

0 ( )

( )6

NL REFC BE

T T

I V VT T

R

= −

(2-8)

Page 33: Design and verification approaches for reliability and

20

Similarly, the generated nonlinear current INL will then be summed with the PTAT

and CTAT at node VREF to create a curvature-compensated voltage (Note: this is simplified).

ICTAT IPTAT

INL

R3

R4

VDD

VREFC

First-order BRG CorePiecewise curvature

generator

R6

VREF

Q3

V

TT2

T1

INL

VREF

VREFC

(a) (b)

INL

A2

Figure 2.5 Curvature compensation by adding the piecewise linear current (a) simplified schematic (b)

curvature compensation illustration

2.2.3 VGO Extraction in General

The conventional curvature correction techniques attempt to cancel the temperature

nonlinearity of VBE, resulting in an output voltage with a constant term equal or proportional

to VGO plus a high order term of temperature.

The question now arises: is it possible to remove both the T term and 𝑇ln 𝑇 of VBE of

(2-2) so that the temperature-independent term VGO can be extracted? Huijsing, et al., in [7]

first attempted to obtain a VGO-related output voltage using a standard bipolar process. Under

certain assumptions, they successfully derived a Vref proportional to VGO, and achieved

4ppm/°C in the temperature range 0 to125°C. In this work, we will discuss the VGO extraction

in a more geneal way and carfully investigate strategies and analytical constraints for VGO

extraction.

.

Page 34: Design and verification approaches for reliability and

21

In general, a VGO extractor can be achieved through three or more different diodes,

and Figure 2.6(a) illustrates using multiple diodes to extract the VGO. Another

implementation uses the parasitic vertical BJT [25] of a P-type MOSFET as shown in Figure

2.6(b). This is low cost that can easily be integrated in a CMOS process.

gnd

Q1

V1 V2

vdd vdd

I1 I2

gnd

Q3

V3

vdd

I3

Q2

A AnA

gnd

nA A

Q1 Q2

V1 V2

vdd vdd

I1 I2

gnd

A

Q3

V3

vdd

I3

gnd

(a) (b)

Figure 2.6 Illustration of using (a) three diodes (b) three BJT connected as diodes, to extract the VGO

In Figure 2.6, Q1, Q2 and Q3 are three diodes, or BJTs connected as diodes, with area

ratios equal to n:1:1. I1, I2 and I3 are the currents injected into these three diodes. We will

make I1, I2, and I3 have properties such that 𝐼1 = 𝐹1 ∙ 𝑇𝛿1, 𝐼2 = 𝑚 ∙ 𝐼1, and 𝐼3 = 𝐹2 ∙ 𝑇𝛿2 ,

where m is the ratio of the currents I2 and I1, T is the absolute temperature in Kelvin, F1 and

F2 are two temperature independent coefficients, and 𝛿1 and 𝛿2 are two constant integer

numbers (𝛿1 ≠ 𝛿2). Under these conditions, the following relationships among the voltages

V1, V2 and V3 can be expressed as

2

2 1

3 2

ln

( , )

ln

BE GOr

PTAT

NL

V V V aT bT T

V V V g m n T

V V V cT dT T

= = + +

= − = = − = +

(2-9)

Page 35: Design and verification approaches for reliability and

22

where m and n are design variables, g(m, n) is a function of m and n, and a, b, c, and d are

temperature-independent parameters that can be expressed using the following set of

equations

( )

( )

( )

( )

2

1

1

3 2

2 1

2 1

( )ln

( ) ( )ln

BE r GOr

r

r

BE r BE r

r

r

V T V ka T

T q

kb

q

V T V T kc T

T q

kd

q

−= + −

= − −

− = + − = −

(2-10)

Based on the above relationships, a linear combination resulting in a value of VGOr

can be configured. Let

1 2 3GOr BE PTAT NLV AV A V A V= + + (2-11)

leading to

1 1 2 3 1 3( , ) ln( )GOr GOrV AV A a A g m n A c T Ab A d T T= + + + + + (2-12)

Solving for equation (2-12), we obtain:

1

2

3

1

1

( , )

A

bcA a

g m n d

bA

d

=

= −

= −

(2-13)

It can be seen that the voltage given in (2-12) will be equal to VGOr , i.e, the VGOr

extraction will be achieved, when the equations given by (2-13) are satisfied. Note that in (2-

13), we can multiply A1, A2 and A3 by a coefficient 𝛼, resulting in a voltage proportional to

VGO, i.e., 𝛼 VGO.

2.2.4 Discussion

In the above mentioned VGO extraction, the temperature profile of I1, I2 and I3 is

important. Especially, we need I3 to have constant temperature power. There is no good way

Page 36: Design and verification approaches for reliability and

23

gnd

nA A

Q1 Q2

V1 V2

vdd vdd

R1 ΔVBE

I1 I2

Figure 2.7 Generation of PTAT current using two BJTs

to generate the Tn when n is large than one. In order to achieve this, the biggest challenge is

that one needs to have a current to be constant which has the same difficulty level to have a

constant voltage. In this work, we realized it by creating a self-stabilized bootstrap structure.

In this structure, when a set of equations are satisfied, we simultaneously obtain the nonlinear

Tln(T) term and have the voltage and current to be constant over a wide temperature range

which means the VGO extraction is achieved.

2.3 One Implementation of Proposed Voltage Reference Generator

In this section, one implementation of the proposed voltage reference generator based

on VGO extraction will be introduced, and analytical conditions investigated, after which one

implementation of the proposed method will be presented.

2.3.1 Generation of Nonlinear Term Containing TlnT

Since in the process to be used, only PNP substrate BJT is accessible, in the following

analysis we will use PNP in the examples and assume collector current to be equal to emitter

current.

In standard bandgap topology, two BJTs are utilized to create a PTAT. The

generation of PTAT current using two BJTs is shown in Figure 2.7. If standard mechanisms

are applied to force Vo1=Vo2 and I1=I2, the voltage across the resistor R1 will be a PTAT

Page 37: Design and verification approaches for reliability and

24

gnd

PTAT TI

A A

Q2 Q3

VNL

vdd vdd

Figure 2.8 Generation of nonlinear term containing TlnT

voltage, i.e., ∆𝑉𝐵𝐸 = 𝑉𝑇 ln 𝑛 , where 𝑉𝑇 is the thermal voltage, n is the ratio of the emitter

areas between Q1 and Q2. The resulting current in R1 is a PTAT current. A linear

combination of the PTAT voltage and CTAT voltage VBE can lead to first-order temperature

compensation. For low-voltage operation, the two voltages, ∆𝑉𝐵𝐸 and VBE will first be

converted into two currents using dividing resistors before being combined [9].

To achieve a low temperature coefficient, the nonlinear temperature dependence of

VBE must be considered. From (2-2), the nonlinearity of VBE is dominated by the term 𝑇ln𝑇.

While expressing VBE in a Taylor series and canceling the high-order T terms [15] is one

solution to achieve high-order temperature compensation, another approach is to generate a

nonlinear term proportional to 𝑇ln𝑇 [9], [16], [20]. Figure 2.8 illustrates the concept of

generating a nonlinear term containing TlnT using two BJTs Q2 and Q3. Suppose Q2 is biased

at a given PTAT current and Q3 is biased at a temperature-independent (TI) current. Then,

according to (2-2), the VBE of Q2 and Q3 can be written as (2-14) and (2-15) respectively,

Page 38: Design and verification approaches for reliability and

25

gnd

nA A

Q1 Q2

V1 V2

vdd vdd

R1

I1 I2 TI

A

Q3

vdd

INL

PTAT

CTAT

PTAT

R2

R3

TI

vdd

R4

VrefVNL

Figure 2.9 Conceptual generation of temperature independent current

( )2 2( ) ( ) 1 lnBE GOr BE r GOr

r r

T kT TV T V V T V

T q T

= + − − −

(2-14)

( )3 3( ) ( ) 0 lnBE GOr BE r GOr

r r

T kT TV T V V T V

T q T

= + − − −

(2-15)

The voltage difference VNL is obtained by subtracting VBE3 from VBE2:

3,2 3 2( ) ( ) lnNL BE BE r BE r

r r

T kT TV V V T V T

T q T

= = − +

(2-16)

Note that the term ∆𝑉𝐵𝐸3(𝑇𝑟) − ∆𝑉𝐵𝐸2(𝑇𝑟) is not equal to zero and should not be

ignored as in [5], [9] when deriving accurate relationships for achieving VGO extraction, as

will be discussed in detail next.

2.3.2 VGO Extraction

Figure 2.9 illustrates the proposed concept for achieving the VGO extraction.

Transistors Q1 and Q2 are configured as in Figure 2.7 to generate a PTAT current, and

transistors Q2 and Q3 are set up as in Figure 2.8 to produce the nonlinear voltage VNL that

contains the term 𝑇ln𝑇. Resistor R3 is utilized to convert VNL to nonlinear current INL. A

buffer is placed between R3 and the emitter of Q3 such that INL will not affect the current

Page 39: Design and verification approaches for reliability and

26

flowing into Q3. This is necessary because, as one requirement for remaining (2-16) valid, we

must ensure that IQ3 is temperature-independent. Resistor R2 is utilized to generate the CTAT

from VBE2. The PTAT current, CTAT current, and nonlinear current INL are summed at node

V2, resulting in a total current I2. Since I1=I2, equal currents of current CTAT and INL should

be drawn from node V1 to ensure that IQ2=IQ1=PTAT (how this can be achieved is not

included in Figure 2.9 for simplicity). We will now show how to determine appropriate ratios

among resistors R1, R2, and R3 to make I2 temperature-independent.

Current I2 is mirrored and applied to resistor R4 to generate output voltage Vref, that

can be expressed as

4 1,2 2 2,3

1 2 3

4 2 22 2,3

2 1 3

1 1 1

ln .

ref BE BE BE

BE BE

V R V V VR R R

R R RkTn V V

R q R R

= + +

= + +

(2-17)

From (2-2), (2-16), and (2-17), the proper ratios of 𝑅2/𝑅1 and 𝑅2/𝑅3 for VGO

extraction can be derived. Specifically, we treat T and Tln(T) as two independent basis

functions. Then take the derivative of Vref with respect to T and Tln(T); evaluate the

derivatives at T=Tr and set as zero i.e., 0, and 0ln

ref ref

T Tr T Tr

V V

T T T= =

= =

; slove the eqations to

obtain the resistor ratios as (2-18) and (2-19).

2

3

1R

R= − (2-18)

2 3 22

1

( ) ( ) ( ) ( 1).

ln

GOr BE r BE r BE r

r

V V T V T V TR

kTRn

q

− + − −= (2-19)

When (2-18) and (2-19) are satisfied, (2-17) is reduced to (2-20)

Page 40: Design and verification approaches for reliability and

27

R1R2B

VA VB

I1I2

vdd

R2A

Vo

gnd

Q1 Q2

R4

VRef

I4

1

I3

Q3

R3A

R3BINL

INL

n 1

A1

A2

Figure 2.10 One implementation of the proposed method

4

2

ref GOr

RV V

R= (2-20)

It can be seen that the reference voltage in (2-20) is proportional to VGOr. Strictly speaking,

while the value of VGOr is dependent on Tr [4], but it is temperature-independent over a very

wide temperature range (e.g., -40 °C -125°C), so VGO=VGOr is assumed in many references

[5], [14] and frequently also in practice.

One possible implementation of the proposed method is shown in Figure 2.10. The

basic structure of this implementation is similar to that given in [9], but more constraints are

posed for the purpose of extracting VGO, and the proposed method is not limited to this

structure only. In Figure 2.10, currents I1 - I4 are equal and will be temperature-independent

when the resistor ratios are properly adjusted. Resistors R2A, R2B are equal and R3A, R3B are

equal. When resistors are properly sized, (2-20) gives the theoretical output voltage at Vref

where the overall TC should be near zero.

Notice this structure is only one implementation of the proposed method. One can

easily extend the general VGO ideal to various bandgap structures.

Page 41: Design and verification approaches for reliability and

28

Referring to the discussion of Section 2.3 , the practical TC of the circuit increases

with non-ideal factors such as resistor/current mirror mismatches, opamp offset, TC of

resistors (TCR) and etc. In the following subsection, we will talk about the effects of several

error sources based on the example circuit shown in Figure 2.10, and discuss the theoretical

possibility of reducing or removing these non-ideal error sources.

2.4 Discussion of Non-Ideal Error Source

As we emphasized in the introduction, this research is focusing on investigating the

fundamental theoretical efficacy of realizing the VGO extraction. So far, we have shown that

without the consideration of non-ideal source, we are able to generate a reference voltage

proportional to the VGO. In this section, we will derive the effects of several error sources on

the proposed VGO extraction and show the VGO extraction is still theoretical achievable when

these practical error sources are taking into considerations.

We will focus on the non-PTAT error sources showing in Table 2.1 since it is known

that those PTAT error sources can be simply removed by a single temperature trim [17]. In

particular, we will discuss the temperature dependence of resistors (TCR), temperature

dependence of BJT current gain () and opamp offset.

2.4.1 Temperature dependence of resistors (TCR)

For resistors, one good thing is the ratios instead of the absolute values of resistors are

what really matter. Thus, a typical design convention is to use the same type of resistors with

the same TCR. However, even if the same type of resistors is utilized, the TC of the output

voltage may still be affected. To illustrate this, suppose all the resistors R1-R4 have some

TCR with value 𝜆. If we still want Vref to be approximately equal to 𝑅4/𝑅1 ∗ 𝑉𝐺𝑂𝑟, then I4

should not be ideally temperature-independent and indeed we need to intentionally make

Page 42: Design and verification approaches for reliability and

29

𝐼4(𝑇) = 𝑉𝑟𝑒𝑓/𝑅4(𝑇) . In this case, (2-2) is no longer valid, and we should use (2-1) to

express VBE3 with

3

3

( ) 1

( ) 1 ( )r r

I T

I T T T =

+ − (2-21)

Based on this, (2-18) and (2-19) should be modified to become:

2

2 223

1( 1)

1

1 1 22

r

r rr

r

R T

R T TT

T

−−

= =+ −

+ −

(2-22)

( )2 3 2 2 2

2

1

1( ) ( 1) ( ) ( ) 1

1 2

ln

r rGOr BE r BE r BE r r

r r

r

kT kTV V T V T V T T

q q T TR

kTRn

q

−− + − + − − + + − =

(2-23)

These ratios will result in high-order temperature terms at Vref, and therefore, for applications

requiring extremely low TC, resistors with very low TCR are required.

2.4.2 Temperature dependence of BJT current gain

When a substrate BJT is used, it is actually biased through the emitter. Note that the

collector current of a BJT is a fraction of its emitter current where they are related by :

1

=

+ (2-24)

When temperature characteristic of is taking into consideration, equation (2-1) then

should be expressed as

constant

( ) ( ) ln ln

( )= ( ) ln

( )

( ) ( )

( ) ( )BE

E

r

GOr BE r GOr

r r

B

E r

E

r

T I TT kT T kTV T V V T V

T q T IT q

kT

q

T

TV T

T

=

= + − − +

+

(2-25)

Substitute the temperature characteristic of the showing at (2-5) into (2-25), we can

obtain [21]

Page 43: Design and verification approaches for reliability and

30

0

constant

0

(1 )

( ) ( ) ln

1r

r

TB

TB

X

BE BE XT

T

T

TkTV T V T

q

=

+

= +

+

(2-26)

This introduces additional curvature in the VBE(T) and it is only significant for small

values of 0 and large values of XTB [21].

In order to look into the effect of XTB on VBE(T), treat XTB as the variable in (2-26) and

take the Tylor expansion at XTB=0, we can obtain

constant

0

1( , ) ( , ) ln

(1 )r

BE BE

T

T

kV T XTB V T XTB T XTB

q =

= +

+ (2-27)

In (2-27), it can be seen that the coefficient of XTB is related to the basis function

Tln(T). In another word, it does not introduce new high order terms except T and Tln(T). As a

conclusion, the error induced by the temperature dependence of BJT current gain can be

trimmed out by adjusting the resistor ratios of 𝑅2/𝑅1 and 𝑅2/𝑅3.

2.4.3 Opamp offset

The offset of the opamp is another important error source which affects the derivation

of the resistor ratios in the VGO extraction. In the example circuit of Figure 2.10, two opamps

have been used, i.e., A1 and A2. To simplify the illustration, we will separately analyze them.

When the opamp offset of A2 is taking into consideration, the equivalent circuit can

be shown as Figure 2.11.

In this case, (2-17) needs to be modified as

4 1 1 12 2,3 2

1 2 3 3

lnref BE BE OS

R R R RkTV n V V V

R q R R R

= + + −

(2-28)

Page 44: Design and verification approaches for reliability and

31

+ −

R1R2B

VA VB

I1I2

vdd

R2A

Vo

gnd

Q1 Q2

R4

VRef

I4

1

I3

Q3

R3A

R3BINL

INL

n 1

A1

A2

Vos2

VC

Figure 2.11 Equivalent circuit when opamp offset of A2 is injected

Now, we repeat the procedure in section 2.3.2 for deriving the resistor ratios of

𝑅2/𝑅1 and 𝑅2/𝑅3. If VOS2 has no temperature drift, the resistor ratios of (2-18) and (2-19)

are still valid. This is because the eqation set of 0, and 0ln

ref ref

T Tr T Tr

V V

T T T= =

= =

will remain

the same if 𝜕𝑉𝑂𝑆2

𝜕𝑇= 0.

If VOS2 has a temperature drift, things will be slightly different. For simplicity,

suppose VOS2 has a constant temperature coefficient following the above-mentioned

procedure, we can obtain the following modified ratio for R2/R1

2 3 22

1

( ) ( ) ( ) ( 1) ( 1).

ln

GOr BE r BE r BE r r

r

V V T V T V T TR

kTRn

q

− + − − + −= (2-29)

In summary, the offset of opamp A2 can be trimmed out by adjusting the resistor

ratios even it has temperature drift.

When the opamp offset of A2 is taking into consideration, the equivalent circuit can

be shown as Figure 2.12.

Page 45: Design and verification approaches for reliability and

32

+−

R1R2B

VA VB

I1I2

vdd

R2A

Vo

gnd

Q1 Q2

R4

VRef

I4

1

I3

Q3

R3A

R3BINL

INL

n 1

A1

A2

Vos1

VC

Figure 2.12 Equivalent circuit when opamp offset of A1 is injected

In this case, (2-17) could not be modified straightforwardly. By writing the node

equation at VA and VB, we can obtain

2 1 2,1 1 2,3 1

2 1 3

2 2 2,3

2 3

4

1 1 1( ) ( ) ( )

1 1( )

BE OS BE OS BE OS

BE Q BE

ref

I V V V V V VR R R

I V I VR R

V IR

= − + − + −

= + +

=

(2-30)

From (2-30), the current flowing into Q2 will be

2 2,1 1

1 1 2 3

1 1 1 1( )Q BE OSI V V

R R R R= − + + (2-31)

It can be seen IQ2 is no longer a PTAT current which violates the original assumption.

It is worth to point out that to deal with the offset, existing offset techniques such as

chopping methods can be easily combined with the proposed method.

Page 46: Design and verification approaches for reliability and

33

Figure 2.13 Bandgap voltage versus absolute temperature and the tangent line for Tr=300K

2.5 Simulation Results

This section will demonstrate the capability of the proposed method of achieving a

low temperature coefficient. The circuit shown in Figure 2.10 was implemented in the

GlobalFoundries 130nm process, and t. The bandgap voltage versus absolute temperature is

shown in Figure 2.13. The tangent line for Tr=300K is also shown as a red dashed line from

which we can obtain the extrapolated value of VGO, i.e., VGO=VGOr =1.148V. P+ Poly resistor

with a positive TC1 and negative TCend is utilized, and it can be shown that when the W/L

ratio of the unit resistance is chosen to be 1u/5u, the TCR is about 0.5ppm/°C. In this design,

R1=18.16k, R2A=R2B=158.60k, R3A=R3B=48.51k, and R4=93.29k. The widely used 7-

transistor opamps are used as buffers. The resulting current consumption of this design is

103.7uA.

Figure 2.14 shows the simulation results for the output voltage over the temperature

Page 47: Design and verification approaches for reliability and

34

Figure 2.14 Output voltage over process

(a) (b)

Figure 2.15 Output voltage over process with (a)one-point and (b)two-points calibration

0 50 100

Temp(oC)

664.8

664.85

664.9

664.95

665

665.05

Vo(m

V)

Vo over Corner after Trim

tt

fs

sf

ff

ss

range 40°C to 125°C for five different process corners. The nominal TC is about 0.25ppm/°C

and worst-case TC value is 2ppm/°C. The output voltage level is about 665mV,

approximately equal to 𝑅4/𝑅1 ∗ 𝑉𝐺𝑂. Figure 2.15 shows one-point and two-point calibration

Page 48: Design and verification approaches for reliability and

35

results that reflect a worst-case TC value of about 0.7ppm/°C.

Table 2.2 summarizes the comparison of the proposed method to the state-of-the-art

high-precision voltage reference generators. It can be seen that the proposed method has the

potential of creating a voltage reference that has qualitatively better temperature dependence.

Table 2.2 Comparison with the state-of-the-art high-precision voltage reference generators

Ref. [18] [22]

[14] [16] [23] [15] [5] [24] This

work

Year 2015 2015 2015 2014 2014 2012 2012 2012 -

Publication TCAS ISSCC

TED TCAS Electron

. Lett. TCAS JSSC VLSI

Syp.

-

Supply (V) 1.2 1.3-2.6 1.2 1.2 1.6 2.5 0.9-5.5 1.5

Power (uA) 120 4.3 36 416 25 38 3.9 103

Reference(V) 0.735 1.21 1.1402 0.767 0.495 1.285 0.6177 0.615 0.665

Temp range

(C)

-40-120 -40-120 -55-125 -40-120 -40-125 -40-100 -15-150 -50-150 -40-125

Best TC

(ppm/C)

4.2 7 4.1 3.5 6 5 3.9 5.69 0.7

Average

TC(ppm/C)

9.3 - - - - - 15.6 - -

Samples 8 - 12 8 8 5 5 31 -

PSRR(dB) -30

@100k

- -54

@100

-37

@100k

- -55

@10k

- -

Area (mm2) 0.063 0.034 0.05 0.036 0.09 0.04 0.102 0.1 0.046

Type BG BG BG BG Sub-

BG

Curvatu

re

VGO

extract

ion

Process (um) 0.13 0.13 0.18 0.18 0.028 0.5 Bi 0.35 0.13 0.13

2.6 Conclusion

This chapter proposed a voltage reference generator targeted at extracting the silicon

band-gap value VGO from the temperature characteristic of the base-emitter voltage in a

bipolar transistor. The fact that VGO is temperature independent over a very wide temperature

range makes it possible to achieve a very low temperature coefficient. Analytical constraints

that lead to strategies for creating an output voltage equal to VGO when certain mismatches

and offsets are accurately trimmed were carefully investigated. Then the effects of several

non-ideal error sources on the proposed VGO extraction are discussed. It is shown that the VGO

Page 49: Design and verification approaches for reliability and

36

extraction is still theoretical achievable when these practical error sources are taking into

considerations. The proposed method was implemented in the GlobalFoundries 130nm

process. Simulation results show that the design can achieve temperature coefficients as low

as 0.7ppm/°C over the temperature range -40°C to 125°C.

The proposed VGO extraction has the potential of creating a voltage reference that has

qualitatively better temperature dependence. The study of the analytical constraints and

practical non-ideal error sources will enable future researches of precisely extracting the VGO

and creating extremely low temperature coefficient reference generators. This will, in turn,

benefit the high performance mixed-signal and radio-frequency systems.

Page 50: Design and verification approaches for reliability and

37

2.7 References

[1] P. K. T. Mok and K. N. Leung, “Design considerations of recent advanced low-voltage

low-temperature-coefficient CMOS bandgap voltage reference,” in Custom Integrated

Circuits Conference, 2004. Proceedings of the IEEE 2004, 2004, pp. 635–642.

[2] J.-H. Li, X. Zhang, and M. Yu, “A 1.2-V Piecewise Curvature-Corrected Bandgap

Reference in 0.5 m CMOS Process,” IEEE Trans. Very Large Scale Integr. VLSI Syst.,

vol. 19, no. 6, pp. 1118–1122, Jun. 2011.

[3] K. Ueno, T. Hirose, T. Asai, and Y. Amemiya, “A 300 nW, 15 ppm/°C, 20 ppm/V

CMOS Voltage Reference Circuit Consisting of Subthreshold MOSFETs,” IEEE J.

Solid-State Circuits, vol. 44, no. 7, pp. 2047–2054, Jul. 2009.

[4] Y. Tsividis, “Accurate analysis of temperature effects in I/SUB c/V/SUB BE/

characteristics with application to bandgap reference sources,” IEEE J. Solid-State

Circuits, vol. 15, no. 6, pp. 1076–1084, Dec. 1980.

[5] C. M. Andreou, S. Koudounas, and J. Georgiou, “A Novel Wide-Temperature-Range,

3.9 ppm/°C CMOS Bandgap Reference Circuit,” IEEE J. Solid-State Circuits, vol. 47,

no. 2, pp. 574–581, Feb. 2012.

[6] B. S. Song and P. R. Gray, “A precision curvature-compensated CMOS bandgap

reference,” IEEE J. Solid-State Circuits, vol. 18, no. 6, pp. 634–643, Dec. 1983.

[7] M. Gunawan, G. C. M. Meijer, J. Fonderie, and J. H. Huijsing, “A curvature-corrected

low-voltage bandgap reference,” IEEE J. Solid-State Circuits, vol. 28, no. 6, pp. 667–

670, Jun. 1993.

[8] G. Rincon-Mora and P. E. Allen, “A 1.1-V current-mode and piecewise-linear curvature-

corrected bandgap reference,” IEEE J. Solid-State Circuits, vol. 33, no. 10, pp. 1551–

1554, Oct. 1998.

[9] P. Malcovati, F. Maloberti, C. Fiocchi, and M. Pruzzi, “Curvature-compensated

BiCMOS bandgap with 1-V supply voltage,” IEEE J. Solid-State Circuits, vol. 36, no. 7,

pp. 1076–1081, Jul. 2001.

[10] “LTC6655 - 0.25ppm Noise, Low Drift Precision References - Linear Technology.”

http://www.linear.com/product/LTC6655.

[11] “ REF5050 | Series Voltage Reference | Voltage Reference | Description &

parametrics.” http://www.ti.com/product/REF5050.

[12] “ MAX6126 Ultra-High-Precision, Ultra-Low-Noise, Series Voltage Reference -

Maxim.” http://datasheets.maximintegrated.com/en/ds/3623.pdf.

Page 51: Design and verification approaches for reliability and

38

[13] R. Oberhuber, R. Prakash, and V. Ivanov, “A 1 ppm/°C bandgap voltage reference with

new second-order Taylor curvature compensation,” in 23rd IEEE International SOC

Conference, 2010, pp. 71–76.

[14] B. Wang, M. K. Law, and A. Bermak, “A Precision CMOS Voltage Reference

Exploiting Silicon Bandgap Narrowing Effect,” IEEE Trans. Electron Devices, vol. 62,

no. 7, pp. 2128–2135, Jul. 2015.

[15] Z. Zhou et al., “A 1.6-V 25-µA 5-ppm/ C Curvature-Compensated Bandgap Reference,”

IEEE Trans. Circuits Syst. Regul. Pap., vol. 59, no. 4, pp. 677–684, Apr. 2012.

[16] B. Ma and F. Yu, “A Novel 1.2–V 4.5-ppm/°C Curvature-Compensated CMOS Bandgap

Reference,” IEEE Trans. Circuits Syst. Regul. Pap., vol. 61, no. 4, pp. 1026–1035, Apr.

2014.

[17] G. Ge, C. Zhang, G. Hoogzaad, and K. A. A. Makinwa, “A Single-Trim CMOS

Bandgap Reference With a 3σ Inaccuracy of ±0.15% From −40°C to 125°C,” IEEE J.

Solid-State Circuits, vol. 46, no. 11, pp. 2693–2701, Nov. 2011.

[18] Q. Duan and J. Roh, “A 1.2-V 4.2- High-Order Curvature-Compensated CMOS

Bandgap Reference,” IEEE Trans. Circuits Syst. Regul. Pap., vol. 62, no. 3, pp. 662–

670, Mar. 2015.

[19] W. Bludau, A. Onton, and W. Heinke, “Temperature dependence of the band gap of

silicon,” J. Appl. Phys., vol. 45, no. 4, pp. 1846–1848, Apr. 1974.

[20] G. Bernardinis, “Adjustable second-order-compensation bandgap reference,”

US8547165 B1, 01-Oct-2013.

[21] M. A.P. Pertijs and J. H. Huijsing, “Precision temperature sensors in CMOS

technology”, Springer, 2006

[22] G. Maderbacher, S. Marsili, M. Motz, T. Jackum, J. Thielmann, H. Hassander, H.

Gruber, F. Hus, and C. Sandner, “5.8 A digitally assisted single-point-calibration CMOS

bandgap voltage reference with a 3 #x03C3; inaccuracy of #x00B1;0.08% for fuel-gauge

applications,” in Solid- State Circuits Conference - (ISSCC), 2015 IEEE International,

2015, pp. 1–3.

[23] D. F. Bowers and E. J. Modica, “Curvature-corrected low-noise sub-bandgap reference

in 28 nm CMOS technology,” Electronics Letters, vol. 50, no. 5, pp. 396–398, Feb.

2014.

[24] S. Sano, Y. Takahashi, M. Horiguchi, and M. Ota, “A sub-1V 3.9 uW bandgap reference

with a 3 inaccuracy of +-0.34% from -50C to +150 C using piecewise-linear-current

curvature compensation,” in 2012 Symposium on VLSI Circuits (VLSIC), 2012, pp. 22–

23.

Page 52: Design and verification approaches for reliability and

39

[25] W. Bludau, A. Onton, and W. Heinke, “Temperature dependence of the band gap of

silicon,” J. Appl. Phys., vol. 45, no. 4, pp. 1846–1848, Apr. 1974.

Page 53: Design and verification approaches for reliability and

40

CHAPTER 3. AUTO-IDENTIFICATION OF POSITIVE FEEDBACK LOOPS IN

MULTI-STATE VULNERABLE CIRCUITS

A systematic method is proposed for automatically identifying positive feedback

loops (PFLs) in analog/mixed-signal circuits. The method first converts the netlist of a circuit

into a directed dependency graph (DDG) that captures critical relationships among branch

currents and node voltages. It then utilizes graph theory techniques to find all feedback loops

from the DDG and, finally, develops criteria for determining the PFLs. Since multiple states

result from PFLs, this method could identify a circuit’s vulnerability to undesigned operating

points by considering circuit structure only without need for the computation of DC

solutions. The proposed approach has been implemented as a program and simulation results

show it could identify all PFLs very robustly.

3.1 Introduction

Many basic analog circuits, such as self-stabilized bias generators, voltage and

current references, and Schmitt-triggers [1,2,3], frequently utilized as subcircuits in large-

scale circuit, are well known to sometimes possess multiple DC operating points or multiple

states. The presence of multiple states sometimes causes these circuits to fail to function as

designed [4]. Therefore it is worthwhile to verify the presence of such multiple states before

the fabrication of circuits. Unfortunately, according to [5], the commonly used simulators

provide only one solution even though multiple states may be present.

The task of identifying circuits with multiple states can be addressed in two ways: (a)

by discovering more than one operating point, or (b) by identifying certain topological

structural features. Definitely, a circuit can be claimed to possess multiple states once more

than one operating points have been found. However, the known related work [6,7,8] is

oriented toward searching for all operating points which is time-consuming for even small-

Page 54: Design and verification approaches for reliability and

41

Figure 3.1 A feedback structure

scale circuits. The concept of developing topological criteria in helping analyze the operating

points of circuits has attracted many researchers’ attention. Nielsen and Willson

demonstrated that a necessary and sufficient condition for any transistor network to possess

more than one solution is that the topological substructure shown in Figure 3.1, termed a

feedback structure, be present [9]. Nishi derived several similar topological criteria for the

existence and uniqueness of solutions of nonlinear circuits containing controlled sources

[10]. Such theorems are very useful in structurally identifying multi-state vulnerable circuits,

especially for simple circuits where it can be done by inspection. Although a deterministic

algorithm for obtaining the complementary tree structure for Nishi’s criterion has been

proposed [11], it was still inefficient for large circuits. Also, since all of these efforts employ

diodes and bipolar junction transistors (BJTs) as nonlinear devices, these methods are not

applicable for CMOS circuits. Gajani proposed an approach [5] based on topology

partitioning for finding possible multiple solutions, enabling analysis of medium-size circuits

containing BJTs and/or MOSFETs. But no explicit feedback loop definition was provided,

and the lack of distinction between positive feedback loops and negative feedback loops

(NFLs) would increase the computation time.

In this chapter, we introduce clear definitions of PFLs and NFLs for analog/mixed-

signal CMOS circuits and bring a systematic approach to automatically identifying them. The

Page 55: Design and verification approaches for reliability and

42

proposed method is highly efficient in determining whether a circuit, especially a large-scale

circuit, is vulnerable in terms of multiple states, by avoiding the tedious work of computing

DC solutions. Locating sub-circuits containing PFLs allows easier application of intact-loop

or broken-loop continuation methods [12].

In the next section, several definitions for feedback loops based on circuit netlist are

introduced. In section 3.3 , the procedure for identifying PFLs is illustrated by applying the

algorithm to the bootstrapped 𝑉𝑡 reference circuit described in [12]. Section 3.4 reports the

PFLs identification results for several well-known circuits in which stable multiple operating

points often occur. Section 3.5 gives the summary of this work.

3.2 Feedback Loops

In this section, we will first discuss several definitions showing how to construct a

DDG from the netlist, followed by a definition of feedback loops derived from DDGs.

The netlist of a circuit is composed of a list of the instances used in a design.

Together with each instance is an ordered list of net names with connections to its pins. An

instance can include MOSFETs, resistors, diodes or independent sources. Nets are the wires

that connect instances together in the circuit, and pins are the connection points of an

instance.

Definition 1: define a Channel as the part between two pins of any instance that

conducts current from one pin to another; in a circuit, each instance has one channel. A

channel is denoted as 𝑐(𝑛1, 𝑛2), with 𝑐 being the name of the instance and 𝑛1, 𝑛2 being the

incident nets of the two pins, e.g., 𝑀1(𝑉12, 𝑔𝑛𝑑), representing the channel of 𝑀1 , as shown

in Figure 3.2.

Page 56: Design and verification approaches for reliability and

43

vdd

M1 M2

M3

M4 M5

V12

V21

I1 I2 V21

V12

I2I1

gnd

Figure 3.2 Inverse widlar (a) branch-current and controlling voltage (b) directed dependency graph

(a) (b)

Definition 2: define a branch in the netlist 𝑁 as a sequence of the form

𝑛𝑖0, 𝑐𝑗1(𝑛𝑖0, 𝑛𝑖1), 𝑛𝑖1, 𝑐𝑗2(𝑛𝑖1, 𝑛𝑖2), … . , 𝑐𝑗𝑘(𝑛𝑖𝑘−1, 𝑛𝑖𝑘), 𝑛𝑖𝑘

which consists of alternating nets 𝑛𝑖𝑡−1and channels 𝑐𝑗𝑡(𝑡 = 1, … , 𝑘) of netlist 𝑁 with any net

and any channel being visited at most once. The initial net 𝑛𝑖0 is the power supply net

(denoted as "𝑣𝑑𝑑") and the terminal net 𝑛𝑖𝑘 is ground (denoted as "𝑔𝑛𝑑"). The instances

contributing channels to a branch are called instances of that branch. A Branch Current (BC)

is defined as the current flowing through a branch.

For example, the left branch of the inverse widlar shown in Figure 3.2(a) can be

written as: 𝑣𝑑𝑑, 𝑀4(𝑣𝑑𝑑, 𝑉12), 𝑉12, 𝑀1(𝑉12, 𝑔𝑛𝑑), 𝑔𝑛𝑑 , where M4, M1 are the instances of

this branch and I1 is the BC.

Definition 3: consider a circuit having 𝑚 (𝑚 > 2) branches 𝐵1, 𝐵2, … , 𝐵𝑚 whose

corresponding BCs are 𝐼1, 𝐼2, … , 𝐼𝑚. Define a Controlling voltage (CV) as a voltage of any

net in 𝐵𝑗 (excluding "𝑣𝑑𝑑" and "𝑔𝑛𝑑", hereinafter the same) that controls the gate-source

voltage of any transistor of 𝐵𝑖 (𝑖, 𝑗 = 1, 2, … , 𝑚. 𝑖 ≠ 𝑗). The designation “controlling” means

Page 57: Design and verification approaches for reliability and

44

that, in small signal analysis, a small change of this controlling voltage will lead to a change

in the gate-source voltage and thus the branch-currents 𝐼𝑖.

A CV can be found in two cases: (1) the gate of any transistor of 𝐵𝑗 connects (directly

or through resistors, hereinafter the same) to a net of 𝐵𝑖, and this gate voltage is a controlling

voltage 𝑉𝑖𝑗; e.g., 𝑉12 and 𝑉21 in Figure 3.2 2(a); (2) if the source of transistor 𝐵𝑗 connects to a

net of 𝐵𝑖, this source voltage is a controlling voltage 𝑉𝑖𝑗. This relationship is described as

having two dependencies: current-to-voltage dependency 𝐼𝑖 → 𝑉𝑖𝑗 and voltage-to-current

dependency 𝑉𝑖𝑗 → 𝐼𝑗; e.g., 𝐼1 → 𝑉12 and 𝑉12 → 𝐼2 in Figure 3.2(a).

Definition 4: A directed dependency graph is a directed graph with nodes

representing either the branch current or controlling voltage and with oriented arcs

representing the two dependencies: for voltage-to-current dependency 𝑉 → 𝐼 , there is an

oriented arc going from node 𝑉 to node 𝐼; for current-to-voltage dependency 𝐼 → 𝑉, there is

an oriented arc going from node 𝐼 to node 𝑉. The DDG of Figure 3.2(a) is shown in Figure

3.2(b).

Definition 5: given a dependency graph, a feedback loop is defined as a connected

subgraph involving at least four nodes such that each node has only one arc leaving and one

arc entering. For example, based on Figure 3.2(b), the circuit of Figure 3.2(a) has one

feedback loop: 𝐼1 → 𝑉12 → 𝐼2 → 𝑉21 → 𝐼1.

The definition of PFL requires the concept of sign, so we will define PFL in the next

section after introducing the sign of dependency.

Page 58: Design and verification approaches for reliability and

45

vdd

M1

M2

M4 M3

R3

I1 I2

A

B

C

B

C

A

I1 I2M1 (B C gnd gnd)

M2 (A B C gnd)

M3 (A A vdd vdd)

M4 (B A vdd vdd)

R3 (C gnd)

gnd

(b)

(a)

(e)

M1 (B gnd)

M2 (A C)

M3 (A vdd)

M4 (B vdd)

R3 (C gnd)

(c)

B1: vdd, M4, B, M1, gnd

B2: vdd, M3, A, M2, C, R3, gnd

(d)

Figure 3.3 Bootstrapped Vt reference circuit (a) schematic (b) netlist (c) channels list (d)

branches (e) directed dependency graph

3.3 PFLs Identification

In this section, the procedure of identifying PFLs will be presented. First, how to

obtain BC and CV are presented. This is followed by a description of constructing a DDG

and identifying PFLs from DDG.

3.3.1 Analyze the Netlist

The netlist representation of a circuit is chosen for the algorithm. The most common

way for representing the circuit netlist is 𝑁(𝑉, 𝐸(𝑉)) with𝑉 = 𝑉1, 𝑉2, 𝑉3, … , 𝑉𝑛 being a set

of n instances and 𝐸(𝑣) = (𝑒1, 𝑒2, 𝑒3, … , 𝑒𝑚), 𝑚 = |𝑣| being the incident nets of

instance 𝑣(𝑣 ∈ 𝑉) [13]. Here, |𝑣| stands for the number of pins of 𝑣. For example, |𝑣| =

2 for resistors and diodes that are two-pin instances and |𝑣| = 4 for MOSFETs since they

Page 59: Design and verification approaches for reliability and

46

are modeled as four-pin instances. Figure 3.3(b) shows the netlist of the bootstrapped 𝑉𝑡

reference circuit shown in Figure 3.3(a). It’s a list of the instances used in the schematic

followed by their incident nets. Note that the incident nets of MOSFET have the following

ordering: drain, gate, source, and body, and it is assumed that the body of a PMOS is

connected to "𝑣𝑑𝑑" and body of an NMOS is connected to "𝑔𝑛𝑑".

3.3.2 Determine the Channel List

The channel list can be represented by 𝑁(𝑉, 𝐶(𝑉)) with 𝐶(𝑉) = 𝑐(𝑛1, 𝑛2) being the

channel of instance 𝑣 that can be derived from 𝐸(𝑣). Note that, when |𝑣| = 2, 𝐶(𝑣) is

equivalent to 𝐸(𝑣), and when |𝑣| ≥ 2, the only type of instance of concern is that of a

transistor. For MOSFETs, the channel is between the drain and source except when the drain

and source are incident to the same net and the MOSFET is functioning like a diode; in that

case, the channel of MOSFET is between the body and source. Figure 3.3(c) shows the

channel list of Figure 3.3(a).

3.3.3 Construct DDG

To construct a graph, we have to know the nodes and edges of it. The nodes of DDG

are branch-current nodes and controlling voltage nodes and the edges are the dependencies

between the two types of nodes. Both can be obtained by processing the circuit

netlist 𝑁(𝑉, 𝐸(𝑉)).

From the channel list 𝑁(𝑉, 𝐶(𝑉)) we can search the branches between net "𝑣𝑑𝑑" and

net "𝑔𝑛𝑑". This process is similar to finding all paths between two nodes in a graph[13].

Therefore, a depth-first search algorithm[14] can be applied to obtain the branches of a

Page 60: Design and verification approaches for reliability and

47

channel list. As an example, the branches of the channel list in Figure 3.3(c) are shown in

Figure 3.3(d).

According to definition 3, the controlling voltages can be identified by following

every branch and checking the gate-source connections of each transistor based on the circuit

netlist. There are several types of controlling voltages:

• If a source is fixed and the gate is incident to a net of any other branch, then the

gate voltage is a controlling voltage.

• If a gate is fixed and the source is incident to a net of any other branch, then the

source voltage is a controlling voltage.

• If both gate and source are incident to nets of other branches, both are controlling

voltages.

Here ‘fixed’ is defined as one net connected to "𝑣𝑑𝑑" , gnd, or an independent

source. Note that the diode-connected transistors are actually created two-terminal rectifying

devices and therefore are perceived as diodes when searching for controlling voltages. A

branch without transistors is termed a self-determining branch and no dependencies exist

between self-determining branches and other branches.

Take Figure 3.3(d) for example. Branch 𝐵1 has two transistors M4 and M1; from the

circuit netlist shown in Figure 3.3(b), we know that the gate of M4 is incident to net 𝐴 which

is a net of 𝐵2, so 𝐴 is a determining voltage and we obtain dependencies: 𝐼2 → 𝐴, 𝐴 → 𝐼1;

similarly, for M1 we have dependencies: 𝐼2 → 𝐶, 𝐶 → 𝐼1. For branch 𝐵2, since M3 is diode-

connected, it has one transistor M2 and the following dependencies can be obtained: 𝐼1 →

𝐵, 𝐵 → 𝐼2. The DDG of this circuit is shown as Figure 3.3(e).

Page 61: Design and verification approaches for reliability and

48

3.3.4 Identify Feedback Loops and Determine The Sign

Note that the DDG is a directed graph, so detection of feedback loops from DDG can

be achieved by utilizing standard graph theory techniques [12,17]. We adopted Johnson’s

method [16] that can find all the feedback loops of a graph in time bounded by 𝑂((𝑛 +

𝑒)(𝑐 + 1)) and space bounded by 𝑂(𝑛 + 𝑒) , where there are 𝑛 vertices, 𝑒 edges and 𝑐

feedback loops.

As an example, two feedback loops can be identified for the DDG shown in Figure

3.3(e). They are:

𝐼1 → 𝐵 → 𝐼2 → 𝐴 → 𝐼1 (3-1)

𝐼1 → 𝐵 → 𝐼2 → 𝐶 → 𝐼1 (3-2)

It is concluded in [9] that the presence of a feedback structure is a necessary condition

that any transistor network must satisfy to possess the property of bistability. To provide

more insight into this necessary condition, we will define PFLs and NFLs in the following

way:

First, the sign of each dependency has to be assigned. Given a dependency Y→X,

define the sign of this dependency to be the sign of ∂y/∂x in small signal analysis.

For voltage-to-current dependency Y→X, y is the voltage of the controlling voltage

Y and x stands for the current of branch-current X. Positive dependency implies that a small

increase in this voltage will lead to a current increase, and negative dependency implies that a

small increase in this voltage will lead to a current decrease. Similar arguments hold for

current-to-voltage dependencies.

The sign of dependencies can be summarized and classified into the eight categories

shown in Table 3.1.

Page 62: Design and verification approaches for reliability and

49

_

B

A

I1 I2

_

++C

BI1 I2

+ +

_+

(a) (b)

Figure 3.4 Sign of dependencies for Figure 3.2(e) (a) the upper loop (b) the bottom loop

Applying the criterion of Table 3.1 to Figure 3.3, we can obtain the sign for each edge

of these two loops, which is shown in Figure 3.4.

Table 3.1 The Sign of Different Dependencies

Voltage to current dependency

Sign Current to voltage

dependency

Sign

𝑉𝐺,𝑃𝑀𝑂𝑆𝑎 → 𝐼 − 𝐼 → 𝑉𝑆,𝑃𝑀𝑂𝑆 −

𝑉𝐺,𝑁𝑀𝑂𝑆 → 𝐼 + 𝐼 → 𝑉𝑆,𝑁𝑀𝑂𝑆 +

𝑉𝑆,𝑃𝑀𝑂𝑆 → 𝐼 + 𝐼 → 𝑉𝐷,𝑃𝑀𝑂𝑆 +

𝑉𝑆,𝑁𝑀𝑂𝑆 → 𝐼 − 𝐼 → 𝑉𝐷,𝑁𝑀𝑂𝑆 −

𝑎 . 𝑉𝐺,𝑃𝑀𝑂𝑆 stands for the gate voltage of PMOS transistor,

Now a positive feedback loop can be defined as a feedback loop containing a positive

even number of negative dependencies, and a negative feedback loop can be defined as a

feedback loop containing an odd number of negative dependencies.

For example, Figure 3.4(a) has two negative signs and Figure 3.4(b) has one negative

sign, meaning that (1) is a PFL and (2) is a NFL. It should be pointed out the dependency

I1→B has a different sign in the two loops. That is due to the fact that in the upper loop, B is

the drain of PMOS M4, while in the bottom loop, B is the drain of NMOS M1.

Page 63: Design and verification approaches for reliability and

50

I2I1

(a) (b)

VDD

M1

M3 M4

R1

R2

R4R3

M2

R5

M5

M7

I3

I4

M6A

D

B

CA

D

B

C

I1 I2 I3

I4

Figure 3.5 Voltage regulator (a) schematic (b) DDG

3.4 Simulation Results

In this section, we report the results of applying the proposed algorithm to the voltage

regulator and self-biased bandgap reference, circuit types where stable multiple operating

points often occur. The feedback loops are identified from the DDG. PFLs are designated by

determining the sign of each dependency for every feedback loop.

Figure 3.5 shows that the voltage regulator has three feedback loops given by: (3-3)-

(3-5)

𝐼4 → 𝐷 → 𝐼3 → 𝐶 → 𝐼4 (3-3)

𝐼4 → 𝐷 → 𝐼2 → 𝐵 → 𝐼3 → 𝐶 → 𝐼4 (3-4)

𝐼4 → 𝐷 → 𝐼1 → 𝐴 → 𝐼2 → 𝐵 → 𝐼3 → 𝐶 → 𝐼4 (3-5)

Figure 3.6 provides the dependency sign for (3-3)-(3-5), and it can be concluded that

(3-3) and (3-4) are NFL and (3-5) is PFL.

Page 64: Design and verification approaches for reliability and

51

(a)

A

D

B

C

I1 I2 I3

I4

D

C

I3

I4

D

B

C

I2 I3

I4

(b)

(c)

+

_

+

+

+

+

_+

+

+

_ _+ +

+

+

+

+

Figure 3.6 Sign of dependencies for each loop shown in Figure 3.5(b)

Figure 3.7 is another example schematic of a self-biased bandgap reference.

M14 M15 M1 M2

M3 M4

M10

M11M12 M13

R1 R3

VA

VB

gnd

I2I3 I5

I6 I7

vdd

R2

V1

Vo

V3

M9

V2

I4

M8

M7

M5

I1

M6

Vo

Vo1

Figure 3.7 Schematic of self-biased bandgap reference

Page 65: Design and verification approaches for reliability and

52

I1

I2

Vo1

V1 I3 I6

I7

VoVA

VB

I5V2 I4 V3

Figure 3.8 DDG of self-biased bandgap circuit shown in Figure 3.7

(a) (b)

(c)

(d)

I1

I2

Vo1

Vo

I5V2 I4 V3

I1

I2

Vo1

V1 I3

Vo

I5V2 I4 V3

I1

I2

Vo1

V1 I3 I6 VoVA

I1

I2

Vo1

I7

Vo

VB

_

+

+_

_

+ +_

+

+

_

+ _

+ _

+ _

_

++__

_

_

+_

+

+

_

_

+

+

I1

Vo

I5V2 I4 V3

(e)

+

_

++_

_

Figure 3.9 Sign of dependencies for each loop shown in Figure 3.8

Page 66: Design and verification approaches for reliability and

53

The DDG of Figure 3.7 is shown in Figure 3.8, from which five feedback loops can be

identified and the sign of their dependencies are shown in Figure 3.9. It can be concluded that

this bandgap reference has the two PFLs shown in Figure 3.9(a)-(b) and the three NFLs

shown in Figure 3.9(c)-(e).

3.5 Conclusion

This chapter introduces a novel method for identifying all feedback loops and

determining positive feedback loops in a circuit. This method depends on the DDG that

reflects the relationships of branch currents and node voltages in the circuit. Since positive

feedback loops are the sources of multiple states, this method could verify a circuit’s

vulnerability to multiple states simply by its structure, a big advantage in terms of efficiency,

especially for large-scale analog/mixed-signal CMOS circuits. The method has been

implemented as a program and simulation results show its effectiveness and efficiency in

identifying all feedback loops and determine whether a circuit is vulnerable to multiple

states.

Page 67: Design and verification approaches for reliability and

54

3.6 References

[1] G. C. M. Meijer and J. B. Verhoeff, “An Integrated Bandgap Reference,” Solid State

Circuits Conf. (ESSCIRC), 1975 First European, pp.40–41, 2–5, Sept. 1975.

[2] C. Zhao, J. He, S.-H. Lee, K. Peterson, R. L. Geiger and D. Chen, “Linear Vt-based

temperature sensors with low process sensitivity and improved power supply headroom,”

in Proc. IEEE Int. Symp. Circuits Systems,pp.2553–2556, May 2011.

[3] L. B. Goldgeisser, M. M. Green, “A method for automatically finding multiple operating

points in nonlinear circuits,” IEEE Trans Circuits Syst. I, vol. 52, pp776–84. 2005.

[4] Y. T. Wang, D.G. Chen, R. L. Geiger, “Practical methods for verifying removal of Trojan

stable operating points,” in Proc. IEEE Int. Symp. Circuits Systems, pp.2658-2661 May

2013.

[5] G. Gajani, A. Brambilla, and A. Premoli, "Numerical determination of possible multiple

DC solutions of nonlinear circuits," IEEE Trans Circuits Syst. I, vol. 55, pp. 1074–1083,

2008.

[6] J. F. Victor, H. M. Luis, S. R. Arturo, “Applying an iterative decomposed piecewise-

linear model to find multiple operating points,” in Proc. Europ. Conf. Circuit Theor. Des.

(ECCTD), pp. 978–981, 2007.

[7] S. Pastore, “Fast and efficient search for all DC solutions of PWL circuits by means of

oversized polyhedra”. IEEE Trans. Circuits Syst. I, vol. 58, pp. 2270–2279 , 2009.

[8] M. Tadeusiewicz, S. Hałgas, “A Contraction Method for Locating All the DC Solutions

of Circuits Containing Bipolar Transistors,” Circuits,Systems and Signal Processing, vol.

31, pp. 1159–1166, June 2012.

[9] R. O. Nielsen and A. N. Willson, “A fundamental results concerning the Topology of

transistor circuits with multiple equilibria,” Proc. IEEE, vol. 68, no. 2, pp. 196–208,

1980.

[10] T. Nishi and L. O. Chua, “Topological criteria for nonlinear resistive circuits containing

controlled sources to have a unique solution,” IEEE Trans. Circuits Syst., vol. CAS–31,

pp. 722–741, 1984.

[11] C. Mass, “Algorithmic remarks on the Nishi-Chua uniqueness criterion for electrical

networks containing controlled sources,” IEEE Trans Circuits Syst., vol. 36, pp1510-

1520

[12] H. Wen and M. M. Green, "Use of a continuation method for analyzing startup circuits,"

in Proc. IEEE Int. Symp. Circuits Systems, pp.1527–1530, May 2010.

Page 68: Design and verification approaches for reliability and

55

[13] C. J. Alpert, A. B. Kahng, “Recent directions in netlist partitioning: a Survey,” Integr.

VLSI J., vol.19, pp. 1–81, 1995.

[14] M. Migliore, V. Martorana, “An algorithm to find all paths between two nodes in a

graph,” Journal of Computational Physics, vol. 87, pp. 231–236, March 1990.

[15] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, Introduction to Algorithms,

2nd ed., MIT Press and McGraw-Hill, 2001, pp. 540–549.

[16] D. B. Johnson, “Finding all the elementary circuits of a directed graph,” SIAM J.

Comput., vol. 4, pp. 77–84, Mar. 1975.

[17] J.C. Tiernan, “An efficient search algorithm to find the elementary circuits of a graph,”

Communications of the ACM 13, pp. 722–726, 1970.

Page 69: Design and verification approaches for reliability and

56

CHAPTER 4. SYSTEMATIC BREAKING-LOOP METHOD FOR VERIFICATION

AGAINST UNDESIRED OPERATING POINTS

A systematic method is proposed for automatically identifying and breaking positive

feedback loops (PFLs) in a Trojan States Vulnerable Circuit. The method first converts the

netlist of a circuit into a directed dependency graph (DDG), then partitions the DDG into

strongly connected components (SCCs). It then employs graph theory technique to detect all

PFLs and locate breakpoints for every SCC. The proposed method can identify a circuit’s

vulnerability to Trojan States only its structure, avoiding the computation of DC solutions,

and it also can provide insight on how and where to break PFLs such that break-loop

continuation methods can be applied. With Sub-Bandgap reference and widlar-Banba

examples, it is demonstrated that the proposed approach can effectively identify all PFLs and

break-points.

4.1 Introduction

Many basic analog circuits, such as self-stabilized bias generators, voltage and

current references, and Sschmitt-triggers [1-2], are well known to possess multiple DC

operating points or multiple states; and these circuits are frequently utilized as subcircuits in

large-scale circuit. The presence of undesirable stable DC operating points (hereinafter we

use the designation Trojan States or TS to stand for “undesired stable DC operating points”)

sometimes causes these circuits to fail to provide proper function [3]. Therefore it is

worthwhile to obtain awareness of the presence of Trojan States before circuit fabrication.

Unfortunately, according to [4], the commonly used simulators provide only one solution

when TS are present.

The task of identifying circuits with Trojan States can be addressed in two ways: (a)

by finding more than one stable operating point or (b) by identifying certain topological

Page 70: Design and verification approaches for reliability and

57

structures. If using (a), it should be pointed out that there is no need to figure out all possible

operating points, since we can claim that a circuit possesses Trojan State once we found more

than one stable operating points. However, the known related work [5-7] has bren developed

to search for all operating points, a time-consuming process even for small-scale circuits. The

idea of developing topological criteria has attracted much research attention to helping

analyze the circuit operating points. Nielsen and Willson demonstrated that a necessary and

sufficient condition for any transistor network to possess more than one solution is that a

topological substructure, termed a feedback structure, be present [8]. Nishi derived several

similar topological criteria for the existence and uniqueness of the solutions of nonlinear

circuits [9]. Such theorems are very useful for structurally identifying TS-vulnerable circuits,

especially for simple circuits where it can be done by inspection. Later, a deterministic

algorithm for obtaining a complementary tree structure for Nishi’s criterion has been

proposed [10]. However, all of these efforts employ diodes and bipolar junction transistors

(BJTs) as nonlinear devices, so these methods are not applicable to CMOS circuits. In [4],

Gajani, based on topology partitioning, proposed an approach for finding possible multiple

solutions to analyzing medium-sized circuits containing BJTs and/or MOSFETs. But no

explicit feedback loop definition was provided; also, the lack of distinction between positive

feedback loops and negative feedback loops (NFLs) would increase the computation time. In

[11], an efficient break-loop homotopy method for verification against Trojan States was

proposed. It targeted searching only intervals containing TS by breaking PFLs instead of

computing operating points. However, it assumed that the PFLs were already known and

didn’t provide a systematic approach for breaking PFLs.

Page 71: Design and verification approaches for reliability and

58

This chapter introduces a systematic approach to automatically identifying and

breaking all the PFLs for analog/mixed-signal CMOS circuits. The proposed method

constructs a directed dependency graph (DDG) from the netlist of a circuit and partitions it

into strongly connected components (SCCs). For each SCC, it then utilizes graph theory

techniques to detect all the PFLs and locate the break-points (minimum set of nodes that can

open all the PFLs if removed). The located break-points allows easier application of intact-

loop or break-loop continuation methods [11-12]. A block diagram depicting a summary of

proposed methodology is shown in Figure 4.1.

The following section illustrates an approach to constructing a directed dependency

graph from the netlist through an example of the bootstrapped 𝑉𝑡 reference described in [12].

The SCC concept is also briefly described in this section. In section III, the procedure for

PFL detection and break-points identification for each SCC is introduced. Section 4.6

reports the identifying results of PFLs and breakpoints for two circuits. Section 4.7 gives a

brief summary of this work.

Obtain the circuit netlist

Construct the Directed Dependency

Graph

Partition the DDG into SCCs

For each SCC, detect the loops and

determine the sign of each loop

Identify the break-points for each

SCC

Figure 4.1 Flow chart of proposed method

Page 72: Design and verification approaches for reliability and

59

C

B

A1

I1 I2

(b)

A2

vdd

M1

M2

M4 M3

R3

I1 I2

B

C

gnd

(a)

A2A1

+

Figure 4.2 Broken PFLs for Wilson bias generator (a) Break at the schematic (b) Break at the DDG

4.2 Break-loop Homotopy Method

This section will first introduce the break-loop Homotopy method for circuits

containing PFLs and then discuss how to utilize that method to identify the presence or

absence of Trojan states.

Homotopy methods have been widely used to find DC operating points of a circuit

[10, 11]. Conventional Homotopy methods are known to suffer from time-efficiency issues,

especially when the resolution requirement is stringent. An improved break-loop Homotopy

method was proposed in [9, 12]. This method is effective and efficient for the purpose of

Trojan-state detection for three reasons: (1) It does not need to find all DC operating points.

Since whenever any solution rather than the designers’ given solution is found, the circuit

can be identified as having a Trojan state. (2) It targeted to search only for intervals

containing the operating points rather than computing exact values for operating points. (3) It

introduces a computationally-efficient contract-and-divide algorithm that dramatically

reduces computation time.

Page 73: Design and verification approaches for reliability and

60

The break-loop homotopy method first breaks all the PFLs at circuit nodes

corresponding to all vertices in the breakpoint set of the circuit. Each circuit node identified

by this process is broken into two nodes, one serving as an input node and the other serving

as an output node. An independent voltage source is then connected to each input node and,

if the input current is not zero, a dependent current source connected to the output node. By

sweeping the independent voltage sources throughout the predetermined operating range

(e.g., ground to Vdd), the relationship between the input and output voltage at each node pair,

termed the “return map”, can be obtained. Operating points of the circuit are the points on

the return map where the input and output voltages are equal.

A Wilson bias generator will again be used as an example to illustrate the procedure.

As shown in Figure 4.2, A is chosen as the breakpoint set. The vertex A in the DDG of

Figure 4.2 is broken into two vertices: A1 and A2 as shown in Figure 4.2(b). It can be seen

that A1 has an outgoing arrow and A2has an ingoing arrow, so in correspondence with the

circuit schematic of Figure 4.2(a), node A1 serves as an input node and node A2 serves as an

output node. Node A1 in Figure 4.2(a) is then connected to a voltage source and node A2is

left floating because its input current is zero.

The return map of A2 versus A1 at two different temperatures is shown in Figure 4.3.

An interesting observation is that this circuit has only one operating point at 25 oC but will

have three operating points at 125 oC.

Note that the example shown in Figure 4.2(a) only has one positive loop so the

breaking of the loop can be determined by inspection. However, many circuits that become

large and complex due to feedback structure and smart compensation techniques may contain

Page 74: Design and verification approaches for reliability and

61

Figure 4.3 Return map for Wilson bias generator (a) Blue: curve for VA1= VA2 (b) Red: return map

when temperature is 25oC (c) Black: return map when temperature is 125 oC

0 1 2 3 4 50

1

2

3

4

5

VA1

(V)

VA

2(V

)

Return Map for Wilson Circuit

VA2

=VA1

VA2

@ T=25oC

VA2

@ T=125oC

several positive feedback loops and determining where to break the loop is not that

straightforward, as will be further discussed in the next section.

4.3 A Multi-loop Example

In this section, a slightly more complicated example, a voltage regulating circuit by

Jullien [13], will be discussed. It should be pointed out that the feedback loops in this circuit

are nearly impossible to determine by inspection, and the circuit is ihighly vulnerable to

Trojan state that are virtually impossible to verify using existing standard methods.

The schematic of a low dropout (LDO) series voltage regulator is shown in Figure

4.4. This circuit is used to provide the power supply for a Bandgap Reference (BGR) that

also is used to generate bias voltages and tail current for an error amplifier. Note that while

there is only one PFL for each of the individual blocks, the LDO, the BGR, and theerror

amplifier, these blocks are coupled with one another, resulting in 31 PFLs and 30 NFLs

Page 75: Design and verification approaches for reliability and

62

VBG1

VBG1

VBG2

VBG2

Charge

PumpRectifier

RF1

RF2

M15 M16

M14M13

M12M11

M10M9

M8 M7

M6RF1

CF

M19

M20

M26 M25

Q1 Q2

M3

M4

M1M2

R1

C4

M22 M24

M21 M23

M29

M28

M27

M5

R3

R2

R5

R4

R’F2

R”F2

R6 R7

VDDB

VDDHStart-up Circuit

Power-on-Reset CircuitError Amplifier

BGR Core

VDD

A

C

B

D

G

E

F

HK

L

Figure 4.4 A full CMOS Voltage regulating circuit

(found by the proposed loop-identifying algorithm). It's safe to say that the normal human

mind would not be capable of manually detecting these many loops.

Even if the designers were to be aware of the existence of these loops, deciding how

to break all those PFLs still presents a great challenge. By applying the proposed method, the

break point set can be easily found. For example, one possible set is C, G, validated by

removing node C and G in the circuit DDG and verifying that no PFLs exist in the remaining

graph. The 2D break-loop Homotopy method described in [9] was next applied to node C and

G, producing the simulation results shown as Table 1. As an example, [0.82, 0.89] means that

an operating point exists when the voltage at node C is between 0.82~089V and the voltage

at node G is between 1.35~1.45V. It can be seen that the example circuit would have a

Trojan State at 125oC if a start-up circuit were not added.

Page 76: Design and verification approaches for reliability and

63

Table 4.1 Simulation Results of Voltage Regulating Circuit

W/wo Start-

up Circuit

Temperature

(oC) Have multi- State?

Solution Intervals for Nodes C and G

(V)

w/wo 25 No [0.82, 0.89]X[1.35, 1.45]

wo 125 Yes

[0.82, 0.89]X[1.35, 1.45]

[1.44, 1.51]X[1.35, 1.45]

[1.79, 1.86]X[1.35, 1.45]

w 125 No [0.65, 0.69]X[1.09, 1.25]

4.4 Strongly-Connected Components

In this section, we will first describe how to construct a directed dependency graph

(DDG) from the netlist of a circuit, then discuss how to decompose the DDG into strongly-

connected components (SCCs).

4.4.1 Constructing the DDG

Although some of the aspects regarding construction of the DDG have already been

described in the author’s previous work [13], to better introduce the proposed method, a

concise description of DDG construction will be given.

To create a graph, we need to obtain its nodes and edges. The nodes of the proposed

DDG include both branch-current nodes and controlling-voltage nodes, while the edges are

the dependencies between the two types of nodes. Since both the nodes and edges are

obtained through processing the circuit netlist and instance channels, a brief description of

those elements will be presented before discussing the DDG in detail.

Assume the circuit netlist is represented by 𝑁(𝑉, 𝐸(𝑉)) with 𝑉 = 𝑉1, 𝑉2, 𝑉3, … , 𝑉𝑛 being

a set of n instances and 𝐸(𝑣) = (𝑒1, 𝑒2, 𝑒3, … , 𝑒𝑚), 𝑚 = |𝑣| being the incident nets of

instance 𝑣(𝑣 ∈ 𝑉) [14]. Here |𝑣| stands for the number of pins of 𝑣 . For example, |𝑣| =

2 for resistors and diodes, two-pin instances, while |𝑣| = 4 for MOSFETs, since they are

Page 77: Design and verification approaches for reliability and

64

modeled as four-pin instances. Figure 4.5(b) shows the netlist, a list of the instances used in

the schematic followed by their incident nets. of the bootstrapped 𝑉𝑡 reference circuit shown

in Figure 4.5(a). Note that the incident nets of MOSFET are in order: drain, gate, source and

body.

From the circuit netlist 𝑁(𝑉, 𝐸(𝑉)) we can derive the channel list 𝐺(𝑉, 𝐶(𝑉)) with

𝐶(𝑉) = 𝑐(𝑛1, 𝑛2) being the channel of instance 𝑣, defined as the path between two pins of 𝑣

that conducts current from one pin to another. Note that 𝐶(𝑉) can be derived from 𝐸(𝑣), i.e.,

when |𝑣| = 2, 𝐶(𝑣) is equivalent to 𝐸(𝑣), and when |𝑣| ≥ 2, the only type of instance of

concern is the MOSFETin which the channel is between the drain and source except when

the drain and source are incident to a same net, in which case the MOSFET functions like a

diode, and in that case, the MOSFET channel is between the body and the source. For

example, Figure 4.5(c) shows the channel list corresponding to Figure 4.5(a).

vdd

M1

M2

M4 M3

R3

I1 I2

A

B

C

B

C

A

I1 I2M1 (B C gnd gnd)

M2 (A B C gnd)

M3 (A A vdd vdd)

M4 (B A vdd vdd)

R3 (C gnd)

gnd

(b)

(a)

(e)

M1 (B gnd)

M2 (A C)

M3 (A vdd)

M4 (B vdd)

R3 (C gnd)

(c)

B1: vdd, M4, B, M1, gnd

B2: vdd, M3, A, M2, C, R3, gnd

(d)

Figure 4.5 (a) schematic (b) netlist (c) channels list (d)

branches (e) directed dependency graph

Page 78: Design and verification approaches for reliability and

65

We now demonstrate how to search the branch-current nodes and controlling-voltage

nodes from the channel list 𝐺(𝑉, 𝐶(𝑉) as follows:

Taking the channel list 𝐺(𝑉, 𝐶(𝑉) as a graph, with a branch defined as a path

between vertex "𝑣𝑑𝑑" and vertex "𝑔𝑛𝑑" in 𝐺. For example, the branches of the channel list

of Figure 4.5(c) are shown in Figure 4.5(d). A branch is defined in this way because we want

our DDG to reveal relationships or dependencies between the current flowing in the branches

and the node voltages controlling the current. Since the process of searching the branches of

a channel list is similar to that of finding all paths between two nodes in a graph [15], a

depth-first search algorithm [16] can be directly applied.

According to [13], the controlling-voltages and the dependencies between the branch-

current and controlling-voltage can be identified by analyzing the relationships between the

current flowing in each branch and gate-source connections of each transistor.

Consider for example Figure 4.5(d). Branch 𝐵1 has two transistors M4 and M1, and

from the circuit netlist shown in Figure 4.5(b), we know that the gate of M4 is incident to net

𝐴 which is a net of 𝐵2, so 𝐴 is a controlling-voltage and we can designate the dependencies

as: 𝐼2 → 𝐴, 𝐴 → 𝐼1; similarly, for M1 we have dependencies: 𝐼2 → 𝐶, 𝐶 → 𝐼1. For branch 𝐵2,

since M3 is diode-connected, it has one transistor M2 and dependencies can be obtained

as: 𝐼1 → 𝐵, 𝐵 → 𝐼2. The DDG of this circuit is shown in Figure 4.5(e).

4.4.2 Strongly-Connected Components

A Strongly Connected Component 𝐻 of a directed graph or digraph 𝐺 is a directed

subgraph of 𝐺 such that for every pair of vertices 𝑢 and 𝑣 in 𝐻, there is a directed 𝑢 − 𝑣 path

and also a directed 𝑣 − 𝑢 path in 𝐻 [17]. By convention, the trivial graph (with only one

vertex) is strongly-connected.

Page 79: Design and verification approaches for reliability and

66

V1 V2

V4

V3

V5 V6

e1

e2

e3

e4

e5

e6

e7

e9

e8

Figure 4.6 Example directed graph

Any directed graph can be partitioned into a set of disjoint strongly-connected

components. For example, Figure 4.5(e) is itself strongly connected. The digraph shown in

Figure 4.6 has four disjoint SCCs: 𝐻1: (𝑉1, Ø), 𝐻2: (𝑉2, Ø), 𝐻3: (𝑉6, Ø),

𝐻4: (𝑉3, 𝑉4, 𝑉5, 𝑒4, 𝑒5, 𝑒6) . To decompose a digraph G into strongly-connected

components, Tarjan [18] presented an elegant algorithm with 𝑂(𝑛 + 𝑒) running time for an

input graph with 𝑛 vertices and 𝑒 edges.

The motivations for partitioning the DDG into SCCs are: on one hand, it enhances

efficiency of the break-loop homotopy method for verification against TS, especially for

large-scale circuits, since the break-loop method can be applied to each SCC independently;

on the other hand, it improves the process of detecting break-points. This will be further

discussed in the following section.

4.5 Identify and Break PFLs

In this section, the procedure for detecting the PFLs and then breaking them for each

SCC will be discussed. We will first give a brief overview of Feedback Vertex Set concepts

and then demonstrate how to utilize this graph theory technique to identify the break-points.

4.5.1 Identity Positive Feedback Loops

Notice that sinve each SCC is a directed graph, detecting feedback loops from an

SCC can be achieved by utilizing standard graph theory techniques. We have adopted

Page 80: Design and verification approaches for reliability and

67

Johnson’s method as described in [19] that can find all feedback loops of a graph in a time

bounded by 𝑂((𝑛 + 𝑒)(𝑐 + 1)) and space bounded by 𝑂(𝑛 + 𝑒), where 𝑐 is the number of

feedback loops. For example, two feedback loops can be identified for the DDG shown in

Figure 4.5(e). They are:

𝐼1 → 𝐵 → 𝐼2 → 𝐴 → 𝐼1 (4-1)

𝐼1 → 𝐵 → 𝐼2 → 𝐶 → 𝐼1 (4-2)

According to the criteria described in [13], (4-1) is a PFL and (4-2) is a NFL. It

should be pointed out that all trivial SCCs with |𝑉| = 1 have no loops and all non-trivial

SCCs with |𝑉| ≥ 2 have at least one loop. For example, for Figure 4.6, component 𝐻4 has

only one loop: 𝑉3 → 𝑉4 → 𝑉5 → 𝑉3.

4.5.2 Break Positive Feedback Loops

We use breakpoints to represent a minimum set of controlling-voltage nodes which

can break all the PFLs if removed in a DDG. The concept of Feedback Vertex Set (FVS) can

be adopted to help locate the break-points. It is briefly described as follows:

Let 𝐺 be a directed graph. A Feedback Vertex Set 𝐹 for 𝐺 is a set of vertices in 𝐺

such that every directed cycle in 𝐺 contains at least one vertex in 𝐹, or equivalently, that the

removal of 𝐹 from graph 𝐺 leaves a directed acyclic graph. Here, if we define FVS to have

the minimum number of vertices, then a FVS can be used as break-points. Note that the

break-points for a digraph is not unique, even though its size is unique. For example, both

𝐴 and 𝐵 can be used as break-points for the digraph of Figure 4.5(e).

The FVS problem is a classic NP-complete problem that appeared in the first list of

NP-complete problems in Karp’s paper [20]. It is practically efficient in our application since

(i) the DDG has been partitioned into SCCs such that the size of each SCC is small (ii) it is

Page 81: Design and verification approaches for reliability and

68

P3

P0

N4

N5

P1 P2

N0

P4P5

N2 N3N1

P6

D

F

E

C

A

B

G

Q2

Q1

vdd

gnd

I1I2 I3

I4

I5

Figure 4.7 Schematic of the Sub-Bandgap reference

assumed that the size of breakpoints 𝐹 for each SCC satisfy |𝐹| ≤ 2 where |𝐹| is the size of

breakpoints. Assumption (ii) is reasonable because the |𝐹| > 2 means that a circuit would

have more than two coupled PFLs, which would be rare for practical circuits. |𝐹| > 2 also

means that, for the break-loop continuation method, at least three voltage source would

inefficiently need to be inserted and swept simultaneously.

[21] discusses the parameterized FVS problem on directed graphs (DFVS) defined as

follows: given a digraph 𝐺 and a parameter 𝑘, either construct a FVS of at most 𝑘 vertices for

𝐺 or report that no such set exists. In this work, the DFVS problem is resolved with running

time 4𝑘𝑘! 𝑛𝑂(1) so it can be applied to our case when parameter 𝑘 = 2, and is practically

efficient because of this small value of 𝑘.

4.6 Results

In this section, the effectiveness of the proposed approach is demonstrated by

reporting the results of applying the algorithm to both the Sub-Bandgap reference circuit

reported in [22] and the widlar-Banba circuit. The strongly-connected component is

identified for both circuit and also PFLs and breakpoints are pointed out for each SCC.

Page 82: Design and verification approaches for reliability and

69

I2

I1

A

B

I3C

FI4 G

I5E

H1

H2

Figure 4.8 DDG showing SCCs of Figure 4.7

Figure 4.7 is the schematic of a Sub-Bandgap reference circuit. Figure 4.8 shows that

it has two SCCs: 𝐻1 , 𝐻2 , where 𝐻1 has one NFL and 𝐻2 has three PFLs. The size of

breakpoint for 𝐻2 is 2 that can be A, C. Figure 4.9(a) is the schematic of the widlar-Banba

circuit, Figure 4.9(b) shows that it has two SCCs: 𝐻1 , 𝐻2, where 𝐻1 has two PFLs and

𝐻2 has one PFL. The size of break-points for 𝐻1 is 1 that can be 𝑉𝑜 . The size of

breakpoints for 𝐻2 is 1 that can be either 𝑉2 or 𝑉3.

4.7 Conclusion

This chapter introduces a novel method of identifying all the PFLs in a circuit and

determine breakpoints for breaking all PFLs. The method first constructs the DDG and

partitions it into SCCs, then utilizes graph theory techniques to detect all the PFLs and locate

breakpoints for each SCC. On one hand, the method can verify a circuit’s vulnerability to

Trojan States simply by its structure since positive feedback loops are the sources of Trojan

States; on the other hand, the method provides a systematic approach for how and where to

break PFLs such that break-loop continuation methods can be applied. The proposed

approach will be demonstrated through two examples with results that show it can effectively

identify all the PFLs and breakpoints.

Page 83: Design and verification approaches for reliability and

70

M11 M12 M1 M2

M3 M4

M9 M10

R1 R2

VAVB

gnd

I2 I3

I5 I6

vdd

R2

V1

Vo

Vbias

I4

M8

M7

M5

I1

M6

Vo

Vo1

M15 M16

M17

M13 M14

V2

V3I7 I8

M18

M19 M20

I9

Vbias

Banba Widlar

V4

(a)

I1

I2

Vo1

V1 I3 I5

I6

Vo

VA

VB

I9Vbias I4 V4

I8

I7

V2

V3

H1 H2

(b)

Figure 4.9 Widlar-banba circuit (a) schematic (b) DDG showing the strongly connected components

Page 84: Design and verification approaches for reliability and

71

4.8 References

[1] G. C. M. Meijer and J. B. Verhoeff, “An Integrated Bandgap Reference,” Solid State

Circuits Conf. (ESSCIRC), 1975 First European, pp.40–41, 2–5, Sept. 1975.

[2] C. Zhao, J. He, S.-H. Lee, K. Peterson, R. L. Geiger and D. Chen,“Linear Vt-based

temperature sensors with low process sensitivity and improved power supply

headroom,” in Proc. IEEE Int. Symp. Circuits Systems,pp.2553–2556, May 2011.

[3] Y. T. Wang, D.G. Chen, R. L. Geiger, “Practical methods for verifying removal of

Trojan stable operating points,” in Proc. IEEE Int. Symp. Circuits Systems, pp.2658-

2661 May 2013.

[4] G. Gajani, A. Brambilla, and A. Premoli, "Numerical determination of possible multiple

DC solutions of nonlinear circuits," IEEE Trans Circuits Syst. I, vol. 55, pp. 1074–1083,

2008.

[5] J. F. Victor, H. M. Luis, S. R. Arturo, “Applying an iterative decomposed piecewise-

linear model to find multiple operating points,” in Proc. Europ. Conf. Circuit Theor. Des.

(ECCTD), pp. 978–981, 2007.

[6] S. Pastore, “Fast and efficient search for all DC solutions of PWL circuits by means of

oversized polyhedra”. IEEE Trans. Circuits Syst. I, vol. 58, pp. 2270–2279 , 2009.

[7] M. Tadeusiewicz, S. Hałgas, “A Contraction Method for Locating All the DC Solutions

of Circuits Containing Bipolar Transistors,” Circuits,Systems and Signal Processing,

vol. 31, pp. 1159–1166, June 2012.

[8] R. O. Nielsen and A. N. Willson, “A fundamental results concerning the TSology of

transistor circuits with multiple equilibria,” Proc. IEEE, vol. 68, no. 2, pp. 196–208,

1980.

[9] T. Nishi and L. O. Chua, “Topological criteria for nonlinear resistive circuits containing

controlled sources to have a unique solution,” IEEE Trans. Circuits Syst., vol. CAS–31,

pp. 722–741, 1984.

[10] C. Mass, “Algorithmic remarks on the Nishi-Chua uniqueness criterion for electrical

networks containing controlled sources,” IEEE Trans. Circuits Syst., vol. 36, pp. 1510-

1520, 1989.

[11] Y. Li and D. Chen, “Efficient analog verification against Trojan states using divide and

contraction method,” in 2014 IEEE International Symposium on Circuits and Systems

(ISCAS), 2014, pp. 281–284.

[12] H. Wen and M. M. Green, "Use of a continuation method for analyzing startup circuits,"

in Proc. IEEE Int. Symp. Circuits Systems, pp.1527–1530, May 2010.

Page 85: Design and verification approaches for reliability and

72

[13] Z. Liu, Y. Li, R. L. Geiger, and D. Chen, “Auto-identification of positive feedback

loops in multi-state vulnerable circuits,” in 2014 IEEE 32nd VLSI Test Symposium

(VTS), 2014, pp. 1–5.

[14] C. J. Alpert, A. B. Kahng, “Recent directions in netlist partitioning: a Survey,” Integr.

VLSI J., vol.19, pp. 1–81, 1995.

[15] M. Migliore, V. Martorana, “An algorithm to find all paths between two nodes in a

graph,” Journal of Computational Physics, vol. 87, pp. 231–236, March 1990.

[16] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, Introduction to Algorithms,

2nd ed., MIT Press and McGraw-Hill, 2001, pp. 540–549.

[17] K. Ruohonen,“Graph theory,” pp. 28, 2013.

[18] R. Tarjan, “Depth-first search and linear graph algorithms,” SIAM J. Comput., pp. 146–

160, 1972.

[19] D. B. Johnson, “Finding all the elementary circuits of a directed graph,” SIAM J.

Comput., vol. 4, pp. 77–84, Mar. 1975.

[20] R. M. Karp, “Reducibility among combinatorial problems,” Complexity of Computer

Computations, R. E. Miller and J. W. Thatcher, Eds. Plenum Press, New York, pp. 85-

103, 1972.

[21] J. Chen, Y. Liu, S. Lu, B. O'sullivan, I. Razgon. “A fixed-parameter algorithm for the

directed feedback vertex set problem,” Journal of the ACM (JACM), vol.55, October

2008.

[22] B. G. Adriana, T. L. Viswanathan, T.R.Viswanathan, “A Low-Supply-Voltage CMOS

Sub-Bandgap Reference,” IEEE Trans. Circuits Syst. II, vol. 55, pp. 609–613 , 2008.

Page 86: Design and verification approaches for reliability and

73

CHAPTER 5. IMPROVING TIME-EFFICIENCY OF FAULT-COVERAGE

SIMULATION FOR MOS ANALOG CIRCUIT

In analog fault simulation, a number one challenge is that simulation time could grow

rapidly and become prohibitive as circuit size becomes large. This chapter proposes a

systematic method for significantly improving time efficiency in estimating fault coverage

for analog fault simulation. In the proposed method, a circuit under test (CUT) is first

partitioned into independent sub-circuits. This is accomplished by mapping the circuit into a

graph, decomposing the graph into strongly connected components (SCCs), and generating a

sub-circuit for each SCC. The impacts of potential faults directly entering a sub-circuit are

then simulated and recorded using the sub-circuits, and this would be expected to be

considerably more time efficient than fault simulation using the much larger whole circuit.

Finally, fault detectability at the given test-points is evaluated based on the fault impacts and

sensitivity among the different sub-circuits. As a first step toward quick estimation of fault

coverage, this chapter focuses on DC testing. Simulation results show that fault coverage of

DC tests can be estimated sufficiently accurately with simulation time being reduced by 10X

for the benchmark circuit, or by approximately the number of SCCs. For a much larger

circuit, the number of SCCs is expected to be much larger and the time-saving factor would

be much larger.

5.1 Introduction

During the past few years, there has been a rapid integration of semiconductor chips

into automotive and other mission-critical systems in which failure or malfunction may result

in great loss or severe impact on human life, so there naturally is increasing pressure to

guarantee that the underlying integrated circuits (ICs) be fault-free, i.e., to ensure that circuits

with manufacturing defects are detected and rejected by fault-coverage testing in production.

Page 87: Design and verification approaches for reliability and

74

Since it might take months for inadequate test coverage to be revealed by, for example, an

excessive number of customer-returned faulty devices[1], [2], it is then often too late to

modify the design and/or develop new tests to increase fault coverage. Fault simulation is an

effective, economical approach to evaluating the coverage of a given test that provides

immediate feedback to both design and test engineers such that improved design and test

procedures can be achieved to increase production-test coverage before devices are shipped

to customers.

After decades of innovation, fault coverage simulation for digital circuits has

achieved great success, with test escape rates reaching below 0.1 defective parts per million

(dppm) [3], [4]. However, fault simulation for analog circuits has lagged far behind, and

there is a lack of existing commercially-available analog fault simulators [5]. Although

analog circuits typically constitute only a small fraction of modern mixed-signal ASICs, they

represent a major cause of customer returns in the industry [3], [6], so there is an urgent need

to develop practical and efficient methods for analog fault simulation at reasonable cost and

time.

One bottleneck that has made the development of commercial analog fault simulators

impractical is the amount of time and cost for simulating the impractically large number of

potential faults in industrial circuits. For example, as is reported in [5], simulating 2068

defects of an industrial circuit takes about 72 hours. Various improvements to fault

simulation have been proposed, including sampling techniques [5], [7]–[9] and simulation

frameworks [10], [11]. Goncalves and Teixeira [7] employed stratified sampling to group the

number of overall possible defects into homogeneous sub-groups. Guerreiro, et al.,

[8]proposed a fault list compression technique that partitioned the fault list into strata and

Page 88: Design and verification approaches for reliability and

75

identified a set of “representative” faults. Ozev, et al., [9], [12]–[14] developed several

methods targeting near zero dppm test quality, including methods based on outlier analysis,

importance sampling modeling, and fault probability models. Sunter, et al., [5] proposed

likelihood-weighted random sampling (LWRS) to select the smallest number of potential

defects. Blanton, et al., [10], [11] proposed fast and accurate defect simulation frameworks

based on layout-injected defects. In summary, most of these methods focused on reducing the

number of simulated faults to save simulation time while maintaining required quality levels.

This chapter introduces a novel method focusing on reducing the time required for

simulating each single faulty circuit. The central idea is to simulate partial circuits instead of

an entire circuit using a directed-dependency graph to partition a large circuit into relatively

small independent sub-circuits. The time for simulating a sub-circuit is expected to be much

less than the time for simulating the much larger whole circuit. In particular, the impacts of

potential faults directly entering a sub-circuit are simulated and recorded using the sub-

circuits. The fault detectability and overall fault coverage at given test-points are evaluated

based on the recorded fault impacts and sensitivity among different sub-circuits. Circuit

partition is accomplished by creating a directed dependency graph from the circuit netlist,

identifying the SCCs of the graph, and generating a sub-circuit for each SCC.

The objective of this chapter is not to cover all types of faults or to improve analog

fault coverage, but to estimate fault coverage with sufficient accuracy in a shorter time

compared to that used by conventional methods for a given test set. As a first step toward

quick estimation of fault coverage, this chapter focuses on DC tests. The time saved can be

used for more tests, e.g., AC or transient, under given simulation time constraints. Recently,

Dobbelaere, et al., [15] have pointed out the desirability of DC tests for analog fault coverage

Page 89: Design and verification approaches for reliability and

76

analysis due to their low cost, widespread applicability and availability. It has been shown

that fault coverage can be improved at very low cost by introduction of new DC fault models

and testing approaches [15].

A benchmark circuit composed of most widely-used analog blocks will be utilized to

demonstrate and validate the proposed method. Simulation results show that fault coverage

can be estimated sufficiently accurately with simulation time reduced by 10X, approximately

the number of SCCs. For a much larger circuit, the number of SCCs is expected to be much

larger and the time-saving factor would be correspondingly larger.

The remainder of this chapter is organized as follows. Section II previews a skeleton

of the proposed method. Section III illustrates how to construct the DDG for an example

circuit. Section IV describes how to partition a circuit into SCC sub-circuits and the

procedure for performing fault simulation based on the SCC sub-circuits. Section V describes

how to combine the simulated fault impacts with backward sensitivity analysis to evaluate

fault coverage. Section VI demonstrates the effectiveness of the proposed method by

applying the method to a benchmark circuit. Section VII and Section VIII offer discussion

and conclusions, respectively.

5.2 Overview of Proposed Method

Before discussing the proposed approach in detail, let us define several terms used

throughout this chapter. A defect is an unintended physical change in the manufactured

circuit. A fault is a defect that causes a circuit component to fail or not meet rated

specifications. Faults can be of two types: catastrophic and parametric. A catastrophic

fault, or hard fault, is defined as a fault that leads to a change in circuit topology. Hard faults

include short and open circuits. A parametric fault, also called a soft fault, is a fault that

translates into variations in the component parameters. At the circuit or product level, a

Page 90: Design and verification approaches for reliability and

77

defective part is one whose specifications do not meet the rated specifications, due either to

fault(s) in the circuit or other causes.

Fault coverage (FC) is an important test metric used to express test quality of an

integrated circuit. It is defined as the percentage of modeled faults that can be detected by the

test. Another widely-used quality metric is defect level (DL) or test escapes [8], defined as

the ratio of the number of faulty devices shipped to customers to the total number of devices

shipped. DL can be expressed as a function of FC by the well-known Williams-Brown

equation [16]. To meet a high level of quality, it is necessary to minimize DL and maximize

FC. Quantitatively predicting defect levels using fault coverage is difficult, but achieving

high fault coverage does ensure low DL and high quality[17].

Fault simulation is an approach to FC estimation that injects hypothetical physical

defects into a design and verifies that the manufacturing test or verification suite can detect

them. The widely-used fault-oriented methodology [18] follows three phases: 1) obtain the

detection limits at the test-points by simulating the fault-free circuit C0; 2) under single fault

assumption, inject the fault list 𝐹=F1, F2, … Fn one by one into the designed circuit C0

[19] to create faulty circuits C1, C2, … , Cn; 3) simulate each faulty circuit and report fault

detection failure if the results violate detection limits. During fault simulation, a “single

fault” assumption, meaning that only one fault will occur in a circuit at a time, is typically

made.

In conventional analog fault simulation, the number one challenge is that the overall

simulation time could grow exponentially and become prohibitively long as circuit size

becomes large. This occurs mainly because the number of sites for potential faults in modern

mixed-signal circuit blocks can be impractically large, e.g., tens of thousands [5]. To worsen

Page 91: Design and verification approaches for reliability and

78

Circuit netlist

Strongly connected

components

Directed dependency

graph

Fault simulation

SCC Sub-circuits

Fault coverage

evaluation

Faulty Sub-circuits

Given

Fault list

Reduced acyclic

graph

Figure 5.1 Flowchart of the proposed method

the problem, as circuit size increases, the time for simulating every faulty circuit will increase

significantly. For example, simulating every fault may require time ranging from minutes to

days [2]. Sampling or selecting “representative” faults from the fault list offers one way to

reduce simulation time that been explored in various literature references [5], [7], [8].

Another way to reduce simulation time is to relax simulator accuracy, but this will inevitably

reduce the estimation accuracy of fault coverage and the achievable speedup is only 2~10X

[5].

In this work, a new method for significantly reduce the time required for simulating

each faulty circuit Ci (i=1,2…n) will be introduced. The proposed method, complementary to

the mentioned sampling techniques, can be readily combined with these techniques to either

significantly reduce simulation time for a given sampled subset of the fault list, or simulate

significantly more faults (larger sampled subset) within a given time budget.

The flowchart of the proposed method is illustrated in Figure 5.1. The circuit netlist is

Page 92: Design and verification approaches for reliability and

79

first converted to a directed dependency graph (DDG). Then, using graph theory techniques,

the DDG are partitioned into a set of disjoint strongly connected components (SCC). The

SCCs information is made use of in two aspects. On one hand, it is utilized to reduce the

DDG to a simple acyclic graph where each super vertex stands for one SCC. On the other

hand, a sub-circuit, termed a SCC sub-circuit, is created for each SCC,. Using these SCC

sub-circuits and the given fault list 𝐹 , faults 𝐹𝑖 (i = 1,2 … n) are injected to the

corresponding SCC sub-circuits one-by-one to create n faulty circuit Ci′(i = 1,2 … n). These

faulty circuits, generated based on SCC sub-circuits, are each much smaller in size than the

faulty circuit Ci (i=1,2…n) generated based on the whole circuit. The impacts of potential

faults directly entering a sub-circuit are then simulated and recorded using the sub-circuits, a

process expected to be much more time-efficient than fault simulation of the whole circuit.

Finally, the fault detectability at the given test-points is evaluated based on the fault impacts

and a reduced acyclic graph.

5.3 Directed Dependency Graph

In this section, we will first illustrate how to construct the DDG for the simple

example circuit shown in Figure 5.2. SCC concepts will then be defined and identified.

5.3.1 Directed Dependency Graph

The concept of directed dependency graphs (DDG) has been widely used in general

and by the authors in [20], [21] to successfully address analog verification issues and achieve

excellent results. An EDA tool was developed and implemented in Cadence Virtuoso to

automatically convert a circuit netlist to a DDG. An important property of the DDG is that it

captures critical dependencies between the voltages and currents of a circuit. For the purpose

of decomposing a circuit to a sub-circuit, this property is very useful because it allows one to

Page 93: Design and verification approaches for reliability and

80

V1 V2

V3

e1

e2

e3

Figure 5.2 A simple directed graph example

know which voltages and currents are correlated. In this chapter, the DDG will be defined in

a similar manner and demonstrated through the example circuit.

In graph theory, a directed graph G is a pair (V, E) where: 1) V is a set whose

elements are called vertices. 2) E is a set of ordered pairs of vertices, called directed edges or

arcs. The arc from vertex 𝑢 to vertex 𝑣 is written as (𝑢, 𝑣) and the other pair (𝑣, 𝑢) is the arc

in the opposite direction. Figure 5.2 shows a simple example of a directed graph. The circles

stand for vertices and the labels inside the circles refer to vertex names, hence 𝑉 =

𝑉1, 𝑉2, 𝑉3. The oriented arrows represent the directed edges, hence 𝐸 = 𝑒1, 𝑒2, 𝑒3. The

graph in Figure 5.2 can therefore be expressed as

𝐺 = (𝑉1, 𝑉2, 𝑉3, (𝑉1, 𝑉2)(𝑉3, 𝑉2), (𝑉2, 𝑉3))

Now we will apply this directed graph concept to define the DDG of a circuit and

illustrate it through the example circuit shown in Figure 5.3(a).

A node of a circuit refers to a point where two or more circuit elements meet. For two

nodes to be different, their voltages must be different. For example, 𝑉1 and 𝑉𝑜 are two nodes

of the circuit shown in Figure 5.3(a). To avoid confusion, the term “node” will be used only

when describing a circuit schematic and “vertex” will be used with reference to graphs

throughout the rest of this chapter.

For a circuit under test(CUT), a directed dependency graph is defined as a directed

graph DDG(V, E), where the vertex set V represents all voltages and currents in the circuit

Page 94: Design and verification approaches for reliability and

81

M3 M4

M1 M2

V1

V2

I1

I4

M5

M6

I9

Vo

M9

M7

M8

I3

I6IR1 R1

I2I5I7

I8

I9

gnd

vdd

V3

V4

(a)

I1

I4

I3

V1

V2

I5

I6

I9

IR1V3

I2

Vo

I7

I8

V4

(b)

Figure 5.3 Example circuit: Widlar bias generator, (a) schematic (b) DDG

and the edge set E stands for the directed dependencies between voltages and currents. The

sets V and E of a DDG will be described in detail below.

First, the vertex set V of a DDG(V, E) has two types of vertices: a voltage vertex and

a current vertex.

• A voltage vertex represents the voltage at a node in a circuit.

For notational convenience, we will label a voltage vertex using the corresponding

node name. For example, 𝑉1, 𝑉2 are two voltage vertices for the circuit in Figure 5.3(a).

Page 95: Design and verification approaches for reliability and

82

• A current vertex is defined as the total physical current across a device in the

circuit.

We denote a current vertex as I(X, Y, GATE) or I for simplicity. It refers to the

current flowing from node X to node Y. Note that if we have MOSFETS that directly

contribute current to this I, then GATE is the set of nodes to which the gates of these

MOSFETs are connected; otherwise, GATE is an empty set. As an example, I1(vdd, V2,

V1) stands for the current I1 shown in Figure 5.3(a) that flows from “vdd” to “V2”. In this

case there is only one MOSFET M1 that contributes current to I1, hence its GATE has only

one element V2 that stands for the gate of M5.

Second, the edge set E of a DDG(V, E) is composed of all possible directed

dependencies between two vertices in V. A directed dependency is defined based on the

definition of current vertex.

Given a current vertex I(X, Y, GATE), or I for simplicity, there are five possible

directed dependencies 𝑋 → 𝐼, 𝐼 → 𝑋, 𝑌 → 𝐼, 𝐼 → 𝑌, 𝐺𝐴𝑇𝐸 → 𝐼.

To make this definition clearer, four things should be pointed out. 1) The arrow “→”

is used to represent the direction of dependency. For example, 𝑋 → 𝐼 represents the

dependency from 𝑋 to 𝐼. Each directed dependency corresponds to a directed edge in the

DDG, e.g., (𝑋, 𝐼). 2) The dependency 𝐺𝐴𝑇𝐸 → 𝐼 is composed of dependencies from each

element in 𝐺𝐴𝑇𝐸 to 𝐼. 3) The concept of “dependency”, e.g., 𝑋 → 𝐼 means that the partial

derivative of 𝐼 with respect to 𝑋 will be non-zero. In other words, a small change in the value

of 𝑋 will cause a change in the value of 𝐼. 4) The word “possible” is used to reflect that, if X

is vdd, then 𝐼 → 𝑣𝑑𝑑 is not a dependency because it is assumed that power supply (e.g. vdd

or gnd in Figure) will not be affected by the internal circuit. On the other hand, 𝑣𝑑𝑑 → 𝐼 is a

Page 96: Design and verification approaches for reliability and

83

dependency by definition but will not be included in the DDG, because since there will be no

faults occurring at power supply, there is no need to include supply-related dependencies

(Remember that the purpose of the DDG is to investigate the relationships of internal nodes).

As a result, if X is vdd, the dependencies will be 𝑌 → 𝐼, 𝐼 → 𝑌, 𝐺𝐴𝑇𝐸 → 𝐼. Similarly, if Y is

gnd, the dependencies will be 𝑋 → 𝐼, 𝐼 → 𝑋, 𝐺𝐴𝑇𝐸 → 𝐼.

Now, based on the above definitions, we will show how to construct the DDG for the

circuit shown in Figure 5.3(a). First, it can be shown that the circuit has five voltage vertices

and nine current vertices, i.e., V=vdd, gnd, V1, V2, V3, V4, Vo, I1, I2, …, I9. Second,

twenty-six directed dependencies can be identified. Finally, the DDG of Figure 5.3(a) is

shown in Figure 5.3(b). The circles represent voltage or current vertices and the oriented

arrows represent the directed dependencies. This process can be performed automatically and

efficiently using the mentioned EDA tool with running time linear with circuit size.

5.3.2 Strongly-Connected Components

The strongly-connected component is an important concept in standard graph theory.

Any directed graph can be partitioned into a set of disjoint strongly-connected components.

Several graph theory terms summarized below will be used through this chapter .

Let G= (V, E) be a directed graph:

• A path in 𝐺 is a finite sequence of alternating vertices and

edges: 𝑣𝑖0, 𝑒𝑗1, 𝑣𝑖1, 𝑒𝑗2, … , 𝑒𝑗𝑘 , 𝑣𝑖𝑘 , where directed edge 𝑒𝑗𝑡 = (𝑣𝑖𝑡−1, 𝑣𝑖𝑡) for 𝑡 = 1,2, … 𝑘 .

Any vertex or edge is visited at most once.

• A directed graph 𝐻 is strongly-connected if for every pair of vertices in 𝐻, say

𝑢 and 𝑣, there is at least one path from 𝑢 to 𝑣 and at least one path from 𝑣 to 𝑢. By

convention, the trivial graph (with only one vertex) is strongly-connected.

Page 97: Design and verification approaches for reliability and

84

I1

I4

I3

V1

V2

I5

I6

I9

IR1V3

I2

Vo

I7

I8

V4

SCC1 SCC2 SCC3

Figure 5.4 The SCCs for the DDG shown in Figure 2.3(b)

• A Strongly-Connected Component (SCC) 𝐻 of 𝐺 is a subgraph of 𝐺 such that 𝐻 is

strongly-connected, but if we add any vertices or arcs to 𝐻, it is no longer strongly

connected.

• A sink SCC of G is an SCC that has no edges leaving it. A source SCC of G is an

SCC that has no edges entering it. A directed graph has at least one sink SCC and

one source SCC.

A detailed description of an SCC can be found in [22]. The most important property

of an SCC is that, for vertices 𝑢 and 𝑣, if 𝑢 and 𝑣 are in the same SCC, then 𝑢 and 𝑣 will have

bi-directional dependency, meaning that any voltage or current change at 𝑢 (𝑣) will cause

voltage or current change at 𝑣 (𝑢) following the 𝑢 − 𝑣 (𝑣 − 𝑢 ) path. On the other hand, if

𝑢 and 𝑣 are in different SCCs, then 𝑢 and 𝑣 will have one-directional dependency. This SCC

property provides the basis for portioning a circuit into sub-circuits. Only one-directional

dependency can exist between nodes in different sub-circuits. Details will be presented later.

To decompose a digraph G into strongly-connected components, Tarjan [23]

presented an algorithm with a 𝑂(𝑛 + 𝑒) running time, for an input graph with 𝑛 vertices and

𝑒 edges. As an example, after applying Tarjan’s algorithm to the DDG shown in Figure

Page 98: Design and verification approaches for reliability and

85

5.3(b), three SCCs can be identified. They are shown in Figure 5.4 as SCC1~SCC3 and

dashed shadows are used to separate them.

For convenience in describing the method, we define an output vertex 𝑉𝑜 of a SCC 𝐻

as a vertex with outgoing edges leaving H. Similarly, an input vertex 𝑉𝑖 is defined as a vertex

with incoming edges. These input/output vertices are the interconnection points among

different SCCs. For example, in Figure 5.4, 𝑉4 is the output vertex of SCC1 and I9 is the

input vertex of SCC2.

5.4 Fault Simulation with Sub-circuits

In this section, we will show how to make use of the constructed graph to partition a

target circuit into smaller sub-circuits called “SCC sub-circuits”. The procedure and time

efficiency of performing fault simulation based on the SCC sub-circuits will then be

discussed.

5.4.1 SCC Sub-circuits

Notice that the DDG is created in such a way that every vertex has a corresponding

node or an instance in the circuit schematic, so one can easily map the SCC back to a circuit

netlist, i.e., find all the nodes and instances for an SCC because instance connections inside

an SCC sub-netlist are inherent from the original fault-free circuit. To generate a netlist that

can be executed by simulators like Spectre or UltraSim, additional manipulations must be

performed at the interconnection points among different SCCs. This idea is summarized in

the following procedure:

1) Find the circuit nodes that correspond to the input/output vertices of the SCCs.

2) Break these nodes into a pair of “breaking points”. For each “breaking points” pair,

one side is the output vertex of the preceding SCC and the other side is the input vertex of the

succeeding SCC.

Page 99: Design and verification approaches for reliability and

86

M7

M8

I7

I8

V4

vdd

gnd

M3 M4

M1 M2

V1

V2

I1

I4

M9

I3

IR1R1

I2

I9

gnd

vdd

V3

M5

M6

Vo

I6

I5

vdd

Vdc=V4,desired

Vdc=V1,desired

gnd

(a)

M3 M4

M1 M2

V1

V2

I1

I4

M9

I3

IR1 R1

I2

I9

gnd

vdd

V3

M5

M6

Vo

I6

I5

vdd

Vdc=V4,desired

gnd

(b)

Figure 5.5 (a) SCC sub-circuits of example widlar circuit (b) a sub-circuit

generated from the combination of SCC2 and SCC3

3) Connect an independent voltage source to the side that is an SCC input. The

nominal voltage at this “broken node” is set to that of the added voltage source. In other

words, the results from simulating the fault-free circuit can be used, because under the single

fault assumption, when we perform fault simulation for a specific SCC, other parts of the

circuit are fault-free.

Following this procedure, the circuit is partitioned into sub-circuits whose number is

equal to the number of SCCs, so as a result, each SCC sub-circuit will contain all instances

that contribute current vertices to that SCC. The preceding SCC sub-circuit does not load the

succeeding SCC sub-circuit, because if this were not the case, there would have existed

Page 100: Design and verification approaches for reliability and

87

another dependency from the succeeding SCC to the preceding SCC in the DDG and these

two SCCs would have merged into one SCC. In other words, the “broken” nodes are

typically transistor gates with infinite impedance.

Figure 5.5(a) shows the SCC sub-circuits of the example widlar circuit, with three

SCC sub-circuits that correspond to the three SCCs in the DDG of Figure 5.4 identified. The

input vertex of SCC2 is V4 , so a voltage source with Vdc=V4,desired is added. Similarly, the

input vertex of SCC3 is V1 , so a voltage source Vdc=V1,desired is added.

Now, for a hypothetical potential fault 𝐹𝑖, we first determine the SCC sub-circuit that

Fi will directly impact and denote the determined sub-circuit as C0′. Fi is then injected into

C0′ to create a faulty circuit Ci′. By comparing the simulation results of the fault-free sub-

circuit C0′ and the faulty circuit Ci′, voltage or current changes at the output vertices of this

SCC can be determined. These voltage or current changes are termed “fault impacts”, a term

used throughout this chapter. Notice that this process of performing fault simulation for a

potential fault essentially follows the standard three-phase fault-oriented methodology

mentioned in Section II, with the major difference that the proposed method uses sub-circuits

rather than the whole circuit. For example, when simulating a short-circuit fault between

drain and source of transistor M8, the SCC1 sub-circuit will be utilized because M8 is an

instance in the SCC1 sub-circuit. The fault impact will then be obtained at the output node

V4. It should be noted that, if required, a sub-circuit can be generated from the combination

of two or more adjacent SCCs. For example, when simulating the short-circuit fault between

V1 and Vo, SCC2 and SCC3 can be combined to generate a sub-circuit as shown in Figure

5.5(b). Moreover, the user could choose to always use the sub-circuit of Figure 5.5(b) for all

faults in SCC2 and SCC3.

Page 101: Design and verification approaches for reliability and

88

The above procedure is repeated for all potential faults in a fault list 𝐹, and it can be

seen that the faulty circuit Ci′(i = 1,2 … n) generated based on SCC sub-circuits is much

smaller in size than the faulty circuit Ci (i=1,2…n) generated based on the whole circuit.

That is why the simulation time of the proposed method is significantly reduced. This is

extremely advantageous especially when the circuit is large. More details related to time

efficiency will be discussed in the next subsection.

5.4.2 Time Efficiency

In this subsection, we will compare the time efficiency for the proposed sub-circuit

based fault simulation with that for conventional fault simulation.

Suppose a) simulation time is linear with circuit size; b) the time for simulating the

fault-free circuit C0 is approximately equal to the time for simulating a faulty circuit Ci

(i=1,2…n). Then, for conventional fault simulation, the total time 𝑇𝑐𝑜𝑛𝑣 can be expressed as:

0 0

1

n

conv

i

T t n t=

= = (5-1)

where 𝑛 is the number of faults in the fault list and 𝑡0 is the time for simulating the fault-free

circuit C0.

Similarly, for the proposed sub-circuit based fault simulation, the total time 𝑇𝑝𝑟𝑜𝑝 can

be expressed as:

1 1

, withm m

prop j j j

i j

T k t k n= =

= = (5-2)

where 𝑛 is the number of faults in the fault list, 𝑚 is the number of SCCs, 𝑡𝑗 is the time for

simulating a fault-free sub-circuit 𝑗, and 𝑘𝑗 is the number of faults related to sub-circuit 𝑗. To

provide more insight into the difference between 𝑇𝑐𝑜𝑛𝑣 and 𝑇𝑝𝑟𝑜𝑝, we assume that all SCC

Page 102: Design and verification approaches for reliability and

89

sub-circuits have equal size such that 𝑡𝑗 =𝑡0

𝑚, for 𝑗 = 1,2, … , 𝑚. With this assumption, Eq. (5-

2) can be simplified to:

0

1

mconv

prop j

i

t TT k

m m=

= (5-3)

From Eq. (5-3), we can see that the proposed method reduces the fault simulation

time by a factor approximately equal to the number of SCCs. This conclusion is made based

on the assumption that simulation time is linear with circuit size. In reality, simulation time is

typically nonlinear with circuit size, and this will most likely result in a larger time-saving

factor.

In summary, a method for partitioning the CUT into multiple sub-circuits has bee

described in this section. Using these sub-circuits, an efficient fault simulation can be

performed for a given fault list. We will next discuss how to utilize the simulated results to

evaluate the fault coverage.

5.5 Fault Coverage Evaluation

In the previous section we identified the sub-circuits for each SCC such that fault

impacts could be simulated and obtained at output vertices of the SCC sub-circuits. This

section will show how to combine the simulated fault impacts with backward sensitivity

analysis to more effectively evaluate the fault coverage.

As is discussed in section II, a fault is reported as detected if the simulation results

violate the detection limits, the bounds of the accepted voltage or current ranges at the test-

points. The decision function g(), defined by Eq. (5-4), is used to decide whether a given IC

should be passed as good or failed as faulty for a given measurement.

1 ( )

( )0 ( )

nom L nom Upass if D Dg

fail otherwise

+ +=

. (5-4)

Page 103: Design and verification approaches for reliability and

90

where is a measured current or voltage variable at the observation points, nom is the

nominal value of ; DL is the lower detection limit, a negative number, and DU is the upper

detection limit, a positive number. DL and DU can be provided by the designer, based on

production test limits, or based on Monte-Carlo simulations. Approaches to optimal setting of

detection limits based on obtaining faulty and fault-free probability distributions from

Monte-Carlo analysis are presented in [24], [25]. In this chapter, the test-points and

corresponding detection limits are assumed to have been determined, and for simplicity these

detection limits are assumed to be symmetric with respect to the nominal value, meaning that

|DL| is equal to DU , and we can denote either of them simply as D.

Note that while the detection limits are obtained at the test-points for the whole

circuit, in the proposed method fault impacts are obtained at nodes that correspond to the

output vertices of the SCC sub-circuits, and these nodes do not necessarily belong to the

given tests points , so certain manipulations must be performed to build connections between

the fault impacts at SCC outputs and the detection limits at the overall test points. A method

based on a simple weighted graph and sensitivity analysis is proposed for accomplishing this.

5.5.1 Directed Acyclic Graph

First of all, let us introduce another graph technique to reduce the DDG to a simple

acyclic graph for convenience in performing backward sensitivity analysis. Assuming that a

directed graph G is decomposed into SCCs, if one uses a single super-vertex to represent

each SCC, the resulting graph will be ‘shrunk’, and this shrunk graph is guaranteed to be a

directed acyclic graph ( DAG) with no loops [26]. There is motivation to apply this graph

manipulation in the DDG because there only forward paths will remain in an acyclic graph,

so backward sensitivity analysis will be straightforward.

Page 104: Design and verification approaches for reliability and

91

To designate an SCC, rather than using one super-vertex, we will use the

corresponding output vertices of each SCC because the fault impacts are characterized at the

output of each SCC. Among these output vertices, edges will be drawn from vertex 𝑢 to

another vertex 𝑣 if 𝑢 can reach 𝑣 in graph G. The gain in edges can be calculated using

various methods such as Mason’s formula [27] or state-space equations [28] that are outside

the focus of this chapter. The method we adopted to calculate these gains can be briefly

summarized by the following three steps. First, a weighted sensitivity graph is created for

each SCC. Second, using the weighted graph, the input/output gain for each SCC will be

calculated using standard methods [28]. Third, repeat the above procedure for all SCCs

(except source SCCs). The result will be to obtain gains among the output vertices of all

adjacent SCCs because the inputs to an SCC are the output vertices of its preceding SCCs.

As an example, the simplified directed acyclic graph corresponding to Figure 5.4 is

shown in Figure 5.6. The fault impacts for SCC1, SCC2, and SCC3 related faults will be

referred to V4, V1 and Vo , respectively. The gain from V4 to V1 is denoted as G1 and the gain

from V1 to Vo is G2.

5.5.2 Backward Sensitivity Analysis

Sensitivity-based methods such as LIMSoft [29] for analog fault testing have been

previously investigated. The LIMSoft method evaluates the effects of all hard faults on the

output parameters by use of two SPICE circuit simulations and generates a test vector

V1 VoV4

G1 G2

DoD1/oD4/o

SCC1 SCC2 SCC3

Figure 5.6 The directed acyclic graph for Figure 5.3

Page 105: Design and verification approaches for reliability and

92

through gradient functions, so it requires a ‘linear’ assumption for the entire circuit. In the

proposed method, we combine the circuit partitioning and sensitivity analysis. In particular,

the fault impacts at the output of each SCC sub-circuit still rely on simulations and only the

sensitivities among the SCC outputs are calculated and used to evaluate the fault coverage, so

the proposed method is expected to have better fault coverage estimation accuracy while at

the same time reducing simulation time.

With the weighted acyclic graph introduced in the previous subsection, we now can

show how the proposed backward sensitivity analysis works. Suppose 𝑉𝑜 is the chosen test

point for the example circuit and the detection limit at 𝑉𝑜 is 𝐷𝑜 . The sensitivity analysis

begins at the SCC3 related faults. If the impact in 𝑉𝑜 due to a fault is greater than |𝐷𝑜|, this

fault can be detected at vertex 𝑉𝑜 and will be reported as detected, otherwise it will be

reported as undetected. When all SCC3-related faults have been checked, we will move

backward one level in the DAG. Following the edge from 𝑉1 to 𝑉𝑜, the equivalent detection

limit at 𝑉1 is calculated to be 𝐷1/𝑜 = 𝐷𝑜/𝐺2,labeled in red text in the DAG shown in

Figure 5.6. Notice that we call this an “equivalent detection limit” because it is the fault

impact required for SCC2 related faults to be detected at 𝑉𝑜 (not at 𝑉1). Similarly, if the

impact in 𝑉1 due to a SCC2 related fault is greater than |𝐷1/𝑜|, this fault can be detected at

vertex 𝑉𝑜 and we will report this fault as detected. Although the proposed method does not

make a “linear circuit” assumption, we use small-signal local linearization in the fault-free

circuit for the purpose of propagating the detection limits from the test-points to the various

nodes of the circuits. If a fault impact (obtained by simulating a sub-circuit) is large and

exceeds the linear range, this implies that the fault is detected.

Page 106: Design and verification approaches for reliability and

93

Continuing with backward propagation in this manner, we can obtain a list of all

faults that can be detected at vertex 𝑉𝑜, and if a circuit has multiple test-points, we can do the

same for each of them. A fault will be detected as long as it is reported as detected at one test

point. Finally, the fault coverage is evaluated as the number of faults that could be detected

divided by the total number of faults in the fault list that will be simulated. It can be

expressed as Eq. (5-5).

Number of detected faults

FCNumber of simulated faults

= (5-5)

During backward sensitivity analysis, there are two situations that should be made

clear because in these situations the calculation of gains and equivalent detection limits will

not be a straightforward as in the above simple DAG example. One such situation is when

multiple vertices exist in some SCCs, and another is when multiple paths exist from one

vertex to a test point. These situations will be described and addressed by the following

discussion.

First, as has been mentioned, while we use corresponding output vertices (possibly

more than one) to represent each SCC in the directed acyclic graph, in the directed acyclic

graph example shown in Figure 5.6, each SCC only has a single output vertex. Figure 5.7(a)

shows an artificial DAG where SCC1 has two output vertices N1 and N2. By the definition

of SCC we know that there will be paths from N1 to N2 and paths from N2 to N1, even if we

do not show them in the DAG. In such a case, there will be multiple independent equivalent

detection limits from every output vertex of SCC1 to all its succeeding SCCs. For example,

the equivalent detection limits for N1 and N2 can be calculated and illustrated as in Figure

5.7(b). D1/3 is the calculated detection limit at N1 for SCC1-related faults to be detected at

Page 107: Design and verification approaches for reliability and

94

N3 and D1/4 is the calculated detection limit at N1 for SCC1-related faults to be detected at

N4.

Second, when multiple paths exist from a vertex to a test point, multiple equivalent

detection limits will be obtained for the same vertex. Even though we still call them

equivalent detection limits, they are intermediate quantities and not true detection limits. To

illustrate this, consider the simplified graph shown in Figure 5.8, and suppose there are m

paths from N1 to N2, so that m equivalent detection limits, 𝐷1/2(𝑖)

(𝑖 = 1,2, … , 𝑚) will be

obtained at vertex N1. When m is one, the single equivalent detection limit obtained is the

true detection limit. The example DAG of Figure 5.6 is in this category. When m is greater

N2N1

D2D(1)1/2

D(2)1/2

D(m)1/2

Figure 5.8 A simplified graph where multiple paths exist from one vertex to a

test point vertex to a test point

N1 N3

N4N2

D3

D4

N1 N3

N4N2

D3

D1/3

D4

D2/3

D1/4

D2/4

SCC1G1

G2

G3

G4

(a) (b)

Figure 5.7 (a)an artificial DAG where SCC1 has two output vertices N1 and

N2; (b) calculation of equivalent detection limits for N1 and N2

Page 108: Design and verification approaches for reliability and

95

than one, we need to calculate the true equivalent detection limit. We know that the gains of

these paths can be obtained by

2

1/2

( 1,2,..., )i

DG i m

D= = . (5-6)

All the paths with positive gains can be added to obtain the net gain of all the positive gain

paths, 𝐺𝑝. Similarly, all the negative gains can be combined to get 𝐺𝑛.

Now, if the absolute values of 𝐺𝑝 and 𝐺𝑛 are close to one another, all faults in this

SCC have low sensitivity at the test point. To mathematically decide whether the absolute

values are close, we calculate the relative difference (dr) between the absolute value of 𝐺𝑝

and 𝐺𝑛 as:

( )

100%.,

p n

r

p n

G Gd

mean G G

−= (5-7)

Whenever dr is less than a chosen 𝛿, say 5%, then all faults in this SCC are reported as

undetected at this vertex.

If dr is greater than the chosen 𝛿 , the true equivalent detection limit 𝐷1/2 can be

calculated by Eq. (5-8).

2

1/2

i

p n

DD

G G=

+. (5-8)

The delta parameter is an indication of how close the gains in the positive and

negative paths can be before declaring the sensitivity to be too low. If delta is chosen to be

very small, we could be overestimating the sensitivity, and we could label the fault as

detectable when it might not be, resulting in a more liberal estimate of fault coverage than the

true fault coverage. On the other hand, if delta is chosen to be very large, we could be

underestimating the sensitivity, and the fault could be labeled as undetected even when it

Page 109: Design and verification approaches for reliability and

96

T55

T56

T57

T58

T47

T48

T49

T50

T12

T14

T16

T18

VDD

T15

T17

T11

T13

T33

T34

T31 T32

T59

T60

T61

T62

T51

T52

T53

T54

T20

T22

T24

T26

VDD

T23

T25

T19

T21

T28

T27

T29 T30

T2

T4

T6

T8

T5

T7

T1

T3

T9

T10

T36T35

T37

T63

T64

T39T40

T41 T42

T44T43 T46

T45

VD

DV

SS

VSS

VSS

R9

T8 C2

V2

V3 V4

V1

R6

R6

R5 R2R3 R1

T38

p6

p7

p8

wp3

wp4

wp3

wp4

wp3

wp4

wp3

wp4

b2

b1

p5

p4

wp1

wp2

p9

p10

n6

n7

n8

n4

n2

n6

n6

n6

n1 wn1

wn2

wn1

wn2

wn1

wn2

wn3

wn4

b3

n5

vin vip

vin vip

b3

b1

b2

b4

Vr

vo1 vout

vstart

Vr Vr

VrVr

Vaa

Vab

VabVaa

Vr

vpa vpbvpbvpa

vnbvna

vnbvna

P-cascode

biasing

Opamp

biasing 1

P-type

WidlarOpamp core

N-cascode

biasing

Opamp

biasing 2

N-type

WidlarBanba

Simulation Setup

vip

vin vout

Opamp core

R4

Vref

generator

Vref

Figure 5.9 Benchmark circuit

might be detectable, a more conservative estimate of fault coverage. In the implementation, a

flag will be raised when dr is small to suggest that additional tests are required to determine

whether more accurate fault coverage estimation is needed.

It should be mentioned that, in the fault coverage evaluation process, the running time

is 𝑂(𝑚), where m is the number of SCCs. This time is insignificant compared to the time

required for fault simulation. Furthermore, the running time associated with generating the

DDG and SCC sub-circuits is also linear with circuit size, so fault simulation dominates the

overall running time of the proposed method.

5.6 Case Study

In this section, the proposed method is applied to the benchmark circuit shown in

Figure 5.9, chosen because it is composed of widely-used analog blocks such as a bandgap

Page 110: Design and verification approaches for reliability and

97

SCC4

SCC1

SCC2

SCC12

SCC10SCC5

SCC9

SCC6

SCC11

SCC7

SCC3

Vstart

Vr

vo1

vinwp3,wp4

b1,b2

wn1,wn2

b3

wn1,wn2

SCC8wp3,

wp4

Opamp Core

Banba core

Star-up

circuit

N-type

Widlar

P-type

Widlar

P-cascode

biasing

Opamp

biasing 1

Opamp

biasing 2

N-cascode

biasing

Vr

Vref

generator

wp3,wp4

wn1,wn2

Figure 5.10 A ‘simplified’ graph of the benchmark circuit in Figure 5.9

reference, a widlar bias generator, and an op amp. The schematic netlist of the benchmark

circuit contains 64 transistors, 9 resistors, and 1 capacitor.

The circuit can be automatically converted to a DDG using the mentioned EDA tool

(the resulting graph will not be shown because of its complexity). 12 SCCs are then

identified using the graph techniques described. For purposes of illustration, a ‘simplified’

graph of the benchmark circuit is shown in Figure 5.10 with blocks highlighted using dashed

boxes. It can be seen that the identified SCCs correspond to different blocks of the circuit and

the directed edges denote the interactions or dependencies between adjacent blocks. The

labels on these edges represent the names of the connecting nodes, the output vertices of

corresponding preceding SCCs. A label on one edge may contain more than one node, e.g.,

wn1, wn2, meaning that multiple connecting nodes exist between the two adjacent blocks.

Based on the identified SCC, the target circuit can be partitioned into 12 SCC sub-circuits.

To demonstrate the time efficiency of the proposed method, consider a fault list contains 338

Page 111: Design and verification approaches for reliability and

98

selected faults resulting from: (1) a classic 5-fault MOSFET model [30], namely, open drain,

open source and source-drain, drain-gate, source-gate shorts; (2) short and open faults for

resistors and capacitors. A value of 10 Ω was chosen for the resistance values used to model

the shorts and 1 GΩ for the resistance values used to model the opens.

Two important things can be pointed out: 1) While this demonstration of the proposed

method focuses on hard faults, the proposed method is not limited only to hard faults, and it

is possible that detecting soft faults could also be important for quality tests or broader

application aspects. 2) The proposed method is insensitive to the fault model. For a given

fault model and given DC tests, the proposed method tries to achieve the same fault

detectability (with less simulation effort) than in conventional fault simulation. As is well-

known, there are different strategies for modeling the possible faults of a MOSEFT. For

example, while open-gate faults modeled as large-resistances in series with transistor gate

terminals can be added to the fault list in [3], with this model and considering only DC tests,

they will not be detected either by the conventional method of simulating the whole circuit,

or by simulating the sub-circuit as proposed. Recently, ON Semiconductor, in ITC’16 [15]

introduced a new technique for modeling an open gate transistor in DC tests using a

transistor operating in the subthreshold region, implemented by inserting a voltage-controlled

voltage source between the gate and the source terminals of a given transistor and utilizing

the drain-source voltage as the controlling voltage. This model enables testability of open-

gate faults with DC tests in both the conventional and the proposed methods. Furthermore,

the fault list can be extracted from the layout that shows the physical spatial relationship of

conducting materials, using methods like Inductive Fault Analysis (IFA) [5] and tools

described in [31].

Page 112: Design and verification approaches for reliability and

99

The proposed fault-simulation performance was compared to conventional fault

simulation, using Virtuoso Spectre for simulation. The reported simulation times are the

average times for running the benchmark circuit ten times considering that Spectre is running

on a multi-core server. Simulation results are summarized in Table 5.1. The row titled ‘Fault

simulation time’ shows the total time taken by Spectre to perform DC simulations both for

the fault-free circuit and all the faulty circuits. It can be seen that the average fault simulation

time is reduced from 585.19s to 39.18s, a time-saving factor of 15 slightly larger than the

number of SCCs. This may be due to the fact that simulation time is nonlinear with circuit

size. On the other hand, the fault coverage for the proposed fault simulation is 75.14%, close

to the 78.11% coverage of conventional fault simulation. To validate that fault simulation

dominates the overall running time of the proposed method, we also provide another running

time for comparison. In the conventional method, ‘Other time’ includes injecting faults into

the CUT, creating faulty circuit netlists, configuring the simulator (e.g., accuracy options,

working directory etc.) and calculating the fault coverage results. In the proposed method,

‘Other time’ as expected is slightly larger because additional time is consumed for graph

manipulation operations such as generating the DDG and SCC sub-circuits.

Table 5.1 Performance Summary

Proposed Conventional Unit

# of faults simulated 338 338 -

# of faults detected 254 264 -

Fault coverage 75.14 78.11 %

Fault simulation time 39.18 585.19 s

Other time 23.78 14.25 s

Page 113: Design and verification approaches for reliability and

100

We observed estimation inaccuracy for the proposed method, and this was expected

because of the tradeoff between simulation time and estimation accuracy. For undetected

faults in the proposed method, while we could repeat fault simulation using the whole circuit

netlist to accomplish fault coverage closer to that of conventional fault simulation, the cost

would be in added simulation time. The proposed method can be readily combined with

sampling techniques described in the literature [5], possibly dramatically reducing the

simulation time for estimating coverage based on a given number of selected defects. This

seems very promising for quick coverage assessment considering the fact that conventionally

simulating 2068 defects in an industrial circuit takes about 72 hours [5]. On the other hand,

the smaller simulation time required for each individual fault allows simulation of a greater

number of faults within a given simulation time, helping to improve coverage estimation

accuracy that is proportional to the square root of the number of simulated faults [5].

5.7 Discussion

From the above discussion, it can be said that the proposed method reduces fault

simulation time by a factor approximately equal to the number of SCCs during fault coverage

assessment for MOS analog circuit test evaluation.

The method proposed in this chapter is not a replacement for other techniques

mentioned that focus on reducing the number of simulated faults. It is instead complementary

to those methods and it seems highly possible to combine the proposed method with

‘sampling’ techniques to achieve a further time reduction. It is well-known that analog fault

analysis is a challenging problem and the methods described here only solve a small part of

it.

The theoretical foundation of partitioning a large-size circuit into small sub-circuits

requires a well-defined DDG. In this chapter, during construction of the graph, only the

Page 114: Design and verification approaches for reliability and

101

dependencies for MOSFET transistors are introduced in detail. While the concept of creating

a dependency graph and partitioning the circuit based on that graph can be extended to

circuits containing bipolar transistors (BJT) or diodes, the extension to BJTs is not trivial

because the impedance at the base of a BJT cannot be generally regarded as infinite like that

of a MOSFET. Approaches to solving this problem are currently under study.

As is mentioned in the introduction, in this chapter we focused on quick fault-

coverage estimation for DC tests, and for those faults caused by energy storage elements and

known to be not detectable by DC tests, e.g., the capacitor in the benchmark circuit, existing

AC or transient fault analysis methods could be applied to improve the coverage.

Furthermore, for complex mixed-signal circuits that include clocking, fault-coverage testing

based only on DC tests might be insufficient, so the authors are also investigating approaches

to improving the time-efficiency of AC or transient analysis for analog fault simulation.

For the purposes of illustrating the proposed method, catastrophic faults were

assumed, but the method would work for parametric faults as well.

5.8 Conclusion

The systematic method introduced in this chapter significantly improves time

efficiency in estimating fault coverage for MOS analog fault simulation of DC tests. In the

proposed method, the circuit under test is partitioned into independent sub-circuits using

particular graphing techniques, followed by fault simulation performed using these sub-

circuits, an approach expected to be much more time-efficient than fault simulation using the

entire circuit. Fault coverage was estimated using both determination of simulated fault

impacts and backward sensitivity analysis. The proposed method can estimate fault coverage

with sufficient accuracy and reduce fault simulation time by a factor approximately equal to

Page 115: Design and verification approaches for reliability and

102

the number of SCCs. Simulation results based on a benchmark circuit were used to validate

the proposed method.

Page 116: Design and verification approaches for reliability and

103

5.9 References

[1] S. Sunter, “Closing the loop between analog design and test,” in 2016 IEEE

International Symposium on Circuits and Systems (ISCAS), 2016, pp. 894–897.

[2] S. Sunter, K. Jurga, and A. Laidler, “Using Mixed-Signal Defect Simulation to Close

the Loop Between Design and Test,” IEEE Trans. Circuits Syst. Regul. Pap., vol. 63,

no. 12, pp. 2313–2322, Dec. 2016.

[3] A. Coyette, G. Gielen, R. Vanhooren, and W. Dobbelaere, “Optimization of analog fault

coverage by exploiting defect-specific masking,” in Test Symposium (ETS), 2014 19th

IEEE European, 2014, pp. 1–6.

[4] R. Gordon and A. Sadok, “An Overview of Mixed-Signal Production Test from a

Measurement Principle Perspective,” IEEE Des. Test, no. 99, pp. 1–1.

[5] S. Sunter, K. Jurga, P. Dingenen, and R. Vanhooren, “Practical random sampling of

potential defects for analog fault simulation,” in Test Conference (ITC), 2014 IEEE

International, 2014, pp. 1–10.

[6] L. Fang, M. Lemnawar, and Y. Xing, “Cost Effective Outliers Screening with Moving

Limits and Correlation Testing for Analogue ICs,” in Test Conference, 2006. ITC ’06.

IEEE International, 2006, pp. 1–10.

[7] F. M. Goncalves and J. P. Teixeira, “Sampling techniques of non-equally probable

faults in VLSI systems,” in 16th IEEE VLSI Test Symposium, 1998. Proceedings,

1998, pp. 283–288.

[8] N. Guerreiro, M. Santos, and P. Teixeira, “Fault list compression for efficient analogue

and mixed-signal production test preparation,” in Design of Circuits and Integrated

Systems, 2014, pp. 1–6.

[9] E. Yilmaz, A. Meixner, and S. Ozev, “An industrial case study of analog fault

modeling,” in VLSI Test Symposium (VTS), 2011 IEEE 29th, 2011, pp. 178–183.

[10] W. C. Tam and R. D. Blanton, “Physically-aware analysis of systematic defects in

integrated circuits,” in Test Conference (ITC), 2011 IEEE International, 2011, pp. 1–10.

[11] W. C. Tam and R. D. Blanton, “SLIDER: Simulation of Layout-Injected Defects for

Electrical Responses,” IEEE Trans. Comput.-Aided Des. Integr. Circuits Syst., vol. 31,

no. 6, pp. 918–929, Jun. 2012.

[12] W. C. Tam and R. D. Blanton, “SLIDER: A fast and accurate defect simulation

framework,” in VLSI Test Symposium (VTS), 2011 IEEE 29th, 2011, pp. 172–177.

Page 117: Design and verification approaches for reliability and

104

[13] E. Yilmaz and S. Ozev, “Defect-based test optimization for analog/RF circuits for near-

zero DPPM applications,” in IEEE International Conference on Computer Design,

2009. ICCD 2009, 2009, pp. 313–318.

[14] E. Yilmaz and S. Ozev, “Fast and Accurate DPPM Computation Using Model Based

Filtering,” in Test Symposium (ETS), 2011 16th IEEE European, 2011, pp. 165–170.

[15] E. Yilmaz, G. Shofner, L. Winemberg, and S. Ozev, “Fault analysis and simulation of

large scale industrial mixed-signal circuits,” in Design, Automation Test in Europe

Conference Exhibition (DATE), 2013, 2013, pp. 565–570.

[16] B. Esen, A. Coyette, G. Gielen, W. Dobbelaere, and R. Vanhooren, “Effective DC fault

models and testing approach for open defects in analog circuits,” in 2016 IEEE

International Test Conference (ITC), 2016, pp. 1–9.

[17] T. W. Williams and N. C. Brown, “Defect Level as a Function of Fault Coverage,”

IEEE Trans. Comput., vol. 30, no. 12, pp. 987–988, 1981.

[18] C. Xue and R. D. S. Blanton, “Predicting IC Defect Level Using Diagnosis,” in 2014

IEEE 23rd Asian Test Symposium, 2014, pp. 113–118.

[19] B. Kruseman et al., “Defect Oriented Testing for analog/mixed-signal devices,” in Test

Conference (ITC), 2011 IEEE International, 2011, pp. 1–10.

[20] S. K. Sunter, “Defect injection for transistor-level fault simulation,” US8984460 B2,

17-Mar-2015.

[21] Z. Liu, Y. Li, Y. Duan, R. L. Geiger, and D. Chen, “Identification and break of positive

feedback loops in Trojan States Vulnerable Circuits,” in 2014 IEEE International

Symposium on Circuits and Systems (ISCAS), 2014, pp. 289–292.

[22] Z. Liu, Y. Li, Y. Duan, R. L. Geiger, and D. Chen, “Identification and break of positive

feedback loops in Trojan States Vulnerable Circuits,” in 2014 IEEE International

Symposium on Circuits and Systems (ISCAS), 2014, pp. 289–292.

[23] K. Ruohonen, Graph theory, Graafiteoria lecture notes, TUT. 2013.

[24] R. Tarjan, “Depth-First Search and Linear Graph Algorithms,” SIAM J. Comput., vol.

1, no. 2, pp. 146–160, Jun. 1972.

[25] S. J. Spinks, C. D. Chalk, I. M. Bell, and M. Zwolinski, “Generation and Verification of

Tests for Analog Circuits Subject to Process Parameter Deviations,” J. Electron. Test.,

vol. 20, no. 1, pp. 11–23, Feb. 2004.

Page 118: Design and verification approaches for reliability and

105

[26] Z. Wang, G. Gielen, and W. Sansen, “A novel method for the fault detection of analog

integrated circuits,” in Proceedings of IEEE International Symposium on Circuits and

Systems - ISCAS ’94, 1994, vol. 1, pp. 347–350 vol.1.

[27] D. Sanjoy, “Note three: Strongly Connected components.” [Online]. Available:

http://www.cc.gatech.edu/~mihail/D.dasgupta/3.pdf. [Accessed: 19-Dec-2016].

[28] C.-H. Wang, “Computer-aided manipulation of mason’s formula and its applications,”

Int. J. Circuit Theory Appl., vol. 20, no. 4, pp. 357–370, Jul. 1992.

[29] Z. Bubnicki, Modern Control Theory. Springer Science & Business Media, 2005.

[30] N. B. Hamida, K. Saab, D. Marche, B. Kaminska, and G. Quesnel, “LIMSoft:

automated tool for design and test integration of analog circuits,” in Proceedings

International Test Conference 1996. Test and Design Validity, 1996, pp. 571–580.

[31] T. Olbrich, J. Perez, I. A. Grout, A. M. D. Richardson, and C. Ferrer, “Defect-oriented

vs schematic-level based fault simulation for mixed-signal ICs,” in Proceedings

International Test Conference 1996. Test and Design Validity, 1996, pp. 511–520.

[32] A. Jee and F. J. Ferguson, “Carafe: an inductive fault analysis tool for CMOS VLSI

circuits,” in Digest of Papers Eleventh Annual 1993 IEEE VLSI Test Symposium,

1993, pp. 92–98.

Page 119: Design and verification approaches for reliability and

106

CHAPTER 6. IMPROVING ANALOG FAULT-COVERAGE WITH SYSTEMATIC

TEST-POINTS SELECTION AND CONCURRENT SAMPLING

6.1 Introduction

Quality requirements for modern integrated circuit (IC) applications, such as those in

the aerospace and automotive areas, are becoming increasingly stringent. This trend poses

grand challenges to the important process of improving fault coverage, i.e., to prevent

malfunctioning ICs from being shipped to customers.

While testing for faults in the digital part of System-on-Chips (SoCs) is typically

achieved with scan chains [1], replicating this success for analog circuits is not as

straightforward. In general, the primary analog outputs provide very limited observability,

making it virtually impossible to achieve high fault coverage for analog circuits without

observing internal nodes [2]. For example, while fault coverage of a voltage regulator circuit

was shown to be only about 30 percent when only the primary output was observed, fault

coverage jumped to 86 percent if some of the internal nodes were observed [3]. Some

preliminary methods for identifying the required minimal set of observation points to achieve

high fault coverage for catastrophic faults have been investigated in [4].

Although researchers tend to believe that observing some internal nodes is one

effective technique for improving fault coverage, exactly how to access these nodes still

remains challenging in reality. Some form of the Analog test bus (ATB) has traditionally

been utilized for over 30 years to access internal nodes [5]–[7], and it continues to be one of

the most popular embedded test access methods for analog observability. However, the ATB

has some major limitations. Large RC loading and kickback among probe nodes make it very

challenging or nearly impossible to meet high-quality requirements, especially when real-

time fault detection is considered. Other methods have recently been proposed to overcome

Page 120: Design and verification approaches for reliability and

107

some of these limitations, e.g., the Local Detection and Transmission System (LDTS) [2], in

which local threshold detection blocks are added at internal nodes and coupled to an

oscillator. The triggering of this oscillator when defects are detected leaves traces in the

power consumption. While this method enables fault detection it does not enable fault

diagnosis. In addition, since its fault detection is based on a single bit, the LDTS method is

unsuitable for detecting parametric faults. It is known that hard faults can manifest as

parametric effects in a circuit, e.g., as an open or a short of one finger of a MOSFET.

Furthermore, in cases such as automotive ICs etc., the requirement of guaranteeing

functional safety and reliability gives rise to the need for real time, post-deployment

monitoring of ICs to detect even latent faults, and none of the above-mentioned strategies are

suitable for real time monitoring.

This chapter proposes an approach to improving fault coverage in analog circuits

using systematic test-point selection and concurrent sampling. The central idea is to identify

a test point set (TPS) by using a recursive backward method. The determined TPS is

expected to increase the observability of certain faults that otherwise would be undetectable

at the primary outputs of the overall system. A technique for concurrent sampling with local

digitization is introduced to measure a multitude of analog DC voltages [8], and by

concurrentlymonitoring these test point voltages, the fault coverage can be significantly

improved, making real-time monitoring possible. The main contributions of this chapter are

summarized as follows.

• The proposed method can significantly improve the test coverage of embedded

analog functions by monitoring internal test-points; determination of these test-

points is automatic and systematic.

Page 121: Design and verification approaches for reliability and

108

• By using concurrent sampling with local digitization, the proposed method allows

simultaneous monitoring of multiple nodes with multi-bit resolution; moreover, it

enables real-time measurement of analog voltages.

• The proposed method is suitable for detecting parametric faults as well as hard

fault-induced parametric effects because of its capability for monitoring test-

points with multi-bit resolution.

• The design overhead and loading effects introduced by the concurrent sampling

method are much smaller than those of conventional analog test buses.

The remainder of this chapter is organized as follows. Section 6.2 previews the

skeleton of the proposed method. Section 6.3 uses an example circuit to describe an

effective method of identifying a set of test-points using a recursive backward method.

Section 0 describes how to combine the recursive backward method and concurrent

sampling. Section 0 demonstrates the effectiveness of the proposed method by applying it to

a benchmark circuit. Section 0 offers concluding remarks.

6.2 Overview of Proposed Method

Fault coverage (FC) is an important test metric that expresses test quality of an

integrated circuit. It is defined as the percentage of modeled faults that can be detected by the

test. There are several major tasks in practical fault coverage analysis.

1. Model the effect of manufacturing defects and obtain a fault list to be simulated.

2. Determine the test-points that achieve the desired FC.

3. Take measurements at these test-points of a circuit under test (CUT) at these test-

points and send the results out for evaluation.

4. Use the measurement data to decide whether a fault exists in the CUT.

Page 122: Design and verification approaches for reliability and

109

Circuit Netlist

TPS at sink SCCs

FC evaluation

Fault listDDG & SCCs

Final TPS

Fault

simulation

Achieve desired FC?

or DDG is empty

Reduced DDG

Layout

Y

N

Concurrent Sampling

Figure 6.1 Flowchart of the proposed method

The fault list can be generated based on customer returns, design experience,

schematic-based models, or layout-based models [9], [10]. Sampling techniques for selecting

“representative” faults to simulate have been studied [11]–[13].

Because of their low cost and widespread applicability, the importance of DC tests

for analog fault coverage analysis has been pointed out in [14]. It is shown that fault

coverage can be improved at very low cost by introduction of new DC fault models and

testing approaches [14].

In this chapter, we will focus on addressing Tasks 1 and 2 above.

The flowchart of the proposed method is illustrated in Figure 6.1. The method starts

by converting the circuit netlist into a directed dependency graph (DDG) that is then

partitioned into a set of disjoint strongly connected components (SCCs). The SCC

information is utilized to reduce the DDG to a simple acyclic graph with each SCC

represented as a super vertex. This enables us to determine a TPS at the sink SCCs, and fault

Page 123: Design and verification approaches for reliability and

110

detectability and FC at the TPS can then be evaluated. If the FC does not meet the desired

requirement, a recursive backward propagation method can be used to include additional

internal nodes to cover more faults. During each iteration, a reduced DDG is created (by

removing sink SCCs) and a reduced fault list can be generated (by removing detected faults).

In the reduced DDG, new sink SCCs are obtained and additional nodes are added to the TPS.

A final satisfactory TPS is obtained when either the FC meets the desired requirement or the

resulting reduced DDG is empty. Concurrent sampling along with local digitization

techniques is then utilized to export the analog TPS voltages for monitoring.

6.3 Test-Points Set

In this section, we define a method to systematically determine a set of test-points

(TPS) to improve fault coverage. We first define a method to construct the DDG and to

partition it into disjoint strongly connected components using the simple example circuit

shown in Fig.2. The recursive backward method for determining a TPS is then presented.

6.3.1 Directed Dependency Graph

The concept of directed dependency graphs (DDG) has been successfully used for

analog fault analysis by the authors in [4], [15] to achieve excellent results. An EDA tool

was developed and implemented in Cadence Virtuoso to automatically convert a circuit

netlist into a DDG. An important property of the DDG is that it captures a circuit’s critical

dependencies between voltages and currents. For the purpose of decomposing a circuit into

sub-circuits, this property is very useful because it allows us to know which voltages and

currents are correlated. In this subsection, we will briefly use one example circuit to review

the related definitions and point out some concepts that will be utilized in the next

subsection.

Page 124: Design and verification approaches for reliability and

111

For a CUT, a directed dependency graph is defined as a directed graph DDG(V, E),

where the vertex set V represents all voltages and currents in the circuit and the edge set E

stands for the directed dependencies between voltages and currents. As an example, the DDG

of Figure 6.2(a) is shown in Figure 6.2(b). For notational convenience, we label a vertex

(either current or voltage) in the graph using the corresponding circuit variable names. The

motivation for constructing a graph representation of a circuit is that permits standard graph

theory techniques to be employed in systematically decomposing it into subgraphs and to

apply recursive methods. We will next introduce SCC concepts and show how to employ

standard graph theory techniques to decompose a DDG into SCCs.

Any directed graph can be partitioned into a set of disjoint strongly-connected

components [16]. The most important property of an SCC is that for vertices 𝑢 and 𝑣, if

𝑢 and 𝑣 are in the same SCC, then 𝑢 and 𝑣 will have bi-directional dependency. This means

that any voltage or current change at 𝑢 (𝑣) will cause voltage or current change at 𝑣 (𝑢)

following the 𝑢 − 𝑣 (𝑣 − 𝑢 ) path. On the other hand, if 𝑢 and 𝑣 are in different SCCs, then

𝑢 and 𝑣 will have uni-directional dependency. This SCC property provides the basis for

partitioning a circuit into sub-circuits. Only one-directional dependency exists between nodes

lying in different sub-circuits. A sink SCC of is one with no edges emanating from it. As an

example, three SCCs are identified for the DDG shown in Figure 6.2(b), where the dashed

shaded regions are used to separate the SCCs. This example only has one sink SCC, SCC3.

If we use a single super-vertex to represent each SCC, the resulting graph is ‘shrunk’.

This shrunk graph is guaranteed to be a directed acyclic graph (DAG) [15] with forward

paths only and hence a straightforward recursive backward analysis is possible. Figure 6.3

shows the DAG for the DDG shown in Figure 6.2.

Page 125: Design and verification approaches for reliability and

112

M3 M4

M1 M2

V1

V2

I1

I4

M5

M6

Vo

M9

M7

M8

I3

I6IR1 R1

I2I5I7

I8

I9

gnd

vdd

V3

V4

(a)

I1

I4

I3

V1

V2

I5

I6

I9

IR1V3

I2

Vo

I7

I8

V4

SCC1 SCC2 SCC3

(b)

Figure 6.2 Example circuit: Widlar bias generator, (a) schematic (b) DDG with with SCCs

6.3.2 Recursive Backward Propagation Method

In this subsection, a formal method based on graph theory and DDGs and SCCs

concepts used to systematically determine a TPS will be developed.

For a given circuit, a test point (TP) is a selected node in the CUT where certain faults

can be detected by observing or monitoring vertex v. Due to the way a circuit is converted

into the DDG, it is possible to find a vertex in the DDG with the same name as one in the

circuit. The terms “observe” and “monitor” mean measuring and comparing the voltage of

this circuit node. A test point set is a set or a group of test-points.

Page 126: Design and verification approaches for reliability and

113

SCC1 SCC2 SCC3

Figure 6.3 The DAG for the DDG shown in Figure 6.2

It has been shown in [4] that a set Si formed by taking one vertex from each sink SCC

of a DDG has the property that all potential faults can be theoretically detected at these

vertices. This is due to the fact that any vertex in the DDG has a path to vertices in Si so that

a fault that affects an arbitrary vertex in the DDG can propagate to Si. The reason we qualify

our statement as “theoretical” is because the propagation of a fault to test-points does not

guarantee that the fault will cause a large enough voltage or current change at the test-points

for it to be detected. We next introduce through a simple example the recursive backward

propagation method of adding test-points.

Suppose we have the DAG shown in Figure 6.4(a). It has three SCCs (SCC1, SCC2

and SCC3). First of all, we will determine which SCC a fault will directly impact. The term

“impact” means causing a voltage or current change to a vertex of the DDG. As shown in

Figure 6.4(a), 𝑓11, 𝑓12, … , 𝑓1𝑛 are the faults that directly impact SCC1; 𝑓21, 𝑓22, … , 𝑓2𝑚 are the

faults that directly impact SCC2, and so on. The impact of each fault can be simulated using

either standard defect-oriented method [17] or the method introduced in [15] for speedup

consideration.

The recursive backward method starts from the sink SCC (or sink SCCs), SCC3 in

Figure 6.4(a). Suppose 𝑉𝑜 is the identified TP for SCC3. Following the strategies

introduced in [15], we label the detectability of all faults at test point 𝑉𝑜 . Suppose the

detection range at 𝑉𝑜 is 𝐷𝑜. If the impact in 𝑉𝑜 due to a fault is greater than |𝐷𝑜|, this means

that this fault can be detected at 𝑉𝑜 and we will label it with ‘1’; otherwise we will label it

Page 127: Design and verification approaches for reliability and

114

SCC1 SCC2 SCC3

... ... ...f11 f12 f1n f21 f22 f2m f31 f32 f3k

SCC1 SCC2 SCC3 Vo

0 1 1 0 0 1 1 1 1

G1SCC1 SCC2

f11f21 f22

1 1 0

V1

(a)

(b)

(c)

... ... ...f11 f12 f1n f21 f22 f2m f31 f32 f3k

Figure 6.4 Recursive backward method (a) DAG with fault impacts in each SCC (b) first iteration

(c) second iteration

with ‘0’ as shown in Figure 6.4(b). Again, while this is one possible way to determine fault

detectability, it is not necessary. After all sink SCCs have been examined, if all faults have

been labeled with ‘1’, this means that complete fault coverage has been achieved. If there are

still faults labeled with ‘0’, to detect them we must add additional vertices as test-points . To

achieve this, we first remove the existing sink SCCs from the DDG to producde a reduced

DDG. In the reduced DDG, new sink SCCs are obtained and we can define corresponding

TPS for this new set of sink SCCs. Note that the process of making them into actual test-

points is described in the next section. The afore-described procedure is then used to

determine fault detectability at this TPS. Each as yet undetected fault is then further labeled

as ‘1’ or ‘0’ depending on whether or not it is detectable at the new TPS. If one such fault is

Page 128: Design and verification approaches for reliability and

115

indeed detectable at the new TPS, the vertex corresponding to the new TPS is added to the

previous TPS.

Figure 6.4(b) shows the first iteration in which SCC3 is the original sink SCC and 𝑉𝑜

is the selected TP. Figure 6.4(c) shows the second iteration where SCC2 is the new sink SCC

and 𝑉1 is identified as the new TP. This recursive process can be repeated until either all

faults are labeled as detected or the reduced DDG becomes empty. The algorithm is

presented below.

Algorithm: Recursive backward method to obtain TPS Input: DDG, fault_list Obtain SCCs and sink SCCs for the DDG, TPS= ∅ While fault_list ≠ ∅ & DDG≠ ∅

For each sink SCC(i) Do Determine the TP of SCC(i) For each fault f in the fault_list

If f is detectable at TP then Label f as ‘1’ fault_list = fault_list –f TPS = TPS U TP

End if End For Remove vertices of sink SCC(i) from the DDG

End for In the reduced DDG, obtain new sink SCCs

End while

6.4 Concurrent Sampling with Local Digitization

In this section, a method of combining the recursive backward method and concurrent

sampling is introduced. Since the output of the recursive backward method is a list of nodes

that need to be measured, the next step is to develop an actual hardware implementation to

make these test-points observable.

Page 129: Design and verification approaches for reliability and

116

Local digitization is performed using the architecture shown in Figure 6.5. Each node

that needs to be monitored drives the ‘+’ input of a comparator (also called a local digitizer),

while the ‘-‘ input is driven by a voltage reference 𝑉𝑟𝑒𝑓. The node voltage is “measured” by

sweeping 𝑉𝑟𝑒𝑓 in a range (say from a low to a high value) and recording the 𝑉𝑟𝑒𝑓 value at

which the output of the comparator switches from 1 to 0. The step size of 𝑉𝑟𝑒𝑓 can be varied

depending on the desired resolution,. Similarly, care in designing the 𝑉𝑟𝑒𝑓 generation circuit

depends on the desired accuracy.

Figure 6.5 Local Digitization

Voltage nodes in the TPS resulting from the backward-recursive method are

concurrently sampled with local digitizers and held in digital storage elements (FFs), as

shown in Figure 6.6, and FF contents can be read out in one of many ways. Figure 6.6

suggests an implementation in which the FF contents are shifted out through one or more

scan chains. An IJTAG network [18] can also be used to send out the data, as discussed in

[8].

D Q

NodeUnder Test

FF

Local

Connection

VREF

CLK

Scan_Enable

Comparator: 1-Bit Digitizer

FF

Local Connection

Page 130: Design and verification approaches for reliability and

117

Figure 6.6 Architecture of the proposed Concurrent Sampling method

This CS method overcomes several limitations of the ATB. In local digitization, a

comparator can be used instead of a full ADC to avoid area and power overhead. The variety

of test-points requires flexibility in measurement resolution, and from the authors’ experience

in real implementation, the group of nodes can be roughly divided into three categories: 1)

Most nodes, for example, switches controlling nodes in digital trimming circuits, require only

1-bit resolution. 2) Some nodes, e.g., biasing voltages of cascode transistors, require medium

resolution. Three or four-bit resolution is enough to verify that transistors are working in

saturation. 3) Very few nodes, e.g., the supply voltage of analog blocks, may require testing

with high resolution. Sincde measurement resolution is controlled by VREF step size, we can

achieve flexible resolution by controlling VREF sweep and select suitable MUXs and

comparators.

With a given ATB-ADC pair, only one node can be measured at a time due to large

RC loading and kickback effects. With the proposed local digitization, cross-coupling of

nodes between different blocks is totally eliminated, so multiple nodes can be measured at

the same time with the shared VREF sweep. This significantly reduces conversion time,

Node 1

Node 2

Node n

Analog and Mixed-signal IP(s)

1-BitDigitizer

1-BitDigitizer

1-BitDigitizer

DAC

CLK Scan_Enable

VREF

Scan Chain

TDO

Page 131: Design and verification approaches for reliability and

118

especially in SoCs with a large number of test-points. Note that the ground reference voltage

inside a block is itself a test point. Comparator sharing, voltage node ordering, and VREF

phase control can all be further implemented to reduce area overhead and total measurement

time. These enhancements are beyond the scope of this chapter and will not be further

discussed.

Table 6.1 Differences between ATB and CS

Analog Test Bus Concurrent Sampling

Dif

feren

ces

One node at a time Multiple nodes concurrently

Large 1-hot MUX Small decoded MUXs

Large variable RC load Small static local RC load

Upper layer metals Lower layer metals

Production test • Production test

• Real-time monitoring

Differences between ATB and CS are summarized in Table 6.1. It can be seen that,

by using concurrent sampling with local digitization, the proposed method allows

simultaneous monitoring of multiple nodes with multi-bit resolution along with real-time

measurement of analog voltages. Design overhead and loading effects introduced by the

concurrent sampling method are much smaller than for a conventional analog test bus.

6.5 Case Study

In this section, the proposed method is applied to the benchmark circuit shown in

Figure 5.9. To demonstrate the effectiveness of the proposed method, a fault list containing

268 selected faults given by the user will be considered. Virtuoso Spectre was used for

simulation.

Page 132: Design and verification approaches for reliability and

119

Results from the iterations of the proposed recursive backward method are

summarized in Table 6.2. First, the system outputvout is used as the test point, and the

fault coverage is only 33.21 %. During the first iteration, four sink SCCs were found and

vout, Vref, n6, p7 was determined as the TPS. For this situation, the overall fault coverage

increased to 77.61%. During the second iteration, the original four sink SCCs are removed

from the graph, and in the reduced graph two new sink SCCs can be identified and another

two test-points ‘vpa’ and ‘Vaa’ added to the overall TPS, resulting in a FC of 85.07%.

Finally, after three iterations, the graph has again been traversed to produce a final achieved

T55

T56

T57

T58

T47

T48

T49

T50

T12

T14

T16

T18

VDD

T15

T17

T11

T13

T33

T34

T31 T32

T59

T60

T61

T62

T51

T52

T53

T54

T20

T22

T24

T26

VDD

T23

T25

T19

T21

T28

T27

T29 T30

T2

T4

T6

T8

T5

T7

T1

T3

T9

T10

T36T35

T37

T63

T64

T39T40

T41 T42

T44T43 T46

T45

VD

DV

SS

VSS

VSS

R9

T8 C2

V2

V3 V4

V1

R6

R6

R5 R2R3 R1

T38

p6

p7

p8

wp3

wp4

wp3

wp4

wp3

wp4

wp3

wp4

b2

b1

p5

p4

wp1

wp2

p9

p10

n6

n7

n8

n4

n2

n6

n6

n6

n1 wn1

wn2

wn1

wn2

wn1

wn2

wn3

wn4

b3

n5

vin vip

vin vip

b3

b1

b2

b4

Vr

vo1 vout

vstart

Vr VrVr

Vr

Vaa

Vab

VabVaa

Vr

vpa vpbvpbvpa

vnbvna

vnbvna

P-cascode

biasing

Opamp

biasing 1

P-type

WidlarOpamp core

N-cascode

biasing

Opamp

biasing 2

N-type

WidlarBanba

Simulation Setup

vip

vin vout

Opamp core

R4

Vref

generator

Vref

Figure 6.7 Benchmark circuit with the test-points highlighted with different color a) Red: from iteration 0; b) Blue: from

iteration 1; c) Green: from iteration 2; d) Purple: from iteration 3

Page 133: Design and verification approaches for reliability and

120

coverage of 89.55%. The test-points identified in this recursive procedure is highlighted with

different color in Figure 6.7.

With the CS method, glitches resulting from node switching, comparator CLK and

VREF sweeps are attenuated by an order of magnitude compared to those when using the

ATB. Simple strongARM latch comparators are used, with each taking ~10 um2 of area and

negligible quiescent current in the GlobalFoundries 130num process. After the comparator

sharing technique was implemented, area and power overhead of the CS method is no longer

a problem.

Table 6.2 Iterations of The Recursive Backward Method

Iteration TPS Overall FC

0 vout 33.21%

1 vout, Vref, n6, p7 77.61%

2 vout, Vref, n6, p7, vpa, Vaa 85.07%

3 vout, Vref, n6, p7, vpa, Vaa, p4, n5, Vsart 89.55%

Table 6.3 provides the comparison of the proposed TPAC method with state-of-the-

art methods. It can be seen that the proposed method provides an efficient solution to

searching for test-points to significantly improve the FC. Because of the use of concurrent

sampling, soft-fault detection, fault diagnosis, and real-time monitoring become possible.

Table 6.3 Comparison with the state-of-the-art methods

Paper Reduce

Simulation time

Improve

FC

Detect soft

fault

Fault

diagnosis

Real time

Monitoring

Sunter’13 YES NO YES NO NO

Coyette’16 NO YES NO YES NO

Proposed YES YES YES YES YES

Page 134: Design and verification approaches for reliability and

121

6.6 Conclusion

This chapter presents a systematic procedure for improving the test coverage of

embedded analog functions without requiring much added design overhead. This is achieved

by monitoring the voltage of a few test-points in the circuit with concurrent sampling. A

recursive backward method has been proposed for automatically selecting these test-points

and a concurrent sampling technique has been introduced for monitoring these points. Using

the proposed method, the fault coverage can be greatly improved and soft-fault detection,

fault diagnosis, and real-time monitoring become possible. This work could be applied to

manufacturing testing or for real-time fault detection.

Page 135: Design and verification approaches for reliability and

122

6.7 References

[1] L.-T. Wang, C. E. Stroud, and N. A. Touba, System-on-Chip Test Architectures:

Nanometer Design for Testability. Burlington : Elsevier Science, 2010.

[2] A. Coyette, B. Esen, R. Vanhooren, W. Dobbelaere, and G. Gielen, “Automatic

generation of autonomous built-in observability structures for analog circuits,” in 2015

20th IEEE European Test Symposium (ETS), 2015, pp. 1–6.

[3] A. Coyette, B. Esen, W. Dobbelaere, R. Vanhooren, and G. Gielen, “Automatic

generation of test infrastructures for analog integrated circuits by controllability and

observability co-optimization,” Integr. VLSI J., vol. 55, pp. 393–400, Sep. 2016.

[4] Z. Liu, S. K. Chaganti, and D. Chen, “Toward complete analog fault coverage with

minimal observation points using a fault propagation graph,” in 2016 IEEE

International Symposium on Circuits and Systems (ISCAS), 2016, pp. 1282–1285.

[5] P. P. Fasang, D. Mullins, and T. Wong, “Design for testability for mixed analog/digital

ASICs,” in Proceedings of the IEEE 1988 Custom Integrated Circuits Conference,

1988, p. 16.5/1-16.5/4.

[6] C. L. Wey, “Built-in self-test (BIST) structure for analog circuit fault diagnosis,” IEEE

Trans. Instrum. Meas., vol. 39, no. 3, pp. 517–521, Jun. 1990.

[7] L. T. Wurtz, “Built-in self-test structure for mixed-mode circuits,” IEEE Trans. Instrum.

Meas., vol. 42, no. 1, pp. 25–29, Feb. 1993.

[8] N. Liu, S. K. Chaganti, Z. Liu, D. Chen, and A. Majumdar, “Concurrent Sampling with

Local Digitization - An Alternative to Analog Test Bus,” in 2018 IEEE

International Symposium on Circuits and Systems (ISCAS), 2018.

[9] J. P. Shen, W. Maly, and F. J. Ferguson, “Inductive Fault Analysis of MOS Integrated

Circuits,” IEEE Des. Test Comput., vol. 2, no. 6, pp. 13–26, Dec. 1985.

[10] A. Jee and F. J. Ferguson, “Carafe: an inductive fault analysis tool for CMOS VLSI

circuits,” in Digest of Papers Eleventh Annual 1993 IEEE VLSI Test Symposium,

1993, pp. 92–98.

[11] F. M. Goncalves and J. P. Teixeira, “Sampling techniques of non-equally probable

faults in VLSI systems,” in 16th IEEE VLSI Test Symposium, 1998. Proceedings,

1998, pp. 283–288.

[12] N. Guerreiro, M. Santos, and P. Teixeira, “Fault list compression for efficient analogue

and mixed-signal production test preparation,” in Design of Circuits and Integrated

Systems, 2014, pp. 1–6.

Page 136: Design and verification approaches for reliability and

123

[13] S. Sunter, K. Jurga, P. Dingenen, and R. Vanhooren, “Practical random sampling of

potential defects for analog fault simulation,” in Test Conference (ITC), 2014 IEEE

International, 2014, pp. 1–10.

[14] B. Esen, A. Coyette, G. Gielen, W. Dobbelaere, and R. Vanhooren, “Effective DC fault

models and testing approach for open defects in analog circuits,” in 2016 IEEE

International Test Conference (ITC), 2016, pp. 1–9.

[15] Z. Liu, S. K. Chaganti, and D. Chen, “Improving Time-Efficiency of Fault-Coverage

Simulation for MOS Analog Circuit,” IEEE Trans. Circuits Syst. Regul. Pap., vol. PP,

no. 99, pp. 1–11, 2017.

[16] K. Ruohonen, Graph theory, Graafiteoria lecture notes, TUT. 2013.

[17] B. Kruseman et al., “Defect Oriented Testing for analog/mixed-signal devices,” in Test

Conference (ITC), 2011 IEEE International, 2011, pp. 1–10.

[18] “IEEE Standard for Access and Control of Instrumentation Embedded within a

Semiconductor Device,” IEEE Std 1687-2014, pp. 1–283, Dec. 2014.

Page 137: Design and verification approaches for reliability and

124

CHAPTER 7. CONCLUSION

This research investigates two design and verification issues that impact the

reliability of high-performance analog circuits. One is the multi-state issue encountered

during the design stage and caused by the existence of positive feedback. and the other is the

set of fault coverage issues during the manufacturer process. To determine the presence or

absence of multi-states, a systematic procedure is proposed for identifying and breaking

positive feedback loops of a circuit and performing a break-loop homotopy method. To

improve fault coverage for analog circuits, a practical and efficient method for improving

fault coverage at reasonable cost and time is introduced.

Firstly, the design of a low temperature coefficient voltage reference generator is

proposed to target the problem of extracting the VGO from the temperature characteristic of

positively-biased PN junction voltage VBE. VGO is the silicon band gap voltage extrapolated at

zero Kevin and is a constant voltage independent of temperature, supply, and process over a

very wide temperature range. Analytical constraints that lead to strategies for creating an

output voltage proportional to VGO when certain mismatches and offsets are accurately

trimmed have been carefully investigated. The proposed method is implemented in the

GlobalFoundries 130nm process. Simulation results show that the design can achieve

temperature coefficients as low as 0.7ppm/°C over the range -40°C to 125°C over process

corners.

Second, a systematic method is proposed for automatically identifying positive

feedback loops (PFLs) vulnerable to multiple operating points. in analog/mixed-signal

circuits. The method first converts the netlist of a circuit into a directed dependency graph

(DDG) that captures critical relationships among branch currents and node voltages. It then

Page 138: Design and verification approaches for reliability and

125

utilizes graph theory techniques to find all feedback loops from the DDG and, finally, a

criterion for determining the PFLs is developed. Since multiple states is caused by the PFLs,

this method could identify a circuit’s vulnerability to undesigned operating points through

only its structure without the computation required of DC solutions. The proposed approach

was implemented in a program and simulation results show that it could identify all the PFLs

very robustly.

Third, a method is proposed for breaking PFLs in a Multi-state vulnerable circuit. At

the breaking-points detemined, a break-loop homotopy sweep method can be applied to

verify the presence or absence of undesigned operating points. Questions of how and where

to break PFLs is challenging for many circuits, particularly as the circuit becomes large and

feedback structures become complex. To overcome this difficulty, graph theory techniques

are employed to partion a complex circuit graph into disjoint Strongly-Connected

Components (SCCs). Based on this concept, the PFL detection of and breakpoint locating

can be performed for every SCC. This limits the sweep dimension of the break-loop

homotopy sweep method to within one or two even for a large-scale circuit. Using Sub-

Bandgap reference and widlar-Banba examples, it is demonstrated that the proposed

approach can effectively identify all the SCCs and corresponding breakpoints.

Next, a systematic method for significantly improving time efficiency in estimating

the fault coverage for analog fault simulation is introduced. In the proposed method, a circuit

under test (CUT) is first partitioned into independent sub-circuits. The impacts of potential

faults directly entering a sub-circuit are then simulated and recorded using these sub-circuits,

a proess expected to be much more time-efficient than fault simulation using the entire much

larger circuit . Finally, the fault detectability at the given test-points is evaluated based on

Page 139: Design and verification approaches for reliability and

126

fault impacts and sensitivity among different sub-circuits. As a first step toward quick

estimation of fault coverage, this chapter focuses on DC tests, and simulation results show

that the fault coverage measured by such tests can be estimated with sufficient accuracy, with

simulation reduced by 10X, or approximately the number of SCCs for the benchmark circuit.

For a much larger circuit, the number of SCCs is expected to be much larger and the time-

saving factor will be much larger.

Finally, A novel concurrent test-point selection and sampling method is introduced

for significantly improving fault coverage of analog circuits. The method has two major

parts. The first is to select a set of test-points using a recursive backward method such that

the knowledge of values of the selected test-points is sufficient to tell whether a fault has

occurred in the circuit. Since the selected test-points could be internal, concurrent sampling

with local digitization to observe the value of these test-points is proposed. The proposed

concurrent sampling method achieves multi-bit resolution and thus enables detection of both

catastrophic (hard) and parametric faults. As part of the concurrent sampling, the

measurement results are sent out as digital values. The proposed TPAC method can be used

for off-line manufacturer testing as well as for real-time fault detection.

Page 140: Design and verification approaches for reliability and

127

APPENDIX A. PROGRAMS FOR IDENTIFYING AND BREADING FEEDBACK

LOOPS OF A CIRCUIT

1. Main.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './ITV/breakLoop/Strong_conn_comp/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

require './ITV/breakLoop/findPath.pl';

my $start_time=time();

my $start_time2=localtime();

my $debugFlag=1; #determine wether to print out information

if($debugFlag==1)

print "start at:$start_time2\n";

####open the net_from_cadence that generated from Cadence.

#open( MYFILE, "shimit.scs") || die "Can't open myfile: $!";

#open( MYFILE, "./ITV/selfbias_banba_with_cap.scs") || die "Can't open myfile: $!";

#open( MYFILE, "./ITV/myFile_hier_test") || die "Can't open myfile: $!";

#open( MYFILE, "./ITV/myFile") || die "Can't open myfile: $!";

system("perl ./ITV/breakLoop/flattenNetlist.pl >flattenNetlist.log");

open( MYFILE, "./flattenNetlist.txt") || die "Can't open myfile: $!";

my @netlist_from_cadence=<MYFILE>;

if($debugFlag==1)

print @netlist_from_cadence;

close(MYFILE);

####store the useful information in a hash

#my @netlist_usf=grep /(^\w+\d+\s.*\))/, @netlist_from_cadence;

#=================================================

# this is used to include the terminal line <==/^\(/

Page 141: Design and verification approaches for reliability and

128

my @netlist_usf=grep /^\w+\d/ || /^\(/, @netlist_from_cadence;

#=================================================

#################################

#fowlloing code is to get the power

#supply node from the form

################################

my @myPowerSupply=grep /^MyV/, @netlist_from_cadence;

if($debugFlag==1)

print @myPowerSupply;

my $myVdd;

my $myVss;

my $path_begin='vdd!';

my $path_end='gnd!';

my %path_begin;

my %path_end;

$path_begin'vdd!'=1;

$path_end'gnd!'=1;

foreach (@myPowerSupply)

if(/^MyVdd\:\s\"(.*)\"/)

$myVdd=$1;

map($path_begin$_=1,split(/ /,$1));

elsif(/^MyVss\:\s\"(.*)\"/)

$myVss=$1;

map($path_end$_=1,split(/ /,$1));

if(defined $myVdd)

$path_begin=$myVdd;

#delete $path_begin'vdd!';

if(defined $myVss)

$path_end=$myVss;

#delete $path_end'gnd!';

############get the dependencies that we assigned for symbols

my @mySymbolDepden=grep /^MyDep/, @netlist_from_cadence;

if($debugFlag==1)

print @mySymbolDepden;

Page 142: Design and verification approaches for reliability and

129

my %symbolDepen;

foreach (@mySymbolDepden)

if(/^MyDep\:\s\(\"(.*)\"\)/)

my @temp=split(/\" \"/,$1);

#push @SymboleDepden, $1;

my $depenName=$temp[0].$temp[1];

$symbolDepen$depenName=[@temp];

if($debugFlag==1)

print $depenName,"\n";

my %net_from_symbolDepen;

#print @SymboleDepden,"\n";

foreach (keys %symbolDepen)

if($debugFlag==1)

print $_,": ", @$symbolDepen$_,"\n";

for (my $i=0;$i<@$symbolDepen$_-1;$i++)

push @$net_from_symbolDepen@$symbolDepen$_[$i], $_;

if($debugFlag==1)

print "\n**net_from_symbolDepen**\n";

foreach (keys %net_from_symbolDepen)

if($debugFlag==1)

print "$_,=>@$net_from_symbolDepen$_\n";

#################################

#fowlloing code is to get the netlist

################################

if($debugFlag==1)

print "\n**processing the netlist**\n";

#print "netlist_usf:", @netlist_usf;

my %netlist_hash;

my %netlist_usf;

Page 143: Design and verification approaches for reliability and

130

my %instance_prop;

my %instance_terminal;

#foreach $_ (@netlist_usf)

for (my $i=0;$i<@netlist_usf;$i++)

$_=$netlist_usf[$i];

if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)\s/)

$netlist_hash$1=[split(/\" \"/,$2)];

if($debugFlag==1)

print "$1 => @$netlist_hash$1 \n";

$instance_prop$1=$3;

#=========================================================

#########store the terminal infor.

my $instName=$1;

my $nextLine=$netlist_usf[$i+1];

if($nextLine=~/^\(\"(.*)\"\)/) #this considering ("D" "B" "G" "S")

$instance_terminal$instName=[split(/\" \"/,$1)];

if($nextLine=~/^\(\'(.*)\'\)/)#this considering ('D' 'B' 'G' 'S')

$instance_terminal$instName=[split(/\' \'/,$1)];

#=========================================================

elsif(/^(\w+\d+.*)\s+\(\"(.*)\"\)\s+(\w+)\s/) ##this considering we have hierachical

instances which are named like "I0.I1.N4"

$netlist_hash$1=[split(/\" \"/,$2)];

if($debugFlag==1)

print "Got it!!!$1 => @$netlist_hash$1 \n";

$instance_prop$1=$3;

#=========================================================

#########store the terminal infor.

my $instName=$1;

my $nextLine=$netlist_usf[$i+1];

if($nextLine=~/^\(\"(.*)\"\)/)#this considering ("D" "B" "G" "S

$instance_terminal$instName=[split(/\" \"/,$1)];

Page 144: Design and verification approaches for reliability and

131

if($nextLine=~/^\(\'(.*)\'\)/)#this considering ('D' 'B' 'G' 'S')

$instance_terminal$instName=[split(/\' \'/,$1)];

#=========================================================

my %netlist_banba=%netlist_hash;

=pod

my %netlist_widlar=(

N3 => [qw/C C 0 0/],

N2 => [qw/A B 0 0/],

N0 => [qw/B B C 0/],

P1 => [qw/A A vdd! vdd!/],

P0 => [qw/B A vdd! vdd!/],

V0 => [qw/vdd! 0/]);

my %netlist_shimit=(

N1 => [qw/B D C 0/],

N0 => [qw/A net5 C 0/],

R3 => [qw/0 C/],

R2 => [qw/A D/],

R1 => [qw/vdd! B/],

R0 => [qw/vdd! A/],

V0 => [qw/net5 0/]);

=cut

my %netlist_widlar=(

N3 => [qw/C gnd! C gnd!/],

N2 => [qw/A gnd! B gnd!/],

N0 => [qw/B gnd! B C/],

P1 => [qw/A vdd! A vdd!/],

P0 => [qw/B vdd! A vdd!/],

V0 => [qw/vdd! gnd!/]);

my %netlist_shimit=(

N1 => [qw/B D C gnd!/],

N0 => [qw/A net5 C gnd!/],

R3 => [qw/gnd! C/],

R2 => [qw/A D/],

R1 => [qw/vdd! B/],

R0 => [qw/vdd! A/],

V0 => [qw/net5 gnd!/]);

#######################################

#find the channel of each instance

#diode connection transistor

#gate of non-diode connection tansistor

#######################################

Page 145: Design and verification approaches for reliability and

132

my %netlist=%netlist_banba;

my %graph;

my %gate;

my %gate_net;

my %D;

my %S;

for my $instance (keys %netlist)

$_=$instance;

if($debugFlag==1)

print "$instance:";

my $prop=$instance_prop$instance;

if($debugFlag==1)

print "$prop";

my @terminal=@$instance_terminal$instance;

if($debugFlag==1)

print "(@terminal)";

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

if($debugFlag==1)

print " is COMS!!";

elsif($prop=~/pnp|npn/)

if($debugFlag==1)

print " is BJT!!";

if($debugFlag==1)

print "\n";

#if(/P|N|M\d+/)

if($prop=~/^pmos|^pfet|^nmos|^nfet/) #means this is a coms transistor

#determine the channel of transistor

my $net=$netlist$instance;

#=================================================================

===========

Page 146: Design and verification approaches for reliability and

133

my $D;

my $S;

my $B;

my $G;

for(my $i=0;$i<@terminal;$i++)

if($terminal[$i]=~/G/)$G=$net->[$i];

elsif($terminal[$i]=~/S/)$S=$net->[$i];

elsif($terminal[$i]=~/D/)$D=$net->[$i];

elsif($terminal[$i]=~/B/)$B=$net->[$i];

$S$instance=$S;

$D$instance=$D;

# print "D=>$D S=>$S\n";

$graph$instance=[$D,$S];

#if(

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

if($D eq $S)

if($D eq $B)

if($debugFlag==1)

print "since D=S=B It's a varactor (variable capacitor)!!!!!!!!\n";

delete $graph$instance;

$instance_prop$_="varactor";

else

if($debugFlag==1)

print " It's a diode!!!!!!!!\n";

delete $graph$instance;

$instance_prop$_="diode";

$graph$_=[$D,$B];

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

elsif (($D ne $G) and ($G ne $S))#not diode connected

if(($D eq $S) and ($D eq $B))# vorator ###diode transistor or

if($debugFlag==1)

print " It's a varactor (variable capacitor)!!!!!!!!\n";

Page 147: Design and verification approaches for reliability and

134

delete $graph$instance;

else

$gate$instance=$G;

$gate_net$G=[] if (not exists $gate_net$G);

$gate_net$G=[@$gate_net$G, $instance];

else

#search for diode connection and change the name

$_=$instance;

s/P/PD/;

s/N/ND/;

s/M/MD/;

s/T/TD/;

$graph$_=delete $graph$instance;

if($debugFlag==1)

print $instance, " is diode connection => $_\n";

=pod

$graph$instance=[$net->[0],$net->[3]]; #(0 1 2 3 )==>(D B G S)

#determine the gate of transistor

if (($net->[0] ne $net->[2]) and ($net->[2] ne $net->[3]))#not diode connected

if(($net->[0] eq $net->[3]) and ($net->[0] eq $net->[1]))# vorator ###diode

transistor or

print " It's a varactor (variable capacitor)!!!!!!!!\n";

delete $graph$instance;

else

$gate$instance=$net->[2];

$gate_net$net->[2]=[] if (not exists $gate_net$net->[2]);

$gate_net$net->[2]=[@$gate_net$net->[2], $instance];

else

Page 148: Design and verification approaches for reliability and

135

#search for diode connection and change the name

$_=$instance;

s/P/PD/;

s/N/ND/;

s/M/MD/;

s/T/TD/;

$graph$_=delete $graph$instance;

print $instance, " is diode connection => $_\n";

=cut

#=================================================================

=============

elsif($prop=~/cap/) #means this is a capacitor

delete $graph$instance;

elsif(/^I\d+/)

if($debugFlag==1)

print "$_ is: $instance_prop$_\n";

if($instance_prop$_=~/^idc/)$graph$instance=$netlist$instance; #it's not an

independent current source

elsif($prop=~/pnp|npn/)

#determine the channel of BJT

my $net=$netlist$instance;

$graph$instance=[$net->[0],$net->[2]]; #(0 1 2)==>(C B E)

#determine the Base of BJT

if (($net->[0] ne $net->[1]) and ($net->[2] ne $net->[1]))#not diode connected

my $base_channel=$instance.'_BE';

$graph$base_channel=[$net->[1],$net->[2]];

$gate$instance=$net->[1];

$gate_net$net->[1]=[] if (not exists $gate_net$net->[1]);

$gate_net$net->[1]=[@$gate_net$net->[1], $instance];

else

#search for diode connection and change the name

Page 149: Design and verification approaches for reliability and

136

$_=$instance;

s/Q/QD/;

$graph$_=delete $graph$instance;

if($debugFlag==1)

print $instance, " is diode connection $prop => $_\n";

else

$graph$instance=$netlist$instance;

###########################

my %channel=%graph;

if($debugFlag==1)

print "\n**Channel list**\n";

foreach $_ (keys %channel)

print $_, " => [qw/";

print $channel$_->[0],"\t";

print $channel$_->[1],"/]\n";

print "\n**Gate list**\n";

foreach $_ (keys %gate)

print "$_\_gate => '$gate$_'\n";

print "\n**Gate_net list**\n";

foreach $_ (keys %gate_net)

print "$_\_gate_net => '@$gate_net$_'\n";

#############################

##################################

#find the connections for each net

##################################

print "\n**The graph now is: **\n";

Page 150: Design and verification approaches for reliability and

137

foreach my $instance (keys %graph)

print "$instance, @$graph$instance\n";

## if debugFlag

my %temp=%graph;

my $cont=0;

for my $instance (keys %temp)

my $net=$temp$instance;

if (exists $graph$net->[0])

$cont++;

# print "before $cont add net $net->[0] is: @$graph$net->[0]\n";

$graph$net->[0]=[@$graph$net->[0],$instance];

# print "after $cont add net $net->[0] is: @$graph$net->[0]\n";

else

$graph$net->[0]=[$instance];

if (exists $graph$net->[1])

# print "before $cont add net $net->[1] is: @$graph$net->[1]\n";

$graph$net->[1]=[@$graph$net->[1],$instance];

# print "after $cont add net $net->[1] is: @$graph$net->[1]\n";

else

$graph$net->[1]=[$instance];

##################################################

#the following code is to make the MOS/BJT channel as one direction

my $ins=$instance;

if($ins=~/(.*)_BE/)

$ins=$1;

$_=$ins; ## to make sure we can use $instance_prop$_;

s/PD/P/;

s/ND/N/;

Page 151: Design and verification approaches for reliability and

138

s/MD/M/;

s/TD/T/;

my $prop=$instance_prop$_;

if($prop=~/pnp/)

if($debugFlag==1)

print "$net->[0]=>@$graph$net->[0] !!!!!!!!!!!!!\n";

my @ttt=grep (!/$ins/,@$graph$net->[0]);

if($debugFlag==1)

print "@ttt, got it!!!!!!!!!\n";

$graph$net->[0]=[@ttt];

#$graph$net->[0]=[grep (!/$ins/,@$graph$net->[0])];

elsif($prop=~/npn/)

if($debugFlag==1)

print "$net->[1]=>@$graph$net->[1] ????????????!\n";

my @ttt=grep (!/$ins/,@$graph$net->[1]);

if($debugFlag==1)

print "@ttt, got it??????????\n";

$graph$net->[1]=[@ttt];

#$graph$net->[1]=[grep (!/$ins/,@$graph$net->[1])];

####################################################

if($debugFlag==1)

print "\n**After add the net connction, the graph now is:**\n";

foreach my $instance (keys %graph)

print "$instance => [@$graph$instance]\n";

#the following code has problem since if we make channel directed, than we will have some

net connected to one channel

=pod

Page 152: Design and verification approaches for reliability and

139

#######################################

#delete channel without current flowing

#######################################

print "\n**Short the channel without current flowing**\n";

%temp=%graph;

my @floatInstance;

foreach my $instance (keys %temp)

my $net=$temp$instance;

#if(@$net==1 && ($instance ne $path_begin) && ($instance ne $path_end))

if(@$net==1 && (not exists $path_begin$instance) && ($instance ne $path_end))

#means this net(not VDDVSS) is only connected to one channel @$net->[0];

#so no current flowing into this net as well as the connected channel

my $dele_channel=@$net[0];

# print "$instance is only connected to @$net,";

# print "\t so channel $dele_channel can be deleted\n";

#find another pin of the deleting channel (diff from $instance )

# if(!($dele_channel ~ @floatInstance))

if(!(grep$_ eq $dele_channel @floatInstance)) #if the $dele_channel is a

floating#instance ignore the following

my $join_net;

($join_net)=grep (!/$instance/,@$graph$dele_channel);

if (!(defined $join_net))

push @floatInstance, $dele_channel;

print "the channel: $dele_channel is floating! Since it only have one effective net

connection: $instance!";

else short_channel($instance,$dele_channel,$join_net);

# print "$instance => [@$graph$instance]\n";

print "\n**floating inst**:\n", @floatInstance,"\n";

print "\n**Now the graph is:**\n";

foreach my $instance (keys %graph)

print "$instance => [@$graph$instance]\n";

=cut

Page 153: Design and verification approaches for reliability and

140

#########################################

#delete one channel and short this branch

#########################################

sub short_channel

my ($dele_net,$dele_channel,$keep_net)=@_;

#delete this channel from the join net connectioin

if($debugFlag==1)

print "\n$dele_net is only connected to $dele_channel,";

print "\t so channel $dele_channel can be deleted\n";

print "and $dele_net should be joined to --->$keep_net,\n";

new_netconne($dele_channel,$keep_net);

my $combNetName;

#if(($keep_net eq $path_end) or ($keep_net eq $path_begin) )

if(exists $path_begin$keep_net or ($keep_net eq $path_end))

if($debugFlag==1)

print "However power supply net name should not be changed!! Thus $keep_net is

unchanged\n";

$combNetName=$keep_net;

#net "gnd!" should not be recombined!!!

else

$combNetName=$keep_net.'_'.$dele_channel.'_'.$dele_net;

if($debugFlag==1)

print " \t this $keep_net is changed to $combNetName\n";

#####This following part is to change the net name $keep_net to $combNetName###

###########################################################################

##

##for the channel that connected to $keep_net change $keep_net to $combNetName

foreach my $ins(@$graph$keep_net)

my @new_netconne=grep (!/$keep_net/,@$graph$ins);#

#new_netconne is the new connections for net $keep_net after delete $keep_net

$graph$ins=[@new_netconne, $combNetName];

##change the key word $keep_net to $combNetname

$graph$combNetName=delete $graph$keep_net;

Page 154: Design and verification approaches for reliability and

141

##for gate that connected to $keep_net change $keep_net to $combNetName

foreach my $ins (@$gate_net$keep_net)

$gate$ins=$combNetName;

###########################################################################

##

$keep_net=$combNetName;

delete $graph$dele_channel;

#print "@$gate_net$dele_net\n";

if (exists $gate_net$dele_net)

foreach my $change_gate(@$gate_net$dele_net)

#since deleting the net, the gate connected to it should be changed

if($debugFlag==1)

print "$change_gate\_G=>$dele_net originally\n";

$gate$change_gate=$keep_net;

if($debugFlag==1)

print "$change_gate\_G=>$keep_net now\n ";

delete $graph$dele_net;

#############################################

# find new connections for one net that

#comprise a channel after delete this channel

#############################################

sub new_netconne

my ($dele_channel,$keep_net)=@_;

# print "$keep_net=>[@$graph$keep_net] originally\n";

my @new_netconne=grep (!/$dele_channel/,@$graph$keep_net);#

#new_netconne is the new connections for net $keep_net after delete this channel

$graph$keep_net=[@new_netconne];

# print "$keep_net=>[@new_netconne] now\n";

Page 155: Design and verification approaches for reliability and

142

#########################################

#delete one channel and open this branch

#########################################

sub open_channel

my ($dele_channel)=@_;

if($debugFlag==1)

print "\n channel $dele_channel is being deleted\n";

new_netconne($dele_channel,@$graph$dele_channel[0]);

new_netconne($dele_channel,@$graph$dele_channel[1]);

delete $graph$dele_channel;

print STDOUT "progress= 10\n";

##############################

#run the find_path function

#written in findPath.pl file

##############################

######################

#join the path to hash

######################

if($debugFlag==1)

print "\n**path list**\n";

my $i=0;

tie my %path, 'Tie::IxHash';

#my %path;

foreach my $path_begin(keys %path_begin)

my $routes = find_paths($path_begin, $path_end, \%graph);

#my $n=@$routes;

#print $n;

foreach my $pt (@$routes)

my $temp="path";

my $p=join("",($temp, $i++));

if($debugFlag==1)

print $p," => ";

Page 156: Design and verification approaches for reliability and

143

print "@$pt\n";

$path$p=[@$pt];

# print $path$p->[2],"\t";

if($debugFlag==1)

print "\n**search self-determined path**\n";

########################################################

#for each path find the self-determined paths,

#find for each net the belonging to non-self-deter paths

########################################################

#print "\n**path list**\n";

#print "@$_\n" for @$routes;

my %net_path; #store for each net the paths it belongs to

my %check_gate;

my %MOS_Channel;#the real MOS Channel

my %self_deter_path; #stort the self-determined path

my %net__selfDeterPath;#store for each net the belonging to self-deter paths

my %path_bak=%path;

my %supplyVol;

foreach my $pt (keys %path)

#=================================================================

=============================

#find the power supply voltage source

#

my $potentialVDC=$path$pt->[1];

if(exists $instance_prop$potentialVDC)

if($instance_prop$potentialVDC=~/^vdc/ && ($path$pt->[2] eq $path_end))

if($debugFlag==1)

print "\n!!!Got the supply voltage source for $path$pt->[0] is: $potentialVDC

\n";

print "since:";

$supplyVol$path$pt->[0]=$potentialVDC;

Page 157: Design and verification approaches for reliability and

144

#=================================================================

=============================

@_=@$path$pt;

if($debugFlag==1)

print "\n$pt => [qw/@_/]\n";

my $self_deter_flag=1;

my $i=0;

for (my $index=0;$index<@$path$pt;$index++)

#foreach my $net (@$path$pt)

my $net=@$path$pt[$index];

$_=$net;

#print "$_\n";

my $prop;

if(exists $instance_prop$net)# means this net is an instance 1st-if

$prop=$instance_prop$net;

# print "$prop";

# if($prop=~/^pmos|^pfet|^nmos|^nfet/)print " is COMS\n";

#if (/^P\d+/ or /^N\d+/ or /^M\d+/)

if($prop=~/^pmos|^pfet|^nmos|^nfet/) #means this is a coms transistor 2nd-if

$self_deter_flag=0;

if($debugFlag==1)

print "$net\_G should be checked\n";

#save the gate that need to be checked

$check_gate$pt=[] if (not exists $check_gate$pt);

$check_gate$pt=[@$check_gate$pt,$net];

######determine the real drain and source following the path

#if($net=~/^N/)

if($prop=~/^nmos|^nfet/)

$graph$net=[@$path$pt[$index-1],@$path$pt[$index+1]];

else

$graph$net=[@$path$pt[$index+1],@$path$pt[$index-1]];

$MOS_Channel$net=$graph$net;

# 2nd-if

Page 158: Design and verification approaches for reliability and

145

if($prop=~/pnp|npn/) #means this is a BJT 2nd-if

$self_deter_flag=0;

if($debugFlag==1)

print "$net\_B should be checked\n";

#save the gate that need to be checked

$check_gate$pt=[] if (not exists $check_gate$pt);

$check_gate$pt=[@$check_gate$pt,$net];

######determine the real drain and source following the path

#if($net=~/^N/)

if($prop=~/npn/)

$graph$net=[@$path$pt[$index-1],@$path$pt[$index+1]];

else

$graph$net=[@$path$pt[$index+1],@$path$pt[$index-1]];

$MOS_Channel$net=$graph$net;

# 2nd-if

#1st-if

if($i%2==0 && $i>0) # 3nd-if

if ($net ne $path_end)

#find for each net the belonging to non-self-deter paths

$net_path$net=[] if (not exists $net_path$net);

$net_path$net=[@$net_path$net,$pt];

# 3nd-if

# print $i;

$i++;

## for

#one path may not have transistor, but it can bifurcate to another path which can contain tans

=pod

#for each path find the self-determined paths,

if ($self_deter_flag==1)

print "$pt is a self-determined path\n";

for (my $index=@$path$pt;$index>0;$index--)

Page 159: Design and verification approaches for reliability and

146

short_channel(@$path$pt[$index-2],@$path$pt[$index-1],$path_end) if

($index%2==0);

$self_deter_path$pt=$path$pt;

delete $path$pt;

=cut

#foreach

if($debugFlag==1)

print "\nafter deleting the self-determined path:\n";

foreach (keys %path)

print "$_=>@$path$_\n";

#############################################################

print "\n**the real drain and source for each transistor**\n";

#############################################################

my %drain;

my %source;

foreach my $chan (keys %MOS_Channel)

my $D=@$MOS_Channel$chan[0];

my $S=@$MOS_Channel$chan[1];

push @$drain$D, $chan;

push@$source$S, $chan;

if($debugFlag==1)

print "$chan => [@$MOS_Channel$chan] \(D S\)\n";

if($debugFlag==1)

print "\n**drain list**\n";

foreach (keys %drain)

print "$_=>@$drain$_\n";

print "\n**source list**\n";

foreach (keys %source)

print "$_=>@$source$_\n";

Page 160: Design and verification approaches for reliability and

147

print STDOUT "progress= 20\n";

########################################

#for determining voltage and dependencis

########################################

print "\n**find dependencies**\n";

# if debugFlag

my %depen;

my @d;

my %check_source;

foreach my $pt (keys %check_gate) #$pt-> each path that have transistors

if($debugFlag==1)

print "\nFor $pt: @$path$pt\n";

foreach my $ins (@$check_gate$pt) #ins-> each transistor of this path

if($debugFlag==1)

print "\n$ins\[G]=> $gate$ins, ";

my @check_Vgs; # gate voltage and source voltage can both be potential controlling

voltages

push @check_Vgs,$gate$ins; #gate is a potential controlling voltage

#if (($gate$ins eq $path_begin) or ($gate$ins eq $path_end)) # the gate is

connected to fixed voltage

if (exists $path_begin$gate$ins or ($gate$ins eq $path_end)) # the gate is connected

to fixed voltage

#if (@$channel$ins[1] ne ($path_begin and $path_end))# the source is not

connected to Vdd and Vss then is a potential control volt

if($debugFlag==1)

print "source of $ins is not connected to fixed voltage \n";

my $check_Vs=@$channel$ins[1];

push @check_Vgs,$check_Vs;#source is a potential controlling voltage

push @$check_source$check_Vs,$ins;

if($debugFlag==1)

print "Thus, we should check the source of $ins: $check_Vs\n";

Page 161: Design and verification approaches for reliability and

148

#=================================================================

========================

my $mySource=@$MOS_Channel$ins[1];

if($debugFlag==1)

print "!!$ins\[S]=> $mySource\n";

if (!exists $path_begin$mySource && ($mySource ne $path_end))# the source is

not connected to Vdd and Vss then is a potential control volt

if($debugFlag==1)

print "source of $ins is not connected to fixed voltage \n";

my $check_Vs=$mySource;

push @check_Vgs,$check_Vs;#source is a potential controlling voltage

push @$check_source$check_Vs,$ins;

if($debugFlag==1)

print "Thus, we should check the source of $ins: $check_Vs\n";

#=================================================================

========================

foreach my $check_Vgs (@check_Vgs)

foreach my $net_p (@$net_path$check_Vgs) # net_p->each path that the gate

of this transistor gate is conncted to

if ($net_p ne $pt)

if($debugFlag==1)

print "and $check_Vgs is a net of $net_p\n";

# push @d,[$net_p, $check_Vgs],[$check_Vgs, $pt];##this may lead to

repeated dependencies

$depen$net_p.$check_Vgs=[$net_p, $check_Vgs];

$depen$check_Vgs.$pt=[$check_Vgs, $pt];

if($debugFlag==1)

print "depen:$net_p=>$check_Vgs, $check_Vgs=>$pt\n";

Page 162: Design and verification approaches for reliability and

149

###########################consider the symbol dependencies

foreach my $check_Vgs (@check_Vgs)

foreach (keys %symbolDepen)

if($check_Vgs eq @$symbolDepen$_[1])

if($debugFlag==1)

print "and $check_Vgs is a net of symbol dependecies:

@$symbolDepen$_\n";#there is a depen between the symbol depen output to current

path

$depen$check_Vgs.$pt=[$check_Vgs, $pt];

foreach my $net_p (@$net_path@$symbolDepen$_[0]) #find a

path the generate the controlling voltage of the symboe depen

$depen$net_p.@$symbolDepen$_[0]=[$net_p,

@$symbolDepen$_[0]];

if($debugFlag==1)

print "also @$symbolDepen$_[0] is a net of $net_p\n";

=pod

print "\n**source**\n";

foreach (keys %check_source)

print "$_=>[@$check_source$_]\n";

=cut

my %net_from_depen;###list of the paths where the controlling voltages come from

my %path_depen;##list of the denpens that a path belongs to

my %path_from_depen;##list of the denpens that a path belongs to

###############

#after delete the repeated denpendecies

if($debugFlag==1)

print "\n**net from path**\n";

foreach my $net (keys %net_path)

Page 163: Design and verification approaches for reliability and

150

print "$net: @$net_path$net\n";

my %net_path_bak=%net_path;

if($debugFlag==1)

print "\n**dependencies list**\n";

foreach my $item (keys %depen)

if($debugFlag==1)

print "$item: @$depen$item\n";

my $path1=@$depen$item[0];

my $net1=@$depen$item[1];

if($path1=~/^path/)

push @$net_from_depen$net1, $path1;

push @$path_depen$path1, $item;

#if

elsif($net1=~/^path/)

push @$path_depen$net1, $item;

push @$path_from_depen$net1, $item;

#elsif

if($debugFlag==1)

print "\n**list of the paths where the controlling voltages come from**\n";

foreach my $net (keys %net_from_depen)

if($debugFlag==1)

print"$net: @$net_from_depen$net^^^^^^^^^^^^^^^\n";

if(@$net_from_depen$net==2)

#============================================

my ($pt1,$pt2)=@$net_from_depen$net;

if(exists $path$pt1 && exists $path$pt2)

#============================================

combin_paths(@$net_from_depen$net,$net);

Page 164: Design and verification approaches for reliability and

151

#if

foreach my $net (keys %net_path)

if($debugFlag==1)

print"$net: @$net_path$net~~~~~~~~~~~~~~\n";

if(@$net_path$net==2)

#============================================

my ($pt1,$pt2)=@$net_path$net;

if(exists $path$pt1 && exists $path$pt2)

#============================================

combin_paths(@$net_path$net,$net);

#if

if($debugFlag==1)

print "\n**path belongs to depens**\n";

foreach my $path (keys %path_depen)

print"$path: @$path_depen$path\n";

sub combin_paths

if($debugFlag==1)

print "!!!@_!!!\n";

my ($pt1,$pt2, $net)=@_;

my @pt1=@$path$pt1;

my @pt2=@$path$pt2;

if($debugFlag==1)

print "begin test\n";

print "$pt1 is: @pt1,\n $pt2 is: @pt2\n";

my %pt1;

map($pt1$_=1,@pt1); # create %pt1 with elements from @pt1

my @pt2Diff=grep(!defined($pt1$_),@pt2); # returns those elements of @pt2 that don't

# have a hash element in %pt1 therefore they

Page 165: Design and verification approaches for reliability and

152

# do not exist in @pt1.

if($debugFlag==1)

print " the differen in $pt2 is: @pt2Diff\n";

if(!grep((/^P\d+/ or /^N\d+/ or /^M\d+/ or /^T\d+/ or (exists $net_from_depen$_) or

(exists $net_from_symbolDepen$_)), @pt2Diff) ) # there are no transistors and

controlling voltages in the common parts then this path can be combined

#print %net_from_symbolDepen,"\t @pt2Diff\n\n";

#if(!grep((not exists $net_from_symbolDepen$_), @pt2Diff))print "ok!!\n";

if($debugFlag==1)

print "$pt2 can be combined!!\n";

delete $path$pt2;

if($debugFlag==1)

print "@$path_depen$pt2 can be deleted !!\n";

grep(delete $depen$_,@$path_depen$pt2);

new_net_path($pt2, $net);

else# when $pt2 can not be combined, lets check $pt1

my %pt2;

map($pt2$_=1,@pt2);

my @pt1Diff=grep(!defined($pt2$_),@pt1);

if($debugFlag==1)

print " the differen in $pt1 is: @pt1Diff\n";

if(!grep((/^P\d+/ or /^N\d+/ or /^M\d+/ or /^T\d+/ or (exists $net_from_depen$_)

or (exists $net_from_symbolDepen$_)), @pt1Diff) )# there are no transistors and

controlling voltages in the common parts then this path can be combined

if($debugFlag==1)

print "$pt1 can be combined!!\n";

delete $path$pt1;

if($debugFlag==1)

print "@$path_depen$pt1 can be deleted !!\n";

grep(delete $depen$_,@$path_depen$pt1);

new_net_path($pt2, $net);

Page 166: Design and verification approaches for reliability and

153

#############################################

# find new paths for one net it belongs to

#############################################

sub new_net_path

my ($dele_path,$net)=@_;

if($debugFlag==1)

print "$net=>[@$net_path$net] originally\n";

my @new_netconne=grep (!/$dele_path/,@$net_path$net);#

#new_netconne is the new connections for net $net after delete this channel

$net_path$net=[@new_netconne];

if($debugFlag==1)

print "$net=>[@new_netconne] now\n";

if($debugFlag==1)

print "\n**new dependencies after combining some paths**\n";

foreach my $item (keys %depen)

print "$item: @$depen$item\n";

############## add the symbol dependencies we assigned

foreach (keys %symbolDepen)

my $temp=[@$symbolDepen$_[0],@$symbolDepen$_[1]];

if($debugFlag==1)

print @$temp, "\n";

$depen$_=[@$symbolDepen$_[0],@$symbolDepen$_[1]];

###############################################

#build the relationshiop between the net number

###############################################

$i=0;

Page 167: Design and verification approaches for reliability and

154

my %net_num;

undef %net_num;

my %num_net;

undef %num_net;

if($debugFlag==1)

print "\n**net<=>number transform list**\n";

=pod

foreach my $dep (@d)

print " @$dep \n";

if (not exists $net_num$dep->[1])

$net_num$dep->[1]=$i;

$num_net$i=$dep->[1];

$i++;

if (not exists $net_num$dep->[0])

$net_num$dep->[0]=$i;

$num_net$i=$dep->[0];

$i++;

=cut

foreach my $dep (keys %depen)

# print "@$depen$dep \n";

if (not exists $net_num@$depen$dep[1])

$net_num@$depen$dep[1]=$i;

$num_net$i=@$depen$dep[1];

$i++;

if (not exists $net_num@$depen$dep[0])

$net_num@$depen$dep[0]=$i;

$num_net$i=@$depen$dep[0];

$i++;

my $num_vertices=$i;

Page 168: Design and verification approaches for reliability and

155

my $num_depen=keys %depen;

if($debugFlag==1)

print "num_vertices==>$num_vertices\n";

foreach $_(keys %net_num)

print $_,"\t",$net_num$_,"\n";

foreach $_(keys %num_net)

print $_,"\t",$num_net$_,"\n";

# if debugFlag

######################################

#print the dependencies to a text file.

######################################

open( MYDEPEN, ">./dependenciesToJava.txt") || die "Can't open myfile: $!";##'>' means

write only, it will clear and rewrite the file.

open( MYDEPEN1, ">./dependencies.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

if($debugFlag==1)

print "\n**denpendencies list**\n";

=pod

print MYDEPEN $i=keys %depen,"\n";

foreach my $item (keys %depen)

print "$item => '@$depen$item'\n";

print MYDEPEN "$item => '@$depen$item'\n";

close(MYDEPEN);

=cut

=pod

print MYDEPEN $i=@d,"\n";

foreach my $item (@d)

print "@$item[0] => @$item[1]\n";

# print "$net_num@$item[0] => $net_num@$item[1]\n";

# print MYDEPEN "@$item[0],@$item[1]\n";

print MYDEPEN "$net_num@$item[0],$net_num@$item[1]\n";

Page 169: Design and verification approaches for reliability and

156

close(MYDEPEN);

=cut

#=================================================================

=====================================

# Attention this number should be the total number of vertices, not the total number of

dependencies

print MYDEPEN $num_vertices,"\n";

print MYDEPEN $num_depen,"\n";

#=================================================================

=====================================

foreach my $item (keys %depen)

if($debugFlag==1)

print "@$depen$item[0] => @$depen$item[1]\n";

# print "$net_num@$depen$item[0] => $net_num@$depen$item[1]\n";

# print MYDEPEN "@$depen$item[0],@$depen$item[1]\n";

print MYDEPEN

"$net_num@$depen$item[0],$net_num@$depen$item[1]\n";

print MYDEPEN1 "@$depen$item[0] @$depen$item[1]\n";

close(MYDEPEN);

close(MYDEPEN1);

print STDOUT "progress= 30\n";

#################################

#call java code to find loops

#################################

if($debugFlag==1)

print "**\nThe loop found by java**\n";

#system("make");

#system("java ITV.breakLoop.de.graphs.TestCycles >java.log");

####open the loops file that generated from eclips.

open( MYLOOPS, "<loopsFromJava.txt") || die "Can't open myfile: $!";##'<' or omitting

means read only.

print STDOUT "progress= 50\n";

## the sign "+>"open with read and write mode

my @loops_num=<MYLOOPS>;

#print MYLOOPS "";#clear the data after read

Page 170: Design and verification approaches for reliability and

157

close(MYLOOPS);

my @loops_net;

####transform the num to net

foreach (@loops_num)

my @temp;

chomp $_;

@temp=split(/ /,$_);

my @newloops;

foreach my $num (@temp)

push @newloops, $num_net$num;

push @loops_net,[@newloops];

# print "@temp \n";

my @pathNames;

if($debugFlag==1)

print "\n**path list**\n";

open( MYPATH, ">./pathList.txt") || die "Can't open myfile: $!";##'>' means write only, it

will clear and rewrite the file.

foreach (keys %path)

if($debugFlag==1)

print "$_=>@$path$_\n";

print MYPATH "$_=>@$path$_\n";

push @pathNames, $_;

close(MYPATH);

if($debugFlag==1)

print "\nself-determined path:\n";

foreach my $pt (keys %self_deter_path)

if($debugFlag==1)

print "$pt=>@$self_deter_path$pt\n";

Page 171: Design and verification approaches for reliability and

158

for (my $i=0;$i<@$self_deter_path$pt;$i++)

if($i%2==0 && $i>0)

my $net=@$self_deter_path$pt[$i];

if ($net ne $path_end)

#find for each net the belonging to self-deter paths

=pod

$net__selfDeterPath$net=[] if (not exists $net__selfDeterPath$net);

$net__selfDeterPath$net=[@$net__selfDeterPath$net,$pt];

=cut

push @$net__selfDeterPath$net,$pt;

if($debugFlag==1)

print "\n**net from self-determined path**\n";

foreach (keys %net__selfDeterPath)

print "$_=>@$net__selfDeterPath$_\n";

open( MYLOOP, ">loopList.txt") || die "Can't open myfile: $!";##'>' means write only, it will

clear and rewrite the file.

foreach my $pt (keys %path)

print MYLOOP "$pt \t";

foreach (@$path$pt)

s/PD/P/;

s/ND/N/;

s/MD/M/;

s/TD/T/;

s/_BE//;

print MYLOOP "$_ ";

print MYLOOP "\n";

Page 172: Design and verification approaches for reliability and

159

if($debugFlag==1)

print "\n**Loop list**\n";

my $k=0;

my %loopSign;

tie my %loopList, 'Tie::IxHash';

my %net_loop;

my %positLoopList;

my %negLoopList;

my %posLoop_net;

foreach my $loop (@loops_net)

my $iii=@$loop;

# print "$iii\n";

if(@$loop>2)

$k++;

my $loopNum='loop'.$k;

$loopList$loopNum=$loop;

if($debugFlag==1)

print "\n$loopNum: @$loop";

#############################################

#following code is to identify the common Nets

#of two paths

#############################################

sub findPathCommonNets

my ($pt1,$pt2)=@_;

my @pt1=@$path$pt1;

my @pt2=@$path$pt2;

my @common;

my @common2;

for (my $i=1; $i<@pt1-1;$i++)

for (my $j=1; $j<@pt2-1;$j++)

if($pt1[$i] eq $pt2[$j])

Page 173: Design and verification approaches for reliability and

160

push @common,$pt1[$i];

if(@common)

if($common[0] eq $pt1[1])

pop @common;

elsif($common[-1] eq $pt1[-2])

@common= grep($_ ne $common[0], @common);

for (my $index=0; $index<@common;$index++)

if($index%2 ==1)

push @common2, $common[$index];

if(@common2)

if($debugFlag==1)

print "$pt1 & $pt2(common):@common2\n";

return \@common2;

#############################################

#following code is to remove some loop

#since some path in this loop has shared node

#############################################

if($debugFlag==1)

print "\n**path list**\n";

foreach (keys %path)

print "$_=>@$path$_\n";

tie my %pathComm, 'Tie::IxHash';

for (my $i=0; $i<@pathNames;$i++)

Page 174: Design and verification approaches for reliability and

161

my $pt1=$pathNames[$i];

for (my $j=$i+1; $j<@pathNames;$j++)

my $pt2=$pathNames[$j];

my $common=findPathCommonNets($pt1,$pt2);

if(@$common)

$pathComm$pt1.$pt2=$common;

$pathComm$pt2.$pt1=$common;

if($debugFlag==1)

print "\n**path commom nets list**\n";

foreach (keys %pathComm)

print "$_=>@$pathComm$_\n";

tie my %loopList_temp, 'Tie::IxHash';

%loopList_temp=%loopList;

foreach my $loopNum (keys %loopList_temp)

my $loop=$loopList_temp$loopNum;

if($debugFlag==1)

print "\n$loopNum: @$loop\n";

my @temp=@$loop;

#$loopList_temp$loopNum=[@temp];

push @temp,@$loop[0];#make the last item equal to the loop begin

my $sign=0;

my @pathInLoop;

my @netInLoop;

for (my $index=0; $index<@$loop;$index++)

if(@$loop[$index]=~/^path/)

my $I=@$loop[$index];#start from current

if($debugFlag==1)

print "$I\t @$path$I\n";##print the path that need to be highlighted

push @pathInLoop,@$loop[$index];

Page 175: Design and verification approaches for reliability and

162

else

push @netInLoop,@$loop[$index];

if($debugFlag==1)

print "\npathInLoop: @pathInLoop\nnetInLoop: @netInLoop\n";

for (my $i=0; $i<@pathInLoop;$i++)

my $pt1=$pathInLoop[$i];

for (my $j=$i+1; $j<@pathInLoop;$j++)

my $pt2=$pathInLoop[$j];

if(exists $pathComm$pt1.$pt2)

#print "$pt1 $pt2:@$pathComm$pt1.$pt2\n";

my @common=@$pathComm$pt1.$pt2;

my %common;

map($common$_=1,@common); # create %pt1 with elements from @pt1

my @temp=grep(defined($common$_),@netInLoop); # returns those

elements of @pt2 that don't

if(@temp)

if($debugFlag==1)

print "The CV @temp is in $pt1.$pt2: @common\t thus this loop should be

delete!!\n";

delete $loopList$loopNum;

#############################################

#following code is to determine loop sign

#############################################

sub expandLoopBetweenTwoCV

my ($pt,$inst,$CV)=@_;

#print "$pt:@$path$pt\n";

Page 176: Design and verification approaches for reliability and

163

my @k;

my @expand;

for (my $i=0; $i<@$path$pt;$i++)

my $temp=@$path$pt[$i];

if($temp eq $inst || $temp eq $CV)

push @k, $i;

for (my $i=$k[0]; $i<=$k[1];$i++)

push @expand, @$path$pt[$i];

my @expand1;

if($expand[0] ne $inst) #make sure always starts at the input $inst

while(@expand)

my $temp=pop @expand;

push @expand1, $temp;

else

@expand1=@expand;

my @expand2;

for (my $i=0; $i<@expand1;$i++) ### only keep the net

if($i%2==1)push @expand2,$expand1[$i];

return @expand2;

########

#expand loop

tie my %loopListExpand, 'Tie::IxHash';

$k=0;

foreach my $loopNum (keys %loopList)

my $loop=$loopList_temp$loopNum;

if($debugFlag==1)

print "\n$loopNum: @$loop\n";

my @temp=@$loop;

push @temp,@$loop[0];#make the last item equal to the loop begin

my @extendLoop;

for (my $index=0; $index<@$loop;$index++)

Page 177: Design and verification approaches for reliability and

164

push @extendLoop,@$loop[$index];

if(@$loop[$index]=~/^path/)

my $I=@$loop[$index];#start from current

foreach my $MOS (@$check_gate$I)#MOS-> each transistor of this path

my $CV=@$loop[$index-1];

if($CV eq $gate$MOS || $CV eq $MOS_Channel$MOS[1])

#print "$CV -> $MOS ->$temp[$index+1]\n";

my @expand=expandLoopBetweenTwoCV($I, $MOS,$temp[$index+1]);

#print "$temp[$index-1], $temp[$index], $temp[$index+1]\t";

#print "is expaned to: $temp[$index-1] $temp[$index] @expand\n";

#print "input: $I, $MOS,$temp[$index+1]\n";

#print "output: @expand\n";

push @extendLoop,@expand;

pop @extendLoop;

last;

if($debugFlag==1)

print "extendLoop: @extendLoop\n";

my %seen;

my $flag=1;

foreach (@extendLoop)

if(!$seen$_)

$seen$_=1;

else

if($debugFlag==1)

print "$_ is repeated in this loop, so it is not a loop\n";

$flag=0;

last;

if($flag)

$k++;

Page 178: Design and verification approaches for reliability and

165

my $Num='loop'.$k;

$loopListExpand$Num =\@extendLoop;

if($debugFlag==1)

print "\n**Expanded loop list**\n";

foreach (keys %loopListExpand)

print "$_=>@$loopListExpand$_\n";

$k=0;

my %seenLoop;

tie my %loopListOnlyNet, 'Tie::IxHash';

foreach my $loopNum (keys %loopListExpand)

my $loop=$loopListExpand$loopNum;

my @loopOnlyNet;

my $loopOnlyNetStr;

for (my $index=0; $index<@$loop;$index++)

if(@$loop[$index]=~/^path/)

else

push @loopOnlyNet,@$loop[$index];

if(defined $loopOnlyNetStr)

$loopOnlyNetStr=$loopOnlyNetStr.' '.@$loop[$index];

else

$loopOnlyNetStr=@$loop[$index];

if($debugFlag==1)

print "@loopOnlyNet\t$loopOnlyNetStr\n";

if(!$seenLoop$loopOnlyNetStr)

$seenLoop$loopOnlyNetStr=1;

$k++;

Page 179: Design and verification approaches for reliability and

166

my $Num='loop'.$k;

#my @temp=split(/ /,$loopOnlyNetStr);

#print "$_=> @temp\n";

$loopListOnlyNet$Num=$loop;

else

if($debugFlag==1)

print "$_ is repeated loop\n";

if($debugFlag==1)

print "\n**Only Net loop list**\n";

foreach (keys %loopListOnlyNet)

print "$_=>@$loopListOnlyNet$_\n";

print STDOUT "progress= 60\n";

#########

#loop sign

print "\n**determine loop sign**\n";

#if $debugFlag

%loopList=%loopListOnlyNet;

foreach my $loopNum (keys %loopList)

my $loop=$loopList$loopNum;

if($debugFlag==1)

print "\n$loopNum: @$loop\n";

my @temp=@$loop;

#$loopList$loopNum=[@temp];

push @temp,@$loop[0];#make the last item equal to the loop begin

my $sign=0;

for (my $index=0; $index<@$loop;$index++)

if(@$loop[$index]=~/^path/)

my $I=@$loop[$index];#start from current

# print "$I\t @$path$I\n";##print the path that need to be highlighted

Page 180: Design and verification approaches for reliability and

167

foreach my $MOS (@$check_gate$I)#MOS-> each transistor of this path

my $prop=$instance_prop$MOS;

if($prop=~/^pmos|^pfet/)

# print "$I=>$MOS,\n$gate$MOS\t

MOS_Channel$MOS[1]:$MOS_Channel$MOS[1]\n";

if(@$loop[$index-1] eq $gate$MOS)#V_GP->I

$sign+=1 ;

if($debugFlag==1)

print " @$loop[$index-1]=>$I is negtive \n";

if($temp[$index+1] eq $MOS_Channel$MOS[1])#I->V_SP

$sign+=1;

if($debugFlag==1)

print "test $MOS\_S=> $MOS_Channel$MOS[1]\n";

print " $I=>$temp[$index+1] is negtive \n";

#if

else ##NMOS

# print "$I=>$MOS,\n MOS_Channel$MOS:

@$MOS_Channel$MOS\t gate$MOS: $gate$MOS\n";

if(@$loop[$index-1] eq $MOS_Channel$MOS[1]) #V_SN->I

$sign+=1 ;

if($debugFlag==1)

print " @$loop[$index-1]=>$I is negtive \n";

if((@$loop[$index-1] eq $gate$MOS) or (@$loop[$index-1] eq

$MOS_Channel$MOS[1])) #I->V_DN

if(($temp[$index+1] eq $MOS_Channel$MOS[0]) or

($MOS_Channel$MOS[1] eq $path_end)) ## for I->VD_N the VD_N can be a points

more close to 'Vdd' then the drain of current transistor

Page 181: Design and verification approaches for reliability and

168

$sign+=1;

if($debugFlag==1)

print " $I=>$temp[$index+1] is negtive \n";

#else

#foreach

if(!defined $temp[$index+2])$temp[$index+2]=@$loop[1];

my $depenName=$temp[$index+1].$temp[$index+2];

if(exists $symbolDepen$depenName)

if($debugFlag==1)

print "find a symbol dependency\n";

if($symbolDepen$depenName[2]=='1')

if($debugFlag==1)

print " $temp[$index+1]=>$temp[$index+2] is negtive \n";

$sign+=1;

else

#find for each net the belonging to loop

push @$net_loop@$loop[$index],$loopNum;

if ($sign%2==0 && $sign>0)

if($debugFlag==1)

print " positive loop\n";

$loopSign$loopNum='positive';

else

if($debugFlag==1)

print " negtive loop\n";

$loopSign$loopNum='negative';

Page 182: Design and verification approaches for reliability and

169

print MYLOOP "$loopNum\t$loopSign$loopNum\t";

print MYLOOP "@$loop\n";

#=================================================================

===

#Out put the extended loop to "loopList.txt"

=pod

foreach (keys %loopListExpand)

print MYLOOP "$_=>@$loopListExpand$_\n";

=cut

#=================================================================

===

if($debugFlag==1)

print "\n**net from positive loop**\n";

foreach my $net (keys %net_loop)

foreach my $loop (@$net_loop$net)

if($loopSign$loop eq'negative')

# print "$net=>[@$net_loop$net] originally\n";

my @new_netconne=grep (!/$loop/,@$net_loop$net);#

$net_loop$net=[@new_netconne];

#print "$net=>[@new_netconne] now\n";

#elseprint "$net=> [@$net_loop$net]\n";

if($debugFlag==1)

print "$net=> [@$net_loop$net]\n";

#=================================================================

===

#=================================================================

===

if($debugFlag==1)

print "\n**Controlling inst for all nets in positive loops**\n";

open( CLTRINST, ">./controlInstList.txt") || die "Can't open myfile: $!";

Page 183: Design and verification approaches for reliability and

170

foreach my $net (keys %net_loop)

if(@$net_loop$net)# only consider the nets in positive feedback loop which are

potential breakpoints

#find the controling devices for each potential break point

if(exists $gate_net$net) #this can be wrong if we have cascode diode transistor as

in wildlar banba

my @potentialCtrlInst=@$gate_net$net;

my @finalCtrlInst;

my @controlPath;

foreach my $item (keys %depen)

if($item=~/^$net/)

if($debugFlag==1)

print " $item: @$depen$item\n";

push @controlPath,$$depen$item[1];

if($debugFlag==1)

print "controlPath: @controlPath\n";

my $ff;

foreach my $ins(@potentialCtrlInst)#want to check whether this potential control

instance is in the controling path

$ff=0;

foreach my $pt (@controlPath)

if($debugFlag==1)

print "@$path$pt\n";

foreach(@$path$pt)

#print "potentialControlIns: $ins\t pathItem: $_...\n";

if($_ eq $ins)

$ff=1;

if($debugFlag==1)

print "\t$ins exists in $pt!!!\n";

Page 184: Design and verification approaches for reliability and

171

last;

if($ff==1)push @finalCtrlInst, $ins;

#print "$net: @$gate_net$net\n";

#print CLTRINST "$net @$gate_net$net\n";

if($debugFlag==1)

print "$net: @finalCtrlInst\n";

print CLTRINST "$net @finalCtrlInst\n";

close( CLTRINST );

#=================================================================

===

#=================================================================

===

foreach my $loop (keys %loopList)

if($loopSign$loop eq 'positive')

$positLoopList$loop=$loopList$loop;

else

$negLoopList$loop=$loopList$loop;

=pod

print "\n**find positive loop dependencies**\n";

my @pathInPositiLoop;

foreach my $loop (keys %positLoopList)

for (my $index=0; $index<@$positLoopList$loop;$index++)

if(@$positLoopList$loop[$index]=~/^path/)

Page 185: Design and verification approaches for reliability and

172

push @pathInPositiLoop, @$positLoopList$loop[$index];

#print @$positLoopList$loop[$index],"\n";

my %contrLoop;

my %contrLoop_detail;

foreach my $loop (keys %positLoopList)

my @contrlLoop;

my %contrlLoopDepenDetail;

my @contrlLoopDepenDetail;

#push @contrlLoop,$loop;

print "$loop: @$positLoopList$loop\n";

for (my $index=0; $index<@$positLoopList$loop;$index++)

if(@$positLoopList$loop[$index]=~/^path/)

my $pt=@$positLoopList$loop[$index];

print " For $pt:\n";

foreach my $ins (@$check_gate$pt) #ins-> each transistor of this path

print "\tThe gate of $ins is $gate$ins\n";

my @loopDepenDetail;

push @loopDepenDetail,$loop,$gate$ins;

my ($contrlLoop,

$loopdepen)=check_gate($gate$ins,$loop,\@loopDepenDetail);

#print "the control loop is $contrlLoop\n";

#print "Detailed loop depen: @$loopdepen\n\n";

if(!(grep($_ eq $contrlLoop) @contrlLoop))

if (!$contrlLoop eq "")

push @contrlLoop, $contrlLoop;

my @temp;

while(@$loopdepen)

push @temp, (pop @$loopdepen);

push @contrlLoopDepenDetail,\@temp;

Page 186: Design and verification approaches for reliability and

173

print "The final control loop of $loop is @contrlLoop\n";

print "\n";

$contrLoop$loop=[@contrlLoop];

$contrLoop_detail$loop=[@contrlLoopDepenDetail];

print "\n**Group the positive Loop**\n";

my %net_loop_temp=%net_loop;

my %positLoopList_temp=%positLoopList;

my %GroupLoop;

my %GroupLoop_flat;

$i=0;

while(%positLoopList_temp)

$i++;

print "$i\n";

my $maxLoopnum=0;

my $breakPoint=undef;

while (my ($key, $loop)=each(%net_loop_temp))

if(@$loop>$maxLoopnum)

print "Got a better net: since $key=>[@$loop] >$maxLoopnum\n";

$maxLoopnum=@$loop;

$breakPoint=$key;

print "breakPoint=>$breakPoint for: @$net_loop_temp$breakPoint\n";

$GroupLoop$breakPoint=\@$net_loop_temp$breakPoint;

#delete $net_loop_temp$breakPoint;

grep(delete $positLoopList_temp$_,@$net_loop_temp$breakPoint); #delete the

loop after group it

my %new_net_loop_temp;

print "Now the left positive loop is:\n";

foreach my $loop (keys %positLoopList_temp)

my @temp=@$positLoopList_temp$loop;

print "$loop=> @temp\n";

if(@temp>2)

for (my $index=0; $index<@temp;$index++)

if(!($temp[$index]=~/^path/))

#find for each net the belonging to loop

push @$new_net_loop_temp$temp[$index],$loop;

Page 187: Design and verification approaches for reliability and

174

%net_loop_temp=%new_net_loop_temp;

print "Now the new net_loop_temp is;\n";

foreach (keys %net_loop_temp)

print "$_=>[@$net_loop_temp$_]\n";

print "\n**Positive Loop list**\n";

while (my ($key, $value)=each(%positLoopList))

print "$key=> @$value\n";

print "\n**After group them**\n";

foreach my $breakpoint (keys %GroupLoop)

print "$breakpoint=>[@$GroupLoop$breakpoint]\n";

foreach (@$GroupLoop$breakpoint)

push @$GroupLoop_flat$breakpoint,@$positLoopList$_;

# print "@$GroupLoop_flat$breakpoint\n";

print "\n**loop dependencies**\n";

foreach (keys %contrLoop)

my $jj=@$contrLoop$_;

print "For $_: $jj\n";

for (my $k=0; $k<@$contrLoop$_;$k++)

my $L;

$L=@$contrLoop$_[$k];

#print "loop depen$k: $L => $_\n";

my $i=$k+1;

print "loop depen$i: @@$contrLoop_detail$_[$k]\n";

Page 188: Design and verification approaches for reliability and

175

##check whether a gate will cause loop dependencies

sub check_gate

my ($gt,$loop, $loopDepenDetail)=@_;

my @loopDepenDetail=@$loopDepenDetail; #store the detaied information of where a

loop dependency come from

if($gt eq $path_end)

print "\t$gt is fixed bias\n";

push @loopDepenDetail,$path_end;

return ("", \@loopDepenDetail);#$loop;

elsif(exists $net_loop$gt and (grep$_ eq $loop @$net_loop$gt)) #if the $gate is a

net of the loop itself then no loop dependencies caused by this gate

print "\t$gt is a net of the loop itself \n";

push @loopDepenDetail,$loop;

return ("", \@loopDepenDetail);#$loop;

else

if(exists $net_from_depen$gt)###########top level dependency

my ($contrPath)=@$net_from_depen$gt;

print "$gt is from $contrPath,\n";

push @loopDepenDetail,$contrPath;

if(grep$_ eq $contrPath @$positLoopList$loop)# if the $contrPath of this gate

is a path of the loop itself then no loop dependencies caused by this gate

print " the $contrPath is a path of the loop itself\n";

push @loopDepenDetail,$loop;

return ("", \@loopDepenDetail);#$loop;

else

foreach my $L (keys %positLoopList)

if(grep$_ eq $contrPath @$positLoopList$L)# if the $contrPath is a

path of another Loop

print "the $contrPath is a path of another loop: $L\n";

pop @loopDepenDetail;

push @loopDepenDetail,$L;

print "now the return loopdepen is @loopDepenDetail\n";

return ($L,\@loopDepenDetail);

#print "now the return loopdepen is @loopDepenDetail\n";

# if

Page 189: Design and verification approaches for reliability and

176

#foreach

print "continuing finding...\n";

print "the $contrPath is from @$path_from_depen$contrPath\n";

foreach my $contrVolt (@$path_from_depen$contrPath)

print "the $contrPath is controled by $depen$contrVolt[0]\n";

push @loopDepenDetail,$depen$contrVolt[0];

#print "10now the return loopdepen is @loopDepenDetail\n";

#print " we are checking: $depen$contrVolt[0],$loop\n";

my ($contrLoop,

$loopDepen)=check_gate($depen$contrVolt[0],$loop,\@loopDepenDetail);

if ($contrLoop ne $loop)

# @loopDepenDetail=@$loopDepen;

#print "11now the return loopdepen is @$loopDepen\n";

return ($contrLoop,$loopDepen);

#foreach

#else

#if

elsif(exists $net_from_symbolDepen$gt) ##########symbol dependency

print "$gt is from the symbol dependency @$net_from_symbolDepen$gt\n";

foreach my $dep (@$net_from_symbolDepen$gt)

print "@$symbolDepen$dep\t";

my ($contrVolt)=grep(!/$gt/, @$symbolDepen$dep);

print "the $gt is controled by: $contrVolt\n";

push @loopDepenDetail,$contrVolt;

my ($contrLoop, $loopDepen)=check_gate($contrVolt,$loop,\@loopDepenDetail);

if ($contrLoop ne $loop)

# @loopDepenDetail=@$loopDepen;

#print "11now the return loopdepen is @$loopDepen\n";

return ($contrLoop,$loopDepen);

#if

#foreach

#elsif

# else

=cut

#####caculate execution time

my $finish_time=time();

Page 190: Design and verification approaches for reliability and

177

my $finish_time2=localtime();

if($debugFlag==1)

print "finish at:$finish_time2\n";

my $timeused=$finish_time-$start_time;

print "Used time: $timeused\n";

print @mySymbolDepden;

print "\n**positive loop list**\n";

foreach my $loop (keys %positLoopList)

print "$loop: @$positLoopList$loop\n";

print "\n**negative loop list**\n";

# if($debugFlag==1)

open( NEGLOOP, ">./negtiveLoops.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

foreach my $loop (keys %negLoopList)

if($debugFlag==1)

print "$loop=> @$negLoopList$loop\n";

print NEGLOOP "@$negLoopList$loop ";

close(NEGLOOP);

open( PATHLIST, ">./pathList.txt") || die "Can't open myfile: $!";##'>' means write only, it

will clear and rewrite the file.

foreach my $net (keys %net_path_bak)

print PATHLIST "$net: @$net_path_bak$net\n";

foreach (keys %path_bak)

print PATHLIST "$_=>@$path_bak$_\n";

close(PATHLIST);

#=============================

Page 191: Design and verification approaches for reliability and

178

open( SUPPLY, ">./supplyVoltage.txt") || die "Can't open myfile: $!";##'>' means write only,

it will clear and rewrite the file.

foreach my $net (keys %supplyVol)

print SUPPLY "$net $supplyVol$net\n";

close( SUPPLY );

#=============================

print STDOUT "progress= 70\n";

system("perl ./ITV/breakLoop/searchBreakPoints.pl -d $debugFlag");

print STDOUT "FINISHED\n";

2. autoGenerateNetlist.il

;;;load("./ITV/breakLoop/autoModifyNetlist/autoGenerateNetlist.il")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;if this is set to be '1' then the partial netlist for the breaked loop will be generated, otherwise

the whole netlist will begengerated

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

genePartialNetlist=0;

CV=geGetEditCellView()

println(CV)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;set default value

defaltVDD=hiGetCurrentForm()->Vdd->value

defaltVSS=hiGetCurrentForm()->Vss->value

defaltBreakPoint=hiGetCurrentForm()->BreakPoint->value

defaltSCC=hiGetCurrentForm()->strongCompList->value

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

let((myPort pathItemId loopItem pathItem myInstTerm)

myPort = outfile(simplifyFilename("./myPartNetlist.scs"))

fprintf(myPort "//Library name: %L \n" CV~>libName)

fprintf(myPort "//Cell name: %L \n" CV~>cellName)

fprintf(myPort "//View name: %L \n" CV~>cellViewType)

fprintf(myPort "MyVdd: %L \n" defaltVDD)

fprintf(myPort "MyVss: %L \n" defaltVSS)

);let

myNetOfPath=makeTable("myNetOfPath" nil);

Page 192: Design and verification approaches for reliability and

179

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;show the path table;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

println(";;;path list;;;;")

let((pathName)

foreach(pathName pathTable

println(

list(pathName pathTable[pathName])

);println

;selectPath(pathTable[pathName])

);foreach

);let

;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;show the loop table;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;

println(";;;loop list;;;;")

foreach(loopName loopTable

println(

list(loopName loopTable[loopName])

);println

);foreach

;==================================================================

==============================

DDGTable=makeTable("DDGTable" nil) ;store the dimension for each SCC

let( (inport nextLine dependencies DepenName)

inport=infile("./dependencies.txt")

when(inport

while(gets(nextLine inport)

println(nextLine)

dependencies=parseString(nextLine)

DepenName =car(dependencies)

DDGTable[DepenName]=append1(DDGTable[DepenName] cadr(dependencies))

);while

close(inport)

);when

);let

printf("\n**DDG Table**\n")

foreach(DepenName DDGTable

printf("%s=>%L\n" DepenName DDGTable[DepenName])

)

;==================================================================

==============================

aa=nil

breakedLoopFromBreakPoint=nil

Page 193: Design and verification approaches for reliability and

180

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;find the gate of tansistor (controlling transistor that need to connect to sweep votalge

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

let((selWire breakNet instConnToSelNet instNum currentBreakPoint potentialCltrInst)

;;these following code always treat the selected net as breaking point

;selWire=geGetSelSet()

;instConnToSelNet=car(selWire~>net~>instTerms~>inst~>name)

;instConnToSelNet=car(selWire~>net~>instTerms~>inst)

;;the following consider the value from the break point form as breaking point

temp0=parseString(defaltBreakPoint, "");;;from the form we get the breakpoints

breakNets=car(parseString(car(temp0),""))

breakNets=parseString(breakNets," ")

printf("The breakpoints figured out from the form are: %L \n" breakNets)

;println(breakNets)

cltrInst=makeTable("cltrInst" nil)

foreach(currentBreakPoint breakNets;;; several break points foreach

;;;;the following is trying to figure out the breaked loop from the given breaking points

foreach(loopName loopTable

println(loopTable[loopName]);println

foreach(loopItem loopTable[loopName]

if(loopItem==currentBreakPoint then

breakedLoopFromBreakPoint=append1(breakedLoopFromBreakPoint

loopName)

);if

);foreach

);foreach

instNum=makeTable("instNum" nil)

breakNet=dbFindNetByName(CV currentBreakPoint)

instConnToSelNet=breakNet~>instTerms~>inst

;=========================

;=========================

aa=instConnToSelNet

println(

list(" !!!instConnToSelNet" instConnToSelNet~>name)

)

println(instConnToSelNet~>??

)

foreach(inst instConnToSelNet

block=nil

BPS=inst~>name

if(inst~>prop==nil then block=inst; a self-created block is found

; following is to figure out the connection between level to level-1

printf("%s(PIN): %L\n" block~>name block~>instTerms~>name)

Page 194: Design and verification approaches for reliability and

181

printf("%s(Conn): %L\n" block~>name block~>instTerms~>net~>name)

foreach(myTerms block~>instTerms

if(myTerms~>net~>name==currentBreakPoint then

nextLevelBreakPoint=myTerms~>name

printf("Current BPS: %s=>" currentBreakPoint)

BPS=strcat(BPS "." nextLevelBreakPoint)

printf("Next BPS: %s\n" BPS)

);if

);foreach

nextLevelCV=dbGetAnyInstSwitchMaster(block "schematic")

breakNetNextLevel=dbFindNetByName(nextLevelCV nextLevelBreakPoint)

println(breakNetNextLevel~>instTerms~>inst~>name)

)

);foreach

;=========================

;=========================

foreach(inst instConnToSelNet

if(instNum[inst]==nil then

instNum[inst]=1

else

instNum[inst]=instNum[inst]+1

);if

);foreach

potentialCltrInst=nil

potentialCltrInstByName=nil

;println(instNum~>?)

foreach(inst instNum~>?

if(instNum[inst]==1 then ;;the instance that have two terminal connected to the selected

net is diode connection

potentialCltrInst=append1(potentialCltrInst inst)

potentialCltrInstByName=append1(potentialCltrInstByName inst~>name)

);if

);foreach

printf("potentialCltrInst is: %L \n" potentialCltrInst~>name)

;==================================================================

==============================

;make this change becase for cascode transistor, it's not necessarily diode transistors

printf("\n**The breakedLoop are:**\n\n" )

foreach(loopName breakedLoopFromBreakPoint

println(

list(loopName loopTable[loopName])

Page 195: Design and verification approaches for reliability and

182

);println

);foreach

println(

list(currentBreakPoint DDGTable[currentBreakPoint])

);println

foreach(DDGpath DDGTable[currentBreakPoint];foreach DDGTable

println(

list(DDGpath pathTable[DDGpath])

);println

foreach(inst potentialCltrInstByName

printf("??potentialCltrInst: %s\n" inst)

if(member(inst pathTable[DDGpath]) then

printf("??find one control inst: %s\n" inst )

cltrInst[inst]=currentBreakPoint

);if

;=========================

;=========================

;pathItem=pathTable[DDGpath]

foreach(pathItem pathTable[DDGpath]

printf("~~~~~~~~~~~~~~~~~~%s" pathItem)

pathItemList=parseString(pathItem ".")

println(pathItemList)

println(car(last(pathItemList)))

if(inst==car(last(pathItemList)) then

printf("??find one control inst: %s\n" inst )

)

)

;=========================

;=========================

);foreach

);foreach DDGTable

/*

foreach(inst potentialCltrInst

;println(inst~>name)

;println(inst~>instTerms~>name)

;println(inst~>instTerms~>net~>name)

;println(car(selWire~>net)~>name)

foreach(instTerm inst~>instTerms

if(instTerm~>name=="G" && instTerm~>net==breakNet then

printf("found it: %s gate connection should be changed" inst~>name)

cltrInst[inst~>name]=instTerm~>net~>name

;print(inst~>instTerms~>net)

);if

);foreach

Page 196: Design and verification approaches for reliability and

183

printf("\n")

);foreach

*/

;==================================================================

==============================

);;; several break points foreach

);let

printf("\n**The breakedLoop due to %L are:** \n%L \n" breakNets

breakedLoopFromBreakPoint)

printf("\n**Controling Devices & Voltages List**\n")

foreach(ins cltrInst

print(ins)

println(cltrInst[ins])

);foreach

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;generate netlist automatically

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

simulator( 'spectre )

;==================================================================

=============================================================

;don't need this. since this file is called by identifyBPS.il

;in that file CV is arealdy defined

;and this few sentence will actually generate a new window after close it, the activate

window will be nil and cause problem

;so if we click "Netlist" button multiple times, i.e. call this file multiple times in

identifyBPS.il

;CV=geGetEditCellView()

;schCheck(CV)

;==================================================================

=============================================================

design(

CV~>libName

CV~>cellName

CV~>cellViewType

)

address=createNetlist(

?recreateAll t

?display t

)

hiCloseWindow(hiGetCurrentWindow())

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;output the generated netlist and tansistor to a file

Page 197: Design and verification approaches for reliability and

184

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

myPort = outfile("./input.scs")

fprintf(myPort address)

foreach(ins cltrInst

fprintf(myPort "\n%L" ins)

fprintf(myPort " %L" cltrInst[ins])

);foreach

;fprintf(myPort " %L\n" loopTable[breakedLoop])

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;print a loop to a file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

foreach(breakedLoop breakedLoopFromBreakPoint;foreach for several broken Loops

println("breakedLoop now")

println(breakedLoop)

fprintf(myPort "\n%s" car(parseString(breakedLoop)))

if(cadr(parseString(breakedLoop)) then

fprintf(myPort " %s " cadr(parseString(breakedLoop)))

)

;fprintf(myPort "\n%L " breakedLoop)

;print a path to a file

/*

procedure(printPathTFile(pathName)

let((pathItemId pathItem)

foreach(pathItem pathTable[pathName]

pathItemId=dbFindAnyInstByName(CV pathItem)

if( pathItemId then;;or if(pathItem~>objType=="inst"

fprintf(myPort " %L" pathItemId~>name)

);let

);procedure

*/

pathNet=makeTable("pathNet" nil)

foreach(loopItem cdr(loopTable[breakedLoop])

if( rexMatchp("path" loopItem) then

foreach(pathItem pathTable[loopItem]

;fprintf(myPort " %L\t" pathItem)

pathItemId=dbFindAnyInstByName(CV pathItem)

if( pathItemId then;;or if(pathItem~>objType=="inst"

fprintf(myPort " %L" pathItemId~>name)

else

pathNet[pathItem]=loopItem

);if

);foreach

);if

Page 198: Design and verification approaches for reliability and

185

);foreach

);foreach for several broken Loops

fprintf(myPort "\nMyVdd: %L \n" loopListForm->Vdd->value)

fprintf(myPort "MyVss: %L \n" loopListForm->Vss->value)

println("path Net now")

foreach(pathNetItem pathNet

println(pathNetItem)

println(pathNet[pathNetItem])

);foreach

println("end pathnet")

;====================================

;====================================

fprintf(myPort "MyBPS:")

foreach(BPS breakNets

fprintf(myPort " %s" BPS)

)

fprintf(myPort "\n")

;====================================

;====================================

close(myPort)

;view("/home/yli/501labs/autoModifyNetlist/input.scs")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;communication with Netlist modifying program (written in perl)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

println("modifying simulator input file...")

let((result)

if(genePartialNetlist==1 then

cmd="perl ./ITV/breakLoop/autoModifyNetlist/modifyPartialNetlist.pl"

else

;cmd="perl ./ITV/autoModifyNetlist/modifyNetlist.pl"

cmd=strcat("perl ./ITV/breakLoop/autoModifyNetlist/modifyNetlist.pl " defaltSCC)

println(cmd)

);if

ChildId=ipcBeginProcess(cmd "" "" "" "" "autoGeneNetlist.log")

ipcWait(ChildId)

if(!ipcIsActiveProcess(ChildId) then x=1

; view("modifyNetlist.log")

; result=ipcReadProcess(ChildId)

Page 199: Design and verification approaches for reliability and

186

; println(result)

);;if

);let

ipcKillProcess(ChildId)

println(" ...successful.")

view(address)

view("./input1.scs")

;view("autoGeneNetlist.log")

2. modifyNetlist.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './ITV/breakLoop/Strong_conn_comp/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

my $input1 = $ARGV[0];

if ($input1 eq "")

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input1 to stand for SCC name***\n";

print "***E.g. ==> perl modifyNetlist.pl SCC1 <===\n\n";

exit(1);

else

print STDOUT "$input1\n";

#===============================

#####################################

#obtain the suppy voltage source for each vdd

#####################################

open( SUPPLY, "./supplyVoltage.txt") || die "Can't open myfile: $!";

my @supplyVol=<SUPPLY>;

close(SUPPLY);

print @supplyVol;

my %SUPPLY;

my %supplyVol;

my $numSupplyVol=0;

foreach (@supplyVol)

my @temp=split(/\s+/,$_);

$supplyVol$temp[1]=$temp[0];

Page 200: Design and verification approaches for reliability and

187

$numSupplyVol++;

print "\n**supply Voltage source list $numSupplyVol!!!**\n";

foreach (keys %supplyVol)

print "$_ $supplyVol$_\n";

my $supplyCont=0;

my %breakpointReplacement;

#===================================

#####################################

#obtain the instance for each SCC

#####################################

open( SCCInst, "./SCCInst.txt") || die "Can't open myfile: $!";

my @SCCInst=<SCCInst>;

close(SCCInst);

my %SCCInst;

foreach (@SCCInst)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInst$1=\@temp;

print "\n**SCC instance list**\n";

foreach (keys %SCCInst)

print "$_ @$SCCInst$_\n";

print "current SCC is: $input1 @$SCCInst$input1\n\n";

#####################################

#obtain the original netlist, controlling devices and controlling voltage

#####################################

open( MYFILE, "./input.scs") || die "Can't open myfile: $!";

my @address_input=<MYFILE>;

#print @address_input,"\n";

close(MYFILE);

open( MYINPUT, "$address_input[0]") || die "Can't open myfile: $!";

my @input_scs=<MYINPUT>;

Page 201: Design and verification approaches for reliability and

188

print @input_scs;

close(MYINPUT);

my %ctrlInst;

my %ctrlVolt_Inst;

my $ctrlVolt;

my @ctrlVolt;

my @BPS;

foreach $_ (@address_input)

if(/^\"(.*)\"\s\"(.*)\"/)

print $1,"!!!\t",$2,"\n";

my $A=$1;

my $B=$2;

#============================================================

=============

#this code is trying to deal with net name like "Vi-" "Vi+"

if(($B=~/(.*)(\-)/) or ($B=~/(.*)(\+)/))

$B=$1.'\\\\'.$2;# $B will be Vi\\- since in matching rule the first '\' is to tell the

second '\' is a charactor in the original string

#============================================================

=============

$ctrlInst$A=$B;#$A is contolling device and $B is controlling voltage

$ctrlVolt_Inst$B=[] if (not exists $ctrlVolt_Inst$B);

$ctrlVolt_Inst$B=[@$ctrlVolt_Inst$B, $A];

push @ctrlVolt, $B;

$ctrlVolt=$B;

#=================================================================

========

#=================================================================

========

elsif(/^MyBPS:\s(.*)/)

print "$1\n";

my @temp=split(/ /,$1);

foreach my $net (@temp)

if(($net=~/(.*)(\-)/) or ($net=~/(.*)(\+)/))

$net=$1.'\\\\'.$2;# $B will be Vi\\- since in matching rule the first '\' is to tell

the second '\' is a charactor in the original string

Page 202: Design and verification approaches for reliability and

189

push @BPS, $net;

$ctrlVolt=$BPS[0];

#=================================================================

========

#=================================================================

========

print "BPS: @BPS\nThe first controVolt: $ctrlVolt\n";

print "\n**ctrlVolt_Inst list**\n";

foreach $_ (keys %ctrlVolt_Inst)

print "$_ => @$ctrlVolt_Inst$_\n";

#=================================================================

========

#=================================================================

========

#=================================================================

========

open( PATHLIST, "./pathList.txt") || die "Can't open myfile: $!";##'>' means write only, it

will clear and rewrite the file.

my @pathList=<PATHLIST>;

my %BPSPowerSuply;

foreach (@pathList)

if(/^path\d+=>(.*)/)

print $1,"\n";

my @temp=split(/\s+/,$1);

foreach my $sup (@BPS)

if(/$sup/)

print " the breakpint $sup is in path $_ therefore one of its vdd is:

$temp[0]\n";

if(not exists

$BPSPowerSuply$sup)$BPSPowerSuply$sup=[$temp[0]];

else$BPSPowerSuply$sup=[@$BPSPowerSuply$sup, $temp[0]];

Page 203: Design and verification approaches for reliability and

190

print "\n**BPS Power Suply list**\n";

foreach (keys %BPSPowerSuply)

print "$_ @$BPSPowerSuply$_\n";

#=================================================================

========

print "\n**Controlling inst for all nets in positive loops**\n";

open( CTRLINST, "./controlInstList.txt") || die "Can't open myfile: $!";

my @ctrlInstForAllNets=<CTRLINST>;

close(CTRLINST);

my %ctrlInstForAllNets;

foreach $_ (@ctrlInstForAllNets)

my @temp=split(/\s+/,$_);

# print "@temp\t";

my $net=$temp[0];

my @inst=grep !/$net/, @temp;

if(($net=~/(.*)(\-)/) or ($net=~/(.*)(\+)/))

$net=$1.'\\\\'.$2;# $B will be Vi\\- since in matching rule the first '\' is to tell the

second '\' is a charactor in the original string

print "$net => @inst\n";

$ctrlInstForAllNets$net=\@inst;

my %ctrlVolt_Inst1;

foreach (@BPS)

$ctrlVolt_Inst1$_=$ctrlInstForAllNets$_

print "\n**ctrlVolt_Inst1 list**\n";

my @hier_ctrlVolt=split(/\./,$ctrlVolt); #I1.B => I1 B

my $numHier=@hier_ctrlVolt;

my %ctrledBlock;

my %ctrlingBlock;

foreach $_ (keys %ctrlVolt_Inst1)

print "$_ => @$ctrlVolt_Inst1$_\n";

my @temp1=split(/\./,$_ ); #I1.B => I1 B

Page 204: Design and verification approaches for reliability and

191

my $inNum=@temp1;

if($inNum>1) $ctrlingBlock$_=$temp1[$inNum-2];

foreach my $ins(@$ctrlVolt_Inst1$_)

my @temp2=split(/\./,$ins);

my $outNum=@temp2;

if($outNum>1 && ($outNum > $inNum)) #if $outNum > $inNum means that the

controling instance is insider a block of the CV level

$ctrledBlock$_=[] if (not exists $ctrledBlock$_);

$ctrledBlock$_=[@$ctrledBlock$_, $temp2[$outNum-2]];# for control

device like I1.P7 the block I1 also has terminal shoulbe be changed to Vin

if($ctrlingBlock$_)print "ctrlingBlock: $ctrlingBlock$_\n";

if($ctrledBlock$_)print " ctrlingBlock: @$ctrledBlock$_\n";

@ctrlVolt=@BPS;

%ctrlVolt_Inst=%ctrlVolt_Inst1;

=ppod

if($numHier==1)

print "wowowowo\n";

foreach $_ (keys %ctrlVolt_Inst1)

print "!!$_ => @$ctrlVolt_Inst1$_\n";

foreach my $ins(@$ctrlVolt_Inst1$_)

my @temp=split(/\./,$ins);

print "$ins!!! @temp\n";

=cut

#######################################################

#following codes is to find the subcircuit of a netlist

########################################################

print "\n**find the subcircuit of a netlist**\n";

my %subckt_termi;

my %subckt_netlist;

my @subNetlist;

my $subckt_name;

my $flag=0;

my @topLevel;

Page 205: Design and verification approaches for reliability and

192

my @netlist=@input_scs;

for (my $i=0; $i<@netlist;$i++)

#print "$netlist[$i]";

my $currentLine=$netlist[$i];

chop $currentLine;

$_=$netlist[$i];

if(/^subckt\s(.*)/)

my @temp=split(/\s+/,$1);

$subckt_name=$temp[0];

my @terms=grep !/$subckt_name/, @temp;

#print "$subckt_name\t@terms\n";

$subckt_termi$subckt_name=\@terms;

@subNetlist=();

$flag=1;

push @subNetlist, $_;

elsif($flag)

push @subNetlist, $_;

if(/^ends/)

#pop @subNetlist;

$subckt_netlist$subckt_name=[@subNetlist];

$flag=0;

if(!/^ends/ and $flag==0)

push @topLevel,$currentLine;

print "\n**Top level**\n";

for (my $i=0; $i<@topLevel;$i++)

print "$topLevel[$i]\n";

print "\n**subckt netlist**\n";

foreach (keys %subckt_termi)

# print "$_ (@$subckt_termi$_)\n";

print "@$subckt_netlist$_\n";

Page 206: Design and verification approaches for reliability and

193

#=================================================================

========

#=================================================================

========

#####################################

#generate a new netlist to be the same as we're breaking and inserting a voltage

#source at the break-points

#the relsulting netlist **.scs can be used as input file for break-loop homotopy

#method

#####################################

my @newInputScs;

my $BPSindex=1;

my $Vx="ITV2014vx".$BPSindex;

my $Vin="ITV2014Vin".$BPSindex;

my $Vout="ITV2014Vout".$BPSindex;

#==============================================

$breakpointReplacement$ctrlVolt=[$Vin, $Vout, $Vx];

#==============================================

my @instNotInSCC;

my $para_flag=0;

print "\n**For breakPoint: $ctrlVolt**\n";

;#foreach my $netLine (@input_scs)

for (my $index=0;$index<@input_scs;$index++)

my $netLine=$input_scs[$index];

my $currentOutputLine=$netLine;

$_=$netLine;

if($para_flag==1)

push @newInputScs, $netLine;

#add extra parameters

if(/^parameters/) # if3

chomp $currentOutputLine;# remove any newline character from the end of a string

my @temp1=split(/\s+/,$currentOutputLine);

foreach $_ (@temp1)

Page 207: Design and verification approaches for reliability and

194

if(/^Vx(\d+)/) ##the circuit may have some DC voltage named as "Vx**"

$BPSindex=$1+1;

if($BPSindex>0)

$Vx='ITV2014vx'.$BPSindex;#create a new DC voltage

$Vin="ITV2014Vin".$BPSindex;#create a new net name as controlling voltage

$currentOutputLine=$currentOutputLine.' '."$Vx\n";

#==============================================

$breakpointReplacement$ctrlVolt=[$Vin, $Vout];

#==============================================

#==============================================================

#

elsif(/^(V\d+)\s/)##the lines that may contain the power supply voltage source

if(exists $supplyVol$1)

my $volName=$1;

print "############The instance $1 is used to generate vdd:

$supplyVol$volName\n";

my $flag=0;

foreach my $BP (keys %BPSPowerSuply)

if(grep /$supplyVol$volName/, @$BPSPowerSuply$BP)

print "############The $supplyVol$volName in used for

breakpoint: $BP, thus need to changed!\n";

$flag=1;

last;

if($flag==1)

pop @newInputScs;

my $volVal;

if(/dc=(.*)\stype/)

$volVal=$1;

print "The DC value of this vdd is: $volVal????\n";

$supplyCont++;

push @newInputScs,"$volName ($supplyVol$volName 0) vsource

dc=ITV2014vdx$supplyCont type=dc\n";

$SUPPLY$supplyVol$volName="ITV2014vdx".$supplyCont."

$volName dc=$volVal";

Page 208: Design and verification approaches for reliability and

195

#==============================================================

elsif(/^\/\/\s+Library/ or /^\/\/\s+Cell/ or /^\/\/\s+View/) #we want to copy the first three line

push @newInputScs, $netLine;

elsif(/^simulatorOptions/) # we want to insert a line for sweeping voltage source before this

line

pop @newInputScs;

#print "$Vx ($Vin 0) vsource dc=$Vx type=dc\n";

if($numHier==1)

push @newInputScs,"$Vx ($Vin 0) vsource dc=$Vx type=dc\n";

$para_flag=0;

elsif(/^(\w+\d+)\s/) ##the lines that contain the instance netlist

my $currentIns=$1;

if(grep $_ eq $1 @$SCCInst$input1) ###if1

print "$1 is an instance in current SCC!!!!!! \n";

#=================================================================

==============

# end if1

else

if(!/^(V\d+)\s/ && !/^(I\d+)\s/)

print "Line$index $1 is not an instance in current SCC!!!!!! \n";

push @instNotInSCC, $1;

#end if1 else

#=================================================================

==============

$para_flag=1; #this is to make sure the original netlist lines is before the added line

my $temp=pop @newInputScs;

#print "previous line is ", $temp,"\n";

my $Vout1=$Vout.' '; # Ensure that we replace the word $Vout as a whole (avoid

such case: 'Vo'ut-> 'Vout'ut

$temp=~s/$ctrlVolt\s/$Vout1/g;

$Vout1=$Vout.')';

$temp=~s/$ctrlVolt\)/$Vout1/g;

#print "after change previous line is ", $temp,"\n";

Page 209: Design and verification approaches for reliability and

196

push @newInputScs, $temp;

#print "current line is ", $netLine, "\n";

$Vout1=$Vout.' ';

$netLine=~s/$ctrlVolt\s/$Vout1/g;

$Vout1=$Vout.')';

$netLine=~s/$ctrlVolt\)/$Vout1/g;

#print "after change current line is ", $netLine,"\n";

if($temp ne $netLine)

push @newInputScs, $netLine;

foreach my $ins (@$ctrlVolt_Inst$ctrlVolt)

if($currentIns eq $ins) #means find the controlling device line

print "$currentIns is corlling;;;\n";

print "before change:\n$netLine";

$netLine=~s/$Vout/$Vin/g; #replace the controlling voltage with Vin

print "after change:\n$netLine\n";

pop @newInputScs;

push @newInputScs,$netLine;

#end if

#end foreach

#============================================this consider the

controlling blocks

foreach my $ins (@$ctrledBlock$ctrlVolt)

if($currentIns eq $ins) #means find the controlling device line

print "$currentIns is corlling;;;\n";

print "before change:\n$netLine";

$netLine=~s/$Vout/$Vin/g; #replace the controlling voltage with Vin

print "after change:\n$netLine\n";

pop @newInputScs;

push @newInputScs,$netLine;

#end if

#end foreach

#===========================================

#=================================================================

==============

#this part has been moved to before, because even for instances not belongs to

#current SCC we still want to print it out in the first run (so that we have access

#to an modified netlist including all instances with the break-pints modified)

=pod

# end if1

else

if(!/^(V\d+)\s/ && !/^(I\d+)\s/)

Page 210: Design and verification approaches for reliability and

197

print "Line$index $1 is not an instance in current SCC!!!!!! \n";

push @instNotInSCC, $1;

#end if1 else

=cut

#=================================================================

==============

#end if3

#end foreach

=pod

##############################################################

#if an instance is not included in the SCC then there will be a extra continued line wchich we

don't want

#following codes is to delete that line

#my $previousLineInSCC=1;

if($previousLineInSCC ==0) ##if2

#pop @newInputScs;

$previousLineInSCC =1;

#end if2

=cut

#=================================================================

=========

#deal with breakpoint insider a subckt

print "\n**Trying to deal with breakpoint in subckt**\n";

#print "$ctrlVolt=>@$ctrlInstForAllNets$ctrlVolt \t@hier_ctrlVolt, $numHier\n";

if($numHier>=2)#means this circuit has hierachial

print "We need to create a new block for $hier_ctrlVolt[$numHier-2]\n";

my $ctrlVolt_Blk=$hier_ctrlVolt[$numHier-1];

print "Control Voltage:$ctrlVolt => $ctrlVolt_Blk \n";

my @ctrlVolt_Inst_Blk;

foreach(@$ctrlInstForAllNets$ctrlVolt)

my @temp=split(/\./,$_);

push @ctrlVolt_Inst_Blk,$temp[-1];

print "Control instances: @$ctrlInstForAllNets$ctrlVolt => @ctrlVolt_Inst_Blk\n";

for (my $i=0;$i<@newInputScs; $i++)

$_=$newInputScs[$i];

if(/$hier_ctrlVolt[$numHier-2](\s\(.*\)\s)(.*)/) #find the block in the last level

Page 211: Design and verification approaches for reliability and

198

print "$_\n";

#print "$1\t$2\n";

my $blkName=$2;

my $newName=$blkName.'_Break';

$newInputScs[$i]=~s/$blkName/$newName/;#change the block master name

print "=> $newInputScs[$i]\n";

#print "@$subckt_netlist$blkName\n";

$subckt_netlist$newName=$subckt_netlist$blkName; # create a new block

#modify it based on contol voltage and device

print "\n**For breakPoint: $ctrlVolt**\n";

=pod

$BPSindex=$BPSindex+1;

my $Vx="ITV2014vx".$BPSindex;#create a new DC voltage

my $Vin="ITV2014Vin".$BPSindex;#create a new net name as controlling voltage

my $Vout="ITV2014Vout".$BPSindex;

=cut

#==============================================

$breakpointReplacement$ctrlVolt=[$Vin, $Vout, $Vx];

#==============================================

my @subcktOld=@$subckt_netlist$blkName;

my @subcktNew;

for (my $index=0;$index<@subcktOld;$index++)

$_=$subcktOld[$index];

push @subcktNew,$_;

if(/(\w+\d+)\s/)

my $currentIns=$1;

my $temp=pop @subcktNew;

#print "current line is\n\t ",$temp, "\n";

my $Vout1=$Vout.' ';

$temp=~s/$ctrlVolt_Blk\s/$Vout1/g;

$Vout1=$Vout.')';

$temp=~s/$ctrlVolt_Blk\)/$Vout1/g;

#print "after change current line is \n\t", $temp,"\n";

push @subcktNew,$temp;

foreach my $ins (@ctrlVolt_Inst_Blk)

if($currentIns eq $ins) #means find the controlling device line

print "$currentIns is corlling;;;\n";

$temp=pop @subcktNew;

print "before change:\n$temp";

Page 212: Design and verification approaches for reliability and

199

$temp=~s/$Vout/$Vin/g; #replace the controlling voltage with

Vin

print "after change:\n$temp\n";

push @subcktNew,$temp;

#end if

#end foreach

# end if

# end for

my $temp1=pop @subcktNew;

push @subcktNew,"$Vx ($Vin 0) vsource dc=$Vx type=dc\n";

push @subcktNew,$temp1;

$subcktNew[0]=~s/$blkName/$newName/;#change the block master name

$subcktNew[-1]=~s/$blkName/$newName/;#change the block master name

print "modified subckt:\n@subcktNew\n";

$subckt_netlist$newName=\@subcktNew; # create a new block

#=================================================================

=========

print "\n**After first breakPoint, modified Netlist:(without deleting instances in other

SCC)**\n";

print @newInputScs;

#=====================

foreach(keys %subckt_netlist)

#print "$_\n@$subckt_netlist$_\n";

my @newLine=grep /$_/,@newInputScs;

push @newInputScs,@$subckt_netlist$_;

print "\n**After modify the breakPoint in block , modified Netlist:(without deleting instances

in other SCC)**\n";

print @newInputScs;

#=====================

print "\n**Trying to delete the instance not in current SCC**\n";

my @newInputScs2=@newInputScs;

for (my $index=0;$index<@newInputScs2;$index++)

my $currentLine= $newInputScs2[$index];

$_=$currentLine;

if(/^(\w+\d+)\s/)

Page 213: Design and verification approaches for reliability and

200

print $currentLine;

if(grep $_ eq $1 @instNotInSCC)

@newInputScs= grep $_ ne $currentLine @newInputScs;

my $nextLine=$newInputScs2[$index+1];

@newInputScs= grep $_ ne $nextLine @newInputScs;

print "\n**After first breakPoint, modified Netlist:(deleting instances in other SCC)**\n";

print @newInputScs;

##########################################################

###The following code is to deal with multiple breakPoints

##########################################################

#=================================================================

===============

#if we want to exclude the instances of other SCC use my @newInputScs1=@newInputScs;

(but it right now has problems for SCC that need input from other SCC)

#my @newInputScs1=@newInputScs;

my @newInputScs1=@newInputScs2;

#=================================================================

===============

if(keys %ctrlVolt_Inst>1)

print "\nThere are more than one break points: \n";

print keys %ctrlVolt_Inst,"\n";

my @otherPoints=grep (!/$ctrlVolt/,keys %ctrlVolt_Inst);

print @otherPoints,"\n";

#print $BPSindex;

foreach my $ctrlVolt (@otherPoints)

@newInputScs=@newInputScs1; #since each iteration we will add a new line the end

@newInputScs1=();

print "\n**For breakPoint: $ctrlVolt**\n";

$BPSindex=$BPSindex+1;

my $Vx="ITV2014vx".$BPSindex;#create a new DC voltage

my $Vin="ITV2014Vin".$BPSindex;#create a new net name as controlling voltage

my $Vout="ITV2014Vout".$BPSindex;

#==============================================

$breakpointReplacement$ctrlVolt=[$Vin, $Vout, $Vx];

#==============================================

for (my $index=0;$index<@newInputScs;$index++)

$_=$newInputScs[$index];

push @newInputScs1,$_;

Page 214: Design and verification approaches for reliability and

201

if(/^(\w+\d+)\s/)

my $currentIns=$1;

my $temp=pop @newInputScs1;

#print "current line is\n\t ",$temp, "\n";

my $Vout1=$Vout.' ';

$temp=~s/$ctrlVolt\s/$Vout1/g;

$Vout1=$Vout.')';

$temp=~s/$ctrlVolt\)/$Vout1/g;

#print "after change current line is \n\t", $temp,"\n";

push @newInputScs1,$temp;

foreach my $ins (@$ctrlVolt_Inst$ctrlVolt)

if($currentIns eq $ins) #means find the controlling device line

print "$currentIns is corlling;;;\n";

$temp=pop @newInputScs1;

print "before change:\n$temp";

$temp=~s/$Vout/$Vin/g; #replace the controlling voltage with Vin

print "after change:\n$temp\n";

push @newInputScs1,$temp;

#end if

#end foreach

# end if

# end for

push @newInputScs1,"$Vx ($Vin 0) vsource dc=$Vx type=dc\n";

# end foreach

#end if

print "\n**Final modified Netlist**\n";

print @newInputScs1;

open( MODIFYINPUT, ">./input1.scs") || die "Can't open myfile: $!";##'>' means write only,

it will clear and rewrite the file.

print MODIFYINPUT @newInputScs1;

close(MODIFYINPUT);

#=================================================================

=====

open( MODIFIEDITEM, ">./modifiedItems.txt") || die "Can't open myfile: $!";##'>' means

write only, it will clear and rewrite the file.

print MODIFIEDITEM "POWER_SUPPLY $numSupplyVol\n";

foreach (keys %SUPPLY)

print MODIFIEDITEM "$_ $SUPPLY$_\n";

my $numBreakpoint=keys %ctrlVolt_Inst;

Page 215: Design and verification approaches for reliability and

202

print MODIFIEDITEM "BREAK_POINTS $numBreakpoint\n";

foreach (keys %breakpointReplacement)

print MODIFIEDITEM "$_ @$breakpointReplacement$_

@$BPSPowerSuply$_\n";

close(MODIFIEDITEM);

#=================================================================

=====

3. findStrongConnComp.pl

#! /usr/bin/perl

#use FindBin;

#use lib "$FindBin::Bin/../Graph-0.96";

use strict;

use warnings;

use lib './ITV/breakLoop/Strong_conn_comp/Graph-0.96/lib';

use Graph::Directed;

my $g = Graph::Directed->new();

my $g1 = Graph::Directed->new();

my $g2 = Graph::Directed->new();

my $g3 = Graph::Directed->new();

my $g4 = Graph::Directed->new();

my $depenGraph = Graph::Directed->new();

open( MYFILE, "./dependencies.txt") || die "Can't open myfile: $!";

my @dependencies=<MYFILE>;

close(MYFILE);

#print @dependencies;

foreach (@dependencies)

my @temp=split(/\s/,$_);

$depenGraph->add_edges(@temp);

print "depenGraph is:\n $depenGraph\n";

open( MYFILE, "./negtiveLoops.txt") || die "Can't open myfile: $!";

my @negLoops=<MYFILE>;

@negLoops=split(/\s/,$negLoops[0]);

#print "Nodes in negative Loops: \n@negLoops\n";

close(MYFILE);

=pod

############################

####simplify the graph######

############################

Page 216: Design and verification approaches for reliability and

203

my @depenGraph_vertices=$depenGraph->vertices;

foreach (@depenGraph_vertices)

my $inDegree=$depenGraph->in_degree($_);

my $outDegree=$depenGraph->out_degree($_);

if($inDegree==0 or $outDegree==0)

print "$_ in_degree=$inDegree out_degree=$outDegree\n";

$depenGraph=$depenGraph->delete_vertex($_);

print "simplified depenGraph is:\n $depenGraph\n";

=cut

# Each pair is a pair of vertices qw|a b| indicating

# a directed edge from a to b

# graph: lineitem <-> invioce <-> claim <-> insurer

$g1->add_edges( qw| A B B C

C D D A|);

$g2->add_edges( qw| A B B C

C D D A

B E E F F G G H H I I F|);

$g3->add_edges( qw|A B B C

C D D A

B E E F

F G G H

H I I F

I E E C|);

$g4->add_edges( qw| v1 v5 v1 v3

v1 v2 v2 v4

v3 v2 v3 v5

v4 v3 v4 v6 v6 v5|);

$g=$depenGraph;

#$g=$g2;

my @strongConnComp=$g->strongly_connected_components;

print "\nThe graph is: $g\n";

print "\n**Strongly connected components list**\n";

print "Before simplify:\n";

foreach (my $k=0; $k< @strongConnComp; $k++)

Page 217: Design and verification approaches for reliability and

204

my $comp=$strongConnComp[$k];

print "Comp$k => @$comp\n";

#############################################################

####simplify the graph by deleting the one-element components

#############################################################

@strongConnComp=grep (@$_>1,@strongConnComp);

print "\nAfter simplify:\n";

foreach (my $k=0; $k< @strongConnComp; $k++)

my $comp=$strongConnComp[$k];

print "Comp$k => @$comp\n";

=pod

print "In_degree is: ";

print $g->in_degree('A'),"\n";

print "has_a_cycle is: ";

print $g->has_a_cycle,"\n";

print "find_a_cycle is: ";

print $g->find_a_cycle,"\n";

=cut

my @edges=$g->edges;

print "\n**Edges List***\n";

my $i=0;

foreach (@edges)

print "@$_\n";

my @vertices=$g->vertices;

my %breakPoint;

my $temp_g = Graph::Directed->new();

$temp_g->add_edges($g->edges);

my @ii=$temp_g->edges;

foreach (my $k=0; $k< @strongConnComp; $k++)

my $comp=$strongConnComp[$k];

########## obtain the subgraph for each strongcomponent##

my $temp_g = Graph::Directed->new();

print "\nFor Comp$k: @$comp\n";

foreach my $edge (@edges)

Page 218: Design and verification approaches for reliability and

205

if((grep($_ eq @$edge[0]) @$comp) and (grep($_ eq @$edge[1])

@$comp))

#print "@$edge\n";

$temp_g->add_edges(@$edge);

print "subgraph:$temp_g\n";

###############################################

#identify break point for each component

###############################################

my @vertices=$temp_g->vertices;

my $breakOnlyNegLoop;

$breakOnlyNegLoop=0;

if($breakOnlyNegLoop==1)

print "\n###Nodes before deleting the nodes of negative loop:\n @vertices\n";

print "Nodes in negative Loops: \n@negLoops\n";

###### The following part is trying to get rid of the negative loop nodes

###### it enable us to break only positive loops

##*****************************************************

my %negLoops;

map($negLoops$_=1,@negLoops); # create %negLoops with elements from

@negLoops

my @verticesDiff=grep(!defined($negLoops$_),@vertices); # returns those elements of

@vertices that don't

# have a hash element in %negLoops therefore they

# do not exist in @negLoops.

print " \n###Remaining nodes after deleting the nodes of negative loop:\n @verticesDiff\n";

@vertices=@verticesDiff;

##*******************************************************

my @currentBreakingPoint;

if(@vertices>0)

########## Try to find one arc as breaking point##

print "Try to find one arc as breaking point...\n";

foreach (@vertices)

my $c=$temp_g->copy_graph;

#print " Before deleting, the copy graph is $c\n";

$c=$c->delete_vertex($_);

Page 219: Design and verification approaches for reliability and

206

# print " After deleting $_, the copy graph is $c\n";

if(/^path/)

elsif (!$c->has_a_cycle)

push @currentBreakingPoint, $_;

last;

#foreach

############ Try to find two arcs as breaking points##

if(@currentBreakingPoint>0)

print"Get a break point: @currentBreakingPoint\n";

else

print "Try to find two arcs as breaking points...\n";

foreach (my $i=0; $i < @vertices; $i++)

foreach (my $j=$i+1; $j < @vertices; $j++)

my $c=$temp_g->copy_graph;

# print " Before deleting, the copy graph is $c\n";

$c=$c->delete_vertices($vertices[$i],$vertices[$j]);

# print " After deleting $vertices[$i] and $vertices[$j], the copy graph is $c\n";

if($vertices[$i]=~/^path/ or $vertices[$j]=~/^path/)

elsif ($c->is_acyclic)

push @currentBreakingPoint, $vertices[$i];

push @currentBreakingPoint, $vertices[$j];

last;

#foreach

if (@currentBreakingPoint>0)##after finding two breaking point, stop the foreach

print"Get two break point: @currentBreakingPoint\n";

last;

#foreach

# if

if(@currentBreakingPoint==0)print " **warnning** breaking points is larger than 2

for this components!\n";

else$breakPoint$k=\@currentBreakingPoint;

#if

Page 220: Design and verification approaches for reliability and

207

print "\n**BreakPoints List**\n";

foreach (keys %breakPoint)

print "For Comp$_:@$strongConnComp[$_]\n @$breakPoint$_ \n";

4. findPath.pl

#! /usr/bin/perl

use constant LAST => -1;

use constant PATH => 0;

use constant SEEN => 1;

use strict;

use warnings;

sub find_paths

my ($beg, $end, $graph) = @_;# $graph is the ref of %graph

my @solution;

my @work;

for (@$graph->$beg) # $graph->$beg is the ref of key "$beg"

# push @solution, [$beg, $end] if $_ eq $end;

if ($_ eq $end)

push @solution, [$beg, $end];

next;

push @work, [[$beg, $_], $beg => undef, $_ => undef];

#the hash with undef is to check whether the node hasbeen visited

while (@work)

my $item = pop @work;

my ($path, $seen) = @$item[PATH, SEEN];

for my $node (@$graph->$path->[LAST])

next if exists $seen->$node;

my @new_path = (@$path, $node);

if ($node eq $end)

push @solution, \@new_path;

next;

my %new_seen = (%$seen, $node => undef);

push @work, [\@new_path, \%new_seen];

return \@solution;

Page 221: Design and verification approaches for reliability and

208

1;

5. flattenNetlist.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './ITV/breakLoop/Strong_conn_comp/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

my $start_time=time();

my $start_time2=localtime();

print "start at:$start_time2\n";

####open the net_from_cadence that generated from Cadence.

open( MYFILE, "./myFile_hier") || die "Can't open myfile: $!";

my @netlist=<MYFILE>;

print @netlist;

close(MYFILE);

=pod

my @temp=@netlist_from_cadence;

while(@temp)

my $item=pop @temp;

print "$item";

=cut

my %subckt_termi;

my %subckt_netlist;

my @subNetlist;

my $subckt_name;

my $flag=0;

my @topLevel;

for (my $i=0; $i<@netlist;$i++)

#print "$netlist[$i]";

my $currentLine=$netlist[$i];

chop $currentLine;

$_=$netlist[$i];

if(/^subckt\s(.*)\s\(\"(.*)\"\)/)

Page 222: Design and verification approaches for reliability and

209

#print "!!!$_";

#print "$1\t$2\n";

$subckt_termi$1=[split(/\" \"/,$2)];

#print "$1 => @$subckt_termi$1 \n\n";

$subckt_name=$1;

@subNetlist=();

$flag=1;

elsif($flag)

push @subNetlist, $_;

if(/^ends\ssubckt/)

pop @subNetlist;

$subckt_netlist$subckt_name=[@subNetlist];

$flag=0;

if(!/^ends\ssubckt/ and $flag==0)

push @topLevel,$currentLine;

print "\n**Top level**\n";

for (my $i=0; $i<@topLevel;$i++)

print "$topLevel[$i]\n";

print "\n**subckt netlist**\n";

foreach (keys %subckt_termi)

print "$_ (@$subckt_termi$_)\n";

print "@$subckt_netlist$_\n";

#############################################

# flatten a Block

#############################################

sub printBlock

my ($blockName,$master,$term,$termConn)=@_;

Page 223: Design and verification approaches for reliability and

210

print "===$blockName \. $master \. (@$term) => @$termConn===\n";

my %term;

my %termConn;

map($term$_=1,@$term);

for (my $i=0; $i<@$term;$i++)

$termConn@$term[$i]=@$termConn[$i];

# print "@$subckt_netlist$master\n";

my %netlist_hash;

my %instance_prop;

my $instance_name;

my @newNets;

my @flatNetlist;

my $currentMaster;

foreach $_ (@$subckt_netlist$master) ##foreach line in the master

my $currentLine=$_;

chop $currentLine;

if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)\s/)

$netlist_hash$1=[split(/\" \"/,$2)]; # get all the nets in this instance

# print "$1 => @$netlist_hash$1 $3\n";

$instance_name=$blockName.'.'.$1;

$instance_prop$1=$3;

$currentMaster=$3;

@newNets=();

for (my $j=0; $j<@$netlist_hash$1;$j++) ##foreach net in this instance

my $oriNetInSubckt=@$netlist_hash$1[$j];

#print "$oriNetInSubckt\t$term$oriNetInSubckt\n\n!!";

#print keys %term,"!!\n";

if(exists $term$oriNetInSubckt)

#print "$oriNetInSubckt is a pin, should connect to upper level node:

$termConn$oriNetInSubckt\n";

push @newNets,$termConn$oriNetInSubckt;

@$netlist_hash$1[$j]=$termConn$oriNetInSubckt;

##end if

else

push @newNets,$blockName.'.'.$oriNetInSubckt;

Page 224: Design and verification approaches for reliability and

211

@$netlist_hash$1[$j]=$blockName.'.'.$oriNetInSubckt;

##end foreach

#print "!!!!!!!$instance_name=>@newNets\n";

my $temp=join("\" \"", @newNets);

$currentLine=$instance_name." (\"".$temp."\") ".$instance_prop$1;

push @flatNetlist,$currentLine;

if(exists $subckt_netlist $currentMaster)

#print "\nget it!!! $currentMaster\n";

pop @flatNetlist;

my $preLevelNetlist;

$preLevelNetlist=printBlock($instance_name,$3,$subckt_termi$3,$netlist_hash$

1);

push @flatNetlist, @$preLevelNetlist;

##end if

##end if

elsif(!exists $subckt_netlist $currentMaster)

push @flatNetlist,$currentLine;

##end foreach

for (my $i=0; $i<@flatNetlist;$i++)

print"$flatNetlist[$i]\n";

return \@flatNetlist;

my @term=("VSS", "A", "B") ;

my @termConn=("gnd!", "A", "B");

#printBlock("I0","Block",\@term,\@termConn);

print "\n**fatten netlist**\n";

open( FLATNETLIST, ">./flattenNetlist.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

my @topLevelFlatten=@topLevel;

for (my $i=0; $i<@topLevel;$i++)

$_=$topLevel[$i];

#print "!!!!!!!$_\n\n";

#if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)\s/)

Page 225: Design and verification approaches for reliability and

212

if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)/)

my $master=$3;

#print "master: $master\n";

if(exists $subckt_netlist$master)

my $blockName=$1;

my $termConn=[split(/\" \"/,$2)];

my $nextLine=$topLevel[$i+1];

$nextLine=~s/\(\"//g;

$nextLine=~s/\"\)//g;

my $term=[split(/\" \"/,$nextLine)];

for (my $i=0; $i<@$term;$i++) # this is to make sure each element in

@$term) will not have space

@$term[$i]=~s/\s+//g;

print "===$blockName \. $master \. (@$term) => @$termConn===\n";

my $newBlock=printBlock($blockName,$master,$term,$termConn);

@topLevelFlatten = grep $_ and ($_ ne $topLevel[$i]) and ($_ ne $topLevel[$i+1])

@topLevelFlatten;

push @topLevelFlatten,@$newBlock;

elseprint "$topLevel[$i]\n";

elseprint "$topLevel[$i]\n";

print "\n**fatten netlist**\n";

for (my $i=0; $i<@topLevelFlatten;$i++)

print "$topLevelFlatten[$i]\n";

print FLATNETLIST "$topLevelFlatten[$i]\n";

close(FLATNETLIST);

6. identifySCC.il

;;;load("./ITV/identifySCC.il")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;identify the SCC list for current;;;;;;;;;;

;;;;;schematic and try display the loops for each SCC ;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Page 226: Design and verification approaches for reliability and

213

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;read data from a file and store them into a table

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CV=geGetEditCellView()

tableName = sprintf( nil "%s %s %s"

CV~>libName CV~>cellName CV~>viewName )

loopTable=makeTable(tableName nil)

loopTableNameList=nil

pathTable=makeTable(tableName nil)

let( (inport nextLine loopList loopName pathName)

inport=infile("./loopList.txt")

when( inport

while(gets(nextLine inport)

println(nextLine)

loopList=parseString(nextLine)

if( rexMatchp("loop" car(loopList)) then

loopName=car(loopList)

loopTable[loopName]=append(loopTable[loopName] cdr(loopList))

loopTableNameList=append1(loopTableNameList loopName)

else rexMatchp("path" car(loopList))

pathName=car(loopList)

pathTable[pathName]=append(pathTable[pathName] cdr(loopList))

);if

);while

close(inport)

);when

);let

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;procedure for highlight loops;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;select nets

procedure( selectNet(NetId)

let((NetFigs fig)

NetFigs=NetId~>figs

foreach( fig NetFigs

geSelectFig(fig)

);foreach

);let

);procedure

;;select instance

procedure( selectInst(instId)

Page 227: Design and verification approaches for reliability and

214

geSelectFig(instId)

);procedure

;;highlight Nets

;lpp=list("y0" "drawing")

procedure(highLightNet(hlSetId netId)

let((fig)

;hlSetId=geCreateHilightSet(CV lppNet)

hlSetId->enable = nil

foreach(fig netId~>figs geAddHilightFig(hlSetId fig))

hlSetId->enable = t

);let

);proc

;;highlight Instance

procedure(highLightInst(hlSetId instId)

;hlSetId=geCreateHilightSet(CV lppInst)

hlSetId->enable = nil

geAddHilightFig(hlSetId instId)

hlSetId->enable = t

);proc

;;select path

procedure(selectPath(path)

let((NetId InstId item hierachi_item)

MyVdd=loopListForm->Vdd->value

MyVss=loopListForm->Vss->value

Temp1=parseString(MyVdd " ")

Temp2=parseString(MyVss " ")

PowerNet=append(Temp1 Temp2)

foreach(item path

if(!member(item PowerNet) then

hierachi_item=parseString(item ".")

item=car(hierachi_item)

NetId=dbFindNetByName(CV item);gets DataID for Net as to get the and select figs

attached.

InstId=dbFindAnyInstByName(CV item);gets DataID for Inst as to get the and select figs

attached.

if( NetId then selectNet(NetId)

else selectInst(InstId)

);if

);if

);foreach

);let

Page 228: Design and verification approaches for reliability and

215

);procedure

;find the transistor that cause net-to-path dependencies and select

procedure(findTransCauseDepen(netName pathName flash)

let((itemId itemTermNet hlSetId)

;println("Now find depen")

;printf("begin net is %s and target path is %s\n" netName pathName)

foreach(pathItem pathTable[pathName]

itemId=dbFindAnyInstByName(CV pathItem)

if( itemId then;;or if(pathItem~>objType=="inst"

;printf("the for Terminal of instance %s is connected to:" itemId~>name)

;println(itemId~>instTerms~>net~>name)

foreach(itemTermNet itemId~>instTerms~>net~>name

if(itemTermNet==netName then

;println(itemId~>name)

;println(itemTermNet)

;printf("dependency from %s to %s of %s is highlighted!\n" netName

itemId~>name pathName)

lppInst=list("y2" "drawing")

;;;flash

; hlSetIdFlash=geCreateHilightSet(CV lppInst)

; highLightNet(hlSetIdFlash NetId)

; hiUpdate()

; hiSleep(1)

; geDeleteHilightSet(hlSetIdFlash)

; hiUpdate()

; hiSleep(1)

hlSetId=geCreateHilightSet(CV lppInst)

highLightInst(hlSetId itemId)

hiUpdate()

;;flash

if(flash=="YES" then

selectInst(itemId)

hiUpdate()

hiSleep(1)

geDeselectFig(itemId)

hiUpdate()

hiSleep(1)

);if

selectInst(itemId)

);if

);foreach

);if

);foreach

Page 229: Design and verification approaches for reliability and

216

);let

);proc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;highlight components( in sequence and flash);;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

procedure(highLightLoopInSequence(loopName lpp flash)

let((lastItem Term NetId InstId parseTerm Temp hlSetId)

geDeselectAllFig(CV)

geDeleteAllHilightSet(CV)

lastItem=car(last(loopTable[loopName]))

lastItem1=nil;;;mainly to deal with some net name formed from combining the gate

resistors

foreach(Term cdr(loopTable[loopName])

;println(Term)

if( rexMatchp("path" Term) then

findTransCauseDepen(lastItem Term flash)

if(lastItem1 then

findTransCauseDepen(lastItem1 Term flash)

);if

else

Temp=parseString(Term "_")

;println(Temp)

foreach(parseTerm Temp

NetId=dbFindNetByName(CV parseTerm );gets DataID for Net as to get and select

the figs attached

InstId=dbFindAnyInstByName(CV parseTerm );gets DataID for Instance as to get

and select the figs attached

hlSetIdFlash=geCreateHilightSet(CV lpp)

hlSetId=geCreateHilightSet(CV lpp)

if(NetId then

;println(NetId~>name)

;;;flash

if(flash=="YES" then

highLightNet(hlSetIdFlash NetId)

hiUpdate()

hiSleep(1)

geDeleteHilightSet(hlSetIdFlash)

hiUpdate()

hiSleep(1)

);if

highLightNet(hlSetId NetId)

hiUpdate()

else

Page 230: Design and verification approaches for reliability and

217

;println(InstId~>name)

;;;flash

if(flash=="YES" then

highLightInst(hlSetIdFlash InstId)

hiUpdate()

hiSleep(1)

geDeleteHilightSet(hlSetIdFlash)

hiUpdate()

hiSleep(1)

);if

highLightInst(hlSetId InstId)

hiUpdate()

);if

);foreach

lastItem=car(Temp);; the first and the last net parsed from the combined name may

both possibly be the controlling voltage

lastItem1=car(last(cdr(Temp)))

);if

);foreach

);let

);procedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;show the path table;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

println(";;;path list;;;;")

foreach(pathName pathTable

println(

list(pathName pathTable[pathName])

);println

;selectPath(pathTable[pathName])

);foreach

;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;show the loop table;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;

println(";;;loop list;;;;")

foreach(loopName loopTable

println(

list(loopName loopTable[loopName])

);println

);foreach

Page 231: Design and verification approaches for reliability and

218

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;show the interface of loop highlighting;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

procedure( TrShowListBox( aList )

hiShowListBox(

?name gensym( 'TrExampleListBox )

?choices aList

?callback 'TrExampleListBoxCB

?title "Loop List"

?multipleSelect t

?applyButton t

)

) ; procedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;differentiate negative and positive loops ;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

positiveLoop=nil

negativeLoop=nil

loopListName=nil

let((loopSign posLoopNum negLoopNum combName loopTable_temp combName1)

posLoopNum=0

negLoopNum=0

loopTable_temp=loopTable

loopTable=makeTable(tableName nil);;since I want to change the table keyword so I store

the original table in a temperary and create a new table

foreach(loopName loopTableNameList

;foreach(loopName loopTable_temp

loopSign=car(loopTable_temp[loopName])

if(loopSign=="positive" then

posLoopNum=posLoopNum+1

combName=strcat("Positive loop" pcExprToString(posLoopNum))

;combName=strcat("Positive" loopName)

loopTable[combName]=loopTable_temp[loopName]

positiveLoop=append1(positiveLoop combName)

;print("new table Item:")

println(combName)

println(loopTable_temp[loopName])

else

negLoopNum=negLoopNum+1

combName=strcat("Negative loop" pcExprToString(negLoopNum))

;combName=strcat("Negative" loopName)

loopTable[combName]=loopTable_temp[loopName]

negativeLoop=append1(negativeLoop combName)

;print("new table Item:")

Page 232: Design and verification approaches for reliability and

219

println(combName)

println(loopTable_temp[loopName])

);if

);foreach

);let

println(positiveLoop)

println(negativeLoop)

loopListName=append(positiveLoop negativeLoop)

;=================================================================

;=================================================================

;=================================================================

;=================================================================

;=================================================================

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;procedure for auto-searching the break-points;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

strongCompnents_list=nil

procedure(autoIdentifySCC()

breakPointsTable=makeTable("breakPointsTable" nil);

breakOnlyPFLTable=makeTable("breakOnlyPFLTable" nil);

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;get the SCC table;;;;;

SCCTable=makeTable(tableName nil)

let( (inport nextLine SCCList SCCName)

inport=infile("SCCList.txt")

when( inport

while(gets(nextLine inport)

SCCList=parseString(nextLine)

if( rexMatchp("SCC" car(SCCList)) then

SCCName=car(SCCList)

SCCTable[SCCName]=append(SCCTable[SCCName] cdr(SCCList))

);if

);while

close(inport)

);when

);let

Page 233: Design and verification approaches for reliability and

220

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;show the SCC table;;;;;

printf("\n**SCC List**\n")

foreach(SCCName SCCTable

println(

list(SCCName SCCTable[SCCName])

);println

;selectSCC(SCCTable[SCCName])

);foreach

printf("\n**get the instance of each SCC**\n")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;get the instance of each SCC;;;;;

let((myPort SCCName SCCitem pathItem)

myPort = outfile("./SCCInst.txt")

foreach(SCCName SCCTable ;;foreach1

fprintf(myPort "%s" SCCName)

foreach(SCCitem SCCTable[SCCName] ;;foreach2

if(rexMatchp("path" SCCitem) then ;;if1

;println(list(SCCitem pathTable[SCCitem]))

foreach(pathItem pathTable[SCCitem] ;;foreach3

if(dbFindAnyInstByName(CV pathItem) then ;;if2

fprintf(myPort " %s" pathItem)

);;if2

);foreach3

);;;if1

);foreach2

fprintf(myPort "\n")

);foreach1

close(myPort)

);let

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;get the loopInSCC table;;;;;

loopInSCC=makeTable(tableName nil)

let( (inport nextLine SCCList SCCName posLoopNum negLoopNum)

inport=infile("loopOfSCC.txt")

when( inport

posLoopNum=0

negLoopNum=0

while(gets(nextLine inport)

SCCList=parseString(nextLine)

Page 234: Design and verification approaches for reliability and

221

;;fowwing code create a table to change the loop name correspond to that in

the createNetlist.il

;;and keep the infor of the SCC it belongs to

if(rexMatchp("positive" car(SCCList)) then

posLoopNum=posLoopNum+1

combName=strcat("Positive loop" pcExprToString(posLoopNum))

loopInSCC[combName]=cadr(SCCList)

else

negLoopNum=negLoopNum+1

combName=strcat("Negative loop" pcExprToString(negLoopNum))

loopInSCC[combName]=cadr(SCCList)

);if

);while

close(inport)

);when

);let

printf("\n**loopInSCC List**\n")

SCC_loop=makeTable(tableName nil)

foreach(SCCName loopInSCC

println(

list(SCCName loopInSCC[SCCName])

);println

SCC_loop[loopInSCC[SCCName]]=append1(SCC_loop[loopInSCC[SCCName]]

SCCName)

);foreach

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;show the loopOfSCC table;;;;;

printf("\n**SCC_loop**\n")

foreach(SCCName SCC_loop

println(

list(SCCName SCC_loop[SCCName])

);println

SCC_loop[SCCName]=sort(SCC_loop[SCCName] 'alphalessp)

println(

list(SCCName SCC_loop[SCCName])

);println

);foreach

printf("\n**Get the breakpoints table**\n")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;get the breakpoints table;;;;;

Page 235: Design and verification approaches for reliability and

222

FILEDATA = infile("BreakPoints.txt")

while(gets(str, FILEDATA)

str=substring(str 1 strlen(str)-1)

LocLine= parseString(str ";")

printf("Now we have %L\n" LocLine)

strongCompnents_list=append1(strongCompnents_list car(LocLine))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;put the break-points into table

foreach(item cdr(LocLine)

last_Char=substring(item strlen(item) strlen(item))

first_Char=substring(item 1 1)

while(last_Char==" "

item=substring(item 1 strlen(item)-1)

last_Char=substring(item strlen(item) strlen(item))

);while

while(first_Char==" "

item=substring(item 2 strlen(item))

first_Char=substring(item 1 1)

);while

;;;;;;;Break-points for only PFLs

if(last_Char=="." then

printf("Got a break-point for breaking only PFL: %s\n" item)

item=substring(item 1 strlen(item)-1)

breakOnlyPFLTable[car(LocLine)]=append1(breakOnlyPFLTable[car(LocLine)],item)

;;;;;;;Break-points for both N/PFLs

else

breakPointsTable[car(LocLine)]=append1(breakPointsTable[car(LocLine)],item)

);if..else..

)

;breakPointsTable[nth(0 LocLine)]=nth(1 LocLine)

);while finish reading data

close(FILEDATA)

printf("\n**BreakOnlyPFLTable List**\n")

foreach( temp breakOnlyPFLTable

printf(" %s %L \n" temp breakOnlyPFLTable[temp])

)

printf("\n**BreakPointsTable List**\n")

foreach( temp breakPointsTable

printf(" %s %L \n" temp breakPointsTable[temp])

);foreach

Page 236: Design and verification approaches for reliability and

223

); procedure autoIdentifySCC()

autoIdentifySCC()

;;procedure for selecting SCC

procedure(selectSCC(SCC)

geDeselectAll() ;;deselect previous SCC

geDeselectAllFig(CV)

geDeleteAllHilightSet(CV)

let((item)

foreach(item SCC

println(item)

if( rexMatchp("path" item) then

selectPath(pathTable[item])

);if

);foreach

);let

);procedure

;selectSCC(SCCTable["SCC0"])

loopListForm->strongCompList->choices=strongCompnents_list

7. identifyBPS.il

;;;load("./ITV/identifyBPS.il")

procedure(selectBreakPoint()

let((CV selWire lpp hlSetId)

;;;if the user does not select a node show a warinng dialog

selWire=geGetSelSet()

if(selWire==nil then

hiHighlightField( hiGetCurrentForm() 'BreakPoint 'error )

selectNetWarning()

;hiRaiseWindow(hiGetCurrentWindow())

else

;;;;highlight the selected net

CV=geGetEditCellView()

lpp=list("y0" "drawing")

hlSetId=geCreateHilightSet(CV lpp)

highLightNet(hlSetId car(selWire~>net))

;;;gemerate amd alter the netlist

hiHighlightField( hiGetCurrentForm() 'BreakPoint 'background )

Page 237: Design and verification approaches for reliability and

224

hiGetCurrentForm()->BreakPoint->value=car(selWire~>net~>name)

;geDeselectAllFig(geGetEditCellView())

;load("./ITV/autoModifyNetlist/autoGenerateNetlist.il")

);if

);let

);procedure

breakPointsTable=makeTable("breakPointsTable" nil);

breakOnlyPFLTable=makeTable("breakOnlyPFLTable" nil);

FILEDATA = infile("BreakPoints.txt")

while(gets(str, FILEDATA)

str=substring(str 1 strlen(str)-1)

LocLine= parseString(str ";")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;put the break-points into table

foreach(item cdr(LocLine)

last_Char=substring(item strlen(item) strlen(item))

first_Char=substring(item 1 1)

while(last_Char==" "

item=substring(item 1 strlen(item)-1)

last_Char=substring(item strlen(item) strlen(item))

);while

while(first_Char==" "

item=substring(item 2 strlen(item))

first_Char=substring(item 1 1)

);while

;;;;;;;Break-points for only PFLs

if(last_Char=="." then

printf("Got a break-point for breaking only PFL: %s\n" item)

item=substring(item 1 strlen(item)-1)

breakOnlyPFLTable[car(LocLine)]=append1(breakOnlyPFLTable[car(LocLine)],item)

;;;;;;;Break-points for both N/PFLs

else

breakPointsTable[car(LocLine)]=append1(breakPointsTable[car(LocLine)],item)

);if..else..

)

;breakPointsTable[nth(0 LocLine)]=nth(1 LocLine)

);while finish reading data

close(FILEDATA)

printf("\n**BreakOnlyPFLTable List**\n")

Page 238: Design and verification approaches for reliability and

225

foreach( temp breakOnlyPFLTable

printf(" %s %L \n" temp breakOnlyPFLTable[temp])

)

printf("\n**BreakPointsTable List**\n")

foreach( temp breakPointsTable

printf(" %s %L \n" temp breakPointsTable[temp])

);foreach

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;procedure for auto-displaying the break-points;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Breakpoints_list_copy=nil

BreakPFLpoints_list_copy=nil

procedure(autoDispBreakPoint()

println("for test")

println(loopListForm~>strongCompList~>value)

if(loopListForm~>strongCompList~>value==" " then

hiDisplayAppDBox(

?name gensym( 'trExampleDialogBox )

?dboxBanner "Warning"

?dboxText "Please Select a SCC!"

?dialogType hicWarningDialog

?dialogStyle 'modal

?location list(600 300)

);hiDisplayAppDBox

else

println("for test1")

println(loopListForm~>BreakOnlyPFLButton~>value)

;;;;;;;;;;;;display breaking-points for only PFLs;;;;

if(loopListForm~>BreakOnlyPFLButton~>value=="YES" then

println("for test2")

println(loopListForm~>strongCompList~>value)

println(breakOnlyPFLTable[loopListForm~>strongCompList~>value])

println("for test2")

if(breakOnlyPFLTable[loopListForm~>strongCompList~>value] then

if(BreakPFLpoints_list_copy==nil then

BreakPFLpoints_list_copy=breakOnlyPFLTable[loopListForm~>strongCompList~>value])

hiGetCurrentForm()->BreakPoint->value =strcat(""

car(BreakPFLpoints_list_copy) "")

BreakPFLpoints_list_copy=cdr(BreakPFLpoints_list_copy)

else

Page 239: Design and verification approaches for reliability and

226

hiGetCurrentForm()->BreakPoint->value =""

hiDisplayAppDBox(

?name gensym( 'trExampleDialogBox )

?dboxBanner "Warning"

?dboxText "Can't Break only PFLs!!"

?dialogType hicWarningDialog

?dialogStyle 'modal

?location list(600 300)

);hiDisplayAppDBox

);if

;;;;;;;;;;;;display breaking-points for both N/PFLs;;;;

else

if(breakPointsTable[loopListForm~>strongCompList~>value] then

if(Breakpoints_list_copy==nil then

Breakpoints_list_copy=breakPointsTable[loopListForm~>strongCompList~>value])

hiGetCurrentForm()->BreakPoint->value =strcat(""

car(Breakpoints_list_copy) "")

Breakpoints_list_copy=cdr(Breakpoints_list_copy)

else

hiGetCurrentForm()->BreakPoint->value =""

hiDisplayAppDBox(

?name gensym( 'trExampleDialogBox )

?dboxBanner "Warning"

?dboxText "No BPS for both N/PFLs!!"

?dialogType hicWarningDialog

?dialogStyle 'modal

?location list(600 300)

);hiDisplayAppDBox

);if

);if

);if

); procedure

procedure(breakLoop()

;;;if the user does not select a node show a warinng dialog

println("the breakpoint is...")

println(hiGetCurrentForm()->BreakPoint->value)

if(hiGetCurrentForm()->BreakPoint->value=="" then

hiHighlightField( hiGetCurrentForm() 'BreakPoint 'error )

selectNetWarning()

else if(hiGetCurrentForm()->BreakPoint->value=="|BPS|>2" then

hiHighlightField( hiGetCurrentForm() 'BreakPoint 'error )

BPSGreaterThanTwoWarning()

else

Page 240: Design and verification approaches for reliability and

227

hiHighlightField( hiGetCurrentForm() 'BreakPoint 'background)

load("./ITV/breakLoop/autoModifyNetlist/autoGenerateNetlist.il")

);else if

);if

);procedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;To check whether the vdd/vss fields

;have been specified with a selected net

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

procedure( checkBreakingPoint( myForm )

println(myForm->BreakPoint->value)

if(myForm->BreakPoint->value =="" then

println("You have to specify BreakPoint")

nil

else

println("You have specified BreakPoint")

t

) ;if

) ; procedure

procedure(formCheck(myForm)

println("now it is checking...")

println(checkBreakingPoint( myForm ))

if( checkBreakingPoint( myForm ) then

hiSetCallbackStatus( myForm t); the form will disappear after you set this status

hiHighlightField( myForm 'BreakPoint 'highlight )

else

hiHighlightField( myForm 'BreakPoint 'highlight )

hiSetCallbackStatus( myForm nil ); the form won't disappear after you set this status

) ; if

);procedure

8. searchBreakPoints.pl

#! /usr/bin/perl

#use FindBin;

#use lib "$FindBin::Bin/../Graph-0.96";

use strict;

use warnings;

use lib './ITV/breakLoop/Strong_conn_comp/Graph-0.96/lib';

use Graph::Directed;

use lib './ITV/breakLoop/Strong_conn_comp/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

my $input1=$ARGV[0];

Page 241: Design and verification approaches for reliability and

228

my $input2=$ARGV[1];

if ($input1 eq "")

print "\n* usage:*\n";

print "-d choose if you like to show the debug output 1(YES) or 0(NO)\n";

print "Example: Perl ./searchBreakPoints.pl -d 1\n\n";

exit(1);

my $debugFlag=0; #determine wether to print out information

if( ($input1=~/-d$/)&& ($input2=~/0$/ or $input2=~/1$/ ))

$debugFlag=$input2; #determine wether to print out information

else

print "error parameter!\n";

exit(0);

my $g = Graph::Directed->new();

my $g1 = Graph::Directed->new();

my $g2 = Graph::Directed->new();

my $g3 = Graph::Directed->new();

my $g4 = Graph::Directed->new();

my $depenGraph = Graph::Directed->new();

open( MYFILE, "./dependencies.txt") || die "Can't open myfile: $!";

my @dependencies=<MYFILE>;

close(MYFILE);

#print @dependencies;

foreach (@dependencies)

my @temp=split(/\s/,$_);

$depenGraph->add_edges(@temp);

if($debugFlag==1)

print "depenGraph is:\n $depenGraph\n";

open( MYFILE, "./negtiveLoops.txt") || die "Can't open myfile: $!";

my @negLoops=<MYFILE>;

@negLoops=split(/\s/,$negLoops[0]);

#print "Nodes in negative Loops: \n@negLoops\n";

close(MYFILE);

Page 242: Design and verification approaches for reliability and

229

#============================================

if($debugFlag==1)

print "\n**use to remove BreakPoints that are not gate**\n";

open( CTRLINST, "./controlInstList.txt") || die "Can't open myfile: $!";

my @ctrlInstForAllNets=<CTRLINST>;

close(CTRLINST);

my @potentialBreakpoints;

my %potentialBreakpoints;

foreach $_ (@ctrlInstForAllNets)

my @temp=split(/\s+/,$_);

push @potentialBreakpoints,$temp[0];

$potentialBreakpoints$temp[0]=1;

if($debugFlag==1)

print "!!!!!!!!!!!!All possible breakpoint: @potentialBreakpoints\n";

#============================================

=pod

############################

####simplify the graph######

############################

my @depenGraph_vertices=$depenGraph->vertices;

foreach (@depenGraph_vertices)

my $inDegree=$depenGraph->in_degree($_);

my $outDegree=$depenGraph->out_degree($_);

if($inDegree==0 or $outDegree==0)

print "$_ in_degree=$inDegree out_degree=$outDegree\n";

$depenGraph=$depenGraph->delete_vertex($_);

print "simplified depenGraph is:\n $depenGraph\n";

=cut

# Each pair is a pair of vertices qw|a b| indicating

# a directed edge from a to b

# graph: lineitem <-> invioce <-> claim <-> insurer

Page 243: Design and verification approaches for reliability and

230

$g1->add_edges( qw| A B B C

C D D A|);

$g2->add_edges( qw| A B B C

C D D A

B E E F F G G H H I I F|);

$g3->add_edges( qw|A B B C

C D D A

B E E F

F G G H

H I I F

I E E C|);

$g4->add_edges( qw| v1 v5 v1 v3

v1 v2 v2 v4

v3 v2 v3 v5

v4 v3 v4 v6 v6 v5|);

$g=$depenGraph;

#$g=$g3;

my @strongConnComp=$g->strongly_connected_components;

if($debugFlag==1)

print "\nThe graph is: $g\n";

print "\n**Strongly connected components list**\n";

print "Before simplify:\n";

foreach (my $k=0; $k< @strongConnComp; $k++)

my $comp=$strongConnComp[$k];

print "Comp$k => @$comp\n";

#if($debugFlag==1)

#############################################################

####simplify the graph by deleting the one-element components

#############################################################

@strongConnComp=grep (@$_>1,@strongConnComp);

if($debugFlag==1)

print "\nAfter simplify:\n";

foreach (my $k=0; $k< @strongConnComp; $k++)

my $comp=$strongConnComp[$k];

print "Comp$k => @$comp\n";

Page 244: Design and verification approaches for reliability and

231

#if($debugFlag==1)

=pod

print "In_degree is: ";

print $g->in_degree('A'),"\n";

print "has_a_cycle is: ";

print $g->has_a_cycle,"\n";

print "find_a_cycle is: ";

print $g->find_a_cycle,"\n";

=cut

my @edges=$g->edges;

my $i=0;

if($debugFlag==1)

print "\n**Edges List***\n";

foreach (@edges)

print "@$_\n";

#if($debugFlag==1)

my @vertices=$g->vertices;

my %breakPoint;

my $temp_g = Graph::Directed->new();

$temp_g->add_edges($g->edges);

my @ii=$temp_g->edges;

=pod

foreach (my $k=0; $k< @strongConnComp; $k++)

my $comp=$strongConnComp[$k];

########## obtain the subgraph for each strongcomponent##

my $temp_g = Graph::Directed->new();

print "\nFor Comp$k: @$comp\n";

foreach my $edge (@edges)

if((grep($_ eq @$edge[0]) @$comp) and (grep($_ eq @$edge[1])

@$comp))

#print "@$edge\n";

$temp_g->add_edges(@$edge);

print "subgraph:$temp_g\n";

###############################################

#identify break point for each component

###############################################

Page 245: Design and verification approaches for reliability and

232

my @vertices=$temp_g->vertices;

my $breakOnlyNegLoop;

$breakOnlyNegLoop=0;

if($breakOnlyNegLoop==1)

print "\n###Nodes before deleting the nodes of negative loop:\n @vertices\n";

print "Nodes in negative Loops: \n@negLoops\n";

###### The following part is trying to get rid of the negative loop nodes

###### it enable us to break only positive loops

##*****************************************************

my %negLoops;

map($negLoops$_=1,@negLoops); # create %negLoops with elements from

@negLoops

my @verticesDiff=grep(!defined($negLoops$_),@vertices); # returns those elements of

@vertices that don't

# have a hash element in %negLoops therefore they

# do not exist in @negLoops.

print " \n###Remaining nodes after deleting the nodes of negative loop:\n @verticesDiff\n";

#@vertices=@verticesDiff;

##*******************************************************

my @currentBreakingPoint;

if(@vertices>0)

########## Try to find one arc as breaking point##

print "Try to find one arc as breaking point...\n";

foreach (@vertices)

my $c=$temp_g->copy_graph;

#print " Before deleting, the copy graph is $c\n";

$c=$c->delete_vertex($_);

# print " After deleting $_, the copy graph is $c\n";

if(/^path/)

elsif (!$c->has_a_cycle)

push @currentBreakingPoint,$_;

push @currentBreakingPoint,';';

#last;

#foreach

Page 246: Design and verification approaches for reliability and

233

############ Try to find two arcs as breaking points##

if(@currentBreakingPoint>0)

print"All possible 1BP: @currentBreakingPoint\n";

else

print "Try to find two arcs as breaking points...\n";

foreach (my $i=0; $i < @vertices; $i++)

foreach (my $j=$i+1; $j < @vertices; $j++)

my $c=$temp_g->copy_graph;

# print " Before deleting, the copy graph is $c\n";

$c=$c->delete_vertices($vertices[$i],$vertices[$j]);

# print " After deleting $vertices[$i] and $vertices[$j], the copy graph is $c\n";

if($vertices[$i]=~/^path/ or $vertices[$j]=~/^path/)

elsif ($c->is_acyclic)

push @currentBreakingPoint, $vertices[$i];

push @currentBreakingPoint, $vertices[$j];

push @currentBreakingPoint, ';';

# last;

#foreach

if (@currentBreakingPoint>0)##after finding two breaking point, stop the foreach

print"All possible 2BP: @currentBreakingPoint\n";

last;

#foreach

# if

if(@currentBreakingPoint==0)print " **warnning** breaking points is larger than 2

for this components!\n";

else$breakPoint$k=\@currentBreakingPoint;

#if

print "\n**BreakPoints List**\n";

open( BREAK, ">./ITV/BreakPoints.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

for (my $index=0; $index<keys %breakPoint; $index++)

$_=$index;

print "For Component$_: @$strongConnComp[$_]\n @$breakPoint$_ \n";

Page 247: Design and verification approaches for reliability and

234

print BREAK "Component$_ @$breakPoint$_ \n";

close(BREAK);

=cut

open( MYFILE, "./loopList.txt") || die "Can't open myfile: $!";

my @loopList=<MYFILE>;

close(MYFILE);

@loopList=grep /^loop\d+/ @loopList;

if($debugFlag==1)

print @loopList;

my %loopOfComp;

my %loopList;

my %PFL;my %NFL;

my @NetInPFL;my @NetInNFL;

my %loopInSCC;

tie %loopInSCC, 'Tie::IxHash'; # make hash keys in order

foreach my $myloop (@loopList)

$_=$myloop;

if(/^(loop\d+)\s+(\w+)\s+(.*)/)

my $myloopName=$1.$2;

my $loop=$3;

my @temp=split(/\s/,$loop);

if($debugFlag==1)

print "\n$myloopName: $loop\n";

$loopList$myloopName=\@temp;

my @temp_wo_path=grep !/^path/ @temp; # only keep the net information of the

loop to simplify the calculation

if($2 eq "positive")

$PFL$myloopName=\@temp_wo_path;

push @NetInPFL,@temp_wo_path;

else

$NFL$myloopName=\@temp_wo_path;

push @NetInNFL,@temp_wo_path;

my $flag=0;

Page 248: Design and verification approaches for reliability and

235

foreach my $loopItem (@temp)

if($debugFlag==1)

print "@strongConnComp?????????????\n";

foreach (my $j=0; $j< @strongConnComp; $j++)

my $comp=$strongConnComp[$j];

if($debugFlag==1)

print "got it $j++++++++++ @$comp\n";

print "Comp$j=> @$comp\n";

#if(grep /$loopItem/ @$comp) ## might be problematic!!!!!!! since B is

belong to [A1 path1 B1]

if(grep $_ eq $loopItem @$comp)

if($debugFlag==1)

print "since $loopItem is in Comp$j [@$comp]\n";

print "$myloopName is belong to: Comp$j\n";

$flag=1;

my $compName="SCC".$j;

$loopInSCC$myloopName="SCC".$j;

if($debugFlag==1)

print "$compName!!!!!!!!!!!!!!!!!!\n";

$loopOfComp$compName=[] if (not exists

$loopOfComp$compName);

$loopOfComp$compName=[@$loopOfComp$compName,

$myloopName];

#$loopOfComp$j=[] if (not exists $loopOfComp$j);

#$loopOfComp$j=[@$loopOfComp$j, $myloopName];

last;

#if

#foreach

last if($flag==1);

#foreach

#if

#foreach

if($debugFlag==1)

Page 249: Design and verification approaches for reliability and

236

print "\n**loop List**\n";

foreach my $loopName (keys %loopList)

print "$loopName: @$loopList$loopName\n";

print "\n**PFL List**\n";

foreach my $loopName (keys %PFL)

print "$loopName: @$PFL$loopName\n";

#print "Nets in PFLs: @NetInPFL\n";

print "\n**NFL List**\n";

foreach my $loopName (keys %NFL)

print "$loopName: @$NFL$loopName\n";

#print "Nets in NFLs: @NetInNFL\n";

print "\n**loopOFComp List**\n";

foreach my $compName (keys %loopOfComp)

print "$compName: @$loopOfComp$compName\n";

#if($debugFlag==1)

my %loopOfComp_bak=%loopOfComp;

#############################

##Get the nets of the graph

############################

my @Nets=@NetInPFL;

push @Nets,@NetInNFL;

#print "Nets of the graph=>@Nets\n";

###remove the deplicate element in @Nets

my %seen;

$seen$_++ for @Nets;

@Nets=grep !/^path/ keys %seen;

if($debugFlag==1)

print "\n**Nets of the graph (Unique)**\nwhole=>@Nets\n";

#############################

##Get the nets of each SCC

############################

my %Nets_SCC;

my %PFL_SCC;

my %NFL_SCC;

foreach (my $k=0; $k< @strongConnComp; $k++)

Page 250: Design and verification approaches for reliability and

237

my $comp=$strongConnComp[$k];

my @Nets=@$comp;

my %seen;

$seen$_++ for @Nets;

@Nets=grep !/^path/ keys %seen;

$Nets_SCC$k=\@Nets;

if($debugFlag==1)

print "Comp$k=>@$Nets_SCC$k\n";

my $compName="SCC".$k;

foreach (@$loopOfComp$compName)

if(/positive/)

$PFL_SCC$k=[] if (not exists $PFL_SCC$k);

$PFL_SCC$k=[@$PFL_SCC$k, $_];

else

$NFL_SCC$k=[] if (not exists $NFL_SCC$k);

$NFL_SCC$k=[@$NFL_SCC$k, $_];

if($debugFlag==1)

print "\n**PFL_SCC**\n";

if(%PFL_SCC) ##this should be added or the fowllowing print command will report error

when %PFL_SCC is empty

foreach my $compName (keys %PFL_SCC)

print "Comp$compName: @$PFL_SCC$compName\n";

print "\n**NFL_SCC**\n";

if (%NFL_SCC)##this should be added or the fowllowing print command will report error

when %NFL_SCC is empty

foreach my $compName (keys %NFL_SCC)

print "Comp$compName: @$NFL_SCC$compName\n";

#if($debugFlag==1)

####################################

Page 251: Design and verification approaches for reliability and

238

##find FVS by brute force

####################################

tie my %SCCDimension, 'Tie::IxHash';

foreach (my $k=0; $k< @strongConnComp; $k++)

######local N/PFL for current SCC

my %PFL_local;

my %NFL_local;

foreach my $loopName (@$PFL_SCC$k)

$PFL_local$loopName=$PFL$loopName;

foreach my $loopName (@$NFL_SCC$k)

$NFL_local$loopName=$NFL$loopName;

my $comp=$strongConnComp[$k];

=pod

########## obtain the subgraph for each strongcomponent##

my $temp_g = Graph::Directed->new();

print "\nFor Comp$k: @$comp\n";

foreach my $edge (@edges)

if((grep($_ eq @$edge[0]) @$comp) and (grep($_ eq @$edge[1])

@$comp))

#print "@$edge\n";

$temp_g->add_edges(@$edge);

# print "subgraph:$temp_g\n";

=cut

print STDOUT "progress= 80\n";

###############################################

#identify break point for each component

###############################################

my @currentBreakingPoint;

my $Dim;

if(@Nets>0)

########## Try to find one arc as breaking point##

if($debugFlag==1)

print "Try to find one arc as breaking point...\n";

foreach (@Nets) # brute force and search each net in the graph

Page 252: Design and verification approaches for reliability and

239

if(/^path/)

else

if(check_net_in_hash($_,\%PFL_local)) # if this net is contained in every

PFL_local then it's a break-point

if($debugFlag==1)

print "$_ => break-point";

print "\nfor test!!!\n";

print check_net_in_NFLs($_,\%NFL_local);

print check_net_in_hash($_,\%PFL_local);

print "\nfor test!!!\n";

if(!check_net_in_NFLs($_,\%NFL_local))# if this net is not contained in

any NFL then it break only PFL_local

if($debugFlag==1)

print " for only PFLs\n";

if( exists $potentialBreakpoints$_)

push @currentBreakingPoint,$_.'.;';# '.' means find a points that only

break PFLs and terminate the for loop

# ';' is used to seperate two BPS

#last;

else

if($debugFlag==1)

print " for both N/PFLs\n";

if( exists $potentialBreakpoints$_)

push @currentBreakingPoint,$_.';'; #';' is used to seperate two BPS

#if

#if

#if

#foreach

############ Try to find two arcs as breaking points##

if(@currentBreakingPoint>0)

if($debugFlag==1)

print"All possible 1BP: @currentBreakingPoint\n";

Page 253: Design and verification approaches for reliability and

240

$Dim=1;

else

if($debugFlag==1)

print "*Nope!!!*\nTry to find two arcs as breaking points...\n";

foreach (my $i=0; $i < @Nets; $i++)

foreach (my $j=$i+1; $j < @Nets; $j++)

if(check_two_nets_in_hash($Nets[$i],$Nets[$j],\%PFL_local))

if($debugFlag==1)

print "$Nets[$i] $Nets[$j] => is break-points";

if(check_net_in_NFLs($Nets[$i],\%NFL_local) or

check_net_in_NFLs($Nets[$j],\%NFL_local))

if( exists $potentialBreakpoints$Nets[$i] && exists

$potentialBreakpoints$Nets[$j])

push @currentBreakingPoint, $Nets[$i];

push @currentBreakingPoint, $Nets[$j].';'; #';' is used to seperate two

BPS

if($debugFlag==1)

print " for both N/PFLs\n";

else

if( exists $potentialBreakpoints$Nets[$i] && exists

$potentialBreakpoints$Nets[$j])

push @currentBreakingPoint, $Nets[$i];

push @currentBreakingPoint, $Nets[$j].'.;'; #';' is used to seperate two

BPS

last;

if($debugFlag==1)

print " for only PFLs\n";

Page 254: Design and verification approaches for reliability and

241

#foreach

#foreach

if (@currentBreakingPoint>0)

if($debugFlag==1)

print"All possible 2BP: @currentBreakingPoint\n";

$Dim=2;

# if

if(@currentBreakingPoint==0)

if($debugFlag==1)

print STDOUT " **warnning** breaking points is larger than 2 for this

components!\n";

push @currentBreakingPoint, "|BPS|>2".';';

push @currentBreakingPoint, "|BPS|>2".'.;';

$breakPoint$k=\@currentBreakingPoint;

else

$breakPoint$k=\@currentBreakingPoint;

$SCCDimension$k=$Dim;

#if

sub check_net_in_loop

my ($net,$loopName)=@_;

if(grep($_ eq $net) @$loopList$loopName)return 1;

elsereturn 0;

sub check_net_in_hash

Page 255: Design and verification approaches for reliability and

242

my ($net,$hash)=@_;

my $flag=1;

foreach my $loopName (keys %$hash)

if(!check_net_in_loop($net,$loopName))$flag=0;last; # if this net is not contained

in some loops return 0 else return 1

return $flag;

sub check_net_in_NFLs

my ($net,$hash)=@_;

my $flag=0;

foreach my $loopName (keys %$hash)

if(check_net_in_loop($net,$loopName))$flag=1;last; # if this net is contained in

some loops return 1 else return 0

return $flag;

sub check_two_nets_in_hash

my ($netA,$netB,$hash)=@_;

my $flag=1;

my %temp=%$hash;

foreach my $loopName (keys %$hash)

if(check_net_in_loop($netA,$loopName))

delete $temp$loopName;

elsif(check_net_in_loop($netB,$loopName))

delete $temp$loopName;

#print keys %temp;

if(keys %temp)$flag=0;

return $flag;

if($debugFlag==1)

print "\n**BreakPoints List**\n";

Page 256: Design and verification approaches for reliability and

243

open( BREAK, ">./BreakPoints.txt") || die "Can't open myfile: $!";##'>' means write only, it

will clear and rewrite the file.

for (my $index=0; $index<keys %breakPoint; $index++)

$_=$index;

if($debugFlag==1)

print "For SCC$_: @$strongConnComp[$_]\n=>@$breakPoint$_ \n";

print BREAK "SCC$_;@$breakPoint$_\n";

close(BREAK);

open( DIMENSION, ">./SCCDimension.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

foreach (keys %SCCDimension)

print DIMENSION "SCC$_ $SCCDimension$_\n";

close(DIMENSION);

open( SCC, ">./SCCList.txt") || die "Can't open myfile: $!";##'>' means write only, it will

clear and rewrite the file.

for (my $index=0; $index<keys %breakPoint; $index++)

$_=$index;

print SCC "SCC$_ @$strongConnComp[$_]\n";

close(SCC);

open( loopOfComp, ">./loopOfSCC.txt") || die "Can't open myfile: $!";##'>' means write

only, it will clear and rewrite the file.

=pod

foreach my $compName (keys %loopOfComp_bak)

print loopOfComp "$compName @$loopOfComp_bak$compName\n";

=cut

foreach my $myloopName (keys %loopInSCC)

print loopOfComp "$myloopName $loopInSCC$myloopName\n";

close(loopOfComp);

Page 257: Design and verification approaches for reliability and

244

APPENDIX B. PROGRAMS FOR IMPROVING TIME EFFICIENCY OF FAULT-

COVERAGE SIMULATION

1. creat_subSG.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

use lib './FPG16/FPG/package/Graph-0.96/lib';

use Graph::Directed;

#=====================How to

use================================================================

==============

#

# 1. At the directory where foder "FPG16" is located, open a terminal;

# 2. Run the command "perl ./FPG16/FPG/create_subSG.pl"

#

# input file list:

# "./FPG_logfile/sg.txt"

# "./FPG_logfile/sg_#.txt"

# "./FPG_logfile/SCC_nodes.txt"

# "./FPG_logfile/SCC_instances.txt"

#

#

# output file list:

# "./FPG_logfile/.txt" contains the fault propagation graph

# "./FPG_logfile/.txt" contains the sensitivity graph

# "./FPG_logfile/SCC_subSG/sg_#_$k.txt"

# "./FPG_logfile/SCC_subSG/sg_$k.txt"

# "./FPG_logfile/SCC_subSG/sg_adj_$k.txt"

#=================================================================

============================================

##################################################################

#### retrieve the instances and nodes for each SCC**\n";

##################################################################

open( MYFILE, "./FPG_logfile/SCC_inst.txt") || die "Can't open SCC_inst.txt: $!";

my @SCC_instances=<MYFILE>;

print "\n**Instance list for each SCC**\n";

print @SCC_instances;

Page 258: Design and verification approaches for reliability and

245

close(MYFILE);

tie my %SCC_instances, 'Tie::IxHash';

tie my %SCC_nodes, 'Tie::IxHash';

for (my $k=0; $k<@SCC_instances; $k++)

my $currentLine=$SCC_instances[$k];

chomp $currentLine;

my @temp=split(/\=\>/, $currentLine);

my $SCC_Name=$temp[0];

if(@temp>1)

$SCC_instances$SCC_Name=$temp[1];

else

$SCC_instances$SCC_Name="";

foreach my $k (keys %SCC_instances)

print "$k => $SCC_instances$k\n";

open( MYFILE, "./FPG_logfile/SCC_nodes.txt") || die "Can't open SCC_nodes.txt: $!";

my @SCC_nodes=<MYFILE>;

print "\n**Nodes list for each SCC**\n";

print @SCC_nodes;

close(MYFILE);

for (my $k=0; $k<@SCC_nodes; $k++)

my $currentLine=$SCC_nodes[$k];

chomp $currentLine;

my @temp=split(/\=\>/, $currentLine);

my $SCC_Name=$temp[0];

if(@temp>1)

$SCC_nodes$SCC_Name=$temp[1];

else

$SCC_nodes$SCC_Name="";

Page 259: Design and verification approaches for reliability and

246

foreach my $k (keys %SCC_nodes)

print "$k => $SCC_nodes$k\n";

##################################################################

#retrive the sensitivity graph

##################################################################

open( MYFILE, "./FPG_logfile/sg.txt") || die "Can't open sg.txt: $!";

my @SG=<MYFILE>;

close(MYFILE);

=pod

print "\n**sg**\n";

print @SG;

=cut

open( MYFILE, "./FPG_logfile/sg_#.txt") || die "Can't open sg_#.txt: $!";

my @SG_num=<MYFILE>;

close(MYFILE);

=pod

print "\n**sg_#**\n";

print @SG_num;

=cut

##################################################################

#for each instance in the SCC,

#obtain the related edge in SG

##################################################################

print "**instances**\n";

tie my %SCC_subSG, 'Tie::IxHash';

foreach my $k (keys %SCC_instances)

print "$k => $SCC_instances$k\n";

my @inst=split(/\s+/,$SCC_instances$k);

#print "@inst\n";

my @SG_used=@SG;

foreach my $item (@inst)

if($item=~/^T(.*)$/)

Page 260: Design and verification approaches for reliability and

247

#print "transistor: T$1\n";

my $j=$1;

foreach my $Line (@SG)

#chomp $Line;

if ($Line=~/\sI$j\s/)

#print "$Line!!!\n";

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

@SG_used=grep !/$Line/ @SG_used;

elsif($item=~/^R(.*)$/)

#print "Resistor: R$1\n";

my $j=$1;

foreach my $Line (@SG)

#chomp $Line;

if ($Line=~/\sIR$j\s/)

#print "$Line!!!\n";

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

@SG_used=grep !/$Line/ @SG_used;

print "$k => $SCC_nodes$k\n";

my @nodes=split(/\s+/,$SCC_nodes$k);

#print "@nodes!!!!\n";

=pod

foreach my $item (@nodes)

Page 261: Design and verification approaches for reliability and

248

foreach my $Line (@SG_used)

#chomp $Line;

if ($Line=~/\sI(\S+)\s/)

my $temp_node=$1;

if ($temp_node eq $item)

#print "$Line!!!\n";

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

=cut

foreach my $Line (@SG_used)

#chomp $Line;

if ($Line=~/\sI(\S+)\s/)

my $temp_node=$1;

if((grep$_ eq $temp_node @nodes))

#print "$Line!!!\n";

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

#my $tt1=@SG;

#my $tt2=@SG_used;

#print "$tt1,$tt2!!!!!!!!!!!!!!!!!!!!!!!!\n";

=pod

Page 262: Design and verification approaches for reliability and

249

##################################################################

#for each node in the SCC,

#obtain the related edge in SG

##################################################################

print "**nodes**\n";

foreach my $k (keys %SCC_nodes)

print "$k => $SCC_nodes$k\n";

my @nodes=split(/\s+/,$SCC_nodes$k);

#print "@nodes!!!!\n";

my @inst=split(/\s+/,$SCC_instances$k);

foreach my $item (@nodes)

foreach my $Line (@SG)

#chomp $Line;

if ($Line=~/\s(I$item)\s/)

#print "$Line!!!\n";

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

if ($Line=~/\s$item\s/)

print "!!!!$item-->$Line\n";

if ($Line=~/\sI(\S+)\s/)

my $temp_node=$1;

my $temp_inst='T'.$temp_node;

print

"#############################$item==>$temp_node=>$Line\n";

if((grep$_ eq $temp_node @nodes))

print "\t$Line is in this

SCC********************";

if((grep$_ eq $temp_inst @inst))

print "\t$Line **is in this

SCC********************";

Page 263: Design and verification approaches for reliability and

250

$SCC_subSG$k=[] if (not exists $SCC_subSG$k);

#$SCC_subSG$k=[@$SCC_subSG$k, $Line];

$SCC_subSG$k=[@$SCC_subSG$k, $Line] if

(!(grep$_ eq $Line @$SCC_subSG$k)); #avoid repeating

=cut

print "\n**subSG for each SCC**\n";

if (! -d './FPG_logfile/SCC_subSG')

system('mkdir -p ./FPG_logfile/SCC_subSG')

else

system('rm -r ./FPG_logfile/SCC_subSG/*');

foreach my $k (keys %SCC_subSG)

print "$k\t => $SCC_instances$k\n";

print "\t => $SCC_nodes$k\n";

print "@$SCC_subSG$k\n";

#system("mkdir SCC_subSG");

open( MYFILE, ">./FPG_logfile/SCC_subSG/sg_#_$k.txt") || die "Can't open

sg_#_$k.txt: $!";

open( MYFILE1, ">./FPG_logfile/SCC_subSG/sg_$k.txt") || die "Can't open

sg_$k.txt: $!";

my $count=0;

my @node;

my %SG_w;

foreach my $edge (@$SCC_subSG$k)

my @temp=split(/\s+/, $edge);

print MYFILE1 " \t$temp[1]\t$temp[2]\t$temp[3]\n";

#print "@temp\n";

my $num=$temp[0];

my @temp1=split(/\s+/, $SG_num[$num-1]);

#print "@temp1\n";

$count++;

print MYFILE $count;

print MYFILE " \t$temp1[1]\t$temp1[2]\t$temp1[3]\n";

Page 264: Design and verification approaches for reliability and

251

push @node,$temp[1] if (!(grep$_ eq $temp[1] @node));

push @node,$temp[2] if (!(grep$_ eq $temp[1] @node));

$SG_w$temp[1].$temp[2]=$temp[3];

#print "\t@node\n";

=pod

open( MYFILE2, ">./FPG_logfile/SCC_subSG/sg_adj_$k.txt") || die "Can't open

sg_adj_$k.txt: $!";

for (my $i=0;$i<@node;$i++)

print "\t\t$node[$i]";

print MYFILE2 "\t\t$node[$i]";

print "\n";

for (my $i=0;$i<@node;$i++)

print "$node[$i]";

print MYFILE2 "$node[$i]";

for (my $j=0;$j<@node;$j++)

if(exists $SG_w$node[$i].$node[$j])

print "\t\t$SG_w$node[$i].$node[$j]";

print MYFILE2 "\t\t$SG_w$node[$i].$node[$j]";

else

print "\t\t0";

print MYFILE2 "\t\t0";

print "\n";

print MYFILE2 "\n";

close(MYFILE2);

=cut

print "\n";

close(MYFILE);

close(MYFILE1);

2. createFPG.pl

#! /usr/bin/perl

use strict;

Page 265: Design and verification approaches for reliability and

252

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

use lib './FPG16/FPG/package/Graph-0.96/lib';

use Graph::Directed;

#$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#This need to take care

my @input_pin;

push @input_pin, "vin";

push @input_pin, "vip";

#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#=====================How to

use================================================================

==============

#

# 1. At the directory where foder "FPG16" is located, open a terminal;

# 2. Run the command "perl ./FPG16/FPG/createFPG.pl"

#

# input file list:

# "./FPG16/FPG/flattenNetlist.pl" Reqired script @dir ./FPG16/FPG/

#

# "./FPG16/FPG/findSCC.pl" Reqired script @dir ./FPG16/FPG/ to find SCC for

fpg.txt

# "./FPG_logfile/op.auto" Reqired file @dir ./FPG16/FPG/ which contains the

DC operating points of gm, gmb, gds, R

# output file list:

# "./FPG_logfile/fpg.txt" contains the fault propagation graph

# "./FPG_logfile/sg.txt" contains the sensitivity graph

# "./FPG_logfile/sg_#.txt" contains the sensitivity graph in number

# "./FPG_logfile/nodes.txt" contains the node list of the sensitivity graph

# "./FPG_logfile/nodes2num.txt" contains the node list of the sensitivity graph in

numbers

# "./FPG_logfile/nodes_impedance.txt" contains the node impedances

my $start_time=time();

my $start_time2=localtime();

##################################################################

#determine wether to print out information

my $debugFlag=1;

Page 266: Design and verification approaches for reliability and

253

if($debugFlag==1)

print "start at:$start_time2\n";

=pod

$cellName="widlar";

$fileName=$cellName."_hier.netlist";

=cut

##################################################################

####flatten the netlist generated from cadence [optional]

##################################################################

system("perl ./FPG16/FPG/flattenNetlist.pl -d 1 >./FPG_logfile/flattenNetlist.log");

##################################################################

#### retrieve the netlist

##################################################################

open( MYFILE, "./FPG_logfile/flattenNetlist.txt") || die "Can't open flattenNetlist.txt: $!";

my @netlist_from_cadence=<MYFILE>;

if($debugFlag==1)

print @netlist_from_cadence;

close(MYFILE);

####store the useful information in a hash

#=================================================

# this is used to include the terminal line <==/^\(/

my @netlist_usf=grep /^\w+\d/ || /^\(/, @netlist_from_cadence;

#=================================================

##################################################################

#fowlloing code is to get the cell name

##################################################################

my @cellName=grep /\/\/Cell/, @netlist_from_cadence;

print "@cellName\n";

my $cellName;

foreach (@cellName)

if (/\"(.*)\"/)

$cellName=$1;

print "cell name==>$cellName\n";

##################################################################

#fowlloing code is to get the power

#supply node from the form

##################################################################

my @myPowerSupply=grep /^MyV/, @netlist_from_cadence;

if($debugFlag==1)

Page 267: Design and verification approaches for reliability and

254

print @myPowerSupply;

my $myVdd;

my $myVss;

my $path_begin='vdd!'; #set default value

my $path_end='gnd!'; #set default value

my %path_begin;

my %path_end;

$path_begin'vdd!'=1; #set default value

$path_end'gnd!'=1; #set default value

foreach (@myPowerSupply)

if(/^MyVdd\:\s\"(.*)\"/)

$myVdd=$1;

map($path_begin$_=1,split(/ /,$1));

elsif(/^MyVss\:\s\"(.*)\"/)

$myVss=$1;

map($path_end$_=1,split(/ /,$1));

if(defined $myVdd)

$path_begin=$myVdd;

#delete $path_begin'vdd!';

if(defined $myVss)

$path_end=$myVss;

#delete $path_end'gnd!';

print "$path_begin, $path_end,!!!!!!!!!!!!!!!!!!!!!!\n";

##################################################################

#fowlloing code is to get the netlist

#################################################################

if($debugFlag==1)

print "\n**processing the netlist**\n";

#print "netlist_usf:", @netlist_usf;

tie my %instance_hash, 'Tie::IxHash';

tie my %netlist_usf, 'Tie::IxHash';

tie my %instance_prop, 'Tie::IxHash';# model name of a device, like 'nfet', 'res', 'cap'

Page 268: Design and verification approaches for reliability and

255

tie my %instance_terminal, 'Tie::IxHash';# teminal name of a device, like 'D', 'S', 'B'

tie my %FPG_depen, 'Tie::IxHash';

tie my %FPG_depen1, 'Tie::IxHash';

my $FPG_Count;

$FPG_Count=0;

for (my $i=0;$i<@netlist_usf;$i++)

$_=$netlist_usf[$i];

if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)\s/)

$instance_hash$1=[split(/\" \"/,$2)];

if($debugFlag==1)

print "$1 => @$instance_hash$1 \n";

$instance_prop$1=$3;

#=========================================================

#########store the terminal infor.

my $instName=$1;

my $nextLine=$netlist_usf[$i+1];

if($nextLine=~/^\(\"(.*)\"\)/) #this considering ("D" "B" "G" "S")

$instance_terminal$instName=[split(/\" \"/,$1)];

if($nextLine=~/^\(\'(.*)\'\)/)#this considering ('D' 'B' 'G' 'S')

$instance_terminal$instName=[split(/\' \'/,$1)];

#=========================================================

elsif(/^(\w+\d+.*)\s+\(\"(.*)\"\)\s+(\w+)\s/) ##this considering we have hierachical

instances which are named like "I0.I1.N4"

$instance_hash$1=[split(/\" \"/,$2)];

if($debugFlag==1)

print "Got it!!!$1 => @$instance_hash$1 \n";

$instance_prop$1=$3;

#=========================================================

#########store the terminal infor.

my $instName=$1;

my $nextLine=$netlist_usf[$i+1];

if($nextLine=~/^\(\"(.*)\"\)/)#this considering ("D" "B" "G" "S

Page 269: Design and verification approaches for reliability and

256

$instance_terminal$instName=[split(/\" \"/,$1)];

if($nextLine=~/^\(\'(.*)\'\)/)#this considering ('D' 'B' 'G' 'S')

$instance_terminal$instName=[split(/\' \'/,$1)];

#=========================================================

###########################################################################

###

#find the channel of each instance

#diode connection transistor

#gate of non-diode connection tansistor

###########################################################################

###

tie my %graph, 'Tie::IxHash';

my %gate;

my %gate_net;

my %D;

my %S;

tie my %DirectedDepen, 'Tie::IxHash';

for my $instance (keys %instance_hash)

$_=$instance;

if($debugFlag==1)

print "$instance:";

my $prop=$instance_prop$instance;

if($debugFlag==1)

print "$prop";

my @terminal=@$instance_terminal$instance;

if($debugFlag==1)

print "(@terminal)";

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

if($debugFlag==1)

Page 270: Design and verification approaches for reliability and

257

print " is COMS!!";

elsif($prop=~/pnp|npn/)

if($debugFlag==1)

print " is BJT!!";

if($debugFlag==1)

print "\n";

#if(/P|N|M\d+/)

if($prop=~/^pmos|^pfet|^nmos|^nfet/) #means this is a coms transistor

#determine the channel of transistor

my $net=$instance_hash$instance;

#=================================================================

===========

my $D;

my $S;

my $B;

my $G;

for(my $i=0;$i<@terminal;$i++)

if($terminal[$i]=~/G/)$G=$net->[$i];

elsif($terminal[$i]=~/S/)$S=$net->[$i];

elsif($terminal[$i]=~/D/)$D=$net->[$i];

elsif($terminal[$i]=~/B/)$B=$net->[$i];

$S$instance=$S;

$D$instance=$D;

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

$gate$instance=$G;

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

# print "D=>$D S=>$S\n";

$graph$instance=[$D,$S];

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

FFFFFFFF

my $I='I_'.$instance;

if(not exists $FPG_depen1$G.$I)

Page 271: Design and verification approaches for reliability and

258

$FPG_depen1$G.$I=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$G, $I];

if(not exists $path_begin$D and ($D ne $path_end))

if(not exists $FPG_depen1$I.$D)

$FPG_depen1$I.$D=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$I, $D];

if(not exists $FPG_depen1$D.$I)

$FPG_depen1$D.$I=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$D, $I];

if(not exists $path_begin$S and ($S ne $path_end))

if(not exists $FPG_depen1$S.$I)

$FPG_depen1$S.$I=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$S, $I];

if(not exists $FPG_depen1$I.$S)

$FPG_depen1$I.$S=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$I, $S];

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

FFFFFFFF

#if(

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

if($D eq $S)

if($D eq $B)

Page 272: Design and verification approaches for reliability and

259

if($debugFlag==1)

print "since D=S=B It's a varactor (variable capacitor)!!!!!!!!\n";

delete $graph$instance;

$instance_prop$_="varactor";

else

if($debugFlag==1)

print " It's a diode!!!!!!!!\n";

delete $graph$instance;

$instance_prop$_="diode";

$graph$_=[$D,$B];

#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

elsif (($D ne $G) and ($G ne $S))#not diode connected

if(($D eq $S) and ($D eq $B))# vorator ###diode transistor or

if($debugFlag==1)

print " It's a varactor (variable capacitor)!!!!!!!!\n";

delete $graph$instance;

else

$gate$instance=$G;

$gate_net$G=[] if (not exists $gate_net$G);

$gate_net$G=[@$gate_net$G, $instance];

else

#search for diode connection and change the name

$_=$instance;

s/P/PD/;

s/N/ND/;

s/M/MD/;

s/T/TD/;

$graph$_=delete $graph$instance;

if($debugFlag==1)

Page 273: Design and verification approaches for reliability and

260

print $instance, " is diode connection => $_\n";

#=================================================================

=============

elsif($prop=~/res/) #means this is a resistor

my $net=$instance_hash$instance;

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

FFFFFFFF

my $I='I_'.$instance;

if(not exists $path_begin@$net[0] and (@$net[0] ne $path_end))

if(not exists $FPG_depen1$I.@$net[0])

$FPG_depen1$I.@$net[0]=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$I, @$net[0]];

if(not exists $FPG_depen1@$net[0].$I)

$FPG_depen1@$net[0].$I=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[@$net[0], $I];

if(not exists $path_begin@$net[1] and (@$net[1] ne $path_end))

if(not exists $FPG_depen1@$net[1].$I)

$FPG_depen1@$net[1].$I=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[@$net[1], $I];

if(not exists $FPG_depen1$I.@$net[1])

$FPG_depen1$I.@$net[1]=1;

$FPG_Count=$FPG_Count+1;

$FPG_depen'DD'.$FPG_Count=[$I, @$net[1]];

Page 274: Design and verification approaches for reliability and

261

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

FFFFFFFF

elsif($prop=~/cap/) #means this is a capacitor

delete $graph$instance;

elsif(/^I\d+/)

if($debugFlag==1)

print "$_ is: $instance_prop$_\n";

if($instance_prop$_=~/^idc/)$graph$instance=$instance_hash$instance;

#it's not an independent current source

elsif($prop=~/pnp|npn/)

#determine the channel of BJT

my $net=$instance_hash$instance;

$graph$instance=[$net->[0],$net->[2]]; #(0 1 2)==>(C B E)

#determine the Base of BJT

if (($net->[0] ne $net->[1]) and ($net->[2] ne $net->[1]))#not diode connected

my $base_channel=$instance.'_BE';

$graph$base_channel=[$net->[1],$net->[2]];

$gate$instance=$net->[1];

$gate_net$net->[1]=[] if (not exists $gate_net$net->[1]);

$gate_net$net->[1]=[@$gate_net$net->[1], $instance];

else

#search for diode connection and change the name

$_=$instance;

s/Q/QD/;

$graph$_=delete $graph$instance;

if($debugFlag==1)

print $instance, " is diode connection $prop => $_\n";

Page 275: Design and verification approaches for reliability and

262

else

$graph$instance=$instance_hash$instance;

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFF

open( MYDEPEN1, ">./FPG_logfile/fpg.txt") || die "Can't open fpg.txt: $!";##'>' means write

only, it will clear and rewrite the file.

if($debugFlag==1)

print "\n**FPG_depen list**\n";

foreach my $item (keys %FPG_depen)

print "$item: @$FPG_depen$item[0] => @$FPG_depen$item[1]\n";

print MYDEPEN1 "@$FPG_depen$item[0] @$FPG_depen$item[1]\n";

close(MYDEPEN1);

#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

#############################################################

# find SCC

system("perl ./FPG16/FPG/findSCC.pl -d $debugFlag");

#############################################################

#############################################################

#### read gm gds from a file

#############################################################

#open( MYFILE, "./$cellName.op") || die "Can't open $cellName.op: $!";

open( MYFILE, "./FPG_logfile/op.auto") || die "Can't open op.auto: $!";

my @op= ('Tie::Array');

@op=<MYFILE>;

close(MYFILE);

#print @op;

#############################################################

#### otain op

#############################################################

tie my %op, 'Tie::IxHash';

Page 276: Design and verification approaches for reliability and

263

foreach (@op)

my @IN=split(/\s+/,$_);

$op$IN[0]=$IN[1];

print "\n**Now creating sensitivity graph:**\n";

print "**OP is:**\n";

foreach my $depen (keys %op)

print "$depen=>$op$depen\n";

print "\n\n**step 1**\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

#1. Extract all the “nets” as voltage nodes;

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

my @Net_vec;

my %net_instance;

foreach my $inst (keys %instance_hash)

=pod

print "$inst=>@$instance_hash$inst\n";

my $prop=$instance_prop$inst;

if($debugFlag==1)

print "$prop";

my @terminal=@$instance_terminal$inst;

if($debugFlag==1)

print "(@terminal)";

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

print " is COMS!!";

=cut

foreach my $net(@$instance_hash$inst)

# print "$net\n";

if(($net ne $path_begin) && ($net ne $path_end) && ($net ne 'gnd!') &&

!(grep$_ eq $net @Net_vec)) #(exclude VDD VSS)

if(!grep(/^$net$/, @input_pin))

Page 277: Design and verification approaches for reliability and

264

push @Net_vec, $net;

if(($net ne $path_begin) && ($net ne $path_end) && ($net ne 'gnd!') ) #(exclude

VDD VSS)

$net_instance$net=[] if (not exists $net_instance$net);

$net_instance$net=[@$net_instance$net, $inst] if (!(grep$_ eq $inst

@$net_instance$net)); #avoid repeating

print "\n**Nets of the circuit, (exclude VDD VSS)**\n";

print "=>@Net_vec\n";

print "\n**Incident device of a net **\n";

for my $_(keys %net_instance)

print "$_==> @$net_instance$_\n";

print "\n\n**step 2**\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

#2. Each voltage node has current node (inject current) to generate it with a gain of Z

(except input voltage nodes, e.g. VA, VB, Vbias);

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

my $sensGraph = Graph::Directed->new();

tie my %SFG, 'Tie::IxHash';

tie my %SFG_w, 'Tie::IxHash';

my %node_impedance;

foreach my $net (@Net_vec)

my @edges=['I'.$net, $net];

$sensGraph->add_edges(@edges);

my $name='I'.$net.'->'.$net;

$SFG$name=['I'.$net, $net];

$SFG_w$name=1;

#####find impedance

Page 278: Design and verification approaches for reliability and

265

my $z=0;

my $nonsource_flag=0; #mean it is not an node that only connect to idea voltage

source

print "\n**For net $net: ";

print "incident instance==>@$net_instance$net**\n";

foreach my $inst(@$net_instance$net)

my $prop=$instance_prop$inst;

my $i;

if($inst=~/^\w(\d+)/)

$i=$1;

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

print "=>$inst\[COMS\]: ";

print "G:$gate$inst\t";

print "D:$D$inst\t";

print "S:$S$inst\n";

if ($net eq $D$inst)

print "gds_$inst = $op'gds_'.$inst is added\n";

$nonsource_flag=1;

$z=$z+$op'gds_'.$inst;

if ($net eq $gate$inst)

print "gm_$inst = $op'gm_'.$inst is added\n";

$z=$z+$op'gm_'.$inst;

elsif ($net eq $S$inst)

print "gds_$inst = $op'gds_'.$inst and gm_$inst = $op'gm_'.$inst

are added\n";

$nonsource_flag=1;

$z=$z+$op'gds_'.$inst+$op'gm_'.$inst;

Page 279: Design and verification approaches for reliability and

266

if($prop=~/^res/)

print "=>$inst\[RES\]: ";

print "1/$inst=$op$inst is added\n";

$nonsource_flag=1;

$z=$z+$op$inst;

if($prop=~/^vdc/ or $prop=~/^vdc/)

print "=>$inst\[vdc/idc\]: ";

print "$inst is a source\n";

if($nonsource_flag)

$SFG_w$name=1/$z;

print "z_$net: $name==>$SFG_w$name!!!\n";

$node_impedance$net=1/$z;

print "\n\n**step 3**\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

#3 For each MOS, include a branch: Vgate Idrain with gain of –gm

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

foreach my $inst (keys %graph)

if (exists $instance_hash$inst)

print "$inst=>@$instance_hash$inst\n";

my $prop;

if (exists $instance_prop$inst)

$prop=$instance_prop$inst ;

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

print "=>$inst\[COMS\]: !!!!!!!!!!!!!!";

print "G:$gate$inst\t";

Page 280: Design and verification approaches for reliability and

267

print "D:$D$inst\t";

print "S:$S$inst\n";

if(($D$inst ne $path_begin) and ($D$inst ne $path_end) )

my $i;

if($inst=~/^\w(\d+)/)

$i=$1;

# add edge: Vgate-->Idrain

my @edges=[$gate$inst,'I'.$D$inst];

$sensGraph->add_edges(@edges);

my $name=$gate$inst.'->I'.$D$inst;

print "$name==>";

$SFG$name=[$gate$inst,'I'.$D$inst];

$SFG_w$name=0-$op'gm_'.$inst;;

print "$SFG_w$name\n";

print "\n\n**step 4**\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

# 4. For MOS whose sources are not vdd/gnd,

# includes a branch: Vgate Isource with gain of gm

# includes a branch: Vsource Idrain with gain of gm+gmb+gds

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

print "$path_begin!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";

foreach my $inst (keys %graph)

print "$inst############################\n";

if (exists $instance_hash$inst)

print "$inst=>@$instance_hash$inst\n";

my $prop;

if (exists $instance_prop$inst)

Page 281: Design and verification approaches for reliability and

268

$prop=$instance_prop$inst ;

print "@@@@@@@@@@@@@@@@@@@\n";

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

print "=>$inst\[COMS\]: ";

print "G:$gate$inst\t";

print "D:$D$inst\t";

print "S:$S$inst\n";

if(($S$inst ne $path_begin) and ($S$inst ne $path_end) )

my $i;

if($inst=~/^\w(\d+)/)

$i=$1;

# add edge: Vgate-->Isource

my @edges=[$gate$inst,'I'.$S$inst];

$sensGraph->add_edges(@edges);

my $name=$gate$inst.'->I'.$S$inst;

print "$name==>";

$SFG$name=[$gate$inst,'I'.$S$inst];

$SFG_w$name=$op'gm_'.$inst;

print "$SFG_w$name\n";

# add edge: Vsource-->Idrain

if(($D$inst ne $path_begin) and ($D$inst ne $path_end) )

@edges=[$S$inst,'I'.$D$inst];

$sensGraph->add_edges(@edges);

$name=$S$inst.'->I'.$D$inst;

print "$name==>";

$SFG$name=[$S$inst,'I'.$D$inst];

$SFG_w$name=$op'gm_'.$inst+$op'gmb_'.$inst+$op'gds_'.$inst;

print "$SFG_w$name\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

Page 282: Design and verification approaches for reliability and

269

# for dioded connected MOS and whose sources are not vdd/gnd,

# includes a branch: Vgate Isource with gain of gm

# includes a branch: Vsource Idrain with gain of gm+gmb+gds

elsif ($inst=~/^PD/ or $inst=~/^ND/ or $inst=~/^MD/ or $inst=~/^TD/ )

print "diode conncted

transistor%%%%%%%%%%%%%%%%%%%%%%%\n";

print "=>$inst\[Diode Conncted COMS\]: ";

$_=$inst;

s/PD/P/;

s/ND/N/;

s/MD/M/;

s/TD/T/;

$inst=$_;

print "G:$gate$inst\t";

print "D:$D$inst\t";

print "S:$S$inst\n";

if(($S$inst ne $path_begin) and ($S$inst ne $path_end) )

my $i;

if($inst=~/^\w(\d+)/)

$i=$1;

# add edge: Vgate-->Isource

my @edges=[$gate$inst,'I'.$S$inst];

$sensGraph->add_edges(@edges);

my $name=$gate$inst.'->I'.$S$inst;

print "\tweight is: gm_$inst = $op'gm_'.$inst \n";

print "$name==>";

$SFG$name=[$gate$inst,'I'.$S$inst];

$SFG_w$name=$op'gm_'.$inst;

print "$SFG_w$name\n";

# add edge: Vsource-->Idrain

if(($D$inst ne $path_begin) and ($D$inst ne $path_end) )

@edges=[$S$inst,'I'.$D$inst];

$sensGraph->add_edges(@edges);

Page 283: Design and verification approaches for reliability and

270

$name=$S$inst.'->I'.$D$inst;

print "\tweight is: gm_$inst = $op'gm_'.$inst, gmb_$inst =

$op'gmb_'.$inst and gds_$inst = $op'gds_'.$inst\n";

print "$name==>";

$SFG$name=[$S$inst,'I'.$D$inst];

$SFG_w$name=$op'gm_'.$inst+$op'gmb_'.$inst+$op'gds_'.$inst;

print "$SFG_w$name\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSS

print "\n\n**step 5**\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

# 5. Form the physical current variables

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

foreach my $inst (keys %instance_hash)

print "$inst=>@$instance_hash$inst\n";

my $prop=$instance_prop$inst;

my $i;

if($inst=~/^\w(\d+)/)

$i=$1;

if($prop=~/^pmos|^pfet|^nmos|^nfet/)

print "=>$inst\[COMS\]: ";

print "G:$gate$inst\t";

print "D:$D$inst\t";

print "S:$S$inst\n";

if(($S$inst ne $path_begin) and ($S$inst ne $path_end) )

# add edge: Vsource-->I_ins

Page 284: Design and verification approaches for reliability and

271

my @edges=[$S$inst,'I'.$i];

$sensGraph->add_edges(@edges);

my $name=$S$inst.'->I'.$i;

print "$name==>";

$SFG$name=[$S$inst,'I'.$i];

$SFG_w$name=$op'gds_'.$inst;

print "$SFG_w$name\n";

if($gate$inst eq $D$inst )

# add edge: Vg,Vs-->I_ins

my @edges=[$gate$inst,'I'.$i];

$sensGraph->add_edges(@edges);

my $name=$gate$inst.'->I'.$i;

print "$name==>";

$SFG$name=[$gate$inst,'I'.$i];

$SFG_w$name=$op'gds_'.$inst+$op'gm_'.$inst;

print "$SFG_w$name\n";

else

# add edge: Vg-->I_ins

my @edges=[$gate$inst,'I'.$i];

$sensGraph->add_edges(@edges);

my $name=$gate$inst.'->I'.$i;

print "$name==>";

$SFG$name=[$gate$inst,'I'.$i];

$SFG_w$name=$op'gm_'.$inst;

print "$SFG_w$name\n";

# add edge: VD-->I_ins

if(($D$inst ne $path_begin) and ($D$inst ne $path_end) )

@edges=[$D$inst,'I'.$i];

$sensGraph->add_edges(@edges);

$name=$D$inst.'->I'.$i;

print "$name==>";

$SFG$name=[$D$inst,'I'.$i];

$SFG_w$name=$op'gds_'.$inst;

print "$SFG_w$name\n";

Page 285: Design and verification approaches for reliability and

272

if($prop=~/^res/)

print "=>$inst\[RES\]: @$instance_hash$inst\n";

foreach my $term(@$instance_hash$inst)

print "$term!!!!!!\n";

if ( ($term ne $path_begin) and ($term ne $path_end))

# add edge: Vres-->I_ins

my @edges=[$term,'IR'.$i];

$sensGraph->add_edges(@edges);

my $name=$term.'->IR'.$i;

print "$name==>";

$SFG$name=[$term,'IR'.$i];

$SFG_w$name=$op$inst;

print "$SFG_w$name\n";

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

# print sensitivity graph to a file

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

open( MYSFG, ">./FPG_logfile/sg.txt") || die "Can't open sg.txt: $!";##'>' means write only,

it will clear and rewrite the file.

print "\n**SFG list**\n";

my $count=0;

my @Nodes;

my %Nodes2num;

my $N=1;

foreach my $item (keys %SFG_w)

$count++;

my @item=split(/->/,$item);

print $count;

print " \t$item[0]\t$item[1]\t";

print "$SFG_w$item\n";

print MYSFG $count;

print MYSFG " \t$item[0]\t$item[1]\t";

Page 286: Design and verification approaches for reliability and

273

print MYSFG "$SFG_w$item\n";

####get the nodes

if(!(grep$_ eq $item[0] @Nodes))

push @Nodes,$item[0];

$Nodes2num$item[0]=$N;

$N++;

if(!(grep$_ eq $item[1] @Nodes))

push @Nodes,$item[1];

$Nodes2num$item[1]=$N;

$N++;

close(MYSFG);

open( MYSFG_NUM, ">./FPG_logfile/sg_#.txt") || die "Can't open sg_#.txt: $!";##'>' means

write only, it will clear and rewrite the file.

$count=0;

foreach my $item (keys %SFG_w)

$count++;

my @item=split(/->/,$item);

print MYSFG_NUM $count;

print MYSFG_NUM " \t$Nodes2num$item[0]\t$Nodes2num$item[1]\t";

print MYSFG_NUM "$SFG_w$item\n";

close(MYSFG_NUM);

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

# print nodes of sensitivity graph to a file

#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

SSSSSSSS

open( MYFILE, ">./FPG_logfile/nodes.txt") || die "Can't open nodes.txt: $!";

#print "\n**Nodes list**\n";

foreach my $node (@Nodes)

#print "$node\n";

print MYFILE "$node\n";

print "\n";

close(MYFILE);

Page 287: Design and verification approaches for reliability and

274

open( MYFILE, ">./FPG_logfile/nodes2num.txt") || die "Can't open nodes2num.txt: $!";

#print "\n**Nodes list**\n";

foreach my $node (@Nodes)

#print "$node\n";

print MYFILE "$node\t$Nodes2num$node\n";

print "\n";

close(MYFILE);

open( MYFILE, ">./FPG_logfile/nodes_impedance.txt") || die "Can't open

nodes_impedance.txt: $!";

#print "\n**Nodes list**\n";

foreach my $net (keys %node_impedance)

#print "$net=>$node_impedance$net\n";

print MYFILE "$net\t$node_impedance$net\n";

print "\n";

close(MYFILE);

print STDOUT "FINISHED\n";

3.findPath.pl

#! /usr/bin/perl

use constant LAST => -1;

use constant PATH => 0;

use constant SEEN => 1;

use strict;

use warnings;

sub find_paths

my ($beg, $end, $graph) = @_;# $graph is the ref of %graph

my @solution;

my @work;

for (@$graph->$beg) # $graph->$beg is the ref of key "$beg"

# push @solution, [$beg, $end] if $_ eq $end;

if ($_ eq $end)

push @solution, [$beg, $end];

next;

push @work, [[$beg, $_], $beg => undef, $_ => undef];

Page 288: Design and verification approaches for reliability and

275

#the hash with undef is to check whether the node hasbeen visited

while (@work)

my $item = pop @work;

my ($path, $seen) = @$item[PATH, SEEN];

for my $node (@$graph->$path->[LAST])

next if exists $seen->$node;

my @new_path = (@$path, $node);

if ($node eq $end)

push @solution, \@new_path;

next;

my %new_seen = (%$seen, $node => undef);

push @work, [\@new_path, \%new_seen];

return \@solution;

1;

4. obtainOP.ocn

#! /bin/sh -exec awd -ocean "$@"

simulator( 'spectre )

design( "/tmp/zqliu216/simulation/Example/spectre/schematic_no_para/netlist/netlist")

resultsDir( "/tmp/zqliu216/simulation/Example/spectre/schematic_no_para" )

path( "/remote/rs/vlsi/ibm8rfcmos/IBM_PDK/cmrf8sf/relDM/Spectre/models" )

modelFile(

'("/remote/cadencelib/nda/ibm8rfcmos/IBM_PDK/cmrf8sf/relDM/Spectre/models/allModels.

scs" "tt")

'("/remote/cadencelib/nda/ibm8rfcmos/IBM_PDK/cmrf8sf/relDM/Spectre/models/design.scs

" "")

)

analysis('dc ?saveOppoint t )

envOption(

'analysisOrder list("dc" "stb")

)

option( 'temp "27.0"

)

temp( 27.0 )

run()

plot( VDC("/vout") )

plot( OP("/T31" "gm") )

plot( OP("/T30" "gm") )

Page 289: Design and verification approaches for reliability and

276

;##########################################################################

############

;Above this line is ocean code for DC simulation to simulating the DC operating points

;obtain this part by using ADE_L with "save ocean script"

;##########################################################################

############

;=====================How to

use=========================================================

;

; 1. Open virtuoso;

; 2. set up a DC simulation for target circuit using ADE_L, then "save ocean script" and

replace the following highlighted part

; 3.

; a) At virtuoso CIW, tun following command:

;

load("/home/zqliu216/DM_template61/AnaFault_201609/FPG16/FPG/obtainOP.ocn"

)

; b) in linux terminal, run the command: system("ocean -restore ./FPG16/FPG/obtainOP.ocn

logfile_obtainOP.txt");

;

; input file list: none

; output file list:

; "./FPG_logfile/op.auto" contains the operating points of the netlist

;==================================================================

======================

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;obtain the instance list that we need to print the DC operating points

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InstTable=makeTable("InstTable" nil) ;store the dimension for each SCC

let( (inport nextLine Iterm InstName)

inport=infile("/home/zqliu216/DM_template61/AnaFault_201609/FPG_logfile/inst_list.txt")

when(inport

while(gets(nextLine inport)

println(nextLine)

Iterm=parseString(nextLine)

InstName =car(Iterm)

InstTable[InstName]=append1(InstTable[InstName] cadr(Iterm))

Page 290: Design and verification approaches for reliability and

277

);while

close(inport)

);when

);let

printf("\n**Instance Table**\n")

foreach(InstName InstTable

printf("%s=>%L\n" InstName InstTable[InstName])

)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;obtain the DC operating points

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

printf("\n**DC operating points**\n")

out=outfile("/home/zqliu216/DM_template61/AnaFault_201609/FPG_logfile/op.auto" "w")

foreach(InstName InstTable

printf("%s=>%L" InstName InstTable[InstName])

cellName=car(InstTable[InstName])

if(cellName=="pmos4" ||cellName=="pfet"|| cellName=="nfet"||cellName=="nmos4" ||

cellName=="pfet33"|| cellName=="nfet33"

then

println(" is a mosfet")

gm=OP(InstName "gm")

gmb=OP(InstName "gmbs")

gds=OP(InstName "gds")

printf("gm_%s\t %1.4e\n" InstName , gm)

if(gmb!=nil then

printf("gmb_%s\t %1.4e\n" InstName , gmb)

); End if

printf("gds_%s\t %1.4e\n" InstName , gds)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;print to file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fprintf(out "gm_%s\t %1.4e\n" InstName , gm)

if(gmb!=nil then

fprintf(out "gmb_%s\t %1.4e\n" InstName , gmb)

); End if

fprintf(out "gds_%s\t %1.4e\n" InstName , gds)

);if

if(cellName=="res"

then

println("is a res")

Page 291: Design and verification approaches for reliability and

278

res=1/OP(InstName "res")

printf("%s\t %1.4e\n" InstName , res)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;print to file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fprintf(out "%s\t %1.4e\n" InstName , res)

); End if

); end for

close(out)

exit()

5. obtainOP_partII.ocn

;##########################################################################

############

;Above this line is ocean code for DC simulation to simulating the DC operating points

;obtain this part by using ADE_L with "save ocean script"

;##########################################################################

############

;=====================How to

use=========================================================

;

; 1. Open virtuoso;

; 2. set up a DC simulation for target circuit using ADE_L, then "save ocean script" and

replace the following highlighted part

; 3.

; a) At virtuoso CIW, tun following command:

;

load("/home/zqliu216/DM_template61/AnaFault_201609/FPG16/FPG/obtainOP.ocn"

)

; b) in linux terminal, run the command: system("ocean -restore ./FPG16/FPG/obtainOP.ocn

logfile_obtainOP.txt");

;

; input file list: none

; output file list:

; "./FPG_logfile/op.auto" contains the operating points of the netlist

;==================================================================

======================

Page 292: Design and verification approaches for reliability and

279

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;obtain the instance list that we need to print the DC operating points

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InstTable=makeTable("InstTable" nil) ;store the dimension for each SCC

let( (inport nextLine Iterm InstName)

inport=infile("/home/zqliu216/DM_template61/AnaFault_201609/FPG_logfile/inst_list.txt")

when(inport

while(gets(nextLine inport)

println(nextLine)

Iterm=parseString(nextLine)

InstName =car(Iterm)

InstTable[InstName]=append1(InstTable[InstName] cadr(Iterm))

);while

close(inport)

);when

);let

printf("\n**Instance Table**\n")

foreach(InstName InstTable

printf("%s=>%L\n" InstName InstTable[InstName])

)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;obtain the DC operating points

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

printf("\n**DC operating points**\n")

out=outfile("/home/zqliu216/DM_template61/AnaFault_201609/FPG_logfile/op.auto" "w")

foreach(InstName InstTable

printf("%s=>%L" InstName InstTable[InstName])

cellName=car(InstTable[InstName])

if(cellName=="pmos4" ||cellName=="pfet"|| cellName=="nfet"||cellName=="nmos4" ||

cellName=="pfet33"|| cellName=="nfet33"

then

println(" is a mosfet")

gm=OP(InstName "gm")

gmb=OP(InstName "gmbs")

gds=OP(InstName "gds")

printf("gm_%s\t %1.4e\n" InstName , gm)

if(gmb!=nil then

printf("gmb_%s\t %1.4e\n" InstName , gmb)

); End if

printf("gds_%s\t %1.4e\n" InstName , gds)

Page 293: Design and verification approaches for reliability and

280

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;print to file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fprintf(out "gm_%s\t %1.4e\n" InstName , gm)

if(gmb!=nil then

fprintf(out "gmb_%s\t %1.4e\n" InstName , gmb)

); End if

fprintf(out "gds_%s\t %1.4e\n" InstName , gds)

);if

if(cellName=="res"

then

println("is a res")

res=1/OP(InstName "res")

printf("%s\t %1.4e\n" InstName , res)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;print to file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fprintf(out "%s\t %1.4e\n" InstName , res)

); End if

); end for

close(out)

exit()

6. SCCsubNetlistForOneSCC

#! /usr/bin/perl

use strict;

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

#=====================How to

use================================================================

==============

#

# 1. At the directory where foder "FPG16" is located, open a terminal;

# 2. Run the command "perl ./FPG16/FPG/SCCsubNetlistForOneSCC.pl SCC5". It will

generate the sub-netlist for SCC5

#

# input file list:

# "./FPG_logfile/SCC_inst.txt" Reqired file contains the instances for each SCC

# created by excuate "perl ./FPG16/FPG/findSCC.pl -d 1"

# "./FPG_logfile/SCC_inputs.txt" Reqired file contains the inputs of each SCC,

Page 294: Design and verification approaches for reliability and

281

# created by excuate "perl ./FPG16/FPG/findSCC.pl -d 1"

# "./example.scs" Reqired file contains the netlist of the desired circuit,

# created by using ADE-->simulation-->Netlist-->Create

# "./spectre.dc"

# output file list:

# "./FPG_logfile/subNetlist/input_$input2.scs" contains the sub-netlist for a

given SCC

#=================================================================

============================================

my $input1 = $ARGV[0];

my $input2 = $ARGV[1];

if ($input1 eq "")

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input1 to stand for DUT netlist***\n";

print "***E.g. ==> perl ./FPG16/FPG/SCCsubNetlistForOneSCC.pl example.scs SCC1

<===\n\n";

exit(1);

elsif ($input2 eq "")

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input2 to stand for SCC name***\n";

print "***E.g. ==> perl ./FPG16/FPG/SCCsubNetlistForOneSCC.pl example.scs SCC1

<===\n\n";

exit(1);

else

#print STDOUT "$input1\n";

###########################################################################

#####

#voltage source to be inserted

###########################################################################

#####

my $VDD="Vdd1 (VDD 0) vsource dc=1.2 type=dc\n";

my $VSS="Vss1 (0 VSS) vsource dc=1.2 type=dc\n";

Page 295: Design and verification approaches for reliability and

282

###########################################################################

#####

#obtain the instance for each SCC

###########################################################################

#####

open( SCCInst, "./FPG_logfile/SCC_inst.txt") || die "Can't open SCC_Inst.txt: $!";

my @SCCInst=<SCCInst>;

close(SCCInst);

tie my %SCCInst, 'Tie::IxHash';

foreach (@SCCInst)

if(/^(SCC\d+)=>(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInst$1=\@temp;

=pod

print "\n**SCC instance list**\n";

foreach (keys %SCCInst)

print "$_==> @$SCCInst$_\n";

print "current SCC is: $input1 @$SCCInst$input1\n\n";

=cut

###########################################################################

#####

#obtain the inputs for each SCC

###########################################################################

#####

open( SCCInputs, "./FPG_logfile/SCC_inputs.txt") || die "Can't open SCC_Inputs.txt: $!";

my @SCCInputs=<SCCInputs>;

close(SCCInputs);

tie my %SCCInputs, 'Tie::IxHash';

foreach (@SCCInputs)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInputs$1=\@temp;

=pod

print "\n**SCC inputs list**\n";

Page 296: Design and verification approaches for reliability and

283

foreach (keys %SCCInputs)

print "$_==> @$SCCInputs$_\n";

=cut

###########################################################################

#####

#obtain the input.scs for each SCC

###########################################################################

#####

open( Netlist, "./$input1") || die "Can't open $input1: $!";

my $start1="\/\/ Generated for: spectre";

my $end1="\/\/ View name: schematic";

my @data1;

my $start2='simulatorOptions';

my $end2='saveOptions';

my @data2;

my @data3;

while (<Netlist>)

if (/^$start1/ .. /$end1/)

push @data1, $_;

next;

elsif (/^$start2/ .. /$end2/)

push @data2, $_;

next;

else

push @data3, $_;

close(Netlist);

=pod

print "\n!!!!!!!!!!!!!!!!!!!!date1 is !!!!!!!!!!!!!!!!\n";

print @data1;

print "\n!!!!!!!!!!!!!!!!!!!!date2 is !!!!!!!!!!!!!!!!\n";

print @data2;

print "\n!!!!!!!!!!!!!!!!!!!!date3 is !!!!!!!!!!!!!!!!\n";

Page 297: Design and verification approaches for reliability and

284

#print @data3;

=cut

my $inst_name;

tie my %netlist_hash, 'Tie::IxHash';

for (my $i=0;$i<@data3;$i++)

$_=$data3[$i];

if(/^(\w+\d+)\s+\((.*)\)\s+(\w+)\s/)

$inst_name=$1;

$netlist_hash$1=$data3[$i];

if(/\\\n$/)# the backslash at the end of line means the next line is the continued

contents

$netlist_hash$inst_name=join('', $netlist_hash$inst_name, $data3[$i+1]);

foreach (keys %netlist_hash)

#print "$_=>$netlist_hash$_\n";

print "$input2\_inst => [@$SCCInst$input2]\n";

if(exists $SCCInputs$input2)

print "$input2\_input => [@$SCCInputs$input2]\n";

###########################################################################

#####

#obtain DC OP for inputs of current SCC

###########################################################################

#####

open( OP, "./spectre.dc") || die "Can't open spectre.dc.: $!";

my @OP=<OP>;

close(OP);

tie my %SCCInputs_OP, 'Tie::IxHash';

foreach my $net (@$SCCInputs$input2)

my @temp=grep /^$net\s/, @OP;

my @tt=split(/\s+/,$temp[0]);

$SCCInputs_OP$net=$tt[1];

Page 298: Design and verification approaches for reliability and

285

foreach my $net (keys %SCCInputs_OP)

print "$net\_DC==> $SCCInputs_OP$net\n";

###########################################################################

#####

#print sub-netlist to file

###########################################################################

#####

open( OUTPUT, ">./FPG_logfile/subNetlist/input_$input2.scs") || die "Can't open myfile:

$!";##'>' means write only, it will clear and rewrite the file.

print OUTPUT @data1;

print OUTPUT $VDD;

print OUTPUT $VSS;

foreach my $net (@$SCCInputs$input2)

#print "$net=>";

my $source="V$net ($net 0) vsource dc=$SCCInputs_OP$net type=dc\n";

##print $source;

print OUTPUT $source;

foreach my $inst (@$SCCInst$input2)

#print "$inst=>";

##print $netlist_hash$inst;

print OUTPUT $netlist_hash$inst;

print OUTPUT @data2;

close( OUTPUT );

print "The sub-netlist for $input2 has been created!

=>./FPG_logfile/subNetlist/input_$input2.scs\n\n";

7. SCCsubNetlistForTwoSCC.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

Page 299: Design and verification approaches for reliability and

286

require './FPG16/FPG/findPath.pl';

#=====================How to

use================================================================

==============

#

# 1. At the directory where foder "FPG16" is located, open a terminal;

# 2. Run the command "perl ./FPG16/FPG/SCCsubNetlistForTwoSCC.pl example.scs

SCC10 SCC11". It will generate the sub-netlist for SCC5

#

# input file list:

# "./FPG_logfile/SCC_inst.txt" Reqired file contains the instances for each SCC

# created by excuate "perl ./FPG16/FPG/findSCC.pl -d 1"

# "./FPG_logfile/SCC_inputs.txt" Reqired file contains the inputs of each SCC,

# created by excuate "perl ./FPG16/FPG/findSCC.pl -d 1"

# "./example.scs" Reqired file contains the netlist of the desired circuit,

# created by using ADE-->simulation-->Netlist-->Create

# "./spectre.dc"

# output file list:

# "./FPG_logfile/subNetlist/input_$input2.scs" contains the sub-netlist for a

given SCC

#=================================================================

============================================

my $input1 = $ARGV[0];

my $input2 = $ARGV[1];

my $input3 = $ARGV[2];

if ($input1 eq "")

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input1 to stand for DUT netlist***\n";

print "***E.g. ==>perl ./FPG16/FPG/SCCsubNetlistForTwoSCC.pl example.scs SCC1

SCC2<===\n\n";

exit(1);

elsif (($input2 eq "") or ($input3 eq ""))

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input2 to stand for SCC name***\n";

print "***E.g. ==> perl ./FPG16/FPG/SCCsubNetlistForTwoSCC.pl example.scs SCC1

SCC2<===\n\n";

exit(1);

Page 300: Design and verification approaches for reliability and

287

else

# print STDOUT "$input1\n";

###########################################################################

#####

#voltage source to be inserted

###########################################################################

#####

my $VDD="Vdd1 (VDD 0) vsource dc=1.2 type=dc\n";

my $VSS="Vss1 (0 VSS) vsource dc=1.2 type=dc\n";

###########################################################################

#####

#obtain the instance for each SCC

###########################################################################

#####

open( SCCInst, "./FPG_logfile/SCC_inst.txt") || die "Can't open SCC_Inst.txt: $!";

my @SCCInst=<SCCInst>;

close(SCCInst);

tie my %SCCInst, 'Tie::IxHash';

foreach (@SCCInst)

if(/^(SCC\d+)=>(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInst$1=\@temp;

=pod

print "\n**SCC instance list**\n";

foreach (keys %SCCInst)

print "$_==> @$SCCInst$_\n";

print "current SCC is: $input1 @$SCCInst$input1\n\n";

=cut

###########################################################################

#####

#obtain the inputs for each SCC

###########################################################################

#####

Page 301: Design and verification approaches for reliability and

288

open( SCCInputs, "./FPG_logfile/SCC_inputs.txt") || die "Can't open SCC_Inputs.txt: $!";

my @SCCInputs=<SCCInputs>;

close(SCCInputs);

tie my %SCCInputs, 'Tie::IxHash';

foreach (@SCCInputs)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInputs$1=\@temp;

=pod

print "\n**SCC inputs list**\n";

foreach (keys %SCCInputs)

print "$_==> @$SCCInputs$_\n";

=cut

###########################################################################

#####

#obtain the outputs for each SCC

###########################################################################

#####

open( SCCOutputs, "./FPG_logfile/SCC_outputs.txt") || die "Can't open SCC_Outputs.txt:

$!";

my @SCCOutputs=<SCCOutputs>;

close(SCCOutputs);

tie my %SCCOutputs, 'Tie::IxHash';

foreach (@SCCOutputs)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCOutputs$1=\@temp;

=pod

print "\n**SCC outputs list**\n";

foreach (keys %SCCOutputs)

print "$_==> @$SCCOutputs$_\n";

Page 302: Design and verification approaches for reliability and

289

=cut

###########################################################################

#####

#obtain the simple standard graph

###########################################################################

#####

open( DAG, "./FPG_logfile/standard_dag.txt") || die "Can't open standard_dag.txt: $!";

my @dag=<DAG>;

close(DAG);

tie my %dag, 'Tie::IxHash';

tie my %graph, 'Tie::IxHash';

foreach my $edge (@dag)

my @temp=split(/\s+/, $edge);

$graph$temp[0]=[] if(not exists $graph$temp[0]);

$graph$temp[0]=[@$graph$temp[0],$temp[1]];

=pod

print "\n**Simple standard graph**\n";

foreach (keys %graph)

print "$_=> @$graph$_\n";

=cut

##############################

#run the find_path function

#written in findPath.pl file

##############################

######################

#join the path to hash

######################

my $i=0;

tie my %path, 'Tie::IxHash';

my @path_begin;

push @path_begin, $input2;

my $path_end=$input3;

##print "path_begin=@path_begin\n";

##print "path_end=$path_end\n";

foreach my $path_begin(@path_begin)

my $routes = find_paths($path_begin, $path_end, \%graph);

Page 303: Design and verification approaches for reliability and

290

#my $n=@$routes;

#print $n;

foreach my $pt (@$routes)

my $temp="path";

my $p=join("",($temp, $i++));

#print $p," => ";

#print "@$pt\n";

$path$p=[@$pt];

my @SCC_list;

my @input_list;

my @output_list;

##print "\n**path list**\n";

foreach (keys %path)

##print "$_=>@$path$_\n";

foreach my $SCC (@$path$_)

if( !grep(/^$SCC$/,@SCC_list))

push @SCC_list,$SCC;

push @input_list, @$SCCInputs$SCC if(exists

$SCCInputs$SCC);

push @output_list, @$SCCOutputs$SCC if(exists

$SCCOutputs$SCC)

##print "SCC list=> @SCC_list\n";

##print "outputs=>@output_list\n";

##print "inputs=>@input_list\n";

my %seen=();

@output_list= grep!$seen$_++ @output_list;#delete duplicated data

@input_list =grep!$seen$_++ @input_list;

##print "\noutputs=>@output_list\n";

##print "inputs=>@input_list\n";

###########################################################################

#####

#obtain the input.scs for the whole circuit

Page 304: Design and verification approaches for reliability and

291

###########################################################################

#####

open( Netlist, "./$input1") || die "Can't open $input1: $!";

my $start1="\/\/ Generated for: spectre";

my $end1="\/\/ View name: schematic";

my @data1;

my $start2='simulatorOptions';

my $end2='saveOptions';

my @data2;

my @data3;

while (<Netlist>)

if (/^$start1/ .. /$end1/)

push @data1, $_;

next;

elsif (/^$start2/ .. /$end2/)

push @data2, $_;

next;

else

push @data3, $_;

close(Netlist);

=pod

print "\n!!!!!!!!!!!!!!!!!!!!date1 is !!!!!!!!!!!!!!!!\n";

print @data1;

print "\n!!!!!!!!!!!!!!!!!!!!date2 is !!!!!!!!!!!!!!!!\n";

print @data2;

print "\n!!!!!!!!!!!!!!!!!!!!date3 is !!!!!!!!!!!!!!!!\n";

#print @data3;

=cut

my $inst_name;

tie my %netlist_hash, 'Tie::IxHash';

for (my $i=0;$i<@data3;$i++)

$_=$data3[$i];

if(/^(\w+\d+)\s+\((.*)\)\s+(\w+)\s/)

$inst_name=$1;

Page 305: Design and verification approaches for reliability and

292

$netlist_hash$1=$data3[$i];

if(/\\\n$/)# the backslash at the end of line means the next line is the continued

contents

$netlist_hash$inst_name=join('', $netlist_hash$inst_name, $data3[$i+1]);

foreach (keys %netlist_hash)

#print "$_=>$netlist_hash$_\n";

##print "\n**parent SCC**\n";

##print "$input2\_inst => [@$SCCInst$input2]\n";

if(exists $SCCInputs$input2)

##print "$input2\_input => [@$SCCInputs$input2]\n";

else

##print "$input2 is a sink SCC!\n";

###########################################################################

#####

#obtain DC OP for inputs of current SCC

###########################################################################

#####

open( OP, "./spectre.dc") || die "Can't open spectre.dc.: $!";

my @OP=<OP>;

close(OP);

my %input_list_OP;

foreach my $net (@input_list)

my @temp=grep /^$net\s/, @OP;

my @tt=split(/\s+/,$temp[0]);

$input_list_OP$net=$tt[1];

##print "$net\_DC==> $input_list_OP$net\n";

close(OP);

Page 306: Design and verification approaches for reliability and

293

###########################################################################

#####

#print sub-netlist to file

###########################################################################

#####

print "\n\n**print sub-netlist to file**\n";

open( OUTPUT, ">./FPG_logfile/subNetlist/input_$input2\_$input3.scs") || die "Can't open

input_$input2\_$input3.scs: $!";##'>' means write only, it will clear and rewrite the file.

print OUTPUT @data1;

print OUTPUT $VDD;

print OUTPUT $VSS;

foreach my $net (@input_list)

my $source="V$net ($net 0) vsource dc=$input_list_OP$net type=dc\n";

print OUTPUT $source;

#print "$net=>";

##print " Added => $source";

foreach my $SCC (@SCC_list)

foreach my $inst (@$SCCInst$SCC)

#print "$inst=>";

##print $netlist_hash$inst;

print OUTPUT $netlist_hash$inst;

print OUTPUT @data2;

close( OUTPUT );

print "The sub-netlist for $input2\_$input3 has been created!

=>./FPG_logfile/subNetlist/input_$input2\_$input3.scs\n\n";

8. subNetlistForAllSCC.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

Page 307: Design and verification approaches for reliability and

294

require './FPG16/FPG/findPath.pl';

require './FPG16/FPG/findPathToSink.pl';

#=====================How to

use================================================================

==============

#

# 1. At the directory where foder "FPG16" is located, open a terminal;

# 2. Run the command "perl ./FPG16/FPG/subNetlistForAllSCC.pl example.scs". It will

generate the sub-netlist for all SCCs

#

# input file list:

# "./FPG_logfile/SCC_inst.txt" Reqired file contains the instances for each SCC

# created by excuate "perl ./FPG16/FPG/findSCC.pl -d 1"

# "./example.scs" Reqired file contains the netlist of the desired circuit,

# created by using ADE-->simulation-->Netlist-->Create

# "./FPG_logfile/standard_dag.txt"

# "./FPG_logfile/SCC_inputs.txt"

# "./FPG_logfile/SCC_outputs.txt"

# "./FPG16/sinkSCC_OP.txt" Desired OP at sink SCC

# output file list:

# "./FPG_logfile/subNetlist/*.scs" contains the sub-netlist for all SCCs

#=================================================================

============================================

my $input1 = $ARGV[0];

if ($input1 eq "")

print "\n***Usage:Generate netlist file for certain SCC***\n";

print "***Need an input1 to stand for DUT netlist***\n";

print "***E.g. ==> perl ./FPG16/FPG/subNetlistForAllSCC.pl example.scs<===\n\n";

exit(1);

###########################################################################

#####

#obtain the instance for each SCC

###########################################################################

#####

open( SCCInst, "./FPG_logfile/SCC_inst.txt") || die "Can't open SCC_Inst.txt: $!";

my @SCCInst=<SCCInst>;

Page 308: Design and verification approaches for reliability and

295

close(SCCInst);

tie my %SCCInst, 'Tie::IxHash';

foreach (@SCCInst)

if(/^(SCC\d+)=>(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInst$1=\@temp;

print "\n**SCC instance list**\n";

foreach (keys %SCCInst)

print "$_==> @$SCCInst$_\n";

#unlink glob "'./FPG_logfile/subNetlist/*.*'";

if (! -d './FPG_logfile/subNetlist')

system('mkdir -p ./FPG_logfile/subNetlist')

else

system('rm -r ./FPG_logfile/subNetlist/*');

print "Simulating the fault-free circuit...";

system("spectre .\/$input1 >.\/FPG_logfile\/spectre_faultFree_Circuit.log");

print "Simulation finished...";

foreach my $SCCi (keys %SCCInst)

#print "!!!!$SCCi==> @$SCCInst$SCCi\n";

if (@$SCCInst$SCCi)

system("perl ./FPG16/FPG/SCCsubNetlistForOneSCC.pl $input1 $SCCi");

###########################################################################

#####

#obtain the standard dat

Page 309: Design and verification approaches for reliability and

296

###########################################################################

#####

open( DAG, "./FPG_logfile/standard_dag.txt") || die "Can't open standard_dag.txt: $!";

my @dag=<DAG>;

close(DAG);

print @dag;

tie my %graph, 'Tie::IxHash';

foreach my $edge (@dag)

my @temp=split(/\s+/, $edge);

$graph$temp[0]=[] if(not exists $graph$temp[0]);

$graph$temp[0]=[@$graph$temp[0],$temp[1]];

foreach (keys %graph)

print "$_=> @$graph$_\n";

foreach my $e (@dag)

print "For edge: $e";

system("perl ./FPG16/FPG/SCCsubNetlistForTwoSCC.pl $input1 $e");

=pod

###########################################################################

#####

#obtain the inputs for each SCC

###########################################################################

#####

open( SCCInputs, "./FPG_logfile/SCC_inputs.txt") || die "Can't open SCC_Inputs.txt: $!";

my @SCCInputs=<SCCInputs>;

close(SCCInputs);

tie my %SCCInputs, 'Tie::IxHash';

foreach (@SCCInputs)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCInputs$1=\@temp;

Page 310: Design and verification approaches for reliability and

297

###########################################################################

#####

#obtain the outputs for each SCC

###########################################################################

#####

open( SCCOutputs, "./FPG_logfile/SCC_outputs.txt") || die "Can't open SCC_Outputs.txt:

$!";

my @SCCOutputs=<SCCOutputs>;

close(SCCOutputs);

tie my %SCCOutputs, 'Tie::IxHash';

my @SCC_list;

foreach (@SCCOutputs)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SCCOutputs$1=\@temp;

push @SCC_list,$1;

###########################################################################

#####

#obtain the sink SCC

###########################################################################

#####

open( SINK, "./FPG16/sinkSCC_OP.txt") || die "Can't open sinkSCC_OP.txt: $!";

my @SINK=<SINK>;

close(SINK);

tie my %SINK, 'Tie::IxHash';

my @sinkSCC_list;

my @sourceSCC_list;

foreach (@SINK)

if(/^(SCC\d+)\s+(.*)/)

#print $1,"\t",$2,"\n";

my @temp=split(/\s+/,$2);

$SINK$1=\@temp;

push @sinkSCC_list,$1;

Page 311: Design and verification approaches for reliability and

298

print "\n**sink SCC list**\n";

foreach (keys %SINK)

print "$_==> @$SINK$_\n";

for my $SCC (@SCC_list)

if(!exists $SCCInputs$SCC)

print "$SCC is a source SCC!\n";

push @sourceSCC_list, $SCC;

##############################

#run the find_path function

#written in findPath.pl file

##############################

######################

#join the path to hash

######################

tie my %path, 'Tie::IxHash';

my $i=0;

tie my %path_endpoints, 'Tie::IxHash';

foreach my $path_begin(@SCC_list)

foreach my $path_end(@sinkSCC_list)

my $routes = find_paths($path_begin, $path_end, \%graph);

#my $n=@$routes;

#print $n;

if(@$routes)

print "$path_begin=>$path_end !!!\n";

$path_endpoints$path_begin=[] if(!exists

$path_endpoints$path_begin);

$path_endpoints$path_begin=[@$path_endpoints$path_begin,$path_end];

foreach my $pt (@$routes)

my $temp="path";

my $p=join("",($temp, $i++));

Page 312: Design and verification approaches for reliability and

299

#print $p," => ";

#print "@$pt\n";

$path$p=[@$pt];

find_path_to_sink(\@SCC_list,\@sinkSCC_list);

=cut

9. main.pl

#! /usr/bin/perl

use strict;

use warnings;

use lib './FPG16/FPG/package/Tie-IxHash-1.23/lib';

use Tie::IxHash; ### Hashes are not ordered, but as usual, CPAN offers a solution:

Tie::IxHash

#use lib './FPG16/FPG/package/Time-HiRes-1.9739/blib/lib';

#use Time::HiRes;

#=====================How to

use================================================================

==============

# 1. run "createNetlist_hier.il" following the instruction, you will get the netlist:

./FPG_logfile/hier.netlist

# 2. At the directory where foder "FPG16" is located, open a terminal;

# Run the command "perl ./FPG16/FPG/main.pl oceanScript_TargedCircuit.ocn"

#

# input file list:

# "./FPG_logfile/hier.netlist" Reqired file contains the netlist that we want to

flatten,

# created by excuate "createNetlist_hier.il"

# output file list:

# "./FPG_logfile/fpg.txt" contains the fault propagation graph

# "./FPG_logfile/sg.txt" contains the sensitivity graph

#=================================================================

============================================

my $input1=$ARGV[0];

if ($input1 eq "")

print "\nError Command!!\n";

print "**Usage Instruction**\n";

Page 313: Design and verification approaches for reliability and

300

print "Please specify the ocean script to simulate the DC operating points of target circuit

\n";

print "Example: perl ./FPG16/FPG/main.pl oceanScript_TargedCircuit.ocn\n\n";

exit(1);

my $ocean;

my $DUT_name;

if( $input1=~/(.*)\.ocn$/)

$DUT_name=$1;

$ocean=$input1; #determine wether to print out information

else

print "Error parameter!\n";

print "File name should end with \"\.ocn\"\n";

exit(0);

my $start_time=time();

print "input fie is: $ocean\n";

if (! -d './FPG_logfile')

system('mkdir -p ./FPG_logfile')

open FILEA, "./$ocean" || die "Cannot open $ocean.ocn: $!";

open FILEB, "./FPG16/FPG/obtainOP_partII.ocn" || die "Cannot open obtainOP_partII.ocn:

$!";

open FILEC, ">./FPG16/FPG/obtainOP.ocn" || die "Cannot open obtainOP.ocn: $!";

print FILEC "#! /bin/sh -exec awd -ocean \"\$\@\"\n\n";

print FILEC <FILEA>;

print FILEC <FILEB>;

close(FILEA);

close(FILEB);

close(FILEC);

####open the net_from_cadence that generated from Cadence.

open( MYFILE, "./FPG_logfile/hier.netlist") || die "Can't open hier.netlist: $!";

my @netlist_from_cadence=<MYFILE>;

print @netlist_from_cadence;

close(MYFILE);

Page 314: Design and verification approaches for reliability and

301

my @netlist_usf=grep /^\w+\d/, @netlist_from_cadence;

#print @netlist_usf;

tie my %instance_prop, 'Tie::IxHash';

for (my $i=0;$i<@netlist_usf;$i++)

$_=$netlist_usf[$i];

if(/^(\w+\d+)\s+\(\"(.*)\"\)\s+(\w+)\s/)

my $inst_name=$1;

my $inst_prop=$3;

print "$inst_name\t$inst_prop\t";

if($inst_prop=~/^pmos|^pfet|^nmos|^nfet/) #means this is a coms transistor

print "is a mos\n";

$instance_prop$inst_name=$inst_prop;

elsif($inst_prop=~/^res/) #means this is a resistor

print "is a res\n";

$instance_prop$inst_name=$inst_prop;

####################print the instance name to a file

open(MYFILE, ">./FPG_logfile/inst_list.txt") || die "Cannot open inst_list.txt: $!";

print "\n**instance list**\n";

foreach (keys %instance_prop)

print "$_\t $instance_prop$_\n";

print MYFILE "$_\t $instance_prop$_\n";

close(MYFILE);

print "\n\nDC simultion is running ...\n";

system("ocean -restore ./FPG16/FPG/obtainOP.ocn >./FPG_logfile/logfile_obtainOP.txt");

print "DC simultion is finished \n";

print "Obtain DC operating points ...\n";

print "Finished\n";

Page 315: Design and verification approaches for reliability and

302

print "createFPG...\n";

system("perl ./FPG16/FPG/createFPG.pl");

print "Finished\n";

print "create_subSG...\n";

system("perl ./FPG16/FPG/create_subSG.pl");

print "Finished\n";

print "subNetlistForAllSCC...\n";

system("perl ./FPG16/FPG/subNetlistForAllSCC.pl $DUT_name.scs");

print "Finished\n";

system('rm ./example.ahdlSimDB -r');

system('rm ./example.raw -r');

my $finish_time=time();

my $timeused=$finish_time-$start_time;

#my $dd=Time::HiRes::gettimeofday();

#print "!!!!$dd\n";

print "start_time: $start_time\n";

print "finish_time: $finish_time\n";

print "Used time: $timeused\n";

=cut

10. main.py

#!/usr/bin/python

# coding: utf-8

import re

import os

import time #for calculating the used time

#os.system('python ./FPG16/FaultSim/simFaultImpacts.py') #simulate SCC by SCC, and

fault impact for SCCs

#os.system('python ./FPG16/FaultSim/gainCalcul.py ')#calculate Gain between SCC and FC

(SCC by SCC)

os.system('python ./FPG16/FaultSim/simFaultImpacts_whole_circuit.py')#simulate whole

circuit

Page 316: Design and verification approaches for reliability and

303

11. simFaultImpacts.py

#!/usr/bin/python

# coding: utf-8

#=====================How to

use================================================================

==============

## 0. Copy the place the folder "FaultSim" under you directory.

#

# required files before running

# (1). make sure the netlist for each SCC is generated

# in this example it is genereated byand placed under './subNetlist'

# (2). "./SCC_outputs.txt" the output nodes (or observation points set) for each SCC

# (3). "./SCC_inputs.txt" the input nodes (or observation points set) for each SCC

#

#

# 1. At the directory where foder "FaultSim" is located, open a terminal;

# 2. Run the command "python ./FaultSim/final_flattened.py"

# If you want to suppress the spectre output logs in terminal, uncomment the

suppress_output variable below,

# else leave it as empty string

# 3. A new folder called simresults will be created in the python directory; netlists and

outputs are stored here

# 4. T1_dg_input.scs indicates the netlist for a short between d(drain) and g(gate) of

transistor T1

# 5. T1_d_input.scs indicates the netlist for an open at d(drain) of transistor T1

# 6. Short is implemented by a resistor r=10 and open by a resistor r=1G ohms

#

#

# make sure the OP in SCC_output.txt is what you would like to observe and generate fault

impacts for!!

#=================================================================

============================================

import re

import os

import time #for calculating the used time

from numpy import * #for array and matrix operation,like taking inversion of a matrix

import sys

from inspect import currentframe, getframeinfo #for detecting and printing out error

information.

#=================================================================

==================================

Page 317: Design and verification approaches for reliability and

304

#modification is needed for this section

#=================================================================

==================================

MOP_DR_array=array([2.532e-3*3,100.6e-3*3, 37.83e-3*3,24.36e-3*3])

#MOP_DR=MOP_DR_array[0]

#gain2vout=122.47

#ignore the spectre simulation and open the previous result

ignore_simulation=1 #if set to be '1', will open the previous simulated result

simul_trivial_circuit=0

MyVDD='VDD' #define the power supply node of the netlist

MyVSS='VSS' #define the ground node of the netlist

T1=0

T2=0

T_rest=0

#=================================================================

==================================

#=================================================================

==================================

###########################################################################

#########################

#specify your netlists and work directory

###########################################################################

#########################

currentdir=os.getcwd()

currentdir='/home/zqliu216/DM_template61/AnaFault_201609'

faultFreeNetlist_workdir=currentdir+'/FPG_logfile/subNetlist' #define the fault-free circuit

netlist for SCC you would like to simulate

faultyNetlist_workdir=currentdir+'/FPG_logfile/FaultSim/simresultsSCC' #store the

modified faulty circuit netlist and their DC simulation results

#os.system("mkdir -p %s"%(faultyNetlist_workdir))

#if os.path.isfile(faultyNetlist_workdir): #if there are documents, delete them

# os.system("rm -r %s/*"%(faultyNetlist_workdir))

if(ignore_simulation==0):

if not os.path.exists(faultyNetlist_workdir):

os.makedirs(faultyNetlist_workdir)

elif os.path.isfile(faultyNetlist_workdir):#if there are documents, delete them

os.system("rm -r %s/*"%(faultyNetlist_workdir))

###########################################################################

#########################

#specify your transitor and resistor master names here

Page 318: Design and verification approaches for reliability and

305

###########################################################################

#########################

mosfet_types= ['nfet33','pfet33','nfet','pfet','ami06N','ami06P']

resistor_types= ['res', 'resistor']

###########################################################################

#########################

#some simulation options

###########################################################################

#########################

suppress_output=''

# To avoid printing spectre output logs in terminal, uncomment the line below

suppress_output='>/dev/null'

# Extra commands to give to spectre. Leave as empty string

spectre_extracommands=''

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_outputs.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_outputs=

SCC_outputs_keys=[]

for i in range(len(contents)):

a=contents[i].split();

SCC_outputs[a[0]]= a[1:] #take items from 1:end in a list, like matlab a[1:end]

SCC_outputs_keys.append(a[0])

print "\n**SCC outputs**"

#for key,value in SCC_outputs.items():

# print "%s\t=> %s" %(key,value)

for key in SCC_outputs_keys:

print "%s\t=> %s" %(key,SCC_outputs[key])

###########################################################################

#########################

#read SCC nodes

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_nodes.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_nodes=

for i in range(len(contents)):

Page 319: Design and verification approaches for reliability and

306

a=contents[i].split();

SCC_nodes[a[0]]= a[1:] #take items from 1:end in a list, like matlab a[1:end]

print "\n**SCC nodes**"

for key in SCC_outputs_keys:

print "%s\t=> %s" %(key,SCC_nodes[key])

sourceSCC_virtual_input=

###########################################################################

#########################

#define a function to read data

###########################################################################

#########################

def readFile(filename,MOP,name):

f = open(filename,'r' )

dc=f.readlines()

f.close()

#########################

dc_str="".join(dc)

#print dc_str

outputs=[]

MOP_eff=[]

for i in range(len(MOP)):

v=re.search('^'+MOP[i]+r'\s+(.*)\n', dc_str, re.MULTILINE)

if v:

value=v.groups()[0]

value=float(value)

#print MOP[i],'==>',value

outputs.append(value)

MOP_eff.append(MOP[i])

else:

print '*error message*'

frameinfo = getframeinfo(currentframe())

print frameinfo.filename, 'line', frameinfo.lineno

exit (MOP[i]+' is not a valid node!')

print name,'\t:',MOP_eff,'=>',outputs

return outputs

###########################################################################

#########################

#define a function to simulate a short fault

###########################################################################

#########################

#def simulShortFault(f_string,str_inserts_short):

###########################################################################

#########################

#read output nodes of each SCC

Page 320: Design and verification approaches for reliability and

307

###########################################################################

#########################

start_time=time.time()

f = open(currentdir+'/FPG_logfile/SCC_outputs.txt', 'r')

SCC_outputs= f.readlines()

f.close()

SCC_outputs_keys=[]

SCC_outputs_hash=

outputs_SCC= # determine the SCC name that an output node belongs to

for i in range(len(SCC_outputs)):

a=SCC_outputs[i].split();

SCC_outputs_hash[a[0]]= a[1:] #take items from 1:end in a list, like matlab a[1:end]

SCC_outputs_keys.append(a[0])

for n in a[1:]:

outputs_SCC[n]=a[0]

###########################################################################

#########################

#read input nodes of each SCC

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_inputs.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_inputs=

SCC_inputs_keys=[]

for i in range(len(contents)):

a=contents[i].split();

SCC_inputs[a[0]]= a[1:]

SCC_inputs_keys.append(a[0])

###########################################################################

#########################

#define variables

###########################################################################

#########################

mos_num=0 # number of mosfet in the netlist

res_num=0 # number of resistor in the netlist

fault_tot=0 # number of faults based on 5-fault model

fault_sim=0 # number of faults that are simulated after combining the shorts with same

ending nodes

sim_time=0 # toltal simulation time

#=================================================================

==================================

Page 321: Design and verification approaches for reliability and

308

MOP_Allshort=[] # store all the simulated short faults name

MOP_Allopen=[] # store all the simulated open faults name

DuplicateFault=[] # Duplicated faults when simulating SCC by SCC (faults same eding

nodes not detected in diff SCCs)

simulated_shorts_hash= # store all the potentioal simulated short faults name for each SCC

(based on 5-fault mode and after combining the shorts with same ending nodes)

str_inserts_added_hash= # store the short fault that need to added at the SCC output: Vo--

>vdd,Vo-->vss, When Vo is an casecode drain

WholeOpenName= # store all the true simulated open faults name for each SCC

WholeShortName= # store all the true simulated short faults name for each SCC

MOP_short= # store all the true simulated short faults impacts for each SCC

MOP_open= # store all the true simulated open faults impacts for each SCC

#============================================================

=======================================

# this part is added 2017.0308 to store the fault impacts for all node

MOP_short_allnodes= # store all the true simulated short faults impacts of all nodes

for each SCC

MOP_open_allnodes= # store all the true simulated open faults impacts of all nodes

for each SCC

MOP_desired_allnodes=

#============================================================

=======================================

faultInstToNet=

#=================================================================

==================================#

faultList_short= #fault list (short name based)

faultList_open= #fault list (open name based)

SCC_Table= #store all the information for simulation of all SCCs

for SCCn in SCC_outputs_keys:

str_inserts_added_hash[SCCn]=()

simulated_shorts_hash[SCCn]=[]

SCC_Table[SCCn]=

WholeOpenName[SCCn]=[]

WholeShortName[SCCn]=[]

MOP_short[SCCn]=[]

MOP_open[SCCn]=[]

#============================================================

=======================================

# this part is added 2017.0308 to store the fault impacts for all node

MOP_short_allnodes[SCCn]=[]

MOP_open_allnodes[SCCn]=[]

MOP_desired_allnodes[SCCn]=[]

Page 322: Design and verification approaches for reliability and

309

#=================================================================

==================================

###########################################################################

#########################

# obtain the fault list fist based on 5-fault mode

# combine the shorts with same ending nodes

# For a SCC interconnection node Vi which will have potential short fault Vi->vdd or Vi-

>vss, only consider the fault in the source SCC

###########################################################################

#########################

for i in range(len(SCC_outputs)):

#for i in range(1):

#for i in [0]:

line=SCC_outputs[i].split()

print 'line==>',line

currentSCCName=line[0]

inputfile=faultFreeNetlist_workdir+'/input_'+currentSCCName+'.scs'

MOPi=line[1:]

#####################################################################

###############################

#simulate fault-free circuit

#obtain desired OP

#####################################################################

###############################

if(ignore_simulation==0):

os.chdir(faultFreeNetlist_workdir)

os.system("spectre "+inputfile+" %s %s"%(spectre_extracommands,

suppress_output))

os.system("cp %s/spectre.dc

%s/%s_spectre.dc"%(faultFreeNetlist_workdir,faultFreeNetlist_workdir,currentSCCName))

outputfile=faultFreeNetlist_workdir+'/%s_spectre.dc'%currentSCCName

MOP_desired=readFile(outputfile,MOPi,'MOP_Desired')

# this part is added on 2017.0308

SCCn=currentSCCName

allnodes_SCCn=SCC_nodes[SCCn]

data_allnodes=readFile(outputfile,allnodes_SCCn,'MOP_Desired')

MOP_desired_allnodes[SCCn].append(data_allnodes)

#####################################################################

###############################

#obtain fault-free netlist

#####################################################################

###############################

f = open(inputfile, 'r')

contents= f.readlines()

Page 323: Design and verification approaches for reliability and

310

f.close()

f_string = "".join(contents)

first_element=re.search(r'(^(\S+)\s\((.*?)\)\s(\S+))(.*\n)', f_string, re.MULTILINE)

entry=first_element.span()[0]

#########################put all the information of current SCC in one table

SCCi_Table= #store all the information for simulation of current SCC

SCCi_Table['MOP_desired']=MOP_desired

SCCi_Table['f_string']=f_string

SCCi_Table['entry']=entry

SCCi_Table['MOPi']=MOPi

SCC_Table[currentSCCName]=SCCi_Table

simulated_shorts=[]

simulated_opens=[]

mainckt_netlist=re.finditer(r'(^(\S+)\s\((.*?)\)\s(\S+))(.*\n)', f_string,

re.MULTILINE)

for element in mainckt_netlist:

start=element.span()[0]

inst_name=element.group(2)

nets=element.group(3).split()

cell_type=element.group(4)

if cell_type in mosfet_types:

mos_num += 1

drain=nets[0]

gate=nets[1]

source=nets[2]

body=nets[3]

str_inserts_shorts='R_%s_dg (%s %s) resistor r=10\n'

%(inst_name,drain,gate),\

'R_%s_gs (%s %s) resistor r=10\n'

%(inst_name,gate,source),\

'R_%s_sd (%s %s) resistor r=10\n'

%(inst_name,source,drain)

str_inserts_opens='R_%s_d (%s %s_op) resistor r=1G\n' %(inst_name,

drain, drain),\

'R_%s_s (%s %s_op) resistor r=1G\n'

%(inst_name, source, source)

fault_tot +=5

for each_short in str_inserts_shorts:

FullShortName=each_short.split()[0][2:]

sn=re.search(r'\((\S+)\s(\S+)\)',each_short)

if sn.group(1) != sn.group(2): # ignore the dioed connected

ShortNets=sn.group(1),sn.group(2)

Page 324: Design and verification approaches for reliability and

311

faultInstToNet[FullShortName]=sn.group(1)+'_'+sn.group(2)

#do not simulate the fault that one end is SCC input and another is

Vdd/Vss, #refer to its parent SCC output

if currentSCCName in SCC_inputs_keys:

##print SCC_inputs[currentSCCName]

##print source,MyVDD,MyVSS

if (gate in SCC_inputs[currentSCCName]) & ((source ==

MyVDD) | (source == MyVSS)):

##print '%s_gs: gate %s, source

%s!!!!!!!!!!!!!!!!!!!'%(inst_name,gate,source)

str_inserts_shorts='R_%s_dg (%s %s) resistor r=10\n'

%(inst_name,drain,gate),\

'R_%s_sd (%s %s) resistor

r=10\n' %(inst_name,source,drain)

DuplicateFault.append('%s_gs'%inst_name)

##print gate

for SCCn in SCC_outputs_keys: #refer to its parent

SCC output

temp=SCC_outputs_hash[SCCn]

if gate in temp:

##print SCCn,'==>',temp

str_inserts_added_hash[SCCn] +=

'R_%s_%s (%s %s) resistor r=10\n' %(gate,source,gate,source), #A single item tuple must

have a trailing comma, such as (d,).

elif (gate in SCC_inputs[currentSCCName]) & ((drain ==

MyVDD) | (drain == MyVSS)):

##print '%s_dg: gate %s, drain

%s!!!!!!!!!!!!!!!!!!!'%(inst_name,gate,drain)

str_inserts_shorts='R_%s_gs (%s %s) resistor r=10\n'

%(inst_name,gate,source),\

'R_%s_sd (%s %s) resistor

r=10\n' %(inst_name,source,drain)

DuplicateFault.append('%s_dg'%inst_name)

##print gate

for SCCn in SCC_outputs_keys: #refer to its parent

SCC output

temp=SCC_outputs_hash[SCCn]

if gate in temp:

##print SCCn,'==>',temp

str_inserts_added_hash[SCCn] +=

'R_%s_%s (%s %s) resistor r=10\n' %(gate,drain,gate,drain),#A single item tuple must have

a trailing comma, such as (d,).

for each_short in str_inserts_shorts:

Page 325: Design and verification approaches for reliability and

312

FullShortName=each_short.split()[0][2:]

sn=re.search(r'\((\S+)\s(\S+)\)',each_short)

if sn.group(1) != sn.group(2): # ignore the dioed connected

ShortNets=sn.group(1),sn.group(2)

if ShortNets in simulated_shorts or

tuple(reversed(ShortNets)) in simulated_shorts:

continue

simulated_shorts.append(ShortNets)

simulated_shorts_hash[currentSCCName]=simulated_shorts

for each_short in str_inserts_shorts:

FullShortName=each_short.split()[0][2:]

###############store the information needed for

simultion/modifying netlist for each short fault

fi_short=

fi_short['SCC']=currentSCCName

fi_short['str_insert']=each_short

faultList_short[FullShortName]=fi_short

for each_open in str_inserts_opens:

FullOpenName=each_open.split()[0][2:]

###############store the information needed for

simultion/modifying netlist for each open fault

fi_open=

fi_open['SCC']=currentSCCName

fi_open['str_insert']=each_open

fi_open['start']=start

faultList_open[FullOpenName]=fi_open

elif cell_type in resistor_types:

res_num +=1

fault_tot += 2

str_inserts_short='R_%s_short (%s %s) resistor r=10\n' %(inst_name,

nets[0], nets[1])

FullShortName=str_inserts_short.split()[0][2:]

###############store the information needed for

simultion/modifying netlist for each short fault

fi_short=

fi_short['SCC']=currentSCCName

fi_short['str_insert']=str_inserts_short

faultList_short[FullShortName]=fi_short

str_inserts_open='R_%s_open (%s %s_op) resistor r=1G\n'

%(inst_name, nets[0], nets[0])

FullOpenName=str_inserts_open.split()[0][2:]

Page 326: Design and verification approaches for reliability and

313

###############store the information needed for

simultion/modifying netlist for each Open fault

fi_open=

fi_open['SCC']=currentSCCName

fi_open['str_insert']=str_inserts_open

fi_open['start']=start

faultList_open[FullOpenName]=fi_open

###########################################################################

#######################

# For a SCC interconnection node Vi which will have potential short fault Vi->vdd or Vi-

>vss, only consider the fault in the source SCC

for SCCn in SCC_outputs_keys:

simulated_shorts=simulated_shorts_hash[SCCn]

#print str_inserts_added_hash[SCCn]

for each_short in str_inserts_added_hash[SCCn]:

sn=re.search(r'\((\S+)\s(\S+)\)',each_short)

ShortNets=sn.group(1),sn.group(2)

if ShortNets in simulated_shorts or tuple(reversed(ShortNets)) in

simulated_shorts:

continue

else:

FullShortName=sn.group(1)+'_'+sn.group(2)

###############store the information needed for

simultion/modifying netlist for each short fault

fi_short=

fi_short['SCC']=currentSCCName

fi_short['str_insert']=each_short

faultList_short[FullShortName]=fi_short

print FullShortName, each_short

print '\n**potential faults that needed to simulated at the SCC output: Vo-->vdd,Vo-->vss,

When Vo is an casecode drain**'

for SCCn in SCC_outputs_keys:

print str_inserts_added_hash[SCCn]

print '\n**do not simulate the fault that one end is SCC input and another is Vdd/Vss**'

print DuplicateFault

###########################################################################

#########################

#simulate open fault

###########################################################################

########################

print '\n**simulate open fault**'

simulated_opens=[]

for FullOpenName in sorted(faultList_open.keys()):

Page 327: Design and verification approaches for reliability and

314

fi_open=faultList_open[FullOpenName]

SCCn=fi_open['SCC']

##print '%s:\t[%s \'%s\']

%s'%(FullOpenName,fi_open['SCC'],fi_open['str_insert'].strip('\n'), fi_open['start'])

f_string=SCC_Table[SCCn]['f_string']

entry=SCC_Table[SCCn]['entry']

MOPi=SCC_Table[SCCn]['MOPi']

start=fi_open['start']

simulated_opens.append(FullOpenName)

on=re.search(r'\((\S+)\s(\S+)\)',fi_open['str_insert'])

OpenNet=on.group(1)

faultInstToNet[FullOpenName]=OpenNet

#print 'OpenNet=.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!',OpenNet

f_mod=re.sub(r'\b%s\b' %(OpenNet), r'%s_op' %(OpenNet),f_string[start:],

count=1)#\b Matches the empty string, but only at the beginning or end of a word. by doing

this, we can match the whole word, this is important!!!!'

f_string_mod=f_string[:start]+f_mod

if(ignore_simulation==0):

faulty=f_string_mod[:entry]+'\n'+fi_open['str_insert']+f_string_mod[entry:]

inputfile=faultyNetlist_workdir+'/'+FullOpenName+'_input.scs'

os.system("touch %s"%(inputfile))

fnew = open(inputfile, 'w')

fnew.write(faulty)

fnew.close()

if simul_trivial_circuit==0:

T2_start=time.time()

os.system("spectre

/home/zqliu216/DM_template61/AnaFault_201609/oneVdc.scs %s

%s"%(spectre_extracommands, suppress_output))

T2+=time.time()-T2_start

os.chdir(faultyNetlist_workdir)

sim_time_start=time.time()

os.system("spectre "+inputfile+" %s %s"%(spectre_extracommands,

suppress_output))

sim_time_end=time.time()

sim_time += sim_time_end-sim_time_start

os.system("cp %s/spectre.dc

%s/%s_spectre.dc"%(faultyNetlist_workdir,faultyNetlist_workdir,FullOpenName))

#########################

#read DC data

outputfile=''

if(ignore_simulation==0):

outputfile=faultyNetlist_workdir+'/spectre.dc'

else:

outputfile=faultyNetlist_workdir+'/%s_spectre.dc' %FullOpenName

Page 328: Design and verification approaches for reliability and

315

data=readFile(outputfile,MOPi,FullOpenName)

MOP_Allopen.append(data)

MOP_open[SCCn].append(data)

fault_sim += 1

WholeOpenName[SCCn]=WholeOpenName[SCCn]+[FullOpenName]

# this part is added on 2017.0308

allnodes_SCCn=SCC_nodes[SCCn]

data_allnodes=readFile(outputfile,allnodes_SCCn,FullOpenName)

MOP_open_allnodes[SCCn].append(data_allnodes)

###########################################################################

#########################

#simulate short fault

###########################################################################

########################

print '\n**simulate short fault**'

###############################

#read the DAG

###############################

filename=currentdir+'/FPG_logfile/standard_dag.txt'

f=open(filename,'r')

dag_contents=f.readlines()

f.close()

for i in range(len(dag_contents)):

a=dag_contents[i].split();

combineSCC=a[0]+'_'+a[1]

#print a[0],a[1],combineSCC

inputfile=faultFreeNetlist_workdir+'/input_'+combineSCC+'.scs'

#print 'inputfile=.',inputfile

###############################

#obtain fault-free netlist

###############################

f = open(inputfile, 'r')

contents= f.readlines()

f.close()

f_string = "".join(contents)

first_element=re.search(r'(^(\S+)\s\((.*?)\)\s(\S+))(.*\n)', f_string, re.MULTILINE)

entry=first_element.span()[0]

#########################put all the information of current SCC in one table

SCCi_Table= #store all the information for simulation of current SCC

SCCi_Table['f_string']=f_string

SCCi_Table['entry']=entry

SCC_Table[combineSCC]=SCCi_Table

Page 329: Design and verification approaches for reliability and

316

###############################

#read the SCC_path_endpoints

###############################

filename=currentdir+'/FPG_logfile/SCC_path_endpoints.txt'

f=open(filename,'r')

path_contents=f.readlines()

f.close()

SCC_path_endpoints=

for i in range(len(path_contents)):

a=path_contents[i].split();

print a[0],'=>',a[1:]

SCC_path_endpoints[a[0]]=a[1:]

simulated_shorts=[]

for FullShortName in sorted(faultList_short.keys()):

fi_short=faultList_short[FullShortName]

SCCn=fi_short['SCC']

##print '%s:\t[%s \'%s\']'%(FullShortName,SCCn,fi_short['str_insert'].strip('\n'))

f_string=SCC_Table[SCCn]['f_string']

entry=SCC_Table[SCCn]['entry']

MOPi=SCC_Table[SCCn]['MOPi']

sn=re.search(r'\((\S+)\s(\S+)\)',fi_short['str_insert'])

if sn.group(1) != sn.group(2): # ignore the dioed connected

ShortNets=sn.group(1),sn.group(2)

#print 'ShortNets=.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!',ShortNets

if ShortNets in simulated_shorts or tuple(reversed(ShortNets)) in

simulated_shorts:

continue

simulated_shorts.append(ShortNets)

if SCCn in SCC_inputs_keys:

#print '\t!!SCC_inputs[SCCn]=',SCC_inputs[SCCn],

print '\tfalut end points=',sn.group(1),sn.group(2)

if (sn.group(1) in SCC_inputs[SCCn]) and (sn.group(1) in

outputs_SCC.keys()):

parentSCC=outputs_SCC[sn.group(1)]

combineSCC=parentSCC+'_'+SCCn

print '\t',sn.group(1),'is a input of ', SCCn,'and output of',

parentSCC

print '\t=>combineSCC=',combineSCC

f_string=SCC_Table[combineSCC]['f_string']

entry=SCC_Table[combineSCC]['entry']

if len(SCC_path_endpoints[parentSCC])>1:

print '\t',parentSCC,'has paths => ',

SCC_path_endpoints[parentSCC],'>1,thus refer fault to', parentSCC

Page 330: Design and verification approaches for reliability and

317

SCCn=parentSCC ### This is trying to refer the fault

impact to the parent SCC, because the parent SCC may have paths to other observation

points where this fault impact may be detected

elif sn.group(2) in SCC_inputs[SCCn] and (sn.group(2) in

outputs_SCC.keys()):

parentSCC=outputs_SCC[sn.group(2)]

combineSCC=parentSCC+'_'+SCCn

print '\t',sn.group(2),'is a input of ', SCCn,'and output of',

parentSCC

print '\t=>combineSCC=',combineSCC

f_string=SCC_Table[combineSCC]['f_string']

entry=SCC_Table[combineSCC]['entry']

if len(SCC_path_endpoints[parentSCC])>1:

print

"\tSCC_path_endpoints[parentSCC]=",SCC_path_endpoints[parentSCC],'>1,thus refer fault

to', parentSCC

SCCn=parentSCC ### This is trying to refer the fault

impact to the parent SCC, because the parent SCC may have paths to other observation

points where this fault impact may be detected

if(ignore_simulation==0):

faulty=f_string[:entry]+'\n'+fi_short['str_insert']+f_string[entry:]

inputfile=faultyNetlist_workdir+'/'+FullShortName+'_input.scs'

os.system("touch %s"%(inputfile))

fnew = open(inputfile, 'w')

fnew.write(faulty)

fnew.close()

if simul_trivial_circuit==0:

T2_start=time.time()

os.system("spectre

/home/zqliu216/DM_template61/AnaFault_201609/oneVdc.scs %s

%s"%(spectre_extracommands, suppress_output))

T2+=time.time()-T2_start

os.chdir(faultyNetlist_workdir)

sim_time_start=time.time()

os.system("spectre "+inputfile+" %s %s"%(spectre_extracommands,

suppress_output))

sim_time_end=time.time()

sim_time += sim_time_end-sim_time_start

os.system("cp %s/spectre.dc

%s/%s_spectre.dc"%(faultyNetlist_workdir,faultyNetlist_workdir,FullShortName))

#########################

#read DC data

outputfile=''

if(ignore_simulation==0):

Page 331: Design and verification approaches for reliability and

318

outputfile=faultyNetlist_workdir+'/spectre.dc'

else:

outputfile=faultyNetlist_workdir+'/%s_spectre.dc' %FullShortName

MOPi=SCC_Table[SCCn]['MOPi']

data=readFile(outputfile,MOPi,FullShortName)

MOP_Allshort.append(data)

MOP_short[SCCn].append(data)

# this part is added on 2017.0308

allnodes_SCCn=SCC_nodes[SCCn]

data_allnodes=readFile(outputfile,allnodes_SCCn,FullShortName)

MOP_short_allnodes[SCCn].append(data_allnodes)

fault_sim += 1

WholeShortName[SCCn]=WholeShortName[SCCn]+[FullShortName]

###########################################################################

#########################

#print out the fault impacts for all SCCs

###########################################################################

#########################

print '#print out the fault impacts for all SCCs..'

for SCCn in SCC_outputs_keys:

#print SCCn,'=>\n'

MOPi_short=asarray(MOP_short[SCCn])

MOPi_open=asarray(MOP_open[SCCn])

MOP_desired=SCC_Table[SCCn]['MOP_desired']

MOPi=SCC_Table[SCCn]['MOPi']

faultImpact=MOPi_short-MOP_desired

directory=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact'

if not os.path.exists(directory):

os.makedirs(directory)

elif os.path.isfile(directory):

os.system("rm -r %s/*"%(directory))

filename=directory+'/'+SCCn+'_faultImpact.txt'

faultname=directory+'/'+SCCn+'_faultName.txt'

fnew = open(filename, 'w')

fnew1 = open(faultname, 'w')

for i in range(len(MOPi)):

fnew.write('\t%s' %MOPi[i])

fnew.write('\n')

for i in range(faultImpact.shape[0]):

for j in range(faultImpact.shape[1]):

fnew.write('%.4e\t' %faultImpact[i][j])

Page 332: Design and verification approaches for reliability and

319

fnew.write('\n')

fnew1.write('%s\n' %WholeShortName[SCCn][i])

faultImpact=MOPi_open-MOP_desired

for i in range(faultImpact.shape[0]):

for j in range(faultImpact.shape[1]):

fnew.write('%.4e\t' %faultImpact[i][j])

fnew.write('\n')

fnew1.write('%s\n' %WholeOpenName[SCCn][i])

#print WholeOpenName[SCCn][i]

###########################################################################

#########################

#print out the faultInstToNet for all SCCs

###########################################################################

#########################

print '#print out the faultInstToNet for all SCCs..'

filename=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact/faultInstToNet.txt'

fnew = open(filename, 'w')

for key,value in faultInstToNet.items():

##print key,value

fnew.write('%s\t%s\n' %(key,value))

elapsed_time = time.time() - start_time

print 'Finished...'

print 'mos_num:',mos_num

print 'res_num:',res_num

print 'fault_tot:',fault_tot

print 'fault_sim:',fault_sim

#print '\n**simulated_shorts**\n',simulated_shorts

##print '\n**output values for short faults**\n',MOP_short

#print '\n**simulated_opens**\n',simulated_opens '

#print '\n**tput values for open faults**\n',MOP_open

print "elapsed_time is: ", elapsed_time

T1=sim_time

T_rest=elapsed_time-T1-T2

print "T1 is: ", T1

print "T2 is: ", T2

print "T1-T2 is: ", T1-T2

print "T_rest is: ", T_rest

Page 333: Design and verification approaches for reliability and

320

simulatedFaultList=[]

for SCCn in SCC_outputs_keys:

#print WholeShortName[SCCn]

#print WholeOpenName[SCCn]

simulatedFaultList = simulatedFaultList + WholeShortName[SCCn] +

WholeOpenName[SCCn]

#print "**\nsimulated fault list**"

#print sorted(simulatedFaultList)

'''

for SCCn in SCC_outputs_keys:

#print 'SCCn=>\t',simulated_shorts_hash[SCCn]

simulated_shorts=simulated_shorts_hash[SCCn]

#print str_inserts_added_hash[SCCn]

for each_short in str_inserts_added_hash[SCCn]:

sn=re.search(r'\((\S+)\s(\S+)\)',each_short)

ShortNets=sn.group(1),sn.group(2)

if ShortNets in simulated_shorts or tuple(reversed(ShortNets)) in

simulated_shorts:

continue

else:

print str_inserts_added_hash[SCCn]

print 'god!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'

'''

###########################################################################

#########################

#print out the fault impacts of all nodes for all SCCs

###########################################################################

#########################

print '#print out the fault impacts of all nodes for all SCCs..'

for SCCn in SCC_outputs_keys:

#print SCCn,'=>\n'

MOPi_short=asarray(MOP_short_allnodes[SCCn])

MOPi_open=asarray(MOP_open_allnodes[SCCn])

MOP_desired=asarray(MOP_desired_allnodes[SCCn])

MOPi=SCC_nodes[SCCn]

print MOPi_short.shape[0],',',MOPi_short.shape[1]

print MOP_desired.shape[0],',',MOP_desired.shape[1]

faultImpact=MOPi_short-MOP_desired

directory=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact'

if not os.path.exists(directory):

os.makedirs(directory)

Page 334: Design and verification approaches for reliability and

321

elif os.path.isfile(directory):

os.system("rm -r %s/*"%(directory))

filename=directory+'/'+SCCn+'_faultImpact_allnodes.txt'

faultname=directory+'/'+SCCn+'_faultName.txt'

fnew = open(filename, 'w')

fnew1 = open(faultname, 'w')

for i in range(len(MOPi)):

fnew.write('\t%s' %MOPi[i])

fnew.write('\n')

for i in range(faultImpact.shape[0]):

for j in range(faultImpact.shape[1]):

fnew.write('%.4e\t' %faultImpact[i][j])

fnew.write('\n')

fnew1.write('%s\n' %WholeShortName[SCCn][i])

faultImpact=MOPi_open-MOP_desired

for i in range(faultImpact.shape[0]):

for j in range(faultImpact.shape[1]):

fnew.write('%.4e\t' %faultImpact[i][j])

fnew.write('\n')

fnew1.write('%s\n' %WholeOpenName[SCCn][i])

#print WholeOpenName[SCCn][i]

12. gainCalcul.py

#!/usr/bin/python

import os

import re

from numpy import * #for array and matrix operation,like taking inversion of a matrix

import time #for calculating the used time

start_time=time.time()

currentdir=os.getcwd()

###########################################################################

#########################

#read SCC inputs

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_inputs.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_inputs=

SCC_inputs_keys=[]

Page 335: Design and verification approaches for reliability and

322

for i in range(len(contents)):

a=contents[i].split();

SCC_inputs[a[0]]= a[1:]

SCC_inputs_keys.append(a[0])

print "\n**SCC inputs**"

#for key,value in SCC_inputs.items():

# print "%s\t=> %s" %(key,value)

for key in SCC_inputs_keys:

print "%s\t=> %s" %(key,SCC_inputs[key])

###########################################################################

#########################

#read SCC outputs

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_outputs.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_outputs=

SCC_outputs_keys=[]

for i in range(len(contents)):

a=contents[i].split();

SCC_outputs[a[0]]= a[1:] #take items from 1:end in a list, like matlab a[1:end]

SCC_outputs_keys.append(a[0])

print "\n**SCC outputs**"

#for key,value in SCC_outputs.items():

# print "%s\t=> %s" %(key,value)

for key in SCC_outputs_keys:

print "%s\t=> %s" %(key,SCC_outputs[key])

###########################################################################

#########################

#read SCC nodes

###########################################################################

#########################

filename=currentdir+'/FPG_logfile/SCC_nodes.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

SCC_nodes=

for i in range(len(contents)):

a=contents[i].split();

SCC_nodes[a[0]]= a[1:] #take items from 1:end in a list, like matlab a[1:end]

print a[0],'=>',a[1:]

Page 336: Design and verification approaches for reliability and

323

print "\n**SCC nodes**"

for key in SCC_outputs_keys:

print key

for key in SCC_outputs_keys:

print "%s\t=> %s" %(key,SCC_nodes[key])

sourceSCC_virtual_input=

for currentSCC in SCC_outputs_keys:

if currentSCC not in SCC_inputs.keys():

print currentSCC,": is a source SCC=>virtual input:

",SCC_nodes[currentSCC][0]

sourceSCC_virtual_input[currentSCC]=SCC_nodes[currentSCC][0]

currentSCC='SCC13'

###########################################################################

#########################

#calculate input output gain for all SCC

###########################################################################

#########################

print "\n*******************************************************"

print "\n**calculate i/o gain for all SCC**"

print "\n*******************************************************"

Gain_hash=

for key in SCC_inputs_keys:

currentSCC=key

print currentSCC,'\t=>\t',

######################################

filename=currentdir+'/FPG_logfile/SCC_subSG/sg_%s.txt' %currentSCC

f=open(filename,'r')

sg=f.readlines()

f.close()

sg_hash=

sg_nodes=[]

for i in range(len(sg)):

a=re.search(r'(\S+)\s+(\S+)\s+(\S+)', sg[i])

sg_hash[a.group(1)+'_'+a.group(2)]=a.group(3)

if a.group(1) not in sg_nodes:

sg_nodes.append(a.group(1))

if a.group(2) not in sg_nodes:

sg_nodes.append(a.group(2))

#sg_inter_nodes=list(set(sg_nodes)-set(SCC_inputs[currentSCC]))

sg_input_nodes=SCC_inputs[currentSCC]

Page 337: Design and verification approaches for reliability and

324

sg_inter_nodes=[item for item in sg_nodes if item not in sg_input_nodes]

sg_output_nodes=SCC_outputs[currentSCC]

#print 'sg_nodes=>', sg_nodes

#print 'sg_inter_nodes=>', sg_inter_nodes

#print 'SCC_inputs=>',sg_input_nodes

#print 'SCC_outputs=>',sg_output_nodes

dim=len(sg_inter_nodes)

A=zeros((dim,dim))

for i in range(dim):

for j in range(dim):

if sg_inter_nodes[i]+'_'+sg_inter_nodes[j] in sg_hash.keys():

A[j][i]=sg_hash[sg_inter_nodes[i]+'_'+sg_inter_nodes[j]]

dim2=len(sg_input_nodes)

B=zeros((dim,dim2))

for i in range(dim2):

for j in range(dim):

if sg_input_nodes[i]+'_'+sg_inter_nodes[j] in sg_hash.keys():

B[j][i]=sg_hash[sg_input_nodes[i]+'_'+sg_inter_nodes[j]]

dim3=len(sg_output_nodes)

C=zeros((dim3,dim))

for i in range(dim3):

node=sg_output_nodes[i]

index=sg_inter_nodes.index(node)

#C[i,:]=A[index,:] #take items from row 'i', any coloum in a matrix, same as

matlab

C[i,index]=1 #take items from row 'i', any coloum in a matrix, same as matlab

A=mat(A)

B=mat(B)

I=mat(eye(A.shape[0]))

V=(I-A).I*B

Gain=C*V

'''

print 'A=>',A

print 'B=>',B

print "C=",C

print '!!!'

#print "I=",I

#print '(I-A).I*B = ',V

'''

print 'Gain: %s=>%s = %s ' %(sg_input_nodes, sg_output_nodes,Gain)

for i in range(len(sg_input_nodes)):

Page 338: Design and verification approaches for reliability and

325

for j in range(len(sg_output_nodes)):

Gain_hash[sg_input_nodes[i]+'_'+sg_output_nodes[j]]=Gain[j,i]

#for key,value in Gain_hash.items():

# print '%s => %s' %(key,value)

###########################################################################

#########################

#calculate internal gain of SCC outputs for all SCC

###########################################################################

#########################

print "\n*******************************************************"

print "\n**calculate internal gain of SCC outputs for all SCC**"

print "\n*******************************************************"

inter_gain_hash=

for key in SCC_outputs_keys:

currentSCC=key

print '\n--For:',currentSCC

######################################

filename=currentdir+'/FPG_logfile/SCC_subSG/sg_%s.txt' %currentSCC

f=open(filename,'r')

sg=f.readlines()

f.close()

sg_hash=

sg_nodes=[]

for i in range(len(sg)):

a=re.search(r'(\S+)\s+(\S+)\s+(\S+)', sg[i])

sg_hash[a.group(1)+'_'+a.group(2)]=a.group(3)

if a.group(1) not in sg_nodes:

sg_nodes.append(a.group(1))

if a.group(2) not in sg_nodes:

sg_nodes.append(a.group(2))

#sg_inter_nodes=list(set(sg_nodes)-set(SCC_inputs[currentSCC]))

sg_input_nodes=[]

if currentSCC in SCC_inputs.keys():

sg_input_nodes=SCC_inputs[currentSCC]

sg_inter_nodes=[item for item in sg_nodes if item not in sg_input_nodes]

sg_output_nodes=SCC_outputs[currentSCC]

#print 'sg_nodes=>', sg_nodes

#print 'sg_inter_nodes=>', sg_inter_nodes

#print 'SCC_inputs=>',sg_input_nodes

#print 'SCC_outputs=>',sg_output_nodes

Page 339: Design and verification approaches for reliability and

326

if len(sg_output_nodes)>1:

print '\tmutiple outputs: ',

if currentSCC in SCC_inputs.keys():

print "non-source SCC!!"

print '\t',SCC_inputs[currentSCC],'=>',SCC_outputs[currentSCC]

for i in range(len(sg_output_nodes)):

for j in range(len(sg_output_nodes)):

if i!=j:

vi=SCC_inputs[currentSCC][0]

v1=sg_output_nodes[i]

v2=sg_output_nodes[j]

gain_vi_v1=Gain_hash[vi+'_'+v1]

gain_vi_v2=Gain_hash[vi+'_'+v2]

gain_v1_v2=gain_vi_v2/gain_vi_v1

print '\t',vi,'=>',v1,'=',gain_vi_v1,

print '\t', vi,'=>',v2,'=',gain_vi_v2,

print '\tgain_%s_%s=%s'%(v1,v2,gain_v1_v2)

Gain_hash[v1+'_'+v2]=gain_v1_v2

else:

print "scource SCC!!"

print

'\t',sourceSCC_virtual_input[currentSCC],'=>',SCC_outputs[currentSCC]

dim=len(sg_inter_nodes)

A=zeros((dim,dim))

for i in range(dim):

for j in range(dim):

if sg_inter_nodes[i]+'_'+sg_inter_nodes[j] in

sg_hash.keys():

A[j][i]=sg_hash[sg_inter_nodes[i]+'_'+sg_inter_nodes[j]]

B=zeros((dim,1))

vi=sourceSCC_virtual_input[currentSCC]

index=sg_inter_nodes.index(vi)

B[index]=1

#print sg_inter_nodes

#print node,B

dim3=len(sg_output_nodes)

C=zeros((dim3,dim))

for i in range(dim3):

node=sg_output_nodes[i]

index=sg_inter_nodes.index(node)

#C[i,:]=A[index,:] #take items from row 'i', any coloum in a

matrix, same as matlab

Page 340: Design and verification approaches for reliability and

327

C[i,index]=1 #take items from row 'i', any coloum in a matrix,

same as

A=mat(A)

B=mat(B)

I=mat(eye(A.shape[0]))

V=(I-A).I*B

Gain=C*V

#print '\tGain: %s=%s * %s ' %(vi,Gain, sg_output_nodes)

for i in range(len(sg_output_nodes)):

for j in range(len(sg_output_nodes)):

if i!=j:

vi=sourceSCC_virtual_input[currentSCC]

v1=sg_output_nodes[i]

v2=sg_output_nodes[j]

gain_vi_v1=Gain[i,0]

gain_vi_v2=Gain[j,0]

gain_v1_v2=gain_vi_v2/gain_vi_v1

print '\t',vi,'=>',v1,'=',gain_vi_v1,

print '\t',vi,'=>',v2,'=',gain_vi_v2,

print '\tgain_%s_%s=%s'%(v1,v2,gain_v1_v2)

Gain_hash[v1+'_'+v2]=gain_v1_v2

'''

dim=len(sg_inter_nodes)

A=zeros((dim,dim))

for i in range(dim):

for j in range(dim):

if sg_inter_nodes[i]+'_'+sg_inter_nodes[j] in sg_hash.keys():

A[j][i]=sg_hash[sg_inter_nodes[i]+'_'+sg_inter_nodes[j]]

dim2=len(sg_output_nodes)

B=zeros((dim,dim2))

for i in range(dim2):

node=sg_output_nodes[i]

index=sg_inter_nodes.index(node)

B[index][i]=1

dim3=len(sg_output_nodes)

C=zeros((dim3,dim))

for i in range(dim3):

node=sg_output_nodes[i]

index=sg_inter_nodes.index(node)

Page 341: Design and verification approaches for reliability and

328

C[i,:]=A[index,:] #take items from row 'i', any coloum in a matrix,

same as matlab

A=mat(A)

B=mat(B)

I=mat(eye(A.shape[0]))

V=(I-A).I*B

Gain=C*V

print '\tGain: %s=%s * %s ' %(sg_output_nodes,Gain, sg_output_nodes)

for i in range(len(sg_output_nodes)):

for j in range(len(sg_output_nodes)):

if i != j:

Gain_hash[sg_output_nodes[i]+'_'+sg_output_nodes[j]]=Gain[j,i]

for i in range(dim3):

for j in range(dim3):

if i != j:

print '\t', sg_output_nodes[i],'=>',

sg_output_nodes[j],Gain[j,i]

'''

#for key,value in Gain_hash.items():

# print '%s => %s' %(key,value)

###########################################################################

#########################

#deine sink SCC, detecting range, MOP

###########################################################################

#########################

#sinkSCC=['SCC13','SCC7','SCC8','SCC10']

sinkSCC=['SCC13','SCC10','SCC4','SCC8']

MOP_sink=['vout','Vref','p6','n8']

MOP_DR_array=array([2.298e-3*3,505.5e-3*3, 37.13e-3*3,24.39e-3*3])

i=0;

SCC=sinkSCC[i]

MOP=MOP_sink[i]

MOP_DR=MOP_DR_array[i];

Page 342: Design and verification approaches for reliability and

329

print SCC,MOP,MOP_DR

###########################################################################

#########################

#define a function to calculate FC for a given fault impact list at given MOP_DR

###########################################################################

#########################

def detectbility(faultImpact_mat, MOP_DR):

#print '\n**faultImpact_mat**\n',faultImpact_mat

temp=faultImpact_mat/MOP_DR

#print temp

logical=(abs(temp)>1)-0

#print logical

total=logical.shape[0]

detect=0

for i in range(logical.shape[0]):

temp=sum(logical[i,:])

if temp >0:

detect += 1

############

ll=zeros((logical.shape[0],1))

for i in range(logical.shape[1]):

ll=ll + logical[:,i]

ll=(ll>=1)-0

detect2=sum(ll)

############

#print 'detect=',detect

#print 'total=',total # number of rows

return total,detect,detect2,ll

###########################################################################

#########################

#read the fault impacts for all SCCs

###########################################################################

#########################

SCC_faultImpact=

for currentSCC in SCC_outputs_keys:

filename=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact/'+currentSCC+'_faultI

mpact.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

faultImpact=

current_MOP=contents[0].split()

dim1=len(contents)-1

dim2=len(current_MOP)

Page 343: Design and verification approaches for reliability and

330

#print current_MOP

faultImpact_mat=zeros((dim1,dim2))

faultImpact_mat=mat(faultImpact_mat)

for i in range(len(contents)-1):

#print 'contents[i+1]=>',contents[i+1].split()

temp=[float(n) for n in contents[i+1].split()]# convert string into numbers

faultImpact_mat[i,:]=mat(temp)

#faultImpact_mat.append(contents[i+1].strip()) #.strip() is like chomp() will

remove all spaces at the end

#print "faultImpact_mat => ",faultImpact_mat

SCC_faultImpact[currentSCC]=[current_MOP, faultImpact_mat]

print '\n**Fault impacts for all SCCs'

SCC_final_label=

total2=0

for key in SCC_outputs_keys:

# print key, SCC_faultImpact[key]

SCC_final_label[key]=SCC_faultImpact[key][1]*0

total2 += SCC_faultImpact[key][1].shape[0]

#print SCC

#print SCC_faultImpact[SCC][1]

#a=detectbility(SCC_faultImpact['SCC5'][1], MOP_DR)

#print 'a=',a

###########################################################################

########################

#find the preceeding SCC for all SCC

###########################################################################

########################

preceeding_SCC=

succeeding_SCC=

for n in SCC_inputs_keys:

preceeding_SCC[n]=[]

for n in SCC_outputs_keys:

succeeding_SCC[n]=[]

for n in SCC_outputs_keys:

#print n, SCC_outputs[n]

for m in SCC_inputs_keys:

adj= False

#common=[i for i in SCC_outputs[n] if i in SCC_inputs[m]]

#common=set(SCC_outputs[n]) & set(SCC_inputs[m])

if set(SCC_outputs[n]) & set(SCC_inputs[m]):

Page 344: Design and verification approaches for reliability and

331

adj=True

#print '\t',m, SCC_inputs[m]

#print '\t',adj

preceeding_SCC[m]=preceeding_SCC[m]+[n]

succeeding_SCC[n]=succeeding_SCC[n]+[m]

print '\n**preceeding SCC'

for key,value in preceeding_SCC.items():

print value, '=>', key

print '\n**succeeding or Standard DAG'

for key,value in succeeding_SCC.items():

print key, '=>', value

###########################################################################

#########################

#Breadth first search

###########################################################################

#########################

print "\n*******************************************************"

print '\n**BFS search'

print "\n*******************************************************"

SCC_dist=

SCC_parent=

SCC_DR=

SCC_faultDectect=

for n,value in SCC_outputs.items():

SCC_dist[n]=100000

SCC_parent[n]=''

SCC_faultDectect[n]=''

SCC_DR[n]=[]

Q=[]

#sinkSCC=['SCC12','SCC8','SCC4','SCC13']

#MOP_sink=['vout','Vref','p6','n8']

#MOP_DR_array=array([2.532e-3*3,100.6e-3*3, 37.83e-3*3,24.36e-3*3])

for i in range(len(sinkSCC)):

SCC=sinkSCC[i]

MOP=MOP_sink[i]

MOP_DR=MOP_DR_array[i];

SCC_dist[SCC]=0

SCC_DR[SCC].append([MOP_DR,MOP,MOP]) #second is the MOP at the sink

SCC, third is the 'virtual' OP that will be kept for current SCC

Page 345: Design and verification approaches for reliability and

332

Q.insert(0,SCC)

while Q:

currentSCC=Q.pop()

print '\ncurrentSCC',currentSCC

print 'SCC_dist_',currentSCC,'=>Lv',SCC_dist[currentSCC]

if SCC_dist[currentSCC] == 0: # sink scc

a=detectbility(SCC_faultImpact[currentSCC][1],

SCC_DR[currentSCC][0][0])

print 'a=',a

if currentSCC in SCC_inputs_keys: #this is not a source SCC

currentSCC_input=SCC_inputs[currentSCC]

print '\t%s_inputs = '%currentSCC,currentSCC_input

print '\t%s_preceeding_SCC = ' %currentSCC,preceeding_SCC[currentSCC]

for parentSCC in preceeding_SCC[currentSCC]: #SCC that is preceeding to

currentSCC

print '\t',parentSCC,'Lv.',SCC_dist[parentSCC],'succeeding_SCC =

',succeeding_SCC[parentSCC]

if SCC_dist[parentSCC] == 100000:# 1st time to reach this SCC

SCC_dist[parentSCC] = SCC_dist[currentSCC] +1

#do backward

print '\t',

SCC_outputs[parentSCC],'=>',SCC_outputs[currentSCC],'\tSCC_DR[%s]='%currentSCC,S

CC_DR[currentSCC]

DR_checked=[]

for DR_vec in SCC_DR[currentSCC]:

print '\t\tDR_vec[1]:', DR_vec[1]

if DR_vec[1] not in DR_checked: # if have multiple paths from

parentSCC-->currentSCC, only check one

DR_checked.append(DR_vec[1])

virtualOP=DR_vec[2]

print '\t\tvirtual OP of currentSCC=>', virtualOP

for v1 in SCC_outputs[parentSCC]: #DRv1=

DRvout/(gain_v1_vout+gain_v1_v2*gain_v2_vout)

eqival_gain=Gain_hash[v1+'_'+virtualOP]

print '\t\t\teqival_gain: gain_%s_%s =

%s'%(v1,virtualOP, Gain_hash[v1+'_'+virtualOP])

for v2 in SCC_outputs[parentSCC]:

if v2 !=v1:

print

'\t\t\teqival_gain+=:gain_%s_%s(%s)'%(v1,v2, Gain_hash[v1+'_'+v2]),

eqival_gain +=

Gain_hash[v1+'_'+v2]*Gain_hash[v2+'_'+virtualOP]

Page 346: Design and verification approaches for reliability and

333

print '*gain_%s_%s (%s) =

%s'%(v2,virtualOP, Gain_hash[v2+'_'+virtualOP], eqival_gain)

DRv1=DR_vec[0]/eqival_gain

print

'\t\tDR_%s=DR_%s/eqival_gain=%s'%(v1, DR_vec[2], DRv1)

print '\t\t',[DRv1,DR_vec[1],v1]

SCC_DR[parentSCC].append([DRv1,DR_vec[1],v1])#we may have multiple

succeeding_SCC[parentSCC].remove(currentSCC) #remove the

current SCC,means this path has beeen traveled, we will not Quene the parentCC until all

succeeding SCC are travelled

if not succeeding_SCC[parentSCC]:

print "\tQuene %s into Q since all succeeding SCC are

travelled" %parentSCC

Q.insert(0,parentSCC)

print '\t\tbefore combination, SCC_DR[%s]=%s' %(parentSCC,

SCC_DR[parentSCC])

DR_hash=

for DR_vec in SCC_DR[parentSCC]:

name=DR_vec[1]+'_'+DR_vec[2]

if name in DR_hash.keys(): #means we have multiple

paths from parentSCC-->sinkSCC

#print '!!!',DR_hash[name],'!!!!'

algebraic_gain=DR_hash[name][0]+1/DR_vec[0]# take the algebraic gain

DR_hash[name]=[algebraic_gain,DR_vec[1],DR_vec[2]]

else:

DR_hash[name]=[1/DR_vec[0],DR_vec[1],DR_vec[2]] #initilize the positive gain for

mutiple path

SCC_DR[parentSCC]=[] #reset the DR for parentSCC

for key,value in DR_hash.items():

SCC_DR[parentSCC].append([1/value[0],value[1],value[2]])

print '\t\tafter combination, SCC_DR[%s]=%s' %(parentSCC,

SCC_DR[parentSCC])

else:

print '\t',currentSCC,'is a source SCC!'

###########################################################################

#########################

#Calculate fault coverage

Page 347: Design and verification approaches for reliability and

334

###########################################################################

#########################

print "\n*******************************************************"

print '\n**Calculate fault coverage'

print "\n*******************************************************"

for SCCn in SCC_outputs_keys:

print 'SCC_DR[%s]=%s' %(SCCn,SCC_DR[SCCn])

print 'SCC_outputs[%s]=%s' %(SCCn,SCC_outputs[SCCn])

OP=[]

for DR_vec in SCC_DR[SCCn]:

if DR_vec[1] not in OP:

OP.append(DR_vec[1])

print OP

dim=len(SCC_outputs[SCCn])

dim2=len(OP)

A=zeros((dim2,dim))

DR_hash=

for DR_vec in SCC_DR[SCCn]:

i=OP.index(DR_vec[1])

j=SCC_outputs[SCCn].index(DR_vec[2])

A[i][j]=DR_vec[0]

print A

for i in range(dim2):

print A[i][:],'!!!!'

a=detectbility(SCC_faultImpact[SCCn][1], mat(A[i][:]))

print '\ta=',a

SCC_final_label[SCCn] += a[3] #as long as one node can detect then

detectable

###########################################################################

#########################

#read the fault name for all SCCs

###########################################################################

#########################

wholeFaultName=

wholeFaultName_propsed=[]

for currentSCC in SCC_outputs_keys:

filename=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact/'+currentSCC+'_fault

Name.txt'

f=open(filename,'r')

contents=f.readlines()

f.close()

Page 348: Design and verification approaches for reliability and

335

f_string = "".join(contents)

f_string_vec=f_string.split()

print '\n--%s\n%s'%(currentSCC,f_string_vec)

wholeFaultName[currentSCC]=f_string_vec

wholeFaultName_propsed=wholeFaultName_propsed+f_string_vec

total=0

detect=0

Undetect=[]

print "\n**undetected fault list**\n"

for SCCn in SCC_outputs_keys:

#print SCCn, '=>', SCC_final_label[SCCn]

print SCCn

logical=SCC_final_label[SCCn]

total+=logical.shape[0]

ll=zeros((logical.shape[0],1))

for i in range(logical.shape[1]):

ll=ll + logical[:,i]

ll=(ll>=1)-0

detect += sum(ll)

for i in range(len(ll)):

if ll[i][0] == 0:

print '\t',i,

print wholeFaultName[SCCn][i]

Undetect.append(wholeFaultName[SCCn][i])

for SCCn in SCC_outputs_keys:

print SCCn, '=>!!!!!!!!!!!!'

current_MOP=SCC_faultImpact[SCCn][0]

faultImpact_mat=SCC_faultImpact[SCCn][1]

#print faultImpact_mat

for i in range(len(wholeFaultName[SCCn])):

print '%s:\t%s => %s\n' %(wholeFaultName[SCCn][i], current_MOP,

faultImpact_mat[i])

elapsed_time = time.time() - start_time

print 'detect=',detect

print 'total=',total # number of rows

FC=float(detect)/total*100

print "FC=%.2f" %FC+'%\n'

print 'total2=',total2

print "elapsed_time is: ", elapsed_time

wholeFaultName_method1=[]

Page 349: Design and verification approaches for reliability and

336

filename=currentdir+'/FPG_logfile/FaultSim/wholeFaultName.txt'

f = open(filename, 'r')

contents=f.readlines()

f.close()

f_string = "".join(contents)

wholeFaultName_method1=f_string.split()

'''

print sorted(wholeFaultName_method1)

print '\n\n'

print sorted(wholeFaultName_propsed)

print '\n\n'

'''

t=set(wholeFaultName_method1)

s = set(wholeFaultName_propsed)

diff1 = [x for x in t if x not in s]

diff2 = [x for x in s if x not in t]

print 'whole=',diff1

print 'SCC_by_SCC=',diff2

print '\n\n'

undetecedFaultName_method1=[]

filename=currentdir+'/FPG_logfile/FaultSim/undetecedFaultName.txt'

f = open(filename, 'r')

contents=f.readlines()

f.close()

f_string = "".join(contents)

undetecedFaultName_method1=f_string.split()

print sorted(undetecedFaultName_method1)

print '\n\n'

print sorted(Undetect)

print '\n\n'

t=set(undetecedFaultName_method1)

s = set(Undetect)

diff3 = sorted([x for x in t if x not in s])

diff4 = sorted([x for x in s if x not in t])

#print 'whole=',sorted(diff3)

#print 'SCC_by_SCC=',sorted(diff4)

'''

filename=currentdir+'/FPG_logfile/FaultSim/SCC_faultImpact/faultInstToNet.txt'

f = open(filename, 'r')

contents=f.readlines()

f.close()

faultInstToNet=

for i in contents:

Page 350: Design and verification approaches for reliability and

337

print i,

a=i.split()

faultInstToNet[a[0]]=a[1]

print 'whole=',

for i in diff3:

print '%s(%s), '%(i,faultInstToNet[i]),

print '\n\nSCC_by_SCC=',

for i in diff4:

print '%s(%s), '%(i,faultInstToNet[i]),

print '\n'

aa=[faultInstToNet[i] for i in diff3]

bb=[faultInstToNet[i] for i in diff4]

i

print 'whole=[',

for i in diff3:

if faultInstToNet[i] not in bb:

print '%s(%s), '%(i,faultInstToNet[i]),

print ']\n\nSCC_by_SCC=[',

for i in diff4:

if faultInstToNet[i] not in aa:

print '%s(%s), '%(i,faultInstToNet[i]),

print ']\n'

'''