Compare commits

...

4 Commits

Author SHA1 Message Date
87f09bed1b Add configuration flags 2024-09-30 14:31:24 -07:00
0bccf8acca Include feature for ebaz4205 2024-09-30 14:30:30 -07:00
d59c283129 Update gateware 2024-09-30 14:27:54 -07:00
62c1765a5f Initial gateware 2024-09-30 09:58:42 -07:00
8 changed files with 268 additions and 3 deletions

248
src/gateware/ebaz4205.py Normal file
View File

@ -0,0 +1,248 @@
#!/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")),
)
]
class EBAZ4205(SoCCore):
def __init__(self, rtio_clk=100e6, 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)
## Uncomment if your EBAZ4205 doesn't have a PHY XTAL
## Clock for PHY is tied to pin U18
# platform.add_extension(
# [
# ("phy_clk", 0, Pins("U18"), IOStandard("LVCMOS33")),
# ]
# )
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),
]
## Uncomment if your EBAZ4205 doesn't have a PHY XTAL
## Left for the user to do, setup a 25 MHz clock for phy_clk.
# phy_clk = platform.request("phy_clk")
# ...
# MDIO
mdio = platform.request("mdio")
self.comb += [
mdio.mdc.eq(self.ps7.enet0.enet.mdio.mdc),
]
mdio_t = Signal()
self.comb += mdio_t.eq(~self.ps7.enet0.enet.mdio.t_n)
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=mdio_t,
)
]
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=100e6, 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()

View File

@ -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]

View File

@ -5,6 +5,11 @@ version = "0.1.0"
authors = ["M-Labs"]
edition = "2018"
[features]
target_zc706 = []
target_kasli_soc = []
target_ebaz4205 = []
[build-dependencies]
build_zynq = { path = "../libbuild_zynq" }

View File

@ -11,7 +11,9 @@ use super::{cache,
core1::rtio_get_destination_status,
dma, linalg,
rpc::{rpc_recv, rpc_send, rpc_send_async}};
use crate::{eh_artiq, i2c, rtio};
use crate::{eh_artiq, rtio};
#[cfg(not(feature = "target_ebaz4205"))]
use crate::i2c;
extern "C" {
fn vsnprintf_(buffer: *mut c_char, count: size_t, format: *const c_char, va: VaList) -> c_int;
@ -109,11 +111,17 @@ pub fn resolve(required: &[u8]) -> Option<u32> {
api!(cache_put = cache::put),
// i2c
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_start = i2c::start),
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_restart = i2c::restart),
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_stop = i2c::stop),
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_write = i2c::write),
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_read = i2c::read),
#[cfg(not(feature = "target_ebaz4205"))]
api!(i2c_switch_select = i2c::switch_select),
// subkernel

View File

@ -21,6 +21,7 @@ pub use pl::csr::rtio_core;
use void::Void;
pub mod eh_artiq;
#[cfg(not(feature = "target_ebaz4205"))]
pub mod i2c;
pub mod irq;
pub mod kernel;

View File

@ -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", "ksupport/target_ebaz4205"]
default = ["target_zc706"]
[build-dependencies]

View File

@ -100,6 +100,7 @@ pub fn main_core0() {
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
#[cfg(not(feature = "target_ebaz4205"))]
ksupport::i2c::init();
#[cfg(feature = "target_kasli_soc")]
{

View File

@ -69,7 +69,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 +429,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))]