[討論] HW#6 建議攻略
[防雷頁]
如果你還是想要一切 DIY,其實你可以按個左鍵跳出去,
底下是給真的沒有頭緒的人參考用的。
1. 當然還是要先把 spec 看過,這點無論如何都不能省!!!
2. 如果你對 AIGER (.aag) format 還不熟悉,
請把講義看一下,或是多看一些例子,或是看一下官網的完整 document.
3. 第一個動手做的當然是 parser.
如果你有寫過 parser, 那你可以跳過這一步,
但如果你沒有寫過 parser (parser = 把一個文字檔讀近來轉成某種資料結構),
那建議你先不要管 "class CirGate",
先完成負責讀檔的 "CirMgr::readCircuit(const string& fileName)" 就好。
至少在這邊寫一點東西之後 "CIRRead" 這個 command 就有作用了!
至於在 readCircuit 裏頭,你可以先寫的,就是 "token parser",
也就是說,讓你的 readCircuit 在讀進 .aag 檔之後,
可以在螢幕上輸出: // 以 ok01.aag 為例
*---------------
aag - aag (1, 1) <== (#line, #column)
7 - M (1, 5)
2 - I (1, 7)
0 - L (1, 9)
3 - O (1, 11)
3 - A (1, 13)
2 - PI 1 (2, 1)
4 - PI 2 (3, 1)
6 - PO 3 (4, 1)
12 - PO 6 (5, 1)
1 - PO !0 (6, 1)
6 13 15 - aig 3 !6 !7 (7, 1)
12 2 4 - aig 6 1 2 (8, 1)
14 3 5 - aig 7 !1 !2 (9, 1)
i0 (10, 1)
x (10, 4)
i1 (11, 1)
y (11, 4)
o0 (12, 1)
s (12, 4)
o1 (13, 1)
c (13, 4)
c (14, 1)
I don't care about comment.
[註] 建議 symbol 部分先不要管它,等到 CirGate 定義好再說。
當然建議你分成一些 (private) member function 來以上如果實現以上的 parsing。
做好了之後,你就已經可以把原來的電路檔的 token 順利的 parse 出來了,
接下來就是如何把他們存到 circuit 裡面。
4. Parse 電路描述檔到 circuit 資料結構上去,有一些事情是一定要做,
另外有一些事情是要先決定的。
* 在 class CirMgr 裏頭一定要有 container 來存 PIs, POs,
以及 DFS 之後所有的 gates list, 而且要知道 sizes.
* 在 parse 的時候,會有需要從 ID 去找 gate pointer,
你要怎麼設計?
(Note: ID := [1, M]; ID = 0 is the constant 0)
* 原始檔案的 M I L O 的值要記錄起來,因為 CIRWrite 會用到。
* 大概會有幾種 gate types: PI, PO, AIG, Const, Undef (<== optional)
你要用 enum CirGateType, 還是要用 inheritence?
以這個作業來說,倒也沒有誰好誰壞,但你現在一定要先做一個決定!!
(大不了以後再改,應該還好)
* 在 class CirGate (或是它的 inherited classes) 裏頭,
一定要有 containers/data members 去存 fanins, 或是 fanouts.
* 在 class CirGate (或是它的 inherited classes) 裏頭,
也一定要有 data members 去紀錄 gate IDs 以及 #line, #column,
* 在 traversal 時一定會需要 "setMark()",參考一下講義想想你要怎麼做。
根據以上的提示,先把基本款的 class CirMgr 以及 CirGate 定義好,
接下來你就準備好可以跟 readCircuit() hook 再一起囉!!
5. Tokens 已經 parse 好,class CirMgr & CirGate 也已經定義好,
接下來就可以建電路囉!!
注意!! 上課有說,由於 AIGER format 裏頭一個 AIG gate 的 fanin 可以用
在後面才會定義到的 gate,
所以你其實無法一邊 construct gates (nodes), 一邊建 connections (edges).
這一步先來建 gates.
要建 gates 簡單,就在你前面 parse 出 token 的地方,new 出相對應的 gates.
比方說,遇到 PI 就 new 一個 PI, 遇到 AIG 就建個 AIG gate.
不過要記得順便把 PI, PO 等 list 順便建起來。
其他要考慮的事情還有:
* ID --> gate pointer 的對應
* AIG 的 fanins 要怎麼記起來? 還是等一下 rewind ifstream 再讀檔一次?
* constant 0 gate 怎麼來?
* PO gate 的 ID 要注意一下 (請見作業說明檔)
好了,到這邊為止你已經把所有的 gates 都建好了,為了確定你有建好,
你可以 cout 一些 information, 或是把 PI, PO, AIG gate 的個數印出來。
6. 接下來是建 connections.
如上所述,看你有沒有在 parse AIG gate 時就把 fanin 的 ID 記起來,
還是你選擇 rewind 後再讀檔一遍,都可以。
建 connection 很簡單,就是對每一個 AIG gates 把它的 fanins 存起來,
然後再到每一個 fanin 把這個 AIG gate 存到它的 fanout 去。
最後記得要把 PO 的 fanin 也建起來,
當然, PO 的 fanin也要把 PO 加到它的 fanout 去。
7. 接下來是建 DFS list,這點請參考講義。
簡單的說,就是從 POs 開始去做 post-order traversal.
8. 完成 CirMgr 中的 printSummary(), printNetlist(), printPIs(), printPOs().
至於 printFloatGates() 你可以先不用管。
當然,cirGate 的 printGate() 可能也要寫一下。
到這裡,你應該就可以完成:
* CIRRead (without -replace)
* CIRPring (without -FLoating)
先休息一下吧! 天氣那麼好...
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.36.59.117
※ 編輯: ric2k1 來自: 114.36.59.117 (12/15 01:06)
推
12/15 01:08, , 1F
12/15 01:08, 1F
→
12/15 01:13, , 2F
12/15 01:13, 2F
→
12/15 01:13, , 3F
12/15 01:13, 3F
推
12/15 02:00, , 4F
12/15 02:00, 4F
推
12/15 02:14, , 5F
12/15 02:14, 5F
推
12/15 02:20, , 6F
12/15 02:20, 6F
推
12/15 11:18, , 7F
12/15 11:18, 7F
推
12/15 13:52, , 8F
12/15 13:52, 8F
推
12/15 20:02, , 9F
12/15 20:02, 9F
推
12/15 21:32, , 10F
12/15 21:32, 10F
推
12/15 23:44, , 11F
12/15 23:44, 11F
→
12/16 01:40, , 12F
12/16 01:40, 12F
→
12/16 01:41, , 13F
12/16 01:41, 13F
→
12/16 01:41, , 14F
12/16 01:41, 14F
推
12/16 09:21, , 15F
12/16 09:21, 15F
推
12/16 20:35, , 16F
12/16 20:35, 16F
推
12/17 16:17, , 17F
12/17 16:17, 17F
推
12/17 17:29, , 18F
12/17 17:29, 18F
推
12/17 18:23, , 19F
12/17 18:23, 19F
推
12/17 21:36, , 20F
12/17 21:36, 20F
→
12/17 22:00, , 21F
12/17 22:00, 21F
→
12/17 22:01, , 22F
12/17 22:01, 22F
→
12/17 22:02, , 23F
12/17 22:02, 23F
推
12/20 01:21, , 24F
12/20 01:21, 24F
推
12/10 10:13,
5年前
, 25F
12/10 10:13, 25F