1 from fractions
import Fraction
3 from migen
.fhdl
.std
import *
4 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
6 from misoclib
.mem
.sdram
.module
import MT46H32M16
7 from misoclib
.mem
.sdram
.phy
import s6ddrphy
8 from misoclib
.mem
.sdram
.core
.lasmicon
import LASMIconSettings
9 from misoclib
.mem
.flash
import spiflash
10 from misoclib
.soc
.sdram
import SDRAMSoC
14 def __init__(self
, platform
, clk_freq
):
15 self
.clock_domains
.cd_sys
= ClockDomain()
16 self
.clock_domains
.cd_sdram_half
= ClockDomain()
17 self
.clock_domains
.cd_sdram_full_wr
= ClockDomain()
18 self
.clock_domains
.cd_sdram_full_rd
= ClockDomain()
20 self
.clk4x_wr_strb
= Signal()
21 self
.clk4x_rd_strb
= Signal()
23 f0
= Fraction(50, 1)*1000000
25 f
= Fraction(clk_freq
*p
, f0
)
26 n
, d
= f
.numerator
, f
.denominator
27 assert 19e6
<= f0
/d
<= 500e6
# pfd
28 assert 400e6
<= f0
*n
/d
<= 1080e6
# vco
30 clk50
= platform
.request("clk50")
32 self
.specials
+= Instance("IBUFG", i_I
=clk50
, o_O
=clk50a
)
34 self
.specials
+= Instance("BUFIO2", p_DIVIDE
=1,
35 p_DIVIDE_BYPASS
="TRUE", p_I_INVERT
="FALSE",
36 i_I
=clk50a
, o_DIVCLK
=clk50b
)
40 self
.specials
.pll
= Instance("PLL_ADV", p_SIM_DEVICE
="SPARTAN6",
41 p_BANDWIDTH
="OPTIMIZED", p_COMPENSATION
="INTERNAL",
42 p_REF_JITTER
=.01, p_CLK_FEEDBACK
="CLKFBOUT",
43 i_DADDR
=0, i_DCLK
=0, i_DEN
=0, i_DI
=0, i_DWE
=0, i_RST
=0, i_REL
=0,
44 p_DIVCLK_DIVIDE
=d
, p_CLKFBOUT_MULT
=n
, p_CLKFBOUT_PHASE
=0.,
45 i_CLKIN1
=clk50b
, i_CLKIN2
=0, i_CLKINSEL
=1,
46 p_CLKIN1_PERIOD
=1e9
/f0
, p_CLKIN2_PERIOD
=0.,
47 i_CLKFBIN
=pll_fb
, o_CLKFBOUT
=pll_fb
, o_LOCKED
=pll_lckd
,
48 o_CLKOUT0
=pll
[0], p_CLKOUT0_DUTY_CYCLE
=.5,
49 o_CLKOUT1
=pll
[1], p_CLKOUT1_DUTY_CYCLE
=.5,
50 o_CLKOUT2
=pll
[2], p_CLKOUT2_DUTY_CYCLE
=.5,
51 o_CLKOUT3
=pll
[3], p_CLKOUT3_DUTY_CYCLE
=.5,
52 o_CLKOUT4
=pll
[4], p_CLKOUT4_DUTY_CYCLE
=.5,
53 o_CLKOUT5
=pll
[5], p_CLKOUT5_DUTY_CYCLE
=.5,
54 p_CLKOUT0_PHASE
=0., p_CLKOUT0_DIVIDE
=p
//4, # sdram wr rd
55 p_CLKOUT1_PHASE
=0., p_CLKOUT1_DIVIDE
=p
//4,
56 p_CLKOUT2_PHASE
=270., p_CLKOUT2_DIVIDE
=p
//2, # sdram dqs adr ctrl
57 p_CLKOUT3_PHASE
=250., p_CLKOUT3_DIVIDE
=p
//2, # off-chip ddr
58 p_CLKOUT4_PHASE
=0., p_CLKOUT4_DIVIDE
=p
//1,
59 p_CLKOUT5_PHASE
=0., p_CLKOUT5_DIVIDE
=p
//1, # sys
61 self
.specials
+= Instance("BUFG", i_I
=pll
[5], o_O
=self
.cd_sys
.clk
)
62 reset
= platform
.request("user_btn")
63 self
.clock_domains
.cd_por
= ClockDomain()
64 por
= Signal(max=1 << 11, reset
=(1 << 11) - 1)
65 self
.sync
.por
+= If(por
!= 0, por
.eq(por
- 1))
66 self
.comb
+= self
.cd_por
.clk
.eq(self
.cd_sys
.clk
)
67 self
.specials
+= AsyncResetSynchronizer(self
.cd_por
, reset
)
68 self
.specials
+= AsyncResetSynchronizer(self
.cd_sys
, ~pll_lckd |
(por
> 0))
69 self
.specials
+= Instance("BUFG", i_I
=pll
[2], o_O
=self
.cd_sdram_half
.clk
)
70 self
.specials
+= Instance("BUFPLL", p_DIVIDE
=4,
71 i_PLLIN
=pll
[0], i_GCLK
=self
.cd_sys
.clk
,
72 i_LOCKED
=pll_lckd
, o_IOCLK
=self
.cd_sdram_full_wr
.clk
,
73 o_SERDESSTROBE
=self
.clk4x_wr_strb
)
75 self
.cd_sdram_full_rd
.clk
.eq(self
.cd_sdram_full_wr
.clk
),
76 self
.clk4x_rd_strb
.eq(self
.clk4x_wr_strb
),
78 clk_sdram_half_shifted
= Signal()
79 self
.specials
+= Instance("BUFG", i_I
=pll
[3], o_O
=clk_sdram_half_shifted
)
80 clk
= platform
.request("ddram_clock")
81 self
.specials
+= Instance("ODDR2", p_DDR_ALIGNMENT
="NONE",
82 p_INIT
=0, p_SRTYPE
="SYNC",
83 i_D0
=1, i_D1
=0, i_S
=0, i_R
=0, i_CE
=1,
84 i_C0
=clk_sdram_half_shifted
, i_C1
=~clk_sdram_half_shifted
,
86 self
.specials
+= Instance("ODDR2", p_DDR_ALIGNMENT
="NONE",
87 p_INIT
=0, p_SRTYPE
="SYNC",
88 i_D0
=0, i_D1
=1, i_S
=0, i_R
=0, i_CE
=1,
89 i_C0
=clk_sdram_half_shifted
, i_C1
=~clk_sdram_half_shifted
,
93 class BaseSoC(SDRAMSoC
):
94 default_platform
= "pipistrello"
99 csr_map
.update(SDRAMSoC
.csr_map
)
101 def __init__(self
, platform
, sdram_controller_settings
=LASMIconSettings(),
102 clk_freq
=(83 + Fraction(1, 3))*1000*1000, **kwargs
):
103 SDRAMSoC
.__init
__(self
, platform
, clk_freq
,
104 cpu_reset_address
=0x170000, # 1.5 MB
105 sdram_controller_settings
=sdram_controller_settings
,
108 self
.submodules
.crg
= _CRG(platform
, clk_freq
)
110 if not self
.integrated_main_ram_size
:
111 self
.submodules
.ddrphy
= s6ddrphy
.S6HalfRateDDRPHY(platform
.request("ddram"),
112 MT46H32M16(self
.clk_freq
),
115 dqs_ddr_alignment
="C1")
117 self
.ddrphy
.clk4x_wr_strb
.eq(self
.crg
.clk4x_wr_strb
),
118 self
.ddrphy
.clk4x_rd_strb
.eq(self
.crg
.clk4x_rd_strb
),
120 self
.register_sdram_phy(self
.ddrphy
)
122 if not self
.integrated_rom_size
:
123 self
.submodules
.spiflash
= spiflash
.SpiFlash(platform
.request("spiflash4x"),
125 self
.add_constant("SPIFLASH_PAGE_SIZE", 256)
126 self
.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
127 self
.flash_boot_address
= 0x180000
128 self
.register_rom(self
.spiflash
.bus
, 0x1000000)
130 default_subtarget
= BaseSoC