-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flipped VOltage Follower Pcell, Analog vibes, Chipathon 2024 #352
Open
Subhampal9
wants to merge
25
commits into
idea-fasoc:main
Choose a base branch
from
Subhampal9:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
309241d
added FVF Pcell files, Analog Vibes, Chipathon 2024
Subhampal9 29af8ab
Updated README.md
Subhampal9 51bb493
Updated comments
Subhampal9 1ac1802
Merge pull request #1 from Subhampal9/Subhampal9-FVF
Subhampal9 aa3eb80
removed code duplication
Subhampal9 85facbc
updated for proper routing to pass all drc
Subhampal9 dfe0499
removed unnecessary lines
Subhampal9 507e10c
adding more flexibility for without tie option
Subhampal9 3b59e93
updated comments
Subhampal9 90826ea
Create README.md
Subhampal9 57f525d
Delete openfasoc/generators/glayout/glayout/flow/blocks/composite/FVF…
Subhampal9 cfc5dbf
Create README.md
Subhampal9 e29620a
Files for FVF based OTA
Subhampal9 8ab4b25
Create transmission_gate.py
Subhampal9 e343b98
Update transmission_gate.py
Subhampal9 52f296c
low voltage current mirror
Subhampal9 84d011d
Update low_voltage_cmirror.py
Subhampal9 8697e20
Update n_block.py
Subhampal9 2308eed
Update p_block.py
Subhampal9 8cac9f5
Update n_block.py
Subhampal9 e77f287
Update ota.py
Subhampal9 a7f4211
Update sky130_ota_tapeout.py
Subhampal9 edab537
Update README.md
Subhampal9 66fbee6
Updated comments
Subhampal9 b5072a0
Update README.md
Subhampal9 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
|
||
Circuit 1 cell sky130_fd_pr__nfet_01v8 and Circuit 2 cell sky130_fd_pr__nfet_01v8 are black boxes. | ||
Warning: Equate pins: cell sky130_fd_pr__nfet_01v8 is a placeholder, treated as a black box. | ||
Warning: Equate pins: cell sky130_fd_pr__nfet_01v8 is a placeholder, treated as a black box. | ||
|
||
Subcircuit pins: | ||
Circuit 1: sky130_fd_pr__nfet_01v8 |Circuit 2: sky130_fd_pr__nfet_01v8 | ||
-------------------------------------------|------------------------------------------- | ||
1 |1 | ||
2 |2 | ||
3 |3 | ||
4 |4 | ||
--------------------------------------------------------------------------------------- | ||
Cell pin lists are equivalent. | ||
Device classes sky130_fd_pr__nfet_01v8 and sky130_fd_pr__nfet_01v8 are equivalent. | ||
Flattening unmatched subcell NMOS in circuit fvf (1)(2 instances) | ||
|
||
Class fvf (0): Merged 3 parallel devices. | ||
Class fvf (1): Merged 3 parallel devices. | ||
Subcircuit summary: | ||
Circuit 1: fvf |Circuit 2: fvf | ||
-------------------------------------------|------------------------------------------- | ||
sky130_fd_pr__nfet_01v8 (6->3) |sky130_fd_pr__nfet_01v8 (6->3) | ||
Number of devices: 3 |Number of devices: 3 | ||
Number of nets: 4 |Number of nets: 4 | ||
--------------------------------------------------------------------------------------- | ||
Netlists match uniquely. | ||
|
||
Subcircuit pins: | ||
Circuit 1: fvf |Circuit 2: fvf | ||
-------------------------------------------|------------------------------------------- | ||
VIN |VIN | ||
Ib |Ib | ||
VOUT |VOUT | ||
VBULK |VBULK | ||
--------------------------------------------------------------------------------------- | ||
Cell pin lists are equivalent. | ||
Device classes fvf and fvf are equivalent. | ||
|
||
Final result: Circuits match uniquely. | ||
. |
37 changes: 37 additions & 0 deletions
37
openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
## FLIPPED VOLTAGE FOLLOWER CELL | ||
|
||
``` | ||
def flipped_voltage_follower( | ||
pdk: MappedPDK, | ||
device_type: str = "nmos", | ||
placement: str = "horizontal", | ||
width: tuple[float,float] = (3,3), | ||
length: tuple[float,float] = (None,None), | ||
fingers: tuple[int,int] = (1,1), | ||
multipliers: tuple[int,int] = (1,1), | ||
dummy_1: tuple[bool,bool] = (True,True), | ||
dummy_2: tuple[bool,bool] = (True,True), | ||
tie_layers1: tuple[str,str] = ("met2","met1"), | ||
tie_layers2: tuple[str,str] = ("met2","met1"), | ||
sd_rmult: int=1, | ||
**kwargs | ||
) -> Component: | ||
""" | ||
creates a Flipped Voltage Follower | ||
pdk: pdk to use | ||
device_type: either "nmos" or "pmos" | ||
placement: either "horizontal" or "vertical" | ||
width: (input fet, feedback fet) | ||
length: (input fet, feedback fet) | ||
fingers: (input fet, feedback fet) | ||
multipliers: (input fet, feedback fet) | ||
dummy_1: dummy for input fet | ||
dummy_2: dummy for feedback fet | ||
tie_layers1: tie layers for input fet | ||
tie_layers2: tie layers for feedback fet | ||
sd_rmult: sd_rmult for both fets | ||
**kwargs: any kwarg that is supported by nmos and pmos | ||
``` | ||
### GDS generated | ||
![gds generated](./fvfgds.png) | ||
|
31 changes: 31 additions & 0 deletions
31
openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using default pdk_root: /usr/bin/miniconda3/share/pdk/ | ||
Defaulting to stale magic_commands.tcl | ||
|
||
Magic 8.3 revision 464 - Compiled on Sat Mar 9 23:18:29 UTC 2024. | ||
Starting magic under Tcl interpreter | ||
Using the terminal as the console. | ||
Using NULL graphics device. | ||
Processing system .magicrc file | ||
Sourcing design .magicrc for technology sky130A ... | ||
2 Magic internal units = 1 Lambda | ||
Input style sky130(): scaleFactor=2, multiplier=2 | ||
The following types are not handled by extraction and will be treated as non-electrical types: | ||
ubm | ||
Scaled tech values by 2 / 1 to match internal grid scaling | ||
Loading sky130A Device Generator Menu ... | ||
Loading "/tmp/tmp0t0g30yo/magic_commands.tcl" from command line. | ||
Warning: Calma reading is not undoable! I hope that's OK. | ||
Library written using GDS-II Release 6.0 | ||
Library name: library | ||
Reading "fvf". | ||
[INFO]: Loading fvf | ||
|
||
Loading DRC CIF style. | ||
No errors found. | ||
[INFO]: DONE with /tmp/tmp0t0g30yo/fvf.rpt | ||
|
||
Using technology "sky130A", version 1.0.471-0-g97d0844 | ||
|
||
Soft errors: | ||
Error while reading cell "fvf" (byte position 118): Unknown layer/datatype in boundary, layer=64 type=44 | ||
|
164 changes: 164 additions & 0 deletions
164
openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
from glayout.flow.pdk.mappedpdk import MappedPDK | ||
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk | ||
from gdsfactory.cell import cell | ||
from gdsfactory.component import Component | ||
from gdsfactory import Component | ||
from glayout.flow.primitives.fet import nmos, pmos, multiplier | ||
from glayout.flow.pdk.util.comp_utils import evaluate_bbox, prec_center, prec_ref_center, align_comp_to_port | ||
from glayout.flow.pdk.util.snap_to_grid import component_snap_to_grid | ||
from glayout.flow.pdk.util.port_utils import rename_ports_by_orientation | ||
from glayout.flow.routing.straight_route import straight_route | ||
from glayout.flow.routing.c_route import c_route | ||
from glayout.flow.routing.L_route import L_route | ||
from glayout.flow.primitives.guardring import tapring | ||
from glayout.flow.pdk.util.port_utils import add_ports_perimeter | ||
from glayout.flow.spice.netlist import Netlist | ||
from glayout.flow.primitives.via_gen import via_stack | ||
from gdsfactory.components import text_freetype, rectangle | ||
|
||
def fvf_netlist(fet_1: Component, fet_2: Component) -> Netlist: | ||
|
||
netlist = Netlist(circuit_name='FLIPPED_VOLTAGE_FOLLOWER', nodes=['VIN', 'VBULK', 'VOUT', 'Ib']) | ||
|
||
netlist.connect_netlist(fet_1.info['netlist'], [('D', 'Ib'), ('G', 'VIN'), ('S', 'VOUT'), ('B', 'VBULK')]) | ||
netlist.connect_netlist(fet_2.info['netlist'], [('D', 'VOUT'), ('G', 'Ib'), ('S', 'VBULK'), ('B', 'VBULK')]) | ||
|
||
return netlist | ||
|
||
def sky130_add_fvf_labels(fvf_in: Component) -> Component: | ||
|
||
fvf_in.unlock() | ||
# define layers` | ||
met1_pin = (68,16) | ||
met1_label = (68,5) | ||
met2_pin = (69,16) | ||
met2_label = (69,5) | ||
# list that will contain all port/comp info | ||
move_info = list() | ||
# create labels and append to info list | ||
# gnd | ||
gnd2label = rectangle(layer=met1_pin,size=(0.5,0.5),centered=True).copy() | ||
gnd2label.add_label(text="VBULK",layer=met1_label) | ||
move_info.append((gnd2label,fvf_in.ports["B_tie_N_top_met_N"],None)) | ||
|
||
#currentbias | ||
ibiaslabel = rectangle(layer=met2_pin,size=(0.5,0.5),centered=True).copy() | ||
ibiaslabel.add_label(text="Ib",layer=met2_label) | ||
move_info.append((ibiaslabel,fvf_in.ports["A_drain_bottom_met_N"],None)) | ||
|
||
# output (3rd stage) | ||
outputlabel = rectangle(layer=met2_pin,size=(0.5,0.5),centered=True).copy() | ||
outputlabel.add_label(text="VOUT",layer=met2_label) | ||
move_info.append((outputlabel,fvf_in.ports["A_source_bottom_met_N"],None)) | ||
|
||
# input | ||
inputlabel = rectangle(layer=met1_pin,size=(0.5,0.5),centered=True).copy() | ||
inputlabel.add_label(text="VIN",layer=met1_label) | ||
move_info.append((inputlabel,fvf_in.ports["A_multiplier_0_gate_N"], None)) | ||
|
||
# move everything to position | ||
for comp, prt, alignment in move_info: | ||
alignment = ('c','b') if alignment is None else alignment | ||
compref = align_comp_to_port(comp, prt, alignment=alignment) | ||
fvf_in.add(compref) | ||
return fvf_in.flatten() | ||
|
||
@cell | ||
def flipped_voltage_follower( | ||
pdk: MappedPDK, | ||
device_type: str = "nmos", | ||
placement: str = "horizontal", | ||
width: tuple[float,float] = (3,3), | ||
length: tuple[float,float] = (None,None), | ||
fingers: tuple[int,int] = (1,1), | ||
multipliers: tuple[int,int] = (1,1), | ||
dummy_1: tuple[bool,bool] = (True,True), | ||
dummy_2: tuple[bool,bool] = (True,True), | ||
tie_layers1: tuple[str,str] = ("met2","met1"), | ||
tie_layers2: tuple[str,str] = ("met2","met1"), | ||
sd_rmult: int=1, | ||
**kwargs | ||
) -> Component: | ||
""" | ||
creates a Flipped Voltage Follower | ||
pdk: pdk to use | ||
device_type: either "nmos" or "pmos" | ||
placement: either "horizontal" or "vertical" | ||
width: (input fet, feedback fet) | ||
length: (input fet, feedback fet) | ||
fingers: (input fet, feedback fet) | ||
multipliers: (input fet, feedback fet) | ||
dummy_1: dummy for input fet | ||
dummy_2: dummy for feedback fet | ||
tie_layers1: tie layers for input fet | ||
tie_layers2: tie layers for feedback fet | ||
sd_rmult: sd_rmult for both fets | ||
**kwargs: any kwarg that is supported by nmos and pmos | ||
""" | ||
|
||
#top level component | ||
top_level = Component(name="flipped_voltage_follower") | ||
|
||
#two fets | ||
if device_type == "nmos": | ||
fet_1 = nmos(pdk, width=width[0], fingers=fingers[0], multipliers=multipliers[0], with_dummy=dummy_1, with_dnwell=False, with_substrate_tap=False, length=length[0], tie_layers=tie_layers1, sd_rmult=sd_rmult, **kwargs) | ||
fet_2 = nmos(pdk, width=width[1], fingers=fingers[1], multipliers=multipliers[1], with_dummy=dummy_2, with_dnwell=False, with_substrate_tap=False, length=length[1], tie_layers=tie_layers2, sd_rmult=sd_rmult, **kwargs) | ||
well = "pwell" | ||
elif device_type == "pmos": | ||
fet_1 = pmos(pdk, width=width[0], fingers=fingers[0], multipliers=multipliers[0], with_dummy=dummy_1, with_substrate_tap=False, length=length[0], tie_layers=tie_layers1, sd_rmult=sd_rmult, **kwargs) | ||
fet_2 = pmos(pdk, width=width[1], fingers=fingers[1], multipliers=multipliers[1], with_dummy=dummy_2, with_substrate_tap=False, length=length[1], tie_layers=tie_layers2, sd_rmult=sd_rmult, **kwargs) | ||
well = "nwell" | ||
fet_1_ref = top_level << fet_1 | ||
fet_2_ref = top_level << fet_2 | ||
|
||
#Relative move | ||
ref_dimensions = evaluate_bbox(fet_2) | ||
if placement == "horizontal": | ||
fet_2_ref.movex(fet_1_ref.xmax + ref_dimensions[0]/2 + pdk.util_max_metal_seperation()+1) | ||
if placement == "vertical": | ||
fet_2_ref.movey(fet_1_ref.ymin - ref_dimensions[1]/2 - pdk.util_max_metal_seperation()-1) | ||
|
||
#Routing | ||
viam2m3 = via_stack(pdk, "met2", "met3", centered=True) | ||
drain_1_via = top_level << viam2m3 | ||
source_1_via = top_level << viam2m3 | ||
drain_2_via = top_level << viam2m3 | ||
gate_2_via = top_level << viam2m3 | ||
drain_1_via.move(fet_1_ref.ports["multiplier_0_drain_W"].center).movex(-0.5*evaluate_bbox(fet_1)[1]) | ||
source_1_via.move(fet_1_ref.ports["multiplier_0_source_E"].center).movex(1.5) | ||
drain_2_via.move(fet_2_ref.ports["multiplier_0_drain_W"].center).movex(-1.5) | ||
gate_2_via.move(fet_2_ref.ports["multiplier_0_gate_E"].center).movex(1) | ||
|
||
top_level << straight_route(pdk, fet_1_ref.ports["multiplier_0_source_E"], source_1_via.ports["bottom_met_W"]) | ||
top_level << straight_route(pdk, fet_2_ref.ports["multiplier_0_drain_W"], drain_2_via.ports["bottom_met_E"]) | ||
top_level << c_route(pdk, source_1_via.ports["top_met_N"], drain_2_via.ports["top_met_N"], extension=1.2*width[1], width1=0.32, width2=0.32, cwidth=0.32, e1glayer="met3", e2glayer="met3", cglayer="met2") | ||
top_level << straight_route(pdk, fet_1_ref.ports["multiplier_0_drain_W"], drain_1_via.ports["bottom_met_E"]) | ||
top_level << c_route(pdk, drain_1_via.ports["top_met_S"], gate_2_via.ports["top_met_S"], extension=1.2*width[1], cglayer="met2") | ||
top_level << straight_route(pdk, fet_2_ref.ports["multiplier_0_gate_E"], gate_2_via.ports["bottom_met_W"]) | ||
|
||
top_level << straight_route(pdk, fet_2_ref.ports["multiplier_0_source_W"], fet_2_ref.ports["tie_W_top_met_W"], glayer1=tie_layers2[1], width=0.2*sd_rmult, fullbottom=True) | ||
|
||
#Renaming Ports | ||
top_level.add_ports(fet_1_ref.get_ports_list(), prefix="A_") | ||
top_level.add_ports(fet_2_ref.get_ports_list(), prefix="B_") | ||
top_level.add_ports(drain_1_via.get_ports_list(), prefix="A_drain_") | ||
top_level.add_ports(source_1_via.get_ports_list(), prefix="A_source_") | ||
top_level.add_ports(drain_2_via.get_ports_list(), prefix="B_drain_") | ||
top_level.add_ports(gate_2_via.get_ports_list(), prefix="B_gate_") | ||
#add dnwell | ||
if well == "nwell": | ||
top_level.add_padding(layers=(pdk.get_glayer("nwell"),),default= 1 ) | ||
|
||
|
||
comp = Component() | ||
compref = comp << top_level | ||
correctionxy = prec_center(compref) | ||
compref.movex(correctionxy[0]).movey(correctionxy[1]) | ||
|
||
component = component_snap_to_grid(rename_ports_by_orientation(top_level)) | ||
|
||
component.info['netlist'] = fvf_netlist(fet_1, fet_2) | ||
|
||
return component | ||
|
||
|
Binary file added
BIN
+13.3 KB
openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code duplication can be reduced here since only the function name changes and not the arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I am uploading the new file