Skip to content

Commit a3b3816

Browse files
Merge pull request #623 from eastWillow/master
Add support for embedfire rise pro
2 parents 041c160 + d7f2b5a commit a3b3816

File tree

2 files changed

+356
-0
lines changed

2 files changed

+356
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#
2+
# This file is part of LiteX-Boards.
3+
#
4+
# Copyright (c) 2024 Yu-Ti Kuo <[email protected]>
5+
# SPDX-License-Identifier: BSD-2-Clause
6+
# embedfire rise pro FPGA: https://detail.tmall.com/item.htm?id=645153441975
7+
8+
from litex.build.generic_platform import *
9+
from litex.build.xilinx import Xilinx7SeriesPlatform
10+
from litex.build.openocd import OpenOCD
11+
from litex.build.xilinx.programmer import VivadoProgrammer
12+
13+
# IOs ----------------------------------------------------------------------------------------------
14+
15+
_io = [
16+
# Clk / Rst
17+
("clk50" , 0, Pins("W19"), IOStandard("LVCMOS33")),
18+
("cpu_reset", 0, Pins("N15"), IOStandard("LVCMOS33")),
19+
20+
# Leds
21+
("user_led", 0, Pins("M21"), IOStandard("LVCMOS33")),
22+
("user_led", 1, Pins("L21"), IOStandard("LVCMOS33")),
23+
("user_led", 2, Pins("K21"), IOStandard("LVCMOS33")),
24+
("user_led", 3, Pins("K22"), IOStandard("LVCMOS33")),
25+
26+
# Buttons
27+
("user_sw", 0, Pins("V17"), IOStandard("LVCMOS33")),
28+
("user_sw", 1, Pins("W17"), IOStandard("LVCMOS33")),
29+
("user_sw", 2, Pins("AA18"), IOStandard("LVCMOS33")),
30+
("user_sw", 3, Pins("AB18"), IOStandard("LVCMOS33")),
31+
32+
# Beeper (Buzzer)
33+
("beeper", 0, Pins("M17"), IOStandard("LVCMOS33")),
34+
35+
# Fan
36+
("fan", 0, Pins("W22"), IOStandard("LVCMOS33")),
37+
38+
# Serial CH340G
39+
("serial", 0,
40+
Subsignal("tx", Pins("N17")),
41+
Subsignal("rx", Pins("P17")),
42+
IOStandard("LVCMOS33")
43+
),
44+
45+
# I2C EEPROM 24C64
46+
("i2c", 0,
47+
Subsignal("scl", Pins("E22")),
48+
Subsignal("sda", Pins("D22")),
49+
IOStandard("LVCMOS33"),
50+
),
51+
52+
# DDR3 SDRAM MT41K256M16
53+
("ddram", 0,
54+
Subsignal("a", Pins(
55+
"AA4 AB2 AA5 AB3 AB1 U2 W1 R2",
56+
"V2 U3 Y1 W2 Y2 U1 V3"),
57+
IOStandard("SSTL135")),
58+
Subsignal("ba", Pins("AA1 Y3 AA3"), IOStandard("SSTL135")),
59+
Subsignal("ras_n", Pins("W6"), IOStandard("SSTL135")),
60+
Subsignal("cas_n", Pins("U5"), IOStandard("SSTL135")),
61+
Subsignal("we_n", Pins("Y4"), IOStandard("SSTL135")),
62+
Subsignal("cs_n", Pins("T1"), IOStandard("SSTL135")),
63+
Subsignal("dm", Pins("D2 G2 M2 M5"), IOStandard("SSTL135")),
64+
Subsignal("dq", Pins(
65+
"C2 G1 A1 F3 B2 F1 B1 E2",
66+
"H3 G3 H2 H5 J1 J5 K1 H4",
67+
"L4 M3 L3 J6 K3 K6 J4 L5",
68+
"P1 N4 R1 N2 M6 N5 P6 P2"),
69+
IOStandard("SSTL135"),
70+
Misc("IN_TERM=UNTUNED_SPLIT_40")),
71+
Subsignal("dqs_p", Pins("E1 K2 M1 P5"),
72+
IOStandard("DIFF_SSTL135"),
73+
Misc("IN_TERM=UNTUNED_SPLIT_40")),
74+
Subsignal("dqs_n", Pins("D1 J2 L1 P4"),
75+
IOStandard("DIFF_SSTL135"),
76+
Misc("IN_TERM=UNTUNED_SPLIT_40")),
77+
Subsignal("clk_p", Pins("V4"), IOStandard("DIFF_SSTL135")),
78+
Subsignal("clk_n", Pins("W4"), IOStandard("DIFF_SSTL135")),
79+
Subsignal("cke", Pins("AB5"), IOStandard("SSTL135")),
80+
Subsignal("odt", Pins("T5"), IOStandard("SSTL135")),
81+
Subsignal("reset_n", Pins("R3"), IOStandard("SSTL135")),
82+
Misc("SLEW=FAST"),
83+
),
84+
85+
# RGMII Ethernet (RTL8211F)
86+
("eth_clocks", 0,
87+
Subsignal("tx", Pins("C18")),
88+
Subsignal("rx", Pins("C19")),
89+
IOStandard("LVCMOS33")
90+
),
91+
("eth", 0,
92+
#SubSignal("inib"), Pins("D21")),
93+
#Subsignal("rst_n", Pins("E21")),
94+
Subsignal("mdio", Pins("G22")),
95+
Subsignal("mdc", Pins("G21")),
96+
Subsignal("rx_ctl", Pins("C22")),
97+
Subsignal("rx_data", Pins("D20 C20 A18 A19")),
98+
Subsignal("tx_ctl", Pins("B22")),
99+
Subsignal("tx_data", Pins("B20 A20 B21 A21")),
100+
IOStandard("LVCMOS33")
101+
),
102+
103+
# SDCard
104+
("spisdcard", 0,
105+
Subsignal("cd", Pins("AA19")),
106+
Subsignal("clk", Pins("Y22")),
107+
Subsignal("mosi", Pins("Y21")),
108+
Subsignal("cs_n", Pins("A14")),
109+
Subsignal("miso", Pins("AB21")),
110+
Misc("SLEW=FAST"),
111+
IOStandard("LVCMOS33"),
112+
),
113+
114+
("sdcard", 0,
115+
Subsignal("data", Pins("AB21 AB22 AB20 W21"),),
116+
Subsignal("cmd", Pins("Y21"),),
117+
Subsignal("clk", Pins("Y22")),
118+
Subsignal("cd", Pins("AA19")),
119+
Misc("SLEW=FAST"),
120+
IOStandard("LVCMOS33"),
121+
),
122+
]
123+
# Connectors ---------------------------------------------------------------------------------------
124+
125+
_connectors = [] # ToDo
126+
127+
# Platform -----------------------------------------------------------------------------------------
128+
129+
class Platform(Xilinx7SeriesPlatform):
130+
default_clk_name = "clk50"
131+
default_clk_period = 1e9/50e6
132+
133+
def __init__(self, variant="a7-35", toolchain="vivado"):
134+
device = {
135+
"a7-35": "xc7a35tfgg484-2",
136+
"a7-100": "xc7a100tfgg484-2",
137+
"a7-200": "xc7a200tfbg484-2"
138+
}[variant]
139+
Xilinx7SeriesPlatform.__init__(self, device, _io, _connectors, toolchain=toolchain)
140+
self.toolchain.bitstream_commands = \
141+
["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"]
142+
self.toolchain.additional_commands = \
143+
["write_cfgmem -force -format bin -interface spix4 -size 16 "
144+
"-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
145+
self.add_platform_command("set_property INTERNAL_VREF 0.675 [get_iobanks 34]")
146+
147+
def create_programmer(self):
148+
return VivadoProgrammer(flash_part="mt25ql128-spi-x1_x2_x4")
149+
150+
def do_finalize(self, fragment):
151+
Xilinx7SeriesPlatform.do_finalize(self, fragment)
152+
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
#!/usr/bin/env python3
2+
3+
#
4+
# This file is part of LiteX-Boards.
5+
#
6+
# Copyright (c) 2024 Yu-Ti Kuo <[email protected]>
7+
# SPDX-License-Identifier: BSD-2-Clause
8+
# embedfire rise pro FPGA: https://detail.tmall.com/item.htm?id=645153441975
9+
10+
from migen import *
11+
12+
from litex.gen import *
13+
14+
from litex_boards.platforms import embedfire_rise_pro
15+
16+
from litex.soc.cores.clock import *
17+
from litex.soc.integration.soc import SoCRegion
18+
from litex.soc.integration.soc_core import *
19+
from litex.soc.integration.builder import *
20+
from litex.soc.cores.led import LedChaser
21+
from litex.soc.cores.gpio import GPIOIn
22+
from litex.soc.cores.xadc import XADC
23+
from litex.soc.cores.dna import DNA
24+
from litex.soc.cores.pwm import PWM
25+
26+
from litedram.modules import MT41K256M16
27+
from litedram.phy import s7ddrphy
28+
29+
from liteeth.phy.mii import LiteEthPHYMII
30+
31+
# CRG ----------------------------------------------------------------------------------------------
32+
33+
class _CRG(LiteXModule):
34+
def __init__(self, platform, sys_clk_freq, with_dram=True, with_rst=True):
35+
self.rst = Signal()
36+
self.cd_sys = ClockDomain()
37+
if with_dram:
38+
self.cd_sys4x = ClockDomain()
39+
self.cd_sys4x_dqs = ClockDomain()
40+
self.cd_idelay = ClockDomain()
41+
42+
# # #
43+
44+
# Clk/Rst.
45+
clk50 = platform.request("clk50")
46+
rst = ~platform.request("cpu_reset") if with_rst else 0
47+
48+
# PLL.
49+
self.pll = pll = S7PLL(speedgrade=-1)
50+
self.comb += pll.reset.eq(rst | self.rst)
51+
pll.register_clkin(clk50, 50e6)
52+
pll.create_clkout(self.cd_sys, sys_clk_freq)
53+
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
54+
if with_dram:
55+
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
56+
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
57+
pll.create_clkout(self.cd_idelay, 200e6)
58+
59+
# IdelayCtrl.
60+
if with_dram:
61+
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
62+
63+
# BaseSoC ------------------------------------------------------------------------------------------
64+
65+
class BaseSoC(SoCCore):
66+
def __init__(self, variant="a7-35", toolchain="vivado", sys_clk_freq=50e6,
67+
with_xadc = False,
68+
with_dna = False,
69+
with_ethernet = False,
70+
with_etherbone = False,
71+
eth_ip = "192.168.1.50",
72+
remote_ip = None,
73+
eth_dynamic_ip = False,
74+
with_led_chaser = True,
75+
with_buttons = False,
76+
with_beeper = True,
77+
**kwargs):
78+
platform = embedfire_rise_pro.Platform(variant=variant, toolchain=toolchain)
79+
80+
# CRG --------------------------------------------------------------------------------------
81+
with_dram = (kwargs.get("integrated_main_ram_size", 0) == 0)
82+
self.crg = _CRG(platform, sys_clk_freq, with_dram)
83+
84+
# SoCCore ----------------------------------------------------------------------------------
85+
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on embedfire", **kwargs)
86+
87+
# XADC -------------------------------------------------------------------------------------
88+
if with_xadc:
89+
self.xadc = XADC()
90+
91+
# DNA --------------------------------------------------------------------------------------
92+
if with_dna:
93+
self.dna = DNA()
94+
self.dna.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
95+
96+
# DDR3 SDRAM -------------------------------------------------------------------------------
97+
if not self.integrated_main_ram_size:
98+
self.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
99+
memtype = "DDR3",
100+
nphases = 4,
101+
sys_clk_freq = sys_clk_freq)
102+
self.add_sdram("sdram",
103+
phy = self.ddrphy,
104+
module = MT41K256M16(sys_clk_freq, "1:4"),
105+
l2_cache_size = kwargs.get("l2_size", 8192)
106+
)
107+
108+
# Ethernet / Etherbone ---------------------------------------------------------------------
109+
if with_ethernet or with_etherbone:
110+
self.ethphy = LiteEthPHYMII(
111+
clock_pads = self.platform.request("eth_clocks"),
112+
pads = self.platform.request("eth"))
113+
if with_etherbone:
114+
self.add_etherbone(phy=self.ethphy, ip_address=eth_ip, with_ethmac=with_ethernet)
115+
elif with_ethernet:
116+
self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip, local_ip=eth_ip, remote_ip=remote_ip)
117+
118+
# Leds -------------------------------------------------------------------------------------
119+
if with_led_chaser:
120+
self.leds = LedChaser(
121+
pads = platform.request_all("user_led"),
122+
sys_clk_freq = sys_clk_freq,
123+
)
124+
self.leds.add_pwm()
125+
126+
# Buttons ----------------------------------------------------------------------------------
127+
if with_buttons:
128+
self.buttons = GPIOIn(
129+
pads = platform.request_all("user_btn"),
130+
with_irq = self.irq.enabled
131+
)
132+
133+
# Beeper------------------------------------------------------------------------------------
134+
self.beeper = PWM(
135+
pwm=platform.request("beeper", 0),
136+
with_csr = True,
137+
default_enable = False,
138+
default_width = 0x800,
139+
default_period = 0xfff,
140+
)
141+
142+
self.fan_pwm = PWM(
143+
pwm=platform.request("fan", 0),
144+
with_csr = True,
145+
default_enable = False,
146+
default_width = 0x800,
147+
default_period = 0xfff,
148+
)
149+
150+
# Build --------------------------------------------------------------------------------------------
151+
152+
def main():
153+
from litex.build.parser import LiteXArgumentParser
154+
parser = LiteXArgumentParser(platform=embedfire_rise_pro.Platform, description="LiteX SoC on embedfire rise pro.")
155+
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream.")
156+
parser.add_target_argument("--variant", default="a7-35", help="Board variant (a7-35 or a7-100 or a7-200).")
157+
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
158+
parser.add_target_argument("--with-xadc", action="store_true", help="Enable 7-Series XADC.")
159+
parser.add_target_argument("--with-dna", action="store_true", help="Enable 7-Series DNA.")
160+
parser.add_target_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.")
161+
parser.add_target_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.")
162+
parser.add_target_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.")
163+
parser.add_target_argument("--remote-ip", default="192.168.1.100", help="Remote IP address of TFTP server.")
164+
parser.add_target_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting.")
165+
sdopts = parser.target_group.add_mutually_exclusive_group()
166+
sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.")
167+
sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support.")
168+
args = parser.parse_args()
169+
170+
assert not (args.with_etherbone and args.eth_dynamic_ip)
171+
172+
soc = BaseSoC(
173+
variant = args.variant,
174+
toolchain = args.toolchain,
175+
sys_clk_freq = args.sys_clk_freq,
176+
with_xadc = args.with_xadc,
177+
with_dna = args.with_dna,
178+
with_ethernet = args.with_ethernet,
179+
with_etherbone = args.with_etherbone,
180+
eth_ip = args.eth_ip,
181+
remote_ip = args.remote_ip,
182+
eth_dynamic_ip = args.eth_dynamic_ip,
183+
**parser.soc_argdict
184+
)
185+
186+
if args.with_spi_sdcard:
187+
soc.add_spi_sdcard()
188+
if args.with_sdcard:
189+
soc.add_sdcard()
190+
191+
builder = Builder(soc, **parser.builder_argdict)
192+
if args.build:
193+
builder.build(**parser.toolchain_argdict)
194+
195+
if args.load:
196+
prog = soc.platform.create_programmer()
197+
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
198+
199+
if args.flash:
200+
prog = soc.platform.create_programmer()
201+
prog.flash(0, builder.get_bitstream_filename(mode="flash"))
202+
203+
if __name__ == "__main__":
204+
main()

0 commit comments

Comments
 (0)