class Streamer(Component): stream: In(StreamerSignature) _seq: Out(SequencerSignature) efb: Out(EfbWishbone) def __init__(self): super().__init__() self.seqmod = Sequencer() def elaborate(self, plat): m = Module() m.submodules.seqmod = self.seqmod ufm_busy = Signal(2) prev_state = Signal(1) just_entered = Signal(1) connect(m, self.seqmod.ctl, self._seq) connect(m, flipped(self.efb), self.seqmod.efb) def next_state_if_asserted(stim, state): with m.If(stim): m.next = state with m.FSM() as fsm: # noqa: F841 with m.State("IDLE"): next_state_if_asserted(self.stream.stb, "ENABLE_CONFIG") with m.State("ENABLE_CONFIG"): next_state_if_asserted(self._seq.ctl.done, "POLL_STATUS_1") # Bleh... easier to make each data strobe an individual state. with m.State("POLL_STATUS_1"): next_state_if_asserted(self._seq.rd.stb, "POLL_STATUS_2") with m.State("POLL_STATUS_2"): next_state_if_asserted(self._seq.rd.stb, "POLL_STATUS_3") with m.State("POLL_STATUS_3"): next_state_if_asserted(self._seq.rd.stb, "POLL_STATUS_4") with m.State("POLL_STATUS_4"): next_state_if_asserted(self._seq.rd.stb, "POLL_STATUS_5") with m.State("POLL_STATUS_5"): with m.If(self._seq.ctl.done): m.next = "SET_UFM_ADDR" next_state_if_asserted(ufm_busy, "POLL_STATUS_1") with m.State("SET_UFM_ADDR"): next_state_if_asserted(self._seq.ctl.done, "READ_UFM") with m.State("READ_UFM"): next_state_if_asserted(self._seq.ctl.done, "DISABLE_CONFIG") with m.State("DISABLE_CONFIG"): next_state_if_asserted(self._seq.ctl.done, "BYPASS") with m.State("BYPASS"): with m.If(self._seq.ctl.done): m.next = "IDLE" next_state_if_asserted(self.stream.stb, "ENABLE_CONFIG") prev_state.width = fsm.state.width m.d.sync += prev_state.eq(fsm.state) m.d.comb += just_entered.eq(prev_state != fsm.state)