[Arya Raychaudhuri's one-man enterprise that believes in Always Move Ahead with New Ideas]
"home" , "code snippets", "via check add paper" "backpage" buttons on the left side, to select a specific page
[Norton Security Seal is now discontinued by Yahoo for Site Solution based websites, but moved from http to https]
the pages are best viewed through internet explorer
WordPress
BLOG PAGE: http://lvs-debug-solutions.com/blog/
[kept inactive to avoid spam]
This is the age of search engines - quickly search for entities and their inter-relationships. And, LVS Debug is all about analyzing netlists and gds/oasis layout databases, and finding their correspondences/matches/mismatches in the post-PD domain. So, much of the codes presented in the 'code snippets' page focus on searching and parsing these huge netlist and layout files, to extract the relevant information and their connection. The other important thing is the focus on revenue/jobs generating creative ideas - because if you cannot come up with new product ideas every now and then, what will you sell tomorrow, in the future? I have now transformed LVS DEBUG SOLUTIONS LLC into a multi-engineering concepts platform (please review the code snippets* pages under https://www.lvs-debug-solutions.com)
google email: arya.raychaudhuri@gmail.com
Please direct all official communications to
arya@lvs-debug-solutions.com, or call 408-480-1936
I typically don't answer calls from unknown callers, to avoid spam. If you are a serious caller, please leave voice or text message, or email...For text message from international locations, please use cellphone number as 1-408-480-1936
LVS DEBUG SOLUTIONS LLC
980 Kiely Blvd, Unit 308
Santa Clara, CA 95051
United States
ph: 1-408-480-1936
arya
[Always break new ground in codes and concepts ...]
LVS DEBUG SOLUTIONS LLC pursues a unique business model - I put up code snippets and technical ideas on this page as tutorial spirited ads for the consulting business. I would request engineers and scientists who benefit from these to urge their management to help LVS DEBUG SOLUTIONS LLC through projects and financial resources - at times it's time to stand up and get counted! After all, it should be reciprocal ... All snippets and IPs presented here are strictly proprietary to LVS DEBUG SOLUTIONS LLC, any commercial use of these is prohibited, without proper distribution agreement with the owner.
Please direct all communications to
arya@lvs-debug-solutions.com, or call 408-480-1936
google email: arya.raychaudhuri@gmail.com
### The mpg (Item#38) at the bottom of the page annotated for proper understanding
***
Item#217> Indications discussed in Item#13 are now verified....
During the course of my recent work (courtesy, a project with Intel) I could test and verify the indications earlier given in Item#13 (see below). You can run an external shell script from inside a run-time TVF function to parse the already generated DRC results from the current run, to generate a number (or even a set of numbers, etc) and put it in a small file. You can later read that number from that small file from inside another TVF function and use it for checks there.
You can often do these things with programs written in general purpose programming languages like Perl or C. But, being able to do this with a Calibre DRC/LVS run will open new application modes.
***
Item#216> A 15-point Security System using the Pulse Generator (Item#155) and the Voltage Monitor (Item#150) - another application of Pgen and Vmon
[Oct 13, 2015, Arya Raychaudhuri, Santa Clara, California]
***
[Aug 24. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#214> Single chip telephone exchange IP - using the concepts of Item#s 213, 209, 150, and 155
Obviously, a single chip telephone exchange will be very compact and leak-proof. But, how to detect wire-tapping activity outside the chip? One idea could be passing a voltage along the voice lines at all idle times, and letting any disturbance to it set a latch on the telephone side - meaning that your line got corrupted when your phone was idle. Suppose you are a EE major and your EE channels are getting corrupted - that's not a good idea. Anyone's telephone line, for that matter!
[Aug 02. 2015, Arya Raychaudhuri, Santa Clara, California]
+phone2pickup edge can be sent through the addressing pulses channel as a first pulse, 2-ringer can be sent through the same channel in its idle mode. phone2up state is latched phone2pickup edge. The state goes to 0 via 2-reset. So, no extra channels are needed.
***
Item#213> Rough schematic of the exchange end circuit for the 8 line scheme shown in Item#209 - the connection between Line 7 and Line 2 shown as an example
[Aug 02. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#212> Rectification of an entire pulse train without an external reset pulse
In this case, the falling edge of the rectified pulse is somewhat more delayed beyond the falling edge of the last pulse. Also, the 20K charge bleed resistor can lead to slightly higher power dissipation/consumption for every train of pulses. Increasing the resistance value makes the output's falling edge delay even larger.
[July 21. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#211> Rectification of a finite pulse train when an externally generated reset pulse is available at the end of the pulse train
The scheme uses the clk-to-Q delay stage of Item#210. The rectified integrated pulse is needed to stop instantaneous opening of the 'preceding' channels of the voltage monitor of Item#150, in such applications where instantaneous opening of channels is undesirable. And, in general, in many other applications involving finite pulse trains.
Who will provide the reset pulse? This can be generated out of the falling edge of the toggle input (T0) of the pulse generator in Item#155, and ORed out into the reset pulse out section.
SIMULATION SHOWN
[July 19, 19. 2015, Arya Raychaudhuri, Santa Clara, California]
Rectification of an entire pulse train with the help of an external reset can be done much more easily by setting a latch with the incoming pulses and resetting it with the reset pulse, but the above scheme can be flexibly extended to rectifying fractions of the pulse train.
***
Item#210> An essential correction to the data entry circuit for the 3-NAND Left to Right Shift Register of Item#172
Earlier the shift aspect was simulated (Item#174), but the data entry into the first stage to the left was not, and was incorrect. Here is the correction.
DATA ENTRY PLUS LEFT TO RIGHT SHIFT SIMULATED
[July 13, 14, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#209> A conceptual diagram of an 8-line telephone exchange using the voltage monitor of Item#150, and the pulse generatior of Item #155 - a potential application space...
Transmission gated connections of line 6 at the Exchange end shown as an example
[July 03. 2015, Arya Raychaudhuri, Santa Clara, California]
In this scheme, the total number of interconnections (vmon to vmon) inside the exchange will be 28 for 8 lines (7+6+5+4+3+2+1), so, in general, for n lines, the total number of interconnections can be derived as n*(n-1)/2 (~ n^2/2). Hence the scheme is suitable for small exchanges.
***
Item#208> Correction to .INCLUDE expander shell script of Item#30
If some spice netlist lines start with '*' - which is a comment in spice, all '*' characters in the netlist should be moved to '#' or "~" and sed-ed back in the script, to avoid issues, e.g.,
sed -e 's/ /%/g' $fff|sed -e 's/\*/\#/g' > tmpX;
then echo $ll|sed -e 's/\#/\*/g';
Additional syntax in brown.
***
Item#207> Perl forking based dynamic emulation of a clk +edge sense circuit (a smaller Perl equivalent of the bash based approach of Item#181)
[May 01. 2015, Arya Raychaudhuri, Santa Clara, California]
Note that the clk (12s/12s) is being generated in the 'parent' process, the AND is running in the 'child' process, and the inverter in the 'grandchild' - all running simultaneously, to generate dynamic output of clk, i2 and +edge. The bash based approach seems to be more natural to me. The inter-process 'pipe' did not work on my system - so, applied the external files based communication (as in shell).
***
Item#206> NAND dual of the Gear NOR of Item#205
[Mar 19. 2015, Arya Raychaudhuri, Santa Clara, California]
*If* the NOR gate of Item#205 works, the above NAND dual should work too. Why call the bias chains zero-bias, one-bias? If we imagined a circular gear in place of the chains, that gear would turn clock-wise, anti-clock respectively. Any possible application space for these gears? Logical sequencing of machines in a mechanical shop floor. For example, if m/c A or m/c B runs, the m/c C should run. If A and B both run, the C should not run. That's an exclusive OR (XOR), which can be configured out of the NAND/NORs.
***
Item#205> Revisiting the Gear NOR of Item#97
Unlike the power transmission system of Item#204 whose operation is crystal clear even without any simulation, the operation of the Gear NOR of Item#97 was not so clear - it was a thought experiment, and I have no simulation tool to simulate the operation. There were questions about spring constants and meshing conflicts (see Item#105). Here is an edited version (relative postions/directions of the INPUTs and the spring shaft altered) of the GearNOR which may have a better chance - still it is a thought experiment.
[Mar 17. 2015, Arya Raychaudhuri, Santa Clara, California]
The idea is that the translation force (F) when any or both INPUT gears start rotating counter-clockwise (upper right indication) will overcome the soft pull (low spring constant) of the spring inside the spring shaft, and detach the regular teeth of the OUTPUT from the zero-bias chain. When both INPUTs start rotating clockwise (lower right indication) the slight frictional translation associated with the pawl teeth will help the spring of the spring shaft to engage the regular teeth to the zero-bias chain. The small rotational torque (T) coming from such friction aids the bigger torque imparted by the zero-bias chain. When one of the INPUTs is rotating counter-clockwise, and the other clockwise, the translation force (F) of the counter-clockwise dominates.
***
Item#204> ElectroMagnet spring-shaft (see Item#203) based gear system - power transfer schematic
[Mar 17. 2015, Arya Raychaudhuri, Santa Clara, California]
Now, referring to the Item#103, it is easy to appreciate that the switch (push-button) based transmission can be turned into automatic by incorporating a 1-4 pulses ADC (as in Item#s 163, 164) on the speedometer analog output, and a voltage monitor (Item#150) type channel (gear) selection.
***
Item#203> Revisiting the spring-shaft of Item#100 with an electromagnetic variation
[Mar 15. 2015, Arya Raychaudhuri, Santa Clara, California]
Interestingly, with this arrangement, a (one) spring-shafted gear with one regular tooth track and one pawl tooth track can replace each gearNOT of Item#103. This will eliminate the need for input and output wheels for the logic gate, and the motors that would drive the input wheels. The engine power chain will be placed transversely with respect to the multi-bangled pawl output shaft.
The electromagnet driven by a gear selection switch will pull the gear's regular teeth to the power chain and the gear will start rotating counter-clockwise to transfer power to its output pawl which will have much lower spring constant teeth with respect to the driver wheel's pawl teeth. This will enable slipping when the driver wheel is disengaged from the power chain, and another gear is selected.
***
Item#202>Quiz 25 : Write a variant of the Perl script of Item#201 to translate the v2lvs netlist of Item#201 to the port-pin correspondence ordering based netlist of Item#200 - should consider other non ^X lines too.
Answer:
***
Item#201>Quiz 24 : Write a variant of the Perl script of Item#200 to create the files 'SubPins.txt' and 'pinsConnect.txt' (see Item#199) out of a Calibre v2lvs source netlist.
[Mar 09. 2015, Arya Raychaudhuri, Santa Clara, California]
Answer: At first, remove the line continuation marks ( '+' ) using perl or shell code of Item#4 or Item#5 - and save the v2lvs netlist as 'v2lnet.txt'. Note that a generalized v2lvs netlist can also contain non v2lvs subckts (standard cells, memories/IPs) which may have been expanded using shell/perl as shown in Item#30/56 - the following perl script should work on those as well.
## v2lvs spice netlist parser
## Arya, March 9 2015
$infile_1 = "v2lnet.txt";
open(JJ, $infile_1);
$subs_mark = ".SUBCKT";
$gotAsub = 0;
@subs = ();
$sn = 0;
while(<JJ>) {
s/^//;
$lastXline = $_;
chomp $lastXline;
if ($lastXline =~ /$subs_mark/) {
$sn++;
@lineXparts = split(/\s+/, $lastXline);
$sx = $lineXparts[1];
push(@subs, $sx);
$ii=0;
$valval = $sx;
for ($qq = 2; $qq <= $#lineXparts ; $qq++) {
$vv = $lineXparts[$qq] . '_#' . $sn;
$valval = $valval . ' ' .$vv;
}
$keyval = $ii;
${$sx}{$keyval} = $sn;
$ii++;
$keyval = $ii;
${$sx}{$keyval} = $valval;
}
if ($lastXline =~ /^X/) {
$ii++;
@lineXparts = split(/\s+/, $lastXline);
$xx = $lineXparts[0];
$valval = $xx;
if ($lineXparts[2] eq '$PINS') {
$ix = 3;
$ex=$#lineXparts;
}
else {
$ix = 1;
$ex=$#lineXparts-1;
}
for ($qq = $ix; $qq <= $ex ; $qq++) {
$vv = $lineXparts[$qq] . '_#' . $sn;
$valval = $valval . ' ' .$vv;
}
$keyval = $ii;
if ($lineXparts[2] eq '$PINS') {
${$sx}{$keyval} = $valval . ' ' . $lineXparts[1] . ' ' . '$PINS';
}
else {
${$sx}{$keyval} = $valval . ' ' . $lineXparts[$#lineXparts];
}
}
}
close(JJ);
$outfile1 = "SubPins2.txt";
$outfile2 = "pinsConnect2.txt";
open(FF, ">$outfile1");
open(JJ, ">$outfile2");
@csx = ();
$cq = 1;
foreach $sx (@subs) {
@lsx = ();
push(@lsx, $sx);
foreach $kk ( sort { $a <=> $b } keys %{$sx} ){
if ($kk > 0) {
$valval = ${$sx}{$kk};
@lineXparts = split(/\s+/, $valval);
if ($lineXparts[0] eq $sx) {
$ex = $#lineXparts;
}
else {
$ex = $#lineXparts - 1 ;
if ($lineXparts[$#lineXparts] eq '$PINS') {
$subname = $lineXparts[$ex];
$sn = ${$subname}{0};
$snx = '_#' . $sn . ' ';
$ex = $ex - 1;
}
else {
$subname = $lineXparts[$#lineXparts];
$xsubline = ${$subname}{1};
@lineYparts = split(/\s+/, $xsubline);
}
for ($ii = 1; $ii <= $ex; $ii++) {
if ($lineXparts[$#lineXparts] eq '$PINS') {
$cc = $lineXparts[$ii];
$cc =~ s/\=/$snx/;
@lineZparts = split(/\s+/, $cc);
$lineXparts[$ii] = $lineZparts[1];
}
else {
$cc = $lineXparts[$ii] . " " . $lineYparts[$ii];
}
$find_nomatch = 1;
if ($cq) {
push(@csx, $cc);
$cq=0;
}
foreach $cx (@csx) {
if ( $cc eq $cx ) {
$find_nomatch = 0;
break;
}
}
if ($find_nomatch) {
push(@csx, $cc);
}
}
}
for ($ii = 1; $ii <= $ex; $ii++) {
$find_nomatch = 1;
foreach $lx (@lsx) {
if ( $lineXparts[$ii] eq $lx ) {
$find_nomatch = 0;
break;
}
}
if ($find_nomatch) {
push(@lsx, $lineXparts[$ii]);
}
}
}
}
foreach $lx (@lsx) {
print FF $lx, " ";
}
print FF "\n";
}
foreach $cx (@csx) {
print JJ $cx, " ","\n" ;
}
close(FF);
close(JJ);
***
Item#200> Subckt hashing based Perl parser to generate the files 'SubPins.txt' and 'pinsConnect.txt' (see Item#199)
The example netlist used:
Subckt hashing (each hash named after the Subckt name, the keys its relevant line numbers, and the corresponding values the lines themselves, see Item#109) enables handling heavily complex netlists at a faster rate.
continued to next frame ...
[Mar 06. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#199> Perl-Scilab combo to drive graph theoretic LVS netlist analysis (see Item#136) - pins/ports graph (vertex/edge) representation using Scilab graphics
A perl netlist parser creates the Subckt, pin/ports listing in 'SubPins.txt':
SUB1 pin1_#1 pin2_#1 pin3_#1 pin4_#1 pin5_#1 vdd_#1 vss_#1
SUB2 pin2_#2 pin3_#2 pin4_#2 pin5_#2 vdd_#2 vss_#2
SUB3 pin4_#3 pin5_#3 vdd_#3 vss_#3
And their connections in 'pinsConnect.txt' :
pin1_#1 pin3_#2
pin2_#1 pin2_#2
pin3_#1 pin5_#2
pin4_#1 pin4_#3
pin5_#1 pin5_#3
vdd_#1 vdd_#2
vss_#1 vss_#2
vdd_#1 vdd_#3
vss_#1 vss_#3
pin3_#2 pin4_#3
pin4_#2 pin5_#3
vdd_#2 vdd_#3
vss_#2 vss_#3
These two files are read in by the following scilab code to generate the graphical representation (bottom):
[Mar 06. 04, 2015, Arya Raychaudhuri, Santa Clara, California]
***
!
Item#198> 3X AND mosfets operating regions description
[Mar 02. 2015, Arya Raychaudhuri, Santa Clara, California]
** The drawback for this AND and its OR dual (Item#195) is that the input impedance for the Q1 input is lower, so the driver for the Q1 input needs to be stronger than that for Q0, ~Q0
***
Item#197> 3X AND based ring oscillator shows speed advantage over 6X AND ring oscillator (see Item#196) for higher aspect ratio of the gate mosfets (W/L = 3, instead of 1)
[Mar 01. 2015, Arya Raychaudhuri, Santa Clara, California]
This is explained with the following experiment where the 3X AND's transmission gate is being requested to charge up a 100fF cap, once with W/L=1 and then with W/L=3. See how the higher NMOS saturation current spike helps the PMOS reach its linear low resistance region faster in the W/L=3 case. This helps the charging speed to be super-linear with respect to W/L. The charging times to 0.9V indicated. Had it been linear, you would expect a charging time of ~1.10ns, but I am seeing 1.05ns. For the 6X NAND there is no such NMOS spike help.
[Mar 01. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#196> Speed comparison between the 3X AND gate of Item#194 and a regular 6X AND gate
The following 21 stage ring oscillators show speed advantage of the regular 6X AND gate over the less space consuming 3X AND gate (see Item#194). This is due to higher parasitic capacitance of sorce/drain junctions in the transmission gate based on the bulk CMOS process - likely to be different with SOI.
[Feb 23. 23, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#195> 3 mosfet ORing -OR dual of the 3 mosfet AND of Item#194
[Feb 19. 25, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#194> 3 mosfet ANDing - another example of context specific reduction of logic transistors
The top toggle generating AND gates of Item#38 (traditional synchronous up counter) could be reduced as follows:
[Feb 19. 2015, Arya Raychaudhuri, Santa Clara, California]
This reduction is appealing only when the inverted state of one of the inputs is available. So, when a particular enabling bit needs to be ANDed with many different logic bits, it's a good idea to keep the inverted state of the enabling bit handy, and then apply the above reduction for various ANDings. Not sure if this reduction has been shown before, if so, please bring it to my attention, will acknowledge the source.
***
Item#193> Logical equivalent of the input Pfet of the clk to Q T-flipflop of Item#177
Interesting how the pfet saves a lot of logic fets. The key to the operation is to adjust the aspect ratios of the pfet and the preceding stage nfet as shown in the following diagram. The pfet leaks about <0.1/R during the ultra-thin ~+clk pulse.
[Feb 19, 2015, Arya Raychaudhuri, Santa Clara, California]
The logical equivalent was computed using an interactive KV map routine:
http://www.mathematik.uni-marburg.de/~thormae/lectures/ti1/code/karnaughmap/
***
Item#192> Comments on the digit recovery from the pulses of Item#191
For each pulse width, the delay buffers are chosen in such a way that the pulse width is exactly demolished - meaning that the output of the nand gate following the inverters remain at 1, so the latch following the nand remains unset (Q=0). Naturally, the upper digits have increasingly longer delays on the buffer chain, so they will also demolish a lower digit pulse width.
For example, if a pulse width corresponding to digit 6 is applied simultaneously to all the delay chains, the pulse is demolished by the delay chains of digits 6 through 9, so those latches remain at 0. But, the delay chains of digits 0 through 5 cannot demolish the digit6 pulse and their nands produce negative pulses, to set (Q=1) their latches. Hence, the XOR at the transition between the digit 5 latch and the digit 6 latch produce a 1 (digit6). All other XORs produce 0s (similar scheme was used in Item#158 with XNORs).
Obviously, the delay chain is critical to the accuracy of the demodulation process, and delays for same size gates change from process to process. What if the pulses are generated using a chip that is done with a particular process, and the pulses move to another chip made by a different process? As long as the ring oscillator frequencies using the delay inverters with the two processes are the same (within a tolerance), the scheme should work.
***
Item#191> Decimal samples (Item#189) to varying pulse widths (pwm) and subsequent demodulation
The following schematic shows how the decimal samples of Item#189 could be used to generate varying pulse widths (pwm) up to 3ns (for digit9), each pulse being roughly 300ps longer than the preceding digit's. The pulses are then exactly demoslihed by delay buffer chains of increasing delay (digit0 through digit9). This is a way to transfer the sampled values to another region of the chip in a speedy way, and using only one channel, even without first writing them to a latch cluster. In actual practice, the inputs to the demodulator delay chains to the right would be a common ORed output of the modulator XOR outputs.
[Feb 16, 16, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#190> Stepper motor type application versus ADC application of the latch cluster (Item#189) and pulse generator (Item#155)
When generating pulses for a stepper motor, for example, all the 168 pulses (see Item#188) will be required out of the latch cluster/pulse generator. It will be somewhat slower - for 999 latch cluster, 999 + 12*3 = 1035 clock cycles per sample. But, for such servo type applications, the speed should be good enough.
But, for ADC we could simply put out the significant digit number of pulses in succession, and the DAC could pick them up accordingly. This will need 3*10 + 12*3 = 66 clock cycles. Also, the write circuit of Item#189 could be redesigned to use 10 comparators instead of 1 and the write process can be turned into a combinatorial sequence to avaoid using 12*3 (36) clock cycles.
***
Item#189> A recursive write circuit for writing into the significant digits of the latch cluster, as discussed in Item#188
First, the latch cluster of Item#170 has been simplified as per later developments, note the data write inputs such as 90set, 11set, etc.
[Feb 10, 2015, Arya Raychaudhuri, Santa Clara, California]
Then the sample sensing circuit of Item#163 has been modified to recursively write into the significant digits, and then start the pulse generator. Note the successive removal of the upper significant digit, and the presentation of the remaining digits for fresh sensing. The inverter delay chains have been replaced by the new clk to Q shift register (Item#174), for better robustness. The significant digit selection takes place through the latches at the top.
[Feb 11, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#188> Generating pulses for stepper motors - a potential application of the pulse mode ADC of Item#s 163, 164, and the clk to Q latch cluster of Item#170
Angles 1 through 359 can be sampled with a modified sampler, where the analog angle data can be saved into the latch cluster (Item#170) like this - let's say, for an angle of 168 degrees, 1 will go into the 3rd least significant digit, 6 into the 2nd least significant digit, and 8 into the least significant digit. A similar scheme was discussed in an earlier grad level work:
A. Raychaudhuri and M.J. Deen, New static storage scheme for analogue signals using four-state resonant-tunneling devices, Electronics Letters, 29, 1435--1437 (1993).
Once, the saving is done the pulse generator will generate 168 pulses. This is a simplistic picture, The actual number of pulses would depend on other factors such as degrees/step, revolutions/sec, number of microsteps, etc.
But, those can be factored into the incoming analog data, and the number of significant digits can be increased to cater to the application scenario.
***
Item#187> Clk to Q updown counter schematic
[Feb 07, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#186> Key difference of the clk to Q mechanism from the prevailing designs
One of the interesting features of the clk-to-Q compare mechanism is that the stage to stage connection is taking place through a negative ~+clk pulse generated by comparing a +clk pulse to Q. In the case of shift registers, the comparing +clk pulse is simultaneous and common to all stages, and in the case of the counter, the comparing +clk pulse is derived from the negative ~+clk pulse coming from the previous stage. This is unlike stage to stage connections through Q in prevailing designs.
To look deeper into the requirements of the gate delays with respect to the pulse width (see Item#185), they refer to the pfets inside the gates (see the Sim Plate of Item#184). If the delta1 is too small, Q will rise too fast before the +clk has returned to 0 - and present an unwanted negative ctl pulse to the gate2 of the latch. If the delta3 is too small, the negative ctl pulse will rise too fast for the latch to make a conflict-free status switch, that is helped by faster nfets of gate 1 faster pfets of gate2.
***
Item#185> Logical wave diagram for the clk to Q T-flipflop
[Feb 04, 2015, Arya Raychaudhuri, Santa Clara, California]
Gate delays are indicated inside the gates, the pulse width delta-p is also indicated. For proper operation, delta1>delta-p, and delta3>delta-p should be met. To appreciate is the interesting dynamism of the clk to Q mechanism with respect to the enable/disable type flipflops currently in use.
***
Item#184> Spice simulation of the clk to Q up counter of Item#178
Note that a standard (commonly used) inverter and NAND based edge detection circuit is being used to generate the +edge and ~+edge for TFF0. An extra inverter is being used between the counter stages to help better shape the input pulses to the next stage. Ideally, the extra inverter should not be needed with better aspect ratio, pulse width, Vth optimization.
[Feb 04, 04, 2015, Arya Raychaudhuri, Santa Clara, California]
Note the control on the down swing of each ctlx pulse during 0-1 transition of the corresponding Qx.
***
Item#183> clk to Q JK FlipFlop, modified from the T flipflop of Item#177
[Feb 01, 2015, Arya Raychaudhuri, Santa Clara, California]
Q [V(qq)], ~Q [V(qqbar)] are plotted for varying J [V(jx)] and K [V(kx)] inputs, at ~Reset=1.
The output resistance of the inverted clk +edge was modeled as an always-on transmission gate:
MN0 pulseinbar vdd pulseinbar1 vss NMOS L=.045um W=0.045um
MP0 pulseinbar vss pulseinbar1 vdd PMOS L=.045um W=0.045um
***
Item#182> An important advantage of shell (or even Perl) based real time emulation (as in Item#s 38, 176, 180, 181)
The output of one circuit can be fed into the input of another - while multiple circuits can run simultaneously on one clock in the background. Leading to first approximation feels about the resulting combinations. Of course, actual circuit simulations should involve the matching of input/output impedances, drive strengths, fanouts, etc.
***
Item#181> An improved emulation code (over Item#180) that involves process forking to allow two gates run simultaneously in real time
This eliminates the need to hard code 'ctl' to 'HI' when the the clock +edge returns to 0, or when Q=0 changing to 1, *without* slowing down the real time sequence.
set +C
inverter_func () { inX=$1; if [ $inX == 'HI' ]; then outX='LO'; else outX='HI'; fi ; }
nand3_func () { in1=$1; in2=$2; in3=$3; sleep 2; if [[ $in1 == 'LO' || $in2 == 'LO' || $in3 == 'LO' ]] ; then out3='HI'; fi ; if [[ $in1 == 'HI' && $in2 == 'HI' && $in3 == 'HI' ]] ; then out3='LO'; fi ; echo $out3 > qqbarval; }
nand3_func1 () { in1=$1; in2=$2; in3=$3; sleep 2; if [[ $in1 == 'LO' || $in2 == 'LO' || $in3 == 'LO' ]] ; then out31='HI'; fi ; if [[ $in1 == 'HI' && $in2 == 'HI' && $in3 == 'HI' ]] ; then out31='LO'; fi ; echo $out31 > ctlval; }
nand2_func () { in1=$1; in2=$2; sleep 2; if [[ $in1 == 'LO' || $in2 == 'LO' ]] ; then out2='HI'; fi ; if [[ $in1 == 'HI' && $in2 == 'HI' ]] ; then out2='LO'; fi ; echo $out2 > qqval; }
pfet_func () { tin=$1; clk=$2; if [ $tin == 'LO' ]; then clk='HI'; fi; }
tx='HI'
reset='HI'
let nn=0
qq='LO'
echo $qq > qqval
qqbar='HI'
echo $qqbar > qqbarval
ck='LO'
ckold='LO'
ctl='HI'
echo $ctl > ctlval
in1X='LO'; in2X='HI'; while [ 1 ]; do sleep 7; inverter_func $in1X; in1X=$outX; echo $outX > ckval; inverter_func $in2X; in2X=$outX; echo $outX > ckbarval; sleep 1; inverter_func $in1X; in1X=$outX; echo $outX > ckval; inverter_func $in2X; in2X=$outX; echo $outX > ckbarval; done &
while [ 1 ]; do qqold=$qq; qqbarold=$qqbar; ctlold=$ctl; while [[ $ck == 'LO' ]]; do ck=`cat ckval`;ckbar=`cat ckbarval`; done; if [ $qqold == 'LO' ]; then pfet_func $tx $ckbar; nand3_func1 $tx $qqold $ck & nand2_func $clk $qqbarold ; qq=`cat qqval`; ctl=`cat ctlval`; nand3_func $ctl $reset $qq; qqbar=`cat qqbarval`; fi; if [ $qqold == 'HI' ]; then nand3_func1 $ck $qqold $tx; ctlold=`cat ctlval`; ck=`cat ckval`; nand3_func1 $tx $qqold $ck & nand3_func $ctlold $reset $qq; qqbar=`cat qqbarval`; ctl=`cat ctlval`; ckbar=`cat ckbarval`; pfet_func $tx $ckbar; nand2_func $clk $qqbar; qq=`cat qqval`; fi ; ck=`cat ckval`; done &
echo "ck ckbar qq ctl qqbar" ; while [ 1 ]; do sleep 1; ck=`cat ckval`; ckbar=`cat ckbarval`; qq=`cat qqval`; ctl=`cat ctlval`; qqbar=`cat qqbarval`; echo $ck $ckbar " " $qq $ctl $qqbar; done
***
Item#180> Shell-based emulation versus spice implementation of the 0/1 to 1/0 and 1/0 to 0/1 toggles of the t-flipflop of Item#177
set +C
inverter_func () { inX=$1; if [ $inX == 'HI' ]; then outX='LO'; else outX='HI'; fi ; }
nand3_func () { in1=$1; in2=$2; in3=$3; sleep 2; if [[ $in1 == 'LO' || $in2 == 'LO' || $in3 == 'LO' ]] ; then out3='HI'; fi ; if [[ $in1 == 'HI' && $in2 == 'HI' && $in3 == 'HI' ]] ; then out3='LO'; fi ; }
nand2_func () { in1=$1; in2=$2; sleep 2; if [[ $in1 == 'LO' || $in2 == 'LO' ]] ; then out2='HI'; fi ; if [[ $in1 == 'HI' && $in2 == 'HI' ]] ; then out2='LO'; fi ; }
pfet_func () { tin=$1; clk=$2; if [ $tin == 'LO' ]; then clk='HI'; fi; }
tx='HI'
reset='HI'
let nn=0
qq='LO'
echo $qq > qqval
qqbar='HI'
echo $qqbar > qqbarval
ck='LO'
ckold='LO'
ctl='HI'
echo $ctl > ctlval
in1X='LO'; in2X='HI'; while [ 1 ]; do sleep 7; inverter_func $in1X; in1X=$outX; echo $outX > ckval; inverter_func $in2X; in2X=$outX; echo $outX > ckbarval; sleep 1; inverter_func $in1X; in1X=$outX; echo $outX > ckval; inverter_func $in2X; in2X=$outX; echo $outX > ckbarval; done &
while [ 1 ]; do qqold=$qq; qqbarold=$qqbar; ctlold=$ctl; while [[ $ck == 'LO' ]]; do ck=`cat ckval`;ckbar=`cat ckbarval`; done; if [ $qqold == 'LO' ]; then pfet_func $tx $ckbar; nand2_func $clk $qqbarold; qq=$out2; echo $qq > qqval; ctl='HI'; echo $ctl > ctlval ; nand3_func $ctl $reset $qq; qqbar=$out3; echo $qqbar > qqbarval; fi; if [ $qqold == 'HI' ]; then nand3_func $ck $qqold $tx; ctl=$out3; echo $ctl > ctlval; nand3_func $ctl $reset $qq; qqbar=$out3; echo $qqbar > qqbarval; echo 'HI' > ctlval; ckbar=`cat ckbarval`; pfet_func $tx $ckbar; nand2_func $clk $qqbar; qq=$out2; echo $qq > qqval; fi ; ck=`cat ckval`; done &
echo "ck ckbar qq ctl qqbar" ; while [ 1 ]; do sleep 1; ck=`cat ckval`; ckbar=`cat ckbarval`; qq=`cat qqval`; ctl=`cat ctlval`; qqbar=`cat qqbarval`; echo $ck $ckbar " " $qq $ctl $qqbar; done
[Jan 26, 2015, Arya Raychaudhuri, Santa Clara, California]
Note the non-ideal, but small realistic dip in the 'ctl' during 0/1 to 1/0 transition in spice simulation result below. The dip can be reduced by further engineering on the aspect ratios, pulse width, and even Vth.
[Feb 01, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#179> On shell-based emulation of clocked digital blocks as in Item#s 38, 176
This method should be very useful to students and teachers of digital electronics, as well as to IP developers - to fully appreciate what's going on inside the circuit. As soon as a particular sub-block emulates satisfactorily, it can be turned into a sub-routine function to be invoked by the next higher sub-block. The clock running as a background process enhances the similarity to an actual chip situation.
For more interactive application of Toggle, Reset, etc., one can simply write their status (HI/LO) to a tiny file in the same directory at any point of time when the routine is running, and let the shell routine read it, just as the clock is written into 'ckval' (see Item#176), and retrieved from it.
To check on the clock +edge and inverted +edge (Item#176) as the circuit runs, do this from another shell in the same directory:
[Jan 25, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#178> A low mosfets count up counter using the T-flipflop of Item#177
[Feb 02, 2015, Arya Raychaudhuri, Santa Clara, California]
The earlier schematic given for this Item had a logical issue. The new schematic is simpler, requiring even less MOSFETs. Note that the +clk and ~+clk for stages 1, 2, 3 are generated directly from the negative going ctl pulse of the preceding stage, and that these stages no longer require the Pfet at the input.
***
Item#177> Spice simulation of a T-flipflop with just 3 NAND gates and a transistor (NAND equivalent of the NOR circuit drawn in Item#175)
[Feb 01, 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#176> Shell (bash) based emulation of the toggling with the T-flipflop of Item#175
[Jan 22, 2015, Arya Raychaudhuri, Santa Clara, California]
Which NOR reacts first to clk edge/~clk edge - that starts the sequence in the phenomenological modeling.
***
Item#175> clk to q compare based T-flipflop with just 3 NOR gates and a transistor - for use in an up counter, such as in Item#s 150,155
[Jan 21. 2015, Arya Raychaudhuri, Santa Clara, California]
The NFET just dissipates the clk +edge, when T=0. The inverted clk +edge is an input to the control NOR gate on the right.
***
Item#174> Simulation of a 8 bit Left to Right shift register using 3 NAND stages (Item#172) - disruptive and pervasive
[Jan 19. 2015, Arya Raychaudhuri, Santa Clara, California]
Item#173> The clk to q compare based data shift (Item#s 170-172) leads to a Left-to-Right *and* Right-to-Left shifting shift register with just 4 NANDs per stage (positive edge triggered shift)
[Feb 15. 2017, Arya Raychaudhuri, Santa Clara, California]
Compare this with a typical bidirectional shift register as on https://www.allaboutcircuits.com/textbook/digital/chpt-12/parallel-in-parallel-out-universal-shift-register/, 5 gates of D-flipflop, and 3 gates outside the flipflop are replaced by just 4 NAND gates.
***
Item#172> Simplification of control gates in the down shift cluster of Item#170 leads to a Left-to-Right shift register with only 3 NAND gates per stage (positive edge triggered shift)
[Jan 17. 2015, Arya Raychaudhuri, Santa Clara, California]
No D-flipflop with 5 gates neededfor this shift register.
***
Item#171> Edits for Up/Down shifting on the down shifting latch cluster of Item#170
Edits to the least significant digit shown here - 'up' = 1 for up shifting, 'up' = 0 down shifting
[Jan 17. 2015, Arya Raychaudhuri, Santa Clara, California]
Now, the same latch cluster can be used for adding integers, subtracting integers, storing, generating a specifiable number of pulses. How many times a set of pulses can be subtracted from the stored value on the cluster can give the result of a division. Running the pulse generator for a specifiable number of times with pulses from another cluster can give rise to a multiplication product that can be stored in a cluster like the above.
***
Item#170> Creating specifiable large number of pulses from the pulse generator of Item#155
For many applications, including decimal calculations, or pulse based relative addressing in a multiplexing situation, many pulses would be required out of the pulse generator, under decimal control. The following schematic shows how a 3-digit decimal number can be reduced to 000, using exactly as many pulses, e.g., a number 235 stored in the three significant digits as 5, 3, and 2 will go down to 000 with exactly 235 pulses.
vpulses pulses 0 PULSE (0 1 10ns 0.1ns 0.1ns 19.8ns 40ns) were applied to get the following simulation result
[Jan 16. 16, 2015, Arya Raychaudhuri, Santa Clara, California]
See that the 000 occurs at 9370ns (10 + 234*40), which is the rising edge of the pulse# 235.
So, how the scheme will work?First the channel# (push button# of the pulse gen Item#155) corresponding to the initial stored value (5 in this case, indicated by q50 latch at 1) on the least significant digit will open to produce so many pulses (5) to also bring the digit0 latch to 1 (q00=1), This will reset the counter without resetting T0, clk. Immediately, channel#10 will open on the pulse gen, and keep repeating the 10 pulses set until the latch farm reaches 000, i.e., q00=1, q01=1, and q02=1.
The schematic indicates how by increasing the number of significant digits, very large decimal integers can translate to pulse domain, for further processing.
***
Item#169> Possibility of basic decimal integer addition and subtraction using the concepts of pulse generator (Item#s 155-156) and voltage monitor (Item#150)
Since double the number of Q0 pulses need to be applied as clk for the voltage monitor to get equal number of Q0 pulses out of it, one can split each pulse gen pulse into two pulses and apply to a reconfigured voltage monitor. That way, 3 pulse gen pulses and 4 pulse gen pulses released sequentially from the pulse gen will give rise to 7 voltage monitor pulses. Also, among the 0-9 least significant digit latches (outside the counter), digit 7 will be set. When the pulse count exceeds 9, the counter will be reset and start again from 0 - holding the carry digit in the next significant digit latch. Thus, 6 and 7 will result in 13 pulses from the voltage monitor Q0, and also, least significant latch 3 will be set, and the next significant latch 1 will be set.
If the two numbers need to be added, the instruction will make the pulse generator release the two numbers sequentially. If the instruction is to subtract, the two pulse sets (numbers) will be released simultaneously, and first go through a destructive interference (XOR) before entering the counter, following a 1-to-2 split. The sign (+/-) of the result can also be stored as (1/0) on a separate latch.
***
Item#168> An additional 'start' button circuit for the pulse generator (Item#155) to generate the three 'open sesame' pulses that enable the Clk line (see Item#167) for the voltage monitor
[Jan 11. 2015, Arya Raychaudhuri, Santa Clara, California]
Simulation results for the three nodes marked 'pulseout', 'qlx', and 'resetlx' are shown below. Note that the three positive pulses V(pulseout) will be transformed into three negatives by the edited output section of the pulse generator of Item#155.
[Jan 11. 2015, Arya Raychaudhuri, Santa Clara, California]
* One useful resource for XOR based pulse generation/modification is here -
http://www.edn.com/Home/PrintView?contentItemId=4423513
***
Item#167> A safety feature for the voltage monitor schematic of Item#150 - will require three negative reset pulses to enable the pulse (clk) line
This will ensure that a voltage monitor/application line doesn't get enabled by spurious pulses on the clk line.
[Jan 10. 2015, Arya Raychaudhuri, Santa Clara, California]
The three negative starting pulses will be generated by an additional 'start' button of the pulse generator (Item#155). In the case of the multi-channel voltage applicator cum monitor, the ch15sel pulse will turn off (unset) the latches (above), instead of the regular 'reset', and there will be no auto-generated 'reset' after the ch15 pulses, the ch15sel will also clear the counter.
***
Item#166> Pulse mode DAC schematic to go with 1-15 levels ADC of Item#s 163-164.
The schematic is derived from that of the voltage monitor of Item#150.
Note that the reset pulse first enables the transmission gate after the unity gain buffer for the voltage level to be held by the holding cap C, and then after a 10 inverters delay, resets the counter. Pulses (13 in this case) are being used to push the counter to state 13 (1101) so that the level select 4-input AND gate can enable the transmission gate next to it, and pass the level 13 of the potential divider resistor-chain onwards.
[Jan 08. 2015, Arya Raychaudhuri, Santa Clara, California]
***
Item#165> How to avoid unknown (X) state related glitches due to the transmission gate near the leading and trailing ends of the transmission gate pulse after the comparator (Item#163)
Using a slightly thinner and slightly delayed pulse (late rise early fall) for the xgate after the comparator. The thinner pulse can be generated out of the delay chain at the top. So, instead of using the level13 pulse to the xgate after the comparator, one can use the thinner pulse out of the delay block to the right of the level13 pulse node.
The transmission gates based approach (as in Item#163) can be used also for parallel to serial, and serial to parallel bits conversion. In some cases, a thin pulse can be widened back using inverters and a latch.
***
Item#164> Pulse mode ADC pulse generation - edits on the circuit of Item#155
Once the Level 13 MOSFET is turned on, 13 pulses are generated in this manner:
[Jan 07. 2017, Arya Raychaudhuri, Santa Clara, California]
Note that in this scheme (protocol), the DAC (to be built from the voltage monitor of Item#150), will need no clock. The pulses themselves will serve as clock pulses to the counter, and the 'reset' pulse as the demarcator. Since the MOSFET is turned on by the 'resetOut' of Item#163, and the 'reset' is generated everytime by the same logic after 15 pulses from the counter (above), the clock here is kept free running. The counter is not working between the 'reset' and turning on of the MOSFET, that is, during the sample sense phase.
Instead, if we had a binary output, the DAC would need a clock to run the DAC counter, and bring it to the latched binary states. At which point, the chxxsel AND of the DAC would open the appropriate channel (voltage level).
***
Item#163> Sample sensing and blue chxx push-button replacing circuit for Pulse Gen (Item#155) converted to ADC
Cycling the start/reset pulses through a delay chain (top) reduces the number of comparators needed to just 1.
[Jan 02. 2015, Arya Raychaudhuri, Santa Clara, California]
In order to get binary outputs instead of pulses out of the pulse generator (Item#155) turned ADC, the Q0 through Qn states would be output, instead of just Q0 pulses, and you would need one less counter stage.Just rewiring the 'chxxsel' AND gate inputs will make that transformation.
***
Item#162> Happy NewYear 2015! How about using the Pulse Generator (Item#155) and the voltage monitor (Item#150) for AtoD and DtoA conversion?
For example, using the sampled voltage levels as the push buttons, and generating n pulses for the nth level, and then converting them back to Analog using the voltage monitor that has the levels on the channels. Will look into this possibility.
***
Item#161> Conceptual reason why the Qx.~Tx and ~Qx.~Tx feedbacks were needed in the T-flipflop of Item#152
Whether it is +edge triggered or -edge triggered, in any MasterSlave T-flipflop, the Qx/~Qx toggle (if Tx was or shifted to 1 during the preceding clock cycle) only when the Slave clk is positive. When the Master clk is positive ~Qx/Qx are logically transmitted to MQx/~MQx. So, we do not need to separately understand +edge and -edge.
The following diagram illustrates the conceptual problem for the AND-NOR flipflop (same can be shown for the all NAND implementation) without the special Qx.~Tx and ~Qx.~Tx feedbacks to the Master NORs. If there is a delay in Tx's shifting from 1 to 0 beyond the positive phase of the Slave clk, MQx/~MQx will remain latched to a toggle ready mode. This delay can be caused by high frequency clocking whereby the Slave positive phase becomes thin, or unequal clk duty cycle, or by multiple gate delays such as with the later stages of the counter or Tx coming from a different datapath.It is to be noted that the total gate delay in the counter context will also include the delays introduced by the Slave AND and NOR gates. The Qx.~Tx and ~Qx.~Tx feedbacks compensate for the delayed 1-0 shift of Tx.
[Dec 29. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#160> Chip function altering from outside the chip with OnChip voltage monitor/applicator (Item#150)
The following diagram shows how a chip's function can be altered by deactivating an active sub-block and activating an idle sub-block using the OnChip voltage monitor of Item#150, running it in a voltage Applicator mode.
[Dec 25. 2014, Arya Raychaudhuri, Santa Clara, California]
Obvipusly, by using a multi-CHannel OnChip voltage applicator/monitor, more such changes can be accomplished. But, that will need more than just two extra pins for the chip. For example, 5 extra pins for 4 simultaneous CHannels.
For all applications of the voltage monitor/applicator, pulse generator, all grounds (chip, voltage sources, meters, pulse generator) must be shorted together, for known reasons.
***
Item#159> Quiz23: Remove the requirement of pushing the 'reset' button after each 'chxx' button for the combined pulse generator and multi-CHannel voltage applicator/monitor discussed in Item#158
For the OnChip single CHannel voltage monitor (Item#150) and the OffChip Pulse Generator (Item#155), pushing the 'reset' button at the end of the measurements make sense. But, when the two functions are combined for a multi-CHannel OffChip device, we would rather remove the requirement of pushing 'reset' after every 'chxx' push, and also at the end. How would you accomplish that?
Answer:
See the following modification .to the relevant section of the Pulse Generator circuit of Item#155. The 'reset' button is replaced by an NMOSFET whose gate is now tied to 'chxxsel' , the output of the channel/number-of-pulses selection AND gate. The inverter delay chain is also adjusted to give a little bit delay to the reset pulse. The reset pulse gets a bit thinner, but, that's Ok.
[Dec 24. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#158> Busy detection and new input/output CHannel opening for multiple simultaneous channels activation with voltage monitor of Item#150
As discussed in Item#157, a combined pulse generator and voltage monitor circuit used in an offChip environment can cater to various probe card channels in a simultaneous opening mode. An example of up to 4 input/output CHs is shown below, with the ch15 push-button being used to clear the open CHs. After each chxx push-button, the reset button must be pressed to open that 'xx' (1-14) channel of the probe card. When 1,2,3, or 4 CHs (input/output, for voltage/current application and monitoring) are opened, the measurements are done. Finally, press ch15, followed by 'reset' again to clear the system. The 'chxxsel' used in the following diagram refers to the output of the 4-input channel selection AND gate at the bottom of the schematic in Item#150. Instead of a single output CH (chip pin) following the AND gate in that schematic, here you see up to 4 CHs being assigned to the incoming channels, in a logical way
[Dec 23. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#157> Multiple simultaneous channels for voltage application and measurement using modifications to the voltage monitor scheme of Item#150
Typical parametric measurements using PCM devices involve probing the devices using probe stations and measuring the I-V characteristics - applying voltages from external voltage sources and measuring currents using external Ammeters. But. this introduces some inaccuracies as exemplified by the following diagram:
[Dec 21. 2014, Arya Raychaudhuri, Santa Clara, California]
As is apparent, Ids is actually Vdd/(Ron+R1+R2), Vds is actually Vdd- Ids*(R1+R2), and Vgs is actually Vgg-Ids*R2. Typical assumption that Vds=Vdd, Vgs=Vgg would be true if R1=R2=0 were to be true. Since R1 and R2 are not clearly known, and can vary from measurement to measurement, the inaccuracy in the measured Ids-Vds curves at different Vgs is obvious. This inaccuracy can be avoided by the following arrangement:
[Dec 21. 2014, Arya Raychaudhuri, Santa Clara, California]
Since voltmeters have high input resistance, any probing resistance leading up to the pick up points of Ch2 and Ch3 can be neglected. A known resistance Rd is placed close to the MOSFET, and the source is locally grounded, also close to the device. We are keeping 4 simultaneous channels open, Ch1 for applying Vdd, Ch4 for applying Vgg, and Ch2 and Ch3 are meant for measuring the potentials VA and VB across the resistance Rd. Now, we can clearly assign, Ids = (VA-VB)/Rd, Vgs = Vgg, Vds= VB.
4 simultaneous channels can be opened by modifying the schematic of Item#150, where we would RS-latch the channels, and sacrifice one channel (e.g., ch15) to unset the RS-latches.
***
Item#156> More possibilities out of the pulse generator of Item#155
As is obvious from the schematic drawing of the pulse generator (Item#155), for any number of pulses to be output, the counter state needs to be pushed to double that number. For example, for 4 pulses, the counter state is pushed to 8 (01000), and therefore, the channel4 selection 6-input AND gate receives ~Q0,~Q1,~Q2,Q3,~Q4 outputs from the 5-bit counter. For 15 pulses, the counter state must be pushed to 30, that's why a 5-bit counter is needed. So, a 6-bit counter will generate a max of 31 pulses, a 7-bit counter will give a max of 63 pulses and so on. This way, one can increase the number of channels to select using the voltage monitor circuit of Item#150.
Some other application of the pulse generator may require alternate positive and negative pulses. That also can be accomplished by extending the concept of positive clk pulses and negative reset pulse generation.How about 5 positive clk pulses, followed by 3 negative clk pulses?
***
Item#155> Push-button operated Pulses (clk/reset) generation circuit for use with the on chip voltage monitor (Item#150-154) - four pulses and reset example shown
[Dec 19. 2014, Arya Raychaudhuri, Santa Clara, California]
Pressing and releasing 'Push button 4' generates four 40ns pulses for a 25MHz free running clock input. These will select the channel 4 of the OnChip voltage monitor. Pressing and releasing the 'reset' button after voltage monitoring for the channel 4 is over, generates a negative (0/-1) 14ns reset pulse
[Dec 17. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#154> clk-reset differentiation and channel4 readout (see Item#150) simulated, using the core 4-bit counter of Item#153
[Dec 15. 2014, Arya Raychaudhuri, Santa Clara, California]
The top frame shows the 4 positive clk pulses, and the negative resetting pulse (at the end of the readout). The output Sel4 of the ch4 readout 4-input AND gate is also plotted here. The middle frame shows a dc readout, for example, a power line with IR drop. The third frame shows a pulse train data readout, for example, a point on a datapath/clockline. The extra transistor MN0X4 helps bleed any residual voltage on vmpin (voltage monitor pin). The clk/reset pin is 'clk' that supplies the clock and reset pulses - and they are processed by the deepNW transistor switch 'MC' (Item#149).
***
Item#153>Four-bit counter simulation with the positive edge triggered MasterSlave FlipFlop of Item#152
[Dec 14. 2014, Arya Raychaudhuri, Santa Clara, California]
Note that the counter is counting fine with 10ns clk pulses given at 100ns intervals. Simulation showed that the top and the bottom AND gates feeding Qx.~Tx and ~Qx.~Tx were necessary for the TFF of Item#152.When a reset pulse was applied at 470ns, the reset took place properly, and the counter started counting again from 0000 upwards, as shown below.
[Dec 14. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#152>T flipflop with JK MasterSlave connections and Toggle simulation
The width limitation on the clk pulses (Item#151) is removed with the following MasterSlave T-flipflop
[Dec 13. 2014, Arya Raychaudhuri, Santa Clara, California]
The positive edge triggering is accomplished with applying the clk to the Slave stage and ~clk to the Master stage. In the regular operation, when Tx=1, and clk=0, the Qx, ~Qx pair transmits to MQx, ~MQx respectively, and keeps the Slave stage in a toggle ready mode as soon as a positive clk pulse (clk=1) is received. But, as seen in Item#150, the counter stages Q1 through Q3 can receive Tx=0 in normal operation. If Tx turns to 0, however, the MQx, ~MQx pair are still held in their toggle-ready state, irrespective of clk. So, the next clk pulse will toggle the Slave stage. So, there is a need to invert the MQx, ~MQx pair, when Tx goes to 0. This is accomplished by feeding the Qx.~Tx and ~Qx.~Tx to the NORs of the Master stage. This is an interesting addition.
The simulation results using 45nm PTM LP model V2.1 (Arizona State University) are shown below:
[Dec 13. 2014, Arya Raychaudhuri, Santa Clara, California]
The top plate shows the clk (green), toggle(pink) and reset(red) pulses, the bottom plate shows the toggling of Qx (red) and ~Qx (yellow). See that there is no impact of clk pulse width, and the toggling takes place in an expected way, no toggling during Tx=0. The reset successfully pushes the Qx to 0.
As an experiment, if I remove the Qx.~Tx and ~Qx.~Tx feeds through the top and bottom AND gates, there is unwanted toggle when Tx=0:
[Dec 13. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#151> Width limitation of the clk pulses used in toggling the AND-NOR TFF (Item#150) simulated with spice
I chose a slower Level3 spice model (courtesy, a Silvaco flipflop simulation example) corresponding to a 2um CMOS node - this helped specify somewhat sizeable clk pulses (1.8ns thin). RingOscillator simulation showed a NOR delay of 0.8 ns - since there are three gates in series, NAND, INV, NOR, the path delay is between 2 and 2.4 ns. So, the 1.8ns clk seemed reasonable. One clk pulse was chosen to be 6.4ns wide to demonstrate the toggling anomaly. The simulation results are shown below :
[Dec 11. 2014, Arya Raychaudhuri, Santa Clara, California]
As shown above, the first 6.4ns clk pulse fails to toggle - when the V(qq)[Qx] was going up, the new Qx pushes it down. The other thin clk pulses toggle as expected. Tx was set to 0 between 80ns and 110ns, so the clk pulse at 90ns doesn't toggle. The reset pulse works fine.
***
Item#150> Multiple points voltage monitor using the Deep NW switch (Item#149), and a synchronous digital counter (see Item#38)
[Dec 10. 2014, Arya Raychaudhuri, Santa Clara, California]
A synchronous digital up counter using T flipflops is nothing new - let me briefly explain the operation. See that there are 4 T flipflops (Q0, Q1, Q2, Q3), named after their primary outputs. For any TFF(Qx), when the toggle input (Tx) is 0, the outputs of two AND gates are unconditionally 0, irrespective of clocking pulse or the states of Qx and ~Qx. So, if the reset line is 0 (typical state) , the two NOR gates act as cross-coupled inverters and sustain the existing states of Qx and ~Qx. Same thing happens if Tx is 1 but clk is 0.
When Tx is 1 and clk goes to 1, if the Qx was 1, the output of the upper AND will be 1, and the output of the lower AND will be 0, since ~Qx was 0. Now, with reset=0, the upper NOR inverts the 1 to 0 (new Qx), and lower NOR toggles ~Qx to 1. Now, if the clk pulse is kept extremely narrow compared to the gate delays, such as the output of a positive edge sense circuit [refer to Item#38 shell emulation, if[[$ck=='HI' && $ckold=='LO'];then posedge = 'Y';fi; ckold=$ck), the new states of Qx and ~Qx will be sustained since clk returned to 0, before the new states could impact the output of the AND gates. Similar logic holds for Qx=0/~Qx=1 toggling, since the structure of the TFF is symmetrical.
Since T0 is always '1', the Q0 will always toggle at a clk pulse - so the counter goes from 0000 to 0001 at the first clk pulse. Since '1' is now presented to T1, the next clk pulse will toggle both Q0 and Q1 - taking the counter to 0010. The third clk pulse moves it to 0011. The AND gates at the top produce a '1' when the lower significant bits are all '1's. So, the fourth pulse takes it to 0100, and so on.
Whenever a particular channel needs to be read, just send as many clock pulses, for channel 4, 4 extremely narrow pulses will take the counter to 0100. The channel selection logic for each channel involves a 4-input AND gate that takes Qx for the 1's, ~Qx for the 0's in the counter state, so for the chanel 4, the inputs are ~Q0, ~Q1, Q2, ~Q3 - the idea is to make the output of the AND to be 'HI' so the transmission gate can transmit the channel voltage to the voltage monitor pin. When the channel is satisfactorily monitored, send a reset pulse (0/-1) to reset TFFs - see that the output of the deepNW switch is inverted to present a '1' to the upper NORs. This way, only the Qx=1, ~Qx=0 situations will toggle to make it 0000 as the reset counter state. Then go for another channel. So, out of the 16 possible states of the counter, 15 can be used to read separate channels (dc or pulse trains), and one (0000) is reserved for resetting the counter.
The restriction on the width (very narrow edge sense types) of the clk pulses can be removed by using master/slave JK flipflops for the TFFs. For positive edge triggering, clk will be applied to the slave, and inverted clk to the master.
***
Item#149> Deep Nwell negative pulse to counter reset pulse generation switch
Towards building a multiple points voltage monitor (for runtime chip diagnostics), a synchronous digital counter (see Item#38) based approach can be envisaged. This will require two pads (chip pins) - one for passing the clocking and reset pulses, and the other for voltage monitoring. One can use 0/1 postive pulses for clocking, and 0/-1 negative pulses for reset. Then, it is important to differentiate between clocking and reset pulses through internal switching. The following configuration does that:
[Dec 08. 2014, Arya Raychaudhuri, Santa Clara, California]
The reset/clock pulsing is applied to the B and S terminals (connected together).
See from the following spice simulation that only during reset pulsing (0/-1) the voltage level V(1) goes to ~0V, while during the clocking pulse (0/1), the V(1) holds at 1V. While the CMOS clock sensing circuitry is unaffected by (0/-1) since the NMOS of the CMOS remains off, and PMOS remains on during such transition:
* Simulation done with LTspiceIV, with an ASU PTM model
***
Item#148> Where tech work and art meet
Some physical verification JPGs come out so good that they could be hung on the walls of an art museum. Here is an example of net traces (yellow) leading from npvss150 ERC errors (magenta) with a background of Nwell rows (red). Npvss150 refer to gates directly tied to VSS - in the absence of sufficient DCAPs in the chip, they could be a problem.
[Dec 06. 2014, Arya Raychaudhuri, Santa Clara, California]
** Coutesy my work for Esilicon corporation.
***
Item#147> YOYO code for controlling the depth of recursion in graphs path tree extraction (See Item#125)
The YOYO code is accomplished with some simple edits to the original routine discussed in Item#123. See that I have added some additional code in 'orange' to the code of Item#123 below, 'grey' lines indicate contexts, 'red' indicates commented out lines:
@valid_path_str_array = ();
open(Fx, ">$outfile");
$vertx = $start_pt;
$rec_depth = 0;
while (1) {
$rec_depth = 0;
$rec_stop = 0;
&find_path($vertx);
}
##&find_path($start_pt);
::::
sub find_path {
$rec_depth++;
($vertx) = @_;
if (($rec_depth == 1) && ($#valid_path_str_array >= 0)) {
}
else {
if ($matchx == 0) {
push(@pathx,$vertx);
}
@pathx_mem = @pathx;
}
::::
print $pathnum, "***GOT A PATH***", "\n";
print "Recursion Depth: ", $rec_depth, "\n";
::::
pop(@pathx);
$vertx = $pathx[$#pathx];
$rec_stop=1;
return;
}
::::
$matchy=0;
if ($rec_stop == 0) {
&find_path($kx);
}
::::
exit;
}
if ($rec_stop == 0 ) {
pop(@pathx);
&find_path($pathx[$#pathx]);
}
}
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
See that I have introduced the global variable $rec_stop to sense the finding of a valid path and return the control to the infinite 'while' loop.
Also, if (($rec_depth == 1) && ($#valid_path_str_array >= 0)) will return 'true' for all first entries into &find_path after a successful path find to maintain the pop-ed status of @pathx before the return. It will return a 'false' for all recursive entries (because, $rec_depth>1) . and also for the initial first entry (when, $#valid_path_str_array= -1) .
***
Item#146> GDS representation and netlisting of a building design
Nov 26, 2014
Speaking of interdisciplinary applications of physical verification concepts (coutesy, my discussion with a potential client earlier), here is an interesting way a multi-storied building can be represented in a GDS database:
[Nov 28. 2014, Arya Raychaudhuri, Santa Clara, California]
See that unit1xx is an instance of a unit (a subcircuit) in the first floor. The pieces corridor cor1x (userd-defined device) connect the units in the first floor, and themselves, using interconnects in metal1. For the second floor, it will be unit2xx, cor2x, metal2, etc. The elevator is a stacking of Vias connecting metal1 to metal2, metal2 to metal3, etc.
Each unit (subcircuit) can have sub-entities like Kitchen, bathroom. living room, bedroom, balcony, etc, each with a unique set of property values, like, area, number of windows, doors, fixtures, etc.
***
Item#145> A disruptive application (Item#143) turned into a constructive one - a rudimentary environmental radiation detector
Please consider the following diagram:
[Nov 19. 2014, Arya Raychaudhuri, Santa Clara, California]
One can play with the number of series diodes (solar cells), their material composition (Eg), CMOS inverter threshold voltage, battery supply voltage, to target various ranges of radiation frequencies/doses.
I am not sure if this type of radiation detector is already constructed by someone (no literature survey done) - but, this looked like a natural extention to the configuration discussed in Item#143.
***
Item#144> Some thoughts on Item#143
Item#143 shows how easy it is to stop the logical flow in a digital system using radiation from a remote source. Obviously, the piece of circuitry shown can occur inside the chip, as well as in the outside chip-to-chip, board-to-board, or even in the subsystem-to-subsystem connection environments.
If it is inside the chip, we can apply netlist ERC methods (such as parsing) to detect such configurations. But, if it is outside the chip, a thorough inspection using other techniqies, not excluding system level netlist ERC, can be applied. Most importantly, the digital system must be rigorously tested under various radiation situations, and the encasements should be radiation-proof.
An interesting afterthought relates to the impact of radiation on the circuits in the human brain. Radiations can have a pernicious effect in that case too, sometimes even irreversible (more like PROMs rather than solar cells). Obviously, you should not test the human brain under various radiation situations, but, must ensure that the environments in which the brain functions are radiation free.
***
Item#143> How radiation on a stack of three diodes can scuttle digital logic flow
Earlier (Item#1 and Item#65) we had discussed parsing a stack of three forward biased diodes between VDD and VSS, as a potential leakage structure. Now, we look at their potential impact on digital logic if they start working in solar cell mode, generating photovoltage across the stack. Please, consider the following diagram:
[Nov 17. 2014, Arya Raychaudhuri, Santa Clara, California]
See that by shining radiation the logical value of 'a' no longer transmits as 'a' at the output of the twin NOR gates, but, the output simply gets stuck at '1', irrespective of 'a' being '1' or '0'. The solar cell open circuit voltage (Voc) generation is explainted with the help of band diagrams (Courtesy, Physics of Semiconductor Devices by SM Sze):
[Nov 17. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#142> Path tree algorithm (Item#122-127) for complex crimes solving
Complex crimes often happen through a chain of command - let's assume that A is the mastermind. Now, A tells P regarding the plan, P then passes some money to Q. It is Q's task to do the execution of the crime, e.g., an arson on a densely populated apartment building. Q uses an intermediary J and pays him some money to hire a petrol bomb thrower V. V does the job T (see that we assign the crime itself a hash identity). So, the full path to the crime is APQJVT. If the path is long, it is often difficult to trace it.
So, the methodology would involve creating a suspects space with all possible suspects, and assigning them hash identities that define their connections. Now, apply the path tree algorithm to find all the possible paths - then invalidate lots and lots of paths using specific details of the connections. This will narrow down the search to the path you are looking for.
***
Item#141> Example of a multi-lingual (shell-tcl-svrf-perl) flow to convert a layout from one fab's design rules to another's at the same tech node ...
The 'tech_convert' wrapper shell script (see flow diagram below) controls the flow, and it takes two arguments - gdsPath and block_name. The script invokes the central calibredrv tcl 'Tsmc2fuji.tcl' which first accomplishes cell-by-cell base layers changes through the shell scripts svrf.csh and svrf2.csh. These two run the base layers sizing svrf scripts ('poly_size.svrf', 'diff_size.svrf') and feed the data back into the 'Tsmc2fuji.tcl'.
Once the cell-by-cell edits are over, the 'tech_convert' facilitates running of the block level DRC correction svrf scripts - 'check_cover.svrf', 'check_coverX.svrf', 'check_coverZ.svrf'. These are also invoked from the central tcl script. Then the converted layout is checked by the target fab's (fujitsu, in this case) design rules. The flow this far is tweaked till the DRC results are satisfacory.
[Oct 17, 17, 2014, Arya Raychaudhuri, Santa Clara, California]
Once the DRC results are satisfactory, the 'tech_convert' goes on to correct multiple cell placements in the target gds. Recursive hierarchy extraction tcls (courtesy, Mentor Graphics), 'source_hier.tcl', and 'target_hier.tcl' extract the hierarchies of the source and target gds files - and the difference, 'hier_diff_new' is fed into the multiple placements correcting recursive perl 'dd.pl'. This perl routine uses an instances computing tcl 'inst.tcl' to generate an excess instances deleter tcl 'dd.tcl'. The 'tech_convert' then runs this 'dd.tcl' with calibredrv to accomplish the final target GDS file. The last step is to verify the LVS correctness of the 'Final GDS' using the 'Fuji_lvs.rules'.
** Courtesy, my work for Jasper Display Corporation in 2011
***
Item#140> The original manuscript of the junctions Vias deficiency checker adder paper (Item#9) now added to a new page "via check add paper" of this website ...
For easier access to readers. Although I had developed the algorithm earlier, I presented the paper when I was with Fastrack Design, San Jose, CA.
***
Item#139> Selecting an appropriate M4 size/spacing combination within a pitch box (Item#138) to achieve a target metal density with linear programming (LP) approach
Please, consider the following diagram
[Oct 13. 2014, Arya Raychaudhuri, Santa Clara, California]
Any point on the objective line intersecting with the constraints satisfaction box is a solution. If we choose to select the smallest size, we go for x1=4, x2=1, if we go for the largest size, we go for x1=10,x2=2.5.
Once the size and spacing are selected. you can use Calibre's RECTANGLES construct to populate the design with the fill pattern, subtracting fill polygons from the exclusion zones (like analog blocks), and within DRC spacings from circuit M4 lines.
***
Item#138> Metal fills over-density correction using random numbers
(Item#99 revisited)
This can be accomplished by sprinkling random dots over a fill pattern, and removing the polygons whose pitch rectangle interacts with a dot, as shown below:
[Oct 12. 2014, Arya Raychaudhuri, Santa Clara, California]
See that the pitch boxes are 5um x 5um, and the M4 rectangles are 4um x 4um). So, the current, metal density in the 20um x 20um space is 64% (16/25). Now, we want to bring the density below 50%, which means we need < 12.5 rectangles (400*0.5/16) in place of 16 that are there in the fill pattern. So, deleting 4 rectangles in a random fashion should suffice.
Create two sets of 4 random numbers with the rand() function in Perl, between 0 and 20: (x1, x2, x3, x4) and (y1, y2, y3, y4). Now, in Calibre, create little rectangles at (x1,y1), (x2,y2), (x3,y3), (x4,y4) - as shown by the red dots in the above fills diagram. Then subtract the M4 pieces whose pitch boxes enclose the dots to get a corrected fills pattern:
[Oct 12. 2014, Arya Raychaudhuri, Santa Clara, California]
This procedure ensures that majority of the fill rectangles remain unchanged - minimizing the perturbation to the parasitic environment.
***
Item#137> The series-parallel resistance splits of Item#131 explained with a diagram and a numerical example
[Sep 26. 2014, Arya Raychaudhuri, Santa Clara, California]
Example:
R= 10, R1= 15, R2=20, R3=25, R4=30 (all in Ohms) Va = 5V
Using traditional resistance reduction
Req = 10 + 15*20*25*30/(15*20*25 + 20*25*30 + 25*30*15 + 15*20*30) = 15.263
Ieq = 5/15.263 = 0.3276
v = 5 - 0.3276 * 10 = 1.724
Number of basic computaions to get v à 19
Using series-parallel splits
Rx1= 10*(1+ 15/20 + 15/25 + 15/30) = 28.5
Rx2= 10*(1+ 20/15 + 20/25 + 20/30) = 38
Rx3= 10*(1+ 25/15 + 25/20 + 25/30) = 47.5
Rx4= 10*(1+ 30/15 + 30/20 + 30/25) = 57
v = 5 * 15 /(28.5 + 15) = 1.724 (Rx1 – R1 branch)
v = 5 * 20 /(38 + 20) = 1.724 (Rx2 – R2 branch)
v = 5 * 25/(47.5 + 25) = 1.724 (Rx3 – R3 branch)
v = 5 * 30/(57 + 30) = 1.724 (Rx4 – R4 branch)
See that node voltages are preserved.
Number of basic computaions to get v --> 10
Check to see parallel combination of Rx1, Rx2, Rx3, Rx4
28.5*38*47.5*57/(28.5*38*47.5 + 38*47.5*57 + 47.5*57*28.5 + 28.5*38*57) = 10 (= R, verified)
Since the node voltages (v) are preserved, the branch currents v/R1, v/R2, v/R3, v/R4 are identical between the two sides. So their summation (Ieq) is also identital, so is also Req (=Va/Ieq).
***
Item#136> Creating pins hash out of a subcircuits hierarchy- making them amenable to the path-tree algorithm (Item#122-126)
September 8, 2014
Consider the following simplified diagram (in reality, there could be 100s of subcircits, and 1000s of pins/ports)
[Sep 08. 2014, Arya Raychaudhuri, Santa Clara, California]
For example, TopCell calls Sub1, Sub2, and Sub4; Sub1 calls Sub3; Sub2 calls Sub3, and Sub4; Sub3 calls Sub4. Sub4 has no instance underneath, could be a standard cell. Ports are internal nets of a subcircuit from which connections are made to sub-instances, they do not receive connections from above. Pins receive connections from above, and can also pass connections to cells below.The VDD/VSS pins are marked with separate fill patterns.
Let's refer to rows and columns by numbers going up from 1, bottom upwards, and left to right respectively. So, 2_2_Sub2 is a port, as also 3_4_Sub2, etc.1_5_TopCell is VDD, 3_5_TopCell is VSS.
The hash 3_2_Topcell has keys at 3_2_Sub1 (value 1) and 2_1_Sub4 (value 1). The hash 1_2_Sub4 will have keys at 3_2_Sub2 (value 1), 2_2_TopCell (value 1), and 2_3_Sub3 (value 1), and so on.We can keep all values of all keys of all hashes at 1, just to indicate connectivity between nodes.
***
Item#135 > Interesting utilization of the failed paths (Item#126) - as in pin propagation through subcircuit hierarchies
Even the failed paths (as discussed in the Item# 126) can have important information in some cases. For example, while looking into a pins hashes graph, if we try to compute the paths between a signal pin of a subcircuit and the top level VDD pin, ideally there should be no paths found (otherwise it's a signal-VDD short!). But, the failed paths will have the information about the signal pin's propagation.
***
Item#134> Incremental path tree extraction runs where a massive graph has already been extracted, but later some vertices/edges have been changed
The algorithm discussed in Item#126 implicitly indicates a way. Store all vertex/edge hashes in files named after the vertices in a storage directory. You can always modify/delete/add hashes in that directory. You can retrieve them back at a later run. Also, save the failed and valid paths in separate files - you can retrieve them back at a later run, and concatenate them into a new failed path strings array, after removing the paths that involve the modified hashes. The incremental paths can then be extracted at fractional runtimes. This procedure requires experimentation and validation.
***
Item# 133> Application of path trees in netlist ERC
Considering the fact that the entire design can be represented as a multi-vertex/edge graph, one can come up with applications of the path tree algorithm or its variants in analyzing the paths in the netlist. Interestingly, as opposed to the parasitic resistance mesh where the nets with parasitic resistance are the edges, the nets on a regular netlist can be the vertices and the devices on them the edges. This way, for example, one can look at the voltage domains and so on.
***
Item# 132> Resistance split of Item# 131 applied to the resistance path trees of Item# 128 - error decreases to 6.131%
[Aug 31. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item#131> Generalizing the resistance split (Item# 129) to any number of parallel branches under R
Suppose, there are 4 branches, R1, R2, R3, R4. When you are looking for the R split for R1, first get,
j= R2/R1
k=R3/R1
l=R4/R1
Then the R split for R1 is R*(1 + 1/j + 1/k + 1/l)
Similarly, for R2, R3, R4. So, the four splits will look like:
R*(1 + R1/R2 + R1/R3 + R1/R4)
R*(1 + R2/R1 + R2/R3 + R2/R4)
R*(1 + R3/R1 + R3/R2 + R3/R4)
R*(1 + R4/R1 + R4/R2 + R4/R3)
[This transformation preserves the node voltage v at the junction node. as well as the currents through the branches. The parallel combination of the splits will evaluate to R. There could be infinite ways R could be split, but there is only one that preserves the node voltage and the branch currents - unique set.
How the splits were obtained is simple. The total currents through the branches (focussing on R1) evaluate to (v/R1)*(1 + 1/j + 1/k + 1/l). That's the current that flows through R. So, in order to make the R1 split of R carry only v/R1, the R should be multiplied by (1 + 1/j + 1/k + 1/l). Same reasoning holds true for R2, R3, R4. Now, since the node voltage is preserved, the parallel combination of the splits must be R]
***
Item#130>Interesting computational advantage of the decoupled R (Item# 129) over non-decoupled when it comes to calculating the current through R1 or R2
Apart from its potential application to decoupling resistance paths from trees, the decoupled R has compute efficiency while calculating the current through R1 or R2.
non-decoupled R: 1 X, 1 +, 1 /, 1 +, 1 /, 1 X. 1 -, 1 /
decoupled R: 1 /, 1 +, 1 X, 1 +, 1 /
***
Item# 129> Partitioning of a common edge (resistance R) when it is connected to two branches R1 and R2 where R1/R2 = k [also valid for complex impedances]
The overestimation of the equivalent resistnce from the path trees can be reduced by properly partitioning the values of the decoupled common edge. Consider the following figure:
[Aug 28. 2014, Arya Raychaudhuri, Santa Clara, California]
It can be shown with simple algebra that the equivalent resistances of the two sides are exactly equal. This partitioning follows the current distributions - so, taking just the multiplicity (n, in this case 2, see Item# 128) of the edge R, and using Rx = Ry = n*R in all cases is oversimplification. In fact, that holds true only in the special case of R1/R2 = 1.
So, the algorithm to calculate equivalent resistance from a tree needs to partition the common edges along the above lines.
***
Item#128> Finding the equivalent resistance of a complex resistors network based on the extracted path trees (Item# 127)
Not only can you find the minimum resistance path between the point C and the point U (for example), you can also compute the equivalent resistance between the two points from the annotated path trees. How? Any edge (e.g., BE) that occurs multiple (n) times in all paths (211), multiply that edge length by n, and use the modified value in the path lengths where BE occurs. Then, simply combine the paths as parallel resistors.
Example:
[Aug 28. 2014, Arya Raychaudhuri, Santa Clara, California]
Using the path tree algorithm (Item# 122 through Item#127) we extract the 4 paths (ABCFGH, ABCDGH, ABEFCDGH, ABEFGH) and also mention the individual edge lengths (e.g., AB, BC, CF, FG, GH), and modify by their multiplicities. For example, AB occurs 4 times, so, its edge length 1 becomes *4 in the decoupled parallel thread (*-marked), etc:
1 2 5 8 9
*4 *4 *10 *16 *36 series resistance-- *70
ABCFGH
1 2 3 6 9
*4 *4 *6 *12 *36 series resistance-- *62
ABCDGH
1 4 7 5 3 6 9
*4 *8 *14 *10 *6 *12 *36 series resistance-- *90
ABEFCDGH
1 4 7 8 9
*4 *8 *14 *16 *36 series resistance-- *78
ABEFGH
Equiv Resistances:
18.4 - tree based (parallel combination of 70, 62, 90, 78)
16.348 - spice computed equivalent resistance
error 12.5%
[**there is some percentage of error with this scheme of decoupling of common edges, due to current distributions not exactly linearly adding up, need to do some detailed analysis]
***
Item#127> Calculation of the path lengths and sorting for minimum through maximum - somewhat trivial compared to path tree extraction
See that I have added some additional code in 'orange' to the code of Item#123 below, 'grey' lines indicate contexts:
push(@valid_path_str_array, $valid_pathx_str);
$path_length[$pathnum-1] = 0;
for ($ih=0; $ih < $#pathx; $ih++) {
$path_length[$pathnum-1] = $path_length[$pathnum-1] + ${$pathx[$ih]}{$pathx[$ih+1]};
}
${$Px_hsh}{$valid_pathx_str} = $path_length[$pathnum-1];
print $pathnum, "***GOT A PATH***", "\n";
::::
if (($#pathx == 0) && ($pathx[0] eq $start_pt)) {
$vv_mem = 0;
foreach $vv ( sort { $a <=> $b } values %{$Px_hsh} ) {
if ($vv_mem != $vv) {
foreach $kk (keys %{$Px_hsh} ) {
if ( ${$Px_hsh}{$kk} == $vv ) {
print $kk, " " , ${$Px_hsh}{$kk}, "\n";
}
}
}
$vv_mem = $vv;
}
exit;
::::
$end_pt = "U";
$Px_hsh = $start_pt . $end_pt;
@pathx = ();
It involves creating a hash 'CU' with the keys assigned to the 211 paths, and the values corresponding to the computed path lengths. The hash is later sorted for its values. Portions from the top and from the bottom of the sorted list shown below:
CBEIQU 9
CBEVIQU 9
CBEVPQU 10
CBEDKMPQU 11
CBEHIQU 11
CBEVKMPQU 11
CDKMPQU 11
CBEVPSTQU 12
:::
:::
CBFHIEDLMKVPQU 25
CDEBFHIVPMRSTQU 25
CDLMPVEBFHIQU 25
CBFHEDLMRSPVIQU 25
CDLMRSPVEBFHIQU 27
CBFHIEDLMKVPSTQU 27
The minimum path length is 9 , and the maximum is 27! This scheme can be used to compute the minimum resistance path in a parasitic resistance mesh of metallizations, and of course, in many other applications.
***
Item#126> The basic ideas behind the path tree code (Item#122 through Item#125)
1. Perl hashing of the vertices to create local hierarchies - making it easier to find the children of each node.
2. Making sure that a path does not wind on to itself using the @pathx_mem array and checking against it.
3. Accumulating the failed paths into @pathx_mem_str_array array and checking against it.
4. Whenever the path tends to wind on to itself or hits a pre-recorded failed path, or a non-endpoint pendant node is hit, pop the path and look for fresh child nodes.
5. If conditions of the step 4 do not occur ,push the path forward till it hits the endpoint.
In fact, this algorithm can be generalized to any hierarchy tree extraction problem, noting that, oftentimes the hierarchy trees can be represented as directed graphs.
For example, in a spice netlist, subcircuits invoking subcircuits will all be node hashes with children nodes, whereas subcircuits with only FETs in them are all endpoints - running the algorithm for each endpoint (start point being the top module) and concatenating the trees will produce the entire tree.
***
Item#125> Controlling the depth of recursion for the 'find_path' subroutine (Item# 123)
The 'while' loop method (Item# 124) has 0 recursion, and the 'find_path' recursive (Item#123) has unlimitedly deep recursion (like a factorial routine). It's a good idea to come up with a scheme to control the depth of recursion, depending on an event such as finding a path. This can be accomplished by combining the 'while' loop with the 'find_sub' approach. As soon as a path is found 'return' the 'find_path' and restart a new recursion. Some comparative results for paths from node U to node C are given below:
find_path
208***GOT A PATH***
Recursion Depth: 3991
UQIVPMLDEBC
209***GOT A PATH***
Recursion Depth: 4012
UQIVEHFBC
210***GOT A PATH***
Recursion Depth: 4021
UQIVEDC
211***GOT A PATH***
Recursion Depth: 4102
UQIVEBC
Fri Aug 15 15:34:32 2014
Fri Aug 15 15:34:33 2014
Combination (YOYO) of find_path and while
208***GOT A PATH***
Recursion Depth: 16
UQIVPMLDEBC
209***GOT A PATH***
Recursion Depth: 20
UQIVEHFBC
210***GOT A PATH***
Recursion Depth: 10
UQIVEDC
211***GOT A PATH***
Recursion Depth: 80
UQIVEBC
Fri Aug 15 15:31:26 2014
Fri Aug 15 15:31:28 2014
See that in the combo approach the recusion depths have been controlled to reasonable levels for each path - the monotonic rise to a high recursion depth (4102) is gone! Refer to Item#57 for a pictorial diagram of recursion.
One thing to note is that the number of valid paths from U to C must be exactly the same as those from C to U, in a graph with all undirected edges. But, it may not be so if some edges are directed (one-way street) - represented by hashes that have keys (adjacent vertex) only for outgoing edges.
***
Item#124> Quiz 22: Convert the recursive subroutine (Item#123) into a while loop - that way, you can avoid deep recursions for very large and complex graphs
Answer: The entire routine should look like this - place the code discussed in Item# 122 at the top. Next paste the 11 lines of the main program portion (at the bottom) of the code discussed in Item# 123, then paste the subroutine 'find_path' below it. So, now you got a concatenated structure.
In this structure, do the following edits:
:::
#&find_path($start_pt);
$vertx = $start_pt;
#sub find_path {
while (1) {
#($vertx) = @_;
if ($matchx == 0) {
:::
else
{
$matchy=0;
#&find_path($kx);
$vertx=$kx;
last;
:::
pop(@pathx);
#&find_path($pathx[$#pathx]);
$vertx = $pathx[$#pathx];
Note that the 'red' lines are getting commented out, the 'green' lines are coming in, the 'grey ' lines don't change
I find the 'while' loop is running a bit faster than the subroutine call - 4s versus 5s for 211 paths between C and U.
***
Item# 123> Recursive Perl to compute the valid paths between any two points on the graph of Item# 122
In the second part of the problem, I discuss a recursive perl to compute all valid paths between node C and node U of the graph shown in Item# 122:
#Arya, August 13, 2014
sub find_path {
($vertx) = @_;
if ($matchx == 0) {
push(@pathx,$vertx);
}
@pathx_mem = @pathx;
#print @pathx, "\n";
#sleep 1;
if ($vertx eq $end_pt) {
$pathx_str = join("" , @pathx);
$matchv = 0;
foreach $vpx (@valid_path_str_array) {
if ($vpx eq $pathx_str) {
$matchv = 1;
last;
}
}
if ($matchv == 0) {
$pathnum++;
$valid_pathx_str = join("" , @pathx);
push(@valid_path_str_array, $valid_pathx_str);
print $pathnum, "***GOT A PATH***", "\n";
print @pathx, "\n";
print Fx @pathx, "\n";
}
pop(@pathx);
$vertx = $pathx[$#pathx];
}
@keys_vertx = keys %{$vertx};
$pathx_copy_str = join("" , @pathx);
foreach $kx (@keys_vertx) {
$matchx = 0;
foreach $pp (@pathx_mem) {
if ($pp eq $kx) {
$matchx = 1;
last;
}
}
$pathx_copy_str_comp = $pathx_copy_str . $kx ;
foreach $pps (@pathx_mem_str_array) {
if ($pps eq $pathx_copy_str_comp) {
$matchx = 1;
last;
}
}
if ($matchx == 0) {
@keys_kx = keys %{$kx};
if (($#keys_kx == 0) && ($kx ne $end_pt)) {
$matchx = 1;
}
else
{
$matchy=0;
&find_path($kx);
}
}
}
if ($matchx == 1) {
$matchy++;
if ($matchy == 1) {
$pathx_mem_str = join ("", @pathx);
push(@pathx_mem_str_array, $pathx_mem_str);
}
if (($#pathx == 0) && ($pathx[0] eq $start_pt)) {
exit;
}
pop(@pathx);
&find_path($pathx[$#pathx]);
}
}
$start_pt = "C";
$end_pt = "U";
@pathx = ();
@pathx_mem_old = ();
@pathx_mem_str_array = ();
$matchx = 0;
$pathnum = 0;
$outfile = "CU_paths";
@valid_path_str_array = ();
open(Fx, ">$outfile");
&find_path($start_pt);
211 valid paths were computed between node C and node U. An excerpt looks like this:
CDKMRSTQU
CDKMRSPQU
CDKMRSPVIQU
CDKMRSPVEHIQU
CDKMRSPVEIQU
CDKMRSPVEBFHIQU
CDKMPSTQU
CDKMPQU
CDKMPVIQU
CDKMPVEHIQU
CDKMPVEIQU
CDKMPVEBFHIQU
:::
:::
In order to see the recursive search process, you can uncomment the lines:
#print @pathx, "\n";
#sleep 1;
[ the routine was run using ActivePerl for windows ]
***
Item# 122> Revisiting the path tree problem of Item#111
August 11, 2014
For example, consider the following graph
[Aug 12. 2014, Arya Raychaudhuri, Santa Clara, California]
As is seen, the list of all edges (vertices and lenghts) are given on the right. We call this list "path_list.txt". The problem, let's say, is to find all valid paths and total lengths between any two vertices of the graph, for example, between C and U.
In this Item we show the first part of the problem - creating the vertex hashes (Perl) out of the list, to assign the vertex name to the hash, its adjacent vertices to the keys, and the corresponding edge length to the values:
## Arya, August 11, 2014
$infile = "path_list.txt";
open(F, $infile);
$ii = 0;
@edg = 0;
while(<F>) {
$lastline = $_;
chomp $lastline;
@line_parts = split(/\s+/, $lastline);
$ex[$ii][0] = $line_parts[0];
$ex[$ii][1] = $line_parts[1];
$ex[$ii][2] = $line_parts[2];
$ii = $ii + 1; }
close(F);
$edg_max= $ii - 1;
@vx = 0;
$vx[0] = $ex[0][0];
$vx[1] = $ex[0][1];
$i_v= 1;
for ($ii = 1; $ii <= $edg_max; $ii++) {
$mm0 = 0; $mm1 = 0;
for ($jj = 0; $jj <= $i_v; $jj++) {
if ($ex[$ii][0] eq $vx[$jj] ) {
$mm0 = 1; }
if ($ex[$ii][1] eq $vx[$jj] ) {
$mm1 = 1;
} }
if ($mm0 == 0) {
$i_v++;
$vx[$i_v] = $ex[$ii][0];
}
if ($mm1 == 0) {
$i_v++;
$vx[$i_v] = $ex[$ii][1];
}
}
for ($jj = 0; $jj <= $i_v; $jj++) {
print $vx[$jj], "\n";
$vx_hsh = $vx[$jj];
for ($ii = 0; $ii <= $edg_max; $ii++) {
if ($ex[$ii][0] eq $vx_hsh ) {
$keyval = $ex[$ii][1]; $valval = $ex[$ii][2];
${$vx_hsh}{$keyval} = $valval;
}
if ($ex[$ii][1] eq $vx_hsh ) {
$keyval = $ex[$ii][0]; $valval = $ex[$ii][2];
${$vx_hsh}{$keyval} = $valval;
}
}
print %{$vx_hsh}, "\n";
}
Result
A
B4
B
F3A4C1E1
C
D4B1
D
C4K1E2L3
L
M1N1D3
N
L1
E
H2D2I2B1V1
V
I1K2P3E1
P
S1Q2M1V3
S
T2R1P1
K
M1D1V2
M
O1R1P1K1L1
O
M1
R
S1M1
F
H1G3B3
H
F1I2E2
I
H2Q3E2V1
Q
T1P2I3U2
T
S2Q1
G
F3
U
Q2
Obviously, the hash (vertex) with only one key-value pair is a pendant vertex.
***
Item# 121> On the chip offset in multichip modules
Obviously, the chip offset shown in Item# 120 is a problem - signals won't properly enter one sector or another, if the probing map (bump text positions) is kept the same for both sectors. One solution could be to have two sets of bump text positions, depending on the sector, but, that's not very practical, considering the fact that for multiple sectors ( > 2), orientations, and nestings of sealRings, there could be more sets needed! In fact, in a simple extension to 3 linear sectors, one can imagine that the middle sector will even come with a different (smaller) chip size!
Another solution could be to increase the scribe spacing between the two sectors (X and X) by two sealRing widths, that will eliminate the offset, at the cost of increaing the chip size - impacting the number of chips per wafer, as well as yield. In fact, for cases where sizes after cutting are different, the spacing increase will still keep the sizes different!
All these issues are coming up due to using the nested multiple sealRings - they are injecting all the offsets and size differences. So, the solution is to go for non-nested simple sealRing structure as shown below:
[Aug 04. 2014, Arya Raychaudhuri, Santa Clara, California]
This reduces the chip size further by eliminating the outer nestings of the sealRing.
***
Item# 120> Intersector XOR - chip cutting and coordintes shifting
As indicated in Item# 119, the two X's can be separted out from the top level multichip XX.gds.gz (topcell XX) for XOR with a CalibreDRV code, somewhat like this:
set L1 [layout create XX.gds.gz -dt_expand -preserveProperties -preserveTextAttributes]
set L2 [layout copy2 $L1 XX X0 Y0 Xm Y1 -preserveProperties -preserveTextAttributes]
$L2 cellname XX X
$L2 gdsout sector1.gds.gz X
set L2 [layout copy2 $L1 XX Xm Y0 X1 Y1 -preserveProperties -preserveTextAttributes]
set L3 [layout create]
$L3 create cell X_cell
$L3 import layout $L2 FALSE append
$L3 create ref X_cell X -(Xm-X0) 0 0 0 1
$L3 expand cell XX
$L3 delete cell XX
$L3 cellname X_cell X
$L3 gdsout sector2.gds.gz X
See that we are coordintes transforming the sector2 (the right X) to match with sector1 (the left X) - so that they are XOR worthy. The following JPG shows a superimposition:
[Aug 01. 2014, Arya Raychaudhuri, Santa Clara, California]
Obviously, even a visual XOR will reveal an offset, as exemplified by the shift of a bump pad position. The 'red' bump belongs to X of sector2, and, the 'yellow' is the corresponding bump of X from sector1. They are shifted by a sealRing width! So, naturally, if the bump text positions are adjusted for sector1, they won't fit the sector2. Now what?
***
Item# 119>Why intersector XOR is a crucial step in doing physical verification of multi-chip modules
In the following JPG, a simple conceptual case is shown where 2 CHIP X's sitting inside nested SealRings (refer to Item# 106) in a single die on the wafer, can be configured into a CHIP Y by swapping only a few Metal/Via layers. So, basically, you are getting two Chips (X and Y) by changing a few Metal/Via layers - reducing mask costs tremendously. But, the two sectors of CHIP X (left and right) must be exatcly the same, including dummy metal/via fills (to ensure identical parasitic ambients). This can be accomplished by cutting out the 2 sectors - [X0,Y0:Xm,Y1] and [Xm,Y0:X1,Y1], with CalibreDRV, and then XOR-ing them with Calibre. In reality, there can be more sectors, orientations, and combinations -making it a bit more interesting.
[Jul 31. 2014, Arya Raychaudhuri, Santa Clara, California]
***
Item# 118> Finding the parasitic resistance mismatches in IG (IndependentGate) FinFets
An independent gate FinFet will be impacted by parasitic resistances associated with the two independent channels corresponding to the two gates (gate1, gate2) as shown in the sschematic below:
[Jul 18. 2014, Arya Raychaudhuri, Santa Clara, California]
For analog applications, the matching properties of the two channels/gates are important. Ideally, one should have RS1=RD1=RS2=RD2. But, in practical devices, they won't be all equal. In order to characterize the asymmetries and mismatches, my earlier grad level work
A. Raychaudhuri, M.J. Deen, M.I.H. King, and J.Kolk, Finding the Asymmetric Parasitic Source and Drain Resistances from the A.C. Conductances of a Single MOS Transistor, Solid-State Electronics, 39, 909-913 (1996).
is very relevant.
***
Item# 117> FinFet drive strength/leakage power optimization through a simple scheme
[Jul 14. 2014, Arya Raychaudhuri, Santa Clara, California]
Although there are IndependentGate (IG), LowPower (LP), IG/LP modes that can operate with multiple supply/Vth values [as discussed in FinFET Circuit Design (Springer) by Prateek Mishra, Anish Muttreja, and Niraj K. Jha], the above scheme offers a first-hand approach to optimization. No multiple supply voltages are needed, only two Vth levels (regular, and high) - this takes advantage of the steep sub-threshold slope of FinFets. A higher Vth helps push the Id-Vgs characteristic to the right, reducing the drive strength by some percents, but decreasing leakage by a couple of orders of magnitude.
***
Item# 116> How CalibreDRV macros can be made very powerful
For example, you can put out gds/oas files from the macro code, embed shell executables inside the macro code, which in turn can run perl, svrf codes for parsing in text and polygon spaces, create Calibre databases that can be parsed in and displayed on the GUI. This is on top of the functionalities that the tool's tcl offers.
Quiz 22: Display all instances of a specifiable standard cell that do not sit within 10 microns (horizontally) of the power switching cells of the power shut-down domains
[answer won't be given!]
***
Item# 115> CalibreDRV macro code (tcl) for coordinates transformation to a subcell of the current cell in view (refer to Item# 107) - see how to develop Macros
Sourcing the following tcl in the transcripts window, will create a Macro called COORDS MACRO under the CalibreDRV GUI's Macros Menu. When you click on the 'COORDS MACRO' item, it will pop up a small window, asking the user to click on a point and enter the subcell (1 level below current) name into which to transform. When finished, GUI will diplay the subcell and take you to the transformed point (Cool!). Also, the transcript will show the relevant instance (e.g., there can be multiple instances of the subcell), and the transformed coordinates
proc ok { } {
destroy .cellName
}
proc coords_call { wb cn xy} {
set lly [$wb cget -_layoutView]
set C [$lly cell]
puts "Transform these coordinates:"
puts $xy
set xx1 [lindex $xy 0]
set yy1 [lindex $xy 1]
set xx [expr $xx1*1000]
set yy [expr $yy1*1000]
puts "From this Cell:"
puts $C
puts "To this Cell:"
puts $cn
set llx [$wb cget -_layout]
set bb [$llx bbox $cn]
set x1c [lindex $bb 0]
set y1c [lindex $bb 1]
set x2c [lindex $bb 2]
set y2c [lindex $bb 3]
set xlc [expr $x2c-$x1c]
set ylc [expr $y2c-$y1c]
##
foreach Ix [$llx iterator ref $C range 0 end -arefToSrefs] {
set cc [lindex $Ix 0]
if {$cc == $cn} {
set x0 [lindex $Ix 1]
set y0 [lindex $Ix 2]
set mir [lindex $Ix 3]
set ang [lindex $Ix 4]
set mag [lindex $Ix 5]
puts $Ix
if { $mir == 0 && $ang == 0 } {
set xt [expr $xx-$x0]
set yt [expr $yy-$y0]
}
if { $mir == 0 && $ang == 90 } {
set xt [expr $yy-$y0]
set yt [expr $x0-$xx]
}
if { $mir == 0 && $ang == 180 } {
set xt [expr $x0-$xx]
set yt [expr $y0-$yy]
}
if { $mir == 0 && $ang == 270 } {
set xt [expr $y0-$yy]
set yt [expr $xx-$x0]
}
if { $mir == 1 && $ang == 0 } {
set xt [expr $xx-$x0]
set yt [expr $y0-$yy]
}
if { $mir == 1 && $ang == 90 } {
set xt [expr $yy-$y0]
set yt [expr $xx-$x0]
}
if { $mir == 1 && $ang == 180 } {
set xt [expr $x0-$xx]
set yt [expr $yy-$y0]
}
if { $mir == 1 && $ang == 270 } {
set xt [expr $y0-$yy]
set yt [expr $x0-$xx]
}
if { $xt >= 0 && $xt <= $xlc && $yt >= 0 && $yt <= $ylc } {
set xtc [expr $xt/1000]
set ytc [expr $yt/1000]
set spc " "
set xtyt "${xtc}${spc}${ytc}"
puts "This instance contains the point"
puts "The transformed Coordinates are:"
puts $xtyt
$wb viewCell $cn
$wb goToClbk $xtc $ytc 5 um
break }
}
}
}
proc coords_plug_in { wbHandle window } {
global name
set name ""
toplevel .cellName
wm geometry .cellName +200+200
label .cellName.label -text "Click on Point and Give Cell name:"
entry .cellName.entry -width 20 -relief sunken -bd 2 -textvariable name
button .cellName.ok -text OK -command ok
pack .cellName.label .cellName.entry .cellName.ok -side left -padx 1m -pady 2m
tkwait window .cellName.ok
set xy [$wbHandle getLastMousePress1]
coords_call $wbHandle $name $xy
}
Macros create "COORDS MACRO" coords_call coords_plug_in
Macros menu
---------------------------------------
[July 2014, Arya Raychaudhuri, Santa Clara, California]
Courtesy, my work at PLX Technology, CalibreDRV ref manual, and, TCL and the Tk Toolkit - John K. Ousterhout
***
Item#114> Reverse bose-einstein condensation to change the identity of materials
I thought about this idea while eating lunch at a Korean restaurant here in Santa Clara - a meal consisting of very cold fine noodles, potato and beef. Why is it so cold, how do they kill the germs in the food, I thought, probably they take it to a very low temperature, and bring it back! Is this an original idea? I don't know.
***
Item#113> LVS deck case studies
I. While looking at a foundry deck, recently, I found that the pplug that SCONNECTs p-diffusion to p-substrate finds dummy structures containing ptap, contact and metal1 subtracted from the set of all pplugs - giving rise to the ptaps inside the dummy structures not appearing in the softchk report. Means what? If a metal1 circuit net accidentally touched the metal1 of the dummy structure, the stamping violation (a short to the substrate) won't be flagged.
II. While the DRC deck can be switched from sub-block mode to FullChip mode, the LVS deck cannot be. So, the LVS deck is allowed to read all top text from all metal layers, even at the FullChip level. That's a problem (see also Item#88), because, let's say, some Vias connecting the top APRDL layer to the top metal layer are missing, and the top metal layer is also texted with the same net name as the bump text to APRDL, LVS will come out correct!
***
Item#112> Fast DEF query routines
Considering how much information DEF files contain, fast DEF parsers will be extremely useful in debugging GDS/Oasis issues. For example, given the X,Y coordinates of a point on a particular metal layer Mx, query the net name from the DEF file. Once the net name is found, put out its entire routing information into a DRC db format to easily view the net's trace on the layout. DEF files being typically huge, the challenge is to write adequately fast parsers.
***
Item#111> Use of recursive routines in shortest path calculations
Shortest paths are relevant in maps and GDS/OASIS databases. One can use recursive routines to compute shortest paths, given the full set of edges (ab, bc, ca, cd etc. with lengths associated, where a, b, c, d etc are the vertices). A path is like a line in a circuit tree - a path starts with the begining node, and ends in three ways, the begining node, the ending node, and a pendant node
***
Item#110> On annotated circuit trees extracted either from source netlist or from GDS
Annotated circuit trees with some properties attached to the tree elements can be a powerful tool for computing various chip statistics, and also for debug.
For example, a simple property like numbers of instances of subcells, and numbers of transistors of leaf cells can lead to calculations of number distributions of certain types of subcells and transistors in different sections of the chip.
Attaching a net name as a property can help view a net's propagation into the hierarchy - a good debug idea.
Using different colors for different sections of the tree you can indicate power shutdown domains.
***
Item#109> SUBCKT hashing in Perl for fast retrievals in recursive tree extraction - hashing is cool because you don't need to search the source netlist every time the details of a subcircuit is needed ...
## find_subckt corrected for sorted retrieval
sub find_subckt {
($sub) = @_;
@current_subs_file = ();
foreach $kk (sort { $a <=> $b } keys %{$sub}) {
$current_subs_file[$kk] = ${$sub}{$kk};
}
}
sub tree_extractor {
($sub_name) = @_;
&find_subckt($sub_name);
:::::::
::::::: Details of tree_extractor routine ::::
&tree_extractor($cell_name);
:::::::
}
$infile_1 = "src.net";
## src.net may be a 60 million lines spice source netlist
## with top cell name TOP_CELL
open(JJ, $infile_1);
$ii = 0;
$subs_mark = ".SUBCKT";
$end_p = ".ENDS";
$gotAsub = 0;
while(<JJ>) {
s/^//;
$lastXline = $_;
chomp $lastXline;
if ($lastXline =~ /$subs_mark/) {
@lineXparts = split(/\s+/, $lastXline);
$sx = $lineXparts[1];
$ii=0;
$gotAsub = 1;
}
if ($gotAsub) {
$keyval = $ii;
$valval = $lastXline;
${$sx}{$keyval} = $valval;
$ii++;
}
if ($lastXline =~ /$end_p/) {
$gotAsub = 0;
}
}
close(JJ);
&tree_extractor("TOP_CELL");
* edited from my earlier script for eSilicon Corporation
***
Item#108> Let's say, a point in a sub-block is at 100, 200 in sub-block coordinates, and the sub-block is instanced at 3000,1000 in the full-chip, at an orientation of 0 270. Find the coordinates of the point in the full-chip coordinates
From the formulas below (Item#107),
100 = 1000 - Y1
200 = X1 - 3000
Find X1, Y1
***
Item#107> Quiz 21: What is this?
0 0 --> X1-X0, Y1-Y0
0 90 --> Y1-Y0, X0-X1
0 180 --> X0-X1, Y0-Y1
0 270 --> Y0-Y1, X1-X0
1 0 --> X1-X0, Y0-Y1
1 90 --> Y1-Y0, X1-X0
1 180 --> X0-X1, Y1-Y0
1 270 --> Y0-Y1, X0-X1
Answer: These are formulas for coordinate transformation from a block coordinate X1,Y1 to a sub-block's coordinate space. The sub-block's instance position being X0, Y0, and the reflection and rotation given by the two numbers on the left. These formulas are used in transforming DRC errors to sub-block space as indicated in Item#90. This is a useful table to keep handy.
***
Item#106> How would you adapt a single SealRing checking DRC deck to check multiple nested SealRings ...
By joining up the nested SealRings with SIZE SR_MARKER OVERUNDER BY <SR_space>, you can bunch them as a single SealRing (with multiple holes) in the DRC deck, and then apply the single SealRing checker constructs. Also, the chip extents for dummy metal filling should be computed carefully not to include SealRing cells. It is advisable to use marker text to mark INNER and OUTER segments of individual rings, rather than the HOLES construct. Key thing to note is that the Isolation Region is needed only for the inner sealrings (circuits facing), and not for the outer ones.
***
Item#105> Splitting the output logic wheel into two wheels - logic 1 wheel and logic 0 wheel ...
will avoid meshing conflicts (see Item#97) while the output switches from 0 to 1 and vice versa. It will be two parallel but independent wheels, one (logic 0 wheel) with 2 pawl tracks to receive the INPUTs and push /pull the shaft using the spring-shaft arrangement of Item#100; and the other (logic 1 wheel) with an opposite tooth pawl track to receive power from the zero-bias chain, but its shaft is being pushed/pulled by the same cylinder as the wheel 0. So, the wheel 0 controls the power transfer, and no rotation direction change is involved, to avoid conflicts. For an application such as gear shifting (Item#103 & 104), the logic 0 wheel will not be used towards the output pawls, only the logic 1 wheel transfers power. When all the INPUT pawls rotate at '1' - the gear system is in 'Neutral', when a particular INPUT is rotated at '0' that gear is selected.
***
Item#104> Relative Speed Meshing
Shown with an example of 2 gears meshing. The idea can be easily extended to 4 or more gears. When the NOT1 output wheel is powered it is moving counter-clock wise and rotating the pawl1 clock-wise. At that time, NOT2 output is not powered, and hence it is moving clock-wise, and slipping on pawl2. Similarly, when the NOT2 is powered, NOT1 slips. Due to inertia of the output shaft, powering of the pawls will take place when the NOT output speed is higher or equal to the pawl speed. If a powered NOT's output speed is lower than the current inertial speed of the corresponding pawl, only slippage will take place due to higher relative speed of the pawl.
[Sep 07. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
Item#103> Logic wheels driven gears shifting...
Is one potential application of the gear-based logic gates discussed in Item#97 & 98. For example, one can use 4 logical NOT gates with different output wheel dia (teeth ratio), and the engine power applied to the zero bias chain of Item#97. Instead of having two input wheels for the NOR, we will have one electrical motor driven wheel per NOT gate. So, we can change gears by flicking a switch!
[Aug 26. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
Item#102> How to avoid high speed meshing of the coupler (Item#101) with the drivens and the output gear...
By keeping the input wheel small dia and the left members of the drivens large, meshing with the outer teeth of the input wheel, you make the coupler end drivens rotate at slow speed. Also, by adding a large dia right member to the output gear and ratioing out with a small dia from that you reduce the coupler end output gear's speed.
[Aug 21. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
Item#101> Simplified car transmission with a spring-shaft modification to the below (Item#100) schematic
Item#87>Finding the equivalent resistance of a complex resistive network
Let's say you are asked to compute the net resistance of a complex metalization network starting from a bump pad (APRDL) all the way up to the entry point to a power pin of an IP sub-block. How would you do that?
Answer: With a calibre script, subtract the pin metals of the IP from the set of all metals, now dump out all metals and vias connected to the bump supplying the potential into a small gds file. A schematic (vias are omitted for simplicity) is shown below:
[May 02. 2013, Arya Raychaudhuri, Sunnyvale, California]
Let's say, the IP power pin is connected to M4 coming from outside. Put a text IP_IN on M4 near the entry, and CHIP_IN on the AP bump (blue) in appropriate text layers. Place a net cutter metal resistance (RM4) layer to the left of IP_IN. Now, with calibre XRC (-r mode)compute the parasitic resistance of the entire network. Then do a dc analysis with spice on that network, applying 0 - 1.8V to CHIP_IN, and ground (0) bias to IP_IN - the simulated current thru IP_IN versus applied ramp on CHIP_IN gives the resistance of the net.
***
Item#86>power shutdown domains ERCs - checking for proper biases to power shutdown domains, mapping the power switch nwells. sleepin-sleepout sequence, etc.
M2_HEADBUF16_X1M_A12TR40 = M2i INSIDE CELL HEADBUF16_X1M_A12TR40
M2_HEADBUF32_X1M_A12TR40 = M2i INSIDE CELL HEADBUF32_X1M_A12TR40
M2_HEADBUF = M2_HEADBUF16_X1M_A12TR40 OR M2_HEADBUF32_X1M_A12TR40
M2_HEADBUF_VDD = M2_HEADBUF WITH TEXT "VDD" 132
M2_HEADBUF_VDDG = M2_HEADBUF WITH TEXT "VDDG" 132
CONNECT M2_HEADBUF_VDD metal2
CONNECT M2_HEADBUF_VDDG metal2
tpdiff_VDD_SW = tpdiff NET AREA RATIO M2_HEADBUF_VDD > 0
Nxwell_VDD_SW = nxwell INTERACT tpdiff_VDD_SW
M2_HEADBUF_VDD_BAD {FLATTEN (M2_HEADBUF_VDD NET AREA RATIO (Metal11 with text "VDD" PRIMARY ONLY) >0)}
M2_HEADBUF_VDDG_BAD {FLATTEN (M2_HEADBUF_VDDG NET AREA RATIO (Metal11 with text "VDD" PRIMARY ONLY) ==0)}
nxwell_VDD_SW {FLATTEN nxwell_VDD_SW}
nxwell_VDD_SW_not_VDD {nxwell_VDD_SW NET AREA RATIO (Metal11 with text "VDD" PRIMARY ONLY) ==0}
We also use calibre to derive the power-up/down sequence maps, continuity checking, and use ‘moving calibre’ to observe the switching sequence.
[Apr 27. 2013, Arya Raychaudhuri, Sunnyvale, California]
(courtesy my work at eSilicon, 2013)
***
Item#85> Quiz19: Since this type of decoupling caps requiring noise coupling (Item#84) can occur between any IP and CORE thru the changing values of Rstk1 and Rstk2 with circuit operations, it's interesting to think of a perl code that can model the noise.
[Hint: instead of turning Vcorevdd to ac ground, use dc 1.1 V, and instead of applying the noise sine wave to Viovdd, use dc 1.8V]
***
Item#84> Noise coupling through the shorting of IO_VSS and CORE_VSS using metallization
Typically, IO_VSS and CORE_VSS get shorted through resistive substrate, but, if they get shorted through metallization, more noise coupling occurs, see this example
vss_noise_coupling
Rstk1 iovdd io 100
Rstk2 corevdd core 100
Rstk3 io iovss 5
Rstk4 core corevss 5
Rcoup io core Rval
Rsub io core 20
Vcorevdd corevdd 0 0
Vcorevss corevss 0 0
Viovss iovss 0 0
Viovdd iovdd 0 SINE(0 0.2 10e6 0 0 0)
.TRAN 50ns 200ns
.PLOT TRAN V(core)
.end
[Mar 26. 2013, Arya Raychaudhuri, Sunnyvale, California]
Rstk1 models the ac resistance of the viastack and on devices from IO_VDD to IO supply point, Rstk2 - CORE_VDD to CORE ground supply point, Rstk3 - IO ptap to IO_VSS pad, Rstk4 - CORE ptap to CORE_VSS pad. Rsub - IO ptap to CORE ptap substrate resistance. Rcoup is the parallel coupling resistance between CORE ptap to IO ptap. We apply a sine noise voltage 200mv amp, 10MHz frequency to IO_VDD, and measure V(core) for Rval = 1M ohms (open condition) and, Rval= 2 ohms (short condition):
[Mar 23. 2013, Arya Raychaudhuri, Sunnyvale, California]
Coupled noise amplitude is about 3.07 mV for the 'open' case
[Mar 23. 2013, Arya Raychaudhuri, Sunnyvale, California]
Coupled noise is about 8mV for the 'short' case
***
Item#83>Quiz18: How would you implement the below (Item#82) experiment in spice?
Answer: First compute V1(t) and I1(t) vectors through a transient analysis on R1-C1; parse the V1(t) vector into a PWL voltage source, and apply to the R2-C2, measure the I2(t) vecor; parse the I1(t) and I2(t) vectors into two PWL current sources and apply in parallel to R1 connected to a very high resistance R0 (1Meg), with the other end of R0 tied to ground, measure V0(t) vector across R0 and plot against time. Much more complicated - didn't try it myself!
Motivates an integrated spice deck methodology with incremental connect/disconnect/connect simulation functionality with c parsers embedded.
***
Item#82> In search of linear charge partitioning ...
In the RC circuit of Item#80, we see two similar branches, R1-C1, and R2-C2. If we break them into two simple RC circuits, compute V1(t) for the R1-C1 branch, apply V1(t) to the R2-C2, and compute V2(t) [possible as per Item#81], we obtain combined delta charge functions as:
dQ(t) = C1*dV1(t) + C2*dV2(t)
If we let this charge get supplied through R1, we can plot Vx(t) [see figure below]. If Vx(t) were constant with time, linear charge partitioning would have existed - but, it does not.
So, one must take the entire circuit, and solve it, linear decomposition is not possible.
Perl code used to calculate Vx(t):
###! /usr/bin/perl -w
## Arya, Feb 9, 2013
$nn=0; $t=0; $dt=10e-10; $Vdd=1.1;
$V1X = 0; $C1=1e-11; $R1=10000;
$V2X = 0; $C2=2e-11; $R2=20000;
while ($nn <2000 ){
$dV1 = (($Vdd - $V1X)/($R1 * $C1))*$dt;
$dV2 = (($V1X - $V2X)/($R2 * $C2))*$dt;
$V1X = $V1X + $dV1;
$V2X = $V2X + $dV2;
$dQ = $C1*$dV1 + $C2*$dV2;
$Vx= $dQ*$R1/$dt + $V1X;
$nn++;
$t = $t + $dt*1e6;
$tp = sprintf("%.4f", $t);
$Vxp = sprintf("%.4f", $Vx);
print $tp, " ", $Vxp, "\n";
}
[Feb 09. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
Item#81> If we gave a voltage ramp for Vdd ($V in perl), instead of a constant voltage of 1.1V
We would start with $V=0; and simply add a line
$V = $V + 1.1/2000;
at the entry of the while loop. See how the curves look:
** drawn with Graph (version 4.4.2) for windows
[Jan 14. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
tem#80> Quiz17:
Write a routine to numerically compute the transient rise of the node voltages V1 and V2 in the following circuit, from t=0 thru t=2 us, at 1 ns steps:
[Jan 08. 2013, Arya Raychaudhuri, Sunnyvale, California]
Answer:
Charge dQ flowing through R1 in a timestep dt distributes into dQ1 (on C1) and dQ2 (on C2) -->
dQ = dQ1 + dQ2 -->
[(V - V1)/R1]*dt = C1 * dV1 + [(V1 -V2)/R2]*dt -->
dV1 = [(V - V1)/(R1 * C1) - (V1 - V2)/(C1 * R2)] * dt (eqn1)
Also, C2 * dV2 = dt*(V1 -V2)/R2 -->
dV2 = dt*(V1 - V2) /(R2 * C2) (eqn2)
These two guiding equations lead to :
## Arya, Jan 07, 2013
$nn=0; $t=0; $dt=10e-10; $V=1.1;
$V1 = 0; $C1=1e-11; $R1=10000;
$V2 = 0; $C2=2e-11; $R2=20000;
while ($nn <2000 ){
$dV1 = (($V - $V1)/($R1 * $C1) - ($V1 - $V2)/($C1 * $R2)) *$dt;
$dV2 = (($V1 - $V2)/($R2 * $C2))* $dt ;
$V1 = $V1 + $dV1;
$V2 = $V2 + $dV2;
$nn++;
$t = $t + $dt*1e6;
$V1p = sprintf("%.4f", $V1);
$V2p = sprintf("%.4f", $V2);
$tp = sprintf("%.4f", $t);
print $tp, " ", $V1p, " " , $V2p , "\n";
}
*Curves drawn with microsoft Excel, compute with ActivePerl64
[Jan 09. 2013, Arya Raychaudhuri, Sunnyvale, California]
Comparing with Spice drawn Curves:
[Jan 09. 2013, Arya Raychaudhuri, Sunnyvale, California]
***
Wishing Happy Newyear 2013 to all coding enthusiasts from the only US based consulting entity that focuses on FullChip LVS debug (single and multi-chip) and recursive routines!
Item#79> Guiding equations in the perl code of Item#78 -
If V is the transient nwell potential,
C*(dV/dt) + V/R = I(pmos)
For, a pmos (complementary to nmos), the I(pmos) can be represented by the nmos equations, with a positive VT, if voltage polarities are reveresed, Vsg for Vgs, Vsd for Vds
For example, in linear region (Vsg - VT) > Vsd
[in our case, (Vdd -VT) > (Vdd - V)
I = K*[(Vsg -VT)*Vsd - 0.5*Vsd^2]
= (K/2)*(Vdd -V)*(Vdd - 2*VT + V)
and in saturation region (Vsg - VT) <= Vsd
[in our case, (Vdd - VT) <= (Vdd - V), or V <= VT]
I = K*(Vsg -VT)^2 = (K/2)*(Vdd- VT)*(Vdd - VT)
***
Item#78> Quiz16: Write a recursive perl to estimate the transient current and nwell voltage rise for one individual nwell of the bottom figure of Item#74 -
Let's say, you don't have spice to do the transient analysis. Sometimes you are faced with such situations where you don't have the ideal tool to solve an engineering problem, yet you are asked to come up with a reasonable estimate. Use the K and VT values from Item#43 (VT will be negative for pmos, K roughly same because the width is double, but mobility is half for pmos) , and the simple pmos equations.
Answer:
###! /usr/bin/perl -w
## Arya, Nov 28, 2012
sub ivcompute {
($V) = @_;
if ( $V <= $VT) {
$I = ($K/2)*($Vdd- $VT)*($Vdd - $VT);
}
else {
$I = ($K/2)*($Vdd -$V)*($Vdd - 2*$VT + $V) ;
}
$dv = ($dt/$C)*($I - $V/$R);
print $t*1e9, " " ,$I*1e6, " ", $V;
print "\n";
$t = $t + $dt;
$V = $V + $dv ;
$nn++;
if ($nn <1001 ) {
&ivcompute($V);
}
}
$nn=0; $t=0; $dt=1e-10; $Vdd=1.1; $VT=0.566; $K=0.002247;
$V = 0; $C=1e-11; $R=1000000;
&ivcompute($V);
** transient data computed with windows ActivePerl64, curves drawn with Microsoft Excel
[Nov 29. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#77> Regarding the energy difference box,Item#75 -
Due to repeated power-up and power-down sequences, the first few power switches will be over-loaded (dissipating more energy) compared to the last ones. The last ones on a very long daisy-chain may actually dissipate insignificantly low amounts of energy, and may not be necessary at all.
Now, if the first switch burns out, it can make either an open, or a short. If it's an open, the second switch will play the role of the first switch, and so on. If it's a short, the power shutdown domain will no longer function in that mode - it will constantly leak power even in the shutdown phase.
***
Item#76> When the nwells are disconnected - bottom schematic of Item#74 -
[Nov 21. 2012, Arya Raychaudhuri, Sunnyvale, California]
See that the energy difference box is now gone, all switches dissipate same amounts of energy. The first, the second, and the 20th nwells rising in potential shown from left to right. But, the peak supply transient (not shown) remains pretty much the same. Can we decrease it? Yes, we can delay the rise of the first few nwells - because we don't gain anything by raising them to supply potential before the 20th. That way, we can use smaller (lesser W) switches in the begining of the chain, and gradually make them wider towards the last in the chain.
An example is shown below where I have used a 0.6 um wide pmos for the first switch, and a 0.65 um for the second. See how the first two transient peaks drop - bringing down the overall supply current! And the nwell rises bunch up.
[Nov 21. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#75> Total transient supply current drawn and individual switching current transients as the nwell voltage rises for the top schematic in item#74 -
As simulated on LTSpice with the ASU model mentioned earlier. See that the peak transient supply current is about 5mA for 20 transistors. If there were 2000 transistors for a large block, the supply current peak would be about 500mA - with 1 Ohm supply impedence, that would bring down the power supply by 0.5V! Also, note the energy dissipation difference between the first switch and the last switch - with more switches, the box would be larger.
[Nov 20. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#74> Conceptual modeling of power shutdown domains power-up sequence
See below that I am depicting two scenarios - the top figure shows the situation when all the powered up nwells are connected by metal, and the bottom figure has the nwells dis-connected from one another.
[Nov 18. 2012, Arya Raychaudhuri, Sunnyvale, California]
This type of modeling (the R, C , pulse delay values are place holders, and not realistic) enables simulating for the power up switching energies in the individual sequential switches, the total current transient drawn from Vdd supply, etc.
As you have seen, when a high energy consuming equipment is suddenly turned on, there is a dip in the supply voltage! If the dip is too excessive, some devices may not function properly. Also, the first switch will perennially dissipate more energy (in the top figure) than the last switch - making it more vulnerable.
***
Item#73> Forked recursives with inter-process communication -
Earlier I talked about running the clock in one fork and the logic in another with inter-process communication. It will be interesting to run two or more recursives in different forks, with inter-process communication. But, the question is what kind of practical situations would be modeled by that?
Here is an idea from circuit tree extraction, for forking recursives. Convert the whole spice netlist into named hashes (after the subckt names}, sort of like the '@' padded subckt files for shell-based instance flatener. Now, fork the process. Both forks should inherit the hashes. Now, within one fork delete a hash for a big sub-block (subckt XYZ), and get the tree for the toplevel. This tree will have the sub-block just as a pendant node.
In the other fork, do the tree for that subckt XYZ. When both forks are over, join the two trees to create the entire tree. Though no inter-process communication is involved - enhances parallelisation of recursive tree extraction. Yet to try this forking myself. But, I recently did a recursive perl spice tree extractor that crunched a 15.8 million line netlist in about 20 minutes on an Intel Xeon (3.47GHz) based server - with forking it would go in even less time.
***
Item#72> Treating problems recursively (when appropriate) is charming -
But, sometimes, the same problem could have been done non-recursively. For example, the instance flattener could be done with a while loop - first read in the toplevel into an array @spice (each line an element), set $serachX to 1, enter the while ($searchX) loop, look for an element starting with X. Once found, readin the corresponding subckt file with pins and element substitutions into array @subckt. Splice the @subckt array into @spice, at that point, and go on with the remaining lines in @spice, and splicing as more X-es are found. Go back to the while loop and repeat the same on the expanded @spice ... until no X-es are found - set $searchX to 0, and get out of the loop. Print out @spice.
***
Item#71> Test Results of running flatten_func
Test spice netlist
------------------
.subckt toplevel AA BB CC
C1 BB CC 100p
X1 AA BB mysub1
M1 AA CC BB BB NMOS L=0.045um W=0.135um
X2 CC mysub2
D1 CC BB diode_model
.ends
.subckt mysub1 JJ KK
R1 JJ PP 100
X4 PP mysub2
R2 PP KK 200
.ends
.subckt mysub2 LL
DD LL YY diode_model
DX YY LL diode_model
M1 1 LL 2 2 NMOS L=0.045um W=0.090um
.ends
After adding the local pin '2' to the mysub2 pinlist (LL 2)
---------------------------------------------------------
.subckt toplevel AA BB CC
C1 BB CC 100p
**@X1@ @AA@ @BB@ @mysub1@
**.subckt mysub1 AA% BB%
R1_X1 AA PP_X1 100
**@X4@_@X1@ @PP@_@X1@ @mysub2@_@X1@
**.subckt mysub2 PP_X1% 2
DD_X1_X4 PP_X1 YY_X1_X4 diode_model
DX_X1_X4 YY_X1_X4 PP_X1 diode_model
M1_X1_X4 1_X1_X4 PP_X1 2_X1_X4 2_X1_X4 NMOS L=0.045um W=0.090um
**.ends
R2_X1 PP_X1 BB 200
**.ends
M1 AA CC BB BB NMOS L=0.045um W=0.135um
**@X2@ @CC@ @mysub2@
**.subckt mysub2 CC% 2
DD_X2 CC YY_X2 diode_model
DX_X2 YY_X2 CC diode_model
M1_X2 1_X2 CC 2_X2 2_X2 NMOS L=0.045um W=0.090um
**.ends
D1 CC BB diode_model
.ends
After removing the pins for subckt mysub2
-----------------------------------------
.subckt toplevel AA BB CC
C1 BB CC 100p
**@X1@ @AA@ @BB@ @mysub1@
**.subckt mysub1 AA% BB%
R1_X1 AA PP_X1 100
**@X4@_@X1@ @PP@_@X1@ @mysub2@_@X1@
Error @mysub2@_@X1@ has less pins than in calling instance:
@X4@_@X1@
Please note that flatten_func is run each time after sourcing fltnr.sh (Item#66) - that does the padding (@)
***
Item#70> More or less pins than ports -
An edited version of the code is given below. It fixes a bug in the original code, and also works for more or less (creates error) subckt pins. Edited portions are in blue:
## Arya, Oct 27, 2012, edited Oct 31, 2012
flatten_func () {
for ii in `cat $fff|sed -e 's/ /#/g'`
do ll=`echo $ii|sed -e 's/#/ /g'`
fld1=`echo $ll|awk '{print $1}'`
if [[ `echo $fld1|grep '@D'` || `echo $fld1|grep '@C'` || `echo $fld1|grep '@R'` ]]
then nn=4
else if [ `echo $fld1|grep '@Q'` ]
then nn=5
else if [ `echo $fld1|grep '@M'` ]
then nn=6
else if [ `echo $fld1|grep '@X'` ]
then nn=`echo $ll|awk '{print NF}'`; let nn++
fi
fi
fi
fi
if [ $erx ]
then return
fi
lx=`echo $ll|awk '{ for (i=1 ; i<"'$nn'" ; i++) if ($i ~ /%/) {printf $i " "} else {printf $i "'$suffx'" " "}; for (i="'$nn'"; i<=NF; i++) printf $i " "}'|sed -e 's/%//'`
if [ `echo $fld1|grep '@X'` ]
then fffx=`echo $ll|awk '{print $NF}'`
inst=$fld1
XXX=$XXX' '$inst
suffx=`echo $XXX|awk '{for (i=1; i<=NF; i++) printf "_" $i}'`
rm -f sedf*
touch sedf1 sedf2
cat $fffx|grep -i subckt |awk '{for (i=3; i<=NF ; i++) printf $i "\n"}' >>sedf1
echo $lx|awk '{for (i=2; i<NF; i++) printf $i "\n"}' >> sedf2
echo '**'$lx
npo=`wc sedf2|awk '{print $1}'`
npi=`wc sedf1|awk '{print $1}'`
if [ $npo -le $npi ]
then
let npi=$npo+2
rm -f sedf1; touch sedf1
cat $fffx|grep -i subckt|awk '{for (i=3; i<="'$npi'"; i++) printf $i "\n"}' >> sedf1
else
echo 'Error '`echo $lx|awk '{print $NF}'`' has less pins than in calling instance:'
echo $lx|awk '{print $1}'
erx=1
return
fi
paste sedf1 sedf2 |sed -e 's/\t/ /' -e 's/^/s\//' -e 's/ /\//' -e 's/$/%\/g/'> sedf
fff=$fffx''$suffx
sed -f sedf $fffx > $fff
flatten_func
else if [[ `echo $ii|grep subckt` || `echo $ii|grep ends` ]]
then if [ $fld1 == '.ends' ]
then XXX=`echo $XXX|awk '{for (i=1; i<NF; i++) printf $i " "}'`
suffx=`echo $XXX|awk '{for (i=1; i<=NF; i++) printf "_" $i}'`
let nx--
let nx--
fi
if [[ $fff == $fftop || $nx -eq 0 ]]
then echo $ll|sed -e 's/@//g'; let nx++
else echo '**'$ll|sed -e 's/@//g'; let nx++
fi
else echo $lx|sed -e 's/@//g'
fi
fi
if [[ -e $fff && `echo $fff|grep '_'` ]]
then rm -f $fff
fi
done }
fftop=@toplevel@; fff=$fftop; XXX=""; nx=1; suffx="";erx=""; set +C; flatten_func; erx=""
Note that we are also flushing the suffix variable 'suffx' and the error tracker 'erx' outside the recursive, to avoid carryovers to a next run. This edited version also logs the instance call.
***
LVS DEBUG SOLUTIONS expresses sympathies for the sufferers in the big storm that has hit the east coast -
I was stuck in my hotel room near Boston last year when a similar storm had hit, dismal situation without power for days, so I know how it feels ... hope the situation recovers quickly.
***
Item#69> Quiz15 - the flatten_func shell script assumes that the number of calling ports (instance ports) is equal to the number of called pins (subckt). What if the subckt had extra pins - could be a couple of globals?
Answer:
Edit these two lines:
cat $fffx|grep -i subckt |awk '{for (i=3; i<=NF ; i++) printf $i "\n"}' >>sedf1
echo $lx|awk '{for (i=2; i<NF; i++) printf $i "\n"}' >> sedf2
TO:
echo $lx|awk '{for (i=2; i<NF; i++) printf $i "\n"}' >> sedf2
npo=`wc sedf2|awk '{print $1}'`
let npi=$npo+2
cat $fffx|grep -i subckt |awk '{for (i=3; i<="'$npi'" ; i++) printf $i "\n"}' >>sedf1
If the subckt pins are less than calling ports, that should stop the routine with an error flag! Edit code to take into account both possibilities, more and less.
***
Item#68> .GLOBALs related post-processing and v2lvs netlists -
Even without .GLOBALs smashing (a pre-processing step), the flattened netlist can be adjusted for the GLOBAL ports by some post-processing. For example, if VDDPST is a global port, any occurrences of VDDPST_X* in the flattened netlist should be replaced (sed) by VDDPST, and VDDPST should be added as a pin name to the top level subckt's pin list.
For v2lvs netlists, the sedf file needs to be generated from the pins assignments following $PINS, wherever present. Quite simple - see v2lvs pins parsing in the context of empty subcircuit making, given earlier.
***
Item#67> Adding more device types -
For simplicity I had only treated the cases for diodes, caps, resistors, and mosfets. To add another device type, e.g., bipolar (Q), edit the following code section appropriately:
if [[ `echo $fld1|grep '@D'` || `echo $fld1|grep '@C'` || `echo $fld1|grep '@R'` ]]
then nn=4
else nn=6
fi
TO
if [[ `echo $fld1|grep '@D'` || `echo $fld1|grep '@C'` || `echo $fld1|grep '@R'` ]]
then nn=4
else if [ `echo $fld1|grep '@Q'` ]
then nn=5
else nn=6
fi
fi
Any explicit-pins-passed netlist should first be expanded for the .INCLUDEs using expand_func (given earlier), then it should be '+' signs removed using the awk construct given earlier, before application of the instance flattener.
***
Item#66> Quiz14 - expand_func recursive shell revisited
Following the hint given in the context of the INCLUDEs expander shell script, create a recursive shell to flatten all instances in the following netlist :
.subckt toplevel AA BB CC
C1 BB CC 100pF
X1 AA BB mysub1
M1 AA CC BB BB NMOS L=0.045um W=0.135um
X2 CC mysub2
D1 CC BB diode_model
.ends
.subckt mysub1 JJ KK
R1 JJ PP 100
X4 PP mysub2
R2 PP KK 200
.ends
.subckt mysub2 LL
DD LL YY diode_model
DX YY LL diode_model
M1 1 LL 2 2 NMOS L=0.045um W=0.090um
.ends
Answer:
the recursive shell netlist flattener flatten_func is shown in the blog page. First, the script breaks the subckts into separate padded (with @) files by the subckt names. Then the flatten_funcworks on those files! The blog page looks a bit corrupted - so the codes are reproduced here.
fltnr.sh
for i in `cat test.net|sed -e 's/ /#/g'`;do ll=`echo $i|sed -e 's/#/ /g'` ; l1=`echo $ll|awk '{print $1}'`; if [ $l1 == '.subckt' ]; then l2=`echo $ll|awk '{print $2}'`; fff='@'$l2'@'; rm -f $fff; touch $fff; echo $ll|awk '{printf $1;for (i=2; i<=NF; i++) printf " @" $i "@ "; printf "\n"}' >> $fff; else if [ $l1 == '.ends' ]; then echo $ll >> $fff; else echo $ll |awk '{for (i=1; i<=NF; i++) printf " @" $i "@ "; printf "\n"}'>> $fff;fi; fi;done
flatten_func
## Arya, Oct 27, 2012
flatten_func () {
for ii in `cat $fff|sed -e 's/ /#/g'`
do ll=`echo $ii|sed -e 's/#/ /g'`
fld1=`echo $ll|awk '{print $1}'`
if [[ `echo $fld1|grep '@D'` || `echo $fld1|grep '@C'` || `echo $fld1|grep '@R'` ]]
then nn=4
else nn=6
fi
lx=`echo $ll|awk '{ for (i=1 ; i<"'$nn'" ; i++) if ($i ~ /%/) {printf $i " "} else {printf $i "'$suffx'" " "}; for (i="'$nn'"; i<=NF; i++) printf $i " "}'|sed -e 's/%//'`
if [ `echo $fld1|grep '@X'` ]
then fffx=`echo $ll|awk '{print $NF}'`
inst=$fld1
XXX=$XXX' '$inst
suffx=`echo $XXX|awk '{for (i=1; i<=NF; i++) printf "_" $i}'`
rm -f sedf*
touch sedf1 sedf2
cat $fffx|grep -i subckt |awk '{for (i=3; i<=NF ; i++) printf $i "\n"}' >>sedf1
echo $lx|awk '{for (i=2; i<NF; i++) printf $i "\n"}' >> sedf2
paste sedf1 sedf2 |sed -e 's/\t/ /' -e 's/^/s\//' -e 's/ /\//' -e 's/$/%\/g/'> sedf
fff=$fffx''$suffx
sed -f sedf $fffx > $fff
flatten_func
else if [[ `echo $ii|grep subckt` || `echo $ii|grep ends` ]]
then if [ $fld1 == '.ends' ]
then XXX=`echo $XXX|awk '{for (i=1; i<NF; i++) printf $i " "}'`
suffx=`echo $XXX|awk '{for (i=1; i<=NF; i++) printf "_" $i}'`
let nx--
let nx--
fi
if [[ $fff == $fftop || $nx -eq 0 ]]
then echo $ll|sed -e 's/@//g'; let nx++
else echo '**'$ll|sed -e 's/@//g'; let nx++
fi
else echo $lx|sed -e 's/@//g'
fi
fi
if [[ -e $fff && `echo $fff|grep '_'` ]]
then rm -f $fff
fi
done }
fff=$fftop
nx=1
XXX=""
flatten_func
See that the variable 'XXX' is the push/pop maker, and 'nx' is a depth counter. The 'nx' has trivial use (controlling the commenting of .subckt/.ends lines) in this routine, but, it's a good diagnostic variable. The routine will not work for netlists with GLOBAL ports, you will need to first smash them into explicit passing as shown in the test netlist. Also, netlists with square brackets '[xyz]' in them should be first converted to angled '<xyz>' or parentheses '(xyz)' before working on them, like,
cat your_netlist|sed -e 's/\[/\(/g' -e 's/\]/\)/g' > test.net
***
Item#65> Quiz13 - 3-diode stack problem revisited -
Earlier I had shown a way to parse 3 forward biased diodes stack from a netlist. That I had done for a client last year with last year's iq. But, now, it can be done much easier. Show a method, starting with the bipolars already split into diodes - all_split_DDs
Answer:
posted on the blog page (http://lvs-debug-solutions.com/blog/). See that it's a middle out approach, first detect the middle diode of the stack, and then go for the leading and trailing ones.
Starting with '#' padded all_vdds/all_gnds :
cat all_split_DDs|sed -e ‘s/ /#/g’ -e ‘s/$/#/’> all_DDs_padded; for i in `cat all_DDs_padded|grep -v -f all_vdds|grep -v -f all_gnds`; do echo $i|sed -e ‘s/#/ /g’; anode=`echo $i|sed -e ‘s/#/ /g’|awk ‘{print $2}’`; cathode=`echo $i|sed -e ‘s/#/ /g’|awk ‘{print $3}’`; sed -e “s/$/$anode\#/” all_vdds> tmpvdds;sed -e “s/\#/\#$cathode\#/” all_gnds> tmpgnds; grep -f tmpvdds all_DDs_padded|sed -e ‘s/#/ /g’; grep -f tmpgnds all_DDs_padded|sed -e ‘s/#/ /g’; echo “—————-”;done
***
Item#64> Site traffic data from Yahoo small business -
[Oct 25. 2012, Arya Raychaudhuri, Sunnyvale, California]
Does it realistically depict the international website hit counts?
***
Item#63> Recursive fet tracer posted on the blog page -
Check it out! The X7 common drain terminal is traced through current carrying terminals on a fictitious cmos.net. As you can see, it uses the source/drain terminals push/pop as explained earlier!
wordpress appears to have truncated a line that generates the work.net from the cmos.net (showing signs of unreliability?) , here it is:
cat cmos.net |awk '{ for (i=1; i<=NF; i++) printf "@" $i "@"; printf "\n"}' > work.net
***
Item#62> Recursive tracing of fets below M9&M10 -
I just casually mentioned about inspecting what is below the pmos pair M9&M10. In practice, it can be rather difficult and tedious when you are dealing with a scrambled netlist thousands of lines long. In that case, you will need a recursive routine to find all the fets connected to the common drain terminal. You would want to trace drain to source to drain to source to ... until you reach a power or a ground. An indicator to how the scope of recursives increases.
***
Item#61> Comments on the 2-input nand parser -
As shown in the blog, I tested it on a small cmos.net:
M1 X2 X1 VDD VDD PMOS
M2 X2 X1 VSS VSS NMOS
M3 X3 X2 VDD VDD PMOS
M4 X3 X2 VSS VSS NMOS
M5 X5 X3 VDD VDD PMOS
M6 X5 VDD VDD VDD PMOS
M7 X5 X3 X6 VSS NMOS
M8 X6 VDD VSS VSS NMOS
M9 X7 X5 VDD VDD PMOS
M10 X7 VDD VDD VDD PMOS
M11 X7 X5 X8 VSS NMOS
M12 X8 VxD VSS VSS NMOS
See that the gate of the M12 transistor is kept floating, so we don't find two nand gates:
source 2nand_fix.sh
PMOS_PAIR:
M5&M6
NMOS_PAIR
M8&M7
——————-
PMOS_PAIR:
M9&M10
NMOS_PAIR
——————-
No correspondence for the second PMOS_PAIR. This shows a way to find netlist problems - by inspecting what's below the M9&M10 pair. We could even have grepped the 'nmos_pair' against the 'pmos pair' - that way, you would see that sometimes, no corresponding PMOS_PAIR is found. Is that due to a netlist issue, could be; but sometimes it's just that you are looking at a 3-input nand gate, or some other config. For example, extend the 2-input nand parser to a 3-input nand parser.
***
Item#60> Issues in the blogged nand parsing script - related to under-padding of terminals/instance names, over-padding of blank spaces
Please, fix and blog.
Since no competitive fix was posted, here is the fix, this also addresses non-gate fanout (like a transmission gate's diffusion), cleans up output (no pins). Also, some unintended overwrites of the temp files (functional bugs) now fixed and re-blogged:
set +C
## set clobber mode
cat cmos.net |awk '{for (i=1; i<=NF; i++) printf "@" $i "@ "; printf "\n"}' >work.net
## padding instances and terminals with @
cat work.net |grep -i NMOS |awk '{print $1 " " $4}' |grep -i VSS |awk '{print $1}' > nmos_gnd
## nmos-es with source ground
cat work.net |grep -i PMOS |awk '{print $1 " " $4}' |grep -i VDD |awk '{print $1}' > pmos_vdd
##pmos-es with source to power
cat work.net |awk '{print $1 " " $2 }' | grep -f pmos_vdd |awk '{print $2}' |sort|uniq >pmos_D_vdd
##drains of pmos-es with source to power
cat work.net |grep -i PMOS|awk '{print $1 " " $2}' |grep -f pmos_vdd> pmos_D
##pmos-es , instance and drain pin
rm -f pmos_pair; touch pmos_pair; for ii in `cat pmos_D_vdd`; do grep $ii pmos_D > pmos_pairX; nn=`wc pmos_pairX|awk '{print $1}'`;if [ $nn == 2 ]; then pm1=`head -1 pmos_pairX|awk '{print $1}'`;gg1=`grep $pm1 work.net|awk '{print $3}'`; pm2=`tail -1 pmos_pairX|awk '{print $1}'`; gg2=`grep $pm2 work.net|awk '{print $3}'`; echo $pm1'&'$pm2'###'$ii'###'$gg1'###'$gg2>> pmos_pair;fi;done
##pmos pairs with source to power, common drain, gates
cat work.net|awk '{print $1 " " $2 }' | grep -f nmos_gnd |awk '{print $2}' |sort|uniq >nmos_D_vss; rm -f nmos_D_gnd; touch nmos_D_gnd; for ii in `cat nmos_D_vss`; do grep $ii work.net>chkD; nn=`wc chkD|awk '{print $1}'`; if [ $nn == 2 ]; then echo $ii >> nmos_D_gnd; fi;done
## drains of nmos-es with source to ground
cat work.net |grep -i NMOS|awk '{print $1 " " $2}' > nmos_SD
cat work.net |grep -i NMOS|awk '{print $1 " " $4}' >> nmos_SD
##nmos-es with source/drain pin
rm -f nmos_pair; touch nmos_pair; for ii in `cat nmos_D_gnd`; do grep $ii nmos_SD > nmos_pairX; nn=`wc nmos_pairX|awk '{print $1}'`;if [ $nn == 2 ]; then nm1=`head -1 nmos_pairX|awk '{print $1}'`;gg1=`grep $nm1 work.net|awk '{print $3}'`;dd1=`grep $nm1 work.net|awk '{print $2}'`; nm2=`tail -1 nmos_pairX|awk '{print $1}'`; gg2=`grep $nm2 work.net|awk '{print $3}'`; dd2=`grep $nm2 work.net|awk '{print $2}'`; if [ $ii == $dd1 ]; then out=`echo $dd2`; else out=`echo $dd1`; fi;echo $nm1'&'$nm2'###'$out'###'$gg1'###'$gg2>> nmos_pair;fi;done
##series nmos pairs, ground up, top drain, gates
for ii in `cat pmos_pair`; do OUT=`echo $ii|sed -e 's/###/ /g'|awk '{print $2}'`; A=`echo $ii|sed -e 's/###/ /g'|awk '{print $3}'`; B=`echo $ii|sed -e 's/###/ /g'|awk '{print $4}'`; pat1=`echo $OUT'###'$A'###'$B`; echo 'PMOS_PAIR:'; echo $ii|sed -e 's/###/ /g' -e 's/@//g' |awk '{print $1}'; pat2=`echo $OUT'###'$B'###'$A`; echo 'NMOS_PAIR';grep $pat2 nmos_pair |sed -e 's/###/ /g' -e 's/@//g' |awk '{print $1}'; grep $pat1 nmos_pair|sed -e 's/###/ /g' -e 's/@//g' |awk '{print $1}'; echo "-------------------";done
##pins swapped grepping of pmos pairs against nmos pairs
Item#59> Logic Parsing revisit: Earlier I had given a shell script to parse inverters from a flat cmos netlist, and had given a hint to do the same for 2-input nand gates. Could anyone do the nand gate parsing?
If so, please post your answer on the blog page. International (from outside of USA) communications are also very welcome. Let's say, for some reason your blog did not get through, you can always e_mail/call/text me using the contact info at the top right corner of this page - hey, my blog did not go through! I will respond and investigate what's stopping it.
Answer:
Since no other solution was posted, I have pasted a 2-input nand parser shell script to the Blog page (http://lvs-debug-solutions.com/blog/). Check it out! A small netlist, then the script, and finally the output on sourcing the script.
The script was written on meego bash, since it incorporates multiple rewrite of temporary files, you need to enable
set +C
in the shell before sourcing the script. It also shows the way to parse 2-input nor gates where the pmos transistors are in series and the nmos are in parallel - you need to edit the script for that.
***
Item#58> Quiz12: Files are like books, you start reading a book, get a reference to another book, immediately start reading that, there you find another reference, and so on -
If I had not used the numerical push/pop, you would never come back to finish reading the books from where the references were made. Sort of like, the last referenced book was so interesting I forgot about what I was reading before! Each succeeding reference is an incremental depth of recursion. Write a recursive perl to print out only the deepest but one reference. Let;s say, that was the most interesting of all the 'books' starting with level 0. This tests if you properly understood the earlier routine - changing the requirement a bit! :-)
Answer:
See the additions/edits to the earlier routine in green, a depth counter array @fhs, and a filenames store array @flx have been added.
#! /usr/bin/perl -w
## Arya, Oct 15, 2012
sub expand_func {
($infile, $fx) = @_;
open($fx, $infile);
while(<$fx>) {
$lastline = $_;
s/^//;
chomp $lastline;
if ( $lastline =~ /$inclpat/ ) {
@ll = split(/\s+/, $lastline);
$fx++;
if ($fx > $fhs[-1] ) {
push(@fhs, $fx);
push(@flx, $ll[1]);
}
&expand_func($ll[1], $fx);
$fx--;
}
else {
#print $lastline, "\n";
}
}
}
$fff = '/home/user/rec_shell/xxx';
$inclpat = 'INCLUDE';
$fx = 100;
@fhs = (100);
@flx = ($fff);
&expand_func($fff, $fx);
open (S, $flx[-2]);
while (<S>) {
print $_;
}
Item#57> Pictorial representation of recursion -
[Oct 14. 2012, Arya Raychaudhuri, Sunnyvale, California]
See that the blue arrow to the left top represents the first entry to the loop (subroutine), then the successive calls and returns follow a clockwise direction. Each color represents a particular depth of recursion. Depths could get into 100s, or even more. If the recursions are not controlled properly, the program can irretrievably enter the singularity zone, and get lost beyond the 'event horizon'. :-)
Curiously, I let the ring oscillator oscillate in the recursive mode. SPICE does not allow recursive subckts, but you can run the truth table of the inverter in a recursive way through shell/perl. And, let it reach unlimited recursion depths - it could go to a depth of 1.7 million on my little meego system! In the above diagram, we are accessing only up to depth 3, see the unaccessed depth levels in the center (in light blue) fading into infinity (ideally!).
***
Item#56> Perl equivalent of the INCLUDEs expander (expand_func, given earlier) -
This uses some sort of a numerical push/pop to remember the open file handles. I had done a similar perl for a client earlier, but I believe this is an improvement. This will also avoid the blank spaces compression that the 'expand_func' shell function was introducing.
#! /usr/bin/perl -w
## Arya, Oct 12, 2012
sub expand_func {
($infile, $fx) = @_;
open($fx, $infile);
while(<$fx>) {
$lastline = $_;
s/^//;
chomp $lastline;
if ( $lastline =~ /$inclpat/ ) {
@ll = split(/\s+/, $lastline);
$fx++; # numerical push
&expand_func($ll[1], $fx);
$fx--; # numerical pop
}
else {
print $lastline, "\n";
}
}
}
$fff = '/home/usr/lvs_engr/xxx';
$inclpat = 'INCLUDE';
$fx = 100;
&expand_func($fff, $fx);
Item#55> About the push/pop perl construct and its shell equivalent:
push - KKK=$KKK' '$i';
pop - match_pat=`echo $KKK|awk '{print $NF}'`; KKK=`echo $KKK|awk '{for (j=1; j<NF; j++) printf $j " "}'`;
push/pop is a very useful construct in writing recursive perls. I first used this early last year while writing recursive codes to extract the circuit tree from spice, and to trace the trajectory of a net in the context of the circuit tree.
***
Item#54> Recursive shell equivalent of the recursive perl to find sub3 impacts
.subckt topcell
X22 uu oo sub3
--
.subckt sub4 x y z
X54 x y sub3
--
.subckt sub19 p q
X23 p q sub3
.subckt sub10 z c
X12 z c sub19
.subckt topcell
X66 1 2 sub10
.subckt topcell
X432 dd bb kk sub4
***
Item#53> Recursive Perl to find all subckts impacted by sub3
#! /usr/bin/perl -w
## Arya, Oct 11, 2012, done on Asus meego bash
sub findsubs {
($match_pat) = @_;
for ($kk=$jj; $kk>=0; $kk=$kk-1) {
if ($findsub == 0) {
if (($ckt[$kk] =~ /$match_pat/) && ($ckt[$kk] =~ /^X/)) {
$findsub = 1;
print "instance= ",$ckt[$kk], "\n";
}
}
if ($findsub == 1) {
if ($ckt[$kk] =~ /$subpat/) {
$findsub = 0;
@cktparts = split(/\s+/, $ckt[$kk]);
print "subckt= ",$cktparts[1], "\n", "\n";
if ($cktparts[1] ne $topcell ) {
push(@impacteds, $cktparts[1]);
## the @impacteds array is appended to by a non-topcell
}
}
}
}
$newsub = pop(@impacteds);
## the last non-topcell in @impacteds is taken out here
if ($newsub) {
##as long as the non-top @impacteds aren't exhausted
$newsub = ' '.$newsub.' ';
&findsubs($newsub);
## recursive call with the new impacted subckt
}
}
$infile = "spicenet.txt";
print $infile, "\n";
open(F, $infile);
$ii = 0;
while(<F>) {
$lastline = $_;
chomp $lastline;
$ckt[$ii] = $lastline.' ';
$ii++;
}
$jj = $ii -1 ;
$findsub=0;
$matchpat = " sub3 ";
$subpat = 'subckt';
@impacteds = ();
$topcell = 'topcell';
&findsubs($matchpat);
## first entry into the recursive
Result:
instance= X23 p q sub3
subckt= sub19
instance= X64 y z sub3
subckt= sub4
instance= X76 rr yy sub3
subckt= topcell
instance= X432 dd bb kk sub4
subckt= topcell
instance= X12 z c sub19
subckt= sub10
instance= X66 1 2 sub10
subckt= topcell
Do it using shell.
***
Item#52> Quiz11: what is the problem with the following perl?
Answer:
There is no problem, except that if I did this in shell, it could be done in three lines:
echo ' sub3 ' > grepf
echo 'subckt' >> grepf
cat spicenet.txt|sed -e s/$/ /' |grep -f grepf|grep -A 1 subckt |grep -B 1 '^X'
Consider the following spicenet.txt:
.subckt topcell
X22 uu oo sub3
X432 dd bb kk sub4
X321 gg hh sub5
X76 rr yy sub3
X66 1 2 sub10
.ends
.subckt sub5 s t
X11 s t sub2
.ends
.subckt sub2 8 9
R1 8 9 100
.ends
.subckt sub4 x y z
X54 x y sub3
X64 y z sub3
.ends
.subckt sub3 a b
Dx a b mod1
.ends
.subckt sub19 p q
X23 p q sub3
.ends
.subckt sub10 z c
X12 z c sub19
.ends
Shell gives:
.subckt topcell
X22 uu oo sub3
--
.subckt sub4 x y z
X54 x y sub3
--
.subckt sub19 p q
X23 p q sub3
Perl gave:
instance= X23 p q sub3
subckt= sub19
instance= X64 y z sub3
subckt= sub4
instance= X76 rr yy sub3
subckt= topcell
What about the sub10 that instantiates sub19 which is impacted by sub3? So, this motivates a recursive routine. You want to see all the sub-blocks of topcell, and their subcells that are impacted by sub3.
***
Item#51> Searching problem subckt with perl -
Let's say there is a problem subckt ('sub3') that came from a vendor. And, it has been instantiated in various other subckts in the fullchip netlist. Write perl to identify those subckts where 'sub3' is instanced.
Here is a way how:
## written with activePerl64 for windows7
## Arya, Oct 10, 2012
$infile = "spicenet.txt";
## assumes there is no '+' sign continuation mark in netlist ## all subckt defs start with lower case .subckt, instances ## start with upper case X
open(F, $infile);
$ii = 0;
while(<F>) {
$lastline = $_;
chomp $lastline;
$ckt[$ii] = $lastline.' ';
$ii++;
}
## first read in the entire netlist into @ckt
$jj = $ii -1 ;
$findsub=0;
$match_pat = " sub3 ";
$subpat = 'subckt';
for ($kk=$jj; $kk>=0; $kk=$kk-1) {
##Searching from bottom up
if ($findsub == 0) {
if (($ckt[$kk] =~ /$match_pat/) && ($ckt[$kk] =~ /^X/)) {
$findsub = 1;
## finds first match, start looking for the subckt
print "instance= ",$ckt[$kk], "\n";
}
}
if ($findsub == 1) {
if ($ckt[$kk] =~ /$subpat/) {
## finds the subckt, start finding the next instance match
$findsub = 0;
@cktparts = split(/\s+/, $ckt[$kk]);
print "subckt= ",$cktparts[1], "\n";print "\n";
}
}
}
***
Item#50> Quiz10: In the counter shell code given below (way below), if you turned the t2 input to the AND gate to 'HI' or 'LO' what would happen?
Answer:
AND input t2 disconnected and turned to 'HI' :
the counter counts from 0 thru 6, then jumps to 15 and collapses to 0 again, and so on.
AND input t2 disconnected and turned to 'LO' :
the counter counts from 0 thru 7 and collapses to 0
Obviously, in both cases, the counter cannot run its full course. In fact, the 'LO' case turns it into a 3-bit counter. Also, the results indicate that if the t2 input to the AND was just disconnected, and not turned to anything (HI/LO), the 8th count becomes unpredictable! That's why, floating gate checks are so vital, because, floating gates make the circuit's behavior unpredictable.
When a whole digital block (even analog sub-blocks represented by current/voltage transfer equations) is converted into a shell/perl routine, the possibilities in real-time experiments and debugging are endless!
***
Item#49> Real-time 4-bit counter action [at the bottom of this page] shown through an mp4 [Oct 4. 2012] taken with my cellphone, for a 3-stage ring osc [shell code given earlier] -
Note the times awked out of `date` pasted to the counts - 3 stage ring osc gives rise to 6s period intervals from count to count.
Means what? You can model even larger digital blocks in this way, and debug their various nodes in the real-time mode!
* shell-based digital emulation done on an Intel atom based Asus meego system, mp4 taken with a Samsung gravity smart phone
***
Item#48> Quiz9: Is the following model unrealistic, reducing gas consumption as you go uphill?
Answer:
Yes, as the number of stages of the ring oscillator decreases, the dynamic power consumption (~n*C*Vdd^2*f, n - number of stages, C - the combined gate caps [pmos/nmos] per stage, f - the ring osc frequency, Vdd - ring osc power) remains somewhat unchanged, f increases, but n decreases. Of course, this is counter-balanced by the effect of the filter cap at the output (if any), that bleeds power at a rate proportional to the ring osc frequency (f).
But, it's a good idea to think of an explicit power bleed circuit to model the gas consumption, and apply it in parallel to the ring osc:
[Oct 01. 2012, Arya Raychaudhuri, Sunnyvale, California]
The MOSFET (Mx) will bleed power as square of the ramp function - so somewhat pessimistic (gas guzzler). More gas friendly cars would be modeled by a base resistance coupled low-beta npn (bipolar) device (IC ~ beta*IB).
***
Item#47> Possible extension of running the clock in the background and sensing it in the foreground into mechanical rotational movements modeling? :-)
Let's say, the main clock is running at a higher frequency. Now, referring to the rotating wheel (see below in the context of moving calibre flags), in one calibreDRV session, rotate the wheel at the frequency of the clock - the mother motor. In another parallel session, sense the clock at a fraction of the frequency - this models the gear ratio, and rotate the wheel, and so on. For example, if the mother motor (clock) is stopped, the other wheels stop. If a particular driven motor is stopped, it's like disengaging the clutch!
* gears courtesy science.howstuffworks.com, the mother motor on the right.
[Sep 29. 2012, Arya Raychaudhuri, Sunnyvale, California]
I was driving my automatic transmission car on cruise control (tries to maintain constant speed) yesterday up a ramp on freeway 5 near LA - as the slope increases, the RPM of the motor increases, and the gear ratio goes up (slower gear). So, you can think of a numerical ramp function - for low difficulty value (1-3), set the ring oscillator stages to 21 and gear ratio to 7, for difficulty value >3<=6, set ring osc stages to 15 (higher frequency, RPM), gear ratio to 11, etc.
***
Item#46> LVS thought on the dual MOS ckt -
One interesting projection to the LVS domain is that you can let such ckts be recognized as a user-defined device (UDD, seed as the cell extent), and then trace all the internal parts as derived polygons - pass them as parameters to the property calculation routine. Use the voltage transfer equation to calculate Vin, Vo at several points - put out the calculated points as properties in an extracted netlist, only for specific ckts. Parse the properties to see if they meet the requirement.
***
Item#45> Dual MOS feed forward
The configuration shown below represents a negative feed forward mechanism - if anyone has seen the config in the literature let me know, I will acknowledge the precursor. If we add a similar PMOS between Vo and a pad supply (1.8V) source, with its gate tied to the Vin also, we get a dual MOS feed forward that can steady the Vo in a narrow range in the face of Vin swing between 0.75V and 1.55V - then you don't need the charge pump.
[Sep 27. 2012, Arya Raychaudhuri, Sunnyvale, California]
Look at the Vo variation with Vin -
[Sep 27. 2012, Arya Raychaudhuri, Sunnyvale, California]
When MC is leaking, MC2 is not and vice versa -
[Sep 27. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#44> Quiz8: Knowing that MC is working in saturation, derive the functional relationship between Vo and Vout for the output stage -
Hint:
Id = (K/2)*(Vout -VT)^2 [^2 means squaring]
Answer:
[Sep 26. 2012, Arya Raychaudhuri, Sunnyvale, California]
Since the opamp has very high gain (~1e6), for any small Vop, the voltage difference between '+' and '-' terminals is close to 0, and Vout is transferred to the '-' terminal
So, for current path i1,
(Vop - Vout)/R2 = Vout/R1 -->Vop = Vout (1+R2/R1) ~ Vout
Since R1>>R2, actually, R1 could be made even higher
For current path i2,
(Vop - Vo)/R3 = (K/2)*(Vout -VT)^2 -->
Vo = (Vout - VT) * [1 - (R3*K/2)*(Vout - VT)] + VT, since Vop = Vout from current path i1
Means what? If R3=0 (zero output resistance) or K=0 (no MC, open), Vo = Vout, no voltage reduction. So, you need to have finite R3 and sizeable (W/L) --> K to get voltage reduction as a function of Vout. If W/L too high, more space needed for MC layout, more leakage current, if R3 too high, more output resistance, not good. So, strike a balance between the two.
***
Item#43> Now, lets look at measuring the K and VT of the MC transistor -
In linear mode, Id = K [VGS -VT -VDS/2]*VDS
VDS 1 0 DC 0.05
VGS 2 0 DC
MC 1 2 0 0 NMOS L=0.045um W=0.45um
.DC VGS 0 1 0.005
.PLOT DC I(1)
[Sep 25. 2012, Arya Raychaudhuri, Sunnyvale, California]
Threshold voltage (VT) is where the maximum slope (K*VDS) of the curve cuts the VGS axis, minus VDS/2. So, export this data into a text file id_vg_linear.txt , and apply this perl:
[Sep 25. 2012, Arya Raychaudhuri, Sunnyvale, California]
Gets us: K=0.002247 A/V^2 VT=0.566V
Means what? MC is running in saturation mode, even till Vin = 1.2V
***
Item#42> A non-inverting opamp with a voltage controlled active load at the output of the charge pump circuit helps decrease open-circuit output voltage/output impedance -
An unresearched [could have been discussed elsewhere] output stage (**there was an error in the yesterday's figure with R2 connection, it is now corrected, 9-25-2012)
[Sep 25. 2012, Arya Raychaudhuri, Sunnyvale, California]
I simulated for R1=10 KOhms, R2=100 Ohms, R3=1000 Ohms, a MC aspect ratio of 10, and an ideal opamp -
Vin=0.75V, Vout(oc)=1.24V, Vo=0.96V
Vin=1.2V, Vout(oc)=1.75V, Vo=1.2V
Improved Output impedance (much less):
At Vin=1V, from the Vout vs Rx curves (discussed below),
Vout=0.48V at Rx=10KOhms
For the same Vin/Rx, the above circuit simulates Vo=1V
The problem with this apprach is that MC leaks current (~0.5mA) in steady state - but shows a way to bring down output voltage with a voltage controlled resistor (MC).
Also, higher (>1.1V) voltage tolerant transistors may be needed for the ckt to sustain overdrive voltages.
***
Item#41> unsetting noclobber in bash - some of the scripts that involve repeatedly rewriting to an existing file will require
set +C
## enables rewriting in the shell
set -C
## disables rewriting in the shell, default condition
***
Item#40> Quiz7: In the shell implementation of the 4-bit counter (below), we did not apply any gate delay to the AND gate and the T flipflop, why?
Answer:
We needed the gate delay in the inverter to generate the clock, but the clock cycle is much longer (22s >> 1s for inverter) than the gate delay, even for the AND and the TFF (probably a couple of seconds).
Now, when the TFFs sense the clock positive edge, they simultaneously start reacting to their inputs (T0-T3) even before the ANDs can change their outputs - because, physically, the ANDs have gate delay. Once the TFF inputs enter the TFFs, any subsequent change in the inputs doesn't matter until the next clock positive edge. So, we let the TFFs switch instantly (no gate delay), and present their outputs (Q0-Q4) to the inputs of the ANDs, which are then sequentially switched, also instantly (no gate delay). Because, even if we applied gate delay to the ANDs, they would all be switching and generating fresh T0-T3 much before the next positive edge.
This simplifies the coding, without losing the focus on modeling the counter action.
***
Item#39> Perl equivalent of running the clock in the background and sensing it in the foreground - Forking
[Sep 20. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#38> Extension of shell based logic modeling - the first 4-bit (0-15) binary up counter in
http://www.doe.carleton.ca/~jknight/97.478/97.478_01F/dig3cirH.pdf
** Diagram Courtesy Carleton U , Canada
[Sep 19. 2012, Arya Raychaudhuri, Sunnyvale, California]
Write shell code to show counter action (0 to 15) - use the output of the below ring oscillator as the clock.
### A real time emulation of the counter is shown at the bottom of this page
- Introducing Shell based dynamic emulation of digital circuits
[Sep 20. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#37> The truth table of an inverter is encapsulated in the following shell function - gate delay of 1s. Write a shell to mimic an 11-inverter ring oscillator
inverter_func () {if [ $inX == "HI" ] ; then outX='LO'; else outX='HI'; fi; sleep 1 ; }
Here is how:
inX='HI'
let nn=0
while [ 1 ]; do let nn=$nn+1; inverter_func; inX=$outX; echo $nn; if [ $nn -eq 11 ]; then let nn=0; echo $outX; fi; done
* done using bash
** each call to the inverter_func represents passing the signal through a stage, notice that only for odd number of stages, the outX will toggle from HI to LO and back (oscillate). In this case, the time period (one HI to the next HI) is 22s - so, the frequency is 1/22 Hz
***
Item#36> Quiz6: Find the effective source potential (V_eff) and input resistance (R_in) for the charge pump (below) around a load resistance Rx of 50 KOhms -
I had used the following spice netlist in my earlier sim:
test charge pump
MN1 1 3 2 VSS NMOS L=0.045um W=0.135um
MN2 1 2 3 VSS NMOS L=0.045um W=0.135um
MP1 5 3 2 VDD PMOS L=0.045um W=0.27um
MP2 5 2 3 VDD PMOS L=0.045um W=0.27um
C1 7 2 15pf
C2 6 3 15pF
Cx 5 0 10pF
Rx 5 0 50000
VIN 1 0 DC 1
VHI VDD 0 DC 1
VLO VSS 0 DC 0
Vphi 7 0 PULSE (0 1 1ns 1ns 1ns 24ns 50ns)
Vphi_bar 6 0 PULSE (0 1 26ns 1ns 1ns 24ns 50ns)
.LIB PTM45LP_model_lib.txt
.TRAN 1ns 2000ns
.PLOT TRAN V(5)
Answer:
Realize that for a constant voltage source V_eff with an input resistance R_in, the output voltage Vout across a load of Rx is given by
Vout = V_eff* [Rx/(Rx+R_in)]
So, knowing Vout [see V(5) above] for two Rx values around 50KOhms,
Vout=1.447V for Rx=55000
Vout=1.343V for Rx=45000
we can find, R_in = 29.4KOhms, V_eff=2.22V
The value of R_in is high due to small aspect ratios (3 for nmos, and 6 for pmos) chosen for the sim. The R_in can be significantly brought down with a higher aspect ratio, or by using lower (than the standard cells) threshold transistors.
[Sep 16. 2012, Arya Raychaudhuri, Sunnyvale, California]
See that the ring ocillator is merrily vibrating with a peak of ~1.2V when fed with the Vout from the charge pump! Means what? An IR drop affected zone of standard cells could be fed with it.
See below for an interesting comparison of Vout from the charge pump against the Vout from a constant voltage source (2V/25KOhms). The quicker saturation of the charge pump Vout is due to phenomenological reasons.
** curves drawn using microsoft excel
[Sep 16. 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#35> Locally raising the voltage to address IR drop issue -
Earlier I had discussed perl-SVRF based Via deficiency checker-adder to address IR drop issues. Here is another way to do it - by raising the local VDD slightly with a cmos charge pump [courtesy, Wikipedia]:
http://en.wikipedia.org/wiki/File:Cross-coupled_voltage_multiplier.svg
I did a simulation of the first stage, see the result below
[Sep 14. 2012, Arya Raychaudhuri, Sunnyvale, California]
I took Vin=1V, the clocks phi1 and phi2 (180 out of phase with phi1) at 1V/20MHz, the caps at 15pf - the red trace is Vout, getting pumped to ~1.4V
***
Item#34> On various applications of the ring oscillator -
The ring oscillator is an interesting contraption with various applications, for example, in temp sensing and leakage power estimation:
[http://www-unix.ecs.umass.edu/~bdatta/lab4_report.htm]
As is seen in the below FFT compare, the fundamental frequency shifts to 2.328 GHz if we remove the RC filter from node 10 (below netlist). Such is the sensitivity of the oscillator that's appealing towards mapping various parameters to frequency.
[Sep 13, 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#33> Netlist debug : An 11-stage ring oscillator vibrating at 1.418GHz:
test ring ckt - 1.418GHz
MN55 5 4 0 0 NMOS L=0.045um W=0.09um
MN2 2 1 0 0 NMOS L=0.045um W=0.09um
MN3 3 2 0 0 NMOS L=0.045um W=0.09um
MP4 4 3 VDD VDD PMOS L=0.045um W=0.135um
MN31 1 11 0 0 NMOS L=0.045um W=0.09um
MP5 5 4 VDD VDD PMOS L=0.045um W=0.135um
MN6 6 5 0 0 NMOS L=0.045um W=0.09um
MP27 1 11 VDD VDD PMOS L=0.045um W=0.135um
MP35 3 2 VDD VDD PMOS L=0.045um W=0.135um
MP67 7 6 VDD VDD PMOS L=0.045um W=0.135um
MP62 11 13 VDD VDD PMOS L=0.045um W=0.135um
MN7 7 6 0 0 NMOS L=0.045um W=0.09um
MP85 8 7 VDD VDD PMOS L=0.045um W=0.135um
MN71 11 10 12 0 NMOS L=0.045um W=0.09um
MN25 8 7 0 0 NMOS L=0.045um W=0.09um
MP95 9 8 VDD VDD PMOS L=0.045um W=0.135um
MP29 2 1 VDD VDD PMOS L=0.045um W=0.135um
MN19 9 8 0 0 NMOS L=0.045um W=0.09um
MN46 4 3 0 0 NMOS L=0.045um W=0.09um
MP90 10 9 VDD VDD PMOS L=0.045um W=0.135um
MN10 10 9 0 0 NMOS L=0.045um W=0.09um
MP11 11 10 VDD VDD PMOS L=0.045um W=0.135um
MN12 12 13 0 0 NMOS L=0.045um W=0.09um
MP16 6 5 VDD VDD PMOS L=0.045um W=0.135um
.LIB PTM45LP_model_lib.txt
**model source:http://ptm.asu.edu/modelcard/LP/45nm_LP.pm
R1 10 17 1000
C1 17 0 0.005pF
VSUP VDD 0 DC 1
VEN 13 0 PWL (0 0V 1ns 0V 1.1ns 1V)
.TRAN .1ns 10ns
.PLOT TRAN V(17)
** Simulation done using Linear Technology's LTspice IV
[Sep 12, 2012, Arya Raychaudhuri, Sunnyvale, California]
Find the inverter transistor pairs from the above netlist using the logic parsing discussed earlier.
***
Item#32> Time-tested engineering principle - create a solution S for a problem P, transform similar problems Q, R, T .... to P and then apply S to solve them.
Using this hint, create a netlist flattener using a Recursive shell - expand all instances (^X...) using their subcircuit definitions and write out a flat devices (^M..., ^D..., ^R..., ^C..., etc.) only (no instances) netlist.
Comments:
One of the important things to keep track of is to properly add the instance names to the device names as the expansion takes place. For example, the top level's expansion can have device names like M1, M2, D1 etc., but the devices for instance X1 under top level, should be named M1.X1, M2.X1, etc., again if there is an instance X2 under this X1, the devices of that X2 should come out as M1.X1.X2, M7.X1.X2, etc. So, should be the case for the non-passed local ports.
Dealing with the passed ports is simpler. Create a sedf file with the calling pins and called ports (of the subcircuit)whenever an instance call is encountered, using sed -f sedf subckt_file_sans_top_bottom_line
Pipe this into a function that does the M1.X1.X2 type maneuvers - the result of this becomes the new $fff (see below) for the next recursion.
***
Item#31> Results of the Recursive shell on a sample test case -
Three files xxx, yyy, zzz created.
Contents of xxx:
this is line 1 in xxx
this is line 2 in xxx
.INCLUDE /home/usr/lvs_engr/yyy
this is line 4 in xxx
this is line 5 in xxx
.INCLUDE /home/usr/lvs_engr/zzz
this is line 7 in xxx
Contents of yyy:
line 1 in yyy
line 2 in yyy
.INCLUDE /home/usr/lvs_engr/zzz
line 4 in yyy
Contents of zzz:
#1 in zzz
#2 in zzz
#3 in zzz
Now, we set,
fff=/home/usr/lvs_engr/xxx
Run script,
test_func
Result:
this is line 1 in xxx
this is line 2 in xxx
line 1 in yyy
line 2 in yyy
#1 in zzz
#2 in zzz
#3 in zzz
line 4 in yyy
this is line 4 in xxx
this is line 5 in xxx
#1 in zzz
#2 in zzz
#3 in zzz
this is line 7 in xxx
***
Item#30> Quiz5: Recursive shell - expand all .INCLUDE files (often the memory/IP/standard cells library netlists) in a spice netlist using a recursive shell script, and print out the full netlist without any .INCLUDE in it.
Recursive (self-calling, the script calling itself as a subroutine function), because the .INCLUDE files themselves can have more .INCLUDEs in them and so on.
Answer.
expand_func () {sed -e 's/ /%/g' $fff > tmpX; for ii in `cat tmpX`; do ll=`echo $ii|sed -e 's/%/ /g'` ; ld=`echo $ll|awk '{print $1}'`; if [ $ld != ".INCLUDE" ] ; then echo $ll; else fff=`echo $ll|awk '{print $2}'`; expand_func; fi ; done }
## recursive function defined
fff=/home/usr/lvs_engr/fullchip.netlist
## the fullchip netlist path set here
expand_func
## function call to initiate script run
## Done in bash
*** If some spice netlist lines start with '*' - which is a comment in spice, all '*' characters in the netlist should be moved to '#' or "~" and sed-ed back in the above script, to avoid issues, e.g.,
sed -e 's/ /%/g' $fff|sed -e 's/\*/\#/g' > tmpX;
then echo $ll|sed -e 's/\#/\*/g';
Additional syntax in brown.
***
Item#29> Pins swapped grepping with awk -
If you carefully notice in the figure below,
Mx1&Mx2 Out A B
Mx3&Mx4 Out B A
would also form a 2-input nand, so you need to 'pin-swap-grep' it with awk , like
cat testf |tr [:lower:] [:upper:]|awk '{if(($2 == "OUT") && ((($3 == "A")&&($4 == "B")) || (($3 == "B")&&($4 == "A")))) print}' > testf_awked
## first transfer case, lower to upper
grep -i -f testf_awked testf
## get back original case in 'grepped'
***
Item#28> Extend the logic parsing to 2 input NAND gates -
[Sep 06, 2012, Arya Raychaudhuri, Sunnyvale, California]
Hint: create compound devices like
Mx1&Mx2 Out A B
Mx3&Mx4 Out A B
And, then grep like with the inverter [Sept 6, 2012]
Good thing about this line of looking into the netlist is that it imports the complementarity of the CMOS configuration into parsing.
***
Item#27> Interesting domain of logic parsing from CMOS netlists -
Find all inverting pairs like
MX1 XD1 XG1 VDD VDD PMOS ......
MX2 XD1 XG1 VSS VSS NMOS ......
in a complex CMOS netlist using shell code, to produce instance pairs like
MX1
MX2
MX34
MX37
etc.
Answer:
cat cmos.net |awk '{print $1 "@ " $2 " " $3 " " $4 " " $6}' >work.net
## get @ padded instance name, and relevant pins, model name
cat work.net |grep -i NMOS | awk '{print $1 " " $4}' |grep -i VSS |awk '{print $1}' > nmos_gnd
## linear list nmos with source to VSS
cat work.net |grep -i PMOS | awk '{print $1 " " $4}' |grep -i VDD |awk '{print $1}' > pmos_vdd
## linear list of pmos with source to VDD
cat work.net |awk '{print $1 "###" $2 "###" $3 "###"}' |grep -f pmos_vdd > pmos_DG_vdd
## get padded (###) instance, drain, gate of those pmos
for nm in `cat nmos_gnd`; do dd=`grep $nm work.net|awk '{print $2}'`; gg=`grep $nm work.net|awk '{print $3}'`; idg=$dd'###'$gg'###'; pm=`grep $idg pmos_DG_vdd|sed -e 's/###/ /'|awk '{print $1}'`; if [ "$pm" ]; then echo $nm ' ' $pm; fi; done
## the trick is in creating the padded pins for the candidate nmos devices, and grepping the candidate pmos devices with it, in a batch process
## Done in bash
***
Item#26> Shape transformation 2: Last time I showed you how to create notches in a 10um by 1um bar - now let's see if you can do this -
[Sep 05, 2012, Arya Raychaudhuri, Sunnyvale, California]
Create a regular octagon hole (all sides of equal length) in the middle of the same 10um by 1um bar, 2um from the center, with a bounding box size of 0.4 um for the octagon. Assume the resolution and precision to be 0.001 um.
Answer:
DIFF_C = EXTENTS DIFF CENTERS
LEFT_NOTCHER_1 = SHIFT ((GROW DIFF_C LEFT BY 1.9) NOT (GROW DIFF_C LEFT BY 1.5)) BY 0 (-0.7)
LEFT_NOTCHER_2 = SHIFT ((GROW DIFF_C LEFT BY 1.9) NOT (GROW DIFF_C LEFT BY 1.5)) BY 0 0.7
BOUND_BOX = EXT LEFT_NOTCHER_1 LEFT_NOTCHER_2 == 0.4 OPPOSITE REGION
OCTAGON_CORNERS = INT BOUND_BOX <= 0.117 ABUT == 90 REGION
// if octagon side is a, a + a*sqrt(2) = 0.4 --> a = .166
// so, corner triangle non-diagonal sides = 0.166/sqrt(2)
// --> 0.117
DIFF_WITH_OCTAGON_HOLE = DIFF NOT ( BOUND_BOX NOT OCTAGON_CORNERS)
***
Item#25> If the src and drn of a MOSFET are tied to pwr and gnd respectively, or reverse respectively, and the gate is floating, some spurious charge riding on the gate can favorably bias the transistor, and create a resistive short between pwr and gnd -
Write shell script to extract such MOSFETs from a flat mosfets-only netlist (subckt) - make sure their gates are not tied to a subckt pin or a diffusion.
Answer:
cat mosfet_subckt.sp | awk '{if ($1 != "+") printf "\n"; for (i=1; i<=NF; i++) printf "%s ", $i}' |sed -e 's/+//g' > mosfet_subckt_ljX.sp
## join the '+' sign continued lines
cat mosfet_subckt_ljX.sp |grep -i subckt |awk '{for (i=3; i<=NF; i++) printf $i "\n"}' > sub_pins_list
## collect the subckt pins into a linear file
cat mosfet_subckt_ljX.sp |grep -i '^M' |awk '{printf $2 "\n"; printf $4 "\n"}' > diff_pins_list
## collect the diffusion pins of mosfets into a linear file
touch no_float_pins_; cat sub_pins_list >> no_float_pins_; cat diff_pins_list >> no_float_pins_;sort no_float_pins_|uniq >no_float_pins
## concatenate the two pins list files into no_float_pins
cat mosfet_subckt_ljX.sp |grep -i '^M' |awk '{printf $1 " " $2 " " $4}' |grep -f vdd_list|grep -f gnd_list |awk '{print $1}' > mosfets_pgsd
## get the mosfets whose s/d are tied to p/g
cat mosfet_subckt_ljX.sp |grep -i '^M' |grep -f mosfets_pgsd|awk '{print $1 " " $3}'|grep -v -f no_float_pins|awk '{print $1}' > mosfets_pgsd_floatGate
***
Item#24> Shape Transformation: Sometimes it is necessary to change the shapes of some polygons in the design using a physical verification tool, such as Calibre. Here is an interesting task.
[Sep 01, 2012, Arya Raychaudhuri, Sunnyvale, California]
The diffusion bar at the top is 10um long and 1um in height. Create two notches, each 0.2um deep and 0.4um long, at 1um from the center of the bar, as shown in the lower bar.
DIFF_C = EXTENTS DIFF CENTERS
LEFT_NOTCHER = SHIFT ((GROW DIFF_C LEFT BY 0.9) NOT (GROW DIFF_C LEFT BY 0.5)) BY 0 (-0.2)
RIGHT_NOTCHER = SHIFT ((GROW DIFF_C RIGHT BY 0.9) NOT (GROW DIFF_C RIGHT BY 0.5)) BY 0 0.2
LEFT_NOTCH = ENC LEFT_NOTCHER DIFF == 0.2 OPPOSITE REGION
RIGHT_NOTCH = ENC RIGHT_NOTCHER DIFF == 0.2 OPPOSITE REGION
DIFF_NOTCHED = DIFF NOT (LEFT_NOTCH OR RIGHT_NOTCH)
***
Item#23> Quiz4 : Use of DISCONNECT in yesterday's example.
In your deck, if you had another set of connects before the CONNECTs I established, you could have used a DISCONNECT command to remove the previous connectivity model. The new connectivity model would then operate under a
DRC INCREMENTAL CONNECT YES //like in an antenna deck
But, you could still use the derived polygon variables created under the previous connectivity model under the new one. Let's say, in the previous connects you had CONNECTed all the way up to M1, starting from M10, and derived a polygon set:
M2_VDD_X = M2 NET AREA RATIO (M10 WITH TEXT "VDD" 126 PRIMARY ONLY) > 0
Now, my question is would the polygon sets M2_VDD_X and M2_CONN_M1_CONN_M2_VDD (see below) be exactly identical in all cases?
Answer: NO, see figure below -
M2_VDD_X - m2(1,2,3), M2_VDD - m2(1), M2_CONN_M1_CONN_M2_VDD - m2(1,2)
[Aug 30, 2012, Arya Raychaudhuri, Sunnyvale, California]
***
Item#22> Quiz3 : Distinction between electrical connectivity and physical connectivity in the ruledeck context -
Electrical connectivity is established through CONNECT/SCONNECT constructs. for example,
CONNECT M2 M1 BY V1
//metal1 gets electrically connected to metal2 by via1
While,
M1_CONN_M2 = M1 INTERACT (V1 INTERACT M2)
//M1_CONN_M2 is metal1 physically connected to metal2
Now, based on this distinction write code to find all up-connects from M1 VDD rails in a 10 metals design. As you know, power/ground should typically flow down the metal layers (top M10 to bottom M1), not up, like M1 to M2.
Answer:
::::<preceding code>
CONNECT M10 M9 BY V9
CONNECT M9 M8 BY V8
::::<succeeding connects thru the metal/via layers>
CONNECT M3 M2 BY V2 // stop here
M2_VDD = M2 NET VDD //traced from M10s marked VDD
M1_CONN_M2_VDD = M1 INTERACT (V1 INTERACT M2_VDD)
M2_CONN_M1_CONN_M2_VDD = M2 INTERACT (V1 INTERACT M1_CONN_M2_VDD)
SHOW_M2_UPCONNECTS {@ M2 uptaps from M1 VDD rails
M2_CONN_M1_CONN_M2_VDD NOT M2_VDD
}
***
Item#21> Another deep nwell related flaw -
The isolated psub enclosed above a deep nwell is not fully surrounded by nwell ring(s). Someone leaves a little DRC correct gap! Then the psub is no longer isolated.
***
Item#20> There is p-substrate under deep nwells - interesting LVS deck thought!
One of the most important things to consider while writing an LVS deck is to make sure that all the possible shorting scenarios are covered. For example, if you had not 'connect'ed the p-diffusion to n-diffusion, you would not correctly model the saliciding. One crucial thing to check for your LVS deck is to see if it correctly models the connections through the p-substrate under nwells and even deep nwells.
True, the p-substrate inside deep nwells is isolated from the global psub, but what if someone wants to make a donut shaped deep nwell, and wants to place some devices in the center of the donut. The p-substrate in that region is not isolated, and is connected to the global psub through the underneath of the deep nwell!
***
Item#19> More on colors and movements -
You can modify the calibreDRV layer properties file to enter hex codes for shades with a different layer name (lay1, lay2, lay3, etc.), and then use the layers to plot density, and even current density on interconnects (static flags). Also, changing shades to indicate transient voltage rise/fall (moving flags) at nodes. [Aug 27, 2012] For hex codes, one of the nice websites to look up:
http://www.colorschemer.com/online.html
Item#18> How to move calibre flags. Look at the figure below:
[Aug 25, 2012, Arya Raychaudhuri, Sunnyvale, California]
Create two polygons in a tcl (calibreDRV) - one corresponding to the blues, the other the reds (above). then use the $L create polygon and $L delete polygon constructs on the alternate polygons interspersed with after 200 (ms) commands and put it in a while (1) loop, you will see the wheel rotating continuously on the gui. If you had gotten the flags from a DRC run - it will be moving calibre! [Aug 25 2012]
***
Item#17> v2lvs tip: v2lvs -v <verilog_netlist> [-l <stub_file>] [.......] -o <spice_output>
When do you need a stub_file while translating the top module's verlog netlist? Do this simple test:
grep '\:[0-9]*\]' verilog_netlist | grep -v '\:0\]' -->
NULL - no need of stubs
non-NULL - need stub_file
Multi-bit buses with non-zero LSBs going into a sub-module needs the stub (input/output pin definitions) for that module
***
Item#16> Speeding up net tracing on CalibreDRV
The net trace function on ClaibreDRV is extremely useful for debugging, but sometimes rather slow due to multitude of vias on net junctions. A good way to speed up is to create a temporary database with the multiple vias joined together into a single large via - should do it with size up/down with a tcl (calibreDRV). [Aug 22, 2012]
This is an interesting idea - that can impact LVS extraction times also.
***
Item#15> Calibre SVRF quiz2:
Typically, in a design there will be many instances of a particular cell (CX), distributed all over. Write SVRF code to locate the second farthest (not the farthest, but the one next nearer) from the left-bottom corner of the chip.
::::
::::
CX_EXT = EXTENT CELL CX ORIGINAL
CONNECT CX_EXT
DEVICE CXX CX_EXT CX_EXT(A)
[
property dist_from_origin
XC = X_LOC(CX_EXT)
YC= Y_LOC(CX_EXT)
dist_from_origin = XC * XC + YC * YC
]
will extract CXX devices devices with 'dist_from_origin' as a property parameter, numeric sort on the prop value after removal of the '=' sign in the netlist will yield the second last instance.
I could not come up with a pure single-run SVRF code to do this - the solution given involves parsing from outside. If anyone can provide a pure SVRF (single-run) for this, please e_mail me - I will post it here and acknowledge.
***
Item#14> Sort of like writing a routine that checks everyday at a particular time if I have updated this page, if no update, does nothing, but, if updated, rings an alarm bell so that you can open this site to look up the new input!
Yes, I am talking about the cron-make combo - a combination of the crontab and a makefile. With the crontab you can program the time and frequency of running a shell code. And, within the shell code you can embed a makefile to sense if the GDS or verilog data have been updated. If updated, it will start a drc/lvs run, otherwise, it will do nothing, saving license usage in a multi-user environment. I recently used this combo to good advantage!
***
Item#13> If you had not placed the '&' after the LVS fork (below):
the calibre command would first execute in real time, and then the next commands would be taken up. This leads to the interesting idea of running a shell/perl script through the 'exec' to parse the already generated DRC results db or some density/NARAC files (from preceding SVRF) to get a set of parameters to be used in the later TVF layer ops. Cool stuff - because it helps you impact the succeeding part of the DRC run with the previous results, all at runtime!
I am yet to try this idea. It may or may not happen properly - not sure. [Aug 18, 2012]
***
Item#12> Conditional spawning of an LVS run from a DRC run - depending on some derived polygon layer (LLX) - if LLX is NULL, start an LVS run and exit the parent DRC run, if LLX is non-null continue with the DRC run
LLX = <bunch of booleans>
spawn_rule {@ we use a runtime tvf function here
TVF lvs_spawner LLX
}
//If LLX is non-null, the DRC run continues with an output of LLX to drc results db
TVF FUNCTIN lvs_spawner [/*
tvf::GET_LAYER_ARGS lay1
if {[tvf::IS_LAYER_EMPTY $lay1]} {
exec calibre -64 -spice extracted.net -hcell hcells lvs_deck &
### see the '&' pushes the calibre lvs extraction run as a background subprocess, and the tcl process immediately proceeds to the next command
tvf::OUTLAYER "COPY $lay1"
exit
} else {
tvf::OUTLAYER "COPY $lay1"
### if LLX is non-null return the output to the calling SVRF
}
*/]
//end of lvs_spawner
***
Item#11> Shifting the origin of a design from the center to the left-bottom corner with a tcl (calibreDRV)
#! /usr/bin/tclsh
set L1 [layout create TOPCELL.gds -dt_expand -preserveProperties -preserveTextAttributes]
##Read the gds into variable L1, the TOPCELL has origin at the center, but its left-bottom coordinates are -2000, -1000 um
set L2 [layout create]
##create an empty handle L2
$L2 create cell My_cell
##create a cell 'My_cell' in L2
$L2 import layout $L1 FALSE append
##import the TOPCELL into L2
$L2 create ref My_cell TOPCELL 2000000 1000000 0 0 1
## create an instance of the TOPCELL at 2000,1000 um
$L2 expand cell TOPCELL
##flatten/merge the top level of the TOPCELL into My_cell
$L2 delete cell TOPCELL
##delete the TOPCELL from L2, since it is already merged to My_cell
$L2 cellname My_cell TOPCELL
##change My_cell name to TOPCELL
$L2 oasisout TOPCELL.oas TOPCELL -noEmptyCells -noRefs
##put out an OASIS file with the TOPCELL origin shifted
***
Item#10> Calibre SVRF quiz.
Let's say in a particular layout, there are multi-faceted polygons in a particular layer (as is always the case) - write SVRF code to identify those polygons whose all edges are of unequal lengths. Assume that no edge is less than 90nm in length.
Possible Approach - steps:
1. size up the polygons (X) by .005um --> Y
2. size down the polygons (X) by .005um --> Z
3. Get Y - Z --> P, this will be thin .01um width polygons all around the periphery of the X shapes
4. INT P == 0.01um PARALLEL OPPOSITE REGION --> Q, they will be thin 0.01um wide rectangles sitting in the middle of the edges. If a particular X has two or more Q's of equal area, then it is not what we are looking for.
5. CONNECT Q to X, so now the Q's interacting with the same X, are on the same net
6. Create single terminal Devices with Q's, and declare it's area as a parameter
7. Extract the layout into a flat netlist, in this netlist each net is a separate polygon in X
8. Parse this netlist with 'net' and 'Area' to get what you are looking for.
***
Item#9> When just finding fault (with the physical design) is not enough. You want to fix the issues. An example of how you can detect Via deficient junctions and add additional Vias with Calibre:
Please, refer to my earlier paper in Mentor Archives (moved from EETimes) -
The core algorithm uses the NET AREA RATIO construct in a useful way.
1. Find all the M(n) to M(n+1) [like M1 to M2, M6 to M7, etc.] junctions that are rectangular and are on the same net
2. With the RECTANGLES command fill them up in a DRC conscious way
3. Take the NET AREA RATIO between new Via fills and the pre-existing Vias on the same junctions - if the ratio is greater than a certain factor (degree of deficiency), these are Via deficient junctions - flag.
4. Subtract the pre-existing Vias from the new fills in a DRC conscious way, and put them out into a GDS (with DRC CHECK MAP) as an overlay mount - these are your fixes!
***
Item#8> Pattern recognition. Earlier you saw netlist pattern parsing (3 forward biased diodes stack example), now let's look at a layout pattern:
[Aug 13, 2012, Arya Raychaudhuri, Sunnyvale, California]
You could do this by using the LVS user-defined device construct. See that the pattern extent interacts with all the pieces - that's your device seed! One terminal devicing is good enough - need to read in only the pattern layers. Extracted netlist shows the pattern locations.
Pattern replication - Once the pattern extent is identified, all the pieces of the pattern can be placed in different polygon variables by AND-ing with the extent polygon. Now, you could use the svrf SHIFT construct (see above in the discussion on creating the octagon shape) to create multiple replicas of the pattern at various locations. Also, the GROW construct can help fib the pattern.
***
Item#7> LVS Debug is all about speed, if you can't do it quickly, it's like not doing it at all! Here is a quick and easy way to find LVS metal shorts in a device-less way -
Just read in the metal and Via layers, connect from the top metal down to the metal1, attach the text layers to the resprctive metals. Just declare one dummy device:
M1_Dummy = M1 WITH TEXT "non-existent"
// device seed
DEVICE NODEV M1_Dummy M1(P)
//The NODEV user-defined device satisfies the
//requirement of at least one device type in the deck
Now,
LVS ISOLATE SHORTS YES BY LAYER
in this little lvs deck will extract metal shorts much faster!
***
Item#6> Coordinate transforming fullchip DRC results into the space of a 0 reflection, 0 rotation, unity magnification cell (CX) with instance origin at x0,y0 :
grep -n '^' fullchip_drc.db | sed -e 's/:/ /' | grep -v '[A-Za-z\}*]' >
num_lines
## grepping out only the coordinate numbers
grep -n '^' fullchip_drc.db | sed -e 's/:/ /' | grep '[A-Za-z\}*]' > non_num_lines
## grepping out the other lines, see that we are also including the last line of DRC check texts '}'
cat num_lines | awk '{print $1 " " $2-x0 " " $3-y0}' > num_lines_xform
## coordinate transforming, but keeping the line number ($1) intact
cat non_num_lines >> num_lines_xform
## appending the non_num_lines to the transformed coordinates
sort -n -k 1 num_lines_xform | awk '{for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n"}' |sed -e 's/FULLCHIP_NAME/CX/'
> CX_space_drc.db
## The numeric sort with line numbers in place brings the file back to previous shape, then we remove the line numbers. Change the top line to CX. It's a good parsing technique
** Similar parsing was shown in my earlier coauthored work in Electronic Design - read: http://electronicdesign.com/article/eda/programmed-splitting-of-full-chip-calibre-drc-erc-errors-into-sub-block-space
***
Item#5> Shell equivalent of removing line numbers (nums:lines --> lines)
cat source_netlist_nn.sp |sed -e 's/:/ /' | awk '{ for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n"}' > source_netlist_nnX.sp
## See that we are first moving the ':' to a blank space, and then awk-ing out the 2nd to the last element (word) of each line. This runs faster than the perl
***
Item#4> Perl code for removing line numbers (nums:lines --> lines)
#! /usr/bin/perl –w
$infile = "source_netlist_nn.sp";
## line numbered 30 million lines netlist
open(H, $infile);
## connect a filehandle H to the input file, open in read mode
$pc = 0;
## setting the write enable to 0, so that line# 1 is not written out
while (defined($char = getc(H))) {
## getc is a one character reader function with perl
## charater by character batch process
if ($pc) {
print $char;
## writing out the character, depending on the write enable value
}
if ($char eq ":") {
$pc = 1;
## setting the write enable to 1, so that rest of the line beyond ':' is written out
}
if ($char eq "\n") {
$pc = 0;
## setting the write enable to 0, if the character is a line breaker, so that the next line's number is not written out
}
}
***
Item#3> Creating empty subcircuit definitions in black-box LVS situations - shell code example:
In this case, the LVS compare report ('lvs_test.rep') reports the missing subckt definitions in the source netlist ('source_netlist.sp'). So, you want to create empties from the instance calls in the source (v2lvs netlist), here is how -
cat source_netlist.sp | awk '{if ($1 != "+") printf "\n"; for (i=1; i<=NF; i++) printf "%s ", $i}' |sed -e 's/+//g' > source_netlist_ljX.sp
## remove '+' signs and join the broken lines
cat source_netlist_ljX.sp | grep -n '^' | sed -e 's/:/: /' > source_netlist_lj_nn.sp
## lines numbered
foreach ss (`grep Error lvs_test.rep | grep SUBCKT | awk '{print $7}' | sed -e 's/"//g' | sort | uniq`)
## one by one treat the missing subckt errors in the LVS report, this is batch processing
set tt = 'X'`echo $ss`'X'
## pad the subckt name with 'X's, helps avoid mixups
set nn = `awk '{print $1 " X" $3 "X"}' source_netlist_lj_nn.sp|grep -m 1 $tt |awk '{print $1}'`
## find the line number of the first occurrence of the subckt instance (with pin assignments) in the source netlist
set nnx = '^'`echo $nn`
## pad line number with line-starter
grep $nnx source_netlist_lj_nn.sp | sed -e 's/$PINS//' -e 's/=/ /g' | awk '{printf ".SUBCKT " $3 " "; for (i=4; i<=NF; i=i+2) printf "%s ", $i; printf "\n";printf ".ENDS"; printf "\n"}'
## create empty subckt for this $ss, see that we are awk-ing every alternate, pin-names, not assignments (i =i+2)
end
***
Item#2> What is canopy connection based short detection?
It's a way to bring out LVS shorts between non-texted metals in some specifiable cells, and texted nets. For example, you can create a copy of the BULK (extent) of the design, attach a TEXT to it. This becomes your texted canopy. Now connect the non-texted metals of the specific cells (let's say, scribe line) to the canopy. This helps transfer the net identity of the canopy to those unnamed metals. Now, run LVS extraction to find the shorts - pretty simple, really! It's the idea that drives the engine.
***
Item#1> SHELL Code for finding three forward biased diodes in a stack - explained:
From the flattened, "+" signs removed netlist, grep out the diodes and bipolars into - "all_DQs"
Create lists of all powers, grounds - "all_vdds", "all_gnds"
Now, go ahead -
cat all_DQs | grep QX | grep PNP > all_Q_pnps
## all PNP bipolars
cat all_DQs | grep QX | grep NPN > all_Q_npns
## all NPN bipolars
cat all_Q_pnps | awk '{print "DXc" $1 " " $2 " " $3}' > all_DcQ_pnps
## all the collector diodes of the PNPs, $2 - anode, $3 - cathode
cat all_Q_pnps | awk '{print "DXe" $1 " " $4 " " $3}' > all_DeQ_pnps
## all the emitter diodes of the PNPs, $4 - anode, $3 - cathode
cat all_Q_npns | awk '{print "DXc" $1 " " $3 " " $2}' > all_DcQ_npns
## all collector diodes of the NPNs, $3 - anode, $2 - cathode
cat all_Q_npns | awk '{print "DXe" $1 " " $3 " " $4}' > all_DeQ_npns
## all emitter diodes of the NPNs, $3 - anode, $4 - cathode
cat all_DQs | grep -v '^QX' > all_split_DDs
## all pure diodes
cat all_DcQ_npns >> all_split_DDs
cat all_DeQ_npns >> all_split_DDs
cat all_DcQ_pnps >> all_split_DDs
cat all_DeQ_pnps >> all_split_DDs
## all pure diodes plus coll/emit diodes of the bipolars
grep -n '^' all_split_DDs | sed -e 's/:/ /' > all_split_DDs_num
## line numbered
grep DX all_split_DDs_num | awk '{print $1 " " $2 " " $3}' | grep -f all_vdds | awk '{print $2}' > all_split_DX_power_anode
## diodes (instances) whose anode is connected to power
grep -f all_split_DX_power_anode all_split_DDs_num | awk '{print $4}' | sort | uniq | grep -v -f all_vdds > all_split_DX_power_anodes_cathode
## cathodes of the diodes whose anode is power
grep DX all_split_DDs_num | awk '{print $1 " " $2 " " $3}' | grep -f all_split_DX_power_anodes_cathode | awk '{print $2}' > all_split_DX_power_anode2
## diode instances whose anode is connected to the cathodes of the diodes whose anode is power
grep -f all_split_DX_power_anode2 all_split_DDs_num | awk '{print $4}' | sort | uniq | grep -v -f all_vdds > all_split_DX_power_anodes_cathode2
## cathodes of the diodes whose anode is connected to the cathodes of the diodes whose anode is power
grep DX all_split_DDs_num | awk '{print $1 " " $2 " " $3}' | grep -f all_split_DX_power_anodes_cathode2 | awk '{print $2}' > all_split_DX_power_anode3
## diode instances whose anode is connected to the cathodes of the diodes whose anode is connected to the cathodes of the diodes whose anode is power
grep -f all_split_DX_power_anode3 all_split_DDs_num | awk '{print $1 " " $2 " " $3 " " $4}' | grep -v -f all_vdds |grep -f all_gnds > all_split_DX_power_gnd_stack_trail
## diodes ( instances + pins ) whose cathode is a ground node and the anode is connected to the cathodes of the diodes whose anode is connected to the cathodes of the diodes whose anode is power - so, this is the trailing diode of the three-diode stack , located
========================================
### Below is Real time shell based emulation of the 0-15 digital counter (Item#38). See the counter updating every 6s as a result of a 3-stage ring oscillator based on a 1s delay inverter. The number of stages is reduced from 11 to 3, to make the update rate faster:
All snippets presented here are strictly proprietary to LVS DEBUG SOLUTIONS LLC, any commercial use of these is prohibited, without proper distribution agreement with the owner.
Arya Raychaudhuri
[the dates added to the drawings and plates indicate last edit dates]
In this page, we will discuss interesting LVS ideas, code snippets and ckt IPs (New Compute Machinery)
[Spot some of the new contributions to EE and ME]
Email/Call/Blog me if you have questions and comments, or want to buy scripts, circuit IPs ...
Keep watching!
To get these and similar problems sorted out in a comprehensive manner, and for fullchip physical verification through tapeout, please hire the services of LVS DEBUG SOLUTIONS LLC
Disclaimer: If you use the code snippets presented here without entering into a consulting agreement with LVS DEBUG SOLUTIONS LLC, the latter is not responsible for any outcome thereof.
"Where tireless striving stretches its arms towards perfection" - a favorite line from Tagore
Intelligent IP parents (female IP vmon, Item#150 and male IP pgen, Item#155) give rise to a number of smart applications (children)....
The reason for so many smart applications (children) of the pgen and the vmon is that they have mild IQ - they can count (pulses), and based on that, can take some decisions. An interesting thing to note is that their complexity is very low compared to a microController, for example, which has a very high IQ; but for many applications the mild IQ is enough, keeps the complexity low
Copyright 2011 LVS DEBUG SOLUTIONS & 2012 LVS DEBUG SOLUTIONS LLC All rights reserved.
LVS DEBUG SOLUTIONS LLC
980 Kiely Blvd, Unit 308
Santa Clara, CA 95051
United States
ph: 1-408-480-1936
arya