-
Notifications
You must be signed in to change notification settings - Fork 285
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #539 from trabucayre/tangPrimer25k
sipeed_tang_primer_25k: new board
- Loading branch information
Showing
2 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# | ||
# This file is part of LiteX-Boards. | ||
# | ||
# Copyright (c) 2023 Gwenhael Goavec-Merou <[email protected]> | ||
# SPDX-License-Identifier: BSD-2-Clause | ||
|
||
from migen import * | ||
|
||
from litex.build.generic_platform import * | ||
from litex.build.gowin.platform import GowinPlatform | ||
from litex.build.openfpgaloader import OpenFPGALoader | ||
|
||
|
||
# IOs ---------------------------------------------------------------------------------------------- | ||
|
||
_io = [ | ||
# Clk / Rst. | ||
("clk50", 0, Pins("E2"), IOStandard("LVCMOS33")), | ||
|
||
# SPIFlash. | ||
("spiflash", 0, | ||
Subsignal("cs_n", Pins("E6"), IOStandard("LVCMOS33")), | ||
Subsignal("clk", Pins("E7"), IOStandard("LVCMOS33")), | ||
Subsignal("mosi", Pins("D6"), IOStandard("LVCMOS33")), | ||
Subsignal("miso", Pins("E5"), IOStandard("LVCMOS33")), | ||
Subsignal("wp", Pins("D5"), IOStandard("LVCMOS33")), | ||
Subsignal("hold", Pins("E4"), IOStandard("LVCMOS33")), | ||
), | ||
("spiflashx4", 0, | ||
Subsignal("cs_n", Pins("E6"), IOStandard("LVCMOS33")), | ||
Subsignal("clk", Pins("E7"), IOStandard("LVCMOS33")), | ||
Subsignal("dq", Pins("D6 E5 D5 E4"), IOStandard("LVCMOS33")), | ||
), | ||
] | ||
|
||
# Dock 204 Pins SODIMM Connector ------------------------------------------------------------------- | ||
|
||
_connectors = [ | ||
["J1", | ||
# ------------------------------------------------- | ||
"---", # 0 | ||
# GND GND ( 1-10). | ||
" --- --- L9 H5 K9 J5 J8 L5 K8 K5", | ||
# GND (11-20). | ||
" F7 H8 F6 H7 --- G7 E8 G8 B3 F5", | ||
# 3V3 3V3 GND GND 3V3 (21-30). | ||
" C3 G5 E3 --- D7 --- --- --- --- L6", | ||
# 3V3 (31-40). | ||
" --- K6 J11 K7 J10 J7 H11 L7 H10 L8", | ||
# GND GND (41-50). | ||
" G11 L10 G10 K10 --- K11 D11 L11 D10 ---", | ||
# GND GND (51-60). | ||
" C11 E11 C10 E10 B11 A11 B10 A10 --- ---", | ||
], | ||
["J2", | ||
# ---------------------------------------------------------------------- | ||
"---", # 0 | ||
# GND 3V3 3V3 ( 1-10). | ||
" --- --- B2 --- C2 L2 F2 L1 F1 K1", | ||
# GND (11-20). | ||
" A1 K2 D8 J4 E1 K4 D1 G2 --- G1", | ||
# TCK TMS TDO TDI GND (21-30). | ||
" C1 L4 B1 L3 A2 J1 A3 J2 --- G4", | ||
# GND 1V8 1V8 (31-40). | ||
" M0_D3_P H4 M0_D3_N H1 --- H2 M0_D2_P --- M0_D2_N ---", | ||
# GND 2V5 2V5 3V3 GND 3V3 3V3 (41-50). | ||
" --- --- M0_CK_P --- M0_CK_N --- --- --- M0_D1_P ---", | ||
# 5V GND GND 5V 5V GND 5V (51-60). | ||
" M0_D1_N --- --- --- M0_D0_P --- M0_D0_N --- --- ---", | ||
], | ||
] | ||
|
||
# Dock IOs ----------------------------------------------------------------------------------------- | ||
|
||
_dock_io = [ | ||
# Serial. | ||
("serial", 0, | ||
Subsignal("rx", Pins("J1:20")), | ||
Subsignal("tx", Pins("J1:19")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# Leds. | ||
("led", 0, Pins("J1:17"), IOStandard("LVCMOS33")), # Pin READY. | ||
("led", 1, Pins("J1:25"), IOStandard("LVCMOS33")), # Pin DONE. | ||
|
||
# Buttons. | ||
("btn_n", 0, Pins("J1:37"), IOStandard("LVCMOS33")), | ||
("btn_n", 1, Pins("J1:39"), IOStandard("LVCMOS33")), | ||
|
||
# USB. | ||
("usb", 0, | ||
Subsignal("d_p", Pins("J1:30")), | ||
Subsignal("d_n", Pins("J1:32")), | ||
IOStandard("LVCMOS33"), | ||
), | ||
] | ||
|
||
_dock_connectors = [ | ||
# Pmod | ||
("j4", "G11 D11 B11 C11 G10 D10 B10 C10"), | ||
("j5", "A11 E11 K11 L5 A10 E10 L11 K5"), | ||
("j6", " F5 G7 H8 H5 G5 G8 H7 J5"), | ||
|
||
("j3", { | ||
1: "K2", 2: "K1", | ||
3: "L1", 4: "L2", | ||
5: "K4", 6: "J4", | ||
7: "G1", 8: "G2", | ||
9: "L3", 10: "L4", | ||
11: "---", 12: "---", | ||
13: "C2", 14: "B2", | ||
15: "F1", 16: "F2", | ||
17: "A1", 18: "E1", | ||
19: "D1", 20: "E3", | ||
21: "J2", 22: "J1", | ||
23: "H4", 24: "G4", | ||
25: "H2", 26: "H1", | ||
27: "J7", 28: "K7", | ||
29: "L8", 30: "L7", | ||
31: "K10", 32: "L10", | ||
33: "K9", 34: "L9", | ||
35: "K8", 36: "J8", | ||
37: "F6", 38: "F7", | ||
39: "J10", 40: "J11", | ||
}), | ||
] | ||
|
||
# Platform ----------------------------------------------------------------------------------------- | ||
|
||
class Platform(GowinPlatform): | ||
default_clk_name = "clk50" | ||
default_clk_period = 1e9/50e6 | ||
|
||
def __init__(self, toolchain="gowin"): | ||
|
||
GowinPlatform.__init__(self, "GW5A-LV25MG121NC1/I0", _io, _connectors, toolchain=toolchain, devicename="GW5A-25A") | ||
self.add_extension(_dock_io) | ||
self.add_connector(_dock_connectors) | ||
|
||
self.toolchain.options["use_mspi_as_gpio"] = 1 # spi flash | ||
self.toolchain.options["use_ready_as_gpio"] = 1 # led | ||
self.toolchain.options["use_done_as_gpio"] = 1 # led | ||
self.toolchain.options["use_cpu_as_gpio"] = 1 # clk | ||
self.toolchain.options["rw_check_on_ram"] = 1 | ||
|
||
def create_programmer(self, kit="openfpgaloader"): | ||
return OpenFPGALoader(cable="ft2232") | ||
|
||
def do_finalize(self, fragment): | ||
GowinPlatform.do_finalize(self, fragment) | ||
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# | ||
# This file is part of LiteX-Boards. | ||
# | ||
# Copyright (c) 2023 Gwenhael Goavec-Merou <[email protected]> | ||
# SPDX-License-Identifier: BSD-2-Clause | ||
|
||
from migen import * | ||
|
||
from litex.gen import * | ||
|
||
from litex.soc.cores.clock.gowin_gw5a import GW5APLL | ||
from litex.soc.integration.soc_core import * | ||
from litex.soc.integration.builder import * | ||
from litex.soc.cores.led import LedChaser | ||
from litex.soc.cores.gpio import GPIOIn | ||
|
||
from litex_boards.platforms import sipeed_tang_primer_25k | ||
|
||
# CRG ---------------------------------------------------------------------------------------------- | ||
|
||
class _CRG(LiteXModule): | ||
def __init__(self, platform, sys_clk_freq): | ||
self.rst = Signal() | ||
self.cd_sys = ClockDomain() | ||
self.cd_por = ClockDomain() | ||
|
||
# # # | ||
|
||
# Clk | ||
clk50 = platform.request("clk50") | ||
|
||
# Power on reset | ||
por_count = Signal(16, reset=2**16-1) | ||
por_done = Signal() | ||
self.comb += [ | ||
self.cd_por.clk.eq(clk50), | ||
por_done.eq(por_count == 0), | ||
] | ||
self.sync.por += If(~por_done, por_count.eq(por_count - 1)) | ||
|
||
# PLL | ||
self.pll = pll = GW5APLL(devicename=platform.devicename, device=platform.device) | ||
self.comb += pll.reset.eq(~por_done | self.rst) | ||
pll.register_clkin(clk50, 50e6) | ||
pll.create_clkout(self.cd_sys, sys_clk_freq) | ||
|
||
# BaseSoC ------------------------------------------------------------------------------------------ | ||
|
||
class BaseSoC(SoCCore): | ||
def __init__(self, sys_clk_freq=50e6, | ||
with_spi_flash = False, | ||
with_led_chaser = True, | ||
with_buttons = True, | ||
**kwargs): | ||
|
||
platform = sipeed_tang_primer_25k.Platform(toolchain="gowin") | ||
|
||
# CRG -------------------------------------------------------------------------------------- | ||
self.crg = _CRG(platform, sys_clk_freq) | ||
|
||
# SoCCore ---------------------------------------------------------------------------------- | ||
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Tang Primer 25K", **kwargs) | ||
|
||
# SPI Flash -------------------------------------------------------------------------------- | ||
if with_spi_flash: | ||
from litespi.modules import W25Q64FV as SpiFlashModule | ||
from litespi.opcodes import SpiNorFlashOpCodes as Codes | ||
self.add_spi_flash(mode="1x", module=SpiFlashModule(Codes.READ_1_1_1)) | ||
|
||
# Leds ------------------------------------------------------------------------------------- | ||
if with_led_chaser: | ||
self.leds = LedChaser( | ||
pads = platform.request_all("led"), | ||
sys_clk_freq = sys_clk_freq | ||
) | ||
|
||
# Buttons ---------------------------------------------------------------------------------- | ||
if with_buttons: | ||
self.buttons = GPIOIn(pads=~platform.request_all("btn_n")) | ||
|
||
|
||
# Build -------------------------------------------------------------------------------------------- | ||
|
||
def main(): | ||
from litex.build.parser import LiteXArgumentParser | ||
parser = LiteXArgumentParser(platform=sipeed_tang_primer_25k.Platform, description="LiteX SoC on Tang Primer 25K.") | ||
parser.add_target_argument("--flash", action="store_true", help="Flash Bitstream.") | ||
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.") | ||
parser.add_target_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed).") | ||
args = parser.parse_args() | ||
|
||
soc = BaseSoC( | ||
sys_clk_freq = args.sys_clk_freq, | ||
with_spi_flash = args.with_spi_flash, | ||
**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() |