Нажмите ESC, чтобы закрыть

Ремонт ASIC своими руками: диагностика чипов и хеш-плат

Если S19 Pro перестал выдавать свои 110 TH/s, а в веб-интерфейсе вместо 76 чипов светится 0 или оборванная цепочка — плату пора нести на диагностический стенд. В 90% случаев мы имеем дело с отвалом кристалла от перегрева, пробоем LDO-стабилизатора или микротрещиной в текстолите.

Архитектура хеш-платы S19 Pro: как устроены домены и сигналы

На хеш-плате Antminer S19 Pro стоят 76 чипов BM1398, разбитых на 19 последовательных питающих доменов (по 4 чипа в домене). Общее напряжение шины (около 12.5–15V в зависимости от прошивки) делится между ними. На один домен приходится в среднем 0.7–0.8V, а сам чип питается напряжением VCORE порядка 0.32–0.42V.

Сигналы идут последовательно по цепочке от 1-го чипа (возле разъема контрольки) до 76-го:

  • CLK (25 MHz): Тактовый сигнал. Если обрывается на 30-м чипе, все остальные после него тухнут.
  • CO (Command Output): Входная линия команд от контрольной платы.
  • RI (Return Input): Обратная линия ответа в контрольку. Идет в обратном направлении — от 76-го чипа к 1-му.
  • RST (Reset): Линия сброса. Низкий уровень на ней сажает чип в жесткий ресет.
  • BO (Busy Output): Сигнал занятости линии.

Пошаговая диагностика: от логов майнера к прозвонке

Открываем Kernel Log через веб-интерфейс майнера или прошивку (VNish, HiveOS). Смотрим, на чем именно зануляется цепь.

Что искать в логах:

  • Chain 1: found 0 asics — ответа по линии RI нет вообще. Смотрим 1-й чип, его LDO-питание или разъем сигнального шлейфа.
  • Chain 2: only 42 asics found — сигнал «застрял» на 42-м или 43-м чипе. Идем сразу к этому участку.
  • Read temp sensor failed — выбило датчик TMP75. На S19 Pro они стоят на нескольких доменах. Из-за мертвого датчика плата не запустится по соображениям защиты.

Замеры контрольных точек (Test Points)

Запитайте плату от сервисного БП или тестера (без подачи высокого тока на шину) и переведите мультиметр в режим прозвонки диодов (красный щуп на землю GND).

[Чип 42] ---> (CO / CLK / RST) ---> [Чип 43]
[Чип 42] <--- (RI / BO)        <--- [Чип 43]

Относительно земли сопротивление сигнальных линий на контрольных точках должно быть примерно одинаковым по всей плате:

  • CLK, CO, RI, RST: в районе 450–600 Ом.

Если на 43-м чипе точка CLK звенеть в 0 Ом (короткое) или показывает бесконечность — чип под замену.

Питание LDO

Каждому домену нужны вспомогательные напряжения для внутренней логики чипа. Их формируют мелкие LDO-стабилизаторы:

  • VDD 1.8V: питает сигнальную обвязку.
  • VDD 0.8V: питает внутреннее ядро логики.

Если на чипе есть 1.8V, но нет 0.8V — чип не сможет транслировать CLK дальше по цепи, и плата срежет цепочку на нем.

Зачем нужен осциллограф и как им работать

Мультиметр показывает только усредненное постоянное напряжение (DC). Но он бесполезен, когда напряжение в норме, а сам сигнал искажен шумом или сорвана амплитуда. Врать мультиметр может знатно, а осциллограф сразу показывает форму волны.

Нужен прибор с полосой хотя бы 100 MHz и щуп с делителем 10X.

Проверка CLK (Тактовая частота 25 MHz):

Встаем щупом на контрольную точку CLK. Должна быть ровная синусоида или меандр амлитудой около 1.8V. Если вместо нормального сигнала видите сплющенную пилу амплитудой 0.4V — буфер чипа подгорел и не продавливает линию дальше.

Проверка пакетов CO/RI:

При старте плата кидает короткие пачки импульсов. На осциллографе они выглядят как быстрые всплески (Burst). Если на вход чипа 43 пачка пришла, а с его выхода ничего не вылетает — этот чип мертв, либо у него висит RST в нуле.

Пульсации по шине питания (Ripple):

Переключаем вход осциллографа в режим AC (закрытый вход) и меряем конденсаторы прямо на брюхе чипа. Пульсации больше 30–40 мВ говорят о том, что керамика вокруг чипа поплыла от постоянного перегрева.

Справочник контрольных точек (Antminer S19 Pro / BM1398)

ЛинияНорма V (DC)Сигнал на осциллографеСопротивление на GNDСимптом при обрыве
CLK0.8–0.9VСинусоида 25 MHz, 1.8Vpp500–600 ОмЦепь обрывается на битом чипе
CO0–0.2VПачки импульсов 1.8V при опросе500–600 ОмОпрос чипов останавливается
RI1.7–1.8VПачки импульсов при ответе500–600 ОмВыдает 0 ASICs или режет хвост платы
RST1.8VВысокий логический уровень500–650 ОмЧипы не выходят из сброса
VDD 1.8V1.8VЧистая линия (AC-помеха < 20 мВ)1–3 кОмНе работают буферы ввода-вывода
VDD 0.8V0.8VЧистая линия (AC-помеха < 15 мВ)100–300 ОмНе работает ядро чипа

Практика пайки: сдергиваем и сажаем BM1398

Алюминиевые платы S19 Pro работают как огромный теплоотвод. Попытаться сдуть чип просто феном сверху — верный способ ужарить подложку и оторвать пятаки.

Что понадобится:

  • Нижний подогрев (термопрофиль 160–180°C).
  • Паяльный фен (насадка под размер чипа).
  • Безотмывочный BGA-флюс (NC-559, Martin или RMA-223).
  • Свинцовые шары 0.35 мм или свинцовая паста Sn63/Pb37 (свинец плавится при 183°C, что сильно облегчает жизнь по сравнению с заводским безсвинцом).

Порядок действий:

  1. Кладем плату на нижний подогрев, плавно греем до 150–160°C. Если поторопитесь — плату из-за разницы расширения текстолита и алюминия выгнет бананом.
  2. Наносим немного флюса под чип.
  3. Догреваем феном сверху (температура на выходе фена примерно 340–360°C, средний поток). Греем круговыми движениями.
  4. Касаемся чипа пинцетом: как только он «поплыл» на шарах, аккуратно снимаем его строго вверх.
  5. Зачищаем контактные площадки на плате медной оплеткой с канифолью, смываем все галошей или изопропилом.
  6. Накатываем новый чип через трафарет свинцовой пастой или шариками.
  7. Ставим чип по ключу (метка на корпусе и шелкография на плате должны совпасть), позиционируем.
  8. Греем на нижнем подогреве с подачей верхнего фена до посадки. Чип сам сядет на место за счет поверхностного натяжения жидкого припоя.

Парсер логов на Python для быстрой диагностики

Чтобы не ковырять логи вручную, вот рабочий скрипт. Скидываете ему лог с майнера, он выдергивает сбойную цепь и сразу пишет, на какой чип ставить мультиметр.

#!/usr/bin/env python3
import re
import sys
EXPECTED_ASICS = 76
def parse_asic_log(filepath):
    chain_pattern = re.compile(
        r"Chain\[(\d+)\]:\s*found\s*(\d+)\s*asics",
        re.IGNORECASE
    )
    sensor_pattern = re.compile(
        r"sensor[\[\s]*(\d+)[\]\s]*.*temp.*error",
        re.IGNORECASE
    )
    issues_found = False
    problem_chains = []
    reported_sensors = set()
    print(f"[*] Разбор лога: {filepath}\n")
    try:
        with open(filepath, "r", errors="ignore") as f:
            for num, line in enumerate(f, 1):
                # Проверка количества чипов в цепи
                c_match = chain_pattern.search(line)
                if c_match:
                    chain_id = int(c_match.group(1))
                    found = int(c_match.group(2))
                    if found < EXPECTED_ASICS:
                        issues_found = True
                        problem_chains.append(
                            (chain_id, found, EXPECTED_ASICS)
                        )
                        print(
                            f"[!] Цепь {chain_id}: найдено "
                            f"{found} чипов из {EXPECTED_ASICS}."
                        )
                        if found == 0:
                            print(
                                "    -> Не обнаружен первый чип цепи."
                            )
                            print(
                                "    -> Проверить питание платы, RI, "
                                "RST, BOOT и тактирование."
                            )
                        else:
                            print(
                                f"    -> Проверить выход (CLK/CO) "
                                f"чипа #{found}"
                            )
                            print(
                                f"    -> Проверить вход (RI) и "
                                f"LDO-питание чипа #{found + 1}"
                            )
                        print()
                # Проверка датчиков температуры
                s_match = sensor_pattern.search(line)
                if s_match:
                    sensor_id = int(s_match.group(1))
                    if sensor_id not in reported_sensors:
                        issues_found = True
                        reported_sensors.add(sensor_id)
                        print(
                            f"[!] Ошибка датчика температуры "
                            f"#{sensor_id} (строка {num})."
                        )
                        print(
                            "    -> Проверить TMP75, питание "
                            "датчика и линии I2C."
                        )
                        print()
        # Итоговая сводка
        print("=" * 60)
        print("ИТОГОВАЯ СВОДКА")
        print("=" * 60)
        if not issues_found:
            print("[+] Проблем по шаблонам не обнаружено.")
            return False
        if problem_chains:
            print("\nПроблемные цепи:")
            for chain_id, found, expected in problem_chains:
                print(
                    f"  - Chain {chain_id}: "
                    f"{found}/{expected} ASIC"
                )
        if reported_sensors:
            print("\nОшибки датчиков температуры:")
            for sensor_id in sorted(reported_sensors):
                print(f"  - Sensor {sensor_id}")
        print()
        return True
    except FileNotFoundError:
        print(f"[-] Файл не найден: {filepath}")
        return True
    except Exception as e:
        print(f"[-] Ошибка обработки файла: {e}")
        return True
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(
            f"Запуск: {sys.argv[0]} <path_to_log.txt> "
            f"[expected_asics]"
        )
        sys.exit(1)
    if len(sys.argv) >= 3:
        try:
            EXPECTED_ASICS = int(sys.argv[2])
        except ValueError:
            print("[-] expected_asics должен быть числом.")
            sys.exit(1)
    has_issues = parse_asic_log(sys.argv[1])
    sys.exit(1 if has_issues else 0)

Примеры запуска:

python diag.py kernel.log

Для платы с другим количеством чипов:

  • python diag.py kernel.log 63
  • python diag.py kernel.log 72
  • python diag.py kernel.log 80

Чек-лист контрольной проверки перед запуском в корпус

  • Сопротивление шины VCORE: Сопротивление относительно земли не должно быть нулевым (короткое замыкание).
  • Контроль LDO без полной нагрузки: Подаем питание от сервисного БП, проверяем наличие 1.8V и 0.8V на замененном чипе.
  • Прогонка сигнала: Проверяем осциллографом проходит ли 25 MHz через запаянный чип дальше по цепи.
  • Тест под высокой нагрузкой: Собираем майнер обратно, ставим на родные вентиляторы, гоняем плату на штатной прошивке 2–3 часа, отслеживая HW-ошибки по этой цепи.
Сделать краткую выжимку этой статьи с помощью:

FAQ

Переведите мультиметр в режим прозвонки диодов и измерьте сопротивление контрольных точек CLK, CO, RI и RST относительно земли (GND) — рабочие показатели находятся в диапазоне 450–600 Ом. Лог майнера указывает на последний определившийся чип, поэтому неисправность кроется на выходе этого чипа или на входе следующего по цепочке, который обрывает сигнал RI.

Линия VDD 1.8V питает буферы ввода-вывода для передачи сигналов между чипами, а VDD 0.8V подает питание на вычислительное ядро логики. Отсутствие любого из этих напряжений переводит чип в неактивное состояние, из-за чего блокируется тактовая частота CLK и контрольная плата сбрасывает всю цепочку хеш-платы.

Используйте осциллограф с полосой пропускания от 100 MHz и щуп с делителем 10X, чтобы не сажать сигнальные линии при замере. Встаньте щупом на точку CLK для проверки наличия синусоиды 25 MHz с амплитудой около 1.8Vpp, после чего переключите вход в режим AC для поиска пульсаций по шине VCORE, которые не должны превышать 30–40 мВ.
Sying Yu

I am a blockchain developer specializing in building secure, scalable, and innovative decentralized solutions. My expertise covers smart contracts, payment systems, and integrating crypto with fiat to optimize financial workflows. I thrive on creating modern, efficient tools for the evolving digital economy....

Поделитесь своим мнением

Ваш e-mail не будет опубликован. Обязательные поля отмечены *