add fast-servo linien gateware

This commit is contained in:
Florian Agbuya 2024-02-23 18:42:11 +08:00 committed by sb10q
parent e12b672cdc
commit 506bbcc0db
4 changed files with 761 additions and 8 deletions

View File

@ -0,0 +1,38 @@
# diff from elhep/Fast-Servo-Firmmware commit ID 7fae40c:
# https://github.com/elhep/Fast-Servo-Firmware/commit/7fae40c0f872a91218be378f8289b98b1e366729
# Fix for migen add_source deprecation and removed xilinx bootgen command
# .bin file is being generated by bit2bin.py from Linien repository
# https://github.com/linien-org/linien/blob/master/gateware/bit2bin.py
diff --git a/fast_servo/gateware/fast_servo_platform.py b/fast_servo/gateware/fast_servo_platform.py
index 13b4aa3..89a8103 100644
--- a/fast_servo/gateware/fast_servo_platform.py
+++ b/fast_servo/gateware/fast_servo_platform.py
@@ -324,7 +324,12 @@ class Platform(XilinxPlatform):
self.ps7_config = ps7_config
verilog_sources = os.listdir(verilog_dir)
- self.add_sources(verilog_dir, *verilog_sources)
+ self.add_source_dir(verilog_dir)
+
+ def build(self, *args, **kwargs):
+ build_dir = kwargs.get('build_dir', 'build')
+ self.copy_sources(build_dir)
+ super().build(*args, **kwargs)
def do_finalize(self, fragment):
try:
diff --git a/fast_servo/gateware/fast_servo_soc.py b/fast_servo/gateware/fast_servo_soc.py
index 02128f5..abfc583 100644
--- a/fast_servo/gateware/fast_servo_soc.py
+++ b/fast_servo/gateware/fast_servo_soc.py
@@ -282,9 +282,3 @@ if __name__ == "__main__":
os.chdir(os.path.join(root_path, build_dir))
with open(f"{build_name}.bif", "w") as f:
f.write(f"all:\n{{\n\t{build_name}.bit\n}}")
-
- cmd = f"bootgen -image {build_name}.bif -arch zynq -process_bitstream bin -w on".split(" ")
- subprocess.run(cmd)
-
-
-

View File

@ -0,0 +1,603 @@
# diff between linen-org/linien commit ID 93f1f50:
# https://github.com/linien-org/linien/commit/93f1f50ebd86fe3314cab5a549462d0fcbf6a658
# and elhep/linien commit ID b73eea0:
# https://github.com/elhep/linien/commit/b73eea07889dda8b55f0cf4c2afde96cf4c3efd1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b3f3683..98c6e51 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,7 +3,7 @@ repos:
rev: 23.11.0
hooks:
- id: black
- exclude: ^(gateware/logic/|gateware/lowlevel/|gateware/linien_module.py|linien-server/linien_server/csrmap.py)
+ exclude: ^(gateware/logic/|gateware/lowlevel/|gateware/linien_module.py|linien-server/linien_server/csrmap.py|gateware/targets)
- repo: https://github.com/pycqa/isort
rev: 5.12.0
diff --git a/gateware/build_fpga_image.sh b/gateware/build_fpga_image.sh
index f822402..be7401c 100644
--- a/gateware/build_fpga_image.sh
+++ b/gateware/build_fpga_image.sh
@@ -16,4 +16,9 @@ export PATH=$VIVADOPATH:$PATH
rm linien-server/linien_server/gateware.bin -f
# run with -m option to avoid errors related to relative imports without breaking pytest
-python3 -m gateware.fpga_image_helper
\ No newline at end of file
+
+if [ -z "$1" ]; then
+ python3 -m gateware.fpga_image_helper
+else
+ python3 -m gateware.fpga_image_helper -p $1
+fi
\ No newline at end of file
diff --git a/gateware/fpga_image_helper.py b/gateware/fpga_image_helper.py
index 6c34429..a0b12d0 100644
--- a/gateware/fpga_image_helper.py
+++ b/gateware/fpga_image_helper.py
@@ -1,5 +1,6 @@
# Copyright 2014-2015 Robert Jördens <jordens@gmail.com>
# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
#
# This file is part of Linien and based on redpid.
#
@@ -23,14 +24,16 @@ from pathlib import Path
REPO_ROOT_DIR = Path(__file__).resolve().parents[1]
from .bit2bin import bit2bin
-from .hw_platform import Platform
-from .linien_module import RootModule
def py_csrconstants(map, fil):
fil.write("csr_constants = {\n")
- for k, v in root.linien.csrbanks.constants:
- fil.write(" '{}_{}': {},\n".format(k, v.name, v.value.value))
+ for k, v in root.csrbanks.constants:
+ if k == "linien":
+ # compaitbility layer
+ fil.write(" '{}': {},\n".format(v.name, v.value.value))
+ else:
+ fil.write(" '{}_{}': {},\n".format(k, v.name, v.value.value))
fil.write("}\n\n")
@@ -52,26 +55,49 @@ def get_csrmap(banks):
def py_csrmap(it, fil):
fil.write("csr = {\n")
for reg in it:
- fil.write(" '{}_{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg))
+ main_name = reg[0]
+ secondary_name = reg[1]
+ # compaitbility layer
+ if main_name == "linien" or secondary_name.startswith(main_name):
+ fil.write(" '{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg[1:]))
+ else:
+ fil.write(" '{}_{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg))
fil.write("}\n")
if __name__ == "__main__":
- platform = Platform()
- root = RootModule(platform)
+ import argparse
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-p", "--platform", default=None)
+ args = parser.parse_args()
+ if args.platform is None or args.platform.lower() == "redpitaya":
+ from gateware.hw_platform import Platform
+ from gateware.targets.red_pitaya import PitayaSoC
+
+ platform = Platform()
+ root = PitayaSoC(platform)
+ elif args.platform.lower() == "fastservo":
+ from fast_servo.gateware.fast_servo_platform import Platform
+
+ from gateware.targets.fast_servo import LinienFastServo
+
+ platform = Platform()
+ root = LinienFastServo(platform)
+ else:
+ raise ValueError("Unknown platform")
+
+ platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
+ build_dir = REPO_ROOT_DIR / "gateware" / "build"
+ platform.build(root, build_name="top", build_dir=build_dir, run=True)
with open(
REPO_ROOT_DIR / "linien-server" / "linien_server" / "csrmap.py", "w"
) as fil:
- py_csrconstants(root.linien.csrbanks.constants, fil)
- csr = get_csrmap(root.linien.csrbanks.banks)
+ py_csrconstants(root.csrbanks.constants, fil)
+ csr = get_csrmap([*root.csrbanks.banks, *root.linien.csrbanks.banks])
py_csrmap(csr, fil)
fil.write("states = {}\n".format(repr(root.linien.state_names)))
fil.write("signals = {}\n".format(repr(root.linien.signal_names)))
-
- platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
- build_dir = REPO_ROOT_DIR / "gateware" / "build"
- platform.build(root, build_name="top", build_dir=build_dir)
bit2bin(
build_dir / "top.bit",
REPO_ROOT_DIR / "linien-server" / "linien_server" / "gateware.bin",
diff --git a/gateware/linien_module.py b/gateware/linien_module.py
index 16ca186..6905ac0 100644
--- a/gateware/linien_module.py
+++ b/gateware/linien_module.py
@@ -2,6 +2,7 @@
# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
# Copyright 2021-2023 Bastian Leykauf <leykauf@physik.hu-berlin.de>
# Copyright 2022 Christian Freier <christian.freier@nomadatomics.com>
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
#
# This file is part of Linien and based on redpid.
#
@@ -36,19 +37,13 @@ from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
from .logic.autolock import FPGAAutolock
from .logic.chains import FastChain, SlowChain, cross_connect
from .logic.decimation import Decimate
-from .logic.delta_sigma import DeltaSigma
from .logic.iir import Iir
from .logic.limit import LimitCSR
from .logic.modulate import Modulate
from .logic.pid import PID
from .logic.sweep import SweepCSR
-from .lowlevel.analog import PitayaAnalog
-from .lowlevel.crg import CRG
-from .lowlevel.dna import DNA
-from .lowlevel.gpio import Gpio
-from .lowlevel.pitaya_ps import PitayaPS, Sys2CSR, SysCDC, SysInterconnect
+from .lowlevel.pitaya_ps import Sys2CSR
from .lowlevel.scopegen import ScopeGen
-from .lowlevel.xadc import XADC
class LinienLogic(Module, AutoCSR):
@@ -156,45 +151,24 @@ class LinienLogic(Module, AutoCSR):
class LinienModule(Module, AutoCSR):
- def __init__(self, platform):
+ def __init__(self, soc):
width = 14
signal_width = 25
coeff_width = 25
chain_factor_bits = 8
self.init_submodules(
- width, signal_width, coeff_width, chain_factor_bits, platform
+ width, signal_width, coeff_width, chain_factor_bits, soc
)
- self.connect_everything(width, signal_width, coeff_width, chain_factor_bits)
+ self.connect_everything(width, signal_width, coeff_width, chain_factor_bits, soc)
def init_submodules(
- self, width, signal_width, coeff_width, chain_factor_bits, platform
+ self, width, signal_width, coeff_width, chain_factor_bits, soc
):
- sys_double = ClockDomainsRenamer("sys_double")
self.submodules.logic = LinienLogic(
coeff_width=coeff_width, chain_factor_width=chain_factor_bits
)
- self.submodules.analog = PitayaAnalog(
- platform.request("adc"), platform.request("dac")
- )
- self.submodules.xadc = XADC(platform.request("xadc"))
-
- for i in range(4):
- pwm = platform.request("pwm", i)
- ds = sys_double(DeltaSigma(width=15))
- self.comb += pwm.eq(ds.out)
- setattr(self.submodules, f"ds{i}", ds)
-
- exp = platform.request("exp")
- self.submodules.gpio_n = Gpio(exp.n)
- self.submodules.gpio_p = Gpio(exp.p)
-
- leds = Cat(*(platform.request("user_led", i) for i in range(8)))
- self.comb += leds.eq(self.gpio_n.o)
-
- self.submodules.dna = DNA(version=2)
-
self.submodules.fast_a = FastChain(
width,
signal_width,
@@ -210,18 +184,22 @@ class LinienModule(Module, AutoCSR):
offset_signal=self.logic.chain_b_offset_signed,
)
+ # FIXME: does it do anything?!
_ = ClockDomainsRenamer("sys_slow")
sys_double = ClockDomainsRenamer("sys_double")
max_decimation = 16
self.submodules.decimate = sys_double(Decimate(max_decimation))
self.clock_domains.cd_decimated_clock = ClockDomain()
decimated_clock = ClockDomainsRenamer("decimated_clock")
+ # TODO: No support for slow Analog Out on Fast Servo
self.submodules.slow_chain = decimated_clock(SlowChain())
-
self.submodules.scopegen = ScopeGen(signal_width)
+ soc.add_interconnect_slave(self.scopegen.scope_sys)
+ soc.add_interconnect_slave(self.scopegen.asg_sys)
+
self.state_names, self.signal_names = cross_connect(
- self.gpio_n,
+ soc.gpio_n,
[
("fast_a", self.fast_a),
("fast_b", self.fast_b),
@@ -233,10 +211,6 @@ class LinienModule(Module, AutoCSR):
)
csr_map = {
- "dna": 28,
- "xadc": 29,
- "gpio_n": 30,
- "gpio_p": 31,
"fast_a": 0,
"fast_b": 1,
"slow_chain": 2,
@@ -251,19 +225,13 @@ class LinienModule(Module, AutoCSR):
name if mem is None else name + "_" + mem.name_override
],
)
- self.submodules.sys2csr = Sys2CSR()
- self.submodules.csrcon = csr_bus.Interconnect(
- self.sys2csr.csr, self.csrbanks.get_buses()
- )
- self.submodules.syscdc = SysCDC()
- self.comb += self.syscdc.target.connect(self.sys2csr.sys)
- def connect_everything(self, width, signal_width, coeff_width, chain_factor_bits):
+ def connect_everything(self, width, signal_width, coeff_width, chain_factor_bits, soc):
s = signal_width - width
self.comb += [
- self.fast_a.adc.eq(self.analog.adc_a),
- self.fast_b.adc.eq(self.analog.adc_b),
+ self.fast_a.adc.eq(soc.analog.adc_a),
+ self.fast_b.adc.eq(soc.analog.adc_b),
]
# now, we combine the output of the two paths, with a variable factor each.
@@ -297,7 +265,7 @@ class LinienModule(Module, AutoCSR):
self.comb += [
If(
self.logic.pid_only_mode.storage,
- self.logic.pid.input.eq(self.analog.adc_a << s),
+ self.logic.pid.input.eq(soc.analog.adc_a << s),
).Else(
self.logic.pid.input.eq(mixed_limited),
),
@@ -347,40 +315,42 @@ class LinienModule(Module, AutoCSR):
# ANALOG OUTPUTS ---------------------------------------------------------------
# ANALOG OUT 0 gets a special treatment because it may contain signal of slow
# pid or sweep
- analog_out = Signal((width + 3, True))
- self.comb += [
- analog_out.eq(
- Mux(
- self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
- self.logic.sweep.y,
- 0,
- )
- + Mux(
- self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
- self.logic.out_offset_signed,
- 0,
- )
- + Mux(
- self.logic.slow_control_channel.storage
+
+ if soc.soc_name == "RedPitaya":
+ analog_out = Signal((width + 3, True))
+ self.comb += [
+ analog_out.eq(
+ Mux(
+ self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
+ self.logic.sweep.y,
+ 0,
+ )
+ + Mux(
+ self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
+ self.logic.out_offset_signed,
+ 0,
+ )
+ + Mux(
+ self.logic.slow_control_channel.storage
== OutputChannel.ANALOG_OUT0,
self.slow_chain.output,
- 0,
- )
- ),
- ]
- # NOTE: not sure why limit is used
- self.comb += self.slow_chain.limit.x.eq(analog_out)
- # ds0 apparently has 16 bit, but only allowing positive values --> "15 bit"?
- slow_out_shifted = Signal(15)
- self.sync += slow_out_shifted.eq((self.slow_chain.limit.y << 1) + (1 << 14))
- self.comb += self.ds0.data.eq(slow_out_shifted)
-
- # connect other analog outputs
- self.comb += [
- self.ds1.data.eq(self.logic.analog_out_1.storage),
- self.ds2.data.eq(self.logic.analog_out_2.storage),
- self.ds3.data.eq(self.logic.analog_out_3.storage),
- ]
+ 0,
+ )
+ ),
+ ]
+ # NOTE: not sure why limit is used
+ self.comb += self.slow_chain.limit.x.eq(analog_out)
+ # ds0 apparently has 16 bit, but only allowing positive values --> "15 bit"?
+ slow_out_shifted = Signal(15)
+ self.sync += slow_out_shifted.eq((self.slow_chain.limit.y << 1) + (1 << 14))
+ self.comb += soc.ds0.data.eq(slow_out_shifted)
+
+ # connect other analog outputs
+ self.comb += [
+ soc.ds1.data.eq(self.logic.analog_out_1.storage),
+ soc.ds2.data.eq(self.logic.analog_out_2.storage),
+ soc.ds3.data.eq(self.logic.analog_out_3.storage),
+ ]
# ------------------------------------------------------------------------------
@@ -395,7 +365,7 @@ class LinienModule(Module, AutoCSR):
self.comb += [
self.logic.autolock.robust.at_start.eq(self.logic.sweep.sweep.trigger),
- self.scopegen.gpio_trigger.eq(self.gpio_p.i[0]),
+ self.scopegen.gpio_trigger.eq(soc.gpio_p.i[0]),
self.scopegen.sweep_trigger.eq(self.logic.sweep.sweep.trigger),
self.scopegen.automatically_rearm.eq(
self.logic.autolock.request_lock.storage
@@ -404,8 +374,8 @@ class LinienModule(Module, AutoCSR):
self.scopegen.automatically_trigger.eq(
self.logic.autolock.lock_running.status
),
- self.analog.dac_a.eq(self.logic.limit_fast1.y),
- self.analog.dac_b.eq(self.logic.limit_fast2.y),
+ soc.analog.dac_a.eq(self.logic.limit_fast1.y),
+ soc.analog.dac_b.eq(self.logic.limit_fast2.y),
]
# Having this in a comb statement caused errors. See PR #251.
@@ -428,23 +398,4 @@ class DummyHK(Module, AutoCSR):
self.submodules.csrcon = csr_bus.Interconnect(
self.sys2csr.csr, self.csrbanks.get_buses()
)
- self.sys = self.sys2csr.sys
-
-
-class RootModule(Module):
- def __init__(self, platform):
- self.submodules.ps = PitayaPS(platform.request("cpu"))
- self.submodules.crg = CRG(
- platform.request("clk125"), self.ps.fclk[0], ~self.ps.frstn[0]
- )
- self.submodules.linien = LinienModule(platform)
-
- self.submodules.hk = ClockDomainsRenamer("sys_ps")(DummyHK())
-
- self.submodules.ic = SysInterconnect(
- self.ps.axi.sys,
- self.hk.sys,
- self.linien.scopegen.scope_sys,
- self.linien.scopegen.asg_sys,
- self.linien.syscdc.source,
- )
+ self.sys = self.sys2csr.sys
\ No newline at end of file
diff --git a/gateware/targets/__init__.py b/gateware/targets/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/gateware/targets/fast_servo.py b/gateware/targets/fast_servo.py
new file mode 100644
index 0000000..da5bf3b
--- /dev/null
+++ b/gateware/targets/fast_servo.py
@@ -0,0 +1,85 @@
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
+# Warsaw University of Technology
+#
+# This file is part of Linien and provides support for Linien on
+# Fast Servo platform.
+#
+# Linien is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Linien is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linien. If not, see <http://www.gnu.org/licenses/>.
+
+from fast_servo.gateware.fast_servo_soc import BaseSoC
+from migen import *
+from misoc.interconnect import csr_bus
+
+from gateware.linien_module import DummyHK, LinienModule
+from gateware.lowlevel.dna import DNA
+from gateware.lowlevel.gpio import Gpio
+from gateware.lowlevel.pitaya_ps import SysInterconnect
+
+
+class FastServoAnalog(Module):
+ def __init__(self, adc, dac):
+ size = 14 # length of DAC
+
+ self.adc_a = Signal(size)
+ self.adc_b = Signal(size)
+ self.dac_a = Signal(size)
+ self.dac_b = Signal(size)
+
+ self.comb += [
+ self.adc_a.eq(adc.data_out[0][2:]),
+ self.adc_b.eq(adc.data_out[1][2:]),
+ ]
+
+ self.sync += [
+ dac.data_in[0].eq(self.dac_a),
+ dac.data_in[1].eq(self.dac_b),
+ ]
+
+
+class LinienFastServo(BaseSoC):
+ def __init__(self, platform):
+ super().__init__(platform)
+
+ self.submodules.dna = DNA(version=2)
+
+ self.submodules.analog = FastServoAnalog(self.adc, self.dac)
+ gpios = platform.request("gpio")
+ self.submodules.gpio_n = Gpio(gpios.n)
+ # self.csr_devices.append("gpio_n")
+ self.submodules.gpio_p = Gpio(gpios.p)
+ # self.csr_devices.append("gpio_p")
+ self.csr_map.update({
+ "dna": 28,
+ "gpio_n": 30,
+ "gpio_p": 31,
+ })
+
+ # ---------------------------------------------
+ #
+ # FIXME - passing self to LinienModule
+ self.submodules.linien = LinienModule(self)
+
+ def soc_finalize(self):
+ self.add_interconnect_slave(self.syscdc.source)
+ self.submodules.csrbanks = csr_bus.CSRBankArray(self,
+ self.get_csr_dev_address)
+ self.submodules.csrcon = csr_bus.Interconnect(
+ self.sys2csr.csr, [*self.csrbanks.get_buses(), *self.linien.csrbanks.get_buses()]
+ )
+ self.submodules.hk = DummyHK()
+ self.submodules.interconnect = SysInterconnect(
+ self.axi2sys.sys,
+ self.hk.sys,
+ *self.interconnect_slaves
+ )
\ No newline at end of file
diff --git a/gateware/targets/red_pitaya.py b/gateware/targets/red_pitaya.py
new file mode 100644
index 0000000..c029e81
--- /dev/null
+++ b/gateware/targets/red_pitaya.py
@@ -0,0 +1,103 @@
+# Copyright 2014-2015 Robert Jördens <jordens@gmail.com>
+# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
+# Copyright 2021-2023 Bastian Leykauf <leykauf@physik.hu-berlin.de>
+# Copyright 2022 Christian Freier <christian.freier@nomadatomics.com>
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
+#
+# This file is part of Linien and based on redpid.
+#
+# Linien is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Linien is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linien. If not, see <http://www.gnu.org/licenses/>.
+
+from migen import *
+from misoc.interconnect import csr_bus
+from misoc.interconnect.csr import AutoCSR
+
+from gateware.linien_module import DummyHK, LinienModule
+from gateware.logic.delta_sigma import DeltaSigma
+from gateware.lowlevel.analog import PitayaAnalog
+from gateware.lowlevel.crg import CRG
+from gateware.lowlevel.dna import DNA
+from gateware.lowlevel.gpio import Gpio
+from gateware.lowlevel.pitaya_ps import PitayaPS, Sys2CSR, SysCDC, SysInterconnect
+from gateware.lowlevel.xadc import XADC
+
+
+class PitayaSoC(Module, AutoCSR):
+ def __init__(self, platform):
+ self.csr_map = {
+ "gpio_n": 30,
+ "gpio_p": 31,
+ "dna": 28,
+ "xadc": 29,
+ }
+ self.soc_name = "RedPitaya"
+ self.interconnect_slaves = []
+
+ self.submodules.ps = PitayaPS(platform.request("cpu"))
+ self.submodules.crg = CRG(
+ platform.request("clk125"), self.ps.fclk[0], ~self.ps.frstn[0]
+ )
+ self.submodules.sys2csr = Sys2CSR()
+ self.submodules.syscdc = SysCDC()
+ self.comb += self.syscdc.target.connect(self.sys2csr.sys)
+
+ self.submodules.xadc = XADC(platform.request("xadc"))
+ self.submodules.analog = PitayaAnalog(platform.request("adc"), platform.request("dac"))
+
+ for i in range(4):
+ pwm = platform.request("pwm", i)
+ ds = ClockDomainsRenamer("sys_double")(DeltaSigma(width=15))
+ self.comb += pwm.eq(ds.out)
+ setattr(self.submodules, f"ds{i}", ds)
+
+ exp = platform.request("exp")
+ self.submodules.gpio_n = Gpio(exp.n)
+ self.submodules.gpio_p = Gpio(exp.p)
+
+ leds = Cat(*(platform.request("user_led", i) for i in range(8)))
+ self.comb += leds.eq(self.gpio_n.o)
+
+ self.submodules.dna = DNA(version=2)
+
+ # ---------------------------------------------
+ #
+ # FIXME - passing self to LinienModule
+ self.submodules.linien = LinienModule(self)
+ self.add_interconnect_slave(self.syscdc.source)
+ self.run_finalize()
+
+
+ def add_interconnect_slave(self, slave):
+ self.interconnect_slaves.append(slave)
+
+ def get_csr_dev_address(self, name, memory):
+ if memory is not None:
+ name = name + "_" + memory.name_override
+ try:
+ return self.csr_map[name]
+ except KeyError:
+ return None
+
+ def run_finalize(self):
+ self.submodules.csrbanks = csr_bus.CSRBankArray(self,
+ self.get_csr_dev_address)
+ self.submodules.csrcon = csr_bus.Interconnect(
+ self.sys2csr.csr, [*self.csrbanks.get_buses(), *self.linien.csrbanks.get_buses()]
+ )
+ self.submodules.hk = DummyHK()
+ self.submodules.interconnect = SysInterconnect(
+ self.ps.axi.sys,
+ self.hk.sys,
+ *self.interconnect_slaves
+ )
\ No newline at end of file

44
flake.lock generated
View File

@ -18,11 +18,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1703961334, "lastModified": 1706107048,
"narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", "narHash": "sha256-SqcJ9KxQVY+eLojoqYuJhWa4+D9utUzEuFJzOcUS8iY=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", "rev": "6fd7935607b68a96949b51ff08f12109e99ffd1f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -56,7 +56,43 @@
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"not-os": "not-os" "not-os": "not-os",
"src-migen": "src-migen",
"src-misoc": "src-misoc"
}
},
"src-migen": {
"flake": false,
"locked": {
"lastModified": 1702942348,
"narHash": "sha256-gKIfHZxsv+jcgDFRW9mPqmwqbZXuRvXefkZcSFjOGHw=",
"owner": "m-labs",
"repo": "migen",
"rev": "50934ad10a87ade47219b796535978b9bdf24023",
"type": "github"
},
"original": {
"owner": "m-labs",
"repo": "migen",
"type": "github"
}
},
"src-misoc": {
"flake": false,
"locked": {
"lastModified": 1699352904,
"narHash": "sha256-SglyTmXOPv8jJOjwAjJrj/WhAkItQfUbvKfUqrynwRg=",
"ref": "refs/heads/master",
"rev": "a53859f2167c31ab5225b6c09f30cf05527b94f4",
"revCount": 2452,
"submodules": true,
"type": "git",
"url": "https://github.com/m-labs/misoc.git"
},
"original": {
"submodules": true,
"type": "git",
"url": "https://github.com/m-labs/misoc.git"
} }
} }
}, },

View File

@ -5,7 +5,10 @@
inputs.not-os.url = github:cleverca22/not-os; inputs.not-os.url = github:cleverca22/not-os;
inputs.not-os.inputs.nixpkgs.follows = "nixpkgs"; inputs.not-os.inputs.nixpkgs.follows = "nixpkgs";
outputs = { self, nixpkgs, not-os }: inputs.src-migen = { url = github:m-labs/migen; flake = false; };
inputs.src-misoc = { type = "git"; url = "https://github.com/m-labs/misoc.git"; submodules = true; flake = false; };
outputs = { self, nixpkgs, not-os, src-migen, src-misoc }:
let let
pkgs = import nixpkgs { system = "x86_64-linux"; }; pkgs = import nixpkgs { system = "x86_64-linux"; };
not-os-cfg = not-os-configured.config.system; not-os-cfg = not-os-configured.config.system;
@ -23,6 +26,48 @@
]; ];
}; };
migen = pkgs.python3Packages.buildPythonPackage rec {
name = "migen";
src = src-migen;
format = "pyproject";
nativeBuildInputs = [ pkgs.python3Packages.setuptools ];
propagatedBuildInputs = [ pkgs.python3Packages.colorama ];
};
misoc = pkgs.python3Packages.buildPythonPackage {
name = "misoc";
src = src-misoc;
propagatedBuildInputs = with pkgs.python3Packages; [ jinja2 numpy migen pyserial asyncserial ];
};
vivado = pkgs.buildFHSEnv {
name = "vivado";
targetPkgs = pkgs: with pkgs; let
# Apply patch from https://github.com/nix-community/nix-environments/pull/54
# to fix ncurses libtinfo.so's soname issue
ncurses' = ncurses5.overrideAttrs (old: {
configureFlags = old.configureFlags ++ [ "--with-termlib" ];
postFixup = "";
});
in [
libxcrypt-legacy
(ncurses'.override { unicodeSupport = false; })
zlib
libuuid
xorg.libSM
xorg.libICE
xorg.libXrender
xorg.libX11
xorg.libXext
xorg.libXtst
xorg.libXi
freetype
fontconfig
];
profile = "set -e; source /opt/Xilinx/Vivado/2022.2/settings64.sh";
runScript = "vivado";
};
not-os-configured = (import patched-not-os { not-os-configured = (import patched-not-os {
inherit nixpkgs; inherit nixpkgs;
extraModules = [ extraModules = [
@ -146,6 +191,34 @@
}; };
}; };
fast-servo-gateware = pkgs.stdenv.mkDerivation rec {
name = "fast-servo-gateware";
inherit (pkgs.python3Packages.linien-common) src;
prePatch = ''
mkdir -p fast_servo/gateware
cp -r ${./fast-servo/linien-gateware}/. fast_servo/gateware
'';
patches = [
fast-servo/linien-fast-servo-gateware.patch
fast-servo/linien-fast-servo-server.patch
];
nativeBuildInputs = [
(pkgs.python3.withPackages(ps: [ migen misoc ps.linien-common ]))
vivado
];
buildPhase = ''
export HOME=$(mktemp -d)
python -m gateware.fpga_image_helper -p fastservo
'';
installPhase = ''
mkdir -p $out $out/nix-support
cp gateware/build/top.bit $out
cp linien-server/linien_server/gateware.bin $out
echo file binary-dist $out/top.bit >> $out/nix-support/hydra-build-products
echo file binary-dist $out/gateware.bin >> $out/nix-support/hydra-build-products
'';
};
mkbootimage = pkgs.stdenv.mkDerivation { mkbootimage = pkgs.stdenv.mkDerivation {
pname = "mkbootimage"; pname = "mkbootimage";
version = "2.3dev"; version = "2.3dev";
@ -385,10 +458,13 @@
in rec { in rec {
packages.x86_64-linux = { packages.x86_64-linux = {
inherit mkbootimage; inherit mkbootimage;
inherit migen misoc vivado;
}; };
packages.armv7l-linux = packages.armv7l-linux = {
(board-package-set { board = "zc706"; }) // inherit fast-servo-gateware;
(board-package-set { board = "fast-servo"; }); } //
(board-package-set { board = "zc706"; }) //
(board-package-set { board = "fast-servo"; });
hydraJobs = packages.x86_64-linux // packages.armv7l-linux; hydraJobs = packages.x86_64-linux // packages.armv7l-linux;
}; };