Wednesday, September 14, 2011

Understanding the Intel 4004

I have a new microscope that yields way better images than anything I had before, but, unfortunately, I'm having some difficulty getting a camera hooked up to it nicely. In the meantime since I still have images from other sources I thought I'd take some time to go through some parts of the Intel 4004. Flylogic has a similar write-up. This hopes to got a bit deeper especially showing how you can use tools to scale this up to analyze the/a full chip.

This article will use data from a variety of sources. The first is the Intel 4004 35th anniversary page which I like since it explicitly lists material as Creative Commons Attribution-Noncommercial-Share Alike 3.0 License. They also have a composite image (this is the author of the 4004 website so I presume its under the CC license?), schematics, and other assorted information. Datasheet and user manual can be found on Intel's website. I got the masks from FPGA-netlist-tools and read them in CIF format, specifically this file. if you don't want to load this up, you can find the original here. Finally, I'm also going to use a few small excerpts from the Flylogic top metal image and the Flylogic delayered image which I think should be fine under fair use but will take down if they would rather not have them here. I thought Intel had some CC or related images (had maybe even contracted the Flylogic) job) but I can't find those now. If there are no freely available images, if someone wants to donate a 4004 I could release some under a free license of your choice (or three if you have a million: one top metal, one delayered, and one for my collection!).

According to Wikipedia, the 4004 is 10 um pMOS which I was also able to verify on the datasheet ("4004 SINGLE CHIP 4-BIT P-CHANNEL MIROPROCESSOR"). This is similar to the NMOS logic I used in my JSSim inverter write-up except with the polarities reversed. Example PMOS inverter here.

However, I started getting a little confused as I started to look through things. Lajos describes pull-ups when I would expect PMOS to have pull-downs. Looking at various circuits, I also see what appears to be pull-ups. This confused me since I was thinking something along the lines of VDD = +5V, VSS = 0V with non-TTL compatible I/O (I didn't think through if the body connection is correct polarity, probably best to ignore it):


However, this doesn't really work since people would expect TTL compatible and this doesn't mask what I'm seeing in the mask as noted above. However, after looking at the user manual I found this:

Which shows that VDD = -10V and VSS = +5V which allows it to preserve TTL-compatible I/O. It was paired with this summary diagram:


The input stage shows why they want the +5V VSS: it provides the negative bias to trigger the PMOS input at 0 V while still allowing the pull-up to supply negative power for the input = 1 case. I was told that if you think of the circuit in terms of VDD, VSS, etc rather than actual voltages it should be more or less identical to NMOS logic. However, my understanding is that the depletion resistor is wired middle to bottom instead of middle to top so to speak as above. I don't have a good enough understanding of depletion modes to really know why this is the case.

That cleared up, lets see an example. I decided to look at the upper left hand corner because it was convenient. Cross referencing with the schematic a particular signal such as TEST might have been more logical if I was following the schematic rather than focusing on the masks. Here's the metal mask with VDD and VSS highlighted as well as an upper left hand corner area that I'll look at later in orange:


And a complete version also marked, but without VSS/VDD highlight:


Lets start with a theoretical closeup. Here's a dump from my CIF rendering:

The red (okay so its pink, otherwise I had opacity related rendering issues) is poly, the green is diffusion, the blue is metal (VDD), and the black are contacts. So we have two contacts tied to VDD and one going elsewhere which forms our pull-up. Note that you might have a self aligned gate for an enhancement MOSFET, but for depletion the entire area is diffused for normally on behaviour. This is what it actually looks like (Flylogic) in metal:

If the poly had blocked the diffusion we would not have seen the diffusion squiggle inside of the poly area. If they poly and diffusion masks were reversed, we could still tell that they were layered vs blocked since we can see a change on the squiggle exit rather than a solid line. And after delayering:

The poly and diffusion look almost identical. Fortunately, with whatever microscope technique they used (DIC maybe?) they get some good contrast between the traces and the background. I can't say for sure why it discolors where they meet, maybe just minor stress due to proximity.

Okay, but one transistor is the middle of nowhere is kind of hard to follow, so lets take a look at some of the nearby pins and see how it fits in. The upper left hand corner ties in the CM RAM 0-3 pins increasing clockwise starting with CM RAM 0 and 1 on the left and 2 and 3 on top:


These pins essentially provide the chip (bank) selection outputs to the RAM chips (4002). Since you can operate the system with a single 4002 this is an optional pin. Nonetheless, its fine for demonstration purposes. Lets arbitrarily focus on CM-RAM 0. Detailed picture of its layout:


The first thing I did was label all of the transistors that looked like they were involved in this input stage:


There is an identical input stage above that shares a small bit of poly with Q4 (diffusion just visible), but this does not influence us so ignore it. I then created a schematic with transistors arranged like in the above:

This is fine for layout capture, but a little ugly to read. Lets rearrange it to something a little nicer:

And then simplify by converting transistors to resistors where appropriate:

Cross referencing against Lajo's schematic:

They are equivalent. I'm particularly happy with this because this would have taken me a long time before but I got this pretty quickly and without having to fudge anything.

Okay, but that's only part 1 where we've managed to reverse the mask into the schematic. For part 2 is we need to see if we could figure this out from just the optical image. Here's top metal:



And delayered:


Which I've just roughly cut by using a box select + copy/paste from the full size images. I could of course work with the full size images, but they are large enough that they take up a significant amount of memory.

Anyway, I then imported them into Gimp by creating a new, slightly oversized canvas (700 X 700), importing them as layers, and setting their opacity each to 50%:


You'll notice the two images aren't quite aligned. This is why I wanted the oversize canvas as it allows me to move them around. Move them around until they line up. I should mention that I am by no means a Gimp expert, so don't take anything I do as to be the best was possible.

Next I created a layer for each mask. Since its difficult to tell buried contacts from contacts just by looking, I just created a single contacts layer (there there aren't any in our example). Since metal is very clear and un-ambiguous, I started with that by turning opacity back off and hiding the delayered image.

Press B to select the path tool. Click around a metal segment to form a polygon, remembering to click on the start portion to close it. You should now have a dashed line around your metal segment:


Then press shift-V to convert the path into a selection. Then press shift-B to select the fill tool and select a color (I used blue). Finally, fill the color in by clicking the mouse on the selection and then de-select your polygon by press ctrl-shift-A:


Make sure you put it on the metal layer by toggle show/hide for the metal layer. I believe this is the technique that was used to create the masks for the visual-6800 (plus a tool that converted the masks to JSSim input). A few tips:
  • You don't have to de-select the previous path. Just start working on the next one after fill and previous will automatically de-select when you convert it to a new path
  • You don't need to close the polygon. Last and first points will be assumed to be connected
One metal is done contacts are good to do next. As we saw with the original pullup, diffusion and poly can be difficult to tell apart just by looking at them. However, we know that IC designers have specific goals, so we can use those to figure out which is which. That said, some ICs are obfuscated, but we'll ignore that for now. Poly will usually cross diffusion areas. In particular look for it jutting out to complete a diffusion cut-off. That said, in the Flylogic 4004 example poly tends to get a lot of brown discolouration while the diffusion does not.

My first cut looked like this:


A few issues:
  • Need to figure out how to make level paths in Gimp so that it looks nicer. Right now it looks more like a kindergarten or abstract art drawing
  • The bit of diffusion that forms the pullup is not connected. Cross referencing with the masks, it is suppose to jut out to the side to go to a buried contact / via stack. However in the image it looks pretty clearly to NOT do that to me as I clearly the the edge of the diffusion. Maybe I'll get some feedback to clear this up
  • I also made an error with some poly to the right of this going to a buried contact, but this is visible in the images and a double check would have caught this. I also cared less since it wasn't part of the circuit I was analysing
  • What is the stuff under the pad? Maybe diffusion, but its not in those masks. There is a matching passivation mask but that should be on top and this is on the lower layers
This is close enough to the original that I think I could have derived the same schematic although maybe with low confidence on the pullup part. The rest of the chip can be decoded be continuing this exercise.

Hopefully this served to augment the Flylogic article and not just repeat it. In any case it helped me to make sure I really understood it.

Monday, August 8, 2011

Probing sneak peak

I was going to hold off on this since its a bit premature, but since Hyna wanted some details on what I was hoping to do for a probing station here is some quick info.

Since this is still just a part time hobby for me, I didn't want to spend too much on a probe station and waited patiently (course of a year or two of saved eBay searches...). I picked up several micropositioners for pretty good deal but had a much harder time finding a halfway decent probe station inexpensively. My goal was:
-Under $500, especially if it didn't have a microscope
-Have XY axis
-Have a solid platform for mounting probes
-Either have a microscope or not be too much trouble to add one

With that in mind, I eventually found this


Which was decently within budget and even had a Nikon microscope of sorts. The base is pretty solid which was the main thing I was after. The plugs (not visible) happily fit my micropositioners.

Unfortunately, the microscope is not in the best condition and not made with high quality components. However, there is a lot of mounting support and so I kept my eyes peeled on eBay for something I could replace it with. I was looking for something like a Nikon Optiphot since I knew a few people use that with good results. Eventually I found this:




the core of an Olympus BHMJ which seemed like a good match since you can mount it with a boom stand like on mine. It seems well cared for and in good condition. Before purchasing I did some measurements on my station and cross referenced some Olympus documents and was under the impression that the post was even the same diameter. Unfortunately, this turns out not to be the case, but I have access to lathes and so can make a new post without too trouble if I allocate some time for that. This is more of an industrial class microscope that I can buy numerous accessories and high quality optics for as I want to upgrade. I need to take a picture for comparison, but these are 25 mm compared to the standard ~20 mm thread RMS objectives most microscopes use.

You may have also noticed that the microscope didn't include an illuminator. However, I have one in the mail and should soon be able to do a test drive. The Nikon parts are not compatible, but the Nikon lamp setup was pretty bad anyway.

I also might want to switch out the stages for something more accurate. I use to play with lasers and so have a pile of optical quality micropositioners. On that note, you may have noticed the odd orange cord wrapped around the microscope. For some reason the camera port is loaded with a colminator with an FC fiber port + fiber. The exposed end of the fiber is in poor shape, but fiber is relatively inexpensive if I want another. I am not entirely sure what purpose it served though. I asked someone in the photonics business and he mentioned he'd used similar equipment for testing at his facility. I have some YAG lasers...maybe could be retrofitted for microsurgery?

I may look into getting a trinocular head to mount a camera. In the short term though I can put my camera in the eyepiece.

I also decapsulated a chip with some RFNA the other day with good results. For a sneak peak see https://picasaweb.google.com/JohnDMcMaster/First_rfna_decap?authuser=0&feat=directlink but otherwise I'll wait until I can try a second chip and do a more careful job (although the first chip did work, shown below "blinking" although all you can see is a solid on LED)


Edit: some more sneak peak https://picasaweb.google.com/JohnDMcMaster/Ic_live_analysis_08142011?authuser=0&feat=directlink

Sunday, July 10, 2011

A less simple experiment with JSSim

In short:

This post builds on a previous post where I described how to manually build a NMOS clock driven inverter in JSSim. It gave this (see it live):


I concluded by saying I was going to look into automating it and here's the first cut. I tried poking around for tools to automatically convert image files to JSSim files. They seem to either be not fully automated, don't exist, or are squirrelled away somewhere where I can't get to them.

The squireling possibility comes from that I would find it hard to believe that someone actually typed up all of the content in the *.js files. They are difficult to read as is (polygons are position dependent x/y coordinates in a long array) and it seems it would be error prone and tedious to generate that much data from the image files. That said, it did take them a large number of hours to complete the 6502 and it may not have been worth it.

Quietust wrote a toolchain more recently that you can find at here (my sandbox copy on Github). Since it only appeared recently it could not have been used to generate the 6502 meaning there is still a missing link even if there is an alternate route. I messed with it briefly and could not get it to parse my input SVG files. I've since learned more about SVG and probably will have a better idea of why it couldn't parse them (SVG is a huge specification, can specify a rectangle as a rectangle, polygon, patch ,etc), .

Finally, the first point that they are not fully automated comes from the fact that FPGA-netlist-tools. This toolchain is centered around producing synthesizable HDL from a variety of sources (images, JSSim). It has some good tools that pull in a lot of support from Magic VLSI, KLayout, Icarus Verilog, potrace, ImageMagick, gdspy, scipy/ndimage, and more. For example, I was impressed with how little code masks_to_netlists.py (136 lines including comments) used to create netlists from chip images. I was told that it may be possible to convert the output into JSSim files but haven't thoroughly explored it yet. It might not be too much work but I do need to learn more about various EDA CAD formats (CIF, GDS, spice, tech, etc) to figure out what I need to do.

Ultimately I decided I'd rather see how hard it is for me to do it with what I had available and then add support, rework, and integrate with the other tools as I learn more about them. I probably learned a lot more about for example, SVG format this way than I would have by blindly using the other tools/libraries.

For my test case I started by redrawing my image in Inkscape:


after deciding SVG would be easier than a raster image (ex: .tif) to parse. I tried a few conversion utilities with the following results:
  • Open .tif in Inkscape and save as .svg: .tif embedded in .svg, not useful
  • Convert using ImageMagick "convert" utility: created an element for every (non-white?) pixel. Impractical
Fortunately my chip isn't large enough where re-drawing is an issue. FPGA-netlist-tools seems to use potrace with good results for this type of conversion. I'd like to experiment with FPGA-netlist-tools and/or potrace directly in the future to see what I can leverage.

In order to convert an image into decent JSSim code you need to do the following:
  • Render polygons to screen in correct layer in correct net
  • Figure out net connections: which components are connected
  • Identify transistors
  • Identify pullup resistors
  • Identify net names for inputs (and potentially outputs too)
You should also do the following although they aren't critical:
  • Provide transistor geometry. Its used to find transistors which isn't used in main simulation
I wrote the tool in Python and somewhat arbitrarily chose "xml.parsers.expat" to parse the XML. I'm not sure if I could have leveraged anything by using a more integrated SVG parser. One thing I found I had to be careful with was how SVG / Inkscape liked to throw viewports around which led to nested coordinate corrections.

Rendering the polygons is fairly straightforward input to output conversion. After a small bit of research I decided to use Shapely's libgeos GIS library Python bindings for polygons. My simple SVG files were only rectangle, so I only had to parse rectangles. My core engine is built on polygons though and does work with them as demonstrated by the fact that I was able to merge rectangles into single polygons. However, since I drew the polygons as rectangles, I had to combine them. Otherwise you get results like this:



The alpha transparency on the metal doesn't overlay well and shows the underlying construction. I eliminated this by simply using a polygon union function on intersecting polygons on the same layer, replacing one of the polygons, and removing the other. You may also observe the image is upside down. SVG uses an upper left coordinate system and JSSim uses a lower left which means final conversion requires a horizontal flip.

Nets were decided by first assigning each node to a net. I then merged nets when one of the following happened:
  • A polygon intersected itself on the same layer
  • A via intersected diffusion, poly, or metal
Nets were then renumbered for the final output rather than trying to eliminate holes during the merge process.

I thought transistors were going to be difficult to identify but it turned out to be rather simple at least for this simple case. Transistors occur when two diffusion regions are separated by a poly gate (or metal gate for old school CMOS, but uncommon and not supported right now). I expanded each diffusion and poly polygon around its center of mass by a few pixels to find near neighbors and plotted the intersection (plotted using Tkinter):


I'm not sure how this method will scale but will see as I try it out on actual chips. In particular it will only accept the match if there are two intersections but I could easily imagine two gates being controlled by the same poly segment. I'll have to add some arbitration logic to sort out the connections if/when that becomes an issue. With two diffusion nets and a polygon net, we now have the two connections and the gate nodes respectively. I'm currently using the entire poly segment as a rough approximation of where the transistors is but maybe a better approach would be to try to protect between the two intersection polygons.

Pull-ups aren't that hard to identify once the transistors are identified. A pull-up requires the following:
  • One connection to positive voltage / VDD
  • Other two connections shorted together
Simply iterate over the transistors and mark the doubly connected net as a pull-up net.

Finally we have to identify the net names for input and output so that we can actually play with the chip. FPGA-netlist-tools specifies node names as a text file with the various coordinates and names specified in the file. However, I figured I could take advantage of SVG's being able to store text and place that information directly in the layers. From a conceptual standpoint I look for the intersection of the textbox polygon with a net and label that net which is similar to the point concept. This seems fair to do for the following reasons:
  • Most important signals are on the pads which typically don't have wires running under them in a non-flip chip padframe
  • Current chips don't have enough layers that they can't be unambiguously identified. In theory a very dense chip could have multiple metal layers that make resolving which layer we refer to ambiguous
  • Could potentially allow layer specific labels if there were collisions which would allow unambiguous identification. Alternatively could put some markup in the name such it gets identified. For example, instead of "clk0" put "metal2:clk0" to say that clk0 belongs to metal2 which would otherwise be ambiguous
Here's an example showing the text boxes (displayed using a rendering glitch in gthumb):


You have to careful though since text boxes can be much larger than the text. For example:


If this box was any bigger it would have hit diffusion and caused issues.

When the tool runs it looks for layer files in the current directory and spits out *.js. Running in JSSim (see it live):


We now have straight polygons! Mostly anyway. Zooming in:


In particular you'll notice this since it makes segdefs.js larger with the extra 2 points we added. If you look back at the non-merged metal it should be pretty obvious where this comes from. If I care to remove this I'll have to implement some sort of smoothing function to remove points close to each other.

My next step is to try to convert some of the chips in FPGA-netlist-tools into JSSim chips. I believe polygon intersection is somewhat computationally expensive and may have to implement a quadtree map for efficient large scale operation.

Until next time.

Epoxies

Plastic chips come in a variety of epoxies. Some sample chips:


Chip 1 was in acid for a short amount of time so its not a completely fair visual, but it looked about the same before going in. Anyway, In order of increasing glass content, these chips are 2, 3, 1. 3 is a PDIP-40 Microchip PIC, 2 is a TI chip, and I forget what 1 was although I'm tempted to say it was made by ST. Chip 1 decapsulates very qiuckly, 2 is what I'd call normal or a little better, and 2 is difficult. You can see what 1 looks like being in acid for a few minutes, here's what 2 looks like after sitting for a while (with 1):


It forms a hard sediment at the bottom of the beaker instead of really breaking up. There's so much epoxy that acid soaking in actually become noticeable instead of the chip breaking up like usually happens.

1's surface looks like this under a microscope (maybe 10X):

Notice all the junk in there. It makes dissolving it much easier since not only do we not have to dissolve that stuff, but it falls out, pitting the surface and making it corrode faster.

Here's the side of 2:


Interesting that the top and bottom look a little different, I'm not sure if its related to it being hard to dissolve as I haven't got a chance to compare it to similar chips.

And here's 3 (maybe 10X):

You can see some particulate in there (maybe not as apparent in this lower res picture?) and its lighter in color than the 2.

To finish off a few things not related to epoxies but came up during this. This thin package had the die close enough to the surface that it actually managed to poke through long before the package was dissolved:


Also when you do a large lot you get a pile of that junk leftover:


I use to use HNO3 to get rid of it, but it tends to dillute quickly and dilute HNO3 attacks aluminium. Fortunately its unlikely that you'll need to decap any valuable chip in volume so you can safely just pick these out with tweezers for most chips. I'm afraid of the chips scratching but the passivation is pretty strong.

Until next time.

Monday, July 4, 2011

Preparing for live analysis

I have a probing station on the way and am going to try to start learning about live analysis because it will allow me to confirm my understanding of chips. That is I'll predict the state, apply voltage, and then check the levels on the chip. Later on it will of course be useful for numerous applications (probe lines, change signals, etc).

My very first attempt was using 70 % HNO3 on a hot chip a while ago (maybe a year?). Rinse, repeat until exposed. Unfortunately, this method is very slow and takes about an hour of work for a PDIP. Even if you don't care so much about your time, so many handling cycles is dangerous for the chip (thermal stress, break bond wires, dissolve Al, etc).

My next attempt which I only partially went through with was an attempt to automate the above a little. I Dremeled a hole in the bottom of some glassware and filled a beaker with a small amount of nitric. It was then RTV'd onto the surface of a chip and the whole assembly heated. Early results were promising, but its somewhat dangerous if you run out of RTV before the chip is done. Additionally, you can't see the chip's surface so cannot gauge progress easily. I was also left with some residue on the chip. I'm not sure if it was from improper cleaning or more than usually since it was all pooling into the acid cavity.

I didn't go back to this for a while mainly because without a probing station it wasn't a good use of time when I could just throw the chip in an acid bath with much less work. I've recently been moving onto more complicated scenarios and now consider live analysis to be a key objective for the reasons stated at the beginning. However, I value my time and don't want to spend a lot of time putting drops on a sample or dealing with RFNA for assorted reasons. Professional shops use decapsulation machines that squirt acid jets. Could I do something similar?

I started to think and I decided the first thing I should try is to see if I could build an automatic decapsultion with equipment I had. I had a rusted out peristaltic pump which seemed like an okay place to started. I gave up on the motor and rigged up a flexible shaft to it. See it in operation here.

This fed an H2SO4 from the bottom of a beaker which was to squirt a chip on a raised platform in the same beaker. I knew someone that said UL would approve anything, but probably not this. The machine was flat out hazardous for the following reasons:
-Exposed spinning shaft
-Pressurized heated acid on surplus / scavenged parts
-If the acid flow was uneven it could stress the glass and break it

It also suffered from some practical problems:
-I could not get the acid hot enough. I guess a combination that the glass insulated the chip too much and the acid cooled too much (although it was still pretty hot) before it reached the chip
-My platform was just an inverted beaker (inside a larger beaker) and the chip could easily get knocked off

I'm not a man easily defeated though. I spent some time to think about what I could do better. I got some PTFE beakers which I drilled out to make PTFE baskets so that I could take chips out of acid baths easier. Probably a short post on that at some point. It got me thinking: although I couldn't machine / shape glass very easily, I could easily machine PTFE. My goal was to make an assembly that would shield the chip from the acid except for a milled out impression where I wanted it to etch. I ordered some stock, ordered some PTFE bolts, and already had a PTFE sheet.


Before chips can actually be used, its a good idea to mill out a cavity (I used 3/16" (0.1875") TiN coated endmill for 0.3" pitch) so that the die will be reached much faster. Make it less wide than your chip so that you don't collapse the lead frame from excessive etching on the sides. Professional shops x-ray the chips, but you have a few options:
  • Rule of thumb: mill halfway to the top of the leads
  • Sacrifice one to find where the bond wires are. Might be worth it if you have a pile of them, although it still will probably only be an approximation
  • Don't mill it at all if its very thin. Certainly shouldn't be your first sample though as you'll have more issues with the lead frame collapsing
  • Some professional units short all of the pins and wait for continuity to the bond wires. I tried putting some water in the cavity to help detect when they were getting close, but could not do it reliably
In any case, inspect after milling. Try adding water to make bond wires more apparent.

When I was experimenting with the continuity method I got sloppy and didn't pay attention to depth. The endmill hit the Si. While not dangerous to the user, it did ruin the tip by dulling it and taking off the TiN coating (as a reference, silicon is 7.0 Mohs hardness but even titanium is only 6.5) Afterwords packages would heat up instead of being cool to the touch. I'm also told that excessive heat can burn the epoxy and make it difficult to dissolve although I haven't seen this yet. Healthy endmill that went too far:


Dull endmill that went too far:


You can see the wires are more smeared around than cut. For example, in the first image you can make out the bond wire arc cross section but they are more scattered around in the second. Both will still feel pretty sharp to the touch so I'd reccomend you start with a new endmill or be very careful. Another problem with using a dull endmill is that it requires more pressure to start a cut. You need to take off very thin slices and a dull endmill will tend to "bite" and then take a larger slice out. I had good luck using a sharp endmill in a breadboard. The breadboard / pin contact provided a small spring factor which allowed very slow, precise cuts. Additionally, I was able to place it back into position after inspecting depth.

I assembled my piece and lowered it into a beaker after milling a small cavity into the top of a PDIP. To avoid letting the epoxy slag accumulate in the cavity, I put it into the beaker upside-down. This aspect seemed to work rather well. Unfortunately, a few things didn't. First, I misunderestimated PTFE's thermal expansion coefficient. The block expanded a fair amount and wedged itself up against the glass. I feel lucky that it didn't break. Second, related to the first point, PTFE becomes soft at higher temperatures. This had two effects: making the gasket droop down, breaking the seal, and shearing the bolts from the added stress and being softer. Another thing that I did was to tack the chip in place with RTV. Initially I used just a small amount, but I tried to fill it in after seeing the gasket wasn't going to hold the chip in place. I then went so far as the flip the assembly over, but this caused the predicted slag problem. Although there was a clear separation between the epoxy that was still part of the package and that which wasn't, it couldn't be removed without destroying the fragile bond wires. Finally, the larger volume of RTV was significant since it got attacked more readily than the epoxy.

Although it didn't work out, it was a step in the right direction. The PTFE bolts were kinda expensive though so i was a little bummed about that. What if I just made a sold piece? I could prevent circulation at the top by not filling the bath above the top of the assembly. Acid would then stay stagnant in the middle and most likely cooler. And here it is:


After adding some handles to take it out of the acid easier:


The idea worked quite well. I was able to see though that the stirbar:


wasn't knocking the bubbles out like I thought it would. I solved this in two ways. First, I filled the cavity up more carefully from the side to let the acid flow in from the side rather than letting air bubbles get trapped if the acid was just poured in. Second, I drilled two holes on the side to let air escape. While it does increase package corrosion, it didn't see to signfigantly since the acid was mostly hitting the milled out portion.

The first chip gave very good results:


Die before any cleaning:


After pressurized water (although acetone would be preferred if I was serious about keeping it alive, water is hazardous to circuits. 98% H2SO4 is hygroscopic and should not contaminate the chip):


Ultrasound would probably clean it up nicely. Beware though if the connections are weak you may knock them off. Try shielding the ultrasound / user lower power or soaking first and see if it will take it off before running at full force. On a related note, be absolutely sure that you've cleaned the chip thoroughly to eliminate acid. Use acetone, 98 % rubbing alcohol, other other things that won't add water. Put it on gentle heat after to drive out any leftover moisture and store in a sealed container away from moisture and dust. Dissicant is probably a good idea. I had a chip I just flat didn't wash after doing this to, need to take a picture of it.

I need to also test to see how much this special jig helps vs just milling and dumping in the bath. Since the acid doesn't corrode the pins very fast, it may very well be sufficient to just dump it into the bath as is.

I'd like to eliminate the RTV completely by making some PTFE spacers. They'll go on the side of the chip so that it gets held in place better and allows less acid to flow to the top.

An associate has started to experiment with making microprobes which turns out to not be that hard. I think he told me its something along the lines of put tungsten rod in 20 % w/v KOH and run some current through it with a certain polarity. I was told the other parameters but just can't remember them off of the top of my head. Hopefully he'll do a writeup on at some point or I will once I have a need to start making probes. I recently received a probing station and so this might be in the near future.

To summarize, here are the key points
  • Your first chip should be easy to handle. Try a PDIP as they are heavy duty and have lots of room for error. Whatever you chose, you'll probably want to mill it and will want a way to securely hold it
  • Start by milling out a cavity. Use something narrower than your package to avoid collapsing the lead frame. Halfway from the top to the top of the lead frame is a good rule of thumb
  • Mount the chip upside down in a acid proof jig. I used PTFE, glass would also work fine.
  • I used a stir bar to increase circulation although I have yet to prove it actually helps
  • Make sure you can take the chip out of the bath to check on it. You can't under-etch and over-etching endangers the integrity of the chip. Be aware though that thermal shock can kill the chip
  • Avoid using water when rinsing. Use hygroscopic and / or water free solvents. Use ultrasound carefully as it may knock off bond wires.
  • Gently heat dry it when done to be sure you've driven out moisture
  • Store in a dry location. I use centrifuge tubes. Desiccant is probably a good idea although probably not needed

Sunday, July 3, 2011

A simple experiment with JSSim (visual6502)

The folks at visual6502.org have really done a great job on their project and I've been meaning to get more familiar with their work for a while. Now that I graduated I have more time for these projects and was able to dig in over the past week and especially yesterday. Bottom line: my experiment can be found at http://johndmcmaster.github.com/visual6502/ and a demo at http://johndmcmaster.github.com/visual6502/tutorial-inverter.html This writeup is based on my git commit 6a613ee1131bbdec9a8bf4b6eeb02d13147842ab which was forked from mainline's de265ecdb89d8c5d299f09ad69aaf8b87b1aed5d. Changes are as noted, but most code snippets are copyright Brian Silverman, Barry Silverman, Ed Spittles, Achim Breidenbach, Ijor and maybe some others that I missed. See the github source for details.

I don't have much experience with JavaScript but I have enough experience with C like languages that it isn't really hard to use and just try to follow the syntax of things around me. I started by moving the 6502 into its own folder like later chips have been tending to so that I could focus on the relevant files easier. For those not familar with visual6502, here's a screenshot of the 6502 running in JSSim (Java Script Simulator):


Although its not obvious from the still picture, metal, poly, and diffusion are being colored according to their voltage potential. Wow! An outstanding way to learn about chips. However, the complexity of the simulator scared me from really trying to understand how it worked. Fortunately, most of the work is put into the data and the simulator core is easy to follow. In this post I'm going to step you through how visual6502 works and how to create a clocked inverter circuit using simple tools.

The first thing that you'll need is a reference diagram. I somewhat arbitrarily decided to try an NMOS inverter since I knew the 6502 was NMOS logic and could look at an example if I got stuck. An inverter just seemed like something I could easily clock with a single input. Lets start with a brief review of NMOS logic since these days its all about CMOS. In NMOS logic, we use a single transistor polarity and short out voltage through transistors to invert outputs. Here is an NMOS inverter from Wiki:
When A is 0 the switch is open and current can flow from VDD through R to OUT (A: 0, OUT: 1). If we put voltage on A (gate) the switch is closed and shorts out OUT (A: 1, OUT: 0) through the drain at top and source at bottom. NMOS was discontinued because CMOS didn't have the issue of needing to short out a resistor (power consumption when input is 1), eventually became faster (better noise margin), and also took up less chip space.

Converting this into a (simplified) layout:
I used gray for metal, black for contacts, red for poly, green for N diffusion, and white for P substrate. The blue lettering is an arbitrarily assigned net (electrically connected group) number which we'll use later as we convert this into a simulatable data file. I might use the term node and net interchangeably, they mean the same thing here. As a reminder, the distinction between source and drain is less important at a fundamental level. For our purposes we only care that the ends of the green blocks are the switch contacts and that the switch is controlled by the red part (polysilicon aka poly). Finally, assuming self aligned gates, the poly protects the silicon under the gate and so we only have diffusion around the poly and not under it. Early CMOS used metal gates but later switched to poly (not regular Si because you can't grow good crystals on an amorphous SiO2 glass surface).

Notice that we really try to avoid conventional resistors. While they can be made from strips of poly or diffusion, the easiest way is to make them out of transistors. I am not deeply familiar with this and initially had the drain and gate connected instead of the gate and source as above. So if you see images with them reversed its because I was too lazy to re-take screenshots after I fixed it. On my TODO list so that I can better recognize and understand them. The transistor below is more interesting and we'll mostly focus on it.

Pretty picture, but its also pretty lifeless. Time to start digging into the codebase. If you grab a copy of the visual6502 source code (either from my repo listed above or from the main repository at https://github.com/trebonian/visual6502) you should see chip-6800 subdirectory which defines the files you'll need to create for your own simulation:
  • nodenames.js: defines human friendly node names such as clk0
  • segdefs.js: defines how to draw the non-transistor parts and their connections
  • transdefs.js:transistor to net connections and transistor drawing
  • support.js: utilities and overrides to stub out unneeded functions
  • testprogram.js: CPU instructions. Since we won't have a CPU we don't need this file

nodenames.js contains the nodenames variable and looks something like:
var nodenames ={
gnd: 2,
vcc: 1,
clk0: 3,
}
vcc is net 1, gnd is net 2, and clk0 has been aliased to net 3.

segdefs.js contains the segdefs variable and looks something like:
var segdefs = [
[ 4,'-',5, 177,94, 193,95, 193,179, 178,180],
[ 1,'+',4, 128,214, 177,214, 177,265, 129,264],
[ 2,'-',3, 128,95, 179,94, 177,146, 128,146],
[ 4,'-',0, 66,163, 192,161, 193,179, 64,179],
]
Which probably looks pretty cryptic at first glance. The first element is the node number. The second is the pullup status: '+' for pullup and '-' (although I think any non-'+' value will work) for regular. That is a '+' indicates a resistor is connected to the positive supply and will turn on attached gates if not shorted out. Each pair thereafter forms part of the polygon used to draw the chip. All of the above are rough rectangles.

The next number is the layer number. This does not effect the simulation to my knowledge but we do want the visual aspect to work correctly. If you look in expertWires.js you should see:
var layernames = ['metal', 'switched diffusion', 'inputdiode', 'grounded diffusion', 'powered diffusion', 'polysilicon'];
var colors = ['rgba(128,128,192,0.4)','#FFFF00','#FF00FF','#4DFF4D',
'#FF4D4D','#801AC0','rgba(128,0,255,0.75)'];
var drawlayers = [true, true, true, true, true, true];
Which defines the layer numbers (0 indexed). Thus the sample data above defines the layers poly, powered diffusion, grounded diffusion, and metal. Switched diffusion is diffusion that will change state during simulation because its on a switched side of a transistor. In the sample image the two diffusion segments on the right are switched since they may or may not have a voltage potential on them depending on whether the transistor is on. The upper left diffusion is powered since it always has positive voltage and the lower left is grounded diffusion since its always at ground potential. Hopefully poly and metal are self explanatory.

We render in the order given, so make sure to place them in a good order. Make metal last as its semi-transparent and anything else will just cover it up. None of the other polygons (except transistors, but they aren't usually rendered) should overlap but if they do just arrange things as needed.

The final key file is transdefs.js which contains the transdefs variable:
var transdefs = [
['t1',4,2,3,[176,193,96,144],[415,415,11,5,4566],false],
['t2',1,1,3,[177,191,214,265],[415,415,11,5,4566],true],
]
The first element is the node name which is followed by the gate, first, and second net connections respectively. Like in the layout we don't distinguish between the gate and drain.

Now that we know what data we need we need to generate it. While I could learn to use or develop my own tools for converting layers to *.js files, I decided to go with the KISS strategy. I used the Kolourpaint toolchain to generate my *.js files:


I generated the points by hovering the mouse over the various coordinates and typing them into the *.js files. With both windows open at once it went pretty quick. If you're wondering why its upside-down, its because the simulator has the origin in the lower left hand corner and kolourpaint has it in the upper left hand corner. By flipping upside-down the coordinates come out correctly.

But its not over yet. I've glazed over utils.js but its actually necessary for this to work. The stock functions are more specialized for a full blown MCU, a 6502 in particular, and we will have to override these functions as appropriate. Finally, we need to set the canvase size by setting grChipSize which sets width and height. My images were 400 X 400 so I set grChipSize to 400. Lets step through initialization so that we know what we need to fixup.

We start in the main .html file by including a bunch of stuff. In particular you'll need to change the paths to reflect your files instead of the template's. For example, I used chip-6800 so had do substitute things like:
<s cript src="chip-6800/segdefs.js"></script>
for
<s cript src="chip-tutorial/inverter/segdefs.js"></script>
or whereever you put your files. Trusting the general structure and skipping over the HTML layout, the key item is
function handleOnload() {
...
setTimeout(setup,200);
...
}
Which launches setup() in expertWires.js after 200 milliseconds. The other key item in the main file is the play button:
<a href ="javascript:runChip()" id="start"><img class="navplay" src="images/play.png" title="run"></a>
which calls runChip(), but we won't worry about this for now.

This function is mostly just a bootstrap for the next stage. They do a lot of this and I'm not sure why they don't just make function calls.
EDIT: I've been told this is related to not letting scripts run too long and make the browser complain. By re-submitting the request the browser doesn't get so angry. They aren't sure if this is standard for web services but it seems to work.
Anyway, here it is:
function setup(){
statbox = document.getElementById('status');
setStatus('loading ...');
setTimeout(setup_part2, 0);
}
And this gives:
function setup_part2(){
frame = document.getElementById('frame');
statbox = document.getElementById('status');
setupNodes();
setupTransistors();
setupParams();
setupExpertMode();
detectOldBrowser();
setStatus('loading graphics...');
setTimeout(setup_part3, 0);
}
setupNodes() works on segdefs to setup the visual portion. For historical reasons (in a comment I read somewhere) it also contains the pullup status as noted earlier.

setupTransistors() does the actual transistor and net setup. One point of interest is that C1 will become "interesting" if C2 is but C1 isn't (ie GND and VCC will be moved to C2 if they weren't in transdefs.js). We also build a list of all of the transistors connected to each net. That way when we simulate an event we only have to reference the net instead of iterating through all of the other transistors looking for relevant gates by exchanging memory for CPU usage.

setupParams() parses query parameters (page.html?key=value) and so isn't important for basic usage. setupExpertMode() sets up the probe control panel and you don't really need to worry about it. Finally, detectOldBrowser() is compatibility related (makes rendering faster on certain systems?) and you also don't need to worry about it.

We now move onto setup_part3():
function setup_part3(){
if(chipLayoutIsVisible){
updateChipLayoutVisibility(true);
}
setStatus('resetting ' + chipname + '...');
setTimeout(setup_part4, 0);
}
The chip layout should be visible and so we start to render the layout and move onto part 4:
function setup_part4(){
setupTable();
setupNodeNameList();
logThese=signalSet(loglevel);
loadProgram();
setupConsole();
if(noSimulation){
stopChip();
running=undefined;
setStatus('Ready!');
} else {
initChip();
document.getElementById('stop').style.visibility = 'hidden';
go();
}
}
Glaze over things and go to initChip() which is important since you'll need to define it. initChip() is responsible for setting the startup logic state. Unfortunately the default implemetnation in macros.js has statements like setHigh('rdy') which are 6502 specific. I cut that stuff out to give a very basic chip initialization instead. See my support.js, but basically it sets all transistors to off and then recalculates all transistors (recalcNodeList(allNodes())).

recalcNodeList() is a core interface. Its a discrete event simulator where we propagate switch information when things change. Since there's no guarantee it will settle, it will abort after 100 iterations if we did something dumb like create a ring oscillator by accident.

setup_part4 finished by calling go(). This will start looping the simulation. Usually this is by hitting the play button in main, but I hard coded the running variable to true so that I didn't have to hit the button. Also worth noting that I added a step delay variable (go_timeout). It may make sense for larger chips to run at full throttle, but for this simple simulation I limited at 1 Hz. step() will look for the net clk0 and invert its state. It also does a few other things so I added the following stubs:
/*
Simple logic chip stubs
*/
/*
Print registers and such, we have none
Could use the input and output pins I guess if we really wanted to
Used extensivly in macros.js
*/
function chipStatus(){}
//Simple logic chips have no bus to read/write, skip over
//Executed as part of clocking (halfStep()) in macros.js
//Alternativly we could have just re-implemented these functions
function handleBusRead() {}
function handleBusWrite() {}
//Stub implementation in case not using memtable.js
//No memory to track
function setupTable() {}
Whew! We should be ready to run. Check my data files for how I defined the*.js files. Allright, lets see what we get:




?!? Upon a little investigation, we see that there is a 400 pixel gutter. Since our image is 400 pixels, if we set grChipSize to 1200, we will see it centered at the bottom:


But really we want it to look nicer and so take of the 400 pixel left gutter:


Alternativly we could have made the transistors big enough so that the gutter doesn't matter. I added the variable main_area_left_gutter and set it to 0. I'm not clear why they added a gutter to the left but not bottom. In any case, lets see some clocking action! (The above image was taken before I added the clock) Clock on:


Clock off:


And it works! As you can see, the powered and grounded diffusion stay the same and the active diffusion area changes along with the metal. Not too much work overall even if you don't much about web technology.

Thanks to the visual6502 folks for providing such great software and making my inverter be more correct instead of "just work"! My next steps will be to start cross referencing the *.js against the die images and also to generate *.js automatically from layer images. On a final note, I've also learned a relatively simple technique for preparing ICs for live analysis that I'll hopefully make a post in the near future about.

Wednesday, March 2, 2011

Studying the CD4001

Somewhat arbitrarily I decided a CD4001 would be a good chip to really study to get a better feel for how a chip was put together. While I can recognize bits and pieces of larger chips, I still lack the fundamental understanding of how to recognize raw transistor arrangements. Although such basic logic chips have heavy optimizations which can be somewhat undesirable as a study tool, I'm hoping their simplicity makes up for it.

The original chip I was going to look at was a Fairchild CD4011:


I decapsulated it and found it had nice coloring:


Hopefully "POS" doesn't refer to their confidence in their design. This was only intended to be a preliminary quick photo before cleaning, but my metal tweezers slipped and sent it flying to who knows where. I now have plastic tweezers which tend to chip the dies less and less susceptible to slipping. Anyway, take a look at what I think is a National Semiconductor 4001 (was in a tank of 4001's):


In a similar area:


Maybe its just the "natural" arrangement for this sort of configuration? I'll figure out more as I etch out the transistors. Its interesting though that ones a CD4001 and the other is a CD4011.

Another item is interest is that older Texas Instruments datasheets had top metal included. Compare a datasheet with one of my snaps:


...and the (rough) stitch:


One interesting thing with the TI parts is that you can identify pin 1 with a bullet shaped pad. Other vendors have similar things and it seems the shapes tend to be unique per vendor. For example, it seems Motorola may use an octagon like pattern (all taken from what appear to be different revisions of the same 4001):




The first two are nearly identical. The last one has a full octagon where as the first two had a square corner.

I have some etching chemicals coming that will hopefully come by this weekend and I can use to expose some transistors. I have a roll of 100 Phillips 4011's (about $6 from Jameco):


which I'll practice on and then expose other chips that I have more limited capacities after I have some results. Since these chips are so simple, I can actually make guess as to what a lot of things do, but I would like the transistors as well to complete the picture. If successfull, I'd like to write up a tutorial that takes someone through decoding the chip.

On a random note, I get a lot of my chips by scrapping old electronics. I heat gun the board (wearing my 3M industrial respirator so as to not get too many fumes) and collect chips into a tray. Usually there are only a few I really care about, such as the main CPU or some FPGAs. There are lots of leftover small chips. Its not cost effective for me to use them in anything I design for a number of reasons. So, what to do with them? How about throw them in a beaker and decap in mass:


The larger chip is an i960 that I savagely ripped out of a computer that was being junked. As such, it got cracked in two spots. Setting up for mass photography:


They are on a microscope slide with sticky tape. I estimate I spent only about 1 min on each chip. Granted, this has limited usefulness, but it does show a number of interesting designs and I was never going to use the chips otherwise. For the curious, I uploaded a bunch of them to http://intruded.net:8080/uv/UVSG/