def input(self, time, signal): # Split input value into bits and send to internal bit counter inputs. dummy_signal = Signal('dummy') for i_bit in range(self.n_bits): value = signal.state & (1 << i_bit) dummy_signal.set(time, value) self._bit_counters[i_bit].input(time, dummy_signal)
def __init__(self, name, n_bits, onebit_kwargs=None, *args, **kwargs): super(Counter, self).__init__(name, *args, **kwargs) self.n_bits = n_bits if onebit_kwargs is None: onebit_kwargs = {} self._bit_counters = [ CounterOnebit('{}__bit:{}'.format(name, i_bit), **onebit_kwargs) for i_bit in range(n_bits) ] # inputs: 'input', 'x_clear' # outputs: 'output', 'x_carry_out' # # Note: internally, 'input' is split into, and 'output' joined from, # a signal for each bit. # The internal one-bits have an 'or_enable', but this is not used. # The clear signal is inverted to avoid dropped bits carrying over. self._output_combined = sig_join( '{}_combined_output'.format(name), [(bit_counter.output, 1) for bit_counter in self._bit_counters[::-1]]) self.output = self._output_combined.output self._carry_constant_signal = Signal('_carry_value', start_state=1) self._carry_gates = [None] * n_bits # self.add_output('x_carry_out') # Connect input of each bit>0 to a SigSendCopy pseudo-device, connected # to the carry-out of the previous : Similarly, connect our own # carry-out to the last bit-carry-out. # The (SigSendCopy) "carry-gates" are used so we can switch carrying # off during clear operations. for i_bit in range(n_bits): i_next = i_bit + 1 if i_bit < n_bits - 1: carry_name = '_{}_carry:{}'.format(name, i_bit) else: carry_name = '{}__x_carry_out'.format(name) carry_gate = SigSendCopy(carry_name) self._carry_gates[i_bit] = carry_gate carry_gate.connect('input', self._carry_constant_signal) # Note carry-gates ALSO need an initial signal to initialise state. # TODO: possibly should fix this by overriding SendSigCopy.connect? carry_gate.input(0.0, self._carry_constant_signal) carry_gate.connect('send', self._bit_counters[i_bit].x_carry_out) if i_bit < n_bits - 1: # NOTE: these inputs get signals from the main 'input' value, # as well as these carry-overs, which is effectively an # implicit OR : The timings must be kept apart to avoid # unexpected-state exceptions. self._bit_counters[i_next].connect('input', carry_gate.output) else: self.x_carry_out = carry_gate.output
def runtest(): latch = PulseLatch('latch', t_data_2_clr=5.0, t_clr_2_data=5.0, t_out_delay=2.) din = Signal('d_in') clr = Signal('clr') latch.connect('input', din) latch.connect('clr', clr) din.trace() clr.trace() latch.output.trace() SEQ.addall([ setsig(5.0, din, 77), setsig(20.0, clr, '!'), setsig(40.0, din, 35), ]) latchview = PulseLatchView(latch, input_xy=(0, 10), output_xy=(0, 2), value_text_kwargs={'fontsize': 60}) scene = [latchview] ax = viz( scene, until_seqtime=350.0, # speedup_factor=10.0, speedup_factor=5.0, frame_interval_secs=0.05, pause_in_gaps=True) # skip_gaps = True) # pause_every_step=True) print('\n\nRETURN TO EXIT...>') six.moves.input()
from sim.tests import okeq, okin, setsig, fails from sim.device.arith import Counter counter = Counter('TstCount1', n_bits=2, onebit_kwargs={ 't_toggle_0_to_1': 3., 't_toggle_1_to_0': 3., 't_out_2_carry': 1., 't_clear_2_carry': 2., 't_clear_onoff': 4., 't_eor_onoff': 2. }) din = Signal('d_in') clr = Signal('clr') counter.connect('input', din) counter.connect('clear', clr) din.trace() clr.trace() counter.output.trace() counter.x_carry_out.trace() # for bit_counter in counter._bit_counters: # bit_counter.output.trace() # bit_counter.x_carry_out.trace() # # for carry_gate in counter._carry_gates: # carry_gate.output.trace()
from sim.bbc.controller import BbcController from sim.signal import Signal from sim.sequencer import DEFAULT_SEQUENCER as SEQ from sim.tests import setsig cycle = BbcController() print(cycle) sig_start = Signal('start') sig_start.trace() cycle.connect('start', sig_start) cycle.current_phase.trace() # cycle.trace('_do_phase') for phase_name, _ in cycle.phase_names_and_default_durations: getattr(cycle, phase_name).trace() SEQ.add(setsig(0.0, sig_start, '!')) SEQ.run(100.0) SEQ.clear() # Clear out unfinished business, so other tests can run!
def add_output(self, name, start_value=None): full_name = '{}.{}'.format(self.name, name) signal = Signal(full_name, start_value) setattr(self, name, signal)
import sys sys.path.append('/storage/emulated/0/qpython/') from sim.signal import Signal, SIG_UNDEF from sim.sequencer import DEFAULT_SEQUENCER as SEQ from sim.device.pseudo_devices import \ SigBitslice, SigJoin, sig_bitslice, sig_join from sim.tests import okeq, okin, setsig, fails sig_a = Signal('a') d_a0 = sig_bitslice(sig_a, 0) d_a2 = sig_bitslice(sig_a, 2, name='a2_x') d_a12 = sig_bitslice(sig_a, 1, nbits=2) okeq(d_a0.name, 'a:0') okeq(d_a2.name, 'a2_x') okeq(d_a12.name, 'a:1..2') a0 = d_a0.output a2 = d_a2.output a12 = d_a12.output okeq(a0.name, 'a:0.output') okeq(a2.name, 'a2_x.output') okeq(a12.name, 'a:1..2.output') print('\ncheck bit slices') SEQ.addall([ setsig(100.0, sig_a, 0b0101), setsig(200.0, sig_a, SIG_UNDEF), setsig(300.0, sig_a, 0b0010), ])
import sys sys.path.append('/storage/emulated/0/qpython/') from sim.signal import Signal from sim.sequencer import DEFAULT_SEQUENCER as SEQ from sim.device import Device, Action, ClockTick # Test device (clock tick) clk = ClockTick('clock_01', period=10) print(clk) startsig = Signal('start_clock') clk.connect('start', startsig) clk.trace('start') clk.trace('tick') clk.output.trace() # input_hook(device, name, time, signal def start_input_hook(device, time, signal): print('\n =START-INPUT-HOOK: into {}.start : @{} = {}'.format( device.name, time, signal.state)) # action_hook(device, name, time, *args, **kwargs) def tick_action_hook(device, time): print('\n =TICK-ACTION-HOOK: into {}.tick @ {}'.format(device.name, time)) clk.hook('start', start_input_hook)
import sys sys.path.append('/storage/emulated/0/qpython/') print('\n'.join(sys.path)) from sim.signal import Signal # Test signals x = Signal('x') print(x) x.trace() x.set(5.0, 1) x.set(6., 1) x.untrace() msg = 'x untraced, ={}' print(msg.format(x.state)) x.set(0., 0) print(msg.format(x.state))
import sys from sim.tests import \ okeq, okin, setsig, fails from sim.signal import Signal from sim.sequencer import DEFAULT_SEQUENCER as SEQ from sim.device.pulse_ram import PulseRam ram = PulseRam('dm') print(ram) d_in = Signal('data') addr = Signal('addr') ard = Signal('!a_read') aclr = Signal('!a_aclr') ram.connect('d_in', d_in) ram.connect('addr', addr) ram.connect('x_read', ard) ram.connect('x_aclr', aclr) addr.trace() d_in.trace() ard.trace() aclr.trace() ram.out.trace() print('\ncheck set, clr') SEQ.addall([ setsig(100.0, addr, 3),
@Device.input def in2(self, t, sig): self._in[1] = sig.state self._changes[1] = 1 self.out.set(t, SIG_UNDEF) self.seq.add((t + self._settle, Action(self, '_done', 1))) @Device.action def _done(self, t, i_in): self._changes[i_in] = 0 if not any(self._changes): v1, v2 = self._in self.out.set(t, v1 ^ v2) sig1 = Signal('s01') w01 = Wire('w01', delay=20.) print(w01) w01.connect('input', sig1) x01 = Xor2('xor01') x01.trace('_done') x01.connect('in1', sig1) x01.connect('in2', w01.output) SEQ.add((0., lambda t: sig1.set(t, 0))) SEQ.run() okeq(sig1.state, 0) print('remaining events:') print(SEQ.events) print('')
class Counter(Device): """ A multi-bit counter. This is a compound device, containing inner devices and signals. Inputs: 'input', 'clear' Outputs: 'output', 'x_carry_out' """ def __init__(self, name, n_bits, onebit_kwargs=None, *args, **kwargs): super(Counter, self).__init__(name, *args, **kwargs) self.n_bits = n_bits if onebit_kwargs is None: onebit_kwargs = {} self._bit_counters = [ CounterOnebit('{}__bit:{}'.format(name, i_bit), **onebit_kwargs) for i_bit in range(n_bits) ] # inputs: 'input', 'x_clear' # outputs: 'output', 'x_carry_out' # # Note: internally, 'input' is split into, and 'output' joined from, # a signal for each bit. # The internal one-bits have an 'or_enable', but this is not used. # The clear signal is inverted to avoid dropped bits carrying over. self._output_combined = sig_join( '{}_combined_output'.format(name), [(bit_counter.output, 1) for bit_counter in self._bit_counters[::-1]]) self.output = self._output_combined.output self._carry_constant_signal = Signal('_carry_value', start_state=1) self._carry_gates = [None] * n_bits # self.add_output('x_carry_out') # Connect input of each bit>0 to a SigSendCopy pseudo-device, connected # to the carry-out of the previous : Similarly, connect our own # carry-out to the last bit-carry-out. # The (SigSendCopy) "carry-gates" are used so we can switch carrying # off during clear operations. for i_bit in range(n_bits): i_next = i_bit + 1 if i_bit < n_bits - 1: carry_name = '_{}_carry:{}'.format(name, i_bit) else: carry_name = '{}__x_carry_out'.format(name) carry_gate = SigSendCopy(carry_name) self._carry_gates[i_bit] = carry_gate carry_gate.connect('input', self._carry_constant_signal) # Note carry-gates ALSO need an initial signal to initialise state. # TODO: possibly should fix this by overriding SendSigCopy.connect? carry_gate.input(0.0, self._carry_constant_signal) carry_gate.connect('send', self._bit_counters[i_bit].x_carry_out) if i_bit < n_bits - 1: # NOTE: these inputs get signals from the main 'input' value, # as well as these carry-overs, which is effectively an # implicit OR : The timings must be kept apart to avoid # unexpected-state exceptions. self._bit_counters[i_next].connect('input', carry_gate.output) else: self.x_carry_out = carry_gate.output def input(self, time, signal): # Split input value into bits and send to internal bit counter inputs. dummy_signal = Signal('dummy') for i_bit in range(self.n_bits): value = signal.state & (1 << i_bit) dummy_signal.set(time, value) self._bit_counters[i_bit].input(time, dummy_signal) def clear(self, time, signal): # Set the common carry signal to block carry-over while clearing, and # enable it during 'normal' operation. enable_carries = 0 if (signal.state != 0) else 1 self._carry_constant_signal.set(time, enable_carries) # Send the clear signal (new value) to all the bit-counters. for i_bit in range(self.n_bits): self._bit_counters[i_bit].clear(time, signal)
from sim.signal import Signal from sim.sequencer import DEFAULT_SEQUENCER as SEQ from sim.device.pulse_rom import PulseRom words = [17, 4, 0, 42, 299] rom = PulseRom(name='pm', rom_words=words, t_addr_2_asel=1.0, t_asel_2_read=1.0, t_read_2_aclr=1.0, t_aclr_2_addr=1.0, t_out_delay=10.0) print(rom) addr = Signal('addr') aen = Signal('!a_ena') aclr = Signal('!a_dis') read = Signal('!read') rom.connect('addr', addr) rom.connect('x_asel', aen) rom.connect('x_aclr', aclr) rom.connect('x_read', read) addr.trace() aen.trace() aclr.trace() read.trace() rom.out.trace() print('\ncheck set, clr, set')
'pm_mnemonics', instruction_names) pm_ir = PulseRom( 'pm_ir', instruction_ir_bits) pm_k = PulseRom( 'pm_k', instruction_k_values) count_pm_addr = Counter('pm_addr', n_bits=6) # in: 'input' # out: 'output', 'x_carry_out' # Connect the 'next' signal : it needs to be converted to a '1' for a multibit counter input. ir_plus_1 = SigSendCopy(name='ir+1') ir_plus_1.input(0.0, Signal('_tmp', start_state=1)) ir_plus_1.connect('send', cycle.p0_Next) # TODO: this signal will need to be OR-ed with k value (for jumps) and carry-out (for skips) count_pm_addr.connect('input', ir_plus_1.output) # Wire address and timing signals to all 3 PM roms for pm in (pm_mnemonics, pm_ir, pm_k): pm.connect('addr', count_pm_addr.output) pm.connect('x_asel', cycle.p1_AddressPm) pm.connect('x_aclr', cycle.p5_AddC_SaveA) pm_mnemonics.connect('x_read', cycle.p2_PmFetchIr) pm_ir.connect('x_read', cycle.p2_PmFetchIr) pm_k.connect('x_read', cycle.p3_PmFetchK_Clc) # Split off top bit of instruction for immediate signal to preclear acc