# 數位電子導論 Transistor Design Project Reference Guide
Author: waig548
---
# 目錄
[TOC]
---
# 前言
聽教授說往年課程這部分的實作都是用商用軟體,但這屆(112)開始改用開源軟體(`xcircuit`, `klayout`)來做。
助教們似乎也都是第一次使用,好像有人看錄影做也弄不太出來,但==應該==會提供影片中使用的簡報檔。
我認為可以只看project及課程的簡報做出來。
這兩個project我做得還挺開心,各花大約3小時就做完所有要求(包含bonus),也沒遇到什麼嚴重的問題 (有可能是因為我的環境裡面已經有大部分需要的東西)。
希望這篇文章可以協助你輕鬆愜意地完成這兩個project,或是提早假釋脫離牢房。
本文主要分為三個部分:
- `Schematic Design (Front-End)`
- `Layout Design (Back-End)`
- `Appendix`
前兩個分別包含`xcircuit`跟`klayout`安裝、設置、使用上的注意事項與一些操作技巧及`inverter`的schematic和layout設計操作流程
`Appendix`則包含一些可以協助完成project的額外資訊
**建議先看過project的簡報再回來閱讀本文**
文中我會使用全新安裝的WSL distro `Ubuntu 24.04` (其他版本也可以) 作為操作環境基底,
以下是我在環境中先安裝好的套件 (**粗體**代表必要套件,++底線++代表可選套件,==黃底==為與project內容無關的套件):
- **`ubuntu-desktop` - 桌面環境組合包1**
- **`xfce4` - 桌面環境組合包2**
- ++`build-essential` - 建置工具組合包++ - 若要自己build `xcircuit`和`klayout`則為必要
- ==[`fish`](https://fishshell.com/) (包含[`oh-my-fish`](https://github.com/oh-my-fish/oh-my-fish)及[`bobthefish`](https://github.com/oh-my-fish/theme-bobthefish)主題)== - 使用上比較方便的shell,可以嘗試看看
---
# 前置環境
相信各位走到這一步時應該都已經有可以使用圖形化界面的linux系統了,但還是確認一下:
- 如果你是使用虛擬機器的話,可以跳過這部分
- 如果你是使用WSL的話,請先確定已有安裝過對應distro的圖形化界面套件
以Ubuntu來說,執行`sudo apt install ubuntu-desktop`及`sudo apt install xfce4`即可,安裝完可以執行`xclock`或`xcalc`來確認安裝成功
:::warning
由於新版WSL2內建了[wslg](https://github.com/microsoft/wslg)作為預設的圖形化界面backend,不再需要借助MobaXTerm中的X server功能,且我們可以直接執行`wsl.exe`進入WSL系統進行操作,不必使用其進行連接,再加上有時可能會出現操作環境上的問題,非必要情況下可以不使用。
在Windows系統上,個人推薦使用[Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/)來操作WSL,在Win11上內建且為預設terminal,使用起來也頗舒適。
> 使用WSL圖形化界面的[官方文件](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps)
:::
# Schematic Design (Front-End)
## 安裝及設置`xcircuit`
安裝xcircuit有兩種方法:
1. 從package manager下載已經build好的套件
在Ubuntu環境中可以使用`sudo apt install xcircuit`安裝
2. clone repo下來自己build
使用第一個方法的優點是省事,缺點是安裝的可能不是最新版,且不一定每個系統都能用這個方法安裝。
第二個方法的優點是可以確保是最新版,但build過程中遇到狀況時需要自行修正。
### `xcircuit`建置及安裝步驟
1. 安裝建置`xcircuit`必須的套件
`sudo apt-get install build-essential tcl-dev tk-dev
libx11-dev libcairo-dev libxt-dev automake`
2. 把`xcircuit`的repo clone下來
`git clone git://opencircuitdesign.com/xcircuit`
3. 進入`xcircuit`內configure並建置
```shell=
cd xcircuit
autoreconf
./configure
make
```
==`autoreconf`在`make`時有出現`error: version mismatch.`錯誤訊息時才需要執行==
4. 安裝前測試(選擇性)
```shell=
export XCIRCUIT_LIB_DIR=./lib
export XCIRCUIT_SRC_DIR=./lib/tcl
./lib/tcl/xcircuit.sh
```
5. 安裝`xcircuit`
`sudo make install`
建置途中可能會遇到缺少header或找不到executable的情況,大多是因為有缺少安裝一些套件,google(**請使用英文**)一下應該都可以很快找到解決辦法。
---
## `xcircuit`使用方法、注意事項
[官方說明文件和教學](http://opencircuitdesign.com/xcircuit/)
### 主畫面
這應該會是剛開起來的樣子

先介紹一下這個畫面
#### 作畫區域
中間是作畫區域,滾輪可以上下滾動畫面,按住`Shift`改成水平滾動,按住`Ctrl`則變為畫面縮放
#### 功能表列
最上面那排是功能表列,**功能表每個選項都要用滑鼠點擊來展開**
:::warning
使用WSL的話要注意不要在功能表顯示時切換到其他程式,有可能會因為功能表顯示在上層而導致無法看到並點擊到程式本體;若能看到功能表的選項,點下去就可以恢復正常
:::
#### 工具欄
最右邊那排是工具欄
以下列出常用的按鈕圖示及其功能
|圖示|功能|
|---|---|
||移動畫面|
||繪製wire|
||建立文字|
||水平翻轉|
||垂直翻轉|
||切換至下個library|
||顯示所有library|
||顯示所有的page|
其他按鈕可以可以在游標hover過去時在狀態列看到對應的功能簡述
#### 狀態列
最下面的那排是狀態列
- `Symbol`和`Schematic`這兩個按鈕的功能是在有互相關聯的schematic和symbol之間切換檢視
現在看可能不好理解,在後面的`inverter` schematic設計中會再提到
- `Page 1`是目前所在的頁面名稱
- 藍底的`XXX Mode`是顯示目前選擇的工具,按下去會多出`Button bingdings`區塊,其中三個按鈕分別綁定到滑鼠左鍵、中鍵以及右鍵。
==滑鼠中鍵可以改用`Shift`左鍵代替==
---
### 快捷鍵
一些常用的快捷鍵 ++**快捷鍵有大小寫及符號之分**++ 表中==黃底==表示其功能取決於當前選擇的工具
|快捷鍵組合|功能|
|---|---|
|`l`(小寫L)|切換至下個library|
|`Esc`|退出/取消當前所有動作|
|`delete`|刪除選擇的物件|
|`Ctrl+p`|修改已選擇物件之屬性|
|`e`|編輯基礎物件(如文字等)|
|==`滑鼠左鍵`==|繪製/開始/繼續|
|==`滑鼠中鍵/Shift左鍵`==|選擇物件/結束並確認繪製wire|
|==`滑鼠右鍵`==|取消當前動作/取消上一個繪製的wire節點|
|`t`|在滑鼠游標處建立文字|
|`T`|在滑鼠游標處建立pin(腳位)名稱|
|`>`(`Shift+.`)|選擇並編輯滑鼠游標指向的複雜物件(如symbol等)|
詳細的快捷鍵組合可以到`Options > Help!`中查看
---
### 讀取/輸出檔案
這部分要先提一個很重要的觀念:
<font size=5>==**確定好你的working directory再開始做任何事**==</font>
> [!Note] working directory
簡單來說就是你從terminal執行程式當下所在的路徑
>
> 假設剛build並安裝完xcircuit且沒有執行過`cd`指令就打開xcircuit的話,那麼你的working directory就會是剛剛build xcircuit的位置
:::warning
xcircuit中很多輸出檔案的功能(**包含一些project需求要用的功能**)不會提示或要求你指定輸出路徑,而這些功能預設都是輸出到working directory內
如果沒有事先確認好的話,可能會難以找到輸出的檔案,甚至是覆蓋掉其他檔案
:::
#### 讀取schematic
指令:`File > Read X Circuit File`
跳出UI讓你選你要讀的檔案,副檔名為`*.ps`
#### 輸出schematic
指令:`File > Format Page Output`
會跳出以下畫面

比較常用到的東西:
- `Filename`: 你要輸出的檔名或路徑(只有檔名的話會輸出到working directory內)
副檔名為`*.ps`
- `Page label`: 你目前所在的page的名稱(可以自己設定)
- `Write File`: **實際輸出檔案**
:::danger
# 注意事項
1. 當你填完任一欄位後
<font color=red size=7>**一定要按對應欄位的Apply**</font>
不然不會記錄到你填的東西,後續任何輸出動作都會依照上一次有按Apply的設定輸出
2. <font size=5>**一個檔案只能輸出一頁,且不會提示檔案會被覆寫**</font>
輸出前請先確定好檔名、所在頁面再輸出
3. <font size=5>**強烈建議檔名和頁面名稱一致**</font>
輸出其他格式檔案時會使用到,保持兩者一致也能確保後面使用到這些檔案時不容易出錯
:::
#### 輸出SVG圖檔
指令:`File > Export > Export SVG`
<font color=red>**不會提示檔案覆寫**</font>
將目前頁面的內容輸出到working directory中的`<Page Label>.svg`檔案
> [!Warning] 已知問題
輸出的SVG檔雖然會包含繪製的文字(包含pin名稱),但輸出時可能沒有計算到文字的大小導致部分文字可能會被截斷或是顯示不出來。
這需要自己手動調整輸出的SVG檔案,如沒有特殊需求不建議使用。
#### 輸出ngspice netlist
指令:`Netlist > Write SPICE netlist`
<font color=red>**不會提示檔案覆寫**</font>
將目前頁面的內容輸出到working directory中的`<Page Label>.spc`檔案
可以作為基底使用ngspice進行測試
---
## Project內容 - `inverter`
### 要求
1. 繪製`inverter`的schematic及symbol
- [x] schematic和symbol的截圖
- [x] schematic的`.ps`檔
2. 使用ngspice測試你繪製的`inverter`是否功能正確並測量反應時間(slew rate, propagation delay)
- [x] 測試用的`.sp`檔
- [x] 反應時間的測量結果
- [x] 測試模擬的波形(截圖)
3. 把schematic檔案(`.ps`)和測試用的netlist檔案(`.sp`/`.spc`)打包成`.tgz`檔上傳
---
### schematic繪製
完成品的schematic參考圖

需要畫出來的有pMOS和nMOS以及對外連接的pin和wire
概略畫法請參照project的簡報
:::info
此圖為`File > Export > Export SVG`產生後自行調整使其可以顯示所有文字的結果
此做法比較麻煩,建議改為截圖`xcircuit`中的畫面(如下圖)
:::spoiler 範例

:::
:::danger
## 注意事項
- 繪製過程中的pMOS及nMOS請從`AnalogLib`這個library中選擇,不要使用`Generic`中的symbol
- 本project中的pMOS及nMOS需要調整參數,選擇對應電晶體後按`Ctrl+p`即可修改:
|電晶體種類|`width`(`W`)|`length`(`L`)|
|---|---|---|
|`pMOS`|`0.44u`|`0.18u`|
|`nMOS`|`0.22u`|`0.18u`|
- wire的機制 ==此為觀察歸納的結果,官方文件[^xcircuit-internals]中`Netlist Generation`部分也有提到一些==:
- 預設每條wire所對應的連接點只會計算起點和終點,轉折點不計
- 如果有其他物件(包含wire)的pin(連接點)接觸到wire中任意一點,該點也將視為連接點
舉例來說,以下幾組圖分別代表的意義等價 (不同顏色代表不同wire)
-  等價於 
原因:wire起點/終點接觸到其他wire
-  等價於 
原因:Vdd的pin接觸到wire
-  等價於 
原因:兩條wire的起點和終點沒有接觸
-  等價於 
原因:dot的pin就是它自己
- 結論:**繪製時建議每條wire都一次畫完,且需要共點的地方都放上dot**
:::
在繪製完schematic後
<font color=red size=7>**記得先存檔**</font>
<font size=5 color=brown>**且建議檔名和頁面名稱額外加上其他字(如`_schematic`)
以免後續操作意外覆寫掉你的schematic**</font>
---
### 建立symbol
存完檔後下一步就是把畫好的schematic跟對應symbol(`invert`)做關聯
操作步驟(請搭配project簡報服用):
1. 打開symbol library的`Generic`頁面
2. 將滑鼠游標指向到你要綁定的symbol(`invert`)後,按`Shift+.`(`>`)
3. 把pin的名稱修改成和schematic對應pin的名稱相同,如下圖

4. 執行`Netlist > Associate with Schematic`後選擇剛剛畫的schematic
5. 執行`Window > Goto Page > Page 2`切換到另一頁
6. 繪製剛剛綁定的symbol,並設定IO pin的名稱
7. <font size=5 color=red>**修改檔案和頁面名稱使其符合你的symbol名稱**</font>
8. 執行`Netlist > Write SPICE netlist`輸出netlist
:::warning
會需要建立symbol的原因是`xcircuit`在輸出netlist時會以目前繪製的**狀態**輸出
下圖是直接輸出schematic的netlist,可以看到所有部件都平鋪在global scope內

下圖則是建立symbol後以symbol的形式輸出的netlist,可以看到有一個`.subckt`(subcircuit)把schematic中的內容包起來,這種形式才能在後續layout時使用

關於subcircuit的說明可以參照nspice文件
:::
> [!Note]Symbol和輸出netlist中subcircuit的關聯
> 先前在關聯symbol時有設定symbol中的pin名稱和schematic中的pin名稱一致
> 原因是xcircuit在輸出netlist時雖然會修正pin的命名,但若設定不同會出現如下圖的warning
> 
---
### schematic電路模擬
輸出完netlist後
<font color=red size=6>**請先複製一份備份**</font>
備份完可以按照project簡報修改netlist,參考如下圖

其中新增和修改的block:
- `.global vdd`可以讓global scope的`vdd`節點也能被subcircuit接觸
`Vin`為你的input訊號,有關`pulse`的資訊請參閱ngspice文件
==在實作NAND/NOR時會需要多個input==
```=2
.global vdd
Vdd vdd 0 3.3
Vin in 0 pulse(0.0 3.3 0.0 1n 1n 8n 20n)
C1 out 0 15f
```
- 把`agnd`和`avdd`改為`gnd`和`vdd`
```=10
M1 out in GND gnd nfet w=0.22u l=0.18u m=1
M2 out in Vdd vdd pfet W=0.44u L=0.18u M=1
```
- 設定`nfet`和`pfet`的模型
```=14
.model nfet nmos level=49 version=3.3.0
.model pfet pmos level=49 version=3.3.0
```
- 執行模擬和測量
```=19
.control
tran 100p 40n
meas tran t_rise
+TRIG v(out) VAL=0.33 RISE=1
+TARG v(out) VAL=2.97 RISE=1
meas tran t_fall
+TRIG v(out) VAL=2.97 FALL=1
+TARG v(out) VAL=0.33 FALL=1
meas tran t_propagation_r
+TRIG v(in) VAL=1.65 FALL=1
+TARG v(out) VAL=1.65 RISE=1
meas tran t_propagation_f
+TRIG v(in) VAL=1.65 RISE=1
+TARG v(out) VAL=1.65 FALL=1
plot v(in) v(out)
.endc
```
> [!Tip] Control block
> - 使用`.control`開始,`.endc`結束
> - 在control block中的指令**不需要**在前面加上`.`
> - 使用interactive mode(執行`ngspice <檔名>`)時,block內的指令會**自動**執行
> - 詳細內容也請參閱ngspice文件
> [!Important] `propagation delay`的測量
> `propagation delay`是指在對應input變化和output變化之間的時間差
> 以`inverter`來說,因為input只有一個且變化邏輯簡單,選擇測量的時間點也會比較簡單
> 而當有多input時,可以先觀察波形圖來找出哪些地方可以作為測量的時間點
Front-End Design的內容大致就是這樣
打包的部分請自行解決
---
# Layout Design (Back-End)
## 安裝及設置`klayout`
安裝klayout有三種方法:
1. 使用package manager下載安裝
2. 從[官網](https://www.klayout.de/build.html)下載封包後自己安裝
==請先確認網站上有符合自己linux版本的下載連結再使用此方法==
==版本不合會有極高的機率安裝失敗==
3. clone repo下來自己build、安裝
### 下載封裝並安裝
到官網下載完封包後可以使用`sudo apt install ./klayout_*.deb`安裝
版本不合可能會出現下圖的情況 (運行系統是`Ubuntu 24.04`但封包的最高版本只有到`Ubuntu 22.04`)

原因是新版Ubuntu移除了舊版本package的reference,而有些package的名稱會包含版本序號,所以會出現找不到一些dependency的狀況
同理,比較舊的系統看不到比較新的package,也有可能會找不到部分dependency
或是可以使用`sudo dpkg install ./klayout_*.deb`後再執行`sudo apt install --fix-broken`
:::info
若使用fish或其他shell時,wildcard(`*`)可能會被shell先判定使用掉而不被apt接收,這種情況只要escape它(在前面加`\`)就好
:::
---
### `klayout`建置及安裝步驟
1. 安裝建置需要的套件(==取決於系統版本,[官方文件](https://www.klayout.de/build.html)有詳細寫==)
`sudo apt install build-essential qtbase5-dev qttools5-dev libqt5xmlpatterns5-dev qtmultimedia5-dev libqt5multimediawidgets5 libqt5svg5-dev ruby ruby-dev python3 python3-dev libz-dev libgit2-dev`
2. clone repo (因為klayout的repo有一點大,所以使用`--depth=1`選項來只clone最新的版本)
`git clone --depth=1 https://github.com/KLayout/klayout.git`
3. 開始build (可能會很久... ||這次大概兩個半小時,電腦好一點應該會比較快||)
```bash=
cd klayout
sudo ./build.sh -bin /usr/lib/klayout
```
4. 建立執行script
```sh=
echo '#!/bin/sh' >> run_klayout.sh
echo LD_LIBRARY_PATH=/usr/lib/klayout exec /usr/lib/klayout/klayout '"$@"' >> run_klayout.sh
sudo mv run_klayout.sh /usr/bin/klayout
sudo chmod 755 /usr/bin/klayout
```
安裝完成後就可以用`klayout`打開了
預設是檢視模式,不能編輯檔案
可以使用`klayout -e`以編輯模式打開
---
### 設置`klayout`
接下來就是要安裝助教提供的`Free-PDK45`設定檔
```shell=
tar zxvf FreePDK45.tgz
mkdir -p ~/.klayout/tech/
mv FreePDK45 ~/.klayout/tech/
```
:::info
`~`代表目前登入使用者的home directory,會展開為`/home/<username>`, `<username>`為使用者名稱,可以使用`whoami`來確認目前登入使用者的名稱
:::
完成後請確認`~/.klayout/tech/FreePDK45`的內容符合下圖

==**不符合有可能會導致klayout抓不到設定檔**==
排除方法:
1. 如果只有`FreePDK45/`的話,那代表剛剛額外多放了一層,把`FreePDK45/`內的資料搬出來就好
2. 如果出現`No such file or directory`,可能是安裝到其他地方或是少裝到一層;
3. 如果`~/.klayout/tech`裡面有檔案的話,在那邊建立`FreePDK45`路徑後把這些檔案搬到裡面就好
4. 假設上述情況都不成立的話,可以嘗試把`~`改成`$HOME`或是手動展開`~`
裝完設定檔後可以打開klayout並點開`File > New Layout`後檢查`Technology`選單中有沒有出現`FreePDK45 - Free PDK 45nm`選項
有出現的話那恭喜你,你完成了klayout的環境設置。
沒有請回去檢查設定檔是否安裝正確,若仍無法解決請重新安裝klayout。
---
## klayout功能簡介
剛開起來的畫面應該會是這樣,很空

可以先新開一個layout
`File > New Layout`

- `Technology`代表這份layout所使用的++技術++[^layout-technology]
這邊選`FreePDK45`就好,也就是剛剛安裝的設定集
- `Top cell`是這份layout的++最上層單元++的名稱
==因為這份project不會需要用到複雜的結構,可以先視為layout的名稱==
- `Database unit`代表這份layout所使用的`Grid`單位,後續會再詳細說明
:::info
你可以使用`File > Reader Options`來決定新增/開啟layout時預設要使用的技術設定
:::
開完新layout後應該會有類似下圖的畫面

主要可以切割成幾塊區域:
- 最上面包含功能表列和工具欄
- 功能表列
- 預設快捷鍵都會顯示在功能表的選項中
如果要調整或額外綁定快捷鍵可以到`File > Setup`中的
`Application > Customize Menu`設定
- 工具欄 (如未提示,默認為滑鼠左鍵點擊一下)
- `Select`- 選擇物件
左鍵選擇一個,Shift左鍵可以多選,左鍵按住可以框選物件(需完整包含)
選擇物件後連續點兩下(或按`Q`鍵)可編輯物件的屬性
- `Move` - 移動物件
左鍵選取,再一次為放置
- `Ruler` - 測量工具,下拉式選單可以切換種類
- `Add` - 繪製模式
- `Add` - 直接繪製新物件
- `Merge` - 與接觸到的物件合併
- `Erase` - 從接觸到的物件上移除與繪製形狀重疊的部分
- `Mask` - 僅保留接觸到的物件和繪製形狀的交集
- `Diff` - 僅保留接觸到的物件和繪製形狀的差集
- `Polygon` - 繪製多邊形
左鍵建立新的點,連續兩下結束繪製
- `Box` - 繪製矩形
左鍵選擇一個corner,再一下完成繪製
- `Text` - 繪製文字
需要先設定文字內容(在左下`Editor Options`內的`Text`中),再點擊左鍵放置
- `Path` - 繪製多點路徑並以固定半徑填充
左鍵建立新的點,連續兩下結束繪製
可在左下`Editor Options`中的`Path`設定填充半徑
- `Partial` - 移動已存在物件的點或邊
左鍵選取,再一次放置
- 左邊包含:
- `Cells` - 列出layout中所有單元及hierarchy
- `Libraries` - ==本project中不會使用,請先忽略==
- `Editor Options` - 在選擇繪製工具(`Polygon, Box, Text, Path`等)會顯示或按`F3`打開
用來設定幾乎所有編輯動作的行為(`Basic Editing`)和繪製物件的參數
其中`Basic Editing`中常用的設定:
- `Snapping`
- `Grid` - 所有編輯動作(包含繪製和移動)和貼齊網格的最小間隔單位
選單中的選項
- `No grid` - 不限制最小間隔單位、不使用貼齊網格
- `Global grid`- 使用預設的間隔單位(`1nm`)
- `Custom grid ...` - 選擇後會解鎖右邊的欄位
和先前在新增layout畫面中提到的`Database unit`是同一個設定
- `Objects` - 和物件互動的設定
- `Snap to other objects` - 繪製時是否要貼齊其他物件(點、邊)
- `Snap to grid while moving` - 移動時是否要嘗試讓物件的邊貼齊網格
==沒有勾選的情況下,移動物件會依照最小間隔單位計算目的位置==
-> 假設物件A本身沒有和網格貼齊,移動後仍不會和網格貼齊
反之,有勾選則會嘗試將物件A的邊與網格貼齊
- `Angle Constraints` - 部分工具作用時的角度限制
- `Connections` - 作用於作畫機制為兩點連線的工具(`Polygon`、`Path`)
- `Any angle` - 無限制轉角大小
- `Diagonal` - 只能水平、垂直、對角線方向連線
- `Manhattan` - 只能水平、垂直方向連線
- `Movements` - 作用於移動工具
- `Any direction` - 無限制移動方向
- `Diagonal` - 只能水平、垂直、對角線方向移動
- `Manhattan` - 只能水平、垂直方向移動
:::info
按住Ctrl等同於使用Diagonal constraint
按住Shift等同於使用Manhattan constraint
:::
- 中間為主要作畫區域
- 使用滑鼠滾輪可以縮放畫面,按住Shift或Ctrl則分別改為畫面垂直移動和畫面水平移動
- 滑鼠右鍵框選會將畫面移動並縮放到可以完整顯示框選範圍 (類似其他繪圖軟體的放大鏡框選)
- `F2`可以將畫面縮放至符合整個layout大小
- 右邊則包含layer的相關功能
- `Layers` - 列出所有可以繪製的layer
- 按一下選擇layer,連續兩下可顯示/隱藏該layer
- 右鍵會出現更多選項,可以自己試玩看看
- `Layer Toolbox` - layer的顯示設定
- 最下面的狀態列
- `T` - 目前使用的技術設定
- `G` - 顯示目前繪製/移動/選擇/指向物件的狀態,大致上會有以下可能性
- `lx`, `ly`, [`l`] - 目前繪製形狀的邊長或點之間的x, y距離
`l`僅在使用包含點操作的工具(測量工具、`Polygon`、`Path`等)時出現,表示點之間的直線距離
- `dx`, `dy`, [`d`] - 目前移動物件與初始位置的差異
`d`僅在使用`Partial`時出現,表示物件的形變量值
- `x`, `y` - 目前繪製物件在grid上的位置
目前僅觀察到繪製文字時出現
- [`selected:`] \~(~) on... - 目前選擇或滑鼠游標指向物件的資訊
- `xy` - 目前滑鼠游標指向的位置
:::info
## 繪製時的注意事項及個人使用建議
- <font color=red>**繪製物件前需要先選擇layer,也請注意繪製時選擇的layer**</font>
==部分物件(如`Text`)在不同layer所代表的意義不同==
- 可以將`Grid`設定中的最小單位設為`0.01`和把物件貼齊打開,這樣繪製過程中會方便許多
:::
上述如有不理解的部分可以自己動手操作並觀察看看
其他詳細資訊可以參閱[klayout使用手冊](https://www.klayout.de/doc-qt5/manual/index.html)
---
## FreePDK45內容簡介
[官方文件](https://eda.ncsu.edu/freepdk/freepdk45/)
這部分將簡述部分包含在`FreePDK45`中的layer和其他會在project中使用的功能
### Layers
有關各layer的詳細資訊可以參照課程簡報`VLSI`
==以下列出的layer若未註明皆為`<名稱>.drawing`==
|layer名稱|layer代表的東西|
|---|---|
|`pwell`, `newll`|`pwell`和`nwell`層|
|`vtg`, `vth`|標記電晶體的閾值種類,==在本project中只使用`vtg`(general purpose)==<br><font color=red>**繪製時請注意要和`nwell`和`pwell`完全重疊**</font>|
|`pimplant`, `nimplant`|`p+ diffusion`、`n+ diffusion`層|
|`active`|標記有效區域<br><font color=red>**繪製時請注意要和`pimplant`和`nimplant`完全重疊**</font>|
|`poly`|`poly-silicon`層|
|`metal1`|**主metal**層,為cell內部與外界溝通的橋樑|
|`contact`|標記主metal層和`poly`、`pimplant`、`nimplant`層之間的連接口|
|`comment`|標記整個cell的封裝範圍|
|--------------|以下為本project不會使用的layer|
|`metal<n>`|次要的metal層 (不同層代表的意義不同,詳細請參閱官方文件)|
|`via<n>`|標記`metal<n>`和`metal<n+1>`的連接口|
|`thkox`|`Thick Oxide`填充層|
---
### DRC (Design Rule Check)
用來檢查你的layout是否符合`FreePDK45`定義的設計規則 (詳細規則也在官方文件中)
從`Tools > DRC > .../FreePDK45/drc/drc_freepdk45.lydrc`執行
運行完會出現如下圖的視窗

展開後會列出目前layout中不符合設計規則的物件和原因
按照說明修正即可
:::info
**`GRID`類型的錯誤在本project中可以忽略**,只要確保沒有其他錯誤即可
:::
---
### LVS (Layout v.s. Schematic)
這個功能是用來驗證你的layout和你的schematic是否吻合 ==(功能性和部件性質(參數)是否一致)==
由`Tools > LVS > .../FreePDK45/lvs/lvs_freepdk45.lylvs`執行
執行成功的畫面大致如下

:::danger
此功能會把你的layout轉變成SPICE電路(`.cir`檔)並和你提供的schematic(`.sp`檔)比對
==**此功能的所有檔案操作都是在working directory內**==
有一點要注意的是
<font color=red size=5>**當你的layout有一點點小差錯或是提供的schematic格式不對就可能導致LVS失敗**</font>
**詳細資訊和解決方法會在Project內容中細講**
:::
---
## Project內容 - inverter
### 要求
1. 繪製`inverter`的layout
- [x] layout的截圖
- [x] layout的`.gds`檔(`File > Save`,**存檔時記得寫副檔名**)
2. 執行DRC和LVS並確認驗證成功
- [x] 執行DRC和LVS的成功畫面截圖
3. 使用nspice對執行LVS產生的電路進行測試並測量反應時間(slew rate, propagation delay)
- [x] 測試用的netlist檔案(`.cir`/`.sp`)
- [x] 反應時間的測量結果
- [x] 測試模擬的波形(截圖)
4. 把layout檔案(`.gds`)和測試用的netlist檔案(`.sp`/`.cir`)打包成`.tgz`檔上傳
---
### layout繪製
完成品的參考圖

:::info
此圖為按`F2`後使用`File > Screenshot`產生 (會要求存檔位置)
:::
繪製過程可以參照project簡報
:::danger
## 注意事項
- **電晶體架構**
- **由`pimplant`、`nwell`、`poly`組成如下圖的架構為一個`pmos`**

- **由`nimplant`、`pwell`、`poly`組成如下圖的架構為一個`nmos`**

- **其中`poly`<font color=red>必須</font>將一塊`pimplant`或`nimplant`完全分割為`source`塊和`drain`塊,
`poly`則作為電晶體的`gate`
<font color=blue>建議讓`poly`穿過要分割的`pimplant`和`nimplant`,以免出現其他問題</font>**
- 同一個layer上有重疊/接觸的物件會互相連通 (視為同一塊)
- 需要使用`Text`來標記IO的pin,<font color=red>**請注意要繪製在`metal1`層上**</font>
- 物件大小可以在object properties(選取後連續左鍵兩下或按`Q`)中調整
建議使用`Center/Size`頁面來調整,如下圖

- **繪製規範**
- **每個`contact`的大小必須為`65 nm x 65 nm`(`0.065 x 0.065`)**
- <font color=red> **每個`poly`的"寬度"(上圖中的`w`值)需和先前在schematic指定電晶體的`L`值相同**</font>
- <font color=red>**每個`pimplant`和`nimplant`的"高度"(上圖中的`h`值)需與先前在schematic裡指定對應電晶體的`W`值相同**</font>
- <font color=red>**請記得為你的`pwell`及`nwell`畫上`vtg`並確保有完全重疊**
雖然實際上只需要覆蓋到包含電晶體的部分,但安全起見,建議還是完全重疊</font>
- <font color=red>**再次提醒,`acitve`區域要和`pimplant`區域與`nimplant`區域完全重疊**
你也可以讓`active`範圍超出implant範圍,但不建議</font>
- **上述四點都會影響LVS輸出的電路中電晶體的參數**
- <font color=red>**請記得為你的`well tap`(用於連接well和vdd、gnd的implant)繪製contact和active**</font>
well tap示意圖  從`metal1`經過`contact`連接到`pimplant`和`pwell` (`pimplant`和`pwell`因互為同材質,所以互相導通)
:::
---
### DRC和LVS
DRC的操作步驟前面就有提過了,這邊就不贅述
完成DRC後就可以進到這份project中的重頭戲,<font size=6 class=rainbow-text>**_LVS_**</font>,也是許多人難以跨越的"牆"
在開始進行LVS之前,請先執行以下動作
1. 複製一份前個project輸出的`.spc`檔案到目前的working directory內並將副檔名改為`.sp`
2. 確認檔名和目前layout的`top cell`名稱一致
要修改cell的名稱,在cells中對要改名的cell右鍵就可以找到選項修改
名字隨意,但建議與目前layout內容相關,如`invert`
3. 打開第一步的`.sp`檔並把
- [x] 第一行的`<`和`>`去掉 (你也可以整行刪掉)
- [x] 確保`.subckt`和`X1`的subcircuit名稱和`top cell`名稱一致
- [x] `agnd`和`avdd`分別改成`gnd`和`vdd`,
- [x] `nfet`與`pfet`分別改成`NMOS_VTG`與`PMOS_VTG`
- 如下圖

:::info
這邊稍微講一下`vtg`和`active`層與LVS輸出電晶體的關係
- `vtg`在前面提到是用來標記電晶體的閾值種類,如果沒有繪製標記的話預設會是判定為low threshold(`vtl`),如下圖

- `active`就有趣一點了,它控制的是implant的有效範圍,假設今天你的active沒有完全覆蓋implant的話,它就可能會影響到輸出電晶體的W值
如下圖我讓active的高度比implant小一點

則輸出的電晶體的W值就會受到影響跟著變小

LVS是拿layout輸出的電路與schematic做比對,而參數不同的電晶體會被視作不同種的電晶體,因而導致比對失敗 (==schematic中沒有指定的參數不會被比對==)
:::
前置作業做完後你就可以滿懷期待得按下那顆神聖的按鈕並祈禱~~不會WA~~它通過驗證
不論成功與否,LVS都會在working directory生出名為`<top cell名稱>_extracted.cir`的檔案,內容是你的layout所代表的電路
如果驗證失敗,建議先打開LVS生的檔案和你的schematic的電路比對,通常很快就會看出原因
還是不能解決的話請開新檔案重搓
---
### layout電路模擬
完成LVS之後就是模擬layout電路的時間了
要做的操作基本上和Front-End Design做的差不多,但這邊不會使用`.global vdd`,
而是要把`vdd`和`gnd`帶入subcircuit的參數(`X1`那行),如下二圖


因為要做的動作一樣,這邊就不細講
Back-End Design的部分在這邊告一段落
<font size=6 color=red>**記得要打包**</font>
# Appendix
## diffusion sharing
考慮下圖的schematic:

如果將不同電晶體獨立繪製出來可能會有類似下圖的結構:

可以看到腳位`b`所在的metal會讓兩顆電晶體的一部分implant連通
而實際上可以將那兩塊implant在同一層連通再把那塊用metal接出來,如下圖:

這種做法叫做 ==`diffusion sharing`==,可以有效減少材料消耗及layout整體大小
若腳位`b`不需要的話也可以再縮減那部分implant的大小:

<style>
.rainbow-text {
background: linear-gradient(to left, indigo, purple, blue, dodgerblue, green, orange, red);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
[^layout-technology]: [Klayout Technology Management](https://www.klayout.de/doc-qt5/about/technology_manager.html)
[^xcircuit-internals]: [XCircuit internal structures](http://opencircuitdesign.com/xcircuit/internals/internals.html)