Skip to content

Commit

Permalink
targets: add netv2 targets
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotr Binkowski committed Jan 23, 2020
1 parent f39b41c commit b5f73ac
Show file tree
Hide file tree
Showing 5 changed files with 402 additions and 20 deletions.
40 changes: 20 additions & 20 deletions platforms/netv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,28 @@
("ddram", 0,
Subsignal("a", Pins(
"U6 V4 W5 V5 AA1 Y2 AB1 AB3",
"AB2 Y3 W6 Y1 V2 AA3"
),
IOStandard("SSTL15")),
Subsignal("ba", Pins("U5 W4 V7"), IOStandard("SSTL15")),
Subsignal("ras_n", Pins("Y9"), IOStandard("SSTL15")),
Subsignal("cas_n", Pins("Y7"), IOStandard("SSTL15")),
Subsignal("we_n", Pins("V8"), IOStandard("SSTL15")),
Subsignal("dm", Pins("M5 L3"), IOStandard("SSTL15")),
"AB2 Y3 W6 Y1 V2 AA3"),
IOStandard("SSTL15_R")),
Subsignal("ba", Pins("U5 W4 V7"), IOStandard("SSTL15_R")),
Subsignal("ras_n", Pins("Y9"), IOStandard("SSTL15_R")),
Subsignal("cas_n", Pins("Y7"), IOStandard("SSTL15_R")),
Subsignal("we_n", Pins("V8"), IOStandard("SSTL15_R")),
Subsignal("dm", Pins("G1 H4 M5 L3"), IOStandard("SSTL15_R")),
Subsignal("dq", Pins(
"N2 M6 P1 N5 P2 N4 R1 P6 "
"K3 M2 K4 M3 J6 L5 J4 K6 "
),
IOStandard("SSTL15"),
Misc("IN_TERM=UNTUNED_SPLIT_50")),
Subsignal("dqs_p", Pins("P5 M1"), IOStandard("DIFF_SSTL15")),
Subsignal("dqs_n", Pins("P4 L1"), IOStandard("DIFF_SSTL15")),
Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15")),
Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15")),
Subsignal("cke", Pins("Y8"), IOStandard("SSTL15")),
Subsignal("odt", Pins("W9"), IOStandard("SSTL15")),
"C2 F1 B1 F3 A1 D2 B2 E2",
"J5 H3 K1 H2 J1 G2 H5 G3",
"N2 M6 P1 N5 P2 N4 R1 P6",
"K3 M2 K4 M3 J6 L5 J4 K6"),
IOStandard("SSTL15_R"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("dqs_p", Pins("E1 K2 P5 M1"), IOStandard("DIFF_SSTL15_R")),
Subsignal("dqs_n", Pins("D1 J2 P4 L1"), IOStandard("DIFF_SSTL15_R")),
Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15_R")),
Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15_R")),
Subsignal("cke", Pins("Y8"), IOStandard("SSTL15_R")),
Subsignal("odt", Pins("W9"), IOStandard("SSTL15_R")),
Subsignal("reset_n", Pins("AB5"), IOStandard("LVCMOS15")),
Subsignal("cs_n", Pins("V9"), IOStandard("SSTL15")),
Subsignal("cs_n", Pins("V9"), IOStandard("SSTL15_R")),
Misc("SLEW=FAST"),
),

Expand Down
48 changes: 48 additions & 0 deletions targets/netv2/Makefile.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# netv2 targets

ifneq ($(PLATFORM),netv2)
$(error "Platform should be netv2 when using this file!?")
endif

# Settings
DEFAULT_TARGET = net
TARGET ?= $(DEFAULT_TARGET)

COMM_PORT ?= /dev/ttyUSB0
BAUD ?= 115200

# Image
image-flash-$(PLATFORM): image-flash-py
@true

# Gateware
gateware-load-$(PLATFORM):
@echo "Unsupported"
@false

gateware-flash-$(PLATFORM): gateware-flash-py
@true

# Firmware
firmware-load-$(PLATFORM):
flterm --port=$(COMM_PORT) --kernel=$(FIRMWARE_FILEBASE).bin --speed=$(BAUD)


firmware-flash-$(PLATFORM): firmware-flash-py
@true

firmware-connect-$(PLATFORM):
flterm --port=$(COMM_PORT) --speed=$(BAUD)

# Bios
bios-flash-$(PLATFORM):
@echo "Unsupported."
@false

# Extra commands
help-$(PLATFORM):
@true

reset-$(PLATFORM):
@echo "Unsupported."
@false
154 changes: 154 additions & 0 deletions targets/netv2/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Support for the NeTV2 board
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.soc.integration.soc_core import mem_decoder
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litex.soc.interconnect import wishbone

from litedram.modules import K4B2G1646F
from litedram.phy import a7ddrphy
from litedram.core import ControllerSettings

from gateware import cas
from gateware import info

from targets.utils import csr_map_update, period_ns


class _CRG(Module):
def __init__(self, platform):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
self.clock_domains.cd_clk200 = ClockDomain()
self.clock_domains.cd_clk100 = ClockDomain()
self.clock_domains.cd_eth = ClockDomain()

clk50 = platform.request("clk50")

pll_locked = Signal()
pll_fb = Signal()
self.pll_sys = Signal()
pll_sys4x = Signal()
pll_sys4x_dqs = Signal()
pll_clk200 = Signal()
pll_clk100 = Signal()
pll_clk_eth = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,

# VCO @ 1600 MHz
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=20.0,
p_CLKFBOUT_MULT=32, p_DIVCLK_DIVIDE=1,
i_CLKIN1=clk50, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,

# 100 MHz
p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=self.pll_sys,

# 400 MHz
p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_sys4x,

# 400 MHz dqs
p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0,
o_CLKOUT2=pll_sys4x_dqs,

# 200 MHz
p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0,
o_CLKOUT3=pll_clk200,

# 50MHz
p_CLKOUT4_DIVIDE=32, p_CLKOUT4_PHASE=0.0,
o_CLKOUT4=pll_clk_eth,

# 100MHz
p_CLKOUT5_DIVIDE=16, p_CLKOUT5_PHASE=0.0,
o_CLKOUT5=pll_clk100
),
Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk),
Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
Instance("BUFG", i_I=pll_clk100, o_O=self.cd_clk100.clk),
Instance("BUFG", i_I=pll_clk_eth, o_O=self.cd_eth.clk),
AsyncResetSynchronizer(self.cd_sys, ~pll_locked),
AsyncResetSynchronizer(self.cd_clk200, ~pll_locked),
AsyncResetSynchronizer(self.cd_clk100, ~pll_locked),
AsyncResetSynchronizer(self.cd_eth, ~pll_locked),
]

reset_counter = Signal(4, reset=15)
ic_reset = Signal(reset=1)
self.sync.clk200 += \
If(reset_counter != 0,
reset_counter.eq(reset_counter - 1)
).Else(
ic_reset.eq(0)
)
self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)


class BaseSoC(SoCSDRAM):
csr_peripherals = (
"ddrphy",
"info",
"cas",
)
csr_map_update(SoCSDRAM.csr_map, csr_peripherals)

SoCSDRAM.mem_map = {
"rom": 0x00000000,
"sram": 0x10000000,
"main_ram": 0x40000000,
"csr": 0xe0000000,
}

mem_map = {
"spiflash": 0x20000000,
"emulator_ram": 0x50000000,
}
mem_map.update(SoCSDRAM.mem_map)

def __init__(self, platform, csr_data_width=8, **kwargs):
if 'integrated_rom_size' not in kwargs:
kwargs['integrated_rom_size']=0x8000
if 'integrated_sram_size' not in kwargs:
kwargs['integrated_sram_size']=0x8000

clk_freq = int(100e6)
SoCSDRAM.__init__(self, platform, clk_freq, csr_data_width=csr_data_width, **kwargs)

self.submodules.crg = _CRG(platform)
self.crg.cd_sys.clk.attr.add("keep")
self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq))

# Basic peripherals
self.submodules.info = info.Info(platform, self.__class__.__name__)
self.submodules.cas = cas.ControlAndStatus(platform, clk_freq)

if self.cpu_type == "vexriscv" and self.cpu_variant == "linux":
size = 0x4000
self.submodules.emulator_ram = wishbone.SRAM(size)
self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size)

bios_size = 0x8000

# sdram
sdram_module = K4B2G1646F(self.clk_freq, "1:4")
self.submodules.ddrphy = a7ddrphy.A7DDRPHY(
platform.request("ddram"))
controller_settings = ControllerSettings(
with_bandwidth=True,
cmd_buffer_depth=8,
with_refresh=True)
self.register_sdram(self.ddrphy,
sdram_module.geom_settings,
sdram_module.timing_settings,
controller_settings=controller_settings)


SoC = BaseSoC
133 changes: 133 additions & 0 deletions targets/netv2/hdmi2pcie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
from migen import *

from targets.netv2.base import SoC as BaseSoC

from litex.soc.interconnect import wishbone
from litex.soc.cores.freqmeter import FreqMeter

from litepcie.phy.s7pciephy import S7PCIEPHY
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
from litepcie.frontend.dma import LitePCIeDMA
from litepcie.frontend.wishbone import LitePCIeWishboneBridge

from litevideo.input import HDMIIn
from litevideo.output import VideoOut

from targets.utils import period_ns, csr_map_update

class WishboneEndianSwap(Module):
def __init__(self, wb_if):
self.wishbone = wishbone.Interface()
self.sync += [
self.wishbone.adr.eq(wb_if.adr),

self.wishbone.dat_w[0:8].eq(wb_if.dat_w[24:32]),
self.wishbone.dat_w[8:16].eq(wb_if.dat_w[16:24]),
self.wishbone.dat_w[16:24].eq(wb_if.dat_w[8:16]),
self.wishbone.dat_w[24:32].eq(wb_if.dat_w[0:8]),
#self.wishbone.dat_w.eq(wb_if.dat_w),

wb_if.dat_r[0:8].eq(self.wishbone.dat_r[24:32]),
wb_if.dat_r[8:16].eq(self.wishbone.dat_r[16:24]),
wb_if.dat_r[16:24].eq(self.wishbone.dat_r[8:16]),
wb_if.dat_r[24:32].eq(self.wishbone.dat_r[0:8]),
#wb_if.dat_r.eq(self.wishbone.dat_r),

self.wishbone.sel[3].eq(wb_if.sel[0]),
self.wishbone.sel[2].eq(wb_if.sel[1]),
self.wishbone.sel[1].eq(wb_if.sel[2]),
self.wishbone.sel[0].eq(wb_if.sel[3]),
#self.wishbone.sel.eq(wb_if.sel),

self.wishbone.cyc.eq(wb_if.cyc),
self.wishbone.stb.eq(wb_if.stb),
wb_if.ack.eq(self.wishbone.ack),
self.wishbone.we.eq(wb_if.we),
self.wishbone.cti.eq(wb_if.cti),
self.wishbone.bte.eq(wb_if.bte),
wb_if.err.eq(self.wishbone.err),
]


class HDMI2PCIeSoC(BaseSoC):
csr_peripherals = [
"pcie_phy",
"pcie_dma0",
"pcie_dma1",
"pcie_msi",

"hdmi_out0",
"hdmi_in0",
"hdmi_in0_freq",
"hdmi_in0_edid_mem",
]
csr_map_update(BaseSoC.csr_map, csr_peripherals)

def __init__(self, platform, *args, **kwargs):
BaseSoC.__init__(self, platform, csr_data_width=32, *args, **kwargs)

sys_clk_freq = int(100e6)

# pcie phy
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"), bar0_size=32*1024*1024)
platform.add_false_path_constraints(
self.crg.cd_sys.clk,
self.pcie_phy.cd_pcie.clk)

# pcie endpoint
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy)

# pcie wishbone bridge
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint, lambda a: 1, shadow_base=0x40000000)
self.submodules.wb_swap = WishboneEndianSwap(self.pcie_bridge.wishbone)
self.add_wb_master(self.wb_swap.wishbone)

# pcie dma
self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True)

# pcie msi
self.submodules.pcie_msi = LitePCIeMSI()
self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
self.interrupts = {
"PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq,
"PCIE_DMA0_READER": self.pcie_dma0.reader.irq
}
for i, (k, v) in enumerate(sorted(self.interrupts.items())):
self.comb += self.pcie_msi.irqs[i].eq(v)
self.add_constant(k + "_INTERRUPT", i)

# hdmi in 0
hdmi_in0_pads = platform.request("hdmi_in", 0)
self.submodules.hdmi_in0_freq = FreqMeter(period=sys_clk_freq)
self.submodules.hdmi_in0 = HDMIIn(
hdmi_in0_pads,
self.sdram.crossbar.get_port(mode="write"),
fifo_depth=1024,
device="xc7",
split_mmcm=True)
self.comb += self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk),
for clk in [self.hdmi_in0.clocking.cd_pix.clk,
self.hdmi_in0.clocking.cd_pix1p25x.clk,
self.hdmi_in0.clocking.cd_pix5x.clk]:
self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)
self.platform.add_period_constraint(platform.lookup_request("hdmi_in", 0).clk_p, period_ns(148.5e6))

# hdmi out 0
hdmi_out0_dram_port = self.sdram.crossbar.get_port(mode="read", dw=16, cd="hdmi_out0_pix", reverse=True)
self.submodules.hdmi_out0 = VideoOut(
platform.device,
platform.request("hdmi_out", 0),
hdmi_out0_dram_port,
"ycbcr422",
fifo_depth=4096)
for clk in [self.hdmi_out0.driver.clocking.cd_pix.clk,
self.hdmi_out0.driver.clocking.cd_pix5x.clk]:
self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)

for name, value in sorted(self.platform.hdmi_infos.items()):
self.add_constant(name, value)

self.add_interrupt("hdmi_in0")


SoC = HDMI2PCIeSoC
Loading

0 comments on commit b5f73ac

Please sign in to comment.