generated from saji/ecp5-template
wip: wishbone tool and non-workign hub75
This commit is contained in:
parent
49e395653e
commit
a7ba60b81f
|
@ -49,6 +49,7 @@
|
||||||
nextpnr
|
nextpnr
|
||||||
pkgsCross.riscv64.buildPackages.gcc
|
pkgsCross.riscv64.buildPackages.gcc
|
||||||
gnumake
|
gnumake
|
||||||
|
wishbone-tool
|
||||||
# simulators
|
# simulators
|
||||||
verilog
|
verilog
|
||||||
verilator
|
verilator
|
||||||
|
|
|
@ -2,25 +2,92 @@
|
||||||
|
|
||||||
# r0 g0 b0 gnd r1 g1 b1 e a b c d clk stb oe gnd
|
# r0 g0 b0 gnd r1 g1 b1 e a b c d clk stb oe gnd
|
||||||
from litex.build.generic_platform import Signal, Subsignal, Pins
|
from litex.build.generic_platform import Signal, Subsignal, Pins
|
||||||
from litex.build.io import Module
|
from litex.build.io import FSM, Module
|
||||||
|
from litex.gen import If, NextState, NextValue
|
||||||
|
|
||||||
def make_hub75_iodevice(index, basename):
|
def make_hub75_iodevice(index, basename):
|
||||||
b = basename
|
b = basename
|
||||||
signals = ("hub75_iodev", index,
|
signals = ("hub75_iodev", index,
|
||||||
Subsignal("r0", Pins(f"{b}:1")),
|
Subsignal("r0", Pins(f"{b}:0")),
|
||||||
Subsignal("g0", Pins(f"{b}:2")),
|
Subsignal("g0", Pins(f"{b}:1")),
|
||||||
Subsignal("b0", Pins(f"{b}:3")),
|
Subsignal("b0", Pins(f"{b}:2")),
|
||||||
Subsignal("r1", Pins(f"{b}:5")),
|
Subsignal("r1", Pins(f"{b}:4")),
|
||||||
Subsignal("g1", Pins(f"{b}:6")),
|
Subsignal("g1", Pins(f"{b}:5")),
|
||||||
Subsignal("b1", Pins(f"{b}:7")),
|
Subsignal("b1", Pins(f"{b}:6")),
|
||||||
Subsignal("addr", Pins(f"{b}:9 {b}:10 {b}:11 {b}:12 {b}:8")),
|
Subsignal("addr", Pins(f"{b}:8 {b}:9 {b}:10 {b}:11 {b}:7")),
|
||||||
Subsignal("clk", Pins(f"{b}:13")),
|
Subsignal("clk", Pins(f"{b}:12")),
|
||||||
Subsignal("stb", Pins(f"{b}:14")),
|
Subsignal("stb", Pins(f"{b}:13")),
|
||||||
Subsignal("oe", Pins(f"{b}:15")),
|
Subsignal("oe", Pins(f"{b}:14")),
|
||||||
)
|
)
|
||||||
return [signals]
|
return [signals]
|
||||||
|
|
||||||
|
|
||||||
class Hub75Driver(Module):
|
class Hub75Driver(Module):
|
||||||
count = Signal(8) # fsm counter
|
def __init__(self, base_freq=60e6, linedepth=128):
|
||||||
|
if base_freq // 2 > 30e6:
|
||||||
|
raise RuntimeError("hi")
|
||||||
|
|
||||||
|
self.phase = Signal() # divider/counter
|
||||||
|
self.addr = Signal(5)
|
||||||
|
self.latch = Signal()
|
||||||
|
self.output_en = Signal()
|
||||||
|
self.rgb = Signal(6)
|
||||||
|
|
||||||
|
|
||||||
|
# clk-en acts as a gate.
|
||||||
|
clock_en = Signal()
|
||||||
|
|
||||||
|
self.clock_out = Signal()
|
||||||
|
# self.comb += self.clock_out.eq(self.phase & clock_en)
|
||||||
|
# clock counter increments.
|
||||||
|
self.sync += self.phase.eq(self.phase + 1)
|
||||||
|
|
||||||
|
# self.sync += If(self.phase == 1, If(clock_en, self.clock_out.eq(self.phase)).Else(self.clock_out.eq(0)))
|
||||||
|
self.sync += If(clock_en, self.clock_out.eq(self.phase)).Else(self.clock_out.eq(0))
|
||||||
|
|
||||||
|
self.fsm = fsm = FSM()
|
||||||
|
self.submodules += self.fsm
|
||||||
|
|
||||||
|
self.comb += self.rgb.eq(0b111010)
|
||||||
|
|
||||||
|
counter = Signal(8)
|
||||||
|
|
||||||
|
fsm.act("ready",
|
||||||
|
NextValue(self.output_en, 1),
|
||||||
|
NextValue(self.pixnum, linedepth - 1),
|
||||||
|
NextValue(self.latch, 0),
|
||||||
|
If(self.phase == 1,
|
||||||
|
NextValue(self.addr, self.addr + 1),
|
||||||
|
NextValue(clock_en, 1),
|
||||||
|
NextState("transmit"),
|
||||||
|
),
|
||||||
|
# If((self.state_count == 7), NextValue(clock_en, ~clock_en)),
|
||||||
|
)
|
||||||
|
fsm.act("transmit",
|
||||||
|
If(self.phase == 1,
|
||||||
|
NextValue(self.pixnum, self.pixnum - 1),
|
||||||
|
If(self.pixnum == 0,
|
||||||
|
NextState("latch_delay"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("latch_delay",
|
||||||
|
NextValue(clock_en, 0),
|
||||||
|
If(self.phase == 1,
|
||||||
|
NextState("latchout")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("latchout",
|
||||||
|
If(self.phase == 1,
|
||||||
|
NextValue(self.latch, 1),
|
||||||
|
NextValue(counter, 0),
|
||||||
|
NextState("done")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("done",
|
||||||
|
NextValue(self.output_en, 0),
|
||||||
|
NextValue(self.latch, 0),
|
||||||
|
NextValue(counter, counter + 1),
|
||||||
|
If(counter == 255, NextState("ready"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ _connectors = [
|
||||||
class _CRG(LiteXModule):
|
class _CRG(LiteXModule):
|
||||||
def __init__(self, platform, sys_clk_freq, with_reset = False):
|
def __init__(self, platform, sys_clk_freq, with_reset = False):
|
||||||
self.cd_sys = ClockDomain("sys")
|
self.cd_sys = ClockDomain("sys")
|
||||||
|
self.cd_hub = ClockDomain("hub")
|
||||||
# self.cd_sdram = ClockDomain("sdram")
|
# self.cd_sdram = ClockDomain("sdram")
|
||||||
self.cd_sys2x = ClockDomain()
|
self.cd_sys2x = ClockDomain()
|
||||||
self.cd_sys2x_ps = ClockDomain()
|
self.cd_sys2x_ps = ClockDomain()
|
||||||
|
@ -105,13 +106,14 @@ class _CRG(LiteXModule):
|
||||||
self.pll = pll = ECP5PLL()
|
self.pll = pll = ECP5PLL()
|
||||||
|
|
||||||
rst_n = platform.request("user_btn_n", 0) if with_reset else 1
|
rst_n = platform.request("user_btn_n", 0) if with_reset else 1
|
||||||
self.comb += [pll.reset.eq(~rst_n)]
|
self.comb += pll.reset.eq(~rst_n)
|
||||||
pll.register_clkin(clk25, 25e6)
|
pll.register_clkin(clk25, 25e6)
|
||||||
pll.create_clkout(self.cd_sys, sys_clk_freq)
|
pll.create_clkout(self.cd_sys, sys_clk_freq)
|
||||||
# for the sdram
|
# for the sdram
|
||||||
# pll.create_clkout(self.cd_sdram, sys_clk_freq, phase=180)
|
# pll.create_clkout(self.cd_sdram, sys_clk_freq, phase=180)
|
||||||
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
|
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
|
||||||
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180)
|
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180)
|
||||||
|
pll.create_clkout(self.cd_hub, 30e6)
|
||||||
|
|
||||||
|
|
||||||
sdram_clk = ClockSignal("sys2x_ps")
|
sdram_clk = ClockSignal("sys2x_ps")
|
||||||
|
|
|
@ -13,7 +13,7 @@ from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
|
||||||
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
|
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
|
||||||
|
|
||||||
from platform.colorlight_5a_75b_8_0 import Groovy1Platform
|
from platform.colorlight_5a_75b_8_0 import Groovy1Platform
|
||||||
|
from hub75 import Hub75Driver, make_hub75_iodevice
|
||||||
|
|
||||||
class GroovySoC(SoCCore):
|
class GroovySoC(SoCCore):
|
||||||
def __init__(self, platform, sys_clk_freq,
|
def __init__(self, platform, sys_clk_freq,
|
||||||
|
@ -49,6 +49,24 @@ class GroovySoC(SoCCore):
|
||||||
self.mem_map["spiflash"] = 0x20000000
|
self.mem_map["spiflash"] = 0x20000000
|
||||||
mod = SpiFlashModule(SpiNorFlashOpCodes.READ_1_1_1)
|
mod = SpiFlashModule(SpiNorFlashOpCodes.READ_1_1_1)
|
||||||
self.add_spi_flash(mode="1x", module=SpiFlashModule, with_master=False)
|
self.add_spi_flash(mode="1x", module=SpiFlashModule, with_master=False)
|
||||||
|
self.platform.add_extension(make_hub75_iodevice(0, "j4"))
|
||||||
|
hub_io = self.platform.request("hub75_iodev", 0)
|
||||||
|
self.submodules.hub75 = hub75 = ClockDomainsRenamer("hub")(Hub75Driver())
|
||||||
|
self.comb += [
|
||||||
|
hub_io.r0.eq(hub75.rgb[0]),
|
||||||
|
hub_io.r1.eq(hub75.rgb[3]),
|
||||||
|
hub_io.g0.eq(hub75.rgb[1]),
|
||||||
|
hub_io.g1.eq(hub75.rgb[4]),
|
||||||
|
hub_io.b0.eq(hub75.rgb[2]),
|
||||||
|
hub_io.b1.eq(hub75.rgb[5]),
|
||||||
|
hub_io.clk.eq(hub75.clock_out),
|
||||||
|
hub_io.addr.eq(hub75.addr),
|
||||||
|
hub_io.oe.eq(hub75.output_en),
|
||||||
|
hub_io.stb.eq(hub75.latch),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
let
|
let
|
||||||
tag = "2023.12";
|
tag = "2023.12";
|
||||||
in final: prev: {
|
in final: prev: {
|
||||||
|
wishbone-tool = prev.callPackage(import ./wishbone-tool.nix) { };
|
||||||
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
|
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
|
||||||
(python-final: python-prev: {
|
(python-final: python-prev: {
|
||||||
litex = python-final.callPackage(import ./litex.nix tag) { };
|
litex = python-final.callPackage(import ./litex.nix tag) { };
|
||||||
|
|
17
litex/wishbone-tool.nix
Normal file
17
litex/wishbone-tool.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{ lib, fetchFromGitHub, rustPlatform }:
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage rec {
|
||||||
|
pname = "wishbone-tool";
|
||||||
|
version = "0.7.9-git";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "litex-hub";
|
||||||
|
repo = "wishbone-utils";
|
||||||
|
rev = "master";
|
||||||
|
hash = "sha256-ZEJ3hd5G/zziCMqG1yvRzrt3JX6PtJupenq+xM8AKO0=";
|
||||||
|
};
|
||||||
|
sourceRoot = "${src.name}/wishbone-tool";
|
||||||
|
|
||||||
|
|
||||||
|
cargoHash = "sha256-kWvtZEXtb5bZ7/hd8jsr41UGSDOuDU4tyKWAL0kDoIg=";
|
||||||
|
}
|
Loading…
Reference in a new issue