Skip to content

Commit

Permalink
Use SDRAM on the Papilio Pro
Browse files Browse the repository at this point in the history
Based on code by Robert Jordens
sbourdeauducq committed May 23, 2014
1 parent 1dcbb07 commit e9b49eb
Showing 1 changed file with 79 additions and 30 deletions.
109 changes: 79 additions & 30 deletions targets/simple.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,95 @@
from fractions import Fraction

from migen.fhdl.std import *
from migen.bus import wishbone

from misoclib import spiflash
from misoclib.gensoc import GenSoC
from misoclib import lasmicon, spiflash
from misoclib.sdramphy import gensdrphy
from misoclib.gensoc import SDRAMSoC

class PowerOnRst(Module):
def __init__(self, cd, overwrite_cd_rst=True):
self.clock_domains.cd_pwr_on = ClockDomain(reset_less=True)
self.cd_pwr_on.clk = cd.clk
self.pwr_on_rst = Signal()
class _CRG(Module):
def __init__(self, platform, clk_freq):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys_ps = ClockDomain()

rst_n = Signal()
self.sync.pwr_on += rst_n.eq(1)
self.comb += self.pwr_on_rst.eq(~rst_n)
f0 = 32*1000*1000
clk32 = platform.request("clk32")
clk32a = Signal()
self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a)
clk32b = Signal()
self.specials += Instance("BUFIO2", p_DIVIDE=1,
p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
i_I=clk32a, o_DIVCLK=clk32b)
f = Fraction(int(clk_freq), int(f0))
n, m, p = f.denominator, f.numerator, 8
assert f0/n*m == clk_freq
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=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0.,
i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1,
p_CLKIN1_PERIOD=1/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//1,
p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1,
p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1,
p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1,
p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys
p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps
)
self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk)
self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk)
self.specials += Instance("FD", p_INIT=1, i_D=~pll_lckd,
i_C=self.cd_sys.clk, o_Q=self.cd_sys.rst)

if overwrite_cd_rst:
self.comb += cd.rst.eq(self.pwr_on_rst)
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=self.cd_sys.clk, i_C1=~self.cd_sys.clk,
o_Q=platform.request("sdram_clock"))

class SimpleSoC(GenSoC):
class SimpleSoC(SDRAMSoC):
default_platform = "papilio_pro"

def __init__(self, platform, **kwargs):
GenSoC.__init__(self, platform,
clk_freq=32*1000000,
cpu_reset_address=0x60000,
**kwargs)
def __init__(self, platform):
clk_freq = 80*1000*1000
SDRAMSoC.__init__(self, platform, clk_freq,
cpu_reset_address=0x160000)

# We can't use reset_less as CPU does require a reset signal
self.clock_domains.cd_sys = ClockDomain()
self.submodules += PowerOnRst(self.cd_sys)
self.comb += self.cd_sys.clk.eq(platform.request("clk32"))
self.submodules.crg = _CRG(platform, clk_freq)

sdram_geom = lasmicon.GeomSettings(
bank_a=2,
row_a=12,
col_a=8
)
sdram_timing = lasmicon.TimingSettings(
tRP=self.ns(15),
tRCD=self.ns(15),
tWR=self.ns(14),
tWTR=2,
tREFI=self.ns(64*1000*1000/4096, False),
tRFC=self.ns(66),
req_queue_size=8,
read_time=32,
write_time=16
)
self.submodules.sdrphy = gensdrphy.GENSDRPHY(platform.request("sdram"))
self.register_sdram_phy(self.sdrphy.dfi, self.sdrphy.phy_settings, sdram_geom, sdram_timing)

# BIOS is in SPI flash
self.submodules.spiflash = spiflash.SpiFlash(platform.request("spiflash2x"),
cmd=0xefef, cmd_width=16, addr_width=24, dummy=4)
cmd=0xefef, cmd_width=16, addr_width=24, dummy=4, div=4)
self.flash_boot_address = 0x70000
self.register_rom(self.spiflash.bus)

# TODO: use on-board SDRAM instead of block RAM
sys_ram_size = 32*1024
self.submodules.sys_ram = wishbone.SRAM(sys_ram_size)
self.add_wb_slave(lambda a: a[27:29] == 2, self.sys_ram.bus)
self.add_cpu_memory_region("sdram", 0x40000000, sys_ram_size)

default_subtarget = SimpleSoC

0 comments on commit e9b49eb

Please sign in to comment.