generated from saji/ecp5-template
rename bitslicer to hub75, rework hub75ctrl sig
This commit is contained in:
parent
c328d174ad
commit
3d49afe6ed
|
@ -1,4 +1,4 @@
|
||||||
from amaranth import unsigned
|
from amaranth import Array, unsigned
|
||||||
from amaranth.lib import wiring, data
|
from amaranth.lib import wiring, data
|
||||||
from amaranth.lib.wiring import Out
|
from amaranth.lib.wiring import Out
|
||||||
|
|
||||||
|
@ -42,13 +42,14 @@ class Hub75Ctrl(wiring.Signature):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, n_strings: int = 1):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
{
|
{
|
||||||
"latch": Out(1),
|
"latch": Out(1),
|
||||||
"oe": Out(1),
|
"oe": Out(1),
|
||||||
"addr": Out(5),
|
"addr": Out(5),
|
||||||
"display_clk": Out(1),
|
"display_clk": Out(1),
|
||||||
|
"data": Out(Hub75Data()).array(n_strings),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,30 @@
|
||||||
# This file contains code to generate these timing adjustments and
|
# This file contains code to generate these timing adjustments and
|
||||||
# control/quantify them.
|
# control/quantify them.
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: This doesn't work. As much as I wish it did. Because the numbers are still
|
||||||
|
# added linearly. values that are between the powers of two (which are fitted to the log
|
||||||
|
# curve) are not even remotely close to matching.
|
||||||
|
# thankfully a gamma LUT is only 64 elements. we will need 3 muxes per color (1 per channel).
|
||||||
|
|
||||||
from math import pow
|
from math import pow
|
||||||
|
|
||||||
|
from amaranth import Module, Cat, Mux, ShapeLike, Signal, Assert
|
||||||
|
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.utils import ceil_log2
|
||||||
|
|
||||||
|
|
||||||
|
class GammaLUT(wiring.Component):
|
||||||
|
def __init__(self, n_bits: int, gamma: float = 2.2):
|
||||||
|
self.gamma = gamma
|
||||||
|
self.n_bits = n_bits
|
||||||
|
self.lut = [pow(x, gamma) for x in range(2**n_bits)]
|
||||||
|
|
||||||
|
# TODO: we can combo it maybe with the variable timing method.
|
||||||
|
super().__init__(wiring.Signature({}))
|
||||||
|
|
||||||
def _gammavec(vals: [float], g: float) -> [float]:
|
def _gammavec(vals: [float], g: float) -> [float]:
|
||||||
return [pow(x, g) for x in vals]
|
return [pow(x, g) for x in vals]
|
||||||
|
|
|
@ -163,8 +163,7 @@ class Hub75Coordinator(wiring.Component):
|
||||||
self.n_strings = n_strings
|
self.n_strings = n_strings
|
||||||
super().__init__(
|
super().__init__(
|
||||||
{
|
{
|
||||||
"ctrl": Out(Hub75Ctrl),
|
"hub75": Out(Hub75Ctrl(n_strings)),
|
||||||
"data": data.ArrayLayout(Hub75Data, n_strings),
|
|
||||||
# TODO: fetching routine? maybe it's passed through.
|
# TODO: fetching routine? maybe it's passed through.
|
||||||
}
|
}
|
||||||
)
|
)
|
|
@ -5,7 +5,7 @@ from amaranth.lib.wiring import In, Out
|
||||||
from amaranth.lib.memory import Memory, WritePort
|
from amaranth.lib.memory import Memory, WritePort
|
||||||
from amaranth.sim import Simulator
|
from amaranth.sim import Simulator
|
||||||
|
|
||||||
from ..bitslicer import Hub75StringDriver, Rgb666Layout
|
from ..hub75 import Hub75Coordinator, Hub75StringDriver, Rgb666Layout
|
||||||
|
|
||||||
|
|
||||||
def test_stringdriver():
|
def test_stringdriver():
|
||||||
|
@ -36,3 +36,8 @@ def test_stringdriver():
|
||||||
|
|
||||||
with sim.write_vcd("output.vcd"):
|
with sim.write_vcd("output.vcd"):
|
||||||
sim.run_until(1e-6 * 1000)
|
sim.run_until(1e-6 * 1000)
|
||||||
|
|
||||||
|
|
||||||
|
def test_hub75():
|
||||||
|
m = Module()
|
||||||
|
m.submodules.dut = dut = Hub75Coordinator(1)
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
from amaranth import Array, Module, Cat, Signal, Assert, 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, WritePort
|
|
||||||
from amaranth.sim import Simulator
|
from amaranth.sim import Simulator
|
||||||
|
|
||||||
from ..bitslicer import Hub75StringDriver, Rgb666Layout, SwapBuffer
|
from ..hub75 import Hub75StringDriver, Rgb666Layout, SwapBuffer
|
||||||
|
|
||||||
|
|
||||||
def test_swapbuffer():
|
def test_swapbuffer():
|
||||||
|
|
|
@ -5,6 +5,12 @@ from amaranth.lib.io import Buffer
|
||||||
from groovylight.platforms.colorlight_5a75b_v8_2 import Colorlight_5A75B_R82Platform
|
from groovylight.platforms.colorlight_5a75b_v8_2 import Colorlight_5A75B_R82Platform
|
||||||
|
|
||||||
|
|
||||||
|
def progs_exist(programs) -> bool:
|
||||||
|
for p in programs:
|
||||||
|
if shutil.which(p) is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
class Blinky(Elaboratable):
|
class Blinky(Elaboratable):
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
|
@ -24,5 +30,8 @@ class Blinky(Elaboratable):
|
||||||
|
|
||||||
|
|
||||||
def test_platform():
|
def test_platform():
|
||||||
|
if not progs_exist(["yosys", "nextpnr-ecp5", "openFPGALoader"]):
|
||||||
|
pytest.skip("missing toolchain programs")
|
||||||
plat = Colorlight_5A75B_R82Platform()
|
plat = Colorlight_5A75B_R82Platform()
|
||||||
|
|
||||||
plat.build(Blinky())
|
plat.build(Blinky())
|
||||||
|
|
Loading…
Reference in a new issue