目前已基本實現函數和結構體的面向對象化。node
對象:以數電模塊爲單位(應該)網絡
內部成員:線路,邏輯門,鏈接關係。以及虛擬化的輸入端(調試用)。框架
方法:函數
一.基本操做:測試
typedef _line* line; #define line_create(lptr) do { \ _line_create(&lptr); \ } while(0) main() { line l; line_create(l);
(...) }
其中:
typedef struct _LINE {
(...)
} _line; #define MAXN 50000 _line _line__ALLOC_SPACE[MAXN]; _line* LAS_ptr = _line__ALLOC_SPACE; //initial is first address void _line_create(_line **ptr_addr) { //_line's pointer's address *ptr_addr = ++LAS_ptr;
(...)
}
效果:申請從內存池中分配一個線路,將指針返回給封裝好的line類型。優化
typedef _logic_gate* gate; #define gate_create(gptr, value) do { \ _logic_gate_create(&gptr, value); \ } while(0) main() { gate g; gate_create(g, n);
(...) } //n = 1: and gate n = 2: or gate n = 3: not gate
其中:ui
typedef struct _LOGIC_GATE { char gate; //and = 1 or = 2 not = 3 (...) } _logic_gate; _logic_gate _logic_gate__ALLOC_SPACE[MAXN]; _logic_gate* LGAS_ptr = _logic_gate__ALLOC_SPACE; void _logic_gate_create(_logic_gate **ptr_addr, char value) { *ptr_addr = ++LGAS_ptr; (**ptr_addr).gate = value; (...) }
效果:申請從內存池中分配一個邏輯門,將指針返回給封裝好的gate類型。this
#define ATT_NULL 0 #define PIN -1 typedef struct _LINE { (...) BOOL level; //electric level char attach_name; //-1:pin 0:ATT_NULL >0:logic_gate's name(1,2,3....) (...) } _line; BOOL _pin_attach(_line *line_ptr, BOOL pin_value) { (...) (*line_ptr).attach_name = PIN; (*line_ptr).level = pin_value; (...) } #define pin_attach(lptr, value) do { \ _pin_attach(lptr, value); \ } while(0) main() { line l; line_create(l); pin_attach(l, BOOL_VALUE);
(...) }
效果:l被標記成爲鏈接輸入端的線路,並被持續性地賦值爲BOOL_VALUE(TRUE或者FALSE)spa
#define attin(gptr, inptr) do { \ _logic_gate_income_attach(gptr, inptr); \ } while(0) #define attout(gptr, outptr) do { \ _logic_gate_outcome_attach(gptr, outptr); \ } while(0) main() { line l1, l2, l3; gate g; (...) attin(g, l1); attin(g, l2); attout(g, l3); (...) }
其中:3d
typedef struct _LINE { (...) struct _LOGIC_GATE_LIST* list_head; (...) } _line; typedef struct _LOGIC_GATE { (...) struct _LINE *outcome_ptr; (...) } _logic_gate; typedef struct _LOGIC_GATE_LIST { struct _LOGIC_GATE* gate_ptr; struct _LOGIC_GATE_LIST* next; } _logic_gate_list;
_logic_gate_list _logic_gate_list__ALLOC_SPACE[MAXN]; _logic_gate_list *LGLAS_ptr = _logic_gate_list__ALLOC_SPACE;
BOOL _logic_gate_income_attach(_logic_gate *gate_ptr, _line *income_ptr) { LGLAS_ptr++; //allocate new node into the list table "line's logic_gates" (*LGLAS_ptr).gate_ptr = gate_ptr; (*LGLAS_ptr).next = (*income_ptr).list_head; (*income_ptr).list_head = LGLAS_ptr; (...) //income_ptr's list <- gate_ptr } BOOL _logic_gate_outcome_attach(_logic_gate *gate_ptr, _line *outcome_ptr) { (*gate_ptr).outcome_ptr = outcome_ptr; (...) }
#define line_merge(lmge, lmged) do { \ _line_merge(&lmge, &lmged); \ } while(0) main() { l l1, l2; (...) line_merge(l1, l2); (...) }
其中:
typedef struct _LINE { (...) BOOL remove; //be removed or not? (...) } _line; void _line_free(_line **ptr_addr) { (**ptr_addr).remove = TRUE; //in this case, a space in LAS[] will be wasted, but it worthed } BOOL _line_merge(_line **lineA_ptr_addr, _line **lineB_ptr_addr) { //merge lineB's logic gates into lineA P.S: maybe a gate will connect to a line twice. _logic_gate_list* list_ptr = (**lineB_ptr_addr).list_head; while(list_ptr != GATE_NULL) { _logic_gate_income_attach((*list_ptr).gate_ptr, *lineA_ptr_addr); list_ptr = (*list_ptr).next; //get next logic_gate } _line_free(lineB_ptr_addr); //delete (*lineB_ptr_addr) = (*lineA_ptr_addr); (...) }
注意:
struct _LOGIC_GATE_LIST* GATE_NULL = (struct _LOGIC_GATE_LIST*)987654321; void _line_create(_line **ptr_addr) { //_line's pointer's address (...) (**ptr_addr).list_head = GATE_NULL; //logic_gate_list' head points to GATE_NULL (...) }
從而這樣就能夠實現靜態鏈表結構。
模塊計算:
void CST() { //Circut_state_transition _line now_line; _logic_gate now_gate; _logic_gate_list* list_ptr; //enumerate all the lines and logic_gates while(!LPS.empty()) { now_line = LPS.pop() //last period's lines list_ptr = now_line.list_head; while(list_ptr != GATE_NULL) { now_gate = *(*list_ptr).gate_ptr; //get now_gate's informations (...) LGPS.push(now_gate) //add this logic_gate into logic_gate stack (...) list_ptr = (*list_ptr).next; //get next logic_gate } } (...) //calcaulate logic_gates in logic_gate stack, answers stored in logic_gate_outcome_update_level //update LPS[]: LPS_clear(); while(!LGPS.empty()) { now_gate = LGPS.pop(); (...) if((*now_gate.outcome_ptr).level != _logic_gate_outcome_update_level) { (*(now_gate.outcome_ptr)).level = _logic_gate_outcome_update_level; LPS_push(now_gate.outcome_ptr); } (...) } }
inline void pin_update(line lpin, BOOL value) { //still pin, no need to change name's value if(value != (*lpin).level) { (*lpin).level = value; LPS_push(lpin); //in many situation, this operation will wake-up this circut. } }
二.進階操做:
我在VM_basis++.h中封裝了一些經常使用函數,這裏列出函數的聲明以及用法:
#define and_create(gptr, inptr1, inptr2, outptr) do { \ (...) \ } while(0) #define or_create(gptr, inptr1, inptr2, outptr) do { \ (...) \ } while(0) #define not_create(gptr, inptr, outptr) do { \ (...) \ } while(0) #define line_array_create(array) do { \ (...) \ } while(0) void pins_attach(int argn, ...) { (...) } main() { line L[12]; gate og, ag, ng; line_array_create(L); /****************************************************** for(int i = 1; i < sizeof(L)/sizeof(line); i++) line_create(L[i]); ******************************************************/ and_create(ag, L[1], L[3], L[5]); /****************************************************** gate_create(ag, 1); attin(ag, L[1]); attin(ag, L[3]); attout(ag, L[5]); ******************************************************/ or_create(og, L[2], L[4], L[6]); not_create(ng, L[7], L[8]); pins_attach(3, L[9], FALSE, L[10], FALSE, L[11], TRUE); /****************************************************** pin_attach(L[9], FALSE); pin_attach(L[10], FALSE); pin_attach(L[11], TRUE); ******************************************************/ (...) }
三.禁忌&注意事項:
爲了提升程序魯棒性,我在VM_basis++.h中加了一些防爆措施:
若是檢測到有以上錯誤,程序會報錯,並指出錯誤類型。
另外還有以下一些不建議使用的方法:
若是檢測到有以上操做,程序會警告,並指出不建議的類型。
另外還存在這樣的一些錯誤,程序能夠運行,可是電路可能紊亂。例如:存在環形脈衝電路。這須要開發者本身意識到這些錯誤。
此外VM_basis++.h中還提供了開發者選項:
/******* developer options *******/ #define CANCEL_SUCCESS() SHOW_SUCCESS = FALSE void SHOW_CIRCUT() { printf("=============== SHOW CIRCUT ===============\n"); _line* _line_iterator = _line__ALLOC_SPACE+1; _logic_gate* _gate_iterator = _logic_gate__ALLOC_SPACE+1; while(_line_iterator <= LAS_ptr) { if((*_line_iterator).remove == FALSE) printf("Line: Name:%d Level:%d\n", (*_line_iterator).name, (*_line_iterator).level); _line_iterator++; } printf("===============================================\n\n"); }
能夠在外部調用CANCEL_SUCCESS()函數來取消創建成功提示。
經過SHOW_CIRCUT()函數,能夠打印出當前全部線路的值。(其中Name爲線路在內存池的下標,或者能夠理解爲物理層面上真正的線路編號)
四. 具體代碼:(按理說頭文件不該該定義變量。固然也無所謂)
VM_basis.h:
#include <stdio.h> typedef char BOOL; #define TRUE 1 #define FALSE 0 #define PIN -1 #define ATT_NULL 0 struct _LINE; struct _LOGIC_GATE; struct _LOGIC_GATE_LIST; typedef struct _LINE { BOOL level; //electric level BOOL remove; //be removed or not? struct _LOGIC_GATE_LIST* list_head; int name; //convenience && acculation char attach_name; //-1:pin 0:ATT_NULL >0:logic_gate's name(1,2,3....) } _line; typedef struct _LOGIC_GATE { char gate; //and or not struct _LINE *incomeA_ptr, *incomeB_ptr, *outcome_ptr; //only allow 2 income argvs int name; } _logic_gate; typedef struct _LOGIC_GATE_LIST { struct _LOGIC_GATE* gate_ptr; struct _LOGIC_GATE_LIST* next; } _logic_gate_list; struct _LINE* LINE_NULL = (struct _LINE*)123456789; struct _LOGIC_GATE_LIST* GATE_NULL = (struct _LOGIC_GATE_LIST*)987654321; /******* circut fundamental structures *******/ #define MAXN 50000 //numbers of lines and logic_gates #define MAXM 50000 //numbers of interactions between lines and logic_gates _line _line__ALLOC_SPACE[MAXN]; _line* LAS_ptr = _line__ALLOC_SPACE; _logic_gate _logic_gate__ALLOC_SPACE[MAXN]; _logic_gate* LGAS_ptr = _logic_gate__ALLOC_SPACE; _logic_gate_list _logic_gate_list__ALLOC_SPACE[MAXN]; _logic_gate_list *LGLAS_ptr = _logic_gate_list__ALLOC_SPACE; //change the units' framework structure void _line_create(_line **ptr_addr) { //_line's pointer's address (*ptr_addr) = ++LAS_ptr; (**ptr_addr).level = FALSE; (**ptr_addr).remove = FALSE; (**ptr_addr).name = LAS_ptr-_line__ALLOC_SPACE; //pointer's sub = (addr's D-value)/sizeof(var) (**ptr_addr).attach_name = ATT_NULL; (**ptr_addr).list_head = GATE_NULL; //logic_gate_list' head points to GATE_NULL } void _line_free(_line **ptr_addr) { (**ptr_addr).remove = TRUE; //in this case, a space in LAS[] will be wasted, but it worthed } void _logic_gate_create(_logic_gate **ptr_addr, char value) { (*ptr_addr) = ++LGAS_ptr; (**ptr_addr).gate = value; (**ptr_addr).name = LGAS_ptr-_logic_gate__ALLOC_SPACE; (**ptr_addr).incomeA_ptr = (**ptr_addr).incomeB_ptr = (**ptr_addr).outcome_ptr = LINE_NULL; } //change the units' interaction structure BOOL _logic_gate_income_attach(_logic_gate *gate_ptr, _line *income_ptr) { //Rule:Only allow 2 incomes when gate is or/and gate; Only allow 1 income when gate is not gate. if((*gate_ptr).incomeB_ptr != LINE_NULL || ((*gate_ptr).incomeA_ptr != LINE_NULL) && (*gate_ptr).gate == 3) return FALSE; //attach fail LGLAS_ptr++; //allocate new node into the list table "line's logic_gates" (*LGLAS_ptr).gate_ptr = gate_ptr; (*LGLAS_ptr).next = (*income_ptr).list_head; (*income_ptr).list_head = LGLAS_ptr; if((*gate_ptr).incomeA_ptr == LINE_NULL) (*gate_ptr).incomeA_ptr = income_ptr; else (*gate_ptr).incomeB_ptr = income_ptr; return TRUE; //attach success } BOOL _logic_gate_outcome_attach(_logic_gate *gate_ptr, _line *outcome_ptr) { if((*outcome_ptr).attach_name != ATT_NULL) return FALSE; //line have been attached, attach fail (*outcome_ptr).attach_name = (*gate_ptr).name; (*gate_ptr).outcome_ptr = outcome_ptr; return TRUE; } BOOL _pin_attach(_line *line_ptr, BOOL pin_value) { if((*line_ptr).attach_name != ATT_NULL) return FALSE; (*line_ptr).attach_name = PIN; (*line_ptr).level = pin_value; return TRUE; } //merge lines, lineA <- lineB, including all the logic gates in B BOOL _line_merge(_line **lineA_ptr_addr, _line **lineB_ptr_addr) { if((**lineB_ptr_addr).attach_name != ATT_NULL) return FALSE; //merge lineB's logic gates into lineA P.S: maybe a gate will connect to a line twice. _logic_gate_list* list_ptr = (**lineB_ptr_addr).list_head; while(list_ptr != GATE_NULL) { _logic_gate_income_attach((*list_ptr).gate_ptr, *lineA_ptr_addr); list_ptr = (*list_ptr).next; //get next logic_gate } _line_free(lineB_ptr_addr); //delete (*lineB_ptr_addr) = (*lineA_ptr_addr); //in fact, pysically _lineA and _lineB are the same _line, so there's no need to update attached return TRUE; } /******* units' states && circut transition *******/ BOOL ACCULATE_OPTIMIZATION_FLAG; _line* _line_ptr_stack[MAXN]; //store ptr, acculate copy operations (equels to store names) _logic_gate* _logic_gate_ptr_stack[MAXN]; //LPS -> LGPS -> next LPS -> ... BOOL _logic_gate_outcome_update_level[MAXN]; int LPS_top, LGPS_top; BOOL _logic_gate_vis[MAXN]; //package _line_ptr_stack && line's value operation #define LPS_push(lptr) _line_ptr_stack[LPS_top++] = lptr #define LPS_clear() LPS_top = 0 void CST() { //Circut_state_transition _line now_line; _logic_gate now_gate; _logic_gate_list* list_ptr; //enumerate all the lines and logic_gates while(LPS_top) { now_line = *(_line_ptr_stack[--LPS_top]); list_ptr = now_line.list_head; while(list_ptr != GATE_NULL) { now_gate = (*(*list_ptr).gate_ptr); //get now_gate's informations if(_logic_gate_vis[now_gate.name] == 0) { //LGV[X] == 0: havn't been visited _logic_gate_ptr_stack[LGPS_top++] = (*list_ptr).gate_ptr; //entry ptr _logic_gate_vis[now_gate.name] = TRUE; //mark, in case of gates repeat entry } list_ptr = (*list_ptr).next; //get next logic_gate } } //calcaulate logic_gates int i; for(i = 0; i <= LGPS_top-1; i++) { now_gate = *(_logic_gate_ptr_stack[i]); if(now_gate.outcome_ptr == LINE_NULL) continue; //Warning: no output. no need to calculate if(now_gate.incomeB_ptr == LINE_NULL && now_gate.gate != 3) { //Warning: default input _logic_gate_outcome_update_level[i] = (*(now_gate.incomeA_ptr)).level; continue; } if(now_gate.gate == 1) { if((*(now_gate.incomeA_ptr)).level == TRUE && ((*now_gate.incomeB_ptr).level) == TRUE) _logic_gate_outcome_update_level[i] = TRUE; else _logic_gate_outcome_update_level[i] = FALSE; } if(now_gate.gate == 2) { if((*(now_gate.incomeA_ptr)).level == FALSE && (*(now_gate.incomeB_ptr)).level == FALSE) _logic_gate_outcome_update_level[i] = FALSE; else _logic_gate_outcome_update_level[i] = TRUE; } if(now_gate.gate == 3) { if((*(now_gate.incomeA_ptr)).level == TRUE) _logic_gate_outcome_update_level[i] = FALSE; else _logic_gate_outcome_update_level[i] = TRUE; } } //update LPS[]: LPS_clear(); while(LGPS_top) { now_gate = *(_logic_gate_ptr_stack[--LGPS_top]); if(now_gate.outcome_ptr == LINE_NULL) continue; //Warning: no output. if(ACCULATE_OPTIMIZATION_FLAG == FALSE || (*now_gate.outcome_ptr).level != _logic_gate_outcome_update_level[LGPS_top]) LPS_push(now_gate.outcome_ptr); (*(now_gate.outcome_ptr)).level = _logic_gate_outcome_update_level[LGPS_top]; _logic_gate_vis[now_gate.name] = FALSE; //reset vis[] } }
VM_basis++.h:
#include "VM_basis.h" #include <stdlib.h> #include <stdarg.h> #include <conio.h> /******* package objects and functions *******/ int ERROR_cnt, WARNING_cnt; //package _line & _logic_gate BOOL SHOW_SUCCESS = TRUE; typedef _line* line; typedef _logic_gate* gate; char chs[10][10] = {"", "Or", "And", "Not", "(TRUE)", "(FALSE)"}; #define line_create(lptr) do { \ _line_create(&lptr); \ if(SHOW_SUCCESS == TRUE) printf("Create Line \""#lptr"\"(Name: %d): Succeed\n", (*lptr).name); \ } while(0) #define gate_create(gptr, value) do { \ _logic_gate_create(&gptr, value); \ if(SHOW_SUCCESS == TRUE) printf("Create %s Gate \""#gptr"\"(Name: %d): Succeed\n", chs[value], (*gptr).name); \ } while(0) #define attin(gptr, inptr) do { \ if(_logic_gate_income_attach(gptr, inptr) == FALSE) { \ printf(">>>ERROR: Line \""#inptr"\" cannot attach to \""#gptr"\"'s input:"); \ printf(" \""#gptr"\"'s input ports is full...\n"); \ ERROR_cnt++; \ } \ else if(SHOW_SUCCESS == TRUE) \ printf("Attach Line \""#inptr"\" to \""#gptr"\"'s input: Succeed\n"); \ } while(0) #define attout(gptr, outptr) do { \ if(_logic_gate_outcome_attach(gptr, outptr) == FALSE) { \ printf(">>>ERROR: Line \""#outptr"\" cannot attach to \""#gptr"\"s output:"); \ printf(" \""#outptr"\"have been attached to another unit...\n"); \ ERROR_cnt++; \ }\ else if(SHOW_SUCCESS == TRUE) \ printf("Attach Line \""#outptr"\" to \""#gptr"\"'s output: Succeed\n"); \ } while(0) #define line_merge(lmge, lmged) do { \ if(_line_merge(&lmge, &lmged) == FALSE) { \ printf(">>>ERROR: Line \""#lmged"\" cannot attach to \""#lmge"\":"); \ printf(" \""#lmged"\"have been attached to another unit...\n"); \ ERROR_cnt++; \ }\ else if(SHOW_SUCCESS == TRUE) \ printf("Attach Line \""#lmged"\" to \""#lmge"\": Succeed\n"); \ } while(0) #define pin_attach(lptr, value) do { \ if(_pin_attach(lptr, value) == FALSE) { \ printf(">>>ERROR: Line \""#lptr"\" cannot attach to pin%s", chs[4]); \ printf(": \""#lptr"\" have been attached to another unit...\n"); \ ERROR_cnt++; \ }\ else if(SHOW_SUCCESS == TRUE) \ printf("Attach Line \""#lptr"\" to pin%s: Succeed\n", chs[5]); \ } while(0) //package gate operation #define and_create(gptr, inptr1, inptr2, outptr) do { \ gate_create(gptr, 1); \ attin(gptr, inptr1); \ attin(gptr, inptr2); \ attout(gptr, outptr); \ } while(0) #define or_create(gptr, inptr1, inptr2, outptr) do { \ gate_create(gptr, 2); \ attin(gptr, inptr1); \ attin(gptr, inptr2); \ attout(gptr, outptr); \ } while(0) #define not_create(gptr, inptr, outptr) do { \ gate_create(gptr, 3); \ attin(gptr, inptr); \ attout(gptr, outptr); \ } while(0) //Build lines in a quick way #define line_array_create(array) do { \ BOOL flag_reg = SHOW_SUCCESS; \ SHOW_SUCCESS = FALSE; \ int i, siz = sizeof(array)/sizeof(line); \ for(i = 1; i < siz; i++) { \ line_create(array[i]); \ if(flag_reg == TRUE) \ printf("Create Line \""#array"[%d]\"(Name: %d): Succeed\n", i, (*array[i]).name); \ } \ SHOW_SUCCESS = flag_reg; \ } while(0) void pins_attach(int argn, ...) { va_list(pointer); va_start(pointer, argn); line line_buf; BOOL value_buf; int i; BOOL flag_reg = SHOW_SUCCESS; SHOW_SUCCESS = FALSE; for(i = 1; i <= argn; i++) { line_buf = va_arg(pointer, line); value_buf = va_arg(pointer, int); pin_attach(line_buf, value_buf); if(flag_reg == TRUE) printf("Attach Line(name:%d) to pin%s: Succeed\n", (*line_buf).name, chs[5-value_buf]); } va_end(pointer); SHOW_SUCCESS = flag_reg; } /******* check && circut power on *******/ #define POWER_ON_TIME 1000 void SHOW_CIRCUT(); void POWER_ON() { //check circut, init circut, insert pins into LPS[] for CST LPS_clear(); _line* _line_iterator = _line__ALLOC_SPACE+1; //_line store from LAS[1]. _logic_gate* _gate_iterator = _logic_gate__ALLOC_SPACE+1; //check lines while(_line_iterator <= LAS_ptr) { if((*_line_iterator).remove == FALSE) { if((*_line_iterator).attach_name == ATT_NULL) { printf(">>>ERROR: Line(name:%d) didn't attached to any unit...\n", (*_line_iterator).name); ERROR_cnt++; } if((*_line_iterator).attach_name == PIN) LPS_push(_line_iterator); } _line_iterator++; } //check logic_gates while(_gate_iterator <= LGAS_ptr) { if((*_gate_iterator).outcome_ptr == LINE_NULL) { printf(">>>WARNING: Gate(name:%d) output default...\n", (*_gate_iterator).name); WARNING_cnt++; } int cnt = 0, should_be = 2; if((*_gate_iterator).gate == 3) should_be = 1; if((*_gate_iterator).incomeA_ptr != LINE_NULL) cnt++; if((*_gate_iterator).incomeB_ptr != LINE_NULL) cnt++; if(cnt < should_be) { printf(">>>WARNING: Gate(name:%d) input default(now %d, should be %d)...\n", (*_gate_iterator).name, cnt, should_be); WARNING_cnt++; } _gate_iterator++; } //tips UI printf("-----------------------------------------------"); printf("\n\nInitializ finished. %d ERRORs, %d WARNINGs.\n\n", ERROR_cnt, WARNING_cnt); if(ERROR_cnt != 0 || WARNING_cnt != 0) { printf(">>>Circut may not work properly. Power_on circut anyway?(Y/N)"); char ans = getch(); while(ans != 'y' && ans != 'Y' && ans != 'n' && ans != 'N') ans = getch(); if(ans == 'n' || ans == 'N') exit(0); } else printf("Circut Power_on...\n"); /***POWER_ON: a long period of high-level current. To simulate this operate, we cancel the acculate-optimization in CST, calculate every unit in the circut.***/ /***WHY we need to POWER_ON? The reason is when the circut was built, all the levels and values in it is originnaly default(FALSE), so we need to init. ***/ ACCULATE_OPTIMIZATION_FLAG = FALSE; int i; for(i = 1; i <= POWER_ON_TIME; i++) CST(); ACCULATE_OPTIMIZATION_FLAG = TRUE; } /******* (mannul) update circut input *******/ inline void pin_update(line lpin, BOOL value) { //still pin, no need to change name's value if(value != (*lpin).level) { (*lpin).level = value; LPS_push(lpin); //in many situation, this operation will wake-up this circut. } } /******* developer options *******/ #define CANCEL_SUCCESS() SHOW_SUCCESS = FALSE void SHOW_CIRCUT() { printf("=============== SHOW CIRCUT ===============\n"); _line* _line_iterator = _line__ALLOC_SPACE+1; _logic_gate* _gate_iterator = _logic_gate__ALLOC_SPACE+1; while(_line_iterator <= LAS_ptr) { if((*_line_iterator).remove == FALSE) printf("Line: Name:%d Level:%d\n", (*_line_iterator).name, (*_line_iterator).level); _line_iterator++; } printf("===============================================\n\n"); }
順便再帶一個示例程序:
要實現這樣一個電路(注:4號線鏈接在了2號線上面)
咱們打這樣一個程序:
#include "VM_basis++.h" #define SHOW_SUCCESS_UI_FLAG 1 int main() { if(SHOW_SUCCESS_UI_FLAG != 1) CANCEL_SUCCESS(); line L[9]; gate A, B, C, D; line_array_create(L); pins_attach(3, L[1], FALSE, L[2], TRUE, L[3], FALSE); line_merge(L[2], L[4]); and_create(A, L[1], L[2], L[6]); or_create(B, L[3], L[4], L[5]); not_create(C, L[6], L[7]); and_create(D, L[5], L[7], L[8]); POWER_ON(); SHOW_CIRCUT(); return 0; }
運行結果:
以後,咱們改變輸入端,造出三個測試數據:
相對應地咱們有了以下的代碼:
做爲對應三組數據的三個輸入端電路。咱們把計算次數設爲4,也就是說對於每個輸入數據,咱們把廣搜四次的結果做爲最終結果。(能夠發現數電模塊做爲一個層次網絡的深度只有3,因此廣搜4次是顯然可行的)
三次結果以下:
結果徹底正確,測試樣例經過。
五. 下一層的實現目標:
經過VM_basis++.h,咱們已經能夠比較方便地創建虛擬化的數電模塊,好比鎖存器,T觸發器等等模塊。
下一步的任務是如何在創建完各自的模塊以後,將不一樣模塊的接口鏈接。以及時序控制系統是否能夠正常地控制各個模塊的計算。