def _dropped(self, time): # Emit a dropped '1' as a carry (and stabilise stored value = 0). okin(self._state, ['controls-changing', 'dropping']) # N.B. should NOT occur in 'idle' state. # N.B. no state change unless 'dropping' if self._state == 'dropping': # A special state, just to block control changes during 'dropping', # only entered when input arrives during 'idle-with-clearing'. self._state = 'idle-with-clearing' # 'ELSE' get here while clear goes 0 to 1 --> no state change. # Set stored-value stable. self.output.set(time, 0) # Send carry-out. self.x_carry_out.set(time, 1)
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 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 input(self, time, signal): if signal.state == 0: # Ignore, in this case return okin(self._state, ['idle', 'idle-with-clearing']) self.output.set(time, SIG_UNDEF) if self._state == 'idle': self._state = 'value-toggling' toggle_delay = [self._t_0_1, self._t_1_0][self._value] if self._or_enabled: # In this mode, any input leaves us at '1' # (and we never emit carries). # Note: delay is the same, but will not then emit a carry. self._value = 1 else: self._value = 1 - self._value # invert --> output after delay self.act(time + toggle_delay, '_toggle_output') elif self._state == 'idle-with-clearing': self._state = 'dropping' # Block control changes while dropping. self.act(time + self._t_0_1 + self._t_drop, '_dropped') else: assert False # should never be able to get here.
def x_aclr(self, time, signal): okin(self._state, ('read-but-not-written', 'read-and-written')) self._state = 'disabling-address' self.seq.add((time + self._t_c2a, Action(self, '_a_cleared')))