--- /dev/null
+from litex.build.generic_platform import *
+from litex.build.altera import AlteraPlatform
+from litex.build.altera.programmer import USBBlaster
+
+# I/O --------------------------------------------------------------------------
+
+_io = [
+
+ # Persistent I/O - fixed on the AC440B itself ------------------------------
+
+ # Clk
+ ("clk50", 0, Pins("T2"), IOStandard("3.3-V LVTTL")),
+
+ # D1-D4
+ ("u_led_n", 0, Pins("V22"), IOStandard("3.3-V LVTTL")),
+ ("u_led_n", 1, Pins("V21"), IOStandard("3.3-V LVTTL")),
+ ("u_led_n", 2, Pins("U22"), IOStandard("3.3-V LVTTL")),
+ ("u_led_n", 3, Pins("U21"), IOStandard("3.3-V LVTTL")),
+
+ # RST, K1-K2
+ ("rst_n", 0, Pins("D2"), IOStandard("3.3-V LVTTL")),
+ ("u_key_n", 0, Pins("W1"), IOStandard("3.3-V LVTTL")),
+ ("u_key_n", 1, Pins("V1"), IOStandard("3.3-V LVTTL")),
+
+ # Persistent I/O end -------------------------------------------------------
+
+ ("serial", 0,
+ Subsignal("tx", Pins("Y22"), IOStandard("3.3-V LVTTL")),
+ Subsignal("rx", Pins("W22"), IOStandard("3.3-V LVTTL"))
+ ),
+
+ ]
+
+_connectors = [
+
+]
+
+# Platform ---------------------------------------------------------------------
+
+class Platform(AlteraPlatform):
+ default_clk_name = "clk50"
+ default_clk_period = 1e9/50e6
+
+ def __init__(self, toolchain="quartus"):
+ AlteraPlatform.__init__(self, "EP4CE40F23C8", _io, _connectors, toolchain=toolchain)
+ self.add_platform_command("set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION \"USE AS REGULAR IO\"")
+
+ def create_programmer(self):
+ return USBBlaster()
+
+ def do_finalize(self, fragment):
+ AlteraPlatform.do_finalize(self, fragment)
+ self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
--- /dev/null
+#!/usr/bin/env python3
+
+from migen import *
+
+from litex.gen import *
+
+from litex.soc.cores.clock import CycloneIVPLL
+from litex.soc.integration.soc_core import *
+from litex.soc.integration.builder import *
+from litex.soc.interconnect.csr import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
+
+import mmuless_board
+
+# CRG --------------------------------------------------------------------------
+
+class _CRG(LiteXModule):
+ def __init__(self, platform, sys_clk_freq):
+ self.rst = Signal()
+ self.cd_por = ClockDomain(reset_less=True)
+ self.cd_sys = ClockDomain()
+ # clock domain used only for reset button sync
+ self.cd_sync = ClockDomain()
+
+ clk50 = platform.request("clk50")
+ rst_n = platform.request("rst_n")
+
+ # POR
+ por_count = Signal(16, reset=2**16 - 1)
+ por_done = Signal()
+ self.comb += self.cd_por.clk.eq(clk50)
+ self.comb += por_done.eq(por_count == 0)
+ self.sync.por += If(~por_done, por_count.eq(por_count - 1))
+
+ # PLL
+ self.pll = pll = CycloneIVPLL(speedgrade="-6")
+ self.comb += pll.reset.eq(~por_done | self.rst)
+ pll.register_clkin(clk50, 50e6)
+ pll.create_clkout(self.cd_sys, sys_clk_freq, margin=0, with_reset=False)
+
+ # Sys CD
+ sys_rst = Signal()
+ self.comb += sys_rst.eq(~pll.locked)
+ self.specials += AsyncResetSynchronizer(self.cd_sys, sys_rst)
+
+ # Sync Cd
+ self.comb += self.cd_sync.clk.eq(self.cd_sys.clk)
+ self.specials += AsyncResetSynchronizer(self.cd_sync, ~rst_n)
+
+
+# BaseSoC ----------------------------------------------------------------------
+
+class BaseSoC(SoCCore):
+ def __init__(self, sys_clk_freq=50e6,
+ **kwargs):
+
+ platform = mmuless_board.Platform()
+
+ # CRG ------------------------------------------------------------------
+ self.crg = _CRG(platform, sys_clk_freq)
+
+ # SoCCore --------------------------------------------------------------
+ if kwargs["with_jtagbone"]:
+ if kwargs.get("uart_name", "serial") == "serial": kwargs["uart_name"] = "crossover"
+
+ SoCCore.__init__(self, platform, sys_clk_freq,
+ ident = "LiteX SoC on SiMiaoHub AC440B",
+ **kwargs
+ )
+
+ # Leds -----------------------------------------------------------------
+ leds = Cat(*[platform.request("u_led_n", i) for i in range(4)])
+ self.submodules.leds = CSRStorage(len(leds), description="Board LEDs")
+ self.comb += leds.eq(~self.leds.storage)
+
+ # Buttons --------------------------------------------------------------
+ keys = Cat(*[platform.request("u_key_n", i) for i in range(2)])
+ self.submodules.btns = CSRStatus(len(keys), description="Board buttons")
+ self.comb += self.btns.status.eq(~keys)
+ # Reset button hook
+ self.comb += If(self.crg.cd_sync.rst, self.cpu.reset.eq(1))
+
+
+
+# Build ------------------------------------------------------------------------
+
+def main():
+ from litex.build.parser import LiteXArgumentParser
+ parser = LiteXArgumentParser(platform=mmuless_board.Platform, description="LiteX SoC on SiMiaoHub AC440B")
+ parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
+ args = parser.parse_args()
+
+ soc = BaseSoC(
+ sys_clk_freq = args.sys_clk_freq,
+ **parser.soc_argdict
+ )
+
+ builder = Builder(soc, **parser.builder_argdict)
+ if args.build:
+ builder.build(**parser.toolchain_argdict)
+
+ if args.load:
+ prog = soc.platform.create_programmer()
+ prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
+
+if __name__ == "__main__":
+ main()