Add ebaz4205 support (#327)
Co-authored-by: newell <newell.jensen@gmail.com> Co-committed-by: newell <newell.jensen@gmail.com>
This commit is contained in:
parent
1f81d038e0
commit
81790257a5
253
src/gateware/ebaz4205.py
Normal file
253
src/gateware/ebaz4205.py
Normal file
@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
from operator import itemgetter
|
||||
|
||||
from migen import *
|
||||
from migen.build.platforms import ebaz4205
|
||||
from migen.build.generic_platform import Pins, Subsignal, IOStandard, Misc
|
||||
from migen_axi.integration.soc_core import SoCCore
|
||||
from misoc.interconnect.csr import *
|
||||
|
||||
from artiq.gateware import rtio
|
||||
from artiq.gateware.rtio.phy import ttl_simple
|
||||
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
|
||||
|
||||
import dma
|
||||
import analyzer
|
||||
|
||||
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||
|
||||
_ps = [
|
||||
(
|
||||
"ps",
|
||||
0,
|
||||
Subsignal("clk", Pins("E7"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
|
||||
Subsignal("por_b", Pins("C7"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
|
||||
Subsignal("srst_b", Pins("B10"), IOStandard("LVCMOS18"), Misc("SLEW=FAST")),
|
||||
)
|
||||
]
|
||||
|
||||
_ddr = [
|
||||
(
|
||||
"ddr",
|
||||
0,
|
||||
Subsignal(
|
||||
"a",
|
||||
Pins("N2 K2 M3 K3 M4 L1 L4 K4 K1 J4 F5 G4 E4 D4 F4"),
|
||||
IOStandard("SSTL15"),
|
||||
),
|
||||
Subsignal("ba", Pins("L5 R4 J5"), IOStandard("SSTL15")),
|
||||
Subsignal("cas_n", Pins("P5"), IOStandard("SSTL15")),
|
||||
Subsignal("cke", Pins("N3"), IOStandard("SSTL15")),
|
||||
Subsignal("cs_n", Pins("N1"), IOStandard("SSTL15")),
|
||||
Subsignal("ck_n", Pins("M2"), IOStandard("DIFF_SSTL15"), Misc("SLEW=FAST")),
|
||||
Subsignal("ck_p", Pins("L2"), IOStandard("DIFF_SSTL15"), Misc("SLEW=FAST")),
|
||||
# Pins "T1 Y1" not connected
|
||||
Subsignal("dm", Pins("A1 F1"), IOStandard("SSTL15_T_DCI"), Misc("SLEW=FAST")),
|
||||
Subsignal(
|
||||
"dq",
|
||||
Pins("C3 B3 A2 A4 D3 D1 C1 E1 E2 E3 G3 H3 J3 H2 H1 J1"),
|
||||
# Pins "P1 P3 R3 R1 T4 U4 U2 U3 V1 Y3 W1 Y4 Y2 W3 V2 V3" not connected
|
||||
IOStandard("SSTL15_T_DCI"),
|
||||
Misc("SLEW=FAST"),
|
||||
),
|
||||
Subsignal(
|
||||
"dqs_n",
|
||||
Pins("B2 F2"), # Pins "T2 W4" not connected
|
||||
IOStandard("DIFF_SSTL15_T_DCI"),
|
||||
Misc("SLEW=FAST"),
|
||||
),
|
||||
Subsignal(
|
||||
"dqs_p",
|
||||
Pins("C2 G2"), # Pins "R2 W5" not connected
|
||||
IOStandard("DIFF_SSTL15_T_DCI"),
|
||||
Misc("SLEW=FAST"),
|
||||
),
|
||||
Subsignal("vrn", Pins("G5"), IOStandard("SSTL15_T_DCI"), Misc("SLEW=FAST")),
|
||||
Subsignal("vrp", Pins("H5"), IOStandard("SSTL15_T_DCI"), Misc("SLEW=FAST")),
|
||||
Subsignal("drst_n", Pins("B4"), IOStandard("SSTL15"), Misc("SLEW=FAST")),
|
||||
Subsignal("odt", Pins("N5"), IOStandard("SSTL15")),
|
||||
Subsignal("ras_n", Pins("P4"), IOStandard("SSTL15")),
|
||||
Subsignal("we_n", Pins("M5"), IOStandard("SSTL15")),
|
||||
)
|
||||
]
|
||||
|
||||
# Connector J3
|
||||
_i2c = [
|
||||
(
|
||||
"i2c",
|
||||
0,
|
||||
Subsignal("scl", Pins("U12"), IOStandard("LVCMOS33")),
|
||||
Subsignal("sda", Pins("V13"), IOStandard("LVCMOS33")),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class EBAZ4205(SoCCore):
|
||||
def __init__(self, rtio_clk=125e6, acpki=False):
|
||||
self.acpki = acpki
|
||||
|
||||
platform = ebaz4205.Platform()
|
||||
platform.toolchain.bitstream_commands.extend(
|
||||
[
|
||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||
]
|
||||
)
|
||||
platform.add_extension(_ps)
|
||||
platform.add_extension(_ddr)
|
||||
platform.add_extension(_i2c)
|
||||
|
||||
gmii = platform.request("gmii")
|
||||
platform.add_period_constraint(gmii.rx_clk, 10)
|
||||
platform.add_period_constraint(gmii.tx_clk, 10)
|
||||
platform.add_platform_command(
|
||||
"set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets gmii_tx_clk_IBUF]"
|
||||
)
|
||||
|
||||
ident = self.__class__.__name__
|
||||
if self.acpki:
|
||||
ident = "acpki_" + ident
|
||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||
fix_serdes_timing_path(platform)
|
||||
self.config["RTIO_FREQUENCY"] = str(rtio_clk / 1e6)
|
||||
platform.add_period_constraint(self.ps7.cd_sys.clk, 10)
|
||||
|
||||
self.comb += [
|
||||
self.ps7.enet0.enet.gmii.tx_clk.eq(gmii.tx_clk),
|
||||
self.ps7.enet0.enet.gmii.rx_clk.eq(gmii.rx_clk),
|
||||
]
|
||||
self.clock_domains.cd_eth_rx = ClockDomain(reset_less=False)
|
||||
self.clock_domains.cd_eth_tx = ClockDomain(reset_less=False)
|
||||
self.comb += [
|
||||
ClockSignal("eth_rx").eq(gmii.rx_clk),
|
||||
ClockSignal("eth_tx").eq(gmii.tx_clk),
|
||||
]
|
||||
self.sync.eth_tx += [
|
||||
gmii.txd.eq(self.ps7.enet0.enet.gmii.txd),
|
||||
gmii.tx_en.eq(self.ps7.enet0.enet.gmii.tx_en),
|
||||
]
|
||||
self.sync.eth_rx += [
|
||||
self.ps7.enet0.enet.gmii.rxd.eq(gmii.rxd),
|
||||
self.ps7.enet0.enet.gmii.rx_dv.eq(gmii.rx_dv),
|
||||
]
|
||||
|
||||
# MDIO
|
||||
mdio = platform.request("mdio")
|
||||
self.comb += mdio.mdc.eq(self.ps7.enet0.enet.mdio.mdc)
|
||||
self.specials += Instance(
|
||||
"IOBUF",
|
||||
i_I=self.ps7.enet0.enet.mdio.o,
|
||||
io_IO=mdio.mdio,
|
||||
o_O=self.ps7.enet0.enet.mdio.i,
|
||||
i_T=~self.ps7.enet0.enet.mdio.t_n,
|
||||
)
|
||||
|
||||
# I2C
|
||||
i2c = self.platform.request("i2c")
|
||||
self.specials += [
|
||||
# SCL
|
||||
Instance(
|
||||
"IOBUF",
|
||||
i_I=self.ps7.i2c0.scl.o,
|
||||
io_IO=i2c.scl,
|
||||
o_O=self.ps7.i2c0.scl.i,
|
||||
i_T=~self.ps7.i2c0.scl.t_n,
|
||||
),
|
||||
# SDA
|
||||
Instance(
|
||||
"IOBUF",
|
||||
i_I=self.ps7.i2c0.sda.o,
|
||||
io_IO=i2c.sda,
|
||||
o_O=self.ps7.i2c0.sda.i,
|
||||
i_T=~self.ps7.i2c0.sda.t_n,
|
||||
),
|
||||
]
|
||||
|
||||
self.rtio_channels = []
|
||||
for i in (0, 1):
|
||||
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
|
||||
user_led = self.platform.request("user_led", i)
|
||||
phy = ttl_simple.Output(user_led)
|
||||
self.submodules += phy
|
||||
self.rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||
self.rtio_channels.append(rtio.LogChannel())
|
||||
|
||||
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
|
||||
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
||||
self.csr_devices.append("rtio_core")
|
||||
if self.acpki:
|
||||
import acpki
|
||||
|
||||
self.config["KI_IMPL"] = "acp"
|
||||
self.submodules.rtio = acpki.KernelInitiator(
|
||||
self.rtio_tsc,
|
||||
bus=self.ps7.s_axi_acp,
|
||||
user=self.ps7.s_axi_acp_user,
|
||||
evento=self.ps7.event.o,
|
||||
)
|
||||
self.csr_devices.append("rtio")
|
||||
else:
|
||||
self.config["KI_IMPL"] = "csr"
|
||||
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True)
|
||||
self.csr_devices.append("rtio")
|
||||
|
||||
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
||||
self.csr_devices.append("rtio_dma")
|
||||
|
||||
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||
[self.rtio.cri, self.rtio_dma.cri],
|
||||
[self.rtio_core.cri],
|
||||
enable_routing=True,
|
||||
)
|
||||
self.csr_devices.append("cri_con")
|
||||
|
||||
self.submodules.rtio_moninj = rtio.MonInj(self.rtio_channels)
|
||||
self.csr_devices.append("rtio_moninj")
|
||||
|
||||
self.submodules.rtio_analyzer = analyzer.Analyzer(
|
||||
self.rtio_tsc, self.rtio_core.cri, self.ps7.s_axi_hp1
|
||||
)
|
||||
self.csr_devices.append("rtio_analyzer")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="ARTIQ port to the EBAZ4205 control card of Ebit E9+ BTC miner"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r", default=None, help="build Rust interface into the specified file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m", default=None, help="build Rust memory interface into the specified file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
default=None,
|
||||
help="build Rust compiler configuration into the specified file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-g", default=None, help="build gateware into the specified directory"
|
||||
)
|
||||
parser.add_argument("--rtio-clk", default=125e6, help="RTIO Clock Frequency (Hz)")
|
||||
parser.add_argument(
|
||||
"--acpki", default=False, action="store_true", help="enable ACPKI"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = EBAZ4205(rtio_clk=int(args.rtio_clk), acpki=args.acpki)
|
||||
soc.finalize()
|
||||
|
||||
if args.r is not None:
|
||||
write_csr_file(soc, args.r)
|
||||
if args.m is not None:
|
||||
write_mem_file(soc, args.m)
|
||||
if args.c is not None:
|
||||
write_rustc_cfg_file(soc, args.c)
|
||||
if args.g is not None:
|
||||
soc.build(build_dir=args.g)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -10,6 +10,7 @@ name = "libboard_artiq"
|
||||
[features]
|
||||
target_zc706 = ["libboard_zynq/target_zc706", "libconfig/target_zc706"]
|
||||
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libconfig/target_kasli_soc"]
|
||||
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libconfig/target_ebaz4205"]
|
||||
calibrate_wrpll_skew = []
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||
[features]
|
||||
target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706", "libboard_artiq/target_zc706"]
|
||||
target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc", "libboard_artiq/target_kasli_soc"]
|
||||
target_ebaz4205 = ["libboard_zynq/target_ebaz4205", "libsupport_zynq/target_ebaz4205", "libconfig/target_ebaz4205", "libboard_artiq/target_ebaz4205"]
|
||||
default = ["target_zc706"]
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -1,6 +1,8 @@
|
||||
#[cfg(not(feature = "target_ebaz4205"))]
|
||||
use embedded_hal::blocking::delay::DelayMs;
|
||||
#[cfg(has_si5324)]
|
||||
use ksupport::i2c;
|
||||
#[cfg(not(feature = "target_ebaz4205"))]
|
||||
use libboard_artiq::pl;
|
||||
#[cfg(has_si5324)]
|
||||
use libboard_artiq::si5324;
|
||||
@ -10,7 +12,9 @@ use libboard_artiq::si549;
|
||||
use libboard_zynq::i2c::I2c;
|
||||
use libboard_zynq::timer::GlobalTimer;
|
||||
use libconfig::Config;
|
||||
use log::{info, warn};
|
||||
use log::warn;
|
||||
#[cfg(not(feature = "target_ebaz4205"))]
|
||||
use log::info;
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
@ -69,7 +73,7 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock {
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(not(has_drtio))]
|
||||
#[cfg(not(any(has_drtio, feature = "target_ebaz4205")))]
|
||||
fn init_rtio(timer: &mut GlobalTimer) {
|
||||
info!("Switching SYS clocks...");
|
||||
unsafe {
|
||||
@ -429,7 +433,7 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||
#[cfg(has_drtio)]
|
||||
init_drtio(timer);
|
||||
|
||||
#[cfg(not(has_drtio))]
|
||||
#[cfg(not(any(has_drtio, feature = "target_ebaz4205")))]
|
||||
init_rtio(timer);
|
||||
|
||||
#[cfg(all(has_si549, has_wrpll))]
|
||||
|
Loading…
Reference in New Issue
Block a user