From d4003b8cfafba4973792e97b5be3e32e0ff1ab15 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 28 Aug 2024 19:59:30 +0200 Subject: [PATCH 01/12] efinix add SCHMITT_TRIGGER support --- litex/build/efinix/efinity.py | 4 ++++ litex/build/efinix/platform.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/litex/build/efinix/efinity.py b/litex/build/efinix/efinity.py index 0f782ac6b..e668f8700 100644 --- a/litex/build/efinix/efinity.py +++ b/litex/build/efinix/efinity.py @@ -164,6 +164,10 @@ class EfinityToolchain(GenericToolchain): prop = "PULL_OPTION" val = c.misc + if c.misc == "SCHMITT_TRIGGER": + prop = "SCHMITT_TRIGGER" + val = "1" + if "DRIVE_STRENGTH" in c.misc: prop = "DRIVE_STRENGTH" val = c.misc.split("=")[1] diff --git a/litex/build/efinix/platform.py b/litex/build/efinix/platform.py index 9808369ef..4b5777aa9 100644 --- a/litex/build/efinix/platform.py +++ b/litex/build/efinix/platform.py @@ -109,6 +109,10 @@ class EfinixPlatform(GenericPlatform): prop = "PULL_OPTION" val = o.misc ret.append((prop, val)) + if o.misc == "SCHMITT_TRIGGER": + prop = "SCHMITT_TRIGGER" + val = "1" + ret.append((prop, val)) if "DRIVE_STRENGTH" in o.misc: prop = "DRIVE_STRENGTH" val = o.misc.split("=")[1] From cc3f13670a7ccbd7af491b3ffe764dc175e7acfc Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 28 Aug 2024 20:13:03 +0200 Subject: [PATCH 02/12] Merge pull request #2050 from Dolu1990/efinix_pll_ext_fix efinix: Fix PLL with external clock input ifacewriter --- litex/build/efinix/ifacewriter.py | 2 ++ litex/soc/cores/clock/efinix.py | 1 + 2 files changed, 3 insertions(+) diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index 95cd66c8a..b2ca619fd 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -295,6 +295,8 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) else: cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_src="{}", refclk_name="{}", ext_refclk_no="{}")\n\n' \ .format(name, block["resource"], block["input_clock"], block["input_clock_name"], block["clock_no"]) + for p, val in block["input_properties"]: + cmd += 'design.set_property("{}","{}","{}")\n'.format(block["input_clock_name"], p, val) else: cmd += 'design.gen_pll_ref_clock("{}", pll_res="{}", refclk_name="{}", refclk_src="CORE")\n'.format(name, block["resource"], block["input_signal"]) cmd += 'design.set_property("{}", "CORE_CLK_PIN", "{}", block_type="PLL")\n\n'.format(name, block["input_signal"]) diff --git a/litex/soc/cores/clock/efinix.py b/litex/soc/cores/clock/efinix.py index ba2a9e70d..0ca5ebf6e 100644 --- a/litex/soc/cores/clock/efinix.py +++ b/litex/soc/cores/clock/efinix.py @@ -85,6 +85,7 @@ class EFINIXPLL(LiteXModule): block["input_refclk_name"] = refclk_name block["resource"] = pll_res block["clock_no"] = clock_no + block["input_properties"] = self.platform.get_pin_properties(clkin) self.logger.info("Clock source: {}, using EXT_CLK{}".format(block["input_clock"], clock_no)) self.platform.get_pll_resource(pll_res) else: From 5fb873d209559f94327f23df61cb4f4114e52aa8 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 30 Aug 2024 10:44:10 +0200 Subject: [PATCH 03/12] efinix: Add support for more IO --- litex/build/efinix/common.py | 135 +++++++++++++++++++++++++----- litex/build/efinix/ifacewriter.py | 3 + 2 files changed, 119 insertions(+), 19 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index c52db5ee9..d887249e0 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -139,24 +139,7 @@ class EfinixTristate(Module): def lower(dr): return EfinixTristateImpl(dr.platform, dr.target, dr.o, dr.oe, dr.i) -# Efinix SDRTristate ------------------------------------------------------------------------------- -class EfinixSDRTristateImpl(Module): - def __init__(self, platform, io, o, oe, i, clk): - _o = Signal() - _oe = Signal() - _i = Signal() - self.specials += SDROutput(o, _o, clk) - self.specials += SDRInput(_i, i, clk) - self.submodules += InferedSDRIO(oe, _oe, clk) - tristate = Tristate(io, _o, _oe, _i) - tristate.platform = platform - self.specials += tristate - -class EfinixSDRTristate(Module): - @staticmethod - def lower(dr): - return EfinixSDRTristateImpl(dr.platform, dr.io, dr.o, dr.oe, dr.i, dr.clk) # Efinix DifferentialOutput ------------------------------------------------------------------------ @@ -261,6 +244,119 @@ class EfinixDifferentialInput: def lower(dr): return EfinixDifferentialInputImpl(dr.platform, dr.i_p, dr.i_n, dr.o) + + + + +# Efinix DDRTristate --------------------------------------------------------------------------------- + +class EfinixDDRTristateImpl(Module): + def __init__(self, platform, io, o1, o2, oe1, oe2, i1, i2, clk): + assert oe1 == oe2 + io_name = platform.get_pin_name(io) + io_pad = platform.get_pin_location(io) + io_prop = platform.get_pin_properties(io) + io_data_i_h = platform.add_iface_io(io_name + "_OUT_HI") + io_data_i_l = platform.add_iface_io(io_name + "_OUT_LO") + io_data_o_h = platform.add_iface_io(io_name + "_IN_HI") + io_data_o_l = platform.add_iface_io(io_name + "_IN_LO") + io_data_e = platform.add_iface_io(io_name + "_OE") + self.comb += io_data_i_h.eq(o1) + self.comb += io_data_i_l.eq(o2) + self.comb += io_data_e.eq(oe1) + self.comb += i1.eq(io_data_o_h) + self.comb += i2.eq(io_data_o_l) + block = { + "type" : "GPIO", + "mode" : "INOUT", + "name" : io_name, + "location" : io_pad, + "properties" : io_prop, + "size" : 1, + "in_reg" : "DDIO_RESYNC", + "in_clk_pin" : clk.name_override, # FIXME. + "out_reg" : "DDIO_RESYNC", + "out_clk_pin" : clk.name_override, # FIXME. + "oe_reg" : "REG", + "is_inclk_inverted" : False, + "drive_strength" : 4 # FIXME: Get it from constraints. + } + platform.toolchain.ifacewriter.blocks.append(block) + platform.toolchain.excluded_ios.append(platform.get_pin(io)) + +class EfinixDDRTristate: + @staticmethod + def lower(dr): + return EfinixDDRTristateImpl(dr.platform, dr.io, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.i1, dr.i2, dr.clk) + +# Efinix SDRTristate ------------------------------------------------------------------------------- + +class EfinixSDRTristateImpl(EfinixDDRTristateImpl): + def __init__(self, platform, io, o, oe, i, clk): + io_name = platform.get_pin_name(io) + io_pad = platform.get_pin_location(io) + io_prop = platform.get_pin_properties(io) + io_data_i = platform.add_iface_io(io_name + "_OUT") + io_data_o = platform.add_iface_io(io_name + "_IN") + io_data_e = platform.add_iface_io(io_name + "_OE") + self.comb += io_data_i.eq(o) + self.comb += io_data_e.eq(oe) + self.comb += i.eq(io_data_o) + block = { + "type" : "GPIO", + "mode" : "INOUT", + "name" : io_name, + "location" : io_pad, + "properties" : io_prop, + "size" : 1, + "in_reg" : "REG", + "in_clk_pin" : clk.name_override, # FIXME. + "out_reg" : "REG", + "out_clk_pin" : clk.name_override, # FIXME. + "oe_reg" : "REG", + "is_inclk_inverted" : False, + "drive_strength" : 4 # FIXME: Get it from constraints. + } + platform.toolchain.ifacewriter.blocks.append(block) + platform.toolchain.excluded_ios.append(platform.get_pin(io)) + + +class EfinixSDRTristate(Module): + @staticmethod + def lower(dr): + return EfinixSDRTristateImpl(dr.platform, dr.io, dr.o, dr.oe, dr.i, dr.clk) + +# Efinix SDROutput ------------------------------------------------------------------------------- + +class EfinixSDROutputImpl(Module): + def __init__(self, platform, i, o, clk): + io_name = platform.get_pin_name(o) + io_pad = platform.get_pin_location(o) + io_prop = platform.get_pin_properties(o) + io_data_i = platform.add_iface_io(io_name) + self.comb += io_data_i.eq(i) + block = { + "type" : "GPIO", + "mode" : "OUTPUT", + "name" : io_name, + "location" : io_pad, + "properties" : io_prop, + "size" : 1, + "out_reg" : "REG", + "out_clk_pin" : clk.name_override, # FIXME. + "is_inclk_inverted" : False, + "drive_strength" : 4 # FIXME: Get it from constraints. + } + platform.toolchain.ifacewriter.blocks.append(block) + platform.toolchain.excluded_ios.append(platform.get_pin(o)) + + +class EfinixSDROutput(Module): + @staticmethod + def lower(dr): + return EfinixSDROutputImpl(dr.platform, dr.i, dr.o, dr.clk) + + # Efinix DDROutput --------------------------------------------------------------------------------- class EfinixDDROutputImpl(Module): @@ -280,7 +376,7 @@ class EfinixDDROutputImpl(Module): "properties" : io_prop, "size" : 1, "out_reg" : "DDIO_RESYNC", - "out_clk_pin" : clk, # FIXME. + "out_clk_pin" : clk.name_override, # FIXME. "is_inclk_inverted" : False, "drive_strength" : 4 # FIXME: Get it from constraints. } @@ -311,7 +407,7 @@ class EfinixDDRInputImpl(Module): "properties" : io_prop, "size" : 1, "in_reg" : "DDIO_RESYNC", - "in_clk_pin" : clk, # FIXME. + "in_clk_pin" : clk.name_override, # FIXME. "is_inclk_inverted" : False } platform.toolchain.ifacewriter.blocks.append(block) @@ -331,6 +427,7 @@ efinix_special_overrides = { Tristate : EfinixTristate, DifferentialOutput : EfinixDifferentialOutput, DifferentialInput : EfinixDifferentialInput, + SDROutput : EfinixSDROutput, SDRTristate : EfinixSDRTristate, DDROutput : EfinixDDROutput, DDRInput : EfinixDDRInput, diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index b2ca619fd..5b261d5d4 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -166,6 +166,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) cmd += f'design.assign_pkg_pin("{name}[{i}]","{pad}")\n' if "out_reg" in block: + cmd += f'design.set_property("{name}","oe_REG","{block["out_reg"]}")\n' + + if "oe_reg" in block: cmd += f'design.set_property("{name}","OUT_REG","{block["out_reg"]}")\n' cmd += f'design.set_property("{name}","OUT_CLK_PIN","{block["out_clk_pin"]}")\n' if "out_delay" in block: From c14f1d081631e4a39c1b5cdacc69dbe04441a517 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 30 Aug 2024 10:44:36 +0200 Subject: [PATCH 04/12] vexiiriscv add video support --- litex/soc/cores/cpu/vexiiriscv/core.py | 47 ++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/cpu/vexiiriscv/core.py b/litex/soc/cores/cpu/vexiiriscv/core.py index 27593d7e3..b4fe04346 100755 --- a/litex/soc/cores/cpu/vexiiriscv/core.py +++ b/litex/soc/cores/cpu/vexiiriscv/core.py @@ -59,6 +59,7 @@ class VexiiRiscv(CPU): with_axi3 = False jtag_tap = False jtag_instruction = False + vexii_video = [] vexii_args = "" @@ -137,6 +138,7 @@ class VexiiRiscv(CPU): cpu_group.add_argument("--l2-ways", default=0, help="VexiiRiscv L2 ways, default 8.") cpu_group.add_argument("--l2-self-flush", default=None, help="VexiiRiscv L2 ways will self flush on from,to,cycles") cpu_group.add_argument("--with-axi3", action="store_true", help="mbus will be axi3 instead of axi4") + cpu_group.add_argument("--vexii-video", action="append", default=[], help="Add the memory coherent video controller") @@ -200,6 +202,7 @@ class VexiiRiscv(CPU): VexiiRiscv.l2_ways = args.l2_ways if args.l2_self_flush: VexiiRiscv.l2_self_flush = args.l2_self_flush + VexiiRiscv.vexii_video = args.vexii_video def __init__(self, platform, variant): @@ -306,6 +309,31 @@ class VexiiRiscv(CPU): o_dma_bus_rlast = dma_bus.r.last, ) + for video in VexiiRiscv.vexii_video: + args = {} + for i, val in enumerate(video.split(",")): + name, value = val.split("=") + args.update({name: value}) + name = args["name"] + clk = Signal() + hsync = Signal() + vsync = Signal() + color_en = Signal() + color = Signal(16) + setattr(self, name + "_clk", clk) + setattr(self, name + "_hsync", hsync) + setattr(self, name + "_vsync", vsync) + setattr(self, name + "_color_en", color_en) + setattr(self, name + "_color", color) + self.cpu_params["o_" + name + "_clk"] = clk + self.cpu_params["o_" + name + "_hSync"] = hsync + self.cpu_params["o_" + name + "_vSync"] = vsync + self.cpu_params["o_" + name + "_colorEn"] = color_en + self.cpu_params["o_" + name + "_color"] = color + + + + def set_reset_address(self, reset_address): VexiiRiscv.reset_address = reset_address VexiiRiscv.vexii_args += f" --reset-vector {reset_address}" @@ -327,6 +355,8 @@ class VexiiRiscv(CPU): md5_hash.update(str(VexiiRiscv.with_axi3).encode('utf-8')) md5_hash.update(str(VexiiRiscv.memory_regions).encode('utf-8')) md5_hash.update(str(VexiiRiscv.vexii_args).encode('utf-8')) + md5_hash.update(str(VexiiRiscv.vexii_video).encode('utf-8')) + # md5_hash.update(str(VexiiRiscv.internal_bus_width).encode('utf-8')) @@ -361,6 +391,9 @@ class VexiiRiscv(CPU): gen_args.append(f"--with-dma") if(VexiiRiscv.with_axi3) : gen_args.append(f"--with-axi3") + for arg in VexiiRiscv.vexii_video: + gen_args.append(f"--video {arg}") + cmd = f"""cd {ndir} && sbt "runMain vexiiriscv.soc.litex.SocGen {" ".join(gen_args)}\"""" print("VexiiRiscv generation command :") @@ -469,7 +502,12 @@ class VexiiRiscv(CPU): if soc.get_build_name() == "sim": self.comb += If(debug_ndmreset_rise, soc.crg.cd_sys.rst.eq(1)) else: - self.comb += If(debug_ndmreset_rise, soc.crg.rst.eq(1)) + if hasattr(soc.crg, "rst"): + self.comb += If(debug_ndmreset_rise, soc.crg.rst.eq(1)) + elif hasattr(soc.crg.pll, "reset"): + self.comb += If(debug_ndmreset_rise, soc.crg.pll.reset.eq(1)) + else: + raise Exception("Pll has no reset ?") self.soc_bus = soc.bus # FIXME: Save SoC Bus instance to retrieve the final mem layout on finalization. @@ -482,6 +520,7 @@ class VexiiRiscv(CPU): id_width = 8, version = "axi3" if VexiiRiscv.with_axi3 else "axi4" ) + self.mBus_awallStrb = Signal() self.memory_buses.append(mbus) self.comb += mbus.aw.cache.eq(0xF) @@ -507,7 +546,7 @@ class VexiiRiscv(CPU): o_mBus_awlen = mbus.aw.len, o_mBus_awsize = mbus.aw.size, o_mBus_awburst = mbus.aw.burst, - o_mBus_awallStrb = Open(), + o_mBus_awallStrb = self.mBus_awallStrb, # W Channel. o_mBus_wvalid = mbus.w.valid, i_mBus_wready = mbus.w.ready, @@ -573,6 +612,10 @@ class VexiiRiscv(CPU): mode += "c" if region.cached else "" VexiiRiscv.memory_regions.append( (region.origin, region.size, mode, bus) ) + from litex.build.efinix import EfinixPlatform + if isinstance(self.platform, EfinixPlatform): + VexiiRiscv.vexii_args = "--mmu-sync-read " + VexiiRiscv.vexii_args + self.generate_netlist_name() # Do verilog instance. From 2f2b292e06fd1ac15f581e6d284528dd5c32fa2f Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 30 Aug 2024 18:16:56 +0200 Subject: [PATCH 05/12] vexii add with-cpu-clk --- litex/soc/cores/cpu/vexiiriscv/core.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/cpu/vexiiriscv/core.py b/litex/soc/cores/cpu/vexiiriscv/core.py index b4fe04346..c518ae24f 100755 --- a/litex/soc/cores/cpu/vexiiriscv/core.py +++ b/litex/soc/cores/cpu/vexiiriscv/core.py @@ -59,6 +59,7 @@ class VexiiRiscv(CPU): with_axi3 = False jtag_tap = False jtag_instruction = False + with_cpu_clk = False vexii_video = [] vexii_args = "" @@ -132,6 +133,7 @@ class VexiiRiscv(CPU): cpu_group.add_argument("--with-jtag-instruction", action="store_true", help="Add a JTAG instruction port which implement tunneling for debugging (TAP not included).") cpu_group.add_argument("--update-repo", default="recommended", choices=["latest","wipe+latest","recommended","wipe+recommended","no"], help="Specify how the VexiiRiscv & SpinalHDL repo should be updated (latest: update to HEAD, recommended: Update to known compatible version, no: Don't update, wipe+*: Do clean&reset before checkout)") cpu_group.add_argument("--no-netlist-cache", action="store_true", help="Always (re-)build the netlist.") + cpu_group.add_argument("--with-cpu-clk", action="store_true", help="The CPUs will use a decoupled clock") # cpu_group.add_argument("--with-fpu", action="store_true", help="Enable the F32/F64 FPU.") # cpu_group.add_argument("--with-rvc", action="store_true", help="Enable the Compress ISA extension.") cpu_group.add_argument("--l2-bytes", default=0, help="VexiiRiscv L2 bytes, default 128 KB.") @@ -198,6 +200,7 @@ class VexiiRiscv(CPU): VexiiRiscv.cpu_count = args.cpu_count if args.l2_bytes: VexiiRiscv.l2_bytes = args.l2_bytes + VexiiRiscv.with_cpu_clk = args.with_cpu_clk if args.l2_ways: VexiiRiscv.l2_ways = args.l2_ways if args.l2_self_flush: @@ -223,8 +226,8 @@ class VexiiRiscv(CPU): # CPU Instance. self.cpu_params = dict( # Clk/Rst. - i_system_clk = ClockSignal("sys"), - i_system_reset = ResetSignal("sys") | self.reset, + i_litex_clk = ClockSignal("sys"), + i_litex_reset = ResetSignal("sys") | self.reset, # Patcher/Tracer. # o_patcher_tracer_valid = self.tracer_valid, @@ -255,6 +258,12 @@ class VexiiRiscv(CPU): i_pBus_rresp = pbus.r.resp, ) + if VexiiRiscv.with_cpu_clk: + self.cpu_clk = Signal() + self.cpu_params.update( + i_cpu_clk = self.cpu_clk + ) + if VexiiRiscv.with_dma: self.dma_bus = dma_bus = axi.AXIInterface(data_width=VexiiRiscv.internal_bus_width, address_width=32, id_width=4) @@ -347,6 +356,7 @@ class VexiiRiscv(CPU): md5_hash.update(str(VexiiRiscv.xlen).encode('utf-8')) md5_hash.update(str(VexiiRiscv.cpu_count).encode('utf-8')) md5_hash.update(str(VexiiRiscv.l2_bytes).encode('utf-8')) + md5_hash.update(str(VexiiRiscv.with_cpu_clk).encode('utf-8')) md5_hash.update(str(VexiiRiscv.l2_ways).encode('utf-8')) md5_hash.update(str(VexiiRiscv.l2_self_flush).encode('utf-8')) md5_hash.update(str(VexiiRiscv.jtag_tap).encode('utf-8')) @@ -376,6 +386,8 @@ class VexiiRiscv(CPU): gen_args.append(VexiiRiscv.vexii_args) gen_args.append(f"--cpu-count={VexiiRiscv.cpu_count}") gen_args.append(f"--l2-bytes={VexiiRiscv.l2_bytes}") + if VexiiRiscv.with_cpu_clk: + gen_args.append("--with-cpu-clk") gen_args.append(f"--l2-ways={VexiiRiscv.l2_ways}") if VexiiRiscv.l2_self_flush: gen_args.append(f"--l2-self-flush={VexiiRiscv.l2_self_flush}") From e01ce6f948e4f545e840901c726e0cee4e563045 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 3 Sep 2024 07:55:25 +0200 Subject: [PATCH 06/12] efinix: ifacewriter support drive strength and slew --- litex/build/efinix/ifacewriter.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/litex/build/efinix/ifacewriter.py b/litex/build/efinix/ifacewriter.py index 5b261d5d4..4993011e0 100644 --- a/litex/build/efinix/ifacewriter.py +++ b/litex/build/efinix/ifacewriter.py @@ -192,6 +192,11 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) if "oe_clk_pin" in block: cmd += f'design.set_property("{name}","OE_CLK_PIN","{block["oe_clk_pin"]}")\n' + if "drive_strength" in block: + cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"]) + if "slewrate" in block: + cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"]) + if prop: for p, val in prop: cmd += 'design.set_property("{}","{}","{}")\n'.format(name, p, val) @@ -237,7 +242,9 @@ design.create("{2}", "{3}", "./../gateware", overwrite=True) cmd += f'design.set_property("{name}","OE_CLK_PIN_INV","{block["out_clk_inv"]}")\n' if "drive_strength" in block: - cmd += 'design.set_property("{}","DRIVE_STRENGTH","4")\n'.format(name, block["drive_strength"]) + cmd += 'design.set_property("{}","DRIVE_STRENGTH","{}")\n'.format(name, block["drive_strength"]) + if "slewrate" in block: + cmd += 'design.set_property("{}","SLEWRATE","{}")\n'.format(name, block["slewrate"]) if prop: for p, val in prop: From 19b3f24d9fcdce34422bb420ceb16dcc1bc04874 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 3 Sep 2024 07:57:30 +0200 Subject: [PATCH 07/12] efinix: ifacewriter support drive strength and slew --- litex/build/efinix/common.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/litex/build/efinix/common.py b/litex/build/efinix/common.py index d887249e0..dbcfc66fd 100644 --- a/litex/build/efinix/common.py +++ b/litex/build/efinix/common.py @@ -256,6 +256,7 @@ class EfinixDDRTristateImpl(Module): io_name = platform.get_pin_name(io) io_pad = platform.get_pin_location(io) io_prop = platform.get_pin_properties(io) + io_prop_dict = dict(io_prop) io_data_i_h = platform.add_iface_io(io_name + "_OUT_HI") io_data_i_l = platform.add_iface_io(io_name + "_OUT_LO") io_data_o_h = platform.add_iface_io(io_name + "_IN_HI") @@ -279,7 +280,7 @@ class EfinixDDRTristateImpl(Module): "out_clk_pin" : clk.name_override, # FIXME. "oe_reg" : "REG", "is_inclk_inverted" : False, - "drive_strength" : 4 # FIXME: Get it from constraints. + "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(io)) @@ -296,6 +297,7 @@ class EfinixSDRTristateImpl(EfinixDDRTristateImpl): io_name = platform.get_pin_name(io) io_pad = platform.get_pin_location(io) io_prop = platform.get_pin_properties(io) + io_prop_dict = dict(io_prop) io_data_i = platform.add_iface_io(io_name + "_OUT") io_data_o = platform.add_iface_io(io_name + "_IN") io_data_e = platform.add_iface_io(io_name + "_OE") @@ -315,7 +317,7 @@ class EfinixSDRTristateImpl(EfinixDDRTristateImpl): "out_clk_pin" : clk.name_override, # FIXME. "oe_reg" : "REG", "is_inclk_inverted" : False, - "drive_strength" : 4 # FIXME: Get it from constraints. + "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(io)) @@ -333,6 +335,7 @@ class EfinixSDROutputImpl(Module): io_name = platform.get_pin_name(o) io_pad = platform.get_pin_location(o) io_prop = platform.get_pin_properties(o) + io_prop_dict = dict(io_prop) io_data_i = platform.add_iface_io(io_name) self.comb += io_data_i.eq(i) block = { @@ -345,7 +348,7 @@ class EfinixSDROutputImpl(Module): "out_reg" : "REG", "out_clk_pin" : clk.name_override, # FIXME. "is_inclk_inverted" : False, - "drive_strength" : 4 # FIXME: Get it from constraints. + "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(o)) @@ -364,6 +367,7 @@ class EfinixDDROutputImpl(Module): io_name = platform.get_pin_name(o) io_pad = platform.get_pin_location(o) io_prop = platform.get_pin_properties(o) + io_prop_dict = dict(io_prop) io_data_h = platform.add_iface_io(io_name + "_HI") io_data_l = platform.add_iface_io(io_name + "_LO") self.comb += io_data_h.eq(i1) @@ -378,7 +382,7 @@ class EfinixDDROutputImpl(Module): "out_reg" : "DDIO_RESYNC", "out_clk_pin" : clk.name_override, # FIXME. "is_inclk_inverted" : False, - "drive_strength" : 4 # FIXME: Get it from constraints. + "drive_strength" : io_prop_dict.get("DRIVE_STRENGTH", "4") } platform.toolchain.ifacewriter.blocks.append(block) platform.toolchain.excluded_ios.append(platform.get_pin(o)) From 3de5832b9c682add293804459908f1e1f3a92a0f Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 3 Sep 2024 07:58:24 +0200 Subject: [PATCH 08/12] vexiiriscv: Now use pll.locked for debug reset --- litex/soc/cores/cpu/vexiiriscv/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex/soc/cores/cpu/vexiiriscv/core.py b/litex/soc/cores/cpu/vexiiriscv/core.py index c518ae24f..6bbd42241 100755 --- a/litex/soc/cores/cpu/vexiiriscv/core.py +++ b/litex/soc/cores/cpu/vexiiriscv/core.py @@ -514,10 +514,10 @@ class VexiiRiscv(CPU): if soc.get_build_name() == "sim": self.comb += If(debug_ndmreset_rise, soc.crg.cd_sys.rst.eq(1)) else: - if hasattr(soc.crg, "rst"): + if hasattr(soc.crg.pll, "locked"): + self.comb += If(debug_ndmreset, soc.crg.pll.locked.eq(0)) + elif hasattr(soc.crg, "rst"): self.comb += If(debug_ndmreset_rise, soc.crg.rst.eq(1)) - elif hasattr(soc.crg.pll, "reset"): - self.comb += If(debug_ndmreset_rise, soc.crg.pll.reset.eq(1)) else: raise Exception("Pll has no reset ?") From a90ab9dcca26e0dc97e030262d31d232947f742d Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 3 Sep 2024 12:05:26 +0200 Subject: [PATCH 09/12] efinix: Merge pt.sdc to the litex sdc to get constraints right --- litex/build/efinix/efinity.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/litex/build/efinix/efinity.py b/litex/build/efinix/efinity.py index e668f8700..01ebb6ac2 100644 --- a/litex/build/efinix/efinity.py +++ b/litex/build/efinix/efinity.py @@ -271,7 +271,7 @@ class EfinityToolchain(GenericToolchain): # Add Timing Constraints. constraint_info = et.SubElement(root, "efx:constraint_info") - et.SubElement(constraint_info, "efx:sdc_file", name=f"{self._build_name}.sdc") + et.SubElement(constraint_info, "efx:sdc_file", name=f"{self._build_name}_merged.sdc") # Add Misc Info. misc_info = et.SubElement(root, "efx:misc_info") @@ -306,6 +306,26 @@ class EfinityToolchain(GenericToolchain): return "" # not used def run_script(self, script): + # Place and Route. + r = tools.subprocess_call_filtered([self.efinity_path + "/bin/python3", + self.efinity_path + "/scripts/efx_run_pt.py", + f"{self._build_name}", + self.platform.family, + self.platform.device + ], common.colors) + if r != 0: + raise OSError("Error occurred during efx_run_pt execution.") + + # Merge SDC + with open(f"{self._build_name}_merged.sdc", 'w') as outfile: + with open(f"outflow/{self._build_name}.pt.sdc") as infile: + outfile.write(infile.read()) + outfile.write("\n") + outfile.write("#########################\n") + outfile.write("\n") + with open(f"{self._build_name}.sdc") as infile: + outfile.write(infile.read()) + # Synthesis/Mapping. r = tools.subprocess_call_filtered([self.efinity_path + "/bin/efx_map", "--project", f"{self._build_name}", @@ -336,15 +356,7 @@ class EfinityToolchain(GenericToolchain): if r != 0: raise OSError("Error occurred during efx_map execution.") - # Place and Route. - r = tools.subprocess_call_filtered([self.efinity_path + "/bin/python3", - self.efinity_path + "/scripts/efx_run_pt.py", - f"{self._build_name}", - self.platform.family, - self.platform.device - ], common.colors) - if r != 0: - raise OSError("Error occurred during efx_run_pt execution.") + r = tools.subprocess_call_filtered([self.efinity_path + "/bin/efx_pnr", "--circuit", f"{self._build_name}", @@ -358,7 +370,7 @@ class EfinityToolchain(GenericToolchain): "--use_vdb_file", "on", "--place_file", f"outflow/{self._build_name}.place", "--route_file", f"outflow/{self._build_name}.route", - "--sdc_file", f"{self._build_name}.sdc", + "--sdc_file", f"{self._build_name}_merged.sdc", "--sync_file", f"outflow/{self._build_name}.interface.csv", "--seed", "1", "--work_dir", "work_pnr", From 84e7e816c77359a667ffa62c64bf59099845b282 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 5 Sep 2024 10:16:43 +0200 Subject: [PATCH 10/12] efinix: pll now force the generated clock into cd.clk *WARNING* --- litex/soc/cores/clock/efinix.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/clock/efinix.py b/litex/soc/cores/clock/efinix.py index 0ca5ebf6e..04a012f88 100644 --- a/litex/soc/cores/clock/efinix.py +++ b/litex/soc/cores/clock/efinix.py @@ -107,11 +107,15 @@ class EFINIXPLL(LiteXModule): clk_out_name = f"{self.name}_clkout{self.nclkouts}" if name == "" else name if cd is not None: - self.platform.add_extension([(clk_out_name, 0, Pins(1))]) clk_name = f"{cd.name}_clk" + clk_out_name = clk_name # To unify constraints names + self.platform.add_extension([(clk_out_name, 0, Pins(1))]) clk_out = self.platform.request(clk_out_name) self.comb += cd.clk.eq(clk_out) - self.platform.add_period_constraint(clk=clk_out, period=1e9/freq, name=clk_name) + # Efinity will generate xxx.pt.sdc constraints automaticaly, + # so, the user realy need to use the toplevel pin from the pll instead of an intermediate signal + # This is a dirty workaround. But i don't have any better + cd.clk = clk_out if with_reset: self.specials += AsyncResetSynchronizer(cd, ~self.locked) self.platform.toolchain.excluded_ios.append(clk_out_name) From 1f2418de3bf13f87c8cd1dd77edf174082830198 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 5 Sep 2024 10:17:22 +0200 Subject: [PATCH 11/12] core/usb_ohci: fix SDRTristate clock --- litex/soc/cores/usb_ohci.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litex/soc/cores/usb_ohci.py b/litex/soc/cores/usb_ohci.py index 264eac726..179316b88 100644 --- a/litex/soc/cores/usb_ohci.py +++ b/litex/soc/cores/usb_ohci.py @@ -95,12 +95,14 @@ class USBOHCI(LiteXModule): o = usb_ios[i].dp_o, oe = usb_ios[i].dp_oe, i = usb_ios[i].dp_i, + clk = ClockSignal("usb") ) self.specials += SDRTristate( io = pads.dm[i], o = usb_ios[i].dm_o, oe = usb_ios[i].dm_oe, i = usb_ios[i].dm_i, + clk = ClockSignal("usb") ) self.add_sources(platform) From f512c6507714461d0ff0989e82d6f1c3b792136a Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 5 Sep 2024 13:17:22 +0200 Subject: [PATCH 12/12] vexiiriscv git update --- litex/soc/cores/cpu/vexiiriscv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/cpu/vexiiriscv/core.py b/litex/soc/cores/cpu/vexiiriscv/core.py index 6bbd42241..acab027f5 100755 --- a/litex/soc/cores/cpu/vexiiriscv/core.py +++ b/litex/soc/cores/cpu/vexiiriscv/core.py @@ -152,7 +152,7 @@ class VexiiRiscv(CPU): vdir = get_data_mod("cpu", "vexiiriscv").data_location ndir = os.path.join(vdir, "ext", "VexiiRiscv") - NaxRiscv.git_setup("VexiiRiscv", ndir, "https://github.com/SpinalHDL/VexiiRiscv.git", "dev", "36dad634", args.update_repo) + NaxRiscv.git_setup("VexiiRiscv", ndir, "https://github.com/SpinalHDL/VexiiRiscv.git", "dev", "a15ea92c", args.update_repo) if not args.cpu_variant: args.cpu_variant = "standard"