From ab806060363db8cdb4c2637f08d751004be7ad4c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 27 May 2020 18:40:45 +0200 Subject: [PATCH] soc/core/uart: move WishboneStreamingBridge in it and rename to Stream2Wishbone. --- litex/soc/cores/uart.py | 126 +++++++++++++++++++++- litex/soc/interconnect/wishbonebridge.py | 127 ----------------------- 2 files changed, 123 insertions(+), 130 deletions(-) delete mode 100644 litex/soc/interconnect/wishbonebridge.py diff --git a/litex/soc/cores/uart.py b/litex/soc/cores/uart.py index 011fe5503..f9ffeace9 100644 --- a/litex/soc/cores/uart.py +++ b/litex/soc/cores/uart.py @@ -4,14 +4,17 @@ # This file is Copyright (c) 2018 Tim 'mithro' Ansell # License: BSD +from math import log2 + from migen import * from migen.genlib.record import Record from migen.genlib.cdc import MultiReg +from migen.genlib.misc import WaitTimer from litex.soc.interconnect.csr import * from litex.soc.interconnect.csr_eventmanager import * +from litex.soc.interconnect import wishbone from litex.soc.interconnect import stream -from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge # Common ------------------------------------------------------------------------------------------- @@ -239,10 +242,127 @@ class UART(Module, AutoCSR, UARTInterface): self.ev.rx.trigger.eq(~rx_fifo.source.valid) ] -class UARTBone(WishboneStreamingBridge): +# UART Bone ---------------------------------------------------------------------------------------- + +CMD_WRITE = 0x01 +CMD_READ = 0x02 + +class Stream2Wishbone(Module): + def __init__(self, phy, clk_freq, data_width=32, address_width=32): + self.wishbone = wishbone.Interface() + self.comb += phy.source.ready.eq(1) # Always accept incoming stream. + + # # # + + cmd = Signal(8, reset_less=True) + length = Signal(8, reset_less=True) + address = Signal(address_width, reset_less=True) + data = Signal(data_width, reset_less=True) + bytes_count = Signal(int(log2(data_width//8)), reset_less=True) + words_count = Signal(8, reset_less=True) + + bytes_count_done = (bytes_count == (data_width//8 - 1)) + words_count_done = (words_count == (length - 1)) + + fsm = ResetInserter()(FSM(reset_state="RECEIVE-CMD")) + timer = WaitTimer(int(100e-3*clk_freq)) + self.comb += timer.wait.eq(~fsm.ongoing("RECEIVE-CMD")) + self.submodules += fsm, timer + self.comb += fsm.reset.eq(timer.done) + fsm.act("RECEIVE-CMD", + NextValue(bytes_count, 0), + NextValue(words_count, 0), + If(phy.source.valid, + NextValue(cmd, phy.source.data), + NextState("RECEIVE-LENGTH") + ) + ) + fsm.act("RECEIVE-LENGTH", + If(phy.source.valid, + NextValue(length, phy.source.data), + NextState("RECEIVE-ADDRESS") + ) + ) + fsm.act("RECEIVE-ADDRESS", + If(phy.source.valid, + NextValue(address, Cat(phy.source.data, address)), + NextValue(bytes_count, bytes_count + 1), + If(bytes_count_done, + If(cmd == CMD_WRITE, + NextState("RECEIVE-DATA") + ).Elif(cmd == CMD_READ, + NextState("READ-DATA") + ).Else( + NextState("RECEIVE-CMD") + ) + ) + ) + ) + fsm.act("RECEIVE-DATA", + If(phy.source.valid, + NextValue(data, Cat(phy.source.data, data)), + NextValue(bytes_count, bytes_count + 1), + If(bytes_count_done, + NextState("WRITE-DATA") + ) + ) + ) + self.comb += [ + self.wishbone.adr.eq(address), + self.wishbone.dat_w.eq(data), + self.wishbone.sel.eq(2**(data_width//8) - 1) + ] + fsm.act("WRITE-DATA", + self.wishbone.stb.eq(1), + self.wishbone.we.eq(1), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + NextValue(words_count, words_count + 1), + NextValue(address, address + 1), + If(words_count_done, + NextState("RECEIVE-CMD") + ).Else( + NextState("RECEIVE-DATA") + ) + ) + ) + fsm.act("READ-DATA", + self.wishbone.stb.eq(1), + self.wishbone.we.eq(0), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + NextValue(data, self.wishbone.dat_r), + NextState("SEND-DATA") + ) + ) + cases = {} + for i, n in enumerate(reversed(range(data_width//8))): + cases[i] = phy.sink.data.eq(data[8*n:]) + self.comb += Case(bytes_count, cases) + fsm.act("SEND-DATA", + phy.sink.valid.eq(1), + If(phy.sink.ready, + NextValue(bytes_count, bytes_count + 1), + If(bytes_count_done, + NextValue(words_count, words_count + 1), + NextValue(address, address + 1), + If(words_count_done, + NextState("RECEIVE-CMD") + ).Else( + NextState("READ-DATA") + ) + ) + ) + ) + self.comb += phy.sink.last.eq(bytes_count_done & words_count_done) + if hasattr(phy.sink, "length"): + self.comb += phy.sink.length.eq((data_width//8)*length) + + +class UARTBone(Stream2Wishbone): def __init__(self, pads, clk_freq, baudrate=115200): self.submodules.phy = RS232PHY(pads, clk_freq, baudrate) - WishboneStreamingBridge.__init__(self, self.phy, clk_freq) + Stream2Wishbone.__init__(self, self.phy, clk_freq) class UARTWishboneBridge(UARTBone): pass diff --git a/litex/soc/interconnect/wishbonebridge.py b/litex/soc/interconnect/wishbonebridge.py deleted file mode 100644 index 153a94397..000000000 --- a/litex/soc/interconnect/wishbonebridge.py +++ /dev/null @@ -1,127 +0,0 @@ -# This file is Copyright (c) 2015-2020 Florent Kermarrec -# License: BSD - -from math import log2 - -from migen import * - -from migen.genlib.misc import WaitTimer - -from litex.soc.interconnect import wishbone -from litex.soc.interconnect import stream - -# Wishbone Streaming Bridge ------------------------------------------------------------------------ - -CMD_WRITE = 0x01 -CMD_READ = 0x02 - -class WishboneStreamingBridge(Module): - def __init__(self, phy, clk_freq, data_width=32, address_width=32): - self.wishbone = wishbone.Interface() - self.comb += phy.source.ready.eq(1) # Always accept incoming stream. - - # # # - - cmd = Signal(8, reset_less=True) - length = Signal(8, reset_less=True) - address = Signal(address_width, reset_less=True) - data = Signal(data_width, reset_less=True) - bytes_count = Signal(int(log2(data_width//8)), reset_less=True) - words_count = Signal(8, reset_less=True) - - bytes_count_done = (bytes_count == (data_width//8 - 1)) - words_count_done = (words_count == (length - 1)) - - fsm = ResetInserter()(FSM(reset_state="RECEIVE-CMD")) - timer = WaitTimer(int(100e-3*clk_freq)) - self.comb += timer.wait.eq(~fsm.ongoing("RECEIVE-CMD")) - self.submodules += fsm, timer - self.comb += fsm.reset.eq(timer.done) - fsm.act("RECEIVE-CMD", - NextValue(bytes_count, 0), - NextValue(words_count, 0), - If(phy.source.valid, - NextValue(cmd, phy.source.data), - NextState("RECEIVE-LENGTH") - ) - ) - fsm.act("RECEIVE-LENGTH", - If(phy.source.valid, - NextValue(length, phy.source.data), - NextState("RECEIVE-ADDRESS") - ) - ) - fsm.act("RECEIVE-ADDRESS", - If(phy.source.valid, - NextValue(address, Cat(phy.source.data, address)), - NextValue(bytes_count, bytes_count + 1), - If(bytes_count_done, - If(cmd == CMD_WRITE, - NextState("RECEIVE-DATA") - ).Elif(cmd == CMD_READ, - NextState("READ-DATA") - ).Else( - NextState("RECEIVE-CMD") - ) - ) - ) - ) - fsm.act("RECEIVE-DATA", - If(phy.source.valid, - NextValue(data, Cat(phy.source.data, data)), - NextValue(bytes_count, bytes_count + 1), - If(bytes_count_done, - NextState("WRITE-DATA") - ) - ) - ) - self.comb += [ - self.wishbone.adr.eq(address), - self.wishbone.dat_w.eq(data), - self.wishbone.sel.eq(2**(data_width//8) - 1) - ] - fsm.act("WRITE-DATA", - self.wishbone.stb.eq(1), - self.wishbone.we.eq(1), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - NextValue(words_count, words_count + 1), - NextValue(address, address + 1), - If(words_count_done, - NextState("RECEIVE-CMD") - ).Else( - NextState("RECEIVE-DATA") - ) - ) - ) - fsm.act("READ-DATA", - self.wishbone.stb.eq(1), - self.wishbone.we.eq(0), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - NextValue(data, self.wishbone.dat_r), - NextState("SEND-DATA") - ) - ) - cases = {} - for i, n in enumerate(reversed(range(data_width//8))): - cases[i] = phy.sink.data.eq(data[8*n:]) - self.comb += Case(bytes_count, cases) - fsm.act("SEND-DATA", - phy.sink.valid.eq(1), - If(phy.sink.ready, - NextValue(bytes_count, bytes_count + 1), - If(bytes_count_done, - NextValue(words_count, words_count + 1), - NextValue(address, address + 1), - If(words_count_done, - NextState("RECEIVE-CMD") - ).Else( - NextState("READ-DATA") - ) - ) - ) - ) - self.comb += phy.sink.last.eq(bytes_count_done & words_count_done) - if hasattr(phy.sink, "length"): - self.comb += phy.sink.length.eq((data_width//8)*length)