3 # This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
4 # This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
5 # This file is Copyright (c) 2014 Yann Sionneau <ys@m-labs.hk>
9 from fractions
import Fraction
12 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
14 from litex
.boards
.platforms
import minispartan6
16 from litex
.soc
.cores
.clock
import *
17 from litex
.soc
.integration
.soc_sdram
import *
18 from litex
.soc
.integration
.builder
import *
20 from litedram
.modules
import AS4C16M16
21 from litedram
.phy
import GENSDRPHY
23 # CRG ----------------------------------------------------------------------------------------------
26 def __init__(self
, platform
, clk_freq
, use_s6pll
=False):
27 self
.clock_domains
.cd_sys
= ClockDomain()
28 self
.clock_domains
.cd_sys_ps
= ClockDomain()
32 self
.cd_sys
.clk
.attr
.add("keep")
33 self
.cd_sys_ps
.clk
.attr
.add("keep")
36 self
.submodules
.pll
= pll
= S6PLL(speedgrade
=-1)
37 pll
.register_clkin(platform
.request("clk32"), 32e6
)
38 pll
.create_clkout(self
.cd_sys
, clk_freq
)
39 pll
.create_clkout(self
.cd_sys_ps
, clk_freq
, phase
=270)
42 clk32
= platform
.request("clk32")
44 self
.specials
+= Instance("IBUFG", i_I
=clk32
, o_O
=clk32a
)
46 self
.specials
+= Instance("BUFIO2", p_DIVIDE
=1,
47 p_DIVIDE_BYPASS
="TRUE", p_I_INVERT
="FALSE",
48 i_I
=clk32a
, o_DIVCLK
=clk32b
)
49 f
= Fraction(int(clk_freq
), int(f0
))
50 n
, m
, p
= f
.denominator
, f
.numerator
, 8
51 assert f0
/n
*m
== clk_freq
55 self
.specials
.pll
= Instance("PLL_ADV", p_SIM_DEVICE
="SPARTAN6",
56 p_BANDWIDTH
="OPTIMIZED", p_COMPENSATION
="INTERNAL",
57 p_REF_JITTER
=.01, p_CLK_FEEDBACK
="CLKFBOUT",
58 i_DADDR
=0, i_DCLK
=0, i_DEN
=0, i_DI
=0, i_DWE
=0, i_RST
=0, i_REL
=0,
59 p_DIVCLK_DIVIDE
=1, p_CLKFBOUT_MULT
=m
*p
//n
, p_CLKFBOUT_PHASE
=0.,
60 i_CLKIN1
=clk32b
, i_CLKIN2
=0, i_CLKINSEL
=1,
61 p_CLKIN1_PERIOD
=1000000000/f0
, p_CLKIN2_PERIOD
=0.,
62 i_CLKFBIN
=pll_fb
, o_CLKFBOUT
=pll_fb
, o_LOCKED
=pll_lckd
,
63 o_CLKOUT0
=pll
[0], p_CLKOUT0_DUTY_CYCLE
=.5,
64 o_CLKOUT1
=pll
[1], p_CLKOUT1_DUTY_CYCLE
=.5,
65 o_CLKOUT2
=pll
[2], p_CLKOUT2_DUTY_CYCLE
=.5,
66 o_CLKOUT3
=pll
[3], p_CLKOUT3_DUTY_CYCLE
=.5,
67 o_CLKOUT4
=pll
[4], p_CLKOUT4_DUTY_CYCLE
=.5,
68 o_CLKOUT5
=pll
[5], p_CLKOUT5_DUTY_CYCLE
=.5,
69 p_CLKOUT0_PHASE
=0., p_CLKOUT0_DIVIDE
=p
//1,
70 p_CLKOUT1_PHASE
=0., p_CLKOUT1_DIVIDE
=p
//1,
71 p_CLKOUT2_PHASE
=0., p_CLKOUT2_DIVIDE
=p
//1,
72 p_CLKOUT3_PHASE
=0., p_CLKOUT3_DIVIDE
=p
//1,
73 p_CLKOUT4_PHASE
=0., p_CLKOUT4_DIVIDE
=p
//1, # sys
74 p_CLKOUT5_PHASE
=270., p_CLKOUT5_DIVIDE
=p
//1, # sys_ps
76 self
.specials
+= Instance("BUFG", i_I
=pll
[4], o_O
=self
.cd_sys
.clk
)
77 self
.specials
+= Instance("BUFG", i_I
=pll
[5], o_O
=self
.cd_sys_ps
.clk
)
78 self
.specials
+= AsyncResetSynchronizer(self
.cd_sys
, ~pll_lckd
)
80 self
.specials
+= Instance("ODDR2", p_DDR_ALIGNMENT
="NONE",
81 p_INIT
=0, p_SRTYPE
="SYNC",
82 i_D0
=0, i_D1
=1, i_S
=0, i_R
=0, i_CE
=1,
83 i_C0
=self
.cd_sys
.clk
, i_C1
=~self
.cd_sys
.clk
,
84 o_Q
=platform
.request("sdram_clock"))
86 # BaseSoC ------------------------------------------------------------------------------------------
88 class BaseSoC(SoCSDRAM
):
89 def __init__(self
, sys_clk_freq
=int(80e6
), **kwargs
):
90 assert sys_clk_freq
== int(80e6
)
91 platform
= minispartan6
.Platform()
92 SoCSDRAM
.__init
__(self
, platform
, clk_freq
=sys_clk_freq
,
93 integrated_rom_size
=0x8000,
96 self
.submodules
.crg
= _CRG(platform
, sys_clk_freq
)
98 if not self
.integrated_main_ram_size
:
99 self
.submodules
.sdrphy
= GENSDRPHY(platform
.request("sdram"))
100 sdram_module
= AS4C16M16(sys_clk_freq
, "1:1")
101 self
.register_sdram(self
.sdrphy
,
102 sdram_module
.geom_settings
,
103 sdram_module
.timing_settings
)
105 # Build --------------------------------------------------------------------------------------------
108 parser
= argparse
.ArgumentParser(description
="LiteX SoC on MiniSpartan6")
110 soc_sdram_args(parser
)
111 args
= parser
.parse_args()
113 soc
= BaseSoC(**soc_sdram_argdict(args
))
114 builder
= Builder(soc
, **builder_argdict(args
))
118 if __name__
== "__main__":