5b605b92e9fbab22100ba083ecbdf3122b815ca2
[smh-ac440b-litex.git] / smh_ac440b_target.py
1 #!/usr/bin/env python3
2
3 from migen import *
4
5 from litex.gen import *
6
7 from litex.soc.cores.clock import CycloneIVPLL
8 from litex.soc.integration.soc_core import *
9 from litex.soc.integration.builder import *
10 from litex.soc.interconnect.csr import *
11 from migen.genlib.resetsync import AsyncResetSynchronizer
12
13 import mmuless_board
14
15 # CRG --------------------------------------------------------------------------
16
17 class _CRG(LiteXModule):
18 def __init__(self, platform, sys_clk_freq):
19 self.rst = Signal()
20 self.cd_por = ClockDomain(reset_less=True)
21 self.cd_sys = ClockDomain()
22 # clock domain used only for reset button sync
23 self.cd_sync = ClockDomain()
24
25 clk50 = platform.request("clk50")
26 rst_n = platform.request("rst_n")
27
28 # POR
29 por_count = Signal(16, reset=2**16 - 1)
30 por_done = Signal()
31 self.comb += self.cd_por.clk.eq(clk50)
32 self.comb += por_done.eq(por_count == 0)
33 self.sync.por += If(~por_done, por_count.eq(por_count - 1))
34
35 # PLL
36 self.pll = pll = CycloneIVPLL(speedgrade="-6")
37 self.comb += pll.reset.eq(~por_done | self.rst)
38 pll.register_clkin(clk50, 50e6)
39 pll.create_clkout(self.cd_sys, sys_clk_freq, margin=0, with_reset=False)
40
41 # Sys CD
42 sys_rst = Signal()
43 self.comb += sys_rst.eq(~pll.locked)
44 self.specials += AsyncResetSynchronizer(self.cd_sys, sys_rst)
45
46 # Sync Cd
47 self.comb += self.cd_sync.clk.eq(self.cd_sys.clk)
48 self.specials += AsyncResetSynchronizer(self.cd_sync, ~rst_n)
49
50
51 # BaseSoC ----------------------------------------------------------------------
52
53 class BaseSoC(SoCCore):
54 def __init__(self, sys_clk_freq=50e6,
55 **kwargs):
56
57 platform = mmuless_board.Platform()
58
59 # CRG ------------------------------------------------------------------
60 self.crg = _CRG(platform, sys_clk_freq)
61
62 # SoCCore --------------------------------------------------------------
63 if kwargs["with_jtagbone"]:
64 if kwargs.get("uart_name", "serial") == "serial": kwargs["uart_name"] = "crossover"
65
66 SoCCore.__init__(self, platform, sys_clk_freq,
67 ident = "LiteX SoC on SiMiaoHub AC440B",
68 **kwargs
69 )
70
71 # Leds -----------------------------------------------------------------
72 leds = Cat(*[platform.request("u_led_n", i) for i in range(4)])
73 self.submodules.leds = CSRStorage(len(leds), description="Board LEDs")
74 self.comb += leds.eq(~self.leds.storage)
75
76 # Buttons --------------------------------------------------------------
77 keys = Cat(*[platform.request("u_key_n", i) for i in range(2)])
78 self.submodules.btns = CSRStatus(len(keys), description="Board buttons")
79 self.comb += self.btns.status.eq(~keys)
80 # Reset button hook
81 self.comb += If(self.crg.cd_sync.rst, self.cpu.reset.eq(1))
82
83
84
85 # Build ------------------------------------------------------------------------
86
87 def main():
88 from litex.build.parser import LiteXArgumentParser
89 parser = LiteXArgumentParser(platform=mmuless_board.Platform, description="LiteX SoC on SiMiaoHub AC440B")
90 parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
91 args = parser.parse_args()
92
93 soc = BaseSoC(
94 sys_clk_freq = args.sys_clk_freq,
95 **parser.soc_argdict
96 )
97
98 builder = Builder(soc, **parser.builder_argdict)
99 if args.build:
100 builder.build(**parser.toolchain_argdict)
101
102 if args.load:
103 prog = soc.platform.create_programmer()
104 prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
105
106 if __name__ == "__main__":
107 main()