generated from saji/ecp5-template
Compare commits
1 commit
6b034b0176
...
9a106156d0
Author | SHA1 | Date | |
---|---|---|---|
saji | 9a106156d0 |
|
@ -24,11 +24,9 @@ Rgb111Layout = RGBLayout(1, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
class RGBView(data.View):
|
class RGBView(data.View):
|
||||||
def bit_depth(self) -> int:
|
|
||||||
return max(
|
|
||||||
self.red.shape().width, self.green.shape().width, self.blue.shape().width
|
|
||||||
)
|
|
||||||
|
|
||||||
|
def bit_depth(self) -> int:
|
||||||
|
return max(self.red.shape(), self.green.shape(), self.blue.shape())
|
||||||
def channel_slice(self, bit: int) -> Rgb111Layout:
|
def channel_slice(self, bit: int) -> Rgb111Layout:
|
||||||
"""Select bits from each channel and use it to form an Rgb111Layout.
|
"""Select bits from each channel and use it to form an Rgb111Layout.
|
||||||
This is useful for BCM stuff, since the bits are sliced to form a bitplane.
|
This is useful for BCM stuff, since the bits are sliced to form a bitplane.
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
# Holds various implementations of a "fetcher", which is given a display string
|
|
||||||
# to know its location.
|
|
||||||
# during operation, it is given a row index, and responds with the data.
|
|
||||||
|
|
||||||
|
|
||||||
from amaranth import Module, Cat, Mux, ShapeLike, Signal, Assert, Array, unsigned
|
|
||||||
from amaranth.build import Platform
|
|
||||||
from amaranth.lib import wiring, data
|
|
||||||
from amaranth.lib.wiring import In, Out
|
|
||||||
from amaranth.lib.memory import Memory, ReadPort, WritePort
|
|
||||||
from amaranth.lib import stream
|
|
||||||
from amaranth.utils import ceil_log2
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from .common import Rgb666Layout, Hub75Stream, Hub75Ctrl, Hub75Data, Rgb888Layout
|
|
||||||
from .geom import DisplayRotation, DisplayString
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
CoordLayout = data.StructLayout({"x": unsigned(32), "y": unsigned(32)})
|
|
||||||
|
|
||||||
|
|
||||||
class AddressGenerator(wiring.Component):
|
|
||||||
"""Generates (x,y) sequences corresponding to a display row."""
|
|
||||||
|
|
||||||
def __init__(self, geom: DisplayString, *, src_loc_at=0):
|
|
||||||
self.geom = geom
|
|
||||||
super().__init__(
|
|
||||||
{
|
|
||||||
"coordstream": Out(stream.Signature(CoordLayout)),
|
|
||||||
"start": In(1),
|
|
||||||
"done": Out(1),
|
|
||||||
"addr": In(geom.dimensions.addr_bits),
|
|
||||||
},
|
|
||||||
src_loc_at=src_loc_at,
|
|
||||||
)
|
|
||||||
|
|
||||||
def elaborate(self, platform: Platform) -> Module:
|
|
||||||
m = Module()
|
|
||||||
|
|
||||||
counter = Signal(self.geom.dimensions.length)
|
|
||||||
|
|
||||||
# based on the geometry we generate x,y pairs.
|
|
||||||
|
|
||||||
with m.FSM():
|
|
||||||
with m.State("init"):
|
|
||||||
m.d.comb += self.done.eq(0)
|
|
||||||
m.d.sync += counter.eq(0)
|
|
||||||
with m.If(self.start):
|
|
||||||
m.next = "run"
|
|
||||||
|
|
||||||
with m.State("run"):
|
|
||||||
if self.geom.rotation == DisplayRotation.LEFTRIGHT:
|
|
||||||
# default case, +x.
|
|
||||||
pass
|
|
||||||
elif self.geom.rotation == DisplayRotation.UPDOWN:
|
|
||||||
# r 90, +y
|
|
||||||
pass
|
|
||||||
with m.State("done"):
|
|
||||||
m.d.comb += self.done.eq(1)
|
|
||||||
m.next = "init"
|
|
||||||
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
class BasicFetcher(wiring.Component):
|
|
||||||
"""A generic fetcher. Takes a function of the form f(x,y: int) -> RGB."""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, geom: DisplayString, dfunc, data_shape=Rgb888Layout, *, src_loc_at=0
|
|
||||||
):
|
|
||||||
self.dfunc = dfunc
|
|
||||||
super().__init__(
|
|
||||||
{
|
|
||||||
"pixstream": Out(stream.Signature(Rgb888Layout)),
|
|
||||||
"start": In(1),
|
|
||||||
"addr": In(geom.dimensions.addr_bits),
|
|
||||||
},
|
|
||||||
src_loc_at=src_loc_at,
|
|
||||||
)
|
|
|
@ -1,4 +1,4 @@
|
||||||
from amaranth import Module, Cat, Mux, ShapeLike, Signal, Assert, Array
|
from amaranth import Module, Cat, Mux, Print, ShapeLike, Signal, Assert, Array
|
||||||
from amaranth.build import Platform
|
from amaranth.build import Platform
|
||||||
from amaranth.lib import wiring, data
|
from amaranth.lib import wiring, data
|
||||||
from amaranth.lib.wiring import In, Out
|
from amaranth.lib.wiring import In, Out
|
||||||
|
@ -313,6 +313,7 @@ class Hub75DataDriver(wiring.Component):
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
class Hub75Coordinator(wiring.Component):
|
class Hub75Coordinator(wiring.Component):
|
||||||
"""A shared-control hub75 driver"""
|
"""A shared-control hub75 driver"""
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ from groovylight.common import Rgb888Layout, Rgb666Layout, RGBView
|
||||||
def test_rgbview():
|
def test_rgbview():
|
||||||
rgb = Rgb888Layout(0xAABBCC)
|
rgb = Rgb888Layout(0xAABBCC)
|
||||||
|
|
||||||
assert rgb.bit_depth() == 8
|
assert rgb.channel_size() == unsigned(8)
|
||||||
|
|
||||||
rgb18 = Rgb666Layout(0x2DEFD)
|
rgb18 = Rgb666Layout(0x2DEFD)
|
||||||
|
|
||||||
slice = rgb.channel_slice(1)
|
slice = rgb.channel_slice(1)
|
||||||
assert isinstance(slice, RGBView), "channel_slice should return another rgbview"
|
assert isinstance(slice, RGBView), "channel_slice should return another rgbview"
|
||||||
|
|
||||||
assert slice.bit_depth() == 1, "channel_slice channel size should be 1"
|
assert slice.channel_size() == unsigned(1), "channel_slice channel size should be 1"
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
rgb18.channel_slice(5), RGBView
|
rgb18.channel_slice(5), RGBView
|
||||||
), "channel_slice should return another rgbview"
|
), "channel_slice should return another rgbview"
|
||||||
|
|
Loading…
Reference in a new issue