uart: create phy directory and move phy logic to serial.py (will enable selecting...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 1 Mar 2015 10:58:46 +0000 (11:58 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 1 Mar 2015 11:14:34 +0000 (12:14 +0100)
misoclib/com/uart/__init__.py
misoclib/com/uart/phy/__init__.py [new file with mode: 0644]
misoclib/com/uart/phy/serial.py [new file with mode: 0644]
misoclib/com/uart/test/test_serial_phy.py [new file with mode: 0644]
misoclib/soc/__init__.py
misoclib/soc/sdram.py

index ae82797e1a0bc43481e316af8f7143b6e87a3aed..44a74e062798f100dc933d3f089cf340dc355c6b 100644 (file)
 from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
 from migen.bank.description import *
 from migen.bank.eventmanager import *
 from migen.genlib.record import Record
 from migen.flow.actor import Sink, Source
 
-class UARTRX(Module):
-       def __init__(self, pads, tuning_word):
-               self.source = Source([("d", 8)])
-
-               ###
-
-               uart_clk_rxen = Signal()
-               phase_accumulator_rx = Signal(32)
-
-               rx = Signal()
-               self.specials += MultiReg(pads.rx, rx)
-               rx_r = Signal()
-               rx_reg = Signal(8)
-               rx_bitcount = Signal(4)
-               rx_busy = Signal()
-               rx_done = self.source.stb
-               rx_data = self.source.d
-               self.sync += [
-                       rx_done.eq(0),
-                       rx_r.eq(rx),
-                       If(~rx_busy,
-                               If(~rx & rx_r, # look for start bit
-                                       rx_busy.eq(1),
-                                       rx_bitcount.eq(0),
-                               )
-                       ).Else(
-                               If(uart_clk_rxen,
-                                       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))
-                                       )
-                               )
-                       )
-               ]
-               self.sync += \
-                               If(rx_busy,
-                                       Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word)
-                               ).Else(
-                                       Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
-                               )
-
-class UARTTX(Module):
-       def __init__(self, pads, tuning_word):
-               self.sink = Sink([("d", 8)])
-
-               ###
-
-               uart_clk_txen = Signal()
-               phase_accumulator_tx = Signal(32)
-
-               pads.tx.reset = 1
-
-               tx_reg = Signal(8)
-               tx_bitcount = Signal(4)
-               tx_busy = Signal()
-               self.sync += [
-                       self.sink.ack.eq(0),
-                       If(self.sink.stb & ~tx_busy & ~self.sink.ack,
-                               tx_reg.eq(self.sink.d),
-                               tx_bitcount.eq(0),
-                               tx_busy.eq(1),
-                               pads.tx.eq(0)
-                       ).Elif(uart_clk_txen & tx_busy,
-                               tx_bitcount.eq(tx_bitcount + 1),
-                               If(tx_bitcount == 8,
-                                       pads.tx.eq(1)
-                               ).Elif(tx_bitcount == 9,
-                                       pads.tx.eq(1),
-                                       tx_busy.eq(0),
-                                       self.sink.ack.eq(1),
-                               ).Else(
-                                       pads.tx.eq(tx_reg[0]),
-                                       tx_reg.eq(Cat(tx_reg[1:], 0))
-                               )
-                       )
-               ]
-               self.sync += [
-                               If(tx_busy,
-                                       Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + tuning_word)
-                               ).Else(
-                                       Cat(phase_accumulator_tx, uart_clk_txen).eq(0)
-                               )
-               ]
-
 class UART(Module, AutoCSR):
-       def __init__(self, pads, clk_freq, baud=115200):
+       def __init__(self, phy):
                self._rxtx = CSR(8)
 
                self.submodules.ev = EventManager()
                self.ev.tx = EventSourcePulse()
                self.ev.rx = EventSourcePulse()
                self.ev.finalize()
-
-               # Tuning word value
-               self._tuning_word = CSRStorage(32, reset=int((baud/clk_freq)*2**32))
-               tuning_word = self._tuning_word.storage
-
                ###
-
-               self.submodules.rx = UARTRX(pads, tuning_word)
-               self.submodules.tx = UARTTX(pads, tuning_word)
-
                self.sync += [
                        If(self._rxtx.re,
-                               self.tx.sink.stb.eq(1),
-                               self.tx.sink.d.eq(self._rxtx.r),
-                       ).Elif(self.tx.sink.ack,
-                               self.tx.sink.stb.eq(0)
+                               phy.tx.sink.stb.eq(1),
+                               phy.tx.sink.d.eq(self._rxtx.r),
+                       ).Elif(phy.tx.sink.ack,
+                               phy.tx.sink.stb.eq(0)
                        ),
-                       If(self.rx.source.stb,
-                               self._rxtx.w.eq(self.rx.source.d)
+                       If(phy.rx.source.stb,
+                               self._rxtx.w.eq(phy.rx.source.d)
                        )
                ]
                self.comb += [
-                       self.ev.tx.trigger.eq(self.tx.sink.stb & self.tx.sink.ack),
-                       self.ev.rx.trigger.eq(self.rx.source.stb) #self.rx.source.ack supposed to be always 1
+                       self.ev.tx.trigger.eq(phy.tx.sink.stb & phy.tx.sink.ack),
+                       self.ev.rx.trigger.eq(phy.rx.source.stb) #phy.rx.source.ack supposed to be always 1
                ]
-
-class UARTTB(Module):
-       def __init__(self):
-               self.clk_freq = 83333333
-               self.baud = 3000000
-               self.pads = Record([("rx", 1), ("tx", 1)])
-               self.submodules.slave = UART(self.pads, self.clk_freq, self.baud)
-
-       def wait_for(self, ns_time):
-               freq_in_ghz = self.clk_freq/(10**9)
-               period = 1/freq_in_ghz
-               num_loops = int(ns_time/period)
-               for i in range(num_loops+1):
-                       yield
-
-       def gen_simulation(self, selfp):
-               baud_in_ghz = self.baud/(10**9)
-               uart_period = int(1/baud_in_ghz)
-               half_uart_period = int(1/(2*baud_in_ghz))
-
-               # Set TX an RX lines idle
-               selfp.pads.tx = 1
-               selfp.pads.rx = 1
-               yield
-
-               # First send a few characters
-
-               tx_string = "01234"
-               print("Sending string: " + tx_string)
-               for c in tx_string:
-                       selfp.slave._r_rxtx.r = ord(c)
-                       selfp.slave._r_rxtx.re = 1
-                       yield
-                       selfp.slave._r_rxtx.re = 0
-
-                       yield from self.wait_for(half_uart_period)
-
-                       if selfp.pads.tx:
-                               print("FAILURE: no start bit sent")
-
-                       val = 0
-                       for i in range(8):
-                               yield from self.wait_for(uart_period)
-                               val >>= 1
-                               if selfp.pads.tx:
-                                       val |= 0x80
-
-                       yield from self.wait_for(uart_period)
-
-                       if selfp.pads.tx == 0:
-                               print("FAILURE: no stop bit sent")
-
-                       if ord(c) != val:
-                               print("FAILURE: sent decimal value "+str(val)+" (char "+chr(val)+") instead of "+c)
-                       else:
-                               print("SUCCESS: sent "+c)
-                       while selfp.slave.ev.tx.trigger != 1:
-                               yield
-
-               # Then receive a character
-
-               rx_string = '5'
-               print("Receiving character "+rx_string)
-               rx_value = ord(rx_string)
-               for i in range(11):
-                       if (i == 0):
-                               # start bit
-                               selfp.pads.rx = 0
-                       elif (i == 9):
-                               # stop bit
-                               selfp.pads.rx = 1
-                       elif (i == 10):
-                               selfp.pads.rx = 1
-                               break
-                       else:
-                               selfp.pads.rx = 1 if (rx_value & 1) else 0
-                               rx_value >>= 1
-                       yield from self.wait_for(uart_period)
-
-               rx_value = ord(rx_string)
-               received_value = selfp.slave._r_rxtx.w
-               if (received_value == rx_value):
-                       print("RX SUCCESS: ")
-               else:
-                       print("RX FAILURE: ")
-
-               print("received "+chr(received_value))
-
-               while True:
-                       yield
-
-if __name__ == "__main__":
-       from migen.sim.generic import Simulator, TopLevel
-       from migen.sim import icarus
-       with Simulator(UARTTB(), TopLevel("top.vcd", clk_period=int(1/0.08333333)), icarus.Runner(keep_files=False)) as s:
-               s.run(20000)
diff --git a/misoclib/com/uart/phy/__init__.py b/misoclib/com/uart/phy/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/misoclib/com/uart/phy/serial.py b/misoclib/com/uart/phy/serial.py
new file mode 100644 (file)
index 0000000..35f5b7d
--- /dev/null
@@ -0,0 +1,101 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+from migen.flow.actor import Sink, Source
+
+class UARTPHYSerialRX(Module):
+       def __init__(self, pads, tuning_word):
+               self.source = Source([("d", 8)])
+               ###
+               uart_clk_rxen = Signal()
+               phase_accumulator_rx = Signal(32)
+
+               rx = Signal()
+               self.specials += MultiReg(pads.rx, rx)
+               rx_r = Signal()
+               rx_reg = Signal(8)
+               rx_bitcount = Signal(4)
+               rx_busy = Signal()
+               rx_done = self.source.stb
+               rx_data = self.source.d
+               self.sync += [
+                       rx_done.eq(0),
+                       rx_r.eq(rx),
+                       If(~rx_busy,
+                               If(~rx & rx_r, # look for start bit
+                                       rx_busy.eq(1),
+                                       rx_bitcount.eq(0),
+                               )
+                       ).Else(
+                               If(uart_clk_rxen,
+                                       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))
+                                       )
+                               )
+                       )
+               ]
+               self.sync += \
+                               If(rx_busy,
+                                       Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word)
+                               ).Else(
+                                       Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
+                               )
+
+class UARTPHYSerialTX(Module):
+       def __init__(self, pads, tuning_word):
+               self.sink = Sink([("d", 8)])
+               ###
+               uart_clk_txen = Signal()
+               phase_accumulator_tx = Signal(32)
+
+               pads.tx.reset = 1
+
+               tx_reg = Signal(8)
+               tx_bitcount = Signal(4)
+               tx_busy = Signal()
+               self.sync += [
+                       self.sink.ack.eq(0),
+                       If(self.sink.stb & ~tx_busy & ~self.sink.ack,
+                               tx_reg.eq(self.sink.d),
+                               tx_bitcount.eq(0),
+                               tx_busy.eq(1),
+                               pads.tx.eq(0)
+                       ).Elif(uart_clk_txen & tx_busy,
+                               tx_bitcount.eq(tx_bitcount + 1),
+                               If(tx_bitcount == 8,
+                                       pads.tx.eq(1)
+                               ).Elif(tx_bitcount == 9,
+                                       pads.tx.eq(1),
+                                       tx_busy.eq(0),
+                                       self.sink.ack.eq(1),
+                               ).Else(
+                                       pads.tx.eq(tx_reg[0]),
+                                       tx_reg.eq(Cat(tx_reg[1:], 0))
+                               )
+                       )
+               ]
+               self.sync += [
+                               If(tx_busy,
+                                       Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + tuning_word)
+                               ).Else(
+                                       Cat(phase_accumulator_tx, uart_clk_txen).eq(0)
+                               )
+               ]
+
+class UARTPHYSerial(Module, AutoCSR):
+       def __init__(self, pads, clk_freq, baudrate=115200):
+               self._tuning_word = CSRStorage(32, reset=int((baudrate/clk_freq)*2**32))
+               self.submodules.tx = UARTPHYSerialTX(pads, self._tuning_word.storage)
+               self.submodules.rx = UARTPHYSerialRX(pads, self._tuning_word.storage)
+               self.sink, self.source = self.tx.sink, self.rx.source
diff --git a/misoclib/com/uart/test/test_serial_phy.py b/misoclib/com/uart/test/test_serial_phy.py
new file mode 100644 (file)
index 0000000..e7185c9
--- /dev/null
@@ -0,0 +1,96 @@
+# XXX Adapt test to new architecture
+class UARTTB(Module):
+       def __init__(self):
+               self.clk_freq = 83333333
+               self.baud = 3000000
+               self.pads = Record([("rx", 1), ("tx", 1)])
+               self.submodules.slave = UART(self.pads, self.clk_freq, self.baud)
+
+       def wait_for(self, ns_time):
+               freq_in_ghz = self.clk_freq/(10**9)
+               period = 1/freq_in_ghz
+               num_loops = int(ns_time/period)
+               for i in range(num_loops+1):
+                       yield
+
+       def gen_simulation(self, selfp):
+               baud_in_ghz = self.baud/(10**9)
+               uart_period = int(1/baud_in_ghz)
+               half_uart_period = int(1/(2*baud_in_ghz))
+
+               # Set TX an RX lines idle
+               selfp.pads.tx = 1
+               selfp.pads.rx = 1
+               yield
+
+               # First send a few characters
+
+               tx_string = "01234"
+               print("Sending string: " + tx_string)
+               for c in tx_string:
+                       selfp.slave._r_rxtx.r = ord(c)
+                       selfp.slave._r_rxtx.re = 1
+                       yield
+                       selfp.slave._r_rxtx.re = 0
+
+                       yield from self.wait_for(half_uart_period)
+
+                       if selfp.pads.tx:
+                               print("FAILURE: no start bit sent")
+
+                       val = 0
+                       for i in range(8):
+                               yield from self.wait_for(uart_period)
+                               val >>= 1
+                               if selfp.pads.tx:
+                                       val |= 0x80
+
+                       yield from self.wait_for(uart_period)
+
+                       if selfp.pads.tx == 0:
+                               print("FAILURE: no stop bit sent")
+
+                       if ord(c) != val:
+                               print("FAILURE: sent decimal value "+str(val)+" (char "+chr(val)+") instead of "+c)
+                       else:
+                               print("SUCCESS: sent "+c)
+                       while selfp.slave.ev.tx.trigger != 1:
+                               yield
+
+               # Then receive a character
+
+               rx_string = '5'
+               print("Receiving character "+rx_string)
+               rx_value = ord(rx_string)
+               for i in range(11):
+                       if (i == 0):
+                               # start bit
+                               selfp.pads.rx = 0
+                       elif (i == 9):
+                               # stop bit
+                               selfp.pads.rx = 1
+                       elif (i == 10):
+                               selfp.pads.rx = 1
+                               break
+                       else:
+                               selfp.pads.rx = 1 if (rx_value & 1) else 0
+                               rx_value >>= 1
+                       yield from self.wait_for(uart_period)
+
+               rx_value = ord(rx_string)
+               received_value = selfp.slave._r_rxtx.w
+               if (received_value == rx_value):
+                       print("RX SUCCESS: ")
+               else:
+                       print("RX FAILURE: ")
+
+               print("received "+chr(received_value))
+
+               while True:
+                       yield
+
+if __name__ == "__main__":
+       from migen.sim.generic import Simulator, TopLevel
+       from migen.sim import icarus
+       with Simulator(UARTTB(), TopLevel("top.vcd", clk_period=int(1/0.08333333)), icarus.Runner(keep_files=False)) as s:
+               s.run(20000)
index f7d479a0a92f3e83bf13deb714e713f59771ceea..b6ac22f83fb577a64b971ee588c28bc7f22fc577 100644 (file)
@@ -6,6 +6,7 @@ from migen.fhdl.std import *
 from migen.bank import csrgen
 from migen.bus import wishbone, csr, wishbone2csr
 
+from misoclib.com.uart.phy.serial import UARTPHYSerial
 from misoclib.com import uart
 from misoclib.cpu import CPU, lm32, mor1kx
 from misoclib.cpu.peripherals import identifier, timer
@@ -16,11 +17,12 @@ def mem_decoder(address, start=26, end=29):
 class SoC(Module):
        csr_map = {
                "crg":                                  0, # user
-               "uart":                                 1, # provided by default (optional)
-               "identifier":                   2, # provided by default (optional)
-               "timer0":                               3, # provided by default (optional)
-               "buttons":                              4, # user
-               "leds":                                 5, # user
+               "uart_phy":                             1, # provided by default (optional)
+               "uart":                                 2, # provided by default (optional)
+               "identifier":                   3, # provided by default (optional)
+               "timer0":                               4, # provided by default (optional)
+               "buttons":                              5, # user
+               "leds":                                 6, # user
        }
        interrupt_map = {
                "uart":                 0,
@@ -105,7 +107,8 @@ class SoC(Module):
                        self.register_mem("csr", self.mem_map["csr"], self.wishbone2csr.wishbone)
 
                        if with_uart:
-                               self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=uart_baudrate)
+                               self.submodules.uart_phy = UARTPHYSerial(platform.request("serial"), clk_freq, uart_baudrate)
+                               self.submodules.uart = uart.UART(self.uart_phy)
 
                        if with_identifier:
                                platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
index c8534329faf5f87c461f9fc5911e48f7db89e0cb..3dead170f353bb591fa7a3cf884d38f7a18d40dd 100644 (file)
@@ -9,11 +9,11 @@ from misoclib.soc import SoC, mem_decoder
 
 class SDRAMSoC(SoC):
        csr_map = {
-               "dfii":                                 6,
-               "lasmicon":                             7,
-               "wishbone2lasmi":               8,
-               "memtest_w":                    9,
-               "memtest_r":                    10
+               "dfii":                                 7,
+               "lasmicon":                             8,
+               "wishbone2lasmi":               9,
+               "memtest_w":                    10,
+               "memtest_r":                    11
        }
        csr_map.update(SoC.csr_map)