diff --git a/milkymist/uart/__init__.py b/milkymist/uart/__init__.py index 12ad58550..3d052619c 100644 --- a/milkymist/uart/__init__.py +++ b/milkymist/uart/__init__.py @@ -9,7 +9,8 @@ class UART: self._divisor = RegisterField("divisor", 16, reset=int(clk_freq/baud/16)) self._tx_event = EventSourceLevel() - self.events = EventManager(self._tx_event) + self._rx_event = EventSourcePulse() + self.events = EventManager(self._tx_event, self._rx_event) self.bank = csrgen.Bank([self._rxtx, self._divisor] + self.events.get_registers(), address=address) @@ -28,10 +29,11 @@ class UART: enable16_counter.eq(self._divisor.field.r - 1)) ] + # TX tx_reg = Signal(BV(8)) tx_bitcount = Signal(BV(4)) tx_count16 = Signal(BV(4)) - tx_busy = Signal() + tx_busy = self._tx_event.trigger sync += [ If(self._rxtx.re, tx_reg.eq(self._rxtx.r), @@ -55,7 +57,53 @@ class UART: ) ) ] - comb.append(self._tx_event.trigger.eq(tx_busy)) + + # RX + rx0 = Signal() # sychronize + rx = Signal() + sync += [ + rx0.eq(self.rx), + rx.eq(rx0) + ] + rx_r = Signal() + rx_reg = Signal(BV(8)) + rx_bitcount = Signal(BV(4)) + rx_count16 = Signal(BV(4)) + rx_busy = Signal() + rx_done = self._rx_event.trigger + rx_data = self._rxtx.w + sync += [ + rx_done.eq(0), + If(enable16, + rx_r.eq(rx), + If(~rx_busy, + If(~rx & rx_r, # look for start bit + rx_busy.eq(1), + rx_count16.eq(7), + rx_bitcount.eq(0) + ) + ).Else( + rx_count16.eq(rx_count16 + 1), + If(rx_count16 == 0, + rx_bitcount.eq(rx_bitcount + 1), + + If(rx_bitcount == 0, + If(rx, # verify start bit + rx_busy.eq(0) + ) + ).Elif(rx_bitcount == 9, + rx_busy.eq(0), + If(rx, # verify stop bit + rx_data.eq(rx_reg), + rx_done.eq(1) + ) + ).Else( + rx_reg.eq(Cat(rx_reg[1:], rx)) + ) + ) + ) + ) + ] return self.bank.get_fragment() \ + self.events.get_fragment() \