2011-10-29 31 views
4

在我的工作中,我們利用具有布爾邏輯程序的處理器用於工業應用。這些程序可能會變得非常漫長和複雜。它們基本上由輸入位,輸出位和內部布爾位組成。這些位然後用於導致輸出的邏輯語句中。輸入和輸出可以是物理線路輸出或串行通信,但這並不重要。組織簡單布爾邏輯模擬器 - Java

下面是一個簡單的,簡化的例子:

Inputs: 
input1, input2, input3; 

Outputs: 
output1, output2, output3; 

Boolean: 
bool1, bool2, bool3; 

Logic: 
assign input1 && input2 to bool1; 
assign input1 && bool1 to output1; 
assign input2 && input3 to bool2; 
assign output1 && bool2 to output2; 
assign output1 && output2 || bool2 to bool3; 

所以,請記住,我是很新到Java。我做了很多基於web的編程(ruby,php,javascript等)。

基本上我想模擬器要做的是打破程序的格式並允許進行圖形模擬。程序可以相互通信,因此模擬器也應該能夠處理多個程序(並將I/O綁定在一起)。

我的問題是組織入門。我會假設我需要一個「位」類。該類將存儲該位是設置爲TRUE還是FALSE,位的類型,相關等式,位來自哪個處理器等。

但是,接下來我可以達到這樣的程度,或數千個「比特」實例。我如何組織這些比特呢?如果我想抓取來自某個處理器的所有實例,我該如何實現?另外,當我改變模擬器中輸入位的狀態(TRUE或FALSE)時,它將更新其他幾個位的狀態。對此有何建議?我希望儘可能靈活,因爲我想添加其他功能。例如,某些位可以被指定爲定時器(當它們的條件滿足時,它們可能需要一定的時間來設置,或者當它們的條件不再滿足時可能需要一定的時間才能放棄)。

我最初的想法是保持對象的數組或哈希值,並嘗試以某種方式保持它們的組織方式。

我基本上在尋找任何建議。提前致謝。

+0

好問題,也很好的問,並深思熟慮。 +1 – switz

+1

http://www.tetzl.de/java_logic_simulator.html有源代碼。還有其他的,谷歌java模型數字電路 –

回答

3

有趣的問題。你基本上是建立一個簡單的布爾值虛擬處理器。所以我會將模擬器作爲更多的處理器來構建。所以基本上你會有寄存器(輸入,輸出或內部寄存器),那麼邏輯就會定義你的操作數。由於您只處理布爾邏輯,所以想出您需要的一組操作數非常簡單:AND,OR,NOT,XOR。對於像& &,||這些操作數將有兩個輸入和一個輸出。但是,對於不是,你將只有一個輸入和一個輸出。所以我會爲你想支持的每個操作數創建一個類。並且抽象類或接口所有操作數都可以擴展/實現。這將爲客戶端提供接口,以相同的方式評估每個操作數並執行程序。

例如:

public class AndOperation implements Operand, Argument { 

    private Argument argument1; 
    private Argument argument2; 
    private String output; 

    public AndOperation(Argument arg1, Argument arg2) { 
     this(arg1, arg2, null); // this is for chaining where no output exists. 
    } 

    public AndOperation(Argument arg1, Argument arg2, String output) { 
     this.argument1 = arg1; 
     this.argument2 = arg2; 
     this.output = output; 
    } 

    public boolean evaluate() { 
     return argument1.evaluate() && argument2.evaluate(); 
    } 

    public String getOutputRegister() { 
     return output; 
    } 
} 

public interface Argument { 
    public boolean evaluate(); 
} 

public class Register implements Argument { 
    private String name; 
    private boolean value; 

    public boolean evaluate() { 
     return value; 
    } 

    public void setValue(boolean value) { 
     this.value = value; 
    } 
} 


public class Program implements Iterable<Operand> { 

    public Map<Register> registers; 
    public List<Operand> operands; 

    public void parse(InputStream stream) { 
     // this will take in a stream, parse it, and create the 
     // program. Create the registers, and operands used 
     // to evaluate the program 
    } 

    public void evaluate() { 
     for(Operand op : operands) { 
     evaluate(op); 
     } 
    } 

    public void evaluate(Operand operand) { 
     boolean output = op.evaluate(); 
     String name = op.getOutputRegister(); 
     Register register = registers.get(name); 
     register.setValue(output); 
    }   

    public Iterator<Operand> iterator() { 
     return new Debugger(this); 
    } 
} 

public class Debugger implements Iterator<Operand> { 
    private Program program; 
    private int line = 0; 

    public boolean hasNext() { 
     return line < program.size(); 
    } 

    public Operand next() { 
     Operand operand = program.getOperands().get(line); 
     program.evaluate(operand); 
     line++; 
     return operand; 
    } 
} 

這是粗略的。然而,我想指出的一件事情是如何將多個操作數鏈接在一起可以透明地完成。操作數不關心它是從寄存器還是另一個操作數讀取輸入。由於寄存器和操作數實現了參數,所以它取代了。例如:

Operand op = new AndOperand(register1, new OrOperand(register2, register3); 
boolean output = op.evaluate(); // this is register1 && (register2 || register3) 

當然,棘手的部分是解析它,但是在這個有限的空間中有點難以展示。就圖形表示這一點而言,你可以構建一些採用該程序並通過操作數評估操作數並以某種方式將其呈現在屏幕上的東西。沒有更多的努力就可以建立一個調試器。只需要解析器可以創建的更多信息(行號到操作數映射將會有所幫助)。

+0

謝謝你的迴應,這給了我很多想想。 – RyanB

+0

我現在遇到遞歸問題。當我有這樣的說法: 'Bit1 = Bit2 + Bit1' 基本上,因爲Bit1計算爲OrOperand(Bit2,Bit1),所以當它到達語句中的Bit1時,它會連續不斷地評估同一個事物: 'OrOperand(Bit2,OrOperand(Bit2,OrOperand(Bit2,Bit1)))' 處理這個問題的任何建議?我知道我沒有在問題中展示它的一個例子。我不認爲發佈我的完整源代碼將會有所幫助,但如果有要求,我也可以。 – RyanB

+0

我不確定它是如何一遍又一遍地重複同一行。我期望這行被解析爲新的OrOperand(registerBit1,registerBit2,registerBit1),如果評估它不會持續循環給定我在上面的代碼中寫的。如果它正在循環,我會檢查程序中的操作,看看它是否創建了長鏈,當它不應該。解析輸入,然後設置一個斷點,以便查看Program實例。看看是否有任何過多的循環。這不是遞歸本身,它是一個聲明,其中一個寄存器用作輸入和輸出。這不是重複的陳述。 – chubbsondubs