def d_in(self, time, signal): okeq(self._state, 'read-but-not-written') self._state = 'writing' self.seq.add((time + self._t_w2c, Action(self, '_write_done'))) value = signal.state okeq(isinstance(value, (int, float)), True) self._ram_content[self._addr] = int(value)
def x_asel(self, time, signal): """ Address enable input. Event triggered. """ okeq(self._state, 'idle') self._state = 'enabling-address' self.seq.add((time + self._t_sel2rd, Action(self, '_a_enabled')))
def _toggle_output(self, time): okeq(self._state, 'value-toggling') self.output.set(time, self._value) if self._value == 1: # New state is 1, no carry-out. self._state = 'idle' else: # Must also send a carry, before we are stable again. self._state = 'carry-propagating' self.act(time + self._t_carry, '_carry_out')
def x_read(self, time, signal): okeq(self._state, 'active') self._state = 'reading' # Note: does not block until # output, but do have a short # delay before clr is valid. index = min(self._addr, len(self._rom) - 1) data = self._rom[index] self.seq.addall([(time + self._t_delay, Action(self, '_output_update', data)), (time + self._t_rd2clr, Action(self, '_read_done'))])
def x_read(self, time, signal): """ Address enable input. Event triggered. """ okeq(self._state, 'idle') self._state = 'reading' value = self._ram_content.get(self._addr, 0) self._ram_content[self._addr] = 0 self.seq.addall([(time + self._t_r2wc, Action(self, '_read_done')), (time + self._t_delay, Action(self, '_output_update', value))])
def _control_changed(self, time): okeq(self._state, 'controls-changing') # countdown n control changes to end of change period. self._n_control_changes_due -= 1 if self._n_control_changes_due == 0: # Last of 'N' control changes --> change period delay is over. # Reset the interlocks preventing >1 change on the same input. self._or_changing = False self._clear_changing = False # Return to 'idle' or 'clearing' state. if self._clear_enabled: self._state = 'idle-with-clearing' else: self._state = 'idle'
def enable_or(self, time, signal): or_value = signal.state != 0 if or_value == self._or_enabled: return okin(self._state, ['idle', 'idle-with-clearing', 'controls-changing']) okeq(self._or_changing, False) # Internal stored-value and output are unaffected. # We just need a quiet moment to register the control change. self._state = 'controls-changing' # record new value of control. self._or_enabled = or_value # prevent overlapping change on same input. self._or_changing = True # count control changes to allow multiple controls within a change. self._n_control_changes_due += 1 self.act(time + self._t_eor, '_control_changed')
def _input_event(self, i_in, time, state): if self._state == 'idle': self._state = 'get-updates' self._time = time if self.pass_all_events: # just do it now self._update_output(time) else: # schedule an update after # all 'normal' events # at this timepoint. self.seq.add(((time, -9999), Action(self, '_update_output'))) else: okeq(self._state, 'get-updates') okeq(time, self._time)
def _update_output(self, time): okeq(self._state, 'get-updates') okeq(time, self._time) val = 0 for sig, width in zip(self._inputs, self._input_bitwidths): this = sig.state if not isinstance(this, (int, float)): val = SIG_UNDEF break else: mask = (2**width) - 1 this = int(this) & mask val <<= width val |= this self.output.set(time, val) self._state = 'idle'
def clear(self, time, signal): clear_value = signal.state != 0 if clear_value == self._clear_enabled: return okin(self._state, ['idle', 'idle-with-clearing', 'controls-changing']) okeq(self._clear_changing, False) self._state = 'controls-changing' # record new value of control. self._clear_enabled = clear_value # prevent overlapping change on same input. self._clear_changing = True # count control changes to allow multiple controls within a change. self._n_control_changes_due += 1 self.act(time + self._t_clear, '_control_changed') if clear_value and self._value: # Also have a stored '1' to drop. self._value = 0 self.output.set(time, SIG_UNDEF) self.act(time + self._t_drop, '_dropped')
def _a_changed(self, time): okeq(self._state, 'set-addr') self._state = 'idle'
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('') sig1.trace() w01.output.trace() x01.out.trace() SEQ.add((100., lambda t: sig1.set(t, 1))) SEQ.add((200., lambda t: sig1.set(t, 0))) SEQ.add((300., lambda t: sig1.set(t, 1))) print('\nrun to 100.1') SEQ.run(100.1) print('check sig=1, wire=0, xor=x')
def _a_cleared(self, time): okeq(self._state, 'disabling-address') self._state = 'idle'
def x_aclr(self, time, signal): okeq(self._state, 'active') self._state = 'disabling-address' self.seq.add((time + self._t_clr2ad, Action(self, '_a_cleared')))
def _read_done(self, time): # Thus just blocks a re-read # or clear too soon after read. okeq(self._state, 'reading') self._state = 'active'
def _a_enabled(self, time): okeq(self._state, 'enabling-address') self._state = 'active'
def _read_done(self, time): # Thus just blocks a re-read # or clear too soon after read. okeq(self._state, 'reading') self._state = 'read-but-not-written'
def _carry_out(self, time): okeq(self._state, 'carry-propagating') self.x_carry_out.set(time, 1) self._state = 'idle'
def addr(self, time, signal): """Address input.""" okeq(self._state, 'idle') self._state = 'set-addr' self._addr = signal.state self.seq.add((time + self._t_a2sel, Action(self, '_a_changed')))
def _write_done(self, time): okeq(self._state, 'writing') self._state = 'read-and-written'