--- nand.py- +++ nand.py @@ -85,6 +85,28 @@ if pin.conn: pin.set(v) +class Joint_N(Obj): + def __init__(self, parent, n, name='jt_n', latency=None, pos=(0,0), slide=('y',1), lamp_name=None): + Obj.__init__(self, parent, name, latency, pos) + self.n = n + pos = (0, 0) + for i in range(n): + lamp_nm = name_i(lamp_name, i) if lamp_name else None + Joint( self, name_i('jt', i), latency, pos, lamp_nm ) + pos = step_pos_slide(pos, slide) + + def new_pin_conn(self, targ, targ_pin_name, n=-1, direc='to_targ'): + if n < 0: + n = self.n + for i in range(n): + targ_pin = getattr( targ, name_i(targ_pin_name, i), None ) + jt = getattr( self, name_i('jt', i), None ) + if targ_pin and jt: + if direc == 'to_targ': + jt.new_pin().conn = targ_pin + else: + targ_pin.conn = jt.new_pin() + class NOT(Obj): def __init__(self, parent, name='not_', latency=10): Obj.__init__(self, parent, name) @@ -317,6 +339,55 @@ self.jkff.Q.conn = Pin(self, 'Q') self.jkff.nQ.conn = Pin(self, 'nQ') +class COUNTER(Obj): + def __init__(self, parent, bit_n, name='counter', latency=10): + Obj.__init__(self, parent, name) + self.n = bit_n + clk = Pin(self, 'CLK', 'L') + for i in range(bit_n): + tff = TFF( self, name_i('tff', i), latency ) + clk.conn = tff.CLK + tff.Q.conn = Pin( self, name_i('out', i), 'L' ) + clk = tff.nQ + +class DECODER(Obj): + def __init__(self, parent, bit_n, name='decoder', latency=10): + Obj.__init__(self, parent, name) + self.n = bit_n + if bit_n == 1: + Pin(self, 'inp_0', 'L').conn = Joint(self, 'jt_inp').new_pin() + self.jt_inp.new_pin().conn = NOT(self, 'not_', latency).inp + self.not_.out.conn = AND(self, 'and_0', latency).inp_a + self.jt_inp.new_pin().conn = AND(self, 'and_1', latency).inp_a + + Pin(self, 'en', 'L').conn = Joint(self, 'jt_en').new_pin() + self.jt_en.new_pin().conn = self.and_0.inp_b + self.jt_en.new_pin().conn = self.and_1.inp_b + + self.and_0.out.conn = Pin(self, 'out_0') + self.and_1.out.conn = Pin(self, 'out_1') + else: + for i in range(bit_n): + Pin( self, name_i('inp', i), 'L' ) + bn1 = bit_n - 1 + DECODER(self, bn1, 'dec_u', latency) + DECODER(self, bn1, 'dec_d', latency) + Joint_N(self, bn1, 'jt_n') + self.jt_n.new_pin_conn(self, 'inp', bn1, direc='from_targ') + self.jt_n.new_pin_conn(self.dec_u, 'inp') + self.jt_n.new_pin_conn(self.dec_d, 'inp') + + DECODER(self, 1, 'dec_1', latency) + msb = getattr( self, name_i('inp', bn1) ) + msb.conn = self.dec_1.inp_0 + Pin(self, 'en', 'L').conn = self.dec_1.en + self.dec_1.out_0.conn = self.dec_d.en + self.dec_1.out_1.conn = self.dec_u.en + + n1 = 1 << bn1 + new_pin_conn(self, self.dec_d, 0, n1, 'out', direc='from_in_obj') + new_pin_conn(self, self.dec_u, n1, n1, 'out', direc='from_in_obj') + class CLK(Obj): def __init__(self, parent, hz=1.0, name='clk', pos=(0,0), lamp_name=None): Obj.__init__(self, parent, name, None, pos) @@ -358,6 +429,20 @@ print ''.join(lst) sys.stdout.flush() +class Lamp_N(Obj): + def __init__(self, parent, n, name='lamp_n', latency=None, pos=(0,0), slide=('y',1)): + Obj.__init__(self, parent, name, latency, pos) + self.n = n + pos = (0, 0) + for i in range(n): + lamp = Lamp( self, name_i(name, i), latency, pos ) + pos = step_pos_slide(pos, slide) + Pin( self, name_i('inp', i), 'L' ).conn = lamp.inp + + def conn_targ(self, targ, targ_pin_name, n=-1): + n = self.n if n < 0 else n + conn_n( n, targ, 0, targ_pin_name, self, 0, 'inp' ) + class Sched: def __init__(self): self.que = [] @@ -414,13 +499,33 @@ dbgout( 'cmd_exec "{}"'.format(s) ) exec s -def new_pin_conn(obj, in_obj, sta_i): - for i in range(in_obj.n): - pin = getattr( in_obj, name_inp(i) ) - Pin( obj, name_inp( sta_i + i ) ).conn = pin +def step_pos_slide( pos, slide=('y',1) ): + (x, y) = pos + (direc, step) = slide + x += step if direc != 'y' else 0 + y += step if direc == 'y' else 0 + return (x, y) + +def new_pin_conn(obj, in_obj, sta_i, n=-1, name='inp', direc='to_in_obj'): + if n < 0: + n = in_obj.n + for i in range(n): + Pin( obj, name_i( name, sta_i + i ) ) + direc_rev = (direc != 'to_in_obj') + conn_n(n, obj, sta_i, name, in_obj, 0, name, direc_rev) + +def conn_n(n, from_obj, from_sta_i, from_name, to_obj, to_sta_i, to_name, direc_rev=False): + for i in range(n): + from_pin = getattr( from_obj, name_i( from_name, from_sta_i + i ), None ) + to_pin = getattr( to_obj, name_i( to_name, to_sta_i + i ), None ) + if from_pin and to_pin: + if direc_rev: + to_pin.conn = from_pin + else: + from_pin.conn = to_pin -def name_inp(i): - return 'inp_{}'.format(i) +def name_i(name, i): + return '{}_{}'.format(name, i) def str_v(v): return { True: 'H', False: 'L', None: 'Hi-Z' }.get(v, '?')