Skip to content

Commit a8a5476

Browse files
linuswcksbourdeauducq
authored andcommitted
Add phaser target
1 parent ebeff99 commit a8a5476

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

misoc/targets/phaser.py

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
5+
from migen import *
6+
from migen.genlib.resetsync import AsyncResetSynchronizer
7+
from migen.genlib.cdc import MultiReg
8+
from migen.build.platforms.sinara import phaser
9+
10+
from misoc.cores.sdram_settings import MT41K256M16
11+
from misoc.cores.sdram_phy import a7ddrphy
12+
from misoc.cores import virtual_leds, spi_flash, icap
13+
from misoc.cores.a7_gtp import *
14+
from misoc.integration.soc_sdram import *
15+
from misoc.integration.builder import *
16+
from misoc.interconnect.csr import *
17+
18+
19+
class AsyncResetSynchronizerBUFG(Module):
20+
def __init__(self, cd, async_reset):
21+
if not hasattr(async_reset, "attr"):
22+
i, async_reset = async_reset, Signal()
23+
self.comb += async_reset.eq(i)
24+
rst_meta = Signal()
25+
rst_unbuf = Signal()
26+
self.specials += [
27+
Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset,
28+
i_CE=1, i_C=cd.clk, o_Q=rst_meta,
29+
attr={"async_reg", "ars_ff1"}),
30+
Instance("FDPE", p_INIT=1, i_D=rst_meta, i_PRE=async_reset,
31+
i_CE=1, i_C=cd.clk, o_Q=rst_unbuf,
32+
attr={"async_reg", "ars_ff2"}),
33+
Instance("BUFG", i_I=rst_unbuf, o_O=cd.rst)
34+
]
35+
36+
class _RtioSysCRG(Module, AutoCSR):
37+
def __init__(self, platform):
38+
self.clock_domains.cd_sys = ClockDomain()
39+
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
40+
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
41+
self.clock_domains.cd_sys5x = ClockDomain(reset_less=True)
42+
self.clock_domains.cd_clk200 = ClockDomain()
43+
44+
clk125 = platform.request("clk_gtp")
45+
platform.add_period_constraint(clk125, 8.)
46+
self.clk125_buf = Signal()
47+
self.clk125_div2_raw = Signal()
48+
self.clk125_div2 = Signal()
49+
self.specials += Instance("IBUFDS_GTE2",
50+
i_CEB=0,
51+
i_I=clk125.p, i_IB=clk125.n,
52+
o_O=self.clk125_buf,
53+
o_ODIV2=self.clk125_div2_raw,
54+
p_CLKCM_CFG="TRUE",
55+
p_CLKRCV_TRST="TRUE",
56+
p_CLKSWING_CFG=3)
57+
58+
self.specials += Instance("BUFH",
59+
i_I=self.clk125_div2_raw,
60+
o_O=self.clk125_div2)
61+
62+
pll_clk200 = Signal()
63+
pll_fb = Signal()
64+
self.pll_locked = Signal()
65+
self.specials += [
66+
Instance("PLLE2_BASE",
67+
p_CLKIN1_PERIOD=16.0,
68+
i_CLKIN1=self.clk125_div2,
69+
70+
i_CLKFBIN=pll_fb,
71+
o_CLKFBOUT=pll_fb,
72+
o_LOCKED=self.pll_locked,
73+
74+
# VCO @ 1GHz
75+
p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1,
76+
77+
# 200MHz for IDELAYCTRL & OOB reset
78+
# The OOB reset mechanism only resets the MMCM that generates the sysclk,
79+
# clk200 is generated by a PLL parallel to that MMCM, hence not affected
80+
# by the reset.
81+
p_CLKOUT0_DIVIDE=5, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_clk200,
82+
),
83+
Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
84+
AsyncResetSynchronizer(self.cd_clk200, ~self.pll_locked),
85+
]
86+
87+
reset_counter = Signal(4, reset=15)
88+
ic_reset = Signal(reset=1)
89+
self.sync.clk200 += \
90+
If(reset_counter != 0,
91+
reset_counter.eq(reset_counter - 1)
92+
).Else(
93+
ic_reset.eq(0)
94+
)
95+
self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
96+
97+
mmcm_fb_in = Signal()
98+
mmcm_fb_out = Signal()
99+
mmcm_locked = Signal()
100+
mmcm_sys = Signal()
101+
mmcm_sys4x = Signal()
102+
sys4x_fb_in = Signal()
103+
sys4x_fb_out = Signal()
104+
mmcm_sys4x_dqs = Signal()
105+
mmcm_sys5x = Signal()
106+
self.reset = Signal()
107+
self.specials += [
108+
Instance("MMCME2_BASE",
109+
p_CLKIN1_PERIOD=16.0,
110+
i_CLKIN1=self.clk125_div2,
111+
112+
i_RST=self.reset,
113+
114+
i_CLKFBIN=mmcm_fb_in,
115+
o_CLKFBOUT=mmcm_fb_out,
116+
o_LOCKED=mmcm_locked,
117+
118+
# VCO @ 1.25GHz with MULT=20
119+
p_CLKFBOUT_MULT_F=20, p_DIVCLK_DIVIDE=1,
120+
121+
# 500MHz. Must be more than 400MHz as per DDR3 specs.
122+
p_CLKOUT0_DIVIDE_F=2.5, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=mmcm_sys4x,
123+
124+
# 125MHz
125+
p_CLKOUT1_DIVIDE=10, p_CLKOUT1_PHASE=0.0, o_CLKOUT1=mmcm_sys,
126+
127+
# 625MHz
128+
p_CLKOUT2_DIVIDE=2, p_CLKOUT2_PHASE=0.0, o_CLKOUT2=mmcm_sys5x,
129+
),
130+
Instance("MMCME2_BASE",
131+
p_CLKIN1_PERIOD=2.0,
132+
i_CLKIN1=self.cd_sys4x.clk,
133+
134+
i_RST=~mmcm_locked,
135+
136+
i_CLKFBIN=sys4x_fb_in,
137+
o_CLKFBOUT=sys4x_fb_out,
138+
139+
# VCO @ 1GHz with MULT=2
140+
p_CLKFBOUT_MULT_F=2, p_DIVCLK_DIVIDE=1,
141+
142+
# 500MHz
143+
p_CLKOUT0_DIVIDE_F=2, p_CLKOUT0_PHASE=90.0, o_CLKOUT0=mmcm_sys4x_dqs,
144+
),
145+
Instance("BUFG", i_I=sys4x_fb_out, o_O=sys4x_fb_in),
146+
Instance("BUFG", i_I=mmcm_sys, o_O=self.cd_sys.clk),
147+
Instance("BUFG", i_I=mmcm_sys4x, o_O=self.cd_sys4x.clk),
148+
Instance("BUFG", i_I=mmcm_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk),
149+
Instance("BUFG", i_I=mmcm_sys5x, o_O=self.cd_sys5x.clk),
150+
Instance("BUFG", i_I=mmcm_fb_out, o_O=mmcm_fb_in),
151+
]
152+
153+
self.submodules += AsyncResetSynchronizerBUFG(self.cd_sys, ~mmcm_locked)
154+
155+
156+
class BaseSoC(SoCSDRAM):
157+
def __init__(self, sdram_controller_type="minicon", clk_freq=None, **kwargs):
158+
platform = phaser.Platform(speed_grade="-3", with_uart=True)
159+
160+
if not clk_freq:
161+
clk_freq = 125e6
162+
163+
SoCSDRAM.__init__(self, platform, cpu_reset_address=0x400000, clk_freq=clk_freq, **kwargs)
164+
165+
self.submodules.crg = _RtioSysCRG(platform)
166+
self.csr_devices.append("crg")
167+
168+
self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/self.clk_freq)
169+
170+
self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"))
171+
sdram_module = MT41K256M16(self.clk_freq, "1:4")
172+
self.register_sdram(self.ddrphy, sdram_controller_type,
173+
sdram_module.geom_settings, sdram_module.timing_settings)
174+
self.csr_devices.append("ddrphy")
175+
176+
self.submodules.virtual_leds = virtual_leds.VirtualLeds()
177+
self.csr_devices.append("virtual_leds")
178+
179+
if not self.integrated_rom_size:
180+
spiflash_pads = platform.request("spiflash2x")
181+
spiflash_pads.clk = Signal()
182+
self.specials += Instance("STARTUPE2",
183+
i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0,
184+
i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1)
185+
self.submodules.spiflash = spi_flash.SpiFlash(
186+
spiflash_pads, dummy=5, div=2,
187+
endianness=self.cpu.endianness, dw=self.cpu_dw)
188+
self.config["SPIFLASH_PAGE_SIZE"] = 256
189+
self.config["SPIFLASH_SECTOR_SIZE"] = 0x10000
190+
self.flash_boot_address = 0x450000
191+
self.register_rom(self.spiflash.bus, 16*1024*1024)
192+
self.csr_devices.append("spiflash")
193+
194+
self.submodules.icap = icap.ICAP("7series", platform=platform)
195+
self.csr_devices.append("icap")
196+
197+
198+
def main():
199+
parser = argparse.ArgumentParser(description="MiSoC port to Sinara Phaser")
200+
builder_args(parser)
201+
soc_sdram_args(parser)
202+
args = parser.parse_args()
203+
204+
soc = BaseSoC(**soc_sdram_argdict(args))
205+
builder = Builder(soc, **builder_argdict(args))
206+
builder.build()
207+
208+
209+
if __name__ == "__main__":
210+
main()

0 commit comments

Comments
 (0)