import migen in litex/gen
[litex.git] / litex / soc / misoc / targets / mlabs_video.py
1 #!/usr/bin/env python3
2
3 import argparse
4 import os
5 from fractions import Fraction
6 from math import ceil
7
8 from migen import *
9 from migen.build.generic_platform import ConstraintError
10 from migen.build.platforms import mixxeo, m1
11
12 from misoc.cores.sdram_settings import MT46V32M16
13 from misoc.cores.sdram_phy import S6HalfRateDDRPHY
14 from misoc.cores import nor_flash_16
15 # TODO: from misoc.cores import framebuffer
16 from misoc.cores import gpio
17 from misoc.cores.liteeth_mini.phy import LiteEthPHY
18 from misoc.cores.liteeth_mini.mac import LiteEthMAC
19 from misoc.integration.soc_core import mem_decoder
20 from misoc.integration.soc_sdram import *
21 from misoc.integration.builder import *
22
23
24 class _MXCRG(Module):
25 def __init__(self, pads, outfreq1x):
26 self.clock_domains.cd_sys = ClockDomain()
27 self.clock_domains.cd_sdram_half = ClockDomain()
28 self.clock_domains.cd_sdram_full_wr = ClockDomain()
29 self.clock_domains.cd_sdram_full_rd = ClockDomain()
30 self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
31
32 self.clk4x_wr_strb = Signal()
33 self.clk4x_rd_strb = Signal()
34
35 ###
36
37 infreq = 50*1000000
38 ratio = Fraction(outfreq1x)/Fraction(infreq)
39 in_period = float(Fraction(1000000000)/Fraction(infreq))
40
41 self.specials += Instance("mxcrg",
42 Instance.Parameter("in_period", in_period),
43 Instance.Parameter("f_mult", ratio.numerator),
44 Instance.Parameter("f_div", ratio.denominator),
45 Instance.Input("clk50_pad", pads.clk50),
46 Instance.Input("trigger_reset", pads.trigger_reset),
47
48 Instance.Output("sys_clk", self.cd_sys.clk),
49 Instance.Output("sys_rst", self.cd_sys.rst),
50 Instance.Output("clk2x_270", self.cd_sdram_half.clk),
51 Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
52 Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
53 Instance.Output("base50_clk", self.cd_base50.clk),
54
55 Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
56 Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
57 Instance.Output("norflash_rst_n", pads.norflash_rst_n),
58 Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
59 Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n))
60
61
62 class _MXClockPads:
63 def __init__(self, platform):
64 self.clk50 = platform.request("clk50")
65 self.trigger_reset = 0
66 try:
67 self.trigger_reset = platform.request("user_btn", 1)
68 except ConstraintError:
69 pass
70 self.norflash_rst_n = platform.request("norflash_rst_n")
71 ddram_clock = platform.request("ddram_clock")
72 self.ddr_clk_p = ddram_clock.p
73 self.ddr_clk_n = ddram_clock.n
74
75
76 class BaseSoC(SoCSDRAM):
77 def __init__(self, platform_name="mixxeo", **kwargs):
78 if platform_name == "mixxeo":
79 platform = mixxeo.Platform()
80 elif platform_name == "m1":
81 platform = m1.Platform()
82 else:
83 raise ValueError
84 SoCSDRAM.__init__(self, platform,
85 clk_freq=(83 + Fraction(1, 3))*1000000,
86 cpu_reset_address=0x00180000,
87 **kwargs)
88
89 self.submodules.crg = _MXCRG(_MXClockPads(platform), self.clk_freq)
90
91 if not self.integrated_main_ram_size:
92 sdram_module = MT46V32M16(self.clk_freq)
93 self.submodules.ddrphy = S6HalfRateDDRPHY(platform.request("ddram"),
94 sdram_module.memtype,
95 rd_bitslip=0,
96 wr_bitslip=3,
97 dqs_ddr_alignment="C1")
98 self.register_sdram(self.ddrphy, "lasmicon",
99 sdram_module.geom_settings, sdram_module.timing_settings)
100 self.comb += [
101 self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
102 self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
103 ]
104
105 if not self.integrated_rom_size:
106 clk_period_ns = 1000000000/self.clk_freq
107 self.submodules.norflash = nor_flash_16.NorFlash16(
108 platform.request("norflash"),
109 ceil(110/clk_period_ns), ceil(50/clk_period_ns))
110 self.flash_boot_address = 0x001a0000
111 self.register_rom(self.norflash.bus)
112
113 platform.add_platform_command("""
114 INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
115 INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
116 """)
117 platform.add_source(os.path.join(misoc_directory, "cores", "mxcrg.v"))
118
119
120 class MiniSoC(BaseSoC):
121 csr_map = {
122 "ethphy": 16,
123 "ethmac": 17,
124 }
125 csr_map.update(BaseSoC.csr_map)
126
127 interrupt_map = {
128 "ethmac": 2,
129 }
130 interrupt_map.update(BaseSoC.interrupt_map)
131
132 mem_map = {
133 "ethmac": 0x30000000, # (shadow @0xb0000000)
134 }
135 mem_map.update(BaseSoC.mem_map)
136
137 def __init__(self, *args, **kwargs):
138 BaseSoC.__init__(self, *args, **kwargs)
139
140 platform = self.platform
141 if platform.name == "mixxeo":
142 self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
143 if platform.name == "m1":
144 self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0),
145 platform.request("user_btn", 2)))
146 self.submodules.leds = gpio.GPIOOut(Cat(platform.request("user_led", i) for i in range(2)))
147
148 self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"),
149 platform.request("eth"))
150 self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
151 self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
152 self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
153
154
155 def get_vga_dvi(platform):
156 try:
157 pads_vga = platform.request("vga_out")
158 except ConstraintError:
159 pads_vga = None
160 try:
161 pads_dvi = platform.request("dvi_out")
162 except ConstraintError:
163 pads_dvi = None
164 else:
165 platform.add_platform_command("""
166 PIN "dviout_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;
167 """)
168 return pads_vga, pads_dvi
169
170
171 def add_vga_tig(platform, fb):
172 platform.add_platform_command("""
173 NET "{vga_clk}" TNM_NET = "GRPvga_clk";
174 NET "sys_clk" TNM_NET = "GRPsys_clk";
175 TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
176 TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
177 """, vga_clk=fb.driver.clocking.cd_pix.clk)
178
179
180 class FramebufferSoC(MiniSoC):
181 csr_map = {
182 "fb": 18,
183 }
184 csr_map.update(MiniSoC.csr_map)
185
186 def __init__(self, *args, **kwargs):
187 MiniSoC.__init__(self, *args, **kwargs)
188 pads_vga, pads_dvi = get_vga_dvi(platform)
189 self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi,
190 self.sdram.crossbar.get_master())
191 add_vga_tig(platform, self.fb)
192
193
194 def main():
195 parser = argparse.ArgumentParser(description="MiSoC port to the Mixxeo and Milkymist One")
196 builder_args(parser)
197 soc_sdram_args(parser)
198 parser.add_argument("--platform", default="mixxeo",
199 help="platform to build for: mixxeo, m1")
200 parser.add_argument("--soc-type", default="base",
201 help="SoC type: base, mini, framebuffer")
202 args = parser.parse_args()
203
204 cls = {
205 "base": BaseSoC,
206 "mini": MiniSoC,
207 "framebuffer": FramebufferSoC
208 }[args.soc_type]
209 soc = cls(args.platform, **soc_sdram_argdict(args))
210 builder = Builder(soc, **builder_argdict(args))
211 builder.build()
212
213
214 if __name__ == "__main__":
215 main()