Задать вопрос
@EvgenySbl

Как должен выглядеть регистр указателя стека на Verilog?

У меня вопрос по программированию на Verilog и счетчику стека в котором будет хранится контекст процессора, т.е. набор его регистров.

Не так давно, посетила мысль написать на Verilog несложный процессор. И вроде бы все относительно просто. Просто до того момента как начинаешь оптимизировать.

Итак. Предположим в процессор закладывается набор регистров, и предполагается некоторое ABI, похожнее на ARM-овское. Первые четыре регистра это аргументы и результат функции, а оставшиеся,- контекст функции. Все равно при вызове функции как правило эти регистры укладываются в стек, т.е. выполняется команда stmia sp!, {r4-r1x,lr}, или push {r4-r1x,lr}. Вообще говоря эта инструкция приводит к приращению указателя стека. О нем и поговорим.

Предположим, преследуя цели защиты контекста функции я решил сохранять эти регистры аппаратно, в отдельный стек. А преследуя цель увеличения производительности, решил еще и сделать отдельные стеки для каждого регистра, но с общим указателем.

Это удобно. Поменял указатель (из специального режима) сделал call и вот ты в новой функции или даже задаче, или прерывании. В этом случае, у каждого регистра своя шина данных и шина адреса, связанная с регистром указателя стека. Они параллельные, а значит быстрые.

Доступ к обычному стеку (как к сегменту памяти) сохраняется для типовых задач. А этот фактически хранит лишь контекст функции/задачи/прерывания.

Насколько я понимаю среди блоков процессора на фабриках, можно найти SRAM, причем даже с отдельными шинами данных и адреса для чтения и записи.

Если с памятью все понятно, то с адресом все немного сложнее. Когда процессор выполняет команду push, следует иметь адрес следующей ячейки в текущем такте работы процессора.
Когда он выполняет команду pop, следует иметь предыдущий адрес, т.к. данные необходимо забрать из памяти. Если конечно планируется сделать это за один такт.

Да, конечно, можно реализовать реверсивную цепочку регистров и это будет быстрее, но у этого есть свои минусы. Во-первых вырастет динамическое энергопотребление, т.к. все триггеры одновременно переключаться. Во-вторых в этом случае не будет указателя стека и процессор станет "однозадачным" + "прерывания" в контексте текущей задачи.

Кроме того, столько триггеров в FPGA для моделирования, наверное нет. Конечно, для маленького МК, можно сделать короткий стек на несколько вызовов. Было что-то подобное в AT90S1200 для регистра PC (call/ret). Там 8 кажется, если не изменяет память. Только сохраняем все регистры общего назначения, не задействованные в передаче аргумента и возвращении результата, включая PC.

Что-то подсказывает что память как готовый блок использовать выгоднее.

Идеи описаны. Вернемся к вопросам реализации. Итак, имеем регистр SP. Фактически, для операций push и pop, требуется иметь сразу два адреса оиличающихся на единицу.

Но при операции push, в начале такта требуется значение на единицу больше, чем при операции pop. Т.е. сигнал WR, в текущем такте должен быть сформирован с соответствующим адресом. А сигнал RD, с другим.

Приращение счетчика, это сумматор. Сумматор использует схему переноса, а значит будет выполнятся в течение некоторого времени.

Если не задумываться о таймингах, то можно сделать реверсивный счетчик и сумматор. Это и будут адреса для чтения и записи. Или нет?

Реверсивный счетчик, это сумматор с числом 1 или 0xFFFF(F), в зависимости от того инкрементируем адрес или нет. Т.е. получается что все биты кроме нулевого меняются. Сумматор задействует схемы переноса разряда, а значит это приводит к некоторой задержке. После сумматора счетчика, нужен еще один сумматор.
Если не конвейеризовать операции сложения и мультиплексирования результата, то уменьшается тактовая частота.

Теперь вопрос.
Получается, чтобы счетчик указателя стека работал быстро, в действительности требуется держать два счетчика, и просчитывать их значения заранее? Т.е. по факту нужны три регистра: значение, значение + 1, значение -1? Или даже еще значение +2?

Неужели, в процессорах, такой простой элемент как счетчик настолько серьезно конвейеризируется? Как это реализуется в серьезных изделиях?
  • Вопрос задан
  • 262 просмотра
Подписаться 2 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
@punzik
Если отвечать на вопрос, а не на очень длинное введение (спорное), то ответ такой:

Счётчик по определению содержит в себе сумматор, как минимум +1 (конечно, если мы говорим о двоичном счётчике в дополнительном коде). В сумматоре используются схемы быстрого параллельного переноса, по этому он обычно работает без дополнительных ухищрений на целевой частоте.

Дополнительные счётчики, как вы предлагаете, ничем не помогут, потому что на следующем такте снова понадобится -1, +1 и +2, только теперь на единицу больше. Как минимум один счётчик всё равно должен считать.

Ну и вы по-моему не с того края начали оптимизировать. Почитайте книжку Харрисов, там разбирается типичный подход к разработке микроархитектуры.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы