class IC_7454: ''' This is a 4-wide 2-input AND-OR Invert gate ''' #Datasheet here, http://www.unitechelectronics.com/7451-7497data.htm def __init__(self): self.pins = [0, 0, 0, 0, 0, None, 0, None, 0, 0, 0, 0, 0, 0, 0] self.gates = Gates() def setIC(self, pin_conf): ''' This method takes a dictionary with key:pin_no and value:pin_value ''' for i in pin_conf: self.pins[i] = pin_conf[i] def setPin(self, pin_no, pin_value): if pin_no < 1 or pin_no > 14: raise Exception("ERROR: there are only 14 pins in this IC") self.pins[pin_no] = pin_value def run(self): output = {} temp = [] temp.append( self.gates.OR( self.gates.AND(self.pins[1], self.pins[2]), self.gates.AND(self.pins[3], self.pins[4], self.pins[5]))) temp.append( self.gates.OR( self.gates.AND(self.pins[9], self.pins[10], self.pins[11]), self.gates.AND(self.pins[12], self.pins[13]))) output[6] = self.gates.NOR(temp[0], temp[1]) if self.pins[7] == 0 and self.pins[14] == 1: return output else: print "Ground and VCC pins have not been configured correctly."
class MUX: ''' This class can be used to create MUX in your circuit. It has a method for each kind of MUX, namely, mux_2_1, mux_4_1, mux_8_1 and mux_16_1 All the methods take 3 parameters(inputs, select lines and strobe). Strobe is high by default inputs and select_inputs are lists. First index of input is 'A', second index is 'B' and so on... But last index of select_inputs is 'S0', second last index is 'S1' and so on... ''' def __init__(self): self.gates = Gates() def run(self,inputs,select_inputs,strobe=1): ''' This method takes 3 parameters [inputs(list),select_inputs(list), optional strobe(int)] This method automatically classifies the type of MUX and returns the computed result(int) ''' allowed = [2,4,8,16] mux_type = len(inputs) if mux_type not in allowed: sys.exit("ERROR: only 4 types of MUX are supported, namely, 2:1, 4:1, 8:1 and 16:1") if 2**len(select_inputs)!=mux_type: sys.exit("ERROR: no of select inputs do not comply with no of inputs") if mux_type == 2: return self.mux_2_1(inputs,select_inputs,strobe) elif mux_type == 4: return self.mux_4_1(inputs,select_inputs,strobe) elif mux_type == 8: return self.mux_8_1(inputs,select_inputs,strobe) elif mux_type == 16: return self.mux_16_1(inputs,select_inputs,strobe) def mux_2_1(self,inputs,select_inputs,strobe=1): ''' This method implements 2:1 MUX using logic gates Input and output is same as run() method ''' s = select_inputs[0] a = inputs[0] b = inputs[1] result = self.gates.OR(self.gates.AND(a,self.gates.NOT(s)),self.gates.AND(b,s)) if strobe==1: return result else: return self.gates.NOT(result) def mux_4_1(self,inputs,select_inputs,strobe=1): ''' This method implements 4:1 MUX using logic gates Input and output is same as run() method ''' select_inputs = select_inputs[::-1] s0 = select_inputs[0] s1 = select_inputs[1] a,b,c,d = inputs[0],inputs[1],inputs[2],inputs[3] term1 = self.gates.AND(a,self.gates.NOT(s0),self.gates.NOT(s1)) term2 = self.gates.AND(b,s0,self.gates.NOT(s1)) term3 = self.gates.AND(c,self.gates.NOT(s0),s1) term4 = self.gates.AND(d,s0,s1) result = self.gates.OR(term1,term2,term3,term4) if strobe==1: return result else: return self.gates.NOT(result) def mux_8_1(self,inputs,select_inputs,strobe=1): ''' This method implements 8:1 MUX using logic gates Input and output is same as run() method ''' select_inputs = select_inputs[::-1] s0 = select_inputs[0] s1 = select_inputs[1] s2 = select_inputs[2] a,b,c,d,e,f,g,h = inputs[0],inputs[1],inputs[2],inputs[3],inputs[4],inputs[5],inputs[6],inputs[7] term1 = self.gates.AND(a,self.gates.NOT(s2),self.gates.NOT(s1),self.gates.NOT(s0)) term2 = self.gates.AND(b,self.gates.NOT(s2),self.gates.NOT(s1),s0) term3 = self.gates.AND(c,self.gates.NOT(s2),s1,self.gates.NOT(s0)) term4 = self.gates.AND(d,self.gates.NOT(s2),s1,s0) term5 = self.gates.AND(e,s2,self.gates.NOT(s1),self.gates.NOT(s0)) term6 = self.gates.AND(f,s2,self.gates.NOT(s1),s0) term7 = self.gates.AND(g,s2,s1,self.gates.NOT(s0)) term8 = self.gates.AND(h,s2,s1,s0) result = self.gates.OR(term1,term2,term3,term4,term5,term6,term7,term8) if strobe==1: return result else: return self.gates.NOT(result) def mux_16_1(self,inputs,select_inputs,strobe=1): ''' This method implements 16:1 MUX using two 8:1 MUX and one 2:1 MUX Input and output is same as run() method ''' select_inputs = select_inputs[::-1] s0 = select_inputs[0] s1 = select_inputs[1] s2 = select_inputs[2] s3 = select_inputs[3] first_mux_8_1 = self.mux_8_1(inputs[0:8],[s2,s1,s0]) second_mux_8_1 = self.mux_8_1(inputs[8:],[s2,s1,s0]) result = self.mux_2_1([first_mux_8_1,second_mux_8_1],[s3]) if strobe==1: return result else: return self.gates.NOT(result)
class Operation: ''' This class serves binary addition and subtraction on n-bit numbers ''' def __init__(self): self.gates = Gates() def add_one_bit(self,a,b,c=0): ''' This method takes two one bit numbers and returns a dictionary of their sum and carry DictKeys: 'sum', 'carry' ''' a_xor_b = self.gates.XOR(a,b) asum = self.gates.XOR(a_xor_b,c) a_and_b = self.gates.AND(a,b) a_xor_b_and_c = self.gates.AND(a_xor_b,c) carry = self.gates.OR(a_xor_b_and_c, a_and_b) return {'sum':asum, 'carry':carry} def add(self,a,b,carry=0): ''' This method takes 2 lists of binary numbers with an optional carry it uses add_one_bit method to add those numbers This method returns a dictionary of a list and an integer DictKeys: 'sum', 'carry' ''' a = a[::-1] b = b[::-1] hold = [] if len(a)!=len(b): diff = abs(len(a)-len(b)) if len(a)>len(b): for i in range(diff): b.append(0) else: for i in range(diff): a.append(0) for i in xrange(len(a)): step=self.add_one_bit(a[i],b[i],carry) hold.append(step['sum']) carry=step['carry'] hold=hold[::-1] return {'sum':hold,'carry':carry} def subtract(self,a,b,carry=1): ''' This method takes 2 lists of binary numbers with an optional carry it uses add method to subtract those numbers using 1's complement method This method returns a dictionary of a list and an integer DictKeys: 'difference', 'carry' ''' a = a[::-1] b = b[::-1] if len(a)!=len(b): diff = abs(len(a)-len(b)) if len(a)>len(b): for i in range(diff): b.append(0) else: for i in range(diff): a.append(0) a=a[::-1] b=b[::-1] for i in range(len(b)): b[i]=self.gates.NOT(b[i]) temp = self.add(a,b,carry) return {'difference':temp['sum'],'carry':temp['carry']} def multiply(self,a,b): ''' This method takes 2 lists of binary numbers and multiplies those numbers using and add function This method returns a binary number ''' a = a[::-1] b = b[::-1] hold = [[] for i in range(len(b))] for i in range(len(b)): for j in range(len(a)+len(b)): hold[i].append(0) for i in range(len(b)): k=0 for j in range(i,len(a)+i): hold[i][j]=self.gates.AND(a[k],b[i]) k+=1 for i in range(len(hold)): hold[i]=hold[i][::-1] last_out = self.add(hold[0],hold[1])['sum'] last_out.insert(self.add(hold[0],hold[1])['carry'],0) for i in range(1,len(hold)-1): temp = self.add(hold[i],last_out) last_out = temp['sum'].insert(0,temp['carry']) return last_out