Поскольку ваша основная забота, похоже, заключается в изучении дизайна микроконтроллера, хороший подход мог бы рассмотреть некоторые из ранних моделей микропроцессора.Возьмем, например, Z80:
![Z80 Memory and I/O](https://i.stack.imgur.com/zmB27.gif)
Чтобы ответить на ваш первый вопрос (один против нескольких автобусов), это чип использует единую шину для всего, и он имеет очень простой дизайн. Вероятно, вы могли бы использовать что-то подобное. Чтобы сделать терминологию понятной, одна системная шина может состоять из подпути (и они также называются шинами). На рисунке показана системная шина, состоящая из шины данных двунаправленного трафика (8 бит) и адресной шины (16 бит).
Чтобы ответить на второй вопрос (как знают компоненты, когда они активны), на изображении выше вы видите два разных сигнала, запрос памяти и запрос ввода-вывода. Одновременно будет активен только один, и когда запрос ввода-вывода активен, именно тогда к нему можно получить доступ к периферии.
Если у вас нет большого количества периферийных устройств, вам не нужно использовать все 16 адресных линий (некоторые Z80 имеют 8-разрядное пространство ввода/вывода). Каждое периферийное устройство будет доступно через некоторые адреса в этом пространстве. Например, в очень простой системе:
- периферийное таймер может использовать адреса от 00h до 03h
- УАПП может адреса от 08h до 0FH
В этом простом примере, вам нужно обеспечивают две цепи: один будет определять, когда адрес находится в диапазоне 00-03h, а другой будет делать то же самое для 08-0Fh. Если вы выполняете логику «и» между выходом каждого детектора и сигналом запроса ввода-вывода, тогда у вас будет два сигнала, указывающих, когда к каждому из периферийных устройств обращаются. Ваше периферийное оборудование должно в первую очередь прослушивать этот сигнал.
Наконец, в отношении вашего вопроса о инструкциях поток данных внутри вашего микропроцессора будет иметь несколько этапов. Обычно это называется процессорным datapath. Распространено разделить этапы на:
- FETCH: прочитайте инструкцию из памяти программы
- ДЕКОДИРОВАТЬ: проверить определенные биты в инструкции, и решить, какой тип обучения это
- ВЫПОЛНИТЬ: взять действия, предусмотренные инструкцией (например, АЛУ операции)
- ПАМЯТЬ: для некоторых инструкций, которые вы должны сделать данные чтения или записи
- WRITE НАЗАД: обновляют свои регистры процессора с новыми значениями, затронутых инструкцией
![A Typical Microprocessor Datapath](https://www.cs.umd.edu/class/fall2001/cmsc411/projects/DLX/onecycle.gif)
Источник: https://www.cs.umd.edu/class/fall2001/cmsc411/projects/DLX/proj.html
Большая часть вашей работы иметь дело с отдельными инструкциями будет сделана в DECODE и EXECUTE этапов. Что касается контроля данных, вам понадобится конечный автомат, который контролирует последовательность операций через 5 этапов. Этот функциональный блок обычно называется блоком управления.Здесь у вас есть несколько вариантов:
- Ваш государственный автомат может идти по всем этапам последовательно, по одному за раз. Для выполнения команды потребуется несколько тактовых циклов.
- Как и в случае выбора выше, но комбинируя два или более этапа за один цикл, если вы хотите сделать вещи проще и быстрее.
- Трубопровод выполнения инструкций. Это может дать большой прирост скорости, но, возможно, лучше оставить его на потом, потому что все может стать довольно сложным.
Что касается реализации, я рекомендую держать функциональные блоки как отдельные объекты, и убедитесь, что вы пишете испытательный стенд для каждого блока. Ваша работа будет быстрее, если вы напишете эти тестовые стенды.
Что касается блоков, файл регистра довольно легко кодировать. Декодер инструкций также прост, если у вас есть четкое представление о макете инструкций и опкодах. И ALU также легко, если вы знаете, какие операции он должен выполнять.
Я бы начал с написания testbenches для декодера команд и файла регистра. Затем я бы написал сценарий, который запускает все тестовые узлы и автоматически проверяет их результаты. Только тогда я бы сосредоточился на реализации самих функциональных блоков.
+1 Вы прибивали мои проблемы :) Я не совсем понимаю ваш ответ, но думал, но это определенный прогресс. Я вижу два автобуса на первой схеме, что я ошибаюсь? Кроме того, кто контролирует последовательное выполнение datapath (CPU?)? И как вы обеспечиваете правильный запуск (сброс?)? Кроме того, есть ли у вас какие-либо рекомендации относительно того, с чего начать сначала? – nha
Отредактировал ответ, чтобы решить эти проблемы (@nha), и, надеюсь, сделать вещи немного яснее – rick
Яснее :) Я могу опубликовать следующий вопрос о фактической реализации. – nha