Skip to content
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

Chipathon2024 saltychip #347

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1a3770b
Add the transmission gate (still onging) folder from the SaltyChi tea…
tsengs0 Nov 3, 2024
0377bae
Add the README and __init__.py files for the transmission gate block
tsengs0 Nov 3, 2024
5d7dc55
Add mimcap array layout
tsengs0 Nov 3, 2024
23738f6
Update the progress in the README
tsengs0 Nov 3, 2024
de306c8
Modify the layout of the transmission by rotating every MOSFET 90 degree
tsengs0 Nov 8, 2024
b1d1ae0
Add dummy cells to the PMOS-NMOS pair for the TG against the asymmeti…
tsengs0 Nov 10, 2024
ecabeed
Complete routing of the TG w/ an inverter for controlling the gates o…
tsengs0 Nov 10, 2024
929bf0b
Add the first draft of layout report and GDS w/o I/O port yet
tsengs0 Nov 10, 2024
e5e9a2c
Add the external I/O ports for the transmission gate
tsengs0 Nov 13, 2024
4830dce
Create a Colab notebook generating and displaying the transmission ga…
tsengs0 Nov 14, 2024
477ff15
Add functions to automatically insert the external I/O ports on the t…
tsengs0 Nov 14, 2024
e034352
Add the ToDo list for the PR draft submission
tsengs0 Nov 15, 2024
94561b6
Change the route layer inside the transmission gate
tsengs0 Nov 17, 2024
6d8e8be
Add the external pins for the LVS process
tsengs0 Nov 17, 2024
c75a0a5
Team: Salty Chip, Chipathon2024
tsengs0 Nov 17, 2024
cc695ac
Team: Salty Chip, Chipathon2024
tsengs0 Nov 18, 2024
84b94b3
Team: Salty Chip, Chipathon2024
tsengs0 Nov 20, 2024
351cbdf
Team: Salty Chip, Chipathon2024
tsengs0 Nov 21, 2024
8bd30da
Final modification of the intergititized layout of the transmission g…
tsengs0 Nov 23, 2024
6d79564
Modify the netlist gen for the transmission gate
tsengs0 Nov 23, 2024
0fcd05a
Contributor: Team SaltyChip, Chipathon 2024
tsengs0 Nov 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@

# PCell of transmission gate
- Contributor: Team SaltyChip (from Chipathon 2024)


## Glayout Source codes (1)

- **Function:** short_width_tg
- **Description/Purpose:** to build a layout of the transmission gate without multifinger transistors
- **Source file:** transmission_gate.py

```
def short_width_tg(
pdk: MappedPDK,
component_name: str = "tg",
with_substrate_tap: bool = False,
fet_min_width: float = 3,
pmos_width: float = 3,
pmos_length: float = 0.15,
nmos_width: float = 3,
nmos_length: float = 0.15,
add_pin: bool = True, # For LVS
**kwargs
) -> Component:
```
| Parameter | Type | Description | Default | Constraint/Limit |
| --- | --- | --- | --- | --- |
| pdk | MappedPDK | To select the target PDK | | sky130 or gf180mcu |
| component_name | string | The component name of the instantiated PCell | tg | |
| fet_min_width | float | A constraint to specify the mimimum width of each PMOS/NMOS inside the PCell | 3 (unit: um) | fet_min_width >= 2 |
| pmos_width | float | Width of the PMOS in the underlying PCell | 3 (unit: um) | pmos_width = fet_min_width |
| pmos_length | float | Length of the PMOS in the underlying PCell | 0.15 (unit: um) | pmos_length = 0.15 |
| nmos_width | float |Width of the NMOS in the underlying PCell | 3 (unit: um) | float | nmos_width = fet_min_width |
| nmos_length | float | Length of the NMOS in the underlying PCell | 0.15 (unit: um) | nmos_length = 0.15 |
| with_substrate_tap | bool | To add substrate tap surrounding the top level of the PCell if it is set True | False | |
| add_pin | bool | To add the pins with labels for the top level of the PCell (for the LVS) if it is set True | True | |

---

## Glayout Source codes (2)

- **Function:** long_width_tg
- **Description/Purpose:** to build an interdigitized layout of the transmission gate when the width of the underlying trasistors is relatively long
- **Source file:** transmission_gate.py

```
def long_width_tg(
pdk: MappedPDK,
component_name: str = "tg",
fet_min_width: float = 3,
pmos_width: float = 12,
pmos_length: float = 0.15,
nmos_width: float = 12,
nmos_length: float = 0.15,
with_substrate_tap: bool = True,
add_pin: bool = True, # For LVS
**kwargs
) -> Component:
```
| Parameter | Type | Description | Default | Constraint/Limit |
| --- | --- | --- | --- | --- |
| pdk | MappedPDK | To select the target PDK | | sky130 or gf180mcu |
| component_name | string | The component name of the instantiated PCell | tg | |
| fet_min_width | float | A constraint to specify the mimimum width of each PMOS/NMOS inside the PCell | 3 (unit: um) | fet_min_width >= 2 |
| pmos_width | float | Width of the PMOS in the underlying PCell | 12 (unit: um) | **pmos_width** must be a multiple of **fet_min_width*4** |
| pmos_length | float | Length of the PMOS in the underlying PCell | 0.15 (unit: um) | pmos_length = 0.15 |
| nmos_width | float |Width of the NMOS in the underlying PCell | 12 (unit: um) | **nmos_width** must be a multiple of **fet_min_width*4** |
| nmos_length | float | Length of the NMOS in the underlying PCell | 0.15 (unit: um) | nmos_length = 0.15 |
| add_pin | bool | To add the pins with labels for the top level of the PCell (for the LVS) if it is set True | True | |
| with_substrate_tap | bool | To add substrate tap surrounding the top level of the PCell if it is set True | False | |

---

## Glayout Source codes (3)

- **Function:** tg_cell
- **Description/Purpose:** a generic function to build a layout of the transmission gate in an either single-finger or multifinger fashion depeending on the specified widht of PMOS/NMOS
- **Source file:** transmission_gate.py

```
def tg_cell(
pdk: MappedPDK,
component_name: str = "tg",
fet_min_width: float = 3,
pmos_width: float = 6,
pmos_length: float = 0.15,
nmos_width: float = 6,
nmos_length: float = 0.15,
add_pin: bool = True, # For LVS
with_substrate_tap: bool = True,
**kwargs
) -> Component:
```
| Parameter | Type | Description | Default | Constraint/Limit |
| --- | --- | --- | --- | --- |
| pdk | MappedPDK | To select the target PDK | | sky130 or gf180mcu |
| component_name | string | The component name of the instantiated PCell | tg | |
| fet_min_width | float | A constraint to specify the mimimum width of each PMOS/NMOS inside the PCell | 3 (unit: um) | fet_min_width >= 2 |
| pmos_width | float | Width of the PMOS in the underlying PCell | 12 (unit: um) | **pmos_width** must be equal to **fet_min_width** or a multiple of **fet_min_width*4** |
| pmos_length | float | Length of the PMOS in the underlying PCell | 0.15 (unit: um) | pmos_length = 0.15 |
| nmos_width | float |Width of the NMOS in the underlying PCell | 12 (unit: um) | **nmos_width** must be equal to **fet_min_width** or a multiple of **fet_min_width*4** |
| nmos_length | float | Length of the NMOS in the underlying PCell | 0.15 (unit: um) | nmos_length = 0.15 |
| add_pin | bool | To add the pins with labels for the top level of the PCell (for the LVS) if it is set True | True | |
| with_substrate_tap | bool | To add substrate tap surrounding the top level of the PCell if it is set True | False | |

---

## Example code of evaluating the PCell

In this example, a Python file, **eval.py** created under the directory **transmission_gate**, is wrote as follow which diplays the GDS and the check the DRC and LVS results.

```
from datetime import datetime
import subprocess
#from glayout.flow.pdk.gf180_mapped import gf180
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk as sky130
import transmission_gate as tg

TARGET_PDK = sky130
PWD_OUTPUT = subprocess.run(['pwd'], capture_output=True, text=True)
GDS_DIR = PWD_OUTPUT.stdout.strip() + "/gds"
DRC_RPT_DIR = PWD_OUTPUT.stdout.strip() + "/regression/drc"
LVS_RPT_DIR = PWD_OUTPUT.stdout.strip() + "/regression/lvs"

pmos_width = 12
pmos_length = 0.15
nmos_width = 12
nmos_length = 0.15
fet_min_width = 3

def basic_tg_eval():
tg_dut = tg.tg_cell(
pdk=TARGET_PDK,
component_name="tg",
fet_min_width=fet_min_width,
pmos_width=pmos_width,
pmos_length=pmos_length,
nmos_width=nmos_width,
nmos_length=nmos_length,
with_substrate_tap=True,
add_pin=True
)

tg_dut.show()
print(tg_dut.info["netlist"].generate_netlist())
tg_dut.write_gds(f"{GDS_DIR}/{tg_dut.name}.gds")

now = datetime.now() # Get the current date and time
regression_id = now.strftime('%Y%m%d%H%M%S') # Format the date and time without spaces

magic_drc_result = sky130.drc_magic(
layout=tg_dut,
design_name=tg_dut.name,
output_file=f"{DRC_RPT_DIR}/{tg_dut.name}_{regression_id}_drc.rpt"
)
print(f"Magic DRC result ({tg_dut.name}): \n", magic_drc_result)
print("--------------------------------------")
netgen_lvs_result = sky130.lvs_netgen(
layout=tg_dut,
design_name=tg_dut.name,
output_file_path=f"{LVS_RPT_DIR}/{tg_dut.name}_{regression_id}_lvs.rpt",
copy_intermediate_files=True
)

def main():
basic_tg_eval()

if __name__ == "__main__":
main()
```

---

## Progress (until 24/11/2024)

- ToDo list
- Transmission gate
- [x] Layout
- [x] Add ports w/ labels onto the layout (for the subsequent LVS)
- [x] DRC of the layout w/o error (Magic)
- [ ] DRC of the layout w/o error (Klayout)
- [x] Create the baseline schematic of the created component
- [ ] LVS w/o error
- [x] Document about the PCell specification
- [ ] PEX and create the testbench
- [ ] Verification gets passed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from glayout.flow.blocks.elementary.transmission_gate.transmission_gate import transmission_gate_netlist
from glayout.flow.blocks.elementary.transmission_gate.transmission_gate import short_width_tg
from glayout.flow.blocks.elementary.transmission_gate.transmission_gate import long_width_tg
from glayout.flow.blocks.elementary.transmission_gate.transmission_gate import tg_cell
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from datetime import datetime
import subprocess
#from glayout.flow.pdk.gf180_mapped import gf180
from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk as sky130
import transmission_gate as tg

TARGET_PDK = sky130
PWD_OUTPUT = subprocess.run(['pwd'], capture_output=True, text=True)
GDS_DIR = PWD_OUTPUT.stdout.strip() + "/gds"
DRC_RPT_DIR = PWD_OUTPUT.stdout.strip() + "/regression/drc"
LVS_RPT_DIR = PWD_OUTPUT.stdout.strip() + "/regression/lvs"

pmos_width = 12
pmos_length = 0.15
nmos_width = 12
nmos_length = 0.15
fet_min_width = 3

def basic_tg_eval():
tg_dut = tg.tg_cell(
pdk=TARGET_PDK,
component_name="tg",
fet_min_width=fet_min_width,
pmos_width=pmos_width,
pmos_length=pmos_length,
nmos_width=nmos_width,
nmos_length=nmos_length,
with_substrate_tap=True,
add_pin=True
)

tg_dut.show()
print(tg_dut.info["netlist"].generate_netlist())
tg_dut.write_gds(f"{GDS_DIR}/{tg_dut.name}.gds")

now = datetime.now() # Get the current date and time
regression_id = now.strftime('%Y%m%d%H%M%S') # Format the date and time without spaces

magic_drc_result = sky130.drc_magic(
layout=tg_dut,
design_name=tg_dut.name,
output_file=f"{DRC_RPT_DIR}/{tg_dut.name}_{regression_id}_drc.rpt"
)
print(f"Magic DRC result ({tg_dut.name}): \n", magic_drc_result)
print("--------------------------------------")
netgen_lvs_result = sky130.lvs_netgen(
layout=tg_dut,
design_name=tg_dut.name,
output_file_path=f"{LVS_RPT_DIR}/{tg_dut.name}_{regression_id}_lvs.rpt",
copy_intermediate_files=True
)

def main():
basic_tg_eval()

if __name__ == "__main__":
main()
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tg_cell_471429cf count:
----------------------------------------

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

Circuit 1 cell sky130_fd_pr__pfet_01v8 and Circuit 2 cell sky130_fd_pr__pfet_01v8 are black boxes.
Warning: Equate pins: cell sky130_fd_pr__pfet_01v8 is a placeholder, treated as a black box.
Warning: Equate pins: cell sky130_fd_pr__pfet_01v8 is a placeholder, treated as a black box.

Subcircuit pins:
Circuit 1: sky130_fd_pr__pfet_01v8 |Circuit 2: sky130_fd_pr__pfet_01v8
-------------------------------------------|-------------------------------------------
1 |1
2 |2
3 |3
4 |4
---------------------------------------------------------------------------------------
Cell pin lists are equivalent.
Device classes sky130_fd_pr__pfet_01v8 and sky130_fd_pr__pfet_01v8 are equivalent.

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.

Class tg_cell_471429cf (0): Merged 6 parallel devices.
Subcircuit summary:
Circuit 1: tg_cell_471429cf |Circuit 2: tg_cell_471429cf
-------------------------------------------|-------------------------------------------
sky130_fd_pr__pfet_01v8 (6->3) |sky130_fd_pr__pfet_01v8 (4->1) **Mismatch*
sky130_fd_pr__nfet_01v8 (6->3) |sky130_fd_pr__nfet_01v8 (4->1) **Mismatch*
Number of devices: 6 **Mismatch** |Number of devices: 2 **Mismatch**
Number of nets: 10 **Mismatch** |Number of nets: 6 **Mismatch**
---------------------------------------------------------------------------------------
NET mismatches: Class fragments follow (with fanout counts):
Circuit 1: tg_cell_471429cf |Circuit 2: tg_cell_471429cf

---------------------------------------------------------------------------------------
Net: w_n715_603# |Net: VDD
sky130_fd_pr__pfet_01v8/4 = 3 | sky130_fd_pr__pfet_01v8/4 = 1
|
Net: a_n877_n684# |Net: VSS
sky130_fd_pr__nfet_01v8/4 = 3 | sky130_fd_pr__nfet_01v8/4 = 1
---------------------------------------------------------------------------------------
Netlists do not match.

Subcircuit pins:
Circuit 1: tg_cell_471429cf |Circuit 2: tg_cell_471429cf
-------------------------------------------|-------------------------------------------
Cell pin lists are equivalent.
Device classes tg_cell_471429cf and tg_cell_471429cf are equivalent.

Final result: Netlists do not match.
Loading