From 597d778cf6cbc8cd90312ab280f9067531437972 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 26 Dec 2018 10:10:27 +0000 Subject: [PATCH] examples: add an FSM usage example (UART receiver). --- examples/fsm.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++ nmigen/hdl/dsl.py | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 examples/fsm.py diff --git a/examples/fsm.py b/examples/fsm.py new file mode 100644 index 0000000..2f7ed50 --- /dev/null +++ b/examples/fsm.py @@ -0,0 +1,60 @@ +from nmigen import * +from nmigen.cli import main + + +class UARTReceiver: + def __init__(self, divisor): + self.divisor = divisor + + self.i = Signal() + self.data = Signal(8) + self.rdy = Signal() + self.ack = Signal() + self.err = Signal() + + def get_fragment(self, platform): + m = Module() + + ctr = Signal(max=self.divisor) + stb = Signal() + with m.If(ctr == 0): + m.d.sync += ctr.eq(self.divisor - 1) + m.d.comb += stb.eq(1) + with m.Else(): + m.d.sync += ctr.eq(ctr - 1) + + bit = Signal(3) + with m.FSM(): + with m.State("START"): + with m.If(~self.i): + m.next = "DATA" + m.d.sync += [ + ctr.eq(self.divisor // 2), + bit.eq(7), + ] + with m.State("DATA"): + with m.If(stb): + m.d.sync += [ + bit.eq(bit - 1), + self.data.eq(Cat(self.i, self.data)) + ] + with m.If(bit == 0): + m.next = "STOP" + with m.State("STOP"): + with m.If(stb): + with m.If(self.i): + m.next = "DONE" + with m.Else(): + m.next = "ERROR" + with m.State("DONE"): + m.d.comb += self.rdy.eq(1) + with m.If(self.ack): + m.next = "START" + with m.State("ERROR"): + m.d.comb += self.err.eq(1) + return m.lower(platform) + + +if __name__ == "__main__": + rx = UARTReceiver(20) + main(rx, ports=[rx.i, rx.data, rx.rdy, rx.ack, rx.err]) diff --git a/nmigen/hdl/dsl.py b/nmigen/hdl/dsl.py index 7a531a7..eec3f6e 100644 --- a/nmigen/hdl/dsl.py +++ b/nmigen/hdl/dsl.py @@ -299,7 +299,7 @@ class Module(_ModuleBuilderRoot): fsm_signal.nbits = bits_for(len(fsm_encoding) - 1) # The FSM is encoded such that the state with encoding 0 is always the reset state. fsm_decoding = {n: s for s, n in fsm_encoding.items()} - fsm_signal.decoder = lambda v: "{}/{}".format(fsm_decoding[n], n) + fsm_signal.decoder = lambda n: "{}/{}".format(fsm_decoding[n], n) self._statements.append(Switch(fsm_signal, OrderedDict((fsm_encoding[name], stmts) for name, stmts in fsm_states.items()))) -- 2.30.2