wip: wishbone tool and non-workign hub75

This commit is contained in:
saji 2024-04-26 21:36:47 -05:00
parent 49e395653e
commit a7ba60b81f
6 changed files with 121 additions and 15 deletions

View file

@ -49,6 +49,7 @@
nextpnr nextpnr
pkgsCross.riscv64.buildPackages.gcc pkgsCross.riscv64.buildPackages.gcc
gnumake gnumake
wishbone-tool
# simulators # simulators
verilog verilog
verilator verilator

View file

@ -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"))
)

View file

@ -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")

View file

@ -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),
]

View file

@ -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
View 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=";
}