Для чего нужен счетчик команд
В счетчик команд (ПК), обычно называемый указатель инструкции (IP) в Intel x86 и Itanium микропроцессоры, а иногда называли регистр адреса инструкции (IAR), [1] то счетчик команд, [2] или просто часть последовательности команд, [3] это регистр процессора это указывает, где компьютер находится в его программа последовательность. [nb 1]
Обычно ПК увеличивается после получения инструкция, и держит адрес памяти из («точки to «) следующая инструкция, которая будет выполнена. [4] [nb 2]
Процессоры обычно последовательно извлекают инструкции из памяти, но передача управления инструкции изменяют последовательность, помещая новое значение в ПК. Они включают ветви (иногда называемые прыжками), подпрограмма звонки и возвращается. Передача, обусловленная истинностью некоторого утверждения, позволяет компьютеру следовать другой последовательности при разных условиях.
Ветвь обеспечивает выборку следующей инструкции из другого места в памяти. Вызов подпрограммы не только разветвляется, но и сохраняет где-то предыдущее содержимое ПК. Возврат извлекает сохраненное содержимое ПК и помещает его обратно в ПК, возобновляя последовательное выполнение с инструкцией, следующей за вызовом подпрограммы.
Содержание
Аппаратная реализация
Как и другие регистры процессора, ПК может представлять собой набор двоичных защелок, каждая из которых представляет один бит значения ПК. [8] Количество бит (ширина ПК) зависит от архитектуры процессора. Например, «32-битный» ЦП может использовать 32 бита, чтобы иметь возможность адресовать 2 32 единиц памяти. На некоторых процессорах ширина программного счетчика зависит от адресуемой памяти; например, некоторые Контроллеры AVR есть ПК, который оборачивается после 12 бит. [9]
Если ПК является двоичным счетчиком, он может увеличиваться при подаче импульса на его вход COUNT UP, или CPU может вычислить какое-то другое значение и загрузить его в ПК с помощью импульса на его вход LOAD. [10]
Чтобы идентифицировать текущую инструкцию, ПК может быть объединен с другими регистрами, которые идентифицируют сегмент или страница. Этот подход позволяет ПК иметь меньше битов, предполагая, что большинство интересующих модулей памяти находятся в непосредственной близости от него.
Последствия для машинной архитектуры
Использование ПК, который обычно имеет приращение, предполагает, что компьютер выполняет обычно линейную последовательность инструкций. Такой ПК занимает центральное место в фон Неймана архитектура. Таким образом, программисты пишут последовательный поток управления даже для алгоритмов, которые не обязательно должны быть последовательными. Результирующий «узкое место фон Неймана»Привели к исследованиям в области параллельных вычислений, [11] в том числе не фон Неймана или поток данных модели, в которых не использовался ПК; например, вместо того, чтобы указывать последовательные шаги, высокоуровневый программист может указать желаемый функция и программист низкого уровня может указать это, используя комбинаторная логика.
Это исследование также привело к способам ускорения работы обычных ЦП на базе ПК, в том числе:
Последствия в высокоуровневом программировании
Однако новые модели программирования выходят за рамки программирования с последовательным выполнением:
Символ
Поставщики используют разные символы для обозначения счетчика программ в язык ассемблера программы. Хотя использование символа «$» преобладает в Intel, Зилог, Инструменты Техаса, Toshiba, NEC, Сименс и AMD документация процессора, Motorola, Rockwell Semiconductor, Технология микрочипов и Hitachi вместо этого используйте символ «*», [9] в то время как SGS-Thomson Microelectronics использует «ПК». [9]
Счетчик команд,
РЕГИСТРЫ ЦП
Основу большинства ЦП образуют рабочие регистры.
Регистры представляют собой сверхоперативное ЗУ небольшой емкости.
Регистры состоят из триггеров и адресуются подобно ячейкам памяти. Как правило, разрядность регистров совпадает с разрядностью процессора. Число регистров невелико.
Использование в программе рабочих регистров выгодно, так как ЦП может получить содержащиеся в них данные, не обращаясь к памяти.
С помощью внутренних шин регистры связаны друг с другом. С другими блоками системы связь осуществляется под управлением программы.
Если ЦП имеет большое число регистров, программе не потребуется большого числа пересылок данных в память и из памяти. Благодаря этому уменьшается число операций обращения к памяти и формат команд.
Наличие большого числа внутрипроцессорных регистров приводит к расширению возможностей дешифрирования и адресации команд и данных.
На рис.1.1.5 показан типовой набор регистров ЦП.
Регистры могут иметь много различных назначений.
Процессоры содержит несколько основных регистров:
— регистр команд,
— регистр адреса памяти,
— аккумулятор,
— регистры общего назначения (РОН).
-индексные регистры,
-регистр условий,
— указатель стека.
Счетчик команд (СК) содержит адрес ячейки памяти, в которой находится очередная команда.
Цикл выполнения команды начинается с того, что ЦП посылает содержимое счетчика команд в шину адреса; таким образом ЦП извлекает из памяти первое слово команды.
При этом увеличивается на единицу содержимое счетчика команд и, таким образом, в следующем цикле команды из памяти будет извлечена следующая из последовательности команд.
Регистр команд сохраняет код команды до тех пор, пока она не будет дешифрирована.
Регистр адреса памяти содержит адрес данных в памяти. Адреса могут представлять собой часть команд или данные.
Аккумуляторы— это регистры временного хранения, которые используются в процессе вычисления. В аккумуляторе всегда содержится один из операндов арифметических операций. Процессор может также использовать аккумуляторы при выполнении логических операций.
Регистры общего назначения выполняют различные функции. Они могут служить в качестве регистров временного хранения данных или адресов. Программисту предоставляется возможность определять их как аккумуляторы или как счетчики команд.
Индексные регистры используются для адресации данных. Содержимое индексного регистра складывается с адресом ячейки памяти, который содержится в команде. Затем сумма образует действительный адрес данных и исполнительный адрес.
Если содержимое индексного регистра изменяется, одна и та же команда может быть использована для обработки данных из ячеек памяти с различными адресами.
Радиолюбитель
Последние комментарии
Радиодетали – почтой
Регистры общего назначения, регистры ввода/вывода, стек, счетчик команд
Регистры общего назначения, регистры ввода/вывода, стек, счетчик команд
Процессорное ядро микроконтроллеров:
— регистры общего назначения
– регистры ввода/вывода
– стек
– счетчик команд
Доброго дня уважаемые радиолюбители!
Приветствую вас на сайте “ Радиолюбитель “
Сегодня мы с вами продолжим более подробное изучение процессорного ядра микроконтроллера.
В прошлый раз мы рассмотрели арифметико-логическое устройство и организацию памяти микроконтроллера. В этой статье я постараюсь кратко, но и в тоже время как можно подробнее рассмотреть оставшиеся вопросы:
— регистры общего назначения
– регистры ввода/вывода
– стек
– счетчик команд
и очень подробно, но чуть позже, рассмотрим порты ввода/вывода.
Регистры общего назначения
Надо помнить, что физически РОН (как и рассматриваемые ниже регистры ввода/вывода) не входят в память данных, но для повышения эффективности работы МК и его производительности, РОН (и регистры ввода/вывода) располагаются в адресном пространстве памяти данных, и к ним можно обращаться как по их именам, так и как к ячейкам памяти ОЗУ (SRAM).
Так как все РОН восьмиразрядные (однобайтовые) то и оперировать они могут только с однобайтными данными. В случае, если необходимо проводить операции с двухбайтными данными (шестнадцатиразрядными), то РОН с R26 по R31 могут образовывать сдвоенные регистры, которые в свою очередь могут выступать в роли самостоятельных шестандцатиразрядных регистров и тогда они имеют другие имена (такие сдвоенные регистры иногда называют “словом”, по аналогии с ячейками памяти программ):
R26 и R27 – сдвоенный регистр “Х”,
R28 и R29 – сдвоенный регистр “Y”,
R30 и R31 – сдвоенный регистр “Z”.
При этом первый регистр в такой паре (R26, или R28, или R30) играет роль младшего байта и обозначается дополнительной буквой “L”. Например: XL, YL, ZL.
Второй регистр в паре играет роль старшего байта и обозначается дополнительной буквой “H”. Например: XH, YH, ZH.
Это позволяет нам записать (или считать значение), к примеру, двухбайтовое число непосредственно в двойной регистр, обратившись к его буквенному обозначению X, Y или Z, а также считать любой байт (или записать в любой байт) выбрав буквенное обозначение младшего или старшего байта двойного регистра (к примеру XL или XH).
Кроме того необходимо помнить, что хотя и все регистры общего назначения одинаковы, но не все из них могут участвовать в некоторых операциях. При этом, регистрам с R16 по R31 доступны все операции, а регистрам с R0 по R15 – не все.
И еще. В некоторых МК (Tiny) двойной регистр только один – Z (R30,R31).
В описание каждой команды указывается, какие РОН могут участвовать в данной операции, к примеру:
Регистры ввода/вывода
Как мы уже знаем, в МК присутствует много различных периферийных устройств. Кроме них, в МК есть и внутренние устройства. Всеми этими устройствами необходимо управлять, задавать необходимые режимы работы. Для этих целей в МК существуют регистры ввода/вывода.
Еще раз напомню, что хотя РОН и РВВ выделяется место в памяти данных, но доступное пространство памяти данных для нас от этого не уменьшается, ведь физически они там не располагаются. Если написано, что МК имеет память данных 128 байт, то значит мы можем использовать эти 128 байт в своих целях. Просто первый адрес памяти данных будет начинаться не с нуля, как в памяти программ или энергонезависимой памяти.
Кусочек из таблицы регистров ввода/вывода (первое число – номер регистра, и оно же его адрес в адресном пространстве РВВ, в скобках указывается адрес регистра в адресном пространстве памяти данных, т.е. номер +32):
Назначение и работу РВВ мы будем изучать постепенно, по мере изучения работы устройств МК.
Следующую статью мы посвятим изучению одного, но самого главного, чаще всего используемого в программах – регистру состояния, под названием SREG.
Стек
Стек, или указатель стека – это специальный регистр, который предназначен для организации стековой памяти.
Можно сказать, что стек (точнее стековая память, стек состоит из двух частей: указатель стека и стековая память) – это туннель с тупиком в конце, состоящий из ячеек памяти. По мере заполнения ячеек памяти первые данные уходят в глубь стека, и добраться до них можно, только вытащив сначала последние введенные данные. Допустим, если мы запишем в стек последовательно три числа: 10,20 и 30, то для того, чтобы затем извлечь из стековой памяти число 10, предварительно придется извлечь числа 30 и 20. Т.е., значение записанное последним всегда будет прочитано первым.
Стек широко используются не только МК в своих целях, но и программистами.
К примеру, при выполнении команды перехода к подпрограмме, МК самостоятельно записывает в стек адрес следующей команды, с которой будет продолжено выполнение основной программы после возвращения из подпрограммы. Возвращаясь из подпрограммы, МК извлекает этот адрес и загружает в счетчик команд, в результате чего выполнение программы продолжается с прерванного места.
Для нас тоже очень удобно сохранять в стеке данные при входе в подпрограмму, а затем извлекать их по возвращению из подпрограммы. Также удобно в стеке сохранять промежуточные результаты вычислений, а затем, по мере необходимости, извлекать их.
В микроконтроллерах, в которых отсутствует память данных (ОЗУ), а это часть МК семейства Tiny, стек организуется аппаратно. В таких МК стек располагается в собственной памяти а глубина его равна трем уровням. Аппаратный стек не доступен программисту, его в своих целях использует только сам МК, сохраняя в нем адреса команд при переходе к подпрограммам. Так как возможности аппаратного стека мы использовать в своих целях не можем, то на этом и закончим его изучение.
Во всех остальных МК, которые имеют память данных, стек организуется программно. Стек в этом случае не имеет собственной памяти а использует память данных (ОЗУ). Такой стек доступен для наших целей и рассмотрим его подробней.
Для организации процесса записи данных в стек и их чтения предназначен указатель стека.
В качестве указателя стека используются один или два регистра ввода/вывода:
– если память данных небольшая (до 256 байт), используется один восьмиразрядный РВВ – SPL;
– если память данных большая (более 256 байт), к первому РВВ – SPL, добавляется второй – SPH, и вместе они составляют один шестнадцатиразрядный указатель стека.
В указателе стека содержится адрес ячейки памяти, в которую будут записаны или считаны данные.
Для программиста в системе команд МК есть две специальные команды:
— PUSH – команда записи в стек
– POP – команда чтения из стека
Давайте рассмотри как происходит запись в стек и чтение из него.
Запись данных в стек:
Для того, чтобы записать данные в стек, их предварительно необходимо загрузить в любой РОН.
По команде PUSH МК записывает данные из указанного нами РОН в память данных по адресу, на который указывает указатель стека, а затем уменьшает содержимое стека на 1 (если указатель восьмиразрядный) или на 2 (если указатель шестнадцатиразрядный). Новая команда PUSH запишет данные в следующую ячейку ОЗУ и опять уменьшит содержимое указателя стека. И так, далее.
Чтение данных из стека:
По команде POP, МК сначала увеличивает содержимое указателя стека на 1 или 2, а затем считывает данные с ячейки ОЗУ, на которую указывает указатель стека. И так, далее.
После сброса МК содержимое указателя стека равно нулю. Т.е. получается, что после сброса, указатель стека указывает на нулевую ячейку памяти ОЗУ.
А теперь смотрите, что получится, если мы попробуем что-то записать в стек:
– первая команда PUSH – содержимое РОН будет записано в нулевую ячейку памяти,а затем МК попытается уменьшить содержимое стека на 1 или 2 – и ни чего не получится – адрес ячейки памяти не может быть меньше нуля!
Поэтому, прежде чем пользоваться стековой памятью, необходимо записать в указатель стека значение его вершины – адрес конечной ячейки памяти с которой начнется запись в стек.
Обычно вершиной стека указывают адрес последней ячейки памяти данных. Если у вашего МК ОЗУ составляет 128 байт, то указывают адрес 128 ячейки памяти. Под стек можно использовать всю память, если только вы не будете хранить в ней свои переменные. Если в качестве вершины стека вы укажите конечную ячейку памяти, то следить за стековой памятью в большинстве случаев не обязательно. А если вершиной стека указать ячейку памяти поближе к началу, и при этом использовать ОЗУ для хранения своих данных, то следить за размерностью стека придется – он может залезть на ячейки в которых вы будете хранить свои данные.
Счетчик команд
Счетчик команд – представляет собой регистр, в котором содержится адрес следующей исполняемой команды.
Размер счетчика команд может быть от нескольких разрядов до шестнадцати (двухбайтовый). Размерность счетчика зависит об объема памяти программ. Счетчик команд не доступен для программиста, в него мы не можем ничего записать и не можем из него ничего считать. Работой счетчика команд руководит единолично МК.
При включении питания устройства или сброса микроконтроллера, счетчик команд устанавливается в ноль, т.е. указывает на нулевой адрес памяти программ. Поэтому адресу начинается наша программа (если мы не используем прерывания) или адрес, по которому начинается наша программа (если мы используем прерывания). При нормальном ходе программы содержимое счетчика команд автоматически увеличивается на 1 или 2 (в зависимости от выполняемой команды) в каждом машинном цикле. Т.е., после выполнения команды, счетчик будет указывать адрес следующей команды. Этот порядок будет нарушен, если на пути МК при выполнении программы встретится команда перехода, команда вызова подпрограммы (или возврата из подпрограммы), а также при возникновении прерывания. В этом случае содержимое счетчика – адрес следующей команды, записывается в стек, а в счетчик записывается адрес по которому надо перейти по команде перехода или по прерыванию. По команде возвращения из подпрограммы, в счетчик записывается адрес команды сохраненный в стеке, программа продолжается дальше. Все это проделывается автоматически, без нашего участия.
В продолжении этой статьи, а точнее – окончании, мы очень подробно рассмотрим порты ввода/вывода микроконтроллера.
После этого, вся теория пойдет вперемешку с практикой. Легче понимать работу микроконтроллера разрабатывая практическое устройство.
Расскажу немного о том, что будет дальше.
После портов ввода/вывода мы начнем собирать цифровой вольтметр, попутно изучая и необходимые для этого теоритические вопросы.
Вольтметр я буду собирать на основе МК ATiny26 – самый подходящий (как мне кажется) для этого микроконтроллер. Для вывода информации, в целях изучения вопроса подключения к МК различных типов устройств для отображения информации, мы будем использовать сначала светодиодные сегментные индикаторы, которые потом заменим сегментным LCD дисплеем, который потом заменим буквенно-цифровым ЖК индикатором, а его, в свою очередь, если не погибнем в процессе, графическим ЖК индикатором. Затем добавим к вольтметру амперметр, а сверху этого бутерброда положим частотомер. Что будет дальше, честно говоря, я пока не знаю.
Счётчик команд
В большинстве процессоров после выполнения команды, если она не нарушает последовательности команд (например, команда перехода), счётчик автоматически увеличивается (постинкремент). Понятие счётчика команд тесно связано с архитектурой фон Неймана, одним из принципов которой является выполнение команд друг за другом в определённой последовательности.
Связанные понятия
В информатике бу́фер (англ. buffer), мн. ч. бу́феры — это область памяти, используемая для временного хранения данных при вводе или выводе. Обмен данными (ввод и вывод) может происходить как с внешними устройствами, так и с процессами в пределах компьютера. Буферы могут быть реализованы в аппаратном или программном обеспечении, но подавляющее большинство буферов реализуется в программном обеспечении. Буферы используются, когда существует разница между скоростью получения данных и скоростью их обработки.
Ввод-вывод через порты (англ. I/O ports) — схемотехническое решение, организующее взаимодействие процессора и устройств ввода-вывода. Противоположность вводу-выводу через память.
В информатике и теории автоматов состояние цифровой логической схемы или компьютерной программы является техническим термином для всей хранимой информации, к которой схема или программа в данный момент времени имеет доступ. Вывод данных цифровой схемы или компьютерной программы в любой момент времени полностью определяется его текущими входными данными и его состоянием.
Планирование выполнения задач — одна из ключевых концепций в многозадачности и многопроцессорности как в операционных системах общего назначения, так и в операционных системах реального времени. Планирование заключается в назначении приоритетов процессам в очереди с приоритетами. Программный код, выполняющий эту задачу, называется планировщиком (англ. task switcher, scheduler).
Собираем 8-битный компьютер
У меня нет цели научить читателя компьютерной электронике, но есть цель немного о ней рассказать и заинтересовать для самостоятельного изучения. Поэтому в статье упущено много базовой информации, нет деталей реализации различных компонентов, упрощены схемы — я не хочу перегружать материал. Если вас заинтересует статья, в конце есть раздел со всеми ссылками на видео и книгу для детального ознакомления.
Видеоиллюстрация
На видео снизу я разбираю программу для вывода на экран чисел Фибоначчи, написанную на языке C. Из кода на языке С, я генерирую код на языке ассемблера, чтобы лучше понять принципы выполнение программы на компьютере. Так как компьютер из статьи не понимает язык ассемблера, я перевожу его на язык, который он понимает.
Вы можете посмотреть первые 10 секунд видео, в котором демонстрируется выполнение программы, вернуться на статью и дочитать ее, а потом с бóльшим контекстом досмотреть видео.
Архитектура
Компьютер построен на архитектуре SAP-1 simpleaspossible. SAP-1 — это архитектура для начинающих, главная цель — понять базовые идеи и концепции построения компьютера без углубления в детали. Дизайн специально разработан для академических целей.
Большинство деталей в проекте — это 7400 серия интегральных микросхем от Texas Instruments, американской компании-производителя полупроводниковых изделий.
Компоненты
Компьютер состоит из следующих компонентов:
Регистр адреса оперативной памяти.
Буферные регистры A и B.
Регистр ввода-вывода и дисплей.
Шина для адреса и данных.
Схема
Схема расположения компонентов выглядит следующим образом:
Компоненты
Тактовый генератор
Тактовый генератор координирует работу всех компонентов в компьютере. Он подключен почти к каждому компоненту отдельно и раз в определенное время выдает напряжение. Это нужно для того, чтобы синхронизировать выполнение программы разными частями компьютера.
В основе тактового генератора лежит чип LM555CN — это таймер, устройство для формирования повторяющихся импульсов тактовых сигналов. С помощью резисторов и конденсатора можно контролировать частоту импульсов. Так, например, у Intel Core i9-7980XE базовая тактовая частота — 2.60 GHz. Это значит, что за одну секунду выдается 2.6 миллиарда импульсов.
Частота импульса складывается из времени наличия напряжения и его отсутствия как проиллюстрировано на рисунке ниже. По формуле ниже, она из документации к таймеру, при резисторе А — 100 Ом, резисторе B — 100K Ом, конденсаторе С — 2 микрофарад, получается, что один такт занимает — 0.693 * 201000 * 0.000002 = 0.278 секунды. За одну секунду получится — 1 / 0.278 = 3.59 такта.
Пример использования тактового генератора — внизу на картинке на макетной плате находится чип SN74LS173, это 4-битный D flip-flop — он нужен для того, чтобы хранить 4 битовых значения. Таким образом можно хранить 16 комбинаций значений, от 0000 до 1111. У чипа 16 ножек с помощью которых он вставляется в плату. Каждая из которых отвечает за свою часть работы. Чтобы не вдаваться в подробности, если на M и N разрешение на запись, и 1D подать напряжение, мы ожидаем, что чип сохранит значение как напряжение и отобразит это в 1Q, выход которого ведет к диоду красная лампочка — но ничего не произойдет. Для сохранения значения нам нужно также подать напряжение на вход CLK clock signal — тактовый сигнал, который исходит из тактового генератора.
В проекте тактовый генератор чуть-чуть сложнее:
Вместо резистора на 100К Ом там находится потенциометр, это «резистор с крутилкой», его можно поворачивать за и против часовой стрелки и динамически изменять сопротивление от 0 ОМ до 1М Ом. Таким образом можно увеличить количество тактов в секунду и компьютер будет работать быстрее, и наоборот.
Вместо одного таймера, там три, переключатель и кнопка. Это позволяет переключаться между двумя режимами — ручной и автоматический. В ручном режиме такт совершается при нажатии кнопки — это позволяет дебагать работу компьютера, а автоматический вы уже видели.
Оперативная память
Оперативная память нужна компьютеру, чтобы хранить определенный набор данных по определенным адресам. Оперативная память используется для хранения команд компьютера (например, сложить два числа), адресов (сложить число по какому-то адресу) и данных (записать какое-то число по какому-то адресу).
Знакомый нам чип SN74LS173 может сохранить 4 бита информации, чтобы сохранить 8 бит информации — нужно взять два SN74LS173. Таким образом, мы можем хранить значения от 0000 0000 до 1111 1111, что равно 256 возможных комбинаций, 2 в степени 8.
На схеме ниже к двум SN74LS173 подключен DIP-переключатель на 8 переключателей, которыми можно задавать 8 бит информации. Так как переключатели подсоединены к питанию, если переключить один из них, он выдаст напряжение. При подаче сигнала от тактового генератора, это значение сохранится в чипе и соответствующий диод загорится.
На самом деле, мы хотим контролировать когда производить запись. Без этого в памяти может оказаться любое значение – например, мы начинаем переключать переключатели, не переключили до конца, а тактовый сигнал сработал и память обновилась.
Для этого мы соединяем входы M и N с кнопкой. Кнопка подключена к напряжению, если на нее нажать, она передаст напряжение по перемычке. Нажав на кнопку и дождавшись тактового сигнала, мы получим запись значения.
Таким образом, схематически, можно выразить масштабируемость оперативной памяти как наличие одной кнопки, которая контролирует запись 8 бит. Если мы хотим иметь 128 бит оперативной памяти, а именно столько памяти в проекте, нам нужно 16 кнопок, каждая из которых отвечает за свои 8 ячеек оперативной памяти 16 * 8 = 128.
Если бы мы горизонтально подключили все ячейки между собой все первые ячейки каждой колонки, все вторые, третьи и так далее, соединив с одним переключателем на 8 переключателей, мы могли бы контролировать в какую именно колонку записать переданное через переключатели значение нажатием кнопки. Нажали на 16-ю кнопку — значение записалось только в последнюю колонку ячеек.
Кнопки получились бы репрезентацией адресов оперативной памяти. Но это сложно масштабировать, легче масштабировать бинарное представление 16 кнопок. То есть 4 бита, от 0000 до 1111 — в сумме 16 комбинаций, что равно количеству кнопок и, соответственно, колонок ячеек. С этим поможет DIP-переключатель на 4 переключателя.
Если значение переключателей будет 0000 — выбираем первый ряд, если 0001 — второй ряд, 0011 — четвертый ряд, и так далее до 1111 — 16 ряд. Раз кнопки превратились в переключатели, а переключатели превратились в перенаправление на определенную колонку ячеек, мы потеряли кнопку на запись — которую тоже надо добавить.
Таким образом, мы изобретаем декодер адресов. На вход декодера подается 4 сигнала, отвечающих за адрес в памяти, и 1 сигнал, отвечающий за запись.
Мы не будем разбирать устройство декодера. Внутри декодера находится комбинационная логика — логические вентили И AND и инверторы NOT. Иллюстрация работы в коротком видео здесь.
Таким образом, мы имеем 4 переключателя для адресов, 8 переключателей для значений ячеек, 1 кнопка на запись значений.
Арифметико-логическое устройство
Арифметико-логическое устройство (АЛУ) — компонент, который выполняет арифметические и логические операции. Например, АЛУ в проекте умеет суммировать и вычитать два числа, каждое из которых представлено 8 битами. Вид операции зависит от положения тумблера: замкнутый тумблер даст сигнал АЛУ сложить числа, разомкнутый вычесть одно число из другого.
Результат операции сразу сохраняется в отдельный 8-битный регистр, чтобы позже выполнить другие функции над ним — например, положить в оперативную память по какому-то из адресов. Этот регистр называется регистр для суммы.
Но на самом деле, АЛУ не принимает произвольные значения из переключателей. Каждое значение хранится в отдельном регистре — A и B. Эти регистры являются буферными регистрами. Буферные регистры предназначены для временного хранения данных и напрямую подключены ко входам АЛУ.
Регистры A и B почти идентичны по строению 4 знакомых нам чипа SN74LS173, но у них разные задачи. Регистр A призван сохранять промежуточный результат вычислений — один операнд, а регистр B призван хранить другой операнд.
Ниже в коде чуть более наглядно о задачах регистров на примере счётчика с инкрементом. Изначально, мы инициализируем переменную a и регистр А значением 0, переменную b регистр B значением 2. Cуммируем a и b, сохраняя в переменную sum регистр суммы в АЛУ. Значение из sum перезаписывается в a. Повторяем в цикле пока a меньше 255.
Схема архитектуры, которую вы уже видели, и пример задачи показывает, что:
Регистр суммы в АЛУ нужен для сохранения результата операции между регистрами A и B — значение можно передать в другие компоненты через шину данных. Например, в регистр A и решить этим задачу с инкрементом.
Регистр B нужен для хранения вспомогательных значений — в него можно только записать через шину данных.
Регистр A нужен для временного хранения значений — его можно передать в другие компоненты через шину данных.
Также АЛУ не подключен к тактовому генератору, это видно на схеме выше, — это ассинхронный компонент. Это значит, что он отрабатывает сразу как только меняются значения в A и/или B. Это достигается за счет того, что в состав АЛУ включены только комбинационные схемы, как у декодера адресов.
Схема SN74LS181— 4-битного АЛУ
Регистр ввода-вывода и дисплей
Внизу на картинке изображен семисегментный индикатор — он может отображать цифры и буквы. Он состоит из семи сегментов, включающихся и выключающихся по отдельности — с помощью подачи питания на опредленные ножки.
Чтобы отобразить букву F, нужно подать питание на 1, 2, 4 и 6 ножки слева направо, сверху вниз. Чтобы отобразить цифру 1, нужно подать питание на 5 и 9 ножки. Вместо порядкового номера ножки, можно использовать буквы на схеме — для цифры 1 это B и C.
Если мы хотим отобразить число, состоящее из нескольких цифр, мы можем использовать несколько индикаторов.
В проекте таких индикаторов 3 — они используются для отображения чисел в диапазоне от 0 00000000 до 255 11111111, один индикатор на одно число 0 отображается как 000, 1 как 001. Также в индикаторе есть ножка десятичного знака DP на схеме на случай, если нужно отображать числа с дробной частью (например, 17.3) — но такой функциональности в проекте нет, поэтому эта ножка не используется. Как вы поняли, шестнадцатеричная система счисления в проекте не используется, вместо F (15), используется два дисплея с 1 и 5.
Снизу проиллюстрированы все возможные варианты отображения одного десятичного числа на дисплее.
Теперь нужно понять как «соединить» 4-битное значение в диапазоне от 0000 0 до 1111 9 с входами дисплея от A до G. Например, если значение 0011, то на B и C нужно подать напряжение, а на A, D, E, F, G не нужно. С этим поможет таблица истинности ниже.
Вы могли заметить, что эта таблица похожа на структуру данных ассоциативный массив. Такой массив может хранить пары вида ключ-значение и поддерживает операции добавления пары, поиска и удаления.
Что еще похоже на ассоциативный массив? Оперативная память — адрес на вход и значения на выход. Мы можем сохранять по адресам, которые соответствуют двоичным числам 1001, значения для входов дисплея, которые соответствуют десятичному отображению 9.
Но оперативная память нам не подойдет потому, что не может хранить свои данные «вечно», только при наличии питания. Это значит, что нам придется каждый раз заново записывать в оперативную память значения из таблицы истинности.
Кроме оперативной памяти есть еще другие, которые сохраняют ее свойства (адреса, значения, запись и так далее):
ROM (read-only memory) — на заводе изготовителя «заливают» значения по адресам, а после значения изменить нельзя. Если надо что-то изменить, необходимо менять чип целиком.
PROM (programmable read-only memory) — изготавливается с «чистыми» значениями, которые можно запрограммировать один раз.
EPROM (erasable programmable read-only memory) — память можно перезаписывать, но чтобы стереть значения нужно несколько часов держать специальное окошко на чипе под светом ультрафиолетовой лампы. Окошко заклеивается наклейкой или изолентой.
EEPROM (electrically erasable programmable read-only memory) — память можно перезаписывать сколько угодно раз с помощью электрических импульсов — напряжения.
В проекте используется EEPROM — AT28C16. У него 11 входов для адресов (от 00000000000 до 11111111111) — это 2^11 комбинаций, то есть 2048 адресов и 8 ячеек памяти на каждый адрес. В сумме это память на 16384 бит (2048 байт,
2 килобайта). С помощью входа OE (output enable), подавая напряжение, можно регулировать — выводить ли на выходы I/O то, что хранится в памяти или нет. С помощью входа WE (write enable), подавая напряжение, при «выключенном» OE, можно сделать из выходов I/O входы для записи в ячейки памяти.
Плата, некий пульт управления памятью, с помощью которой можно менять значения в ячейках и смотреть, что хранится по тому или иному адресу, выглядит вот так:
С помощью DIP-переключателей задается адрес, с помощью диодов выводится значение в ячейке. С помощью перемычек (проводков над диодами) задаются новые значения.
Как отобразить число от 0 до 9 на дисплее мы разобрались. Теперь нужно понять как отобразить трехзначное число (например, 123) на 3 дисплеях. Сложность здесь в том, что на регистр ввода-вывода передается одно 8-битное значение (для 255 это 1111011), а на выходе не 1 дисплей, а 3.
Есть много решений этой задачи, в проекте используется сложный, но менее затратный по ресурсам (нужно меньше чипов). О сложном решении рассказать текстом не просто, поэтому обсудим простое решение.
Для каждой цифры из трехзначного числа — свой отдельный дисплей, а для каждого дисплея — свой отдельный EEPROM. Все адреса EEPROM-ов соединены между собой — это значит, что если на вход в регистр ввода-вывода попадет адрес — он попадет на все EEPROM-ы.
Фишка здесь в том, что каждый из EEPROM-в отображает только часть числа. Первый — первую цифру, второй — вторую, третий — третью. Это достигается за счет того, что каждый из них имеет свою таблицу истинности — различную друг от друга.
На каждый из EEPROM-ов приходит адрес 1111011 (число 123). Первый должен отобразить 1 — значит, в ячейке памяти по адресу 1111011 лежит — 0110000 (значения для дисплея). У второго в памяти лежит — 2 (1101101), у третьего — 3 (1111101).
Счётчик команд
В проекте, как и в современных компьютерах, в оперативной памяти хранятся не только значения, но и инструкции. Инструкции — это команды для компьютера сделать то или иное действие.
Оператор компьютера человек заполняет оперативную память инструкциями — одна инструкция в одной ячейке оперативной памяти, а компьютер выполняет эти инструкции одну за одной — для этого ему нужен счётчик команд.
Какие есть инструкции и как они работают, мы разберем чуть позже — сейчас о порядке выполнения программы:
Как только компьютер подключается к питанию, его надо поставить на паузу через специальную кнопку на плане тактового процессора.
Оперативная память заполняется вручную через DIP-переключатели, связанные с чипами SN74LS173, о которых рассказывалось выше.
Пауза отжимается и компьютер выполняет инструкцию из ячейки памяти по адресу 0000, потом инструкцию 0001, 0002 и так далее.