fixed review remarks; added zynq7000 as a submodule for using the ps as a slave

This commit is contained in:
mkuhn99 2022-11-23 17:20:25 +01:00
parent c489347a51
commit 926ed21f0b
2 changed files with 57 additions and 124 deletions

View File

@ -5,7 +5,7 @@
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import * from litex.build.generic_platform import *
from litex.build.xilinx import Xilinx7SeriesPlatform, VivadoProgrammer, XilinxPlatform from litex.build.xilinx import Xilinx7SeriesPlatform, VivadoProgrammer
# IOs ---------------------------------------------------------------------------------------------- # IOs ----------------------------------------------------------------------------------------------
@ -80,7 +80,7 @@ _usb_uart_pmod_io = [
_connectors = [ _connectors = [
("pmoda", "N15 L14 K16 K14 N16 L15 J16 J14"), # XADC ("pmoda", "N15 L14 K16 K14 N16 L15 J16 J14"), # XADC
("pmodb", "V8 W8 U7 V7 Y7 Y6 V6 W6"), ("pmodb", "V8 W8 U7 V7 Y7 Y6 V6 W6"),
("pmodc", "V15 W15 T11 T10 W14 Y14 T12 U12"), ("pmodc", "V15 W15 T11 T10 W14 Y14 T12 U12"),
("pmodd", "T14 T15 P14 R14 U14 U15 V17 V18"), ("pmodd", "T14 T15 P14 R14 U14 U15 V17 V18"),
("pmode", "V12 W16 J15 H15 V13 U17 T17 Y17"), ("pmode", "V12 W16 J15 H15 V13 U17 T17 Y17"),
@ -88,20 +88,20 @@ _connectors = [
ps7_config = { ps7_config = {
"z7-20" : { "z7-20" : {
"PCW_UIPARAM_DDR_PARTNO " : "MT41K256M16 RE-125", "PCW_UIPARAM_DDR_PARTNO" : "MT41K256M16 RE-125",
"PCW_FPGA_FCLK0_ENABLE " : "1", "PCW_FPGA_FCLK0_ENABLE" : "1",
"PCW_UART1_BAUD_RATE " : "115200", "PCW_UART1_BAUD_RATE" : "115200",
"PCW_EN_UART1 " : "1", "PCW_EN_UART1" : "1",
"PCW_UART1_PERIPHERAL_ENABLE " : "1", "PCW_UART1_PERIPHERAL_ENABLE" : "1",
"PCW_UART1_UART1_IO " : "MIO 48 .. 49", "PCW_UART1_UART1_IO" : "MIO 48 .. 49",
"PCW_PRESET_BANK1_VOLTAGE " : "LVCMOS 1.8V", "PCW_PRESET_BANK1_VOLTAGE" : "LVCMOS 1.8V",
"PCW_USE_M_AXI_GP0 " : "1", "PCW_USE_M_AXI_GP0" : "1",
"PCW_USE_S_AXI_GP0 " : "1", "PCW_USE_S_AXI_GP0" : "1",
"PCW_USB0_PERIPHERAL_ENABLE " : "1", "PCW_USB0_PERIPHERAL_ENABLE" : "1",
"PCW_USB0_USB0_IO " : "MIO 28 .. 39", "PCW_USB0_USB0_IO" : "MIO 28 .. 39",
"PCW_USB0_RESET_ENABLE " : "1", "PCW_USB0_RESET_ENABLE" : "1",
"PCW_USB0_RESET_IO " : "MIO 46", "PCW_USB0_RESET_IO" : "MIO 46",
"PCW_EN_USB0 " : "1" "PCW_EN_USB0" : "1"
} }
} }
# Platform ----------------------------------------------------------------------------------------- # Platform -----------------------------------------------------------------------------------------
@ -115,7 +115,7 @@ class Platform(Xilinx7SeriesPlatform):
"z7-10": "xc7z010-clg400-1", "z7-10": "xc7z010-clg400-1",
"z7-20": "xc7z020-clg400-1" "z7-20": "xc7z020-clg400-1"
}[variant] }[variant]
XilinxPlatform.__init__(self, device, _io, _connectors, toolchain=toolchain) Xilinx7SeriesPlatform.__init__(self, device, _io, _connectors, toolchain=toolchain)
self.add_extension(_ps7_io) self.add_extension(_ps7_io)
self.add_extension(_usb_uart_pmod_io) self.add_extension(_usb_uart_pmod_io)
self.ps7_config = ps7_config[variant] self.ps7_config = ps7_config[variant]

View File

@ -19,7 +19,9 @@ from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import * from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import * from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser from litex.soc.cores.led import LedChaser
from litex.soc.integration.soc import SoCRegion from litex.soc.integration.soc import SoCRegion
from litex.soc.cores import cpu
# CRG ---------------------------------------------------------------------------------------------- # CRG ----------------------------------------------------------------------------------------------
class _CRG(LiteXModule): class _CRG(LiteXModule):
@ -29,11 +31,11 @@ class _CRG(LiteXModule):
# # # # # #
if use_ps7_clk: if use_ps7_clk:
self.comb += ClockSignal("sys").eq(ClockSignal("ps7")) self.comb += ClockSignal("sys").eq(ClockSignal("ps7"))
self.comb += ResetSignal("sys").eq(ResetSignal("ps7") | self.rst) self.comb += ResetSignal("sys").eq(ResetSignal("ps7") | self.rst)
else: else:
self.pll = pll = S7PLL(speedgrade=-1) self.pll = pll = S7PLL(speedgrade=-1)
self.comb += pll.reset.eq(self.rst) self.comb += pll.reset.eq(self.rst)
pll.register_clkin(platform.request("clk125"), 125e6) pll.register_clkin(platform.request("clk125"), 125e6)
pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys, sys_clk_freq)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst. platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
@ -41,12 +43,12 @@ class _CRG(LiteXModule):
# BaseSoC ------------------------------------------------------------------------------------------ # BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore): class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(100e6), variant="z7-10", with_ps7=False, with_led_chaser=True, **kwargs): def __init__(self, sys_clk_freq=100e6, variant="z7-10", with_ps7=False, with_led_chaser=True, **kwargs):
platform = digilent_zybo_z7.Platform() platform = digilent_zybo_z7.Platform()
self.builder = None self.builder = None
# CRG -------------------------------------------------------------------------------------- # CRG --------------------------------------------------------------------------------------
use_ps7_clk = (kwargs.get("cpu_type", None) == "zynq7000") use_ps7_clk = (kwargs.get("cpu_type", None) == "zynq7000")
self.crg = _CRG(platform, sys_clk_freq, use_ps7_clk) self.crg = _CRG(platform, sys_clk_freq, use_ps7_clk)
# SoCCore ---------------------------------------------------------------------------------- # SoCCore ----------------------------------------------------------------------------------
if kwargs["uart_name"] == "serial": if kwargs["uart_name"] == "serial":
@ -58,18 +60,17 @@ class BaseSoC(SoCCore):
'csr': 0x4000_0000, # Zynq GP0 default 'csr': 0x4000_0000, # Zynq GP0 default
} }
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Zybo Z7", **kwargs) SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Zybo Z7", **kwargs)
# Zynq7000 Integration --------------------------------------------------------------------- # Zynq7000 Integration ---------------------------------------------------------------------
if kwargs.get("cpu_type", None) == "zynq7000": if kwargs.get("cpu_type", None) == "zynq7000":
self.cpu.use_rom = True self.cpu.use_rom = True
if variant == "z7-10": if variant == "z7-10":
# Get and set the pre-generated .xci FIXME: change location? add it to the repository? Make config # Get and set the pre-generated .xci FIXME: change location? add it to the repository? Make config
os.makedirs("xci", exist_ok=True) os.makedirs("xci", exist_ok=True)
os.system("wget https://github.com/litex-hub/litex-boards/files/8339591/zybo_z7_ps7.txt") os.system("wget https://github.com/litex-hub/litex-boards/files/8339591/zybo_z7_ps7.txt")
os.system("mv zybo_z7_ps7.txt xci/zybo_z7_ps7.xci") os.system("mv zybo_z7_ps7.txt xci/zybo_z7_ps7.xci")
self.cpu.set_ps7_xci("xci/zybo_z7_ps7.xci") self.cpu.set_ps7_xci("xci/zybo_z7_ps7.xci")
else: else:
self.cpu.set_ps7(name="ps", config = platform.ps7_config) self.cpu.set_ps7(name="ps", config = platform.ps7_config)
# Connect AXI GP0 to the SoC with base address of 0x40000000 (default one) # Connect AXI GP0 to the SoC with base address of 0x40000000 (default one)
@ -90,13 +91,32 @@ class BaseSoC(SoCCore):
linker = True) linker = True)
) )
self.constants["CONFIG_CLOCK_FREQUENCY"] = 666666687 self.constants["CONFIG_CLOCK_FREQUENCY"] = 666666687
self.bus.add_region("flash", SoCRegion(origin=0xFC00_0000, size=0x4_0000, mode="rwx")) self.bus.add_region("flash", SoCRegion(
origin = 0xFC00_0000,
size = 0x4_0000,
mode = "rwx")
)
# PS7 as Slave Integration --------------------------------------------------------------------- # PS7 as Slave Integration ---------------------------------------------------------------------
elif with_ps7: elif with_ps7:
#TODO: ps7_slave for each variant
if variant == "z7-20": if variant == "z7-20":
self.add_ps7() cpu_cls = cpu.CPUS["zynq7000"]
self.add_axi_gp_slave() zynq = cpu_cls(self.platform, "standard") # zynq7000 has no variants
zynq.set_ps7(name="ps", config = platform.ps7_config)
axi_gp_slave0 = zynq.add_axi_gp_slave(clock_domain = self.crg.cd_sys.name)
self.submodules += zynq
self.bus.add_slave(
name="ps",slave=axi_gp_slave0,
region=SoCRegion(
origin=0x2000_0000,
size=0x2000_0000,
mode="rwx"
)
)
else:
#TODO: make config for zybo-z7-10
raise NotImplementedError
# Leds ------------------------------------------------------------------------------------- # Leds -------------------------------------------------------------------------------------
if with_led_chaser: if with_led_chaser:
self.leds = LedChaser( self.leds = LedChaser(
@ -146,110 +166,23 @@ class BaseSoC(SoCCore):
#endif #endif
''') ''')
def add_ps7(self):
ps7_tcl = []
ps7_name = "processing_system"
ps7_tcl.append(f"set ps7 [create_ip -vendor xilinx.com -name processing_system7 -module_name {ps7_name}]")
ps7_tcl.append("set_property -dict [list \\")
for config, value in self.platform.ps7_config.items():
ps7_tcl.append("CONFIG.{} {} \\".format(config, '{{' + str(value) + '}}'))
ps7_tcl.append(f"] [get_ips {ps7_name}]")
ps7_tcl += [
f"upgrade_ip [get_ips {ps7_name}]",
f"generate_target all [get_ips {ps7_name}]",
f"synth_ip [get_ips {ps7_name}]"
]
self.platform.toolchain.pre_synthesis_commands += ps7_tcl
def add_axi_gp_slave(self):
axi_gpn = axi.AXIInterface(data_width=32, address_width=32, id_width=12)
#TODO: better mapping/ Different Regions for IOP and DDR
aw_address = Signal(32)
ar_address = Signal(32)
#FIXME: define offsets with csr register?
self.comb += If(axi_gpn.aw.addr < 0x1ffbffff,
## DDR
aw_address.eq(axi_gpn.aw.addr + 0x0008_0000)
).Else(
## IOP Register
aw_address.eq(axi_gpn.aw.addr + 0xe000_0000))
self.comb += If(axi_gpn.ar.addr < 0x1ffbffff,
## DDR
ar_address.eq(axi_gpn.ar.addr + 0x0008_0000)
).Else(
## IOP Register
ar_address.eq(axi_gpn.ar.addr + 0xe000_0000))
# generate instance of ps7 with ports for axi_s_gp0
ps7_axi_s_gp0 = Instance("processing_system" ,
#o_S_AXI_GP0_ARESETN = axi_gpn.a.resetn,
o_S_AXI_GP0_ARREADY = axi_gpn.ar.ready,
o_S_AXI_GP0_AWREADY = axi_gpn.aw.ready,
o_S_AXI_GP0_BVALID = axi_gpn.b.valid,
o_S_AXI_GP0_RLAST = axi_gpn.r.last,
o_S_AXI_GP0_RVALID = axi_gpn.r.valid,
o_S_AXI_GP0_WREADY = axi_gpn.w.ready,
o_S_AXI_GP0_BRESP = axi_gpn.b.resp,
o_S_AXI_GP0_RRESP = axi_gpn.r.resp,
o_S_AXI_GP0_RDATA = axi_gpn.r.data,
o_S_AXI_GP0_BID = axi_gpn.b.id,
o_S_AXI_GP0_RID = axi_gpn.r.id,
i_S_AXI_GP0_ACLK = ClockSignal("sys"),
i_S_AXI_GP0_ARVALID = axi_gpn.ar.valid,
i_S_AXI_GP0_AWVALID = axi_gpn.aw.valid,
i_S_AXI_GP0_BREADY = axi_gpn.b.ready,
i_S_AXI_GP0_RREADY = axi_gpn.r.ready,
i_S_AXI_GP0_WLAST = axi_gpn.w.last,
i_S_AXI_GP0_WVALID = axi_gpn.w.valid,
i_S_AXI_GP0_ARBURST = axi_gpn.ar.burst,
i_S_AXI_GP0_ARLOCK = axi_gpn.ar.lock,
i_S_AXI_GP0_ARSIZE = axi_gpn.ar.size,
i_S_AXI_GP0_AWBURST = axi_gpn.aw.burst,
i_S_AXI_GP0_AWLOCK = axi_gpn.aw.lock,
i_S_AXI_GP0_AWSIZE = axi_gpn.aw.size,
i_S_AXI_GP0_ARPROT = axi_gpn.ar.prot,
i_S_AXI_GP0_AWPROT = axi_gpn.aw.prot,
i_S_AXI_GP0_ARADDR = ar_address,
i_S_AXI_GP0_AWADDR = aw_address,
i_S_AXI_GP0_WDATA = axi_gpn.w.data,
i_S_AXI_GP0_ARCACHE = axi_gpn.ar.cache,
i_S_AXI_GP0_ARLEN = axi_gpn.ar.len,
i_S_AXI_GP0_ARQOS = axi_gpn.ar.qos,
i_S_AXI_GP0_AWCACHE = axi_gpn.aw.cache,
i_S_AXI_GP0_AWLEN = axi_gpn.aw.len,
i_S_AXI_GP0_AWQOS = axi_gpn.aw.qos,
i_S_AXI_GP0_WSTRB = axi_gpn.w.strb,
i_S_AXI_GP0_ARID = axi_gpn.ar.id,
i_S_AXI_GP0_AWID = axi_gpn.aw.id,
i_S_AXI_GP0_WID = axi_gpn.w.id,
)
self.specials += ps7_axi_s_gp0
self.bus.add_slave(name="main_ram",slave=axi_gpn, region=SoCRegion(origin=0x4000_0000, size=0x2000_0000, mode="rwx"))
# Build -------------------------------------------------------------------------------------------- # Build --------------------------------------------------------------------------------------------
def main(): def main():
from litex.soc.integration.soc import LiteXSoCArgumentParser from litex.build.parser import LiteXArgumentParser
parser = LiteXSoCArgumentParser(description="LiteX SoC on Zybo Z7") parser = LiteXArgumentParser(description="LiteX SoC on Zybo Z7")
target_group = parser.add_argument_group(title="Target options") target_group = parser.add_argument_group(title="Target options")
target_group.add_argument("--build", action="store_true", help="Build design.") target_group.add_argument("--build", action="store_true", help="Build design.")
target_group.add_argument("--load", action="store_true", help="Load bitstream.") target_group.add_argument("--load", action="store_true", help="Load bitstream.")
target_group.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency.") target_group.add_argument("--sys-clk-freq", default=125e6, help="System clock frequency.")
target_group.add_argument("--variant", default="z7-10", help="Board variant (z7-10 or z7-20).") target_group.add_argument("--variant", default="z7-10", help="Board variant (z7-10 or z7-20).")
target_group.add_argument("--with-ps7", action="store_true", help="Add the PS as slave.") target_group.add_argument("--with-ps7", action="store_true", help="Add the PS7 as slave for soft CPUs.")
builder_args(parser) builder_args(parser)
soc_core_args(parser) soc_core_args(parser)
args = parser.parse_args() args = parser.parse_args()
soc = BaseSoC( soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)), sys_clk_freq = args.sys_clk_freq,
variant = args.variant, variant = args.variant,
with_ps7 = args.with_ps7, with_ps7 = args.with_ps7,
**soc_core_argdict(args) **soc_core_argdict(args)