mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
soc/cores/led/WS2812: Add Bus Mastering capability.
Useful on small FPGAs to reduce resource usage: When enabling bus mastering, the core is able to automatically read led values from the bus and can then avoid the internal memory. This is particularly useful when reading values from SPI Flash with a small "Player" core just updating the base address.
This commit is contained in:
parent
649c45e962
commit
92f5a9f0e6
1 changed files with 46 additions and 22 deletions
|
@ -117,19 +117,23 @@ class WS2812(Module):
|
|||
sys_clk_freq: int, in
|
||||
System Clk Frequency.
|
||||
"""
|
||||
def __init__(self, pad, nleds, sys_clk_freq):
|
||||
# Memory.
|
||||
mem = Memory(32, nleds)
|
||||
port = mem.get_port()
|
||||
self.specials += mem, port
|
||||
def __init__(self, pad, nleds, sys_clk_freq, bus_mastering=False, bus_base=None):
|
||||
if bus_mastering:
|
||||
self.bus = bus = wishbone.Interface(data_width=32)
|
||||
else:
|
||||
# Memory.
|
||||
mem = Memory(32, nleds)
|
||||
port = mem.get_port()
|
||||
self.specials += mem, port
|
||||
|
||||
# Wishone Memory.
|
||||
self.submodules.wb_mem = wishbone.SRAM(
|
||||
mem_or_size = mem,
|
||||
read_only = False,
|
||||
bus = wishbone.Interface(data_width=32)
|
||||
)
|
||||
self.bus = self.wb_mem.bus
|
||||
|
||||
# Wishone Memory.
|
||||
self.submodules.wb_mem = wishbone.SRAM(
|
||||
mem_or_size = mem,
|
||||
read_only = False,
|
||||
bus = wishbone.Interface(data_width=32)
|
||||
)
|
||||
self.bus = self.wb_mem.bus
|
||||
|
||||
# Internal Signals.
|
||||
led_data = Signal(24)
|
||||
|
@ -164,17 +168,37 @@ class WS2812(Module):
|
|||
NextState("LED-SHIFT")
|
||||
)
|
||||
)
|
||||
self.comb += port.adr.eq(led_count)
|
||||
fsm.act("LED-SHIFT",
|
||||
NextValue(bit_count, 24-1),
|
||||
NextValue(led_data, port.dat_r),
|
||||
NextValue(led_count, led_count + 1),
|
||||
If(led_count == (nleds-1),
|
||||
NextState("RST")
|
||||
).Else(
|
||||
NextState("BIT-TEST")
|
||||
if bus_mastering:
|
||||
fsm.act("LED-SHIFT",
|
||||
bus.stb.eq(1),
|
||||
bus.cyc.eq(1),
|
||||
bus.we.eq(0),
|
||||
bus.sel.eq(2**(bus.data_width//8)-1),
|
||||
bus.adr.eq(bus_base[2:] + led_count),
|
||||
If(bus.ack,
|
||||
NextValue(bit_count, 24-1),
|
||||
NextValue(led_data, bus.dat_r),
|
||||
NextValue(led_count, led_count + 1),
|
||||
If(led_count == (nleds-1),
|
||||
NextState("RST")
|
||||
).Else(
|
||||
NextState("BIT-TEST")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.comb += port.adr.eq(led_count)
|
||||
fsm.act("LED-SHIFT",
|
||||
NextValue(bit_count, 24-1),
|
||||
NextValue(led_data, port.dat_r),
|
||||
NextValue(led_count, led_count + 1),
|
||||
If(led_count == (nleds-1),
|
||||
NextState("RST")
|
||||
).Else(
|
||||
NextState("BIT-TEST")
|
||||
)
|
||||
)
|
||||
|
||||
fsm.act("BIT-TEST",
|
||||
If(led_data[-1] == 0,
|
||||
NextState("ZERO-SEND"),
|
||||
|
|
Loading…
Reference in a new issue