One easy library to add to the collection is OSU's FreePDK45, found at https://vlsiarch.ecen.okstate.edu/flows/ (direct download link : https://vlsiarch.ecen.okstate.edu/flows/FreePDK_SRC/OSU_FreePDK.tar.gz : only 1.7MB, mirroredhere)
It's a good candidate because it's a really surprisingly tiny library : 33 cells only !
FILL (no logic input or output)
BUFX2 BUFX4 CLKBUF1 CLKBUF2 CLKBUF3 INVX1 INVX2 INVX4 INVX8 TBUFX1 TBUFX2 (1 input, 1 output)
AND2X1 AND2X2 HAX1 NAND2X1 OR2X1 OR2X2 NOR2X1 XNOR2X1 XOR2X1 (2 inputs)
AOI21X1 FAX1 MUX2X1 NAND3X1 NOR3X1 OAI21X1 (3 inputs)
DFFNEGX1 DFFPOSX1 DFFSR LATCH (non-boolean)
This is close to the minimum described at http://www.vlsitechnology.org/html/cell_choice2.html but should be enough for basic circuits. In fact we have the 1st order and most of the 2nd order gates, which I covered in log 31. v2.9 : introducing 4-input gates. OAI211 and AOI211 are missing, which are very useful for incrementers and adders...
The site also provides these same basic standard cells for AMI 0.6um, AMI 0.35um, TSMC 0.25um, and TSMC 0.18um released in 2005 at https://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/iit_stdcells_v2.3beta/iitcells_lib_2.3.tar.gz. A single bundle packages 4 technologies ! The library seems to have evolved to reach v2.7 and included a LEON example project: https://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/osu_soc_v2.7/ (but the latest archive looks broken)
I love how minimal, compact and simple these gates are, accessible to beginners and targeting from 45nm to .5µm. It looks like a "RISC" approach to VLSI ;-) Note also that there are only 2 gates with two output drives and 2 inputs : AND and OR, which are 2nd order gates, merging a NAND/NOR with a X1 or X2 inverter. The rest of the fanout issues are solved by inserting INVX gates at critical fanout points. This means that physical mapping/synthesis should start by examining the fanouts, inserting the inverters/buffers and then deducing which logic function to bubble-push.
I'm not sure how to create the files but I can easily derive them from the A3P files in 3 ways:
- Modify the file generator
- Modify the generated files
- Create a "wrapper" file
Furthermore the sequential gates are not yet clear about the precedence of the inputs.
Extracting the logical functions was as simple as a grep and some sed :
grep -r '>Y=' * |sed 's/.*data//'|sed 's/<tr.*FFF//'|sed 's/<.*//'|sed 's/[.]html.*Y/: Y/' CLKBUF2: Y=A AND2X2: Y=(A&B) NAND3X1: Y=!(A&B&C) NOR3X1: Y=!(A|B|C) XOR2X1: Y=(A^B) BUFX4: Y=A MUX2X1: Y=!(S?(A:B)) OR2X1: Y=(A|B) AND2X1: Y=(A&B) TBUFX2: Y=(EN?!A:'BZ) /INVX8: Y=!A /CLKBUF3: Y=A INVX1: Y=!A AOI21X1: Y=!((A&B)|C) XNOR2X1: Y=!(A^B) BUFX2: Y=A OAI22X1: Y=!((C|D)&(A|B)) TBUFX1: Y=(EN?!A:'BZ) OR2X2: Y=(A|B) OAI21X1: Y=!((A|B)&C) NAND2X1: Y=!(A&B) AOI22X1: Y=!((C&D)|(A&B)) CLKBUF1: Y=A NOR2X1: Y=!(A|B) INVX4: Y=!A INVX2: Y=!A
For the VHDL version, only a few more simple substitutions are required:
$ grep -r '>Y=' * |sed 's/.*data[/]/"/'|sed 's/<tr.*FFF//'|sed 's/<.*//'|sed 's/[.]html.*Y=/": /' |sed 's/[!]/not /g' |sed 's/[|]/ or /g' |sed 's/[&]/ and /g' |sed 's/\^/ xor /g' |sort "AND2X1": (A and B) "AND2X2": (A and B) "AOI21X1": not ((A and B) or C) "AOI22X1": not ((C and D) or (A and B)) "BUFX2": A "BUFX4": A "CLKBUF1": A "CLKBUF2": A "CLKBUF3": A "INVX1": not A "INVX2": not A "INVX4": not A "INVX8": not A "MUX2X1": not (S?(A:B)) "NAND2X1": not (A and B) "NAND3X1": not (A and B and C) "NOR2X1": not (A or B) "NOR3X1": not (A or B or C) "OAI21X1": not ((A or B) and C) "OAI22X1": not ((C or D) and (A or B)) "OR2X1": (A or B) "OR2X2": (A or B) "TBUFX1": (EN?not A:'BZ) "TBUFX2": (EN?not A:'BZ) "XNOR2X1": not (A xor B) "XOR2X1": (A xor B)
Notice that MUX2 should be called MUXI and A and B are swapped relative to the A3P lib. Some other corner cases are easily translated by hand as well. The TBUFs however fall outside of the purely boolean realm...
Some gates have 2 outputs :
HAX1: YC=A and B YS=A xor B FAX1: YC=(A and B) or (B and C) or (C and A) YS=A xor B xor C
These are obviously gates that can be split into known functions (such as MAJ in other libraries) but they certainly offer a space advantage when some inputs are merged. Macros would easily be created for these two gates.
The non-boolean gates need some more analysis.
- LATCH has no extra input, it's just a transparent latch with no reset or preset. It is practically equivalent to MUX2X1 with an extra loopback inverter. Next.
- DFFPOSX1 and DFFNEGX1 are simple simple DFF with no extra input, and you can choose the clock polarity.
- DFFSR is another beast, defined by this code:
FLIPFLOP{ DATA=D CLOCK=CLK PRESET=!S CLEAR=!R Q=P0002 QN=P0003 } Q=P0002
This seems to map to an internal representation of a full flip-flop with Data, Reset and Preset inputs but with no information about the precedence of the signals.
And that's all for this simple but nice PDK. No RAM, no data enable on DFF, no anything, just the minimal set of gates you need to make most common digital circuits.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.