Guest User

Untitled

a guest
Sep 2nd, 2023
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.61 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. #
  4. # This file is part of LiteX-Boards.
  5. #
  6. # Copyright (c) 2023 Nimalan M <[email protected]>
  7. # SPDX-License-Identifier: BSD-2-Clause
  8.  
  9. from migen import *
  10.  
  11. from litex.gen import *
  12.  
  13. from litex.soc.doc import generate_docs, generate_svd
  14. from litex.soc.integration.soc_core import *
  15. from litex.soc.integration.soc import SoCRegion
  16. from litex.soc.integration.builder import *
  17. from litex.soc.cores.clock import iCE40PLL
  18. from litex.soc.cores.led import LedChaser
  19.  
  20. from migen.genlib.resetsync import AsyncResetSynchronizer
  21.  
  22.  
  23. #
  24. # This file is part of LiteX-Boards.
  25. #
  26. # Copyright (c) 2023 Nimalan M <[email protected]>
  27. # SPDX-License-Identifier: BSD-2-Clause
  28.  
  29. # The Alchitry Cu is FPGA Development board
  30. # by SparkFun - https://www.sparkfun.com/products/16526.
  31. #
  32. # It has a Lattice ICE40HX8K-CB132IC and can be programmed
  33. # with the Icestorm toolchain
  34. # Schematic - https://cdn.sparkfun.com/assets/2/6/e/5/e/alchitry_cu_sch_update.pdf
  35.  
  36. from litex.build.generic_platform import *
  37. from litex.build.lattice import LatticeiCE40Platform
  38. from litex.build.lattice.programmer import IceStormProgrammer
  39.  
  40. # IOs ----------------------------------------------------------------------------------------------
  41.  
  42. _io = [
  43. # Clk / Rst
  44. ("clk100", 0, Pins("P7"), IOStandard("LVCMOS33")),
  45. ("cpu_reset", 0, Pins("P8"), IOStandard("LVCMOS33")),
  46.  
  47. # Leds
  48. ("user_led", 0, Pins("J11"), IOStandard("LVCMOS33")),
  49. ("user_led", 1, Pins("K11"), IOStandard("LVCMOS33")),
  50. ("user_led", 2, Pins("K12"), IOStandard("LVCMOS33")),
  51. ("user_led", 3, Pins("K14"), IOStandard("LVCMOS33")),
  52. ("user_led", 4, Pins("L12"), IOStandard("LVCMOS33")),
  53. ("user_led", 5, Pins("L14"), IOStandard("LVCMOS33")),
  54. ("user_led", 6, Pins("M12"), IOStandard("LVCMOS33")),
  55. ("user_led", 7, Pins("N14"), IOStandard("LVCMOS33")),
  56.  
  57. # Serial
  58. ("serial", 0,
  59. Subsignal("rx", Pins("P14")),
  60. Subsignal("tx", Pins("M9")),
  61. IOStandard("LVCMOS33")
  62. ),
  63.  
  64. # Onboard QWIIC
  65. ("i2c", 0,
  66. Subsignal("scl", Pins("A4")),
  67. Subsignal("sda", Pins("A3")),
  68. IOStandard("LVCMOS33"),
  69. ),
  70.  
  71. # SPIFlash X25XXSMD1
  72. ("spiflash", 0,
  73. Subsignal("mosi", Pins("M11")),
  74. Subsignal("miso", Pins("P11")),
  75. Subsignal("clk", Pins("P12")),
  76. Subsignal("cs_n", Pins("P13")),
  77. IOStandard("LVCMOS33")
  78. ),
  79. ]
  80.  
  81. # Connectors ---------------------------------------------------------------------------------------
  82.  
  83. _connectors = []
  84.  
  85. # Platform -----------------------------------------------------------------------------------------
  86.  
  87. class Platform(LatticeiCE40Platform):
  88. default_clk_name = "clk100"
  89. default_clk_period = 1e9/100e6
  90.  
  91. def __init__(self, toolchain="icestorm", **kwargs):
  92. LatticeiCE40Platform.__init__(self, "ice40-hx8k-cb132", _io, _connectors, toolchain=toolchain)
  93.  
  94. def create_programmer(self):
  95. return IceStormProgrammer()
  96.  
  97. def do_finalize(self, fragment):
  98. LatticeiCE40Platform.do_finalize(self, fragment)
  99. self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
  100.  
  101.  
  102.  
  103. kB = 1024
  104. mB = 1024*kB
  105.  
  106.  
  107. # CRG -------------------------------------------------------------------------------------------
  108.  
  109. class _CRG(LiteXModule):
  110. def __init__(self, platform, sys_clk_freq):
  111. self.rst = Signal()
  112. self.cd_sys = ClockDomain()
  113. self.cd_por = ClockDomain()
  114.  
  115. # Clk/Rst
  116. clk100 = platform.request("clk100")
  117. rst_n = platform.request("cpu_reset")
  118.  
  119. # Power On Reset
  120. por_count = Signal(16, reset=2**16-1)
  121. por_done = Signal()
  122. self.comb += self.cd_por.clk.eq(ClockSignal())
  123. self.comb += por_done.eq(por_count == 0)
  124. self.sync.por += If(~por_done, por_count.eq(por_count - 1))
  125.  
  126. self.pll = pll = iCE40PLL(primitive="SB_PLL40_CORE")
  127. self.comb += pll.reset.eq(~rst_n) # FIXME: Add proper iCE40PLL reset support and add back | self.rst.
  128. pll.register_clkin(clk100, 100e6)
  129. pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False)
  130. self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked)
  131. platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq)
  132.  
  133. # BaseSoC -----------------------------------------------------------------------------------------
  134.  
  135. class BaseSoC(SoCCore):
  136. def __init__(self,
  137. bios_flash_offset,
  138. sys_clk_freq=50e6,
  139. with_led_chaser = True,
  140. **kwargs):
  141. # Create our platform (fpga interface)
  142. platform = Platform()
  143.  
  144. # Disable Integrated ROM since too large for iCE40.
  145. kwargs["integrated_rom_size"] = 0
  146.  
  147. # SoC with CPU
  148. SoCCore.__init__(self, platform, sys_clk_freq,
  149. ident = "LiteX SoC on Alchitry Cu",
  150.  
  151. **kwargs)
  152.  
  153. # CRG
  154. self.submodules.crg = _CRG(platform, sys_clk_freq)
  155.  
  156. # SPI Flash --------------------------------------------------------------------------------
  157. from litespi.modules import W25Q32
  158. from litespi.opcodes import SpiNorFlashOpCodes as Codes
  159. self.add_spi_flash(mode="1x", module=W25Q32(Codes.READ_1_1_1), with_master=False)
  160.  
  161. # Add ROM linker region --------------------------------------------------------------------
  162. self.bus.add_region("rom", SoCRegion(
  163. origin = self.bus.regions["spiflash"].origin + bios_flash_offset,
  164. size = 256*kB,
  165. linker = True)
  166. )
  167. self.cpu.set_reset_address(self.bus.regions["rom"].origin)
  168.  
  169. # Led
  170. if with_led_chaser:
  171. self.submodules.leds = LedChaser(pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq,period=0.5)
  172.  
  173. # Flash --------------------------------------------------------------------------------------------
  174.  
  175. def flash(build_dir, build_name, bios_flash_offset):
  176. from litex.build.lattice.programmer import IceStormProgrammer
  177. prog = IceStormProgrammer()
  178. prog.flash(bios_flash_offset, f"{build_dir}/software/bios/bios.bin")
  179. prog.flash(0x00000000, f"{build_dir}/gateware/{build_name}.bin")
  180. #prog.flash(bios_flash_offset, f"{build_dir}/../../firmware/firmware.bin")
  181.  
  182. # Build --------------------------------------------------------------------------------------------
  183.  
  184. def main():
  185. from litex.build.parser import LiteXArgumentParser
  186. parser = LiteXArgumentParser(platform=Platform, description="LiteX SoC on Alchitry Cu")
  187. parser.add_target_argument("--flash", action="store_true", help="Flash Bitstream and BIOS.")
  188. parser.add_target_argument("--bios-flash-offset", default="0x040000", help="BIOS offset in SPI Flash (default: 0x40000)")
  189. parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency (default: 50MHz)")
  190. parser.add_target_argument("--with-led-chaser", action="store_true", help="Enable LED Chaser.")
  191. args = parser.parse_args()
  192.  
  193. soc = BaseSoC(
  194. bios_flash_offset = int(args.bios_flash_offset, 0),
  195. sys_clk_freq = args.sys_clk_freq,
  196. cpu_type = "picorv32",
  197. cpu_variant="minimal"
  198. )
  199. builder = Builder(soc, **parser.builder_argdict)
  200. if args.build:
  201. builder.build(**parser.toolchain_argdict)
  202.  
  203. generate_docs(soc, "build/documentation")
  204. generate_svd(soc, "build/software")
  205.  
  206. if args.flash:
  207. flash(builder.output_dir, soc.build_name, args.bios_flash_offset)
  208.  
  209.  
  210. if __name__ == "__main__":
  211. main()
  212.  
Advertisement
Add Comment
Please, Sign In to add comment