Pages

                           

Monday, January 3, 2011

Logic Circuit

The main reason for simulating Logic Circuit in Python is to understand the concept of Object Oriented Programming and the power of Inheritance.

A couple of Python classes is used to simulate the behavior of logic circuits. The program consists of,

1) A base class LC (logic circuit) which will be subclassed to actual gates and other circuits.

2) A second class, Connector, will be used to provide inputs and outputs to the logic circuits. 

3) And an output connectors connect method which will simulate the wiring of LC's to one another.

In this, 3 basic logic gates AND , OR , NOT are first build. Then using the 3 basic gates a NAND, XOR, NOR, XNOR gates are build.

Then later the half adder and full adder circuits are also build using the logic gates. 

The entire program is as follows:

class Connector :
    
    def __init__ (self, owner, name, activates=0, monitor=0) :
        self.value = None
        self.owner = owner
        self.name  = name
        self.monitor  = monitor
        self.connects = []
        self.activates= activates   # If true change kicks evaluate function

    def connect (self, inputs) :
        if type(inputs) != type([]) : inputs = [inputs]
        for input in inputs : self.connects.append(input)


    def set (self, value) :
        if self.value == value : return      # Ignore if no change
        self.value = value
        if self.activates : self.owner.evaluate()
        if self.monitor :
            print "Connector %s-%s set to %s" % (self.owner.name,self.name,self.value)
        for con in self.connects : con.set(value)

class LC :

    # Logic Circuits have names and an evaluation function defined in child classes
    # They will also contain a set of inputs and outputs

    def __init__ (self, name) :
        self.name = name
    def evaluate (self) : return
            
class Not (LC) :         # Inverter. Input A. Output B.
    def __init__ (self, name) :
        LC.__init__ (self, name)
        self.A = Connector(self,'A', activates=1)
        self.B = Connector(self,'B')
    def evaluate (self) : self.B.set(not self.A.value)

class Gate2 (LC) :         # two input gates. Inputs A and B. Output C.
    def __init__ (self, name) :
        LC.__init__ (self, name)
        self.A = Connector(self,'A', activates=1)
        self.B = Connector(self,'B', activates=1)
        self.C = Connector(self,'C')

class And (Gate2) :       # two input AND Gate
    def __init__ (self, name) :
        Gate2.__init__ (self, name)
    def evaluate (self) : self.C.set(self.A.value and self.B.value)

class Or (Gate2) :         # two input OR gate.
    def __init__ (self, name) :
        Gate2.__init__ (self, name)
    def evaluate (self) : self.C.set(self.A.value or self.B.value)

class Xor (Gate2) :
    def __init__ (self, name) :
        Gate2.__init__ (self, name)
        self.A1 = And("A1") 
        self.A2 = And("A2")
        self.I1 = Not("I1")
        self.I2 = Not("I2")
        self.O1 = Or ("O1")
        self.A.connect    ([ self.A1.A, self.I2.A])
        self.B.connect    ([ self.I1.A, self.A2.A])
        self.I1.B.connect ([ self.A1.B ])
        self.I2.B.connect ([ self.A2.B ])
        self.A1.C.connect ([ self.O1.A ])
        self.A2.C.connect ([ self.O1.B ])
        self.O1.C.connect ([ self.C ])

class HalfAdder (LC) :         # One bit adder, A,B in. Sum and Carry out
    def __init__ (self, name) :
        LC.__init__ (self, name)
        self.A = Connector(self,'A',1)
        self.B = Connector(self,'B',1)
        self.S = Connector(self,'S')
        self.C = Connector(self,'C')
        self.X1= Xor("X1")
        self.A1= And("A1")
        self.A.connect    ([ self.X1.A, self.A1.A])
        self.B.connect    ([ self.X1.B, self.A1.B])
        self.X1.C.connect ([ self.S])
        self.A1.C.connect ([ self.C])

class FullAdder (LC) :         # One bit adder, A,B,Cin in. Sum and Cout out
    def __init__ (self, name) :
        LC.__init__ (self, name)
        self.A    = Connector(self,'A',1,monitor=1)
        self.B    = Connector(self,'B',1,monitor=1)
        self.Cin  = Connector(self,'Cin',1,monitor=1)
        self.S    = Connector(self,'S',monitor=1)
        self.Cout = Connector(self,'Cout',monitor=1)
        self.H1= HalfAdder("H1")
        self.H2= HalfAdder("H2")
        self.O1= Or("O1")
        self.A.connect    ([ self.H1.A ])
        self.B.connect    ([ self.H1.B ])
        self.Cin.connect  ([ self.H2.A ])
        self.H1.S.connect ([ self.H2.B ])
        self.H1.C.connect ([ self.O1.B])
        self.H2.C.connect ([ self.O1.A])
        self.H2.S.connect ([ self.S])
        self.O1.C.connect ([ self.Cout])


class Nor(Gate2):
def __init__(self,name):
Gate2.__init__(self,name)
self.O1=Or("O1")
self.N1=Not("N1")
self.A.connect([self.O1.A])
self.B.connect([self.O1.B])
self.O1.C.connect([self.N1.A])
self.N1.B.connect([self.C])
class Xnor(Gate2):
def __init__(self,name):
Gate2.__init__(self,name)
self.A1=And('A1')
self.A2=And('A2')
self.O1=Or('O1')
self.N1=Not('N1')
self.N2=Not('N2')
self.A.connect([self.A1.A,self.N2.A])
self.B.connect([self.A1.B,self.N1.A])
self.N1.B.connect([self.A2.A])
self.N2.B.connect([self.A2.B])
self.A1.C.connect([self.O1.A])
self.A2.C.connect([self.O1.B])
self.O1.C.connect([self.C])
def main():
gate=input('Enter the Logic Gate( And / Or / Not / Xor / Nor / Xnor ):')
in1=input('Enter the value for A:')
        in2=input('Enter the value for B:')

a=gate('A1')
a.C.monitor=1 
a.A.set(in1)
a.B.set(in2)
main()

No comments:

Post a Comment