Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
initial support for pipistrello board
  • Loading branch information
fallen committed Nov 13, 2015
1 parent 4f2aac2 commit c205b98
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 5 deletions.
10 changes: 7 additions & 3 deletions Makefile
Expand Up @@ -10,10 +10,14 @@ export PYTHONHASHSEED=0

BOARD ?= atlys
MSCDIR ?= third_party/misoc
PROG ?= openocd
ifneq ($(BOARD),pipistrello)
PROG ?= openocd
endif
TARGET ?= hdmi2usb
FILTER ?= tee

ifneq ($(PROG),)
PROGRAMMER_OPTION ?= -Op programmer $(PROG)
endif
HDMI2USBDIR = ../..
PYTHON = python3
DATE = `date +%Y_%m_%d`
Expand All @@ -26,7 +30,7 @@ CMD = $(PYTHON) \
-X $(HDMI2USBDIR) \
-t $(BOARD)_$(TARGET) \
-Ot firmware_filename $(HDMI2USBDIR)/firmware/lm32/firmware.bin \
-Op programmer $(PROG) \
$(PROGRAMMER_OPTION) \
$(MISOC_EXTRA_CMDLINE)

ifeq ($(OS),Windows_NT)
Expand Down
4 changes: 2 additions & 2 deletions firmware/lm32/processor.c
Expand Up @@ -363,12 +363,12 @@ static void edid_set_mode(const struct video_timing *mode)
{
unsigned char edid[128];
int i;
#ifdef CSR_HDMI_OUT0_BASE
#ifdef CSR_HDMI_IN0_BASE
generate_edid(&edid, "OHW", "TV", 2015, "HDMI2USB 1", mode);
for(i=0;i<sizeof(edid);i++)
MMPTR(CSR_HDMI_IN0_EDID_MEM_BASE+4*i) = edid[i];
#endif
#ifdef CSR_HDMI_OUT1_BASE
#ifdef CSR_HDMI_IN1_BASE
generate_edid(&edid, "OHW", "TV", 2015, "HDMI2USB 2", mode);
for(i=0;i<sizeof(edid);i++)
MMPTR(CSR_HDMI_IN1_EDID_MEM_BASE+4*i) = edid[i];
Expand Down
189 changes: 189 additions & 0 deletions targets/pipistrello_base.py
@@ -0,0 +1,189 @@
from gateware.hdmi_out import HDMIOut

from fractions import Fraction
import struct

from migen.fhdl.std import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.bus import wishbone

from misoclib.mem.sdram.module import MT46H32M16
from misoclib.mem.sdram.phy import s6ddrphy
from misoclib.mem.sdram.core.lasmicon import LASMIconSettings
from misoclib.mem.flash import spiflash
from misoclib.soc.sdram import SDRAMSoC

from gateware import dna


class _CRG(Module):
def __init__(self, platform, clk_freq):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sdram_half = ClockDomain()
self.clock_domains.cd_sdram_full_wr = ClockDomain()
self.clock_domains.cd_sdram_full_rd = ClockDomain()
self.clock_domains.cd_base50 = ClockDomain()
self.clock_domains.cd_por = ClockDomain()

self.clk4x_wr_strb = Signal()
self.clk4x_rd_strb = Signal()

f0 = Fraction(50, 1)*1000000
p = 12
f = Fraction(clk_freq*p, f0)
n, d = f.numerator, f.denominator
print("n/d : {}/{}".format(n ,d))
assert 19e6 <= f0/d <= 500e6 # pfd
assert 400e6 <= f0*n/d <= 1080e6 # vco

clk50 = platform.request("clk50")
clk50a = Signal()
self.specials += Instance("IBUFG", i_I=clk50, o_O=clk50a)
clk50b = Signal()
self.specials += Instance("BUFIO2", p_DIVIDE=1,
p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
i_I=clk50a, o_DIVCLK=clk50b)
pll_lckd = Signal()
pll_fb = Signal()
pll = Signal(6)
self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
p_DIVCLK_DIVIDE=d, p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0.,
i_CLKIN1=clk50b, i_CLKIN2=0, i_CLKINSEL=1,
p_CLKIN1_PERIOD=1e9/f0, p_CLKIN2_PERIOD=0.,
i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, # sdram wr rd
p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//4,
p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, # sdram dqs adr ctrl
p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, # off-chip ddr
p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1,
p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, # sys
)
self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys.clk)
reset = platform.request("user_btn")
self.comb += self.cd_base50.clk.eq(clk50a)
por = Signal(max=1 << 11, reset=(1 << 11) - 1)
self.specials += AsyncResetSynchronizer(self.cd_base50, por > 0)
self.sync.por += If(por != 0, por.eq(por - 1))
self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
self.specials += AsyncResetSynchronizer(self.cd_por, reset)
self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0))
self.specials += Instance("BUFG", i_I=pll[2], o_O=self.cd_sdram_half.clk)
self.specials += Instance("BUFPLL", p_DIVIDE=4,
i_PLLIN=pll[0], i_GCLK=self.cd_sys.clk,
i_LOCKED=pll_lckd, o_IOCLK=self.cd_sdram_full_wr.clk,
o_SERDESSTROBE=self.clk4x_wr_strb)
self.comb += [
self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk),
self.clk4x_rd_strb.eq(self.clk4x_wr_strb),
]
clk_sdram_half_shifted = Signal()
self.specials += Instance("BUFG", i_I=pll[3], o_O=clk_sdram_half_shifted)
clk = platform.request("ddram_clock")
self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
p_INIT=0, p_SRTYPE="SYNC",
i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1,
i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
o_Q=clk.p)
self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
p_INIT=0, p_SRTYPE="SYNC",
i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
o_Q=clk.n)


def _get_firmware_data(firmware_filename):
data = []
try:
with open(firmware_filename, "rb") as firmware_file:
while True:
w = firmware_file.read(4)
if not w:
break
data.append(struct.unpack(">I", w)[0])
except:
pass
return data


class BaseSoC(SDRAMSoC):
default_platform = "pipistrello"

csr_map = {
"spiflash": 16,
"ddrphy": 17,
"dna": 18,
}
csr_map.update(SDRAMSoC.csr_map)

mem_map = {
"firmware_ram": 0x20000000, # (default shadow @0xa0000000)
}
mem_map.update(SDRAMSoC.mem_map)

def __init__(self, platform, clk_freq=(83 + Fraction(1, 3))*1000*1000,
sdram_controller_settings=LASMIconSettings(l2_size=32,
with_bandwidth=True),
firmware_ram_size=0xa000, firmware_filename=None, **kwargs):
SDRAMSoC.__init__(self, platform, clk_freq,
integrated_rom_size=0x8000,
sdram_controller_settings=sdram_controller_settings,
**kwargs)

self.submodules.crg = _CRG(platform, clk_freq)
self.submodules.dna = dna.DNA()
self.submodules.firmware_ram = wishbone.SRAM(firmware_ram_size, init=_get_firmware_data(firmware_filename))
self.register_mem("firmware_ram", self.mem_map["firmware_ram"], self.firmware_ram.bus, firmware_ram_size)
self.add_constant("ROM_BOOT_ADDRESS", self.mem_map["firmware_ram"])

if not self.integrated_main_ram_size:
self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY(platform.request("ddram"),
MT46H32M16(self.clk_freq),
rd_bitslip=1,
wr_bitslip=3,
dqs_ddr_alignment="C1")
self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb),
]
self.register_sdram_phy(self.ddrphy)

if not self.integrated_rom_size:
self.submodules.spiflash = spiflash.SpiFlash(platform.request("spiflash4x"),
dummy=10, div=4)
self.add_constant("SPIFLASH_PAGE_SIZE", 256)
self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
self.flash_boot_address = 0x180000
self.register_rom(self.spiflash.bus, 0x1000000)
platform.add_platform_command("""PIN "hdmi_out_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;""")

_hdmi_infos = {
"HDMI_OUT0_MNEMONIC": "J4",
"HDMI_OUT0_DESCRIPTION": "XXX",
}


class VideomixerSoC(BaseSoC):

csr_map = {
"hdmi_out0": 20,
}
csr_map.update(BaseSoC.csr_map)

def __init__(self, platform, **kwargs):
BaseSoC.__init__(self, platform, **kwargs)
self.submodules.hdmi_out0 = HDMIOut(platform.request("hdmi", 0),
self.sdram.crossbar.get_master())

for k, v in _hdmi_infos.items():
self.add_constant(k, v)

default_subtarget = VideomixerSoC

0 comments on commit c205b98

Please sign in to comment.