اضغط على ESC للإغلاق

دليل إصلاح ASIC: تشخيص أعطال الشريحة واستبدال لوحة الهاش

لو جهاز S19 Pro عندك طاح أدائه وما عاد يعطيك الـ 110 TH/s المعتادة، وواجهة المستخدم تظهر لك 0 بدل 76 رقاقة أو السلسلة مقطوعة — خلاص، لازم تسحب لوحة الهاش للفاحص وتفكها على طاولة الصيانة. في 90% من الحالات، السبب يكون انفصال الكريستالة من الحرارة العالية، أو ضربة في منظم الجهد (LDO)، أو كسر دقيق (micro-crack) في شريحة التكستوليت.

معمارية لوحة الهاش في S19 Pro: تقسيم النطاقات والإشارات

تجي لوحة الهاش في Antminer S19 Pro محملة بـ 76 رقاقة من نوع BM1398، مقسمة على 19 نطاق طاقة متسلسل (كل نطاق فيه 4 رقاقات). الجهد الإجمالي للناقل (تقريباً 12.5–15 فولت حسب السوفتوير) يتوزع بينها بالتساوي. يعني كل نطاق يأخذ حوالي 0.7–0.8 فولت، والرقاقة نفسها تتغذى بجهد VCORE في حدود 0.32–0.42 فولت.

الإشارات تمشي بالترتيب في السلسلة من الرقاقة الأولى (جنب سوكت لوحة التحكم) لين الرقاقة رقم 76:

  • CLK (25 MHz): إشارة التوقيت (الساعة). لو انقطعت عند الرقاقة رقم 30، كل الرقاقات اللي بعدها بتطفي فوراً.
  • CO (Command Output): خط الأوامر الداخل من لوحة التحكم.
  • RI (Return Input): خط الاستجابة الراجع للوحة التحكم. يمشي بالعكس — من الرقاقة 76 للرقاقة 1.
  • RST (Reset): خط إعادة الضبط. لو نزل مستواه، يدخل الرقاقة في حالة ريست كاملة.
  • BO (Busy Output): إشارة انشغال الخط.

خطوات التشخيص: من سجلات السجل (Kernel Log) لفحص الاتصالية

افتح الـ Kernel Log عن طريق واجهة الويب للجهاز أو السوفتوير المعدل مثل (VNish أو HiveOS). وشوف السلسلة وين فصلت بالضبط وتصفرت.

شنو تدور عليه في اللوج:

  • Chain 1: found 0 asics — ما في أي رد على خط الـ RI. تشيك فوراً على الرقاقة الأولى، وتغذية الـ LDO الخاصة فيها، أو كابل الإشارة نفسه.
  • Chain 2: only 42 asics found — الإشارة "علقت" عند الرقاقة 42 أو 43. افحص هذه المنطقة مباشرة.
  • Read temp sensor failed — حساس الحرارة TMP75 ضرب. في S19 Pro، الحساسات موزعة على أكثر من نطاق. وإذا مات الحساس، اللوحة ما راح تشتغل كإجراء حماية.

قياس نقاط الاختبار (Test Points)

غذّي اللوحة من باور سبيشل للمختبر أو جهاز فحص (بدون ما تضخ أمبير عالي على الناقل)، واضبط الملتيميتر على وضع فحص الدايود (الطرف الأحمر على الأرضي GND).

[Chip 42] ---> (CO / CLK / RST) ---> [Chip 43]
[Chip 42] <--- (RI / BO)        <--- [Chip 43]

مقاومة خطوط الإشارة عند نقاط الاختبار بالنسبة للأرضي لازم تكون متقاربة ومتناسقة على طول اللوحة:

  • CLK, CO, RI, RST: تقريباً في حدود 450–600 أوم.

لو لقيت نقطة CLK عند الرقاقة 43 تعطي صفر أوم (شورت كامل) أو تعطي ما لا نهاية (قطع) — خلاص، الرقاقة محتاجة تبديل.

تغذية الـ LDO

كل نطاق يحتاج جهود مساعدة لتشغيل الدوائر المنطقية الداخلية للرقاقة. واللي يزودها هي منظمات LDO صغيرة:

  • VDD 1.8V: لتغذية دوائر الإشارة.
  • VDD 0.8V: لتغذية النواة المنطقية الداخلية.

لو الرقاقة واصلها 1.8V وبنفس الوقت غائب عنها الـ 0.8V — ما راح تقدر تمرر إشارة الـ CLK للرقاقة اللي بعدها، واللوحة بتقص السلسلة عندها.

ليه تحتاج الأوسيلوسكوب وكيف تشتغل بيه؟

الملتيميتر يعطيك بس متوسط الجهد المستمر (DC). لكنه الملتيميتر ينعمي وما ينفع لو الجهد ممتاز بس الإشارة مشوهة بنويز أو سعتها طايحة. الملتيميتر ممكن يخدعك بامتياز، بينما الأوسيلوسكوب يوريك شكل الموجة الحقيقي فوراً.

تحتاج جهاز بنطاق ترددي لا يقل عن 100 MHz مع بروب (Probe) بمقسم 10X.

فحص إشارة الـ CLK (تردد الساعة 25 MHz):

حط رأس البروب على نقطة اختبار الـ CLK. المفروض تشوف موجة جيبية (Sinusoidal) متناسقة أو موجة مربعة بسعة تقارب 1.8V. لو شفت بدل الإشارة السليمة موجة مشوهة بسعة 0.4V — فهذا يعني أن البافر (Buffer) الداخلي للرقاقة انحرق وما يقدر يدفع الإشارة للي بعدها.

فحص حزم البيانات CO/RI:

أول ما تشتغل اللوحة ترسل نبضات سريعة. على الأوسيلوسكوب تظهر كأنها قفزات خاطفة (Burst). لو الحزمة وصلت لمدخل الرقاقة 43 وما طلع من مخرجها شيء — فالرقاقة ميتة، أو إشارة الـ RST عندها معلقة على الصفر.

التموجات على خط التغذية (Ripple):

حول مدخل الأوسيلوسكوب لـ AC (المدخل المغلق) وقس المكثفات مباشرة تحت بطن الرقاقة. لو التموجات أكثر من 30–40 millivolt، فهذا دليل أن مكثفات السيراميك حول الرقاقة تلفانة من الحرارة العالية المستمرة.

دليل نقاط الاختبار مرجعي (Antminer S19 Pro / BM1398)

الخطالجهد الطبيعي (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مستوى منطقي مرتفع (High)500–650 أومالرقاقات تظل معلقة في وضع الريست
VDD 1.8V1.8Vخط صافي (تشويش AC أقل من 20mV)1–3 كيلو أومتوقف بافرات الإدخال والإخراج (I/O)
VDD 0.8V0.8Vخط صافي (تشويش AC أقل من 15mV)100–300 أومتوقف النواة الداخلية للرقاقة

الجانب العملي لللحام: فك وتركيب الرقاقة BM1398

لوحات الألومنيوم في S19 Pro تشتغل كمشتت حراري ضخم. أنك تحاول تفك الرقاقة بالهوت اير من فوق بس — هذه أسرع طريقة عشان تحرق الطبقات وتطير المبادئ والمسارات (Pads).

شنو تحتاج للعملية:

  • سخان سفلي (Preheater) ببروفايل حراري بين 160–180°C.
  • كاوية هوت اير (مع نازل بمقاس الرقاقة).
  • فلر BGA ناعم ما يحتاج غسيل (مثل NC-559 أو Martin أو RMA-223).
  • كور قصدير بالرصاص مقاس 0.35 مم أو معجون قصدير رصاصي Sn63/Pb37 (الرصاص ينصهر عند 183°C، وهذا يسهل حياتك مقارنة بقصدير المصنع الخالي من الرصاص Lead-Free).

خطوات العمل:

  1. نحط اللوحة على السخان السفلي ونرفع الحرارة بالتدريج لين 150–160°C. لو استعجلت — التمدد الحراري المختلف بين التكستوليت والألومنيوم بيلوي اللوحة عليك مثل الموزة.
  2. نحط شوية فلكس تحت الرقاقة.
  3. نسخن بالهوت اير من فوق (حرارة الهواء الخارجي تقريباً 340–360°C مع تدفق هواء متوسط). التسخين يكون بحركات دائرية.
  4. نلمس الرقاقة بالملقط بخفة: أول ما تحس إنها "عامت" على الكرات، ارفعها بشويش ورأسياً للأعلى.
  5. ننظف المسارات على اللوحة باستخدام شيلد نحاسي (Copper Braid) مع كولوفونية، ونغسل المنطقة بإيزوبروبانول أو ثينر نظيف.
  6. نعيد صب الكرات (Reballing) للرقاقة الجديدة باستخدام الشابلون ومعجون القصدير الرصاصي أو الكور.
  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"[*] Parsing log file: {filepath}\n")
    
    try:
        with open(filepath, "r", errors="ignore") as f:
            for num, line in enumerate(f, 1):
                # Check ASIC counts per chain
                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 {chain_id}: found "
                            f"{found}/{EXPECTED_ASICS} ASICs."
                        )
                        if found == 0:
                            print(
                                "    -> First ASIC in chain not detected."
                            )
                            print(
                                "    -> Inspect board power rail, RI, "
                                "RST, BOOT, and CLK signals."
                            )
                        else:
                            print(
                                f"    -> Probe output signals (CLK/CO) "
                                f"on ASIC #{found}"
                            )
                            print(
                                f"    -> Probe input signals (RI) and "
                                f"LDO rail on ASIC #{found + 1}"
                            )
                        print()

                # Check temperature sensor faults
                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"[!] Thermal sensor fault on "
                            f"sensor #{sensor_id} (Line {num})."
                        )
                        print(
                            "    -> Check TMP75 IC, LDO power rail, "
                            "and I2C bus lines."
                        )
                        print()

        # Final Diagnostic Summary
        print("=" * 60)
        print("DIAGNOSTIC SUMMARY")
        print("=" * 60)
        if not issues_found:
            print("[+] No known error patterns detected in log.")
            return False

        if problem_chains:
            print("\nFaulty Chains:")
            for chain_id, found, expected in problem_chains:
                print(
                    f"  - Chain {chain_id}: "
                    f"{found}/{expected} ASICs detected"
                )

        if reported_sensors:
            print("\nThermal Sensor Faults:")
            for sensor_id in sorted(reported_sensors):
                print(f"  - Sensor #{sensor_id}")
        print()
        return True

    except FileNotFoundError:
        print(f"[-] File not found: {filepath}")
        return True
    except Exception as e:
        print(f"[-] Error processing file: {e}")
        return True

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(
            f"Usage: {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 must be an integer.")
            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 أوم. يحدد سجل النظام (Kernel Log) آخر شريحة تم التعرف عليها، ويكون العطل عادةً في مخرج هذه الشريحة أو في مدخل الشريحة التالية التي تتسبب في انقطاع إشارة العودة RI.

يتطلب تشغيل الشريحة خط VDD 1.8V لتغذية دوائر التخزين المؤقت لإشارات الدخل والخرج، وخط VDD 0.8V لتغذية نواة المنطق الحسابي الداخلي. يؤدي غياب أي من هذه الجهود إلى توقف الشريحة عن العمل وحظر إرسال إشارة التوقيت CLK، مما يجعل لوحة التحكم تسقط سلسلة لوحة الهاش بالكامل.

استخدم أوسيلوسكوب بعرض نطاق لا يقل عن 100 ميجاهرتز مع مجس بعامل تخميد 10X للقياس على نقطة الاختبار CLK والتأكد من وجود موجة جيبية مستقرة بتردد 25 ميجاهرتز وسعة 1.8Vpp تقريبًا. تحول إلى وضع الاقتران المتناوب (AC Coupling) على مكثفات VCORE للكشف عن التموجات الفولتية (Ripple) التي يجب ألا تتجاوز 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....

شاركنا برأيك

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها *