gateware: add UART to CSR
This commit is contained in:
parent
32fb8383d1
commit
96dabe013a
@ -41,7 +41,7 @@ class I2C(Elaboratable):
|
||||
# [3]: read - read a byte from the bus
|
||||
# [4]: read_ack - ACK value that gets written out during a read operation
|
||||
# [5]: read_ack_en - Hacky solution to determine if we want to save read_ack
|
||||
self.CR = Element(6, Element.Access.W, name="CR")
|
||||
self.CR = Element(6, Element.Access.W, name="I2C_CR")
|
||||
|
||||
# Status register
|
||||
#
|
||||
@ -49,27 +49,28 @@ class I2C(Elaboratable):
|
||||
# [0]: busy - bus is busy operating
|
||||
# [1]: ack - an ACK has been received from a bus slave
|
||||
# [2]: read_ack - a convenience read field to see value of CR->read_ack
|
||||
self.SR = Element(3, Element.Access.R, name="SR")
|
||||
self.SR = Element(3, Element.Access.R, name="I2C_SR")
|
||||
|
||||
# Data write register
|
||||
#
|
||||
# Latches in data to be written when write signal is applied.
|
||||
self.DWR = Element(8, Element.Access.W, name="DWR")
|
||||
self.DWR = Element(8, Element.Access.W, name="I2C_DWR")
|
||||
|
||||
# Data read register
|
||||
#
|
||||
# Only presents valid data after 'read' has started, and once 'busy' is no longer asserted.
|
||||
self.DRR = Element(8, Element.Access.R, name="DRR")
|
||||
self.DRR = Element(8, Element.Access.R, name="I2C_DRR")
|
||||
|
||||
# Set up CSR bus
|
||||
addr_width = ceil(log2(64)) # Support up to 64 registers just because
|
||||
data_width = 8 # 32 bit bus
|
||||
self._csr_mux = Multiplexer(addr_width=addr_width, data_width=data_width)
|
||||
# TODO export the addresses of these somehow
|
||||
self._csr_mux.add(self.CR)
|
||||
self._csr_mux.add(self.SR)
|
||||
self._csr_mux.add(self.DWR)
|
||||
self._csr_mux.add(self.DRR)
|
||||
# TODO export these addresses into some config file
|
||||
cr_start, _stop = self._csr_mux.add(self.CR)
|
||||
sr_start, _stop = self._csr_mux.add(self.SR)
|
||||
dwr_start, _stop = self._csr_mux.add(self.DWR)
|
||||
drr_start, _stop = self._csr_mux.add(self.DRR)
|
||||
print(f"I2C added. CR 0x{cr_start:x}, SR 0x{sr_start:x}, DWR 0x{dwr_start:x}, DRR 0x{drr_start:x}")
|
||||
self.bus = self._csr_mux.bus
|
||||
|
||||
# Set up I2C initiator submodule
|
||||
|
@ -146,7 +146,6 @@ class Core(Elaboratable):
|
||||
print(f"CSR bus added at 0x{start:08x}")
|
||||
|
||||
# I2C (connected to DAC for VCO and ADC?)
|
||||
Signal()
|
||||
if platform is not None:
|
||||
i2c_pads = platform.request("i2c")
|
||||
else:
|
||||
@ -158,7 +157,20 @@ class Core(Elaboratable):
|
||||
m.d.comb += i2c_pads.scl.i.eq(1)
|
||||
self.i2c = i2c.I2C(50e6, 100e3, i2c_pads)
|
||||
m.submodules.i2c = self.i2c
|
||||
self.csr.add(self.i2c.bus)
|
||||
i2c_start, _stop, _step = self.csr.add(self.i2c.bus)
|
||||
print(f"LED added to CSR at 0x{i2c_start}")
|
||||
|
||||
if platform is not None:
|
||||
uart_pads = platform.request("uart")
|
||||
else:
|
||||
uart_pads = type('UARTPads', (), {})
|
||||
uart_pads.tx = Signal()
|
||||
uart_pads.rx = Signal()
|
||||
# TODO spread sysclk freq through design
|
||||
self.uart = uart.UART(50e6, 1152_000)
|
||||
m.submodules.uart = self.uart
|
||||
uart_start, _stop, _step = self.csr.add(self.uart.bus)
|
||||
print(f"UART added to CSR at 0x{uart_start:x}")
|
||||
|
||||
self.csr_bridge = WishboneCSRBridge(self.csr.bus, data_width=32, name="CSR")
|
||||
m.submodules.csr_bridge = self.csr_bridge
|
||||
|
@ -1 +1 @@
|
||||
from colorlight_i9 import *
|
||||
from .colorlight_i9 import *
|
||||
|
@ -25,8 +25,18 @@ class Colorlight_i9_Platform(LatticeECP5Platform):
|
||||
# attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")),
|
||||
|
||||
UARTResource(0,
|
||||
tx="J17",
|
||||
rx="H18",
|
||||
tx="E17",
|
||||
rx="D18",
|
||||
attrs=Attrs(IO_TYPE="LVCMOS33")
|
||||
),
|
||||
UARTResource(1,
|
||||
tx="P16",
|
||||
rx="L5",
|
||||
attrs=Attrs(IO_TYPE="LVCMOS33")
|
||||
),
|
||||
UARTResource(2,
|
||||
tx="J18",
|
||||
rx="J16",
|
||||
attrs=Attrs(IO_TYPE="LVCMOS33")
|
||||
),
|
||||
|
||||
|
@ -38,7 +38,7 @@ class UART(Elaboratable):
|
||||
#
|
||||
# Sets input/output baudrate to system clock / divisor. Resets to value
|
||||
# that provides 115200 baud rate. Writes to this register clear FIFOs.
|
||||
self.DIVISOR = Element(16, Element.Access.RW, name="DIVISOR")
|
||||
self.DIVISOR = Element(16, Element.Access.RW, name="UART_DIVISOR")
|
||||
|
||||
# Status register.
|
||||
#
|
||||
@ -47,22 +47,23 @@ class UART(Elaboratable):
|
||||
# [1]: txfifo_empty
|
||||
# [2]: rxfifo_full
|
||||
# [3]: rxfifo_empty
|
||||
self.SR = Element(4, Element.Access.R, name="SR")
|
||||
self.SR = Element(4, Element.Access.R, name="UART_SR")
|
||||
|
||||
# Data register.
|
||||
#
|
||||
# Writes push data into TX FIFO, and are discarded if full, reads pull
|
||||
# data from RX FIFO, and are invalid if it is empty. Incoming bytes are discarded
|
||||
# if the RX FIFO is full.
|
||||
self.DR = Element(8, Element.Access.RW, name="DR")
|
||||
self.DR = Element(8, Element.Access.RW, name="UART_DR")
|
||||
|
||||
# Set up CSR bus
|
||||
addr_width = ceil(log2(64))
|
||||
data_width = 32
|
||||
data_width = 8
|
||||
self._csr_mux = Multiplexer(addr_width=addr_width, data_width=data_width)
|
||||
self._csr_mux.add(self.DIVISOR)
|
||||
self._csr_mux.add(self.SR)
|
||||
self._csr_mux.add(self.DR)
|
||||
div_start, _stop = self._csr_mux.add(self.DIVISOR)
|
||||
sr_start, _stop = self._csr_mux.add(self.SR)
|
||||
dr_start, _stop = self._csr_mux.add(self.DR)
|
||||
print(f"UART added. DIVISOR 0x{div_start:x}, SR 0x{sr_start:x}, DR 0x{dr_start:x}")
|
||||
self.bus = self._csr_mux.bus
|
||||
|
||||
# Actual business logic
|
||||
@ -94,6 +95,7 @@ class UART(Elaboratable):
|
||||
m.submodules.csr_mux = self._csr_mux
|
||||
|
||||
# Hook up divisor to register.
|
||||
# TODO do some validation and write a known good value if a dumb value was provided
|
||||
m.d.comb += self.DIVISOR.r_data.eq(self._serial.divisor)
|
||||
with m.If(self.DIVISOR.w_stb):
|
||||
m.d.sync += self._serial.divisor.eq(self.DIVISOR.w_data)
|
||||
|
Loading…
Reference in New Issue
Block a user