From 309241d6fa8ca6fcbce8535426848183a4ec794b Mon Sep 17 00:00:00 2001 From: Subhampal9 <122683549+Subhampal9@users.noreply.github.com> Date: Sun, 24 Nov 2024 17:11:09 +0530 Subject: [PATCH 1/6] added FVF Pcell files, Analog Vibes, Chipathon 2024 1. drc and lvs reports are also attached 2. sample picture of gds is attached 3. README file and annotations in fvf.py are added --- .../glayout/flow/blocks/elementary/FVF/LVS | 41 +++++ .../flow/blocks/elementary/FVF/README.md | 35 ++++ .../glayout/flow/blocks/elementary/FVF/drc | 31 ++++ .../glayout/flow/blocks/elementary/FVF/fvf.py | 167 ++++++++++++++++++ .../flow/blocks/elementary/FVF/fvfgds.png | Bin 0 -> 13575 bytes 5 files changed, 274 insertions(+) create mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS create mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md create mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc create mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py create mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS new file mode 100644 index 000000000..515a0a769 --- /dev/null +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS @@ -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. +. diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md new file mode 100644 index 000000000..8f5bca85f --- /dev/null +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md @@ -0,0 +1,35 @@ +##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 + dnwell: adds Deep N-well + sb_short: shorts the source and bulk of input fet if True + 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 + NB:- currently LVS is passed only for nmos without sd_short and pmos with sd_short + diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc new file mode 100644 index 000000000..d622202f2 --- /dev/null +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc @@ -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 + diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py new file mode 100644 index 000000000..7186f9918 --- /dev/null +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py @@ -0,0 +1,167 @@ +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 + dnwell: adds Deep N-well + sb_short: shorts the source and bulk of input fet if True + 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 + NB:- currently LVS is passed only for nmos without sd_short and pmos with sd_short + """ + + #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 + + diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc7422aafc51d3f3af20fe4940bb36ce6f3c142 GIT binary patch literal 13575 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 Date: Sun, 24 Nov 2024 17:20:27 +0530 Subject: [PATCH 2/6] Updated README.md --- .../glayout/flow/blocks/elementary/FVF/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md index 8f5bca85f..1cef36bea 100644 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md @@ -1,4 +1,6 @@ -##FLIPPED VOLTAGE FOLLOWER CELL +## FLIPPED VOLTAGE FOLLOWER CELL + +``` def flipped_voltage_follower( pdk: MappedPDK, device_type: str = "nmos", @@ -25,11 +27,11 @@ def flipped_voltage_follower( multipliers: (input fet, feedback fet) dummy_1: dummy for input fet dummy_2: dummy for feedback fet - dnwell: adds Deep N-well - sb_short: shorts the source and bulk of input fet if True 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 - NB:- currently LVS is passed only for nmos without sd_short and pmos with sd_short +``` +### GDS generated +![gds generated](./fvfgds.png) From 51bb49388030d69eed750d6cc5c5f6781502fb82 Mon Sep 17 00:00:00 2001 From: Subhampal9 <122683549+Subhampal9@users.noreply.github.com> Date: Sun, 24 Nov 2024 17:22:07 +0530 Subject: [PATCH 3/6] Updated comments --- .../glayout/glayout/flow/blocks/elementary/FVF/fvf.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py index 7186f9918..988227fb6 100644 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py @@ -90,13 +90,10 @@ def flipped_voltage_follower( multipliers: (input fet, feedback fet) dummy_1: dummy for input fet dummy_2: dummy for feedback fet - dnwell: adds Deep N-well - sb_short: shorts the source and bulk of input fet if True 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 - NB:- currently LVS is passed only for nmos without sd_short and pmos with sd_short """ #top level component From aa901e8ebdb5e4a9fdc5aec651628a681a16160a Mon Sep 17 00:00:00 2001 From: Subhampal9 <122683549+Subhampal9@users.noreply.github.com> Date: Fri, 29 Nov 2024 22:40:51 +0530 Subject: [PATCH 4/6] Update current_mirror.py Previously a ptap and pwell was layed out irrespective of the device type. Added the code to add specific tap and well layers for each device type --- .../current_mirror/current_mirror.py | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py index e7cdb39e8..ea3759699 100644 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py @@ -102,19 +102,22 @@ def current_mirror( # short gate and drain of one of the reference interdigitized_fets << L_route(pdk, interdigitized_fets.ports['A_drain_W'], gate_short.ports['con_N'], viaoffset=False, fullbottom=False) - top_level << interdigitized_fets - # add the tie layer - if with_tie: + top_level << interdigitized_fets + if with_tie: + if device in ['nmos','nfet']: + tap_layer = "p+s/d" + if device in ['pmos','pfet']: + tap_layer = "n+s/d" tap_sep = max( pdk.util_max_metal_seperation(), pdk.get_grule("active_diff", "active_tap")["min_separation"], ) - tap_sep += pdk.get_grule("p+s/d", "active_tap")["min_enclosure"] + tap_sep += pdk.get_grule(tap_layer, "active_tap")["min_enclosure"] tap_encloses = ( 2 * (tap_sep + interdigitized_fets.xmax), 2 * (tap_sep + interdigitized_fets.ymax), ) - tie_ref = top_level << tapring(pdk, enclosed_rectangle = tap_encloses, sdlayer = "p+s/d", horizontal_glayer = tie_layers[0], vertical_glayer = tie_layers[1]) + tie_ref = top_level << tapring(pdk, enclosed_rectangle = tap_encloses, sdlayer = tap_layer, horizontal_glayer = tie_layers[0], vertical_glayer = tie_layers[1]) top_level.add_ports(tie_ref.get_ports_list(), prefix="welltie_") try: top_level << straight_route(pdk, top_level.ports["A_0_dummy_L_gsdcon_top_met_W"],top_level.ports["welltie_W_top_met_W"],glayer2="met1") @@ -128,8 +131,13 @@ def current_mirror( pass # add a pwell - top_level.add_padding(layers = (pdk.get_glayer("pwell"),), default = pdk.get_grule("pwell", "active_tap")["min_enclosure"], ) - top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("pwell"), prefix="well_") + if device in ['nmos','nfet']: + top_level.add_padding(layers = (pdk.get_glayer("pwell"),), default = pdk.get_grule("pwell", "active_tap")["min_enclosure"], ) + top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("pwell"), prefix="well_") + if device in ['pmos','pfet']: + top_level.add_padding(layers = (pdk.get_glayer("nwell"),), default = pdk.get_grule("nwell", "active_tap")["min_enclosure"], ) + top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("nwell"), prefix="well_") + # add the substrate tap if specified if with_substrate_tap: @@ -151,4 +159,4 @@ def current_mirror( subckt_only=True ) - return top_level \ No newline at end of file + return top_level From 1c1796fcfd8b589bb834bfeaaf03fc8907684c61 Mon Sep 17 00:00:00 2001 From: Subhampal9 <122683549+Subhampal9@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:09:53 +0530 Subject: [PATCH 5/6] Delete openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF directory Now it only contains the change in current_mirror block --- .../glayout/flow/blocks/elementary/FVF/LVS | 41 ----- .../flow/blocks/elementary/FVF/README.md | 37 ---- .../glayout/flow/blocks/elementary/FVF/drc | 31 ---- .../glayout/flow/blocks/elementary/FVF/fvf.py | 164 ------------------ .../flow/blocks/elementary/FVF/fvfgds.png | Bin 13575 -> 0 bytes 5 files changed, 273 deletions(-) delete mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS delete mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md delete mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc delete mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py delete mode 100644 openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS deleted file mode 100644 index 515a0a769..000000000 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/LVS +++ /dev/null @@ -1,41 +0,0 @@ - -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. -. diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md deleted file mode 100644 index 1cef36bea..000000000 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/README.md +++ /dev/null @@ -1,37 +0,0 @@ -## 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) - diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc deleted file mode 100644 index d622202f2..000000000 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/drc +++ /dev/null @@ -1,31 +0,0 @@ -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 - diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py deleted file mode 100644 index 988227fb6..000000000 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvf.py +++ /dev/null @@ -1,164 +0,0 @@ -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 - - diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/FVF/fvfgds.png deleted file mode 100644 index 5bc7422aafc51d3f3af20fe4940bb36ce6f3c142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13575 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 Date: Tue, 4 Feb 2025 19:11:00 +0530 Subject: [PATCH 6/6] fixing indentation error --- .../current_mirror/current_mirror.py | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py index ea3759699..4a9685608 100644 --- a/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py +++ b/openfasoc/generators/glayout/glayout/flow/blocks/elementary/current_mirror/current_mirror.py @@ -102,16 +102,16 @@ def current_mirror( # short gate and drain of one of the reference interdigitized_fets << L_route(pdk, interdigitized_fets.ports['A_drain_W'], gate_short.ports['con_N'], viaoffset=False, fullbottom=False) - top_level << interdigitized_fets - if with_tie: - if device in ['nmos','nfet']: - tap_layer = "p+s/d" - if device in ['pmos','pfet']: - tap_layer = "n+s/d" + top_level << interdigitized_fets + if with_tie: + if device in ['nmos','nfet']: + tap_layer = "p+s/d" + if device in ['pmos','pfet']: + tap_layer = "n+s/d" tap_sep = max( - pdk.util_max_metal_seperation(), - pdk.get_grule("active_diff", "active_tap")["min_separation"], - ) + pdk.util_max_metal_seperation(), + pdk.get_grule("active_diff", "active_tap")["min_separation"], + ) tap_sep += pdk.get_grule(tap_layer, "active_tap")["min_enclosure"] tap_encloses = ( 2 * (tap_sep + interdigitized_fets.xmax), @@ -131,12 +131,12 @@ def current_mirror( pass # add a pwell - if device in ['nmos','nfet']: - top_level.add_padding(layers = (pdk.get_glayer("pwell"),), default = pdk.get_grule("pwell", "active_tap")["min_enclosure"], ) - top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("pwell"), prefix="well_") - if device in ['pmos','pfet']: - top_level.add_padding(layers = (pdk.get_glayer("nwell"),), default = pdk.get_grule("nwell", "active_tap")["min_enclosure"], ) - top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("nwell"), prefix="well_") + if device in ['nmos','nfet']: + top_level.add_padding(layers = (pdk.get_glayer("pwell"),), default = pdk.get_grule("pwell", "active_tap")["min_enclosure"], ) + top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("pwell"), prefix="well_") + if device in ['pmos','pfet']: + top_level.add_padding(layers = (pdk.get_glayer("nwell"),), default = pdk.get_grule("nwell", "active_tap")["min_enclosure"], ) + top_level = add_ports_perimeter(top_level, layer = pdk.get_glayer("nwell"), prefix="well_") # add the substrate tap if specified