Доброго дня. Сегодня я хотел бы рассказать о DDR4 в контексте модулей памяти.
1) Чуть-чуть об авторе
Автор имеет опыт в коммерческой разработке печатных плат около двух лет. До начала этого пути занимался баловством с микроконтроллерами на самодельных платах. На текущий же момент можно перечислить два значимых успешных проекта: материнская плата на RK3588 (LPDDR4X-4266MT/s, HDMI2.1, PCIe2/3, Ethernet 2.5G, USB2/3, SATA3), модуль памяти UDIMM DDR4 3200 MT/s. Разумеется, было много прочих, но они не требовали глубокого понимания работы с согласованием сигналов по задержке, понимания импеданса. Стоит учитывать, что автор является самоучкой чуть более чем полностью, так как более опытных коллег попросту не было и нет. Опыт работы имеется только с российскими фабриками.
Разработка велась в Altium, какого-либо моделирования (Cadence/Ansys/иной софт) не проводилось. Однако, проекты полностью работоспособны, что является косвенным доказательством валидности моих эвристик.
Последний вводный абзац. Если будет интерес и потребность – планируется сделать еще одну статью о workflow при работе с DDR4 в Altium. Также есть что рассказать про LPDDR4, если будет таковой запрос. Если есть интерес к разработке печатных плат – по ссылке доступно мое «пособие», полностью свободное.
2) Группы сигналов DDR4
Для лучшего понимания стоит начать именно с групп сигналов. Есть две разных шины – адресно-командная (CA) и шина данных (DQ). Описание всех линий вышло громоздким, так что будет в конце статьи.
Адресно-командная шина состоит из: CK_t/c, CKE, CS, ODT, ACT, BG0/BG1, BA0/BA1, A0-A17, PAR, ALERT, RESET.
Стоит рассказать о некоторых моментах, связанных с определенными линиями:
A10, A12, A14, A15, A16 – комбинированные, являются и адресными, и командными (подробнее в описании всех линий).
CK_t/c, CKE, CS, ODT – рангозависимые линии, их в одной шине два набора. Для первого ранга используются линии с цифрой «0», для второго – «1». Если на модуле ранг только один – неиспользуемую диффпару CK1_t/c необходимо подключить к резистору 75 Ом рядом с краевым разъемом (_t на один конец резистора, _c на другой). Все остальные линии (CKE1, CS1, ODT1) можно просто ни к чему не подключать.
Alert – нуждается в подтягивающем резисторе к VDD (порядка 40 Ом), который устанавливается со стороны первого (то есть, самого левого) чипа. Сама же линия ведется от краевого коннектора через последний (самый правый) к первому, в обратной всей CA-шине последовательности. НЕ нуждается в согласовании с остальной шиной, однако соблюдение импеданса и опорной плоскости требуется.
Reset – подтягивающий резистор не нужен, согласование не требуется, вести можно хоть совместно с CA-шиной, хоть противоположно ей. Импеданс и опорная плоскость – актуальны.
Шина данных состоит из: DQ, DQS_t/c, DM.
С этой шиной все проще, стоит лишь упомянуть рекомендацию по установке последовательного резистора около 15 Ом рядом с краевым разъемом на каждой линии (DQ, DQS, DM). Эти резисторы помогают не так сильно закидывать линии между процессором и слотом отражениями.
Питания. Это, конечно, не сигналы, но стоит кратко проговорить какие есть и зачем нужны:
VDD – основное напряжение питания логики DRAM. Обычно – 1.2 Вольта.
VDDQ – то же самое, что и VDD, но для домена DQ, часто объединяется в одну линию.
VPP – напряжение, позволяющее управлять затворами ячеек памяти (а транзистор открывается при каждом взаимодействии с ячейкой, чтение/запись/refresh). Обычно – 2.5 Вольта.
VREFCA – референсное напряжение для работы блока адреса и команд (CA и служебные сигналы). Обычно – 0.6 Вольта (VDDQ/2).
VTT – терминационное напряжение, используется для внешнего согласования интерфейсных выводов (адресно-командной шины). Обычно – 0.6 Вольта (VDD/2).
3) Немного общих понятий
Для начала – виды чипов по «битности». Вы могли видеть цифры x4, x8 и x16 относительно чипов памяти. Это – количество линий данных на чип. Стандартная планка памяти имеет ширину шины данных в 64 бита. Посему логично, что чем меньше бит на чип – тем больше потребуется чипов. В случае со стандартными модулями классика – это х8, х16 используется несколько реже, х4 значительно реже. Получается, что в x4 чипах есть только 4 линии данных (+ диффпара DQS + DM/DBI), в x8 – то же самое, но 8 линий данных, а в х16 – два таких набора (то есть, 8 линий данных, DQS и DM/DBI – и так два раза в одном чипе). Если абстрагироваться от емкости чипов – то куда проще использовать x16 чипы, ибо их меньше – значит меньше точек подключения адресно-командной шины к чипам (чуть меньше ломается сигнал), больше расстояние между чипами (удобнее согласовывать, ибо больше места).
Ранее говорилось про «ранги» модуля памяти. Доводилось ли читателю видеть планки памяти, на которых чипы установлены с двух сторон? Ну вот это оно и есть (речь про обычные DIMM). То есть, на одних и тех же контактах шины данных может сидеть два чипа, и не запутывается контроллер памяти только благодаря рангозависимым линиям адресной линии (те же CS0/1, например). Зачем это надо? Увеличение максимального объема планки, в основном. Но трассировка становится труднее – ибо учитывать приходится уже два чипа на одной и той же линии, а не один.
Стоит понять, что такое fly-by и point-to-point. Это – тип подключения Master устройства к другим микросхемам. Point-to-point – подключение от точки к точке. Проще всего привести примеры – это PCIe, UART и так далее, то есть, соединение только между двумя микросхемами (или микросхемой и коннектором). Fly-by же соединяет Master с несколькими микросхемами, подключаясь каждой из своих линий к каждой микросхеме последовательно. Пример – тот же I2C или SPI.
А в DDR4 есть оба вида подключения, для линий данных – point-to-point, от процессора до слота, от слота до чипа памяти. Один источник, один адресат (линии двунаправленные, но не суть). Адресно-командная шина, в свою очередь, относится к fly-by, проходя от слота всеми линиями сначала до первого чипа, от него ко второму и так далее до последнего, после чего эти линии идут на «хвостовую терминацию». В итоге линии данных получаются довольно короткими и согласуются относительно просто (в случае однорангового модуля уж точно), но адресно-командные линии проходят через всю длину планки, и при их согласовании уже возникают трудности.
4) Практические рекомендации
Начнем с p2p-шины, то есть, шины данных. Как и было сказано, для всех линий на ней требуется установка резисторов по 15 Ом рядом со слотом (в случае с планкой). Ставить можно одиночные, сдвоенные (0404) или счетверенные (0408) резисторы, но важно помнить о том, что посадочное место у последнего варианта не очень равномерное (крайние контакты толще внутренних), из-за чего он не очень хорошо подходит для DQS (может дать перекос по задержке, что для дифференциальной пары хуже, чем для одиночных линий в шине).

Линия до резистора и после нее – считается одной и той же, а значит и согласовывать нужно эти линии целиком. Чтобы xSignals (инструмент Altium Designer) считал общую задержку на всей протяженности можно применить один «костыльный» метод: в схеме назначить одинаковую сетку на оба конца резистора, и закоротить эти резисторы на плате (просто нарисовать прямые линии одинаковой ширины под каждым). И теперь можно спокойно создавать класс xSignals от краевого слота до чипа памяти и видеть суммарную задержку линии. И да, крайне важно не забыть об этом, чтобы перед завершением проекта убрать эти перемычки в плате и схеме (или сделать копию проекта с пометкой final, чтобы сохранились данные по задержкам).
Теперь к fly-by шине, то есть, адресно-командной. Критически важно, чтобы все сигналы одной шины от источника доходили до чипа единовременно, и так с каждым чипом. То есть, задержка на каждом участке должна быть одинаковой. Участков тут несколько: процессор – краевой слот, краевой слот – первый чип памяти, первый чип – второй чип, <…>, последний чип – терминационные резисторы.
Настроить это довольно просто. Для каждого чипа придется повторить одинаковый алгоритм действий: xSignals Wizard, первым компонентом нужно выбрать краевой слот, вторым – первый чип памяти. Сетки –все, что указано в списке контактов адресно-командной шины (кроме alert и reset, их согласовывать по задержке нет нужды). Кстати, в случае с двухранговым модулем классов будет в 2 раза больше, так чип снизу – другой компонент, да и часть сеток там другая – CK, CS, CKE, ODT – рангозависимые. Следом – настройка правила High Speed (переход в задержки, указание допуска и целевой линии). И вот, можно проводить линии и согласовывать участок между слотом и чипом памяти.
Но тут есть маленькая ловушка. Задержку до каждого чипа нужно согласовать. Но что именно учитывать? Например, от общей шины отходят переходные отверстия до каждого чипа – надо ли их учитывать для последующих? И тут на выручку приходит…xSignals. Он полезнее, чем может показаться, ибо в расчете задержек в окне PCB – xSignals участвуют только те элементы топологии, через которые сигнал идет от конкретного компонента до конкретного компонента. То есть, для последующих чипов памяти учитываться fanout (дорожки на внешних слоях около BGA-микросхем и переходные отверстия для них) от предыдущих не будут, и это – правильно, так как для трассы они являются stub’ом, а не последовательной задержкой. Поэтому для последующих чипов необходимо настраивать классы xSignals так же от слота до чипа, и никак иначе.

Даже в случае с последним участком – от последнего чипа до терминационных резисторов нужно выбрать источником слот, а конечным компонентом…резисторы? Да, тут проблема, xSignals плохо работает с множественными компонентами. Поэтому можно создать библиотечный PCB-элемент, что будет состоять из этих резисторов. Да, снова «костыли», может есть решение изящнее, но оно работает. Для этого достаточно скопировать все эти резисторы разом, вставить в библиотеку pcblib, создать элемент. Если есть желание – можно собрать и УГО, чтобы подключить к правильным сеткам. Если нет – можно подключить сетки вручную. И вот этот «элемент» уже можно указывать конечным при настройке класса xSignals. Только рекомендуется не ставить его поверх настоящих резисторов хвостовой терминации, ибо иногда Altium отказывается адекватно считать задержку (почему – вопрос хороший). Тут, как и с закорачиванием резисторов на линиях данных, главное не забыть потом вернуть все на место. Еще один момент – номиналы этих резисторов. 39-50 Ом, подключать вторым концом к VTT. Для CLK между VTT и резисторами нужен конденсатор (да, для обеих линий – один, так как вторые концы резисторов терминации CLK соединяются). А вообще – лучше поискать схему, у Altium есть встроенные примеры и там лежит проект SO-DIMM планки, многие моменты подходят.
Немного про задержку в микросхемах. Если разрабатывается распаянная на материнской плате память – то процессор / контроллер / ПЛИС / что-то еще учитывать в общей задержке линий обязательно. Сами же чипы памяти – в целом, игнорировать можно, если читатель согласен снизить потенциальный бюджет на 3-5 пикосекунд из-за разброса (а обычно примерно такой разбег там и встречается). Но лучше попытаться добыть документацию от производителя, если это возможно.
5) Конкретные цифры и буквы
Теперь конкретные данные. Сначала – немного удивления. Шина данных –адекватная, опорой для нее является земля. А вот адресно-командная шина…она особенная, ведь опорой для нее является питание VDD. Это не автор придумал, так написано в официальной документации JEDEC (DDR4 SDRAM UDIMM Design Specification, JEDEC Standard No. 21C). Поэтому по обе стороны (по слоям) от шины данных крайне рекомендуется располагать цельные полигоны земли, а от линий адресно-командной шины – VDD.
Требования к импедансу. Одиночные линии – 40-55 Ом, дифференциальные пары – 70-93 Ом (допуск выглядит слишком большим, но все из того же документа JEDEC). Задержка…удачи, общих истинных значений нет. Intel пишет одно, AMD – другое, иные производители – третье и так далее. Поэтому лучше держать в голове допуск в 10 пикосекунд для шины данных и 20 пикосекунд для адресно-командной шины. Миллиметров тут не будет, почему – рассказано в предыдущей статье. На самом деле допуски по задержкам зависят от планируемой рабочей частоты. Эти вот приведены для скорости 3200 Мбит/сек, в ином случае может быть больше/меньше.
6) Описание всех линий DDR4
В адресно-командную шину входят следующие линии:
CK_t/CK_c. Это дифференциальная пара (_t = P, c = _N), является линией синхронизации для адресно-командной шины. Обычно их две – CK0 и CK1 – используются для двух рангов.
CKE – сигнал, управляющий состоянием памяти. 1 – нормальное функционирование, 0 – игнорирование команд, Power-Down или SelfRefresh. Есть CKE0 и CKE1 для двух рангов.
CS – сигнал chip select, чип игнорирует все при CS = 1. Используется для выбора рангов в многоранговых системах, CS0 активирует нулевой ранг, CS1 первый.
ODT – сигнал, включающий или выключающий On-Die-Termination для линий данных (сигналов DQ, DQS, DM). Тут снова есть ODT0/1
ACT – сигнал активации команды (команды задаются через RAS/CAS/WE). При одном состоянии ACT контакты A16, A15 и A14 воспринимаются как адресные. При другом – эти контакты принимают сигналы RAS/CAS/WE соответственно.
BG0/BG1– Bank Group, часть системы адресации чипа памяти (чипы обычно имеют 4 группы банков), по сути – «старшие биты» адреса.
BA0/BA1 – контакты, отвечающие за адресацию к банку внутри группы банков, «промежуточный» элемент адреса между группой банков и адресом ячеек.
A0-A17 – адресные контакты для доступа к ячейкам внутри банка памяти. Контакт А17 не нужен в случаях, когда емкость чипа меньше 4ГБайт. Некоторые контакты (А10-12, А14-16) мультиплексированы с дополнительными функциями, так что их необходимо подключать вне зависимости от объема чипа.
RAS/A16 – комбинированный контакт, в зависимости от состояния ACT является адресным A16 (при 0) или командным (при 1). RAS (Row Adress Strobe) является одним из трех командных контактов этой группы (RAS, CAS, WE).
CAS/A15 – комбинированный контакт, в зависимости от состояния ACT является адресным A15 (при 0) или командным (при 1). CAS (Column Adress Strobe) является одним из трех командных контактов этой группы (RAS, CAS, WE).
WE/A14 – комбинированный контакт, в зависимости от состояния ACT является адресным A14 (при 0) или командным (при 1). WE (Write Enable) является одним из трех командных контактов этой группы (RAS, CAS, WE).
BC/A12 – Burst Chop – функция, позволяющая управлять количеством тактов передаваемых данных. Стандартная длина – 8 тактов (речь именно о временной шкале, ширина канала управляется иначе). Если BC = 1, то последовательность данных режется до 4 тактов. При 0 длина остается стандартной – 8.
AP/A10 – Auto-Precharge – переключение «предзаряда» на используемом банке или на всех банках чипа. При AP = 1 предзаряд идет на всех банках, при 0 – только на выбранном (на всех нужно в основном для refresh).
PAR – однобитный Parity сигнал, проверка на четность для адреса/команд, эдакая примитивная CRC.
ALERT – многофункциональный контакт, но в UDIMM почти всегда несет только две функции. Первая – проверка CRC данных (по DQ после burst – обычно 8 тактов – контроллер памяти шлет контрольную сумму отправленных данных). Вторая функция – сигнализация о несовпадении Parity по командам/адресу.
Reset – классический reset, активен при 0, в стандартном состоянии должен быть 1 для адекватного функционирования чипа. Подтяжка не требуется. НЕ требует согласования с остальной шиной, но импеданс и возвратный путь – надо.
Теперь – про шину данных:
DQ0-7– контакты двунаправленной шины данных. Нуждается в последовательном резисторе рядом с контактными площадками самой планки (около 15 Ом). Можно менять линии местами внутри младшей и старшей половин байта (DQ0-3 и DQ4-7) одного чипа, но не между этими половинами.
DQS_t/DQS_c – отдельный тактовый сигнал (строб) для линий данных. Является дифференциальной парой, уникален для каждого байта (в х16 конфигурации есть DQSL и DQSH для младшего и старшего байтов), следовательно, линии DQ согласуются с длиной/задержкой именно этого сигнала. Последовательные резисторы по 15 Ом так же востребованы.
DM/DBI/TDQS_t – содержит несколько функций. DM – Data Mask – при 1 данные на конкретном байте не будут записаны в память, DQ игнорируются. При 0 все пишется как обычно. DBI – Data Bus Inversion – используется для экономии энергии при передаче сигналов (например, если в байте единиц больше половины – DBI устанавливается в 1, передаваемые данные инвертируются). TDQS – НЕ используется в UDIMM от слова совсем. Последовательный резистор на 15 Ом тоже нужен.
TDQS_c – TDQS – НЕ используется в UDIMM от слова совсем, поэтому TDQS_c игнорируется и не подключается.
Комментарии (34)

nerudo
24.04.2026 18:14Скажите, если на двухранговых модулях чипы паяются с двух сторон печатной платы, то на 4-ранговых как, с 4 сторон?

Mirakuru77 Автор
24.04.2026 18:144 ранга в стандартном декстопном сегменте в контексте DDR4 не может быть, это строго серверные RDIMM и так далее. На стандартном коннекторе DIMM есть контакты только под два ранга.
За DDR4 RDIMM или DDR5 говорить не могу, так как не занимался изучением этих интерфейсов и не работал с ними.
Пояснение про 2 стороны было преведено чисто с обывательской точки зрения, так проще понять о чем идет речь.
BenderA
24.04.2026 18:14А нельзя было все эти "ранги" объяснить проще, например, исходя из названия сигнала — CS это chip select? Сильно проще для понимания.

ibagdona
24.04.2026 18:14В сокете DDR4 всего есть 5 линий для выбора ранков не зависимо от типа исполнения (UDIMM/RDIMM/NVDIMM): CS[3:0] для внешних, они one-hot, и C[2:0] для внутренних, они декодируются. CS[3:2] совмещены с C[1:0], в итоге получается от 4 внешних до 2 внешних с до 8 внутренних ранков. Модули на 4 ранка могут быть собраны как из SDP корпусов (для x8: две стороны по два ряда), так и из MDP корпусов, больше 4-х ранков - только из MDP, максимально до 16 ранков.

vanxant
24.04.2026 18:14Там кристаллы клеятся друг на друга. Поскольку процессор рассчитан по нагрузочной способности на не более двух чипов на линию, приходится ставить промежуточный регистр, который сам по себе вносит задержку не менее одного такта. Поэтому обычно лупят от души, делают пироги из сразу 8 чипов. Такая память называется регистровой (RDIMM). Это сугубо серверная история. когда нужно вонзить пару терабайт ОЗУ.
Ну или не клеят, а ставят типа так (это планка на 128 Гб):


melodictsk
24.04.2026 18:14А можно с таких планок переставить чипы на обычные не регистровые? Учитывая, что бу северные планки стоят значительно дешевле обычных. Или там и чипы другие?

StpMA
24.04.2026 18:14Почему конденсаторы для VTT на модуле памяти ставятся между VTT и VDD ? Почему не между VTT и GND? Посмотрел несколько примеров модулей. Там один сплошной слой VDD, а GND собирают из кусочков. Получается для CMD/ADDR опорный слой VDD. Но, допустим, у меня собственная плата (не DIMM) на которой стоит и контроллер и память. Много сплошных слоев GND и один VDD. Опорный слой для всех сигналов GND. Не лучше и проще подключать конденсаторы между VTT и GND ?
Аналогичный вопрос про CK_t/CK_c .

HardWrMan
24.04.2026 18:14Я вангую, что подключают там, где больше выбросов тока. Вот выходные драйверы шины данных - они мощные, а значит и ток большой, особенно если надо продавливать длинную шину. Наверное, в этом основной смысл в принципе иметь такое разделение не только питания но и земель.

sim2q
24.04.2026 18:14А вот адресно-командная шина…она особенная, ведь опорой для нее является питание VDD
Всякие SPI (I2C,SWD..) так веду для экономии. Две витых пары, одна с землёй, вторая с питанием, только на концах между питанием и землей надо по конденсатору строго. Приветствуется если кто то поправит если что.

YDR
24.04.2026 18:14Да, для низкоскоростных это проходит. А то, что VDD используется как опора - это похоже на PECL, для избранных сигналов использовать чуть менее шумный + питания.

StpMA
24.04.2026 18:14Stub Series Terminated Logic (SSTL) , оно же Center Tapped Termination (CTT) для всего в DDR3. В DDR4 SSTL для CMD/ADDR , и POD для DQ/DQS. SSTL - push-pull, почему тут VDD предпочтительнее чем GND ?

Mirakuru77 Автор
24.04.2026 18:14Использование VDD как опоры для CA-шины - это требование JEDEC в их документации на DDR4, вероятно, связано с особенностями устройства блока ввода-вывода контроллера памяти и самих чипов. Тут конденсаторы на землю особо не участвуют в передаче возвратного тока. Более того - на высоких частотах конденсатор такую роль просто не может исполнять из-за роста его индуктивности.
Касательно SPI/I2C/SWD - не то, чтобы для них нужна была адекватная опора, если линии не метровые. С SPI только опора желательна, если частоты выходят за 10 МГц.

keplergk104
24.04.2026 18:14Было бы здорово если бы кто то разработал переходник с M.2 nvme ssd на sata и возможность объединять множество М2 ссд в один кластер в нем. Скорости сата3 будет достаточно чтоб найти применение 128-256гб дискам для файлохранидища.

Mirakuru77 Автор
24.04.2026 18:14Переходник PCIe-SATA - есть такая штука как ASM1166/1164. Есть и в виде платы M2 с SATA-коннекторами.
А вот разветвление PCIe на несколько отдельных линий - вопрос открытый. Нужен или хаб, что умеет дробить одну линию на несколько (но тогда от x4 останется x1 по пропускной способности), или пытаться разделить эти x4 на 4 по x1, добавив генератор REFCLK для каждой из этих линий. Но PERST тоже как-то надо делить (участвует в инициализации интерфейса), да и вряд ли какая десктопная система умеет дробить одну шину на несколько.
VADemon
24.04.2026 18:14поздние AM4 все должны уметь в PCIe bifurcation и всё что новее тоже. Intel еще до того эксперементировал с этим, например консьюмерские гибридные Optane (SSD+Optane), как я понял, работают на 2x+2x. Только не уверен, это только фишка линий отведенных на M.2 или все линии умеют в bifurcation.

Konstantin-2
24.04.2026 18:14Спрашиваю из любопытства. Что будет, если обратиться к несуществующей памяти? Я знаю про то, что контроллер памяти не даст этого сделать. Но все же, если обмануть контроллер и сказать, что память (именно планка памяти) большого объема, а фактически такого объема нет, обманутый контроллер отправит планке запрос данных, но ни одна из микросхем памяти не ответит контроллеру, какие байты увидит процессор?

HardWrMan
24.04.2026 18:14Зависит от конкретной реализации схемы. От висячки шины до отзеркаленных данных существующей памяти.

Konstantin-2
24.04.2026 18:14Я правильно понимаю, что "отзеркаленные данные", это когда старшие биты отбрасываются и данные считываются из микросхем из адреса по младшим битам, которые действительно адресуют память, т.е. при обращении происходит зацикливание адреса? А что такое "висячка шины"?

HardWrMan
24.04.2026 18:14Да, верно понимаете. Что касается висячки то тут зависит от реализации. Если есть подтяжки то считается значение этой подтяжки. Если её нет, то считается значение предыдущей транзакции либо её искажённый фантом, всё зависит от паразитной ёмкости шины, которая будет удерживать это значение во времени.
PS Между прочим мироринг (от mirroring) использовался в одном из взломов PS3, где до закрытого ключа добирались именно используя факт отзеркаливания ОЗУ. При этом регистр безопасности не покрывал запретом на чтение эти зеркала. Позже Sony закрыла эту дырку.

DanilinS
24.04.2026 18:14Это когда шина висит в ожидании события ( строба данных), которое никогда не наступит.

Mirakuru77 Автор
24.04.2026 18:14Обмануть контроллер можно попытаться разве что из-под SPD, зашив другие данные. Но не исключено, что в процессе инициализации ОЗУ контроллер заметит отличие конфига памяти и SPD и просто откажется поднимать ее, выдав ошибку.

nerudo
24.04.2026 18:14Объем планки определяется не количеством микросхем (чаще всего их 8 по 8 бит, хотя их количество тоже может быть разным), а внутренним объемом чипов. Конртоллер обращается одновременно ко всем микросхемам по всем 64 битам данных (в рамках одного chip select, конечно - что называется ранком). Если обратиться за пределы адресного пространства микросхемы, то старшие биты адреса (там сложная поэтапная адресация, но в данном контексте это не важно) будут проигнорированы и произойдет доступ к соответсвующей нижней части адресного пространства.
Если какая-то из микросхем памяти внезапно перестала отвечать на запросы, то на соответсвующих разрядах данных будет значение шины по-умолчаню, обусловленное электрическим стандартом. Для DDR4 это вроде как high, т.е. 1. Для каких-то была половина напряжения питания, т.е. может быть случайное значение.

ibagdona
24.04.2026 18:14В общем случае это хрупко и очень платформозависимо. Обработка ошибок протокола DDR - это довольно больно. Детали зависят от конкретного протокола (для DDR4 и DDR5 логика похожая, но реализация значимо разная), и также от конкретной реализации конкретного вендора, вплоть до различий от ревизии корпуса. При ошибке протокола будет выставлен сигнал ALERT, заполнены конкретные MR, и проигнорированы команды, которые были в полете до появления ошибки (после ALERT на DQ не будут данных для чтения, и также посланные в DQ данные записи будут тихо проигнорированы без записи). Надо вычитывать MR и смотреть, где была проблема - там будут записана копия сигналов, которые не понравились корпусу. Итого для DDR4 не будет прочитано ничего, команда прервется до фазы DQ - это на логическом уровне. На физическом уровне DQ подтянуты вверх и вниз, итого другой конец будет видеть idle сигнал в то время, когда там должны были быть данные от чтения. Часто, но не всегда и не везде есть соглашение чтение idle интерпретировать как -1 по ширине запроса - если такой запрос надо отдать дальше, а не сигнализировать ошибку. Но нельзя это принимать как правило - при корректной работе протокола idle в нужные временные интервалы там не может быть. С DDR5 такое симитировать довольно просто на корпусах по 24Gbit - у них ограничение по значениям верхних битов строки. С DDR4 будет сложно - там все в степени 2, корпуса меньшего объема просто игнорируют верхние линии адресов, и доступ будет по модулю реальной емкости без ошибок.
Есть простор для обмана в отображении адресного пространства на сокет, и вот здесь не сложно намеренно присвоить регион на пустой ранк в сокете. Но это будет замечено во время калибровки, и для такого эксперимента нужна платформа, которая может игнорировать калибровку. Тогда при команде чтения на DQ будет idle из-за подтяжки на стороне приемника, и опять по соглашению часто будет получено -1. Запись будет тихо проигнорирована.

Ocelot
24.04.2026 18:14Чтобы xSignals (инструмент Altium Designer) считал общую задержку на всей протяженности можно применить один «костыльный» метод
Альтиум умеет строить xSignals через несколько компонентов, костыли не нужны


Mirakuru77 Автор
24.04.2026 18:14Значит я не до конца разобрался. Вполне нормальная ситуация, наличие пробелов очевидно.
Спасибо за подсказку, теперь работать будет значительно удобнее)
Ocelot
24.04.2026 18:14Либо у вас старая версия, но он так умеет уже года два точно.

Mirakuru77 Автор
24.04.2026 18:1424.4. Но, скорее всего, это моя ошибка, ибо xSignals я осваивал именно под проект планки DDR4. Занимался этим делом в начале этого года (заработало, кстати, с первой попытки). До этого вообще страдал с excel файлом для задержек/длин линий.
Увы, предоставлен сам себе, поэтому многие фичи САПР открываются для меня под соусом "а так можно было?!"
Lagovi
24.04.2026 18:14многие фичи САПР открываются для меня под соусом
Gemini говорит что хорошо знает Altium Designer, пробовали спрашивать?
NickDoom
Что ж вы, люди, творите. Вы ж можете вместе мир перевернуть…
Интересно, кстати, реалистична ли моя мечта — «видеокарта-утилизатор» для кучи мелких DDR (сейчас уже это будет DDR4, конечно). Ящик или ноут апнули, мелкую планку вынули, добавили в видеокарту. А там какие-нибудь дешманские GPU, которые умеют с ней работать, но их очень много и у каждого — один десктопный слот памяти и два бучных :)
Я про аппаратную сторону вопроса. То, что на уровне драйвера это всё заставить работать и балансировать нагрузку — «задачка-неберучка», я не буду спрашивать :)
Mirakuru77 Автор
Теоретически - возможно, если найдется чип GPU совместимый с DDR4. На практике, увы, есть два затыка: стоимость платы в малой серии будет порядочной. И главное - документация на GPU, достать ее будет трудно.
0xdead926e
емнип у нвидии последними совместимыми с ддр4 были паскали. но там уже нельзя редактировать прошивку, поэтому облом.
p0isk
Была похожая идея для битых планок памяти, которые вообще ничего не стоят. Создаётся материнка с 8-16-32 слотами под них. В качестве контроллера плис, интерфейс общения usb/sata/pci-e. Контроллер точно так же, как и в жёстких дисках хранит информацию о битых адресах и перенаправляет запись в резевную область. Цель - быстрый относительно накопителей и дешёвый относительно озу кэш.
sim2q
Мне кажется с них просто сдувают норм чипы и собирают из них рабочие планки. Не знаю про характер повреждения в битых чипах, было что то вроде в linux когда блок специально помечался и не использовался. Но есть ли гарантия, что остальные ячейки со временем будут стабильны.
ToSHiC
Такая фича с перенаправлением есть прямо внутри чипов памяти, называется Post Package Repair. Бывает 2 видов: персистентная, и soft - до следующего ребута.