Разработка устройств на основе цифровых сигнальных процессоров фирмы Analog Devices с использованием Visual DSP++

Предисловие

В настоящее время цифровые сигнальные процессоры, или сокращенно DSP (Digital Signal Processor), приобрели большую популярность в мире и даже признаны отдельной областью науки и техники.

Эта книга является практическим руководством по самостоятельному изучению и применению на практике одного из цифровых сигнальных процессоров фирмы Analog Devices. Она включает в себя подробное описание процессора, схемы для его практического применения и технологию программирования.

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

Состоит из четырех частей: часть I посвящена схемотехнике сигнальных процессоров; в части II рассмотрено программирование устройств; далее в части III описаны вычислительные и аппаратные устройства; в части IV представлены установка, запуск, работа, спектральный анализ сигнала, а также программирование на СИ в среде разработки Visual DSP++.

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

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

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

Автор

Часть I. Схемотехника

В этой части книги освещается история развития различных сигнальных процессоров и дается обзор технических характеристик сигнальных процессоров семейства ADSP-21XX. Кроме того, в ней приводится практическая схема применения процессора ADSP-2181, описываются его архитектура и программно-логическая модель, дается описание системы прерываний процессора.

Глава 1. Обзор

В настоящее время большую популярность приобрели цифровые сигнальные процессоры, или сокращенно DSP (digital signal processor). Эта книга приподнимет завесу таинственности этих компонентов и позволит читателям самостоятельно заняться их освоением и применением в собственных разработках.

Свое название сигнальные процессоры получили в связи с встроенной в них возможностью обработки звуковых и видеосигналов. Это реализовано благодаря высокой скорости работы этих процессоров и заложенной в них специальной системе команд поддерживающей функции цифровой фильтрации и быстрого преобразования Фурье. Ниже перечислены основные отличия сигнальных процессоров от обычных микропроцессоров.

• Наличие аппаратного умножителя.

• Наличие специальных блоков обработки данных.

• Специальная система команд для цифровой обработки сигналов.

• Высокое быстродействие.

• Внутренний умножитель тактовой частоты.

• RISC архитектура.

• Возможность одновременного выполнения нескольких команд.

• Гарвардская архитектура построения процессора.

• Наличие конвейеризации команд и данных.

• Наличие циклических буферов.

• Развитая система внешних интерфейсов.

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

Проведем небольшой экскурс в историю развития данного семейства процессоров. Первые сигнальные процессоры появились в начале 80-х годов. Одной из первых компаний начавшей производство этих процессоров, была японская корпорация NEC, выпустившая однокристальный сигнальный процессор MPD7720. Однако этот процессор не получил широкого распространения, поскольку в 1982 г. на смену ему пришел более производительный и развитый процессор TMS32010, выпущенный фирмой Texas Instruments. Благодаря удачной архитектуре и ряду технических решений он стал стандартом де-факто для сигнальных процессоров. Ниже приведены основные технические характеристики данного процессора.

Разрядность данных 16 бит

Производительность 5 млн. операций в секунду

Объем оперативной памяти 256 слов

Объем памяти программ 4 К слов

Объем подключаемой внешней памяти 4 К слов

Разрядность арифметико-логического устройства 32 бит

Разрядность умножителя 6×16 бит с 32-битным результатом

Разрядность портов ввода-вывода 16 бит

Количество портов ввода-вывода 8

Пропускная способность внешней шины 50 Мбит

Освоение новых микронных технологий и, как следствие, повышение степени интеграции микросхем позволили значительно улучшить характеристики процессоров. И уже в середине 1980-х годов появились сигнальные процессоры второго поколения. К ним можно отнести процессоры все той же фирмы Texas Instruments TMS320C25 и TMS320C5X. Эти процессоры более скоростные и имеют больший объем памяти. Кроме того, у них появилась развитая система обработки прерываний и энергосберегающие режимы работы. В некоторых моделях процессоров снижено напряжение питания. Появились теневые регистры для автоматического сохранения результатов работы в случае возникновения аппаратного или программного прерывания программы. В состав архитектуры процессора добавились таймеры и последовательные синхронные порты с развитой конфигурацией настройки.

В свою очередь, фирма Motorola выпустила сигнальные процессоры семейства DSP56000, которые имеют разрядность 24 бита, двойную внутреннюю шину данных X и Y, удобную при операциях с комплексными числами, и обладают высокой степенью конвейеризации и параллелизма. Эти свойства делают данные процессоры еще более производительными и удобными для цифровой обработки сигналов.

Еще один производитель в лице фирмы AT&T Microelectronics выпускает сигнальные процессоры серии DSP16, которые отличаются наличием кэш-памяти и встроенного высокоскоростного, до 30 Мбайт, параллельного порта.

Фирма Analog Devices вышла на рынок сигнальных процессоров со своей серией ADSP-21XX, которые конкурируют с выше рассмотренными моделями по некоторым техническим параметрам, а кроме того, по цене. Например, процессор ADSP-21msp50 имеет встроенные АЦП и ЦАП и в то же время его стоимость составляет несколько долларов.

На этом развитие сигнальных процессоров не остановилось, и уже в конце 1980-х годов на рынке появились процессоры третьего поколения от перечисленных выше фирм. Отличительной особенностью этого поколения стало появление двоичной плавающей арифметики, увеличение разрядности шины данных, емкости памяти и программ. К этому числу процессоров можно отнести TMS320C30 фирмы Texas Instruments, DSP96002 фирмы Motorola, DSP32C фирмы AT&T Microelectronics и ADSP21020 фирмы Analog Devices.

Впоследствии на рынке появились сигнальные процессоры других фирм. Однако в настоящее время, лидирующее положение в этой области занимают фирмы Texas Instruments, Motorola, AT&T Microelectronics и Analog Devices.

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

Глава 2. Архитектура

В этой главе описывается внутренняя архитектура одного из сигнальных процессоров фирмы Analog Devices ADSP-2181 и примеры его подключения.

Фирма Analog Devices разработала целые семейства сигнальных процессоров и постоянно продолжает выпускать на рынок новые модели. В настоящее время существуют следующие семейства: ADSP-21XX, Shark DSP, BlackFin DSP и др. Но, несмотря на все многообразие этих групп, все они имеют похожую друг на друга архитектуру. Отличие семейств друг от друга заключается, например, в арифметических блоках, которые поддерживают вычисления с фиксированной или плавающей запятой. Кроме того, семейства отличаются производительностью, разрядностью шин данных, структурой внутренних регистров, интерфейсами и т.п. Отличие процессоров друг от друга внутри семейства состоит в основном в объеме и организации внутренней памяти и типе встроенных интерфейсов. В состав каждого из процессоров этого семейства входят следующие функциональные устройства.

• Арифметико-логическое устройство АЛУ.

• Умножитель-накопитель.

• Устройство сдвига.

• Два генератора адреса данных.

• Программный автомат.

• Таймер.

• Последовательный многоканальный порт.

Ниже приведена табл. 2.1 с отличительными характеристиками сигнальных процессоров семейства ADSP-21XX.

Таблица 2.1. Характеристики сигнальных процессоров семейства ADSP-21XX

Ресурсы

2101

2103

2105

2111

2115

21msp58

2171

2173

2181

2183

Объем оперативной памяти программ (слов)

2K

2K

1K

2K

1K

2K

2K

2K

16K

16K

Объем оперативной памяти данных (слов)

1K

1K

512

1K

512

2K

2K

2K

16K

16K

Второй последовательный порт

-

-

-

-

-

-

-

-

+

+

Порт хост-интерфейса

-

-

-

+

-

+

+

+

-

-

Порт прямого доступа к памяти

-

-

-

-

-

-

-

-

+

+

Максимальная внешняя тактовая частота, МГц

20

10,24

13,82

20

20

16,67

16,67

16,67

20

20

Аналого-цифровые преобразователи и фильтры

-

-

-

-

-

+

-

-

-

-

Режим малого потребления

-

-

-

-

-

+

+

+

+

+

Напряжение питания, В

5

3,3

5

5

5

5

5

3,3

5

3,3

Количество сигнальных выводов

68

68

68

100

68

100

128

128

128

128

Остановимся на рассмотрении архитектуры одного из самых распространенных на сегодняшний день процессоров семейства ADSP-21XX, а именно на процессоре ADSP-2181. Этот компонент является самым развитым в своем семействе и включает в себя наибольший объем памяти и множество встроенных интерфейсов.

Сигнальный процессор ADSP-2181 представляет собой однокристальный чип, выпускаемый в 128 выводных корпусах типа PQFP-128 или TQFP-128. Из вышеприведенной информации уже можно составить общее представление о возможностях, заложенных в данный процессор. Но для полноты картины рассмотрим структурную схему внутренней архитектуры этого чипа, приведенную на рис. 2.1.

Рис. 2.1. Структурная схема внутренней архитектуры чипа

Процессор имеет сильно развитую структуру внутренних шин адреса и данных. К их числу относятся шина адреса памяти программ PROGRAM MEMORY ADDRESS, шина адреса памяти данных DATA MEMORY ADDRESS, шина данных памяти программ PROGRAM MEMORY DATA и шина данных памяти данных DATA MEMORY DATA.

Слева на схеме изображен базовый блок архитектуры всего семейства ADSP-2100 BASE ARCHITECTURE включаемый в состав любого из процессоров данного семейства. Он состоит из блока генераторов адреса данных DATA ADDRESS GENERATORS, программного автомата PROGRAM SEQUENCER и арифметического блока ARITHMETIC UNITS.

Блок генераторов адреса данных содержит два генератора: DAG1 и DAG2, предназначенных для инвертирования бит адреса во время выполнения процессором операций быстрого преобразования Фурье (БПФ).

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

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

Рассмотрим блоки, расположенные справа вверху по схеме. Блок управления пониженным питанием POWER DOWN CONTROL обеспечивает управление процессором для перехода в режим пониженного потребления после выполнения соответствующей инструкции и возврат из этого режима после возникновения прерывания или после перезапуска. Блок памяти MEMORY состоит из памяти данных DATA MEMORY и памяти программ PROGRAM MEMORY. Таким образом, оперативная память всего процессора разделена на две независимых части в соответствии с Гарвардской архитектурой построения процессоров. Тем не менее, система команд этого процессора позволяет использовать память программ для хранения данных. Блок программируемых входов-выходов PROGRAMMABLE I/O позволяет запрограммировать несколько выводов по усмотрению разработчика на ввод или на вывод битовых сигналов, что обеспечивает возможность гибкого применения этих выводов. Блок флагов FLAGS управляет тремя битовыми выводами, организованными как сигнальные выходы. Наконец, блок байтового контроллера прямого доступа к памяти BYTE DMA CONTROLLER, сокращенное и часто употребляемое в дальнейшем название которого BDMA, обеспечивает быстрый аппаратный ввод и вывод байтовых данных через внешнюю шину данных процессора.

Теперь рассмотрим блоки, расположенные справа внизу по схеме. Одним из самых популярных и полезных является блок последовательных многофункциональных портов SERIAL PORTS, который включает в себя два последовательных порта SPORT1 и SPORT2. Отличительной особенностью этих портов является то, что они программируемые, синхронные и многоканальные. Т.е. каждый из этих портов способен принимать и передавать информацию от однословного до тридцатидвухсловного последовательного потока бит. Каждое слово в потоке может иметь длину от трех до шестнадцати бит. Этот формат передачи данных часто применяется при построении телекоммуникационных систем. К такому порту можно подключить одновременно до 32 кодеков и получить на их выходе соответственно 32 аналоговых канала ввода-вывода. Согласитесь — это мощный инструмент, который можно применить во многих областях. Кроме того, порты могут программироваться на внешнюю или внутреннюю синхронизацию. Управляющие выводы портов также могут быть запрограммированы на ввод или вывод.

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

И, наконец, блок внутреннего порта INTERNAL DMA PORT IDMA, сокращенное название которого IDMA, предназначен для организации прямого доступа к памяти данных и памяти программ процессора по шестнадцатиразрядной внешней шине. Этот порт играет важную роль при работе с процессором, поскольку позволяет загружать программу и данные непосредственно в память процессора до его старта, стартовать процессор и производить операции чтения и записи данных в память во время его работы, незначительно влияя при этом на производительность процессора.

С внешним миром процессор общается посредством четырнадцатиразрядной шины адреса EXTERNAL ADDRESS BUS, двадцати четырехразрядной шины данных EXTERNAL DATA BUS и шестнадцатиразрядной шины IDMA DMA BUS.

На рис. 2.2 приведена более подробная структурная схема процессора, с указанием разрядности внутренних и внешних шин и более детальным изображением всех описанных выше блоков.

Рис. 2.2. Структурная схема процессора

Более подробную структуру процессора мы рассмотрим позже, когда будем изучать его внутренние регистры и примеры программ.

На рис. 2.3 и 2.4 представлены варианты исполнения процессора в корпусах PQFP-128 и TQFP-128, соответственно. На этих же рисунках изображено назначение всех контактов процессора и приведена их нумерация.

Рис. 2.3. Вариант исполнения процессора в корпусе PQFP-128

Рис. 2.4. Вариант исполнения процессора в корпусе TQFP-128

Изображения дают вид сверху TOP VIEW, выводами вниз PINS DOWN. Сигналы с низкими активными уровнями имеют обозначения с чертой над сигналом. Выводы двойного назначения, определяемого программированием этих выводов, обозначаются через символ «/».

В табл. 2.2 дается описание назначения выводов процессора.

Таблица 2.2 Описание выводов процессора ADSP-2181

Наименование

Вывод I/O

Функция

А0…А13

O

Адресные выводы для адресации области внешней памяти программ, памяти данных, байтовой памяти (BDMA) и устройств ввода-вывода

D0…D23

I/O

Выводы данных для обмена данными с внешней памятью программ и памятью данных. Восемь старших разрядов также используются как адрес байтовой памяти.

-WR

O

Сигнал записи

-RD

O

Сигнал чтения

-IOMS

O

Выбор области памяти

-BMS

O

Выбор байтовой памяти

-DMS

O

Выбор памяти данных

-CMS

O

Выбор комбинированной памяти

-PMS

O

Выбор программной памяти

FL0, FL1, FL2

О

Выходы-флаги

PF0…PF7

I/O

Программируемые выводы

MMAP

I

Выбор карты памяти процессора

-PWD

I

Управление потреблением

BMODE

I

Режим загрузки 0 — ROM, 1 — IDMA

PWDACK

O

Контроль низкого потребления питания

XTAL

I

Соединение с кварцем

CLKIN

I

Внешний генератор, или соединение с кварцем

CLKOUT

O

Выходная тактовая частота

-RESET

I

Сброс процессора

-ERESET

I

Разрешение сброса

-IRQL0

I

Потенциальный запрос прерывания 0

-IRQL1

I

Потенциальный запрос прерывания 1

-IRQ2

I

Динамический или потенциальный запрос прерывания 2

-IRQE

I

Динамический запрос прерывания

-BR

I

Внешний запрос шины

-BG

O

Внешнее предоставление шины

-BGH

O

Внешнее предоставление шины, подтянутое к питанию

IAD0…IAD15

I/O

Шина адреса/данных порта IDMA

-IACK

O

Подтверждение доступа к порту IDMA

-IWR

I

Вход записи в порт IDMA

-IRD

I

Вход чтения из порта IDMA

-IS

I

Вход выборки порта IDMA

IAL

I

Вход защелки адреса порта IDMA

DT0

O

Передача данных

TFS0

I/O

Кадровая синхронизация передачи

RFS0

I/O

Кадровая синхронизация приема

DR0

I

Прием данных

SCLK0

I/O

Программируемый генератор порта 0

DT1/FO

O

Передача данных, или выходной флаг

TFS1/IRQ1

I/O

Кадровая синхронизация передачи, или внешний запрос прерывания 1

RFS1/IRQ0

I/O

Кадровая синхронизация приема, или внешний запрос прерывания 0

DR1/FI

I

Прием данных, или входной флаг

SCLK1

I/O

Программируемый генератор порта 1

-EMS

Сигналы, используемые только в режиме эмуляции

ЕЕ

ECLK

ELOUTELIN

EINT

-EBR

-EBG

GND

Выводы заземления

VDD

Выводы питания

Примечание: I — вход, О — выход; минус перед сигналом означает низкий активный уровень сигнала.

Способ подключения к процессору различных периферийных устройств показан на структурной схеме, приведенной на рис. 2.5. В качестве примера, на этой схеме показано, как подключаются следующие устройства:

Внешний генератор или кварцевый резонатор с половинной тактовой частотой процессора 1/2x CLOCK OR CRYSTAL.

Последовательные устройства SERIAL DEVICE, например кодеки.

Системный интерфейс или микроконтроллер SYSTEM INTERFACE OR MICROCONTROLLER.

Байтовая память BYTE MEMORY.

До 2048 периферийных устройств ввода-вывода I/O SPACE PERIPHERALS.

Внешняя память OVERLAY MEMORY.

Рис. 2.5. Способ подключения к процессору различных периферийных устройств

При использовании внешней памяти, допускается подключение двух 8К-словных сегмента памяти программ TWO 8К РМ SEGMENTS и двух 8К-словных сегмента памяти данных TWO 8К DM SEGMENTS.

Из схемы видно также, какие именно сигналы процессора используются для подключения всех перечисленных внешних устройств.

На рис. 2.6 показан способ подключения кварцевого резонатора к сигнальному процессору. Конденсаторы должны иметь номинальную емкость от 22 до 33 пФ, а максимальная частота кварцевого резонатора должна быть вдвое ниже максимальной внутренней частоты процессора, поскольку внутри процессора производится аппаратное умножение внешней задающей тактовой частоты. Эта удвоенная частота выводится на сигнальный вывод CLKOUT процессора. Вместо кварцевого резонатора, для формирования задающей частоты синхронизации можно использовать интегральный генератор, который, однако, несколько дороже резонатора. В этом случае выход генератора необходимо подключить к выводу CLKIN процессора, а вывод XTAL оставить неподключенным.

Рис. 2.6. Способ подключения кварцевого резонатора к сигнальному процессору

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

Таблица 2.3. Карта памяти процессора

Параметр

Адрес

Память программ

Адрес

Память данных

Адрес

8К слов ВНУТРЕННИЕ (PMOVLAY=0, MMAP=0) или 8К слов ВНЕШНИЕ (PMOVLAY=1 или 2, MMAP=0)

0x3FFF … 0x2000

8К слов ВНУТРЕННИЕ (PMOVLAY=0, MMAP=1)

0x3FFF … 0x2000

32 РЕГИСТРА

0x3FFF … 0x3FE0

8160 слов ВНУТРЕННИЕ

0x3FDF … 0x2000

8К слов ВНУТРЕННИЕ

0x1FFF … 0x0000

8К слов ВНЕШНИЕ

0x1FFF … 0x0000

8К слов ВНУТРЕННИЕ (DMOVLAY=0) или 8К слов ВНЕШНИЕ (DMOVLAY=1 или 2)

0x1FFF … 0x0000

Память программ может быть внутренней INTERNAL, т.е. размещенной на кристалле самого процессора, или внешней EXTERNAL, т.е. размещенной во внешних микросхемах памяти. Поскольку память программ организована 24 разрядными словами, суммарный объем внутренней памяти программ процессора может быть равен (8К слов+8К слов) × 3байта = 48 Кбайт.

На последнем фрагменте рисунка приведена карта памяти данных. Ее режим работы, как внешней или внутренней, определяется с помощью внутреннего регистра процессора DMOVLAY, который аналогично регистру PMOVLAY обнуляется при сбросе или включении процессора, обеспечивая тем самым включение режима использования внутренней памяти данных. В самой верхней области памяти данных размещены 32 служебных регистра процессора, которые организованы как память данных. Поэтому память данных усечена по объему на это количество ячеек памяти. Память данных организована шестнадцатиразрядными словами, поэтому суммарный объем внутренней памяти данных процессора составляет (8К слов + 8К слов) × 2байта = 32 Кбайт.

Учитывая разрядность банков памяти программ и памяти данных, суммарная емкость памяти процессора составляет 80 Кбайт. Это довольно большой объем памяти, достаточный для решения многих задач, написанных на языках ассемблера или Си.

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

Глава 3. Практические схемы включения

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

Итак, приступим непосредственно к практике по освоению сигнального процессора. На рис. 3.1 изображена принципиальная схема тестовой платы для изучения процессора и отладки программ. Файл этой схемы, созданный в системе автоматического проектирования PCAD 4.5, записан на компакт-диск, прилагаемый к данной книге. На схеме показан способ включения самого сигнального процессора и периферийных устройств, подключаемых к нему. Рассмотрим последовательно все сигнальные выводы процессора и их назначение.

Рис. 3.1. Принципиальная схема тестовой платы

Рис. 3.1. Принципиальная схема тестовой платы (продолжение)

Рис. 3.1. Принципиальная схема тестовой платы (окончание)

Как видно из схемы, процессор D1 имеет несколько выводов для подключения питания, что связано с необходимостью распределения токоведущих цепей для обеспечения помехоустойчивости. Используемый в схеме сигнальный процессор допускает питание от источника напряжением 4,5…5,5 В. Стабилизированное напряжение питания 5 В поступает с разъема питания XP1. Конденсаторы CP2 и C3–C7 обеспечивают фильтрацию напряжения по низким и высоким частотам соответственно. Индикатор HL4 с токоограничивающим резистором R3 индицирует наличие питания в схеме. Для питания аналоговой части схемы используются дополнительные элементы фильтрации L1 и C8–C10.

Следующими важными цепями являются входы и выходы генераторных сигналов XTAL, CLKIN и CLKOUT. Первые две цепи предназначены для подключения внешнего источника синхронизации. На приведенной схеме показан способ подключения к процессору кварцевого резонатора BQ1. В случае применения интегрального генератора выход генератора подключается к выводу CLKIN, а вывод XTAL не используется. Стоимость генераторов на сегодняшний день еще превышает стоимость кварцевых резонаторов, поэтому к процессору подключен более дешевый кварцевый резонатор. Номинальная резонансная частота такого резонатора или генератора не должна превышать половину предельно допустимой частоты для данного процессора. Так, для процессора с максимальной тактовой частотой 40 МГц она не должна превышать 20 МГц. Конденсаторы C1 и C2 должны быть керамического типа, емкостью от 18 до 30 пФ.

Внутри процессора производится аппаратное умножение внешней частоты, которая затем используется для синхронизации процессора. Внутренняя частота процессора будет составлять 40 МГц, а длительность выполнения команд 25 нс. Внутренняя частота выводится также на CLKOUT процессора и может быть использована для синхронизации других микросхем, подключаемых к процессору.

Временная диаграмма сигналов синхронизации показана на рис. 3.2, а допустимые параметры этих сигналов приведены в табл. 3.1.

Рис. 3.2. Временная диаграмма сигналов синхронизации

Таблица 3.1 Допустимые параметры сигналов синхронизации процессора

Параметр

Минимум

Максимум

Единица измерения

Сигналы синхронизации

Требуемые длительности:

tCKI

50

150

нс

tCKIL

20

нс

tCKIH

20

нс

Характеристика переключения:

tCKL

0,5tCK-7

нс

tCKH

0,5tCK-7

нс

tCKOH

0

20

нс

tCK= 0,5*tCKI

При выборе сигнального процессора необходимо пользоваться табл. 3.2, в которой приведены заводские маркировки и соответствующие им характеристики.

Таблица 3.2 Характеристики сигнальных процессоров

Заводская маркировка

Рабочий температурный диапазон, °С

Максимальная тактовая частота, МГц

Тип корпуса

Условное обозначение корпуса

ADSP-2181KST-115

0…+70

28,8

TQFP-128*

ST-128

ADSP-2181BST-115

-40…+85

28,8

TQFP-128

ST-128

ADSP-2181KS-115

0…+70

28,8

PQFP-128**

S-128

ADSP-2181BS-115

-40…+85

28,8

PQFP-128

S-128

ADSP-2181KST-133

0…+70

33,3

TQFP-128

ST-128

ADSP-2181BST-133

-40…+85

33,3

TQFP-128

ST-128

ADSP-2181KS-133

0…+70

33,3

PQFP-128

S-128

ADSP-2181BS-133

-40…+85

33,3

PQFP-128

S-128

ADSP-2181KST-160

0…+70

40

TQFP-128

ST-128

ADSP-2181 KS-160

0…+70

40

PQFP-128

S-128

* TQFP — Plastic Thin Quad Flatpack (пластиковый тонкий четырехугольный плоский корпус).

** PQFP — Plastic Quad Flatpack (пластиковый четырехугольный плоский корпус).

В нашем случае использован процессор ADSP-2181KS-133 в корпусе PQFP-128, как получивший большое распространение и легко доступный. В табл. 3.3 приведено соответствие выводов корпуса этого процессора его сигналам.

Таблица 3.3 Соответствие выводов корпуса сигналам процессора

Вывод

Сигнал

Вывод

Сигнал

Вывод

Сигнал

Вывод

Сигнал

1

PF0

33

PWD

65

EBR

97

D23

2

WR

34

IRQ2

66

BR

98

GND

3

RD

35

BMODE

67

EBG

99

IWR

4

IOMS

36

PWDACK

68

BG

100

IRD

5

BMS

37

IACK

69

VDD

101

IAD15

6

DMS

38

BGH

70

DO

102

IAD14

7

CMS

39

VDD

71

D1

103

IAD13

8

GND

40

GND

72

D2

104

IAD12

9

VDD

41

IRQL0

73

D3

105

IAD11

10

PMS

42

IRQL1

74

D4

106

IAD10

11

А0

43

FLO

75

GND

107

IAD9

12

A1

44

FL1

76

D5

108

IAD8

13

A2

45

FL2

77

D6

109

IAD7

14

A3

46

DT0

78

D7

110

IAD6

15

A4

47

TFS0

79

D8

111

VDD

16

A5

48

RFS0

80

D9

112

GND

17

A6

49

DR0

81

D10

113

IAD5

18

A7

50

SCLK0

82

D11

114

IAD4

19

XTAL

51

DT1/FO

83

D12

115

IAD3

20

CLKIN

52

TFS1/IRQ1

84

D13

116

IAD2

21

GND

53

RFS1/IRQ0

85

D14

117

IAD1

22

CLKOUT

54

GND

86

GND

118

IAD0

23

GND

55

DR1/FI

87

VDD

119

PF7

24

VDD

56

SCLK1

88

GND

120

PF6

25

A8

57

ERESET

89

D15

121

PF5

26

A9

58

RESET

90

D16

122

PF4

27

A10

59

EMS

91

D17

123

GND

28

A11

60

ЕЕ

92

D18

124

IS

29

A12

61

ECLK

93

D19

125

IAL

30

А13

62

ELOUT

94

D20

126

PF3

31

IRQE

63

ELIN

95

D21

127

PF2

32

MMAP

64

EINT

96

D22

128

PF1

Сигнал -RESET обеспечивает сброс процессора в исходное состояние. Этот сигнал должен находиться в активном низкоуровневом состоянии при включении и перезагрузке процессора в течение не менее пяти тактовых периодов внешней синхронизации процессора. Обычно для надежного сброса процессора этот сигнал удерживается в активном состоянии не менее нескольких микросекунд. Формирование сигнала сброса в схеме возможно от любого из двух источников. Первый источник этого сигнала реализован на зарядной цепочке R1, CP1. В момент подачи питания на схему, конденсатор CP1 разряжен и на нем удерживается низкий потенциал в течении времени его заряда, достаточного для приведения процессора в исходное состояние. Диод VD1 обеспечивает быстрый разряд этого конденсатора в момент отключения или кратковременного пропадания питания. Кнопка SB4 предназначена для принудительного сброса процессора вручную. Резистор R2 ограничивает ток разряда, предохраняя контакты кнопки от образования искр, и устраняет дребезг контактов совместно с конденсатором CP1. Вторым источником сигнала сброса является сигнал — RESI с разъема XU1, который буферизуется шинным повторителем D4.1 и поступает на микросхему D6. С помощью элементов D6.3 и D6.4 оба сигнала объединяются в один сигнал сброса процессора в инверсном (-RESET) и неинверсном виде (RESET). Наличие неинверсного сигнала требуется для сброса других микросхем с активным высокоуровневым входом сброса.

Сигнал -ERESET и сигналы на выводах 59…65 и 67 процессора предназначены для подключения к нему специального аппаратного эмулятора EZ-ICE, который можно приобрести через представителей фирмы Analog Device в России. Выводы эмулятора подключены к разъему XEZ в соответствии с рекомендациями по применению данного сигнального процессора. Однако на практике вполне можно обходиться и без этого эмулятора.

Следующая группа сигналов -IRQL0, -IRQL1, -IRQ2 и -IRQE отвечает за передачу процессору внешних прерываний. В качестве источников прерываний могут выступать различные микросхемы, датчики, кнопки и т.п. Так, к сигнальному выводу -IRQE подключена кнопка SB5 через цепочку устранения дребезга контактов R22 и CP4. Резистор R23 предназначен для удержания сигнала прерывания в пассивном состоянии. В дальнейшем с ее помощью можно будет принудительно вызывать прерывание процессора при необходимости.

Следующие три сигнала обеспечивают запрос и предоставление внешней шины процессора другим внешним устройствам. На схеме сигнал запроса шины -BR используется только при подключении к схеме эмулятора EZ-ICE и подключен к разъему XEZ. Этот сигнал подтянут к шине питания для приведения его в пассивное состояние. Выходной сигнал -BG, подтверждающий предоставление шины процессором, также подключен к разъему XEZ. Сигнал -BGH не используется и остается не подключенным.

Далее следует группа важных сигналов порта прямого доступа к памяти процессора. Это шестнадцать мультиплексированных сигналов шины адреса данных IAD0–IAD15 и сигналы управления IACK, -IWR, -IRD, -IS, IAL. Данный порт можно использовать для загрузки программ и данных во внутреннюю память процессора и, кроме того, читать содержимое памяти процессора во время его работы. Это позволяет обходиться без эмулятора EZ-ICE, облегчает отладку программ и дает большую гибкость при разработке многопроцессорных схем. На схеме все эти сигналы подключены через буферные микросхемы D2, D3, D4.1, D5.1, D5.5 и D5.5 к внешнему разъему XU1. В дальнейшем мы рассмотрим специальный адаптер, который позволит нам оперативно загружать программы в процессор, читать и записывать данные в его память и окажет большую помощь в изучении самого процессора и освоении его системы команд и способов программирования. Цепочка элементов R4 и C11 фильтрует высокочастотные импульсы, проникающие на чувствительный вход IAL процессора, обеспечивая тем самым повышенную помехозащищенность. Резисторные сборки RN1 и RN2 подтягивают сигналы порта IDMA и прерываний к высокому пассивному уровню.

Следующие две группы сигналов последовательных портов SPORT0 и SPORT1 обеспечивают работу с последовательными устройствами. К порту SPORT0 в схеме подключен кодек DA1 типа MC14LC5480, который содержит в себе кодер и декодер с фильтрами и компандер. В отличие от аналого-цифрового и цифро-аналогового преобразователей, он отличается тем, что выполняет преобразование сигналов по А-типу или μ-типу. Фактически оба эти типа преобразования являются аппроксимацией логарифмической функции с различной степенью приближения. Они активно применяются в телекоммуникационных системах для цифрового преобразования и сжатия информации с максимальным сохранением соотношения сигнал-шум. Для этого аналоговые сигналы малой амплитуды дискретизируются чаще. Для сжатия цифровой информации используется функция компандирования, встроенная в кодек и сигнальный процессор. С помощью этой функции производится прямое и обратное преобразование 13- или 14-разрядных слов в 8-разрядные, за счет нелинейного прореживания. В цифровых каналах связи используются именно такие 8-битные данные. Для нормальной работы кодеку необходимы сигналы синхронизации и кадровые стробы приемника и передатчика. Эти сигналы формируются портом SPORT0 на выводах SCLK0, RFS0 и TFS0 соответственно. Все перечисленные сигналы синхронизации и стробов программируются в процессоре по направлению, частоте, длительности и фазовому сдвигу. Цифровые данные приемника и передатчика порта транслируются на кодек по сигнальным выводам DR0 и DT0 соответственно. Помимо перечисленных узлов, кодек содержит в себе операционные усилители и источник опорного напряжения для смещения напряжения на входах усилителей относительно нулевого потенциала. Аналоговый сигнал на кодек заведен с разъема XIN типа тюльпан, через развязывающий конденсатор C16.

Стабилитроны VS1 и VS2 защищают вход кодека от сигналов большой амплитуды. Резисторы R9 и R10 определяют коэффициент усиления входного сигнала. Опорное напряжение подведено к неинверсному входу кодека через резистор R12. Цепочка R11-C17 корректирует смещение по высоким частотам. Конденсатор C18 является фильтрующим. Оцифрованный сигнал поступает в процессор на вход DR0 для обработки или цифровой записи. В свою очередь, процессор посылает в кодек цифровые сигналы для последующего их преобразования в аналоговый сигнал. После цифро-аналогового преобразования сигнала DT0 от процессора выходной аналоговый сигнал с кодека поступает через ограничительный резистор R14 на разъем XOUT. Кроме того, этот же сигнал поступает на низкочастотный усилитель, выполненный на транзисторах VT1 и VT2. В нагрузку усилителя, через развязывающий конденсатор CR3, включена миниатюрная динамическая головка BA1. Она позволит прослушивать сигналы, генерируемые процессором через кодек. Резисторы R13 и R16 определяют коэффициент усиления всего каскада, а резистор R15 обеспечивает необходимое смещение на базах транзисторов.

Выводы порта SPORT1 являются многофункциональными. Они могут быть запрограммированы как на работу с последовательными устройствами подобно порту SPORT0, так и в альтернативном режиме как флаги входа-выхода и входы прерывания. В нашей схеме используется второй способ их применения. Вывод 51 порта будет работать как выход, а вывод 55 как вход. Кроме того, задействован вход прерывания IRQ1, для формирования прерывания процессора при поступлении информации по сигнальному выводу FI. Эти выводы задействованы для организации последовательного порта RS-232 или проще — компьютерного СОМ порта. Для этого они подключены к микросхеме преобразования уровней DA2. Эта микросхема преобразует ТТЛ уровни сигнала в уровни стандарта RS-232. Конденсаторы C12–C15 обеспечивают работу внутренних умножителей напряжения в микросхеме. Сигналы порта RS-232 выведены на девятиштырьковый разъем XRS1. Назначение сигналов на этом разъеме соответствует стандарту, принятому для персональных компьютеров IBM PC. В дальнейшем к этому порту можно подключить компьютер, с помощью нуль-модемного кабеля, для загрузки обучающих программ с помощью программного пакета EZ-KIT Lite, распространяемого фирмой Analog Device.

Сигналы А0–А13 являются адресными и предназначены для адресации внешней памяти или устройств ввода-вывода. В схеме они подключены к адресным выводам микросхемы постоянной памяти D7, а некоторые из них, к дешифратору устройств ввода-вывода D9.

Сигналы D0–D23 предназначены для передачи данных и для адресации. Младшие восемь бит этой шины участвуют в обмене данными только с расширенной памятью. В нашей схеме эта память не подключена и, соответственно, сигналы D0–D7 не задействованы. Разряды D8–D15 используются для передачи данных при обращении к байтовой памяти BDMA.

В нашей схеме эту роль выполняет микросхема постоянной флэш-памяти D7. Наконец, старшие разряды этой шины D16–D23 выполняют двоякую роль. При обращении к байтовой памяти они несут функцию старших адресных линий, а при обращении к устройствам ввода-вывода являются старшими разрядами шины данных.

Далее следуют сигналы записи -WR, чтения -RD и выборки внешних устройств. В нашей схеме из внешних устройств будет использоваться байтовая память D7, выбираемая сигналом -BMS с помощью дешифратора D8, и устройства ввода-вывода, выбираемые сигналом -IOMS с помощью дешифратора D9 и логических элементов D13.1, D13.2. В схеме присутствует восьмиразрядный регистр ввода D11 и восьмиразрядный регистр вывода D12. Первый из них позволяет снимать дискретные сигналы с различных цифровых датчиков, контактов и пр. А второй обеспечивает возможность управления цифровыми ключами, индикаторами и т.п. Выводы этих регистров заведены на разъемы XI и ХО соответственно.

Временные диаграммы циклов чтения и записи данных процессором, представлены на рис. 3.3 и 3.4, соответственно. Параметры сигналов для этих циклов приводятся в табл. 3.4 и 3.5.

Рис. 3.3. Временная диаграмма цикла чтения

Рис. 3.4. Временная диаграмма цикла записи

Таблица 3.4 Параметры сигналов для цикла чтения данных процессором

Параметр

Минимум

Максимум

Единица измерения

Чтение памяти

Требуемые длительности:

tRDD

0,5 tCK - 9 + w

нс

tAA

0,25 tCK - 10.5 + w

нс

tRDH

0

нс

Характеристика переключения:

tRP

0,5 tCK - 5 + w

0,25 tCK + 7

нс

tCRD

0,25 tCK - 5

нс

tASR

0,25 tCK - 6

нс

tRDA

0,25 tСK - 3

нс

tRWR

0,5 tCK - 5

нс

Таблица 3.5 Параметры сигналов для цикла записи данных процессором

Параметр

Минимум

Максимум

Единица измерения

Запись памяти

Характеристика переключения:

tDW

0,5 tСK - 7 + w

нс

tDH

0,25 tСK - 2

нс

tWP

0,5 tCK - 5 + w

нс

tWDE

0

нс

tASW

0,25 tCK - 6

нс

tDDR

0,25 tCK - 7

нс

tCWR

0,25 tCK - 5

нс

tAW

0,75 tCK - 9 + w

0,25 tСK + 7

нс

tWRA

0,25 tCK - 3

нс

tWWR

0,5 tCK - 5

нс

* w — число циклов задержки * tCK

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

Следующая группа сигналов FL0-FL2 является битовыми выходными сигналами, которые работают только на вывод. К ним подключены индикаторы HL0-HL2 через буферный повторитель D4.2.

В отличие от FL0-FL2, выводы PF0-PF7 являются двунаправленными битовыми сигналами и могут быть запрограммированы как на ввод, так и на вывод побитно. Так, к выводу PF7 подключен индикатор HL3, а выводы PF0-PF3 будут запрограммированы как входы и к ним подключены кнопки SB0-SB3. Резисторы R5–R8 являются токоограничивающими, а резисторная сборка RN3 подтягивает сигналы управления и входные сигналы к высокому уровню.

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

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

Наконец последний вывод процессора BMODE определяет интерфейс, через который будет производиться загрузка процессора. Если на этот вывод подан нулевой потенциал, загрузка процессора будет производиться через интерфейс BDMA, т.е. из байтовой памяти. В противном случае процедура загрузки будет производиться через интерфейс IDMA. В дальнейшем мы рассмотрим оба варианта загрузки. Для автоматизации процесса загрузки в схеме применен триггер, выполненный на элементах D4.1 и D4.2. В зависимости от источника сброса, триггер переключается в такое состояние, которое обеспечивает установку на выводе BMODE сигнала, необходимого для загрузки через соответствующий интерфейс.

Еще одно внешнее устройство в качестве дополнения схемы приведено на рис. 3.5. Это дополнение схемы не является обязательным и может не распаиваться на основную плату. Но если появится необходимость оснащения рассмотренной выше схемы еще одним последовательным портом типа RS-422, это дополнение поможет в этом.

Рис. 3.5. Внешнее устройство в качестве дополнения схемы процессора

Как видно из рисунка, схема содержит интегрированную микросхему UART D12 с подключенными к ней резонатором BQ2 и вспомогательными конденсаторами C19, C20 для запуска внутреннего генератора. Программирование этой микросхемы производится через сигналы шины данных DD0–DD7. Выходные сигналы микросхемы UART подключены к приемопередатчикам — преобразователям уровней сигналов DA3 и DA4 для организации последовательного порта RS-422. Элементы D5.2 и D5.3 инвертируют выходные сигналы управления UART, обеспечивая отключение приемопередатчиков DA3 и DA4 в момент сброса самого UART или при включении.

Элемент D5.3 инвертирует выходной сигнал запроса прерывания от UART. Резисторы R17–R21 обеспечивают пассивное состояние сигналов при отключенной линии связи. Этот порт позволяет обмениваться информацией со 127 другими устройствами по аналогичному порту на расстоянии до 1200 метров. Все сигналы порта выведены на разъем XRS2.

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

Рис. 3.6. Корпус процессора

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

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

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

Глава 4. Программно-логическая модель

В этой главе говорится о внутренней программно-логической модели процессора и его системе прерываний.

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

Итак, начнем с программно-логической модели процессора. Такая модель для ADSP-2181 приведена на рис. 4.1.

Рис. 4.1. Программно-логическая модель ADSP-2181

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

Главный блок регистров представлен на рисунке слева, в процессорном ядре. В первую очередь это блоки регистров программных генераторов адреса DAG1 и DAG2. Данные блоки регистров включают в себя индексные регистры I, регистры длины буфера L и регистры-модификаторы M.

Все перечисленные регистры имеют размерность 14 бит. Эти регистры позволяют организовывать в памяти процессора циклические и линейные буферы, с автоматическим инкрементом адреса слов в этих буферах и отслеживанием их длины. В каждом из блоков генераторов адресов присутствует по четыре группы таких регистров. Использование этих и других регистров будет рассмотрено позже на конкретных примерах.

Блок программного автомата содержит регистры, отвечающие за автоматические операции процессора. В их число входят:

• программный счетчик с 16-уровневым 14-разрядным стеком PC STACK, для организации вызова подпрограмм и обработки прерываний;

• счетчик циклов CNTR с 4-уровневым 14-разрядным стеком COUNT STACK, для организации вложенных программных циклов;

• псевдорегистр OWRCNTR, для обновления значения счетчика CNTR;

• цикловой компаратор LOOP STACK с 4-уровневым 18-разрядным стеком, для обеспечения выполнения программных циклов без тактов ожидания.

Назначение остальных регистров управления и состояния блока программного автомата процессора, приводится в табл. 4.1. Обращение к этим регистрам из программы производится по их логическим именам, совпадающим с именами, приведенными на рис. 4.1 и в табл. 4.1.

Таблица 4.1а Регистр состояния арифметико-логического устройства ASTAT

Разряд

Исходное состояние

Назначение

7

0

Флаг знака ввода в устройство сдвига SHIFTER (SS)

6

0

Флаг переполнения в умножителе-накопителе MAC (MV)

5

0

Флаг частного АЛУ (AQ)

4

0

Флаг знака ввода порта X в АЛУ (AS)

3

0

Флаг переноса бита в АЛУ (АС)

2

0

Флаг переполнения АЛУ (AV)

1

0

Флаг отрицательного результата в АЛУ (AN)

0

0

Флаг нулевого значения в АЛУ (AZ)

Таблица 4.1б Регистр состояния режима процессора MSTAT

Разряд

Исходное состояние

Назначение

6

0

Разрешение режима GO

5

0

Разрешение работы таймера

4

0

Результаты умножителя: 0 — дробные, 1 — целые

3

0

Разрешение режима насыщения регистра AR АЛУ

2

0

Разрешение режима фиксации переполнения АЛУ

1

0

Разрешение бит-реверсивной адресации DAG1

0

0

Выбор банка регистров данных: 0 — главный, 1 — теневой

Таблица 4.1в Регистр разрешения прерываний IMASK (0 — запрещено, 1 — разрешено)

Разряд

Исходное состояние

Назначение

15…10

0

Не используются

9

0

-IRQ2

8

0

-IRQL1

7

0

-IRQL0

6

0

Передатчик SPORT0

5

0

Приемник SPORT0

4

0

-IRQE

3

0

BDMA

2

0

Передатчик SPORT1 или -IRQ1

1

0

Приемник SPORT0 или -IRQ0

0

0

Таймер

Таблица 4.1г Регистр состояния стека SSTAT

Разряд

Исходное состояние

Назначение

7

0

Стек циклов переполнен

6

1

Стек циклов пуст

5

0

Стек состояний переполнен

4

1

Стек состояний пуст

3

0

Стек счетчика переполнен

2

1

Стек счетчика пуст

1

0

Стек счетчика команд переполнен

0

1

Стек счетчика команд пуст

Таблица 4.1д Регистр управления прерываниями ICNTL

Разряд

Исходное состояние

Назначение

4

X

Вложенность прерываний: 0 — запрещена, 1 — разрешена

3

0

Не используется

2

X

Чувствительность -IRQ2: 0 — уровень, 1 — фронт

1

X

Чувствительность -IRQ1: 0 — уровень, 1 — фронт

0

X

Чувствительность -IRQ0: 0 — уровень, 1 — фронт

Таблица 4.1е Регистр установки и сброса прерываний IFC (только запись)

Разряд

Исходное состояние

Назначение

15

0

Принудительная установка прерывания -IRQ2

14

0

Принудительная установка прерывания передатчика SPORT0

13

0

Принудительная установка прерывания приемника SPORT0

12

0

Принудительная установка прерывания -IRQE

11

0

Принудительная установка прерывания BDMA

10

0

Принудительная установка прерывания передатчика SPORT1 или -IRQ1

9

0

Принудительная установка прерывания приемника SPORT0 или -IRQ0

8

0

Принудительная установка прерывания таймера

7

0

Сброс прерывания -IRQ2

6

0

Сброс прерывания передатчика SPORT0

5

0

Сброс прерывания приемника SPORT0

4

0

Сброс прерывания -IRQE

3

0

Сброс прерывания BDMA

2

0

Сброс прерывания передатчика SPORT1 или -IRQ1

1

0

Сброс прерывания приемника SPORT0 или -IRQ0

0

0

Сброс прерывания таймера

X — произвольное состояние после сброса.

Блок арифметико-логического устройства ALU включает в себя:

• два 16-разрядных регистра операндов AX0 и AX1;

• два 16-разрядных регистра операндов AY0 и AY1;

• один 16-разрядный регистр результата AR;

• один 16-разрядный регистр обратной связи AF.

Все эти регистры имеют своих двойников — теневые регистры, изображенные на рисунке программно-логической модели процессора в виде теней. Переключение между основными и теневыми регистрами производится программно. Блок умножителя MAC включает в себя:

• два 16-разрядных регистра операндов MX0 и MX1;

• два 16-разрядных регистра операндов MY0 и MY1;

• два 16-разрядных регистра результата MR0 и MR1;

• один 8-разрядный регистра результата MR2;

• один 16-разрядный регистр обратной связи AMF.

Блок устройства сдвига SHIFTER включает в себя:

• два 16-разрядных регистра результата SR0 и SR1;

• один 5-разрядный регистр блочных операций SB;

• один 8-разрядный регистр экспоненты SE;

• один 16-разрядный регистр операнда SI.

Так же как и в ALU, в блоках MAC и SHIFTER все регистры имеют своих двойников — теневые регистры.

Устройство обмена между шинами представляет собой 8-разрядный регистр PX, участвующий в пересылках между шинами адреса и данных.

Остальные регистры процессора распределены между блоками таймера, интерфейсной памяти, портов SPORT0 и SPORT1, портов IDMA и BDMA и блоком программируемых флагов.

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

Всего в процессоре отведено тридцать две ячейки 16-разрядных слов с адреса 0x3FE0 по адрес 0x3FFF для регистров такого типа. Часть ячеек памяти для таких регистров не используется в рассматриваемом процессоре ADSP-2181, но используется в других процессорах семейства ADSP-21XX.

В табл. 4.2 приведено назначение разрядов всех регистров, отображенных на память процессора.

Таблица 4.2а Регистр управления системой SCR, адрес памяти данных = 0x3FFF

Разряд

Исходное состояние

Назначение

15…13

0

Не используются

12

0

Разрешение порта SPORT0: 0=порт запрещен, 1=порт разрешен

11

0

Разрешение порта SPORT1: 0=порт запрещен, 1=порт разрешен

10

0

Конфигурация режима работы порта SPORT1: 0=сигналы FI FO IRQ0 IRQ1 SCLK, 1=последовательный порт SPORT1

9…3

0

Не используются

2…0

1

Циклы ожидания памяти программ от 0 до 7

Таблица 4.2б Регистр тактов ожидания WSR, адрес памяти данных=0x3FFE

Разряд

Исходное состояние

Назначение

15

0

Не используется

14…12

1

Циклы ожидания памяти данных от 0 до 7

11…9

1

Циклы ожидания 3-й группы портов ввода-вывода от 0 до 7

8…6

1

Циклы ожидания 2-й группы портов ввода-вывода от 0 до 7

5…3

1

Циклы ожидания 1-й группы портов ввода-вывода от 0 до 7

2…0

1

Циклы ожидания 0-й группы портов ввода-вывода от 0 до 7

Таблица 4.2в Регистры таймера

Разряд

Исходное состояние

Назначение

Регистр периода таймера TPERIOD, адрес памяти данных=0x3FFD

15…0

X

Период таймера от 0 до 0xFFFF

Регистр счетчика таймера TCOUNT, адрес памяти данных=0x3FFC

15…0

X

Счетчик таймера от 0 до 0xFFFF

Регистр масштабирования таймера TSCALE, адрес памяти данных=0x3FFB

15…8

0

Не используются

7…0

X

Масштабирование таймера от 0 до 0xFF

Таблица 4.2г Регистры последовательного порта SPORT0

Разряд

Исходное состояние

Назначение

Регистр разрешения многоканального приема S0RW1, адрес памяти данных = 0x3FFA

15…0

X

Разрешение приема канала 31…16

Регистр разрешения многоканального приема S0RW0, адрес памяти данных = 0x3FF9

15…0

X

Разрешение приема канала 15…0

Регистр разрешения многоканальной передачи S0TW1, адрес памяти данных=0x3FF8

15…0

X

Разрешение передачи канала 31…16

Регистр разрешения многоканальной передачи S0TW0, адрес памяти данных=0x3FF7

15…0

X

Разрешение передачи канала 15…0

Регистр управления S0CR, адрес памяти данных=0x3FF6

15

0

Разрешение многоканальности: 0 — запрещено, 1 — разрешено

14

0

Разрешение внутреннего тактового генератора: 0 — запрещен, 1 — разрешен

13

0

Требование кадровой синхронизации приема: 0 — не требуется, 1 — требуется (в многоканальном режиме — задержка)

12

0

Требование широкого кадрового импульса приемника: 0 — не требуется, 1 — требуется (в многоканальном режиме — задержка)

11

0

Требование кадровой синхронизации передатчика: 0 — не требуется, 1 — требуется (в многоканальном режиме — задержка)

10

0

Требование широкого кадрового импульса передатчика: 0 — не требуется, 1 — требуется (в многоканальном режиме — задержка)

9

0

Разрешение внутреннего тактового генератора передатчика: 0 — запрещен, 1 — разрешен (в многоканальном режиме — число каналов: 0 — 24 канала, 1 — 32 канала)

8

0

Разрешение внутреннего кадрового генератора приемника: 0 — запрещено, 1 — разрешено

7

0

Разрешение инвертирования кадрового генератора передатчика: 0 — запрещено, 1 — разрешено (только в многоканальном режиме)

6

0

Разрешение инвертирования кадрового генератора приемника: 0 — запрещено, 1 — разрешено

5, 4

0

Формат данных: 00 — выравнивание по правому краю, старшие биты=0, 01 — выравнивание по правому краю, старшие биты=знаку, 10 — компандирование по МЮ закону, 11 — компандирование по А закону

3…0

0

Длина слова минус 1

Регистр делителя тактовых импульсов S0CLKDIV, адрес памяти данных = 0x3FF5

15…0

0

Делитель частоты тактовых импульсов = (CLKOUT/2*SCLK)-1

Регистр делителя кадровых импульсов приемника S0RFDIV, адрес памяти данных=0x3FF4

15...0

0

Делитель частоты тактовых импульсов = (SCLK/RFS)-1

Регистр управления авто буферизацией S0ABUF, адрес памяти данных = 0x3FF3

15

0

Не используется

14

0

Бит разрешения CLKOUT

13

0

Не используется

12

0

Бит управления округлением со смещением

11…9

0

Номер индексного регистра передатчика

8, 7

0

Номер регистра модификатора передатчика

6…4

0

Номер индексного регистра приемника

3, 2

0

Номер регистра модификатора приемника

1

0

Разрешение автобуферизации передатчика

0

0

Разрешение автобуферизации приемника

Таблица 4.2д Регистры последовательного порта SPORT1

Разряд

Исходное состояние

Назначение

Регистр управления S1CR, адрес памяти данных=0x3FF2

15

0

Флаг FO (только чтение)

14

0

Разрешение внутреннего тактового генератора: 0 — запрещен, 1 — разрешен

13

0

Требование кадровой синхронизации приема: 0 — не требуется, 1 — требуется

12

0

Требование широкого кадрового импульса приемника: 0 — не требуется, 1 — требуется

11

0

Требование кадровой синхронизации передатчика: 0 — не требуется, 1 — требуется

10

0

Требование широкого кадрового импульса передатчика: 0 — не требуется, 1 — требуется

9

0

Разрешение внутреннего тактового генератора передатчика: 0 — запрещен, 1 — разрешен

8

0

Разрешение внутреннего кадрового генератора приемника: 0 — запрещено, 1 — разрешено

7

0

Разрешение инвертирования кадрового генератора передатчика: 0 — запрещено, 1 — разрешено

6

0

Разрешение инвертирования кадрового генератора приемника: 0 — запрещено, 1 — разрешено

5, 4

0

Формат данных: 00 — выравнивание по правому краю, старшие биты=0, 01 — выравнивание по правому краю, старшие биты=знаку, 10 — компандирование по МЮ закону, 11 — компандирование по А закону

3…0

0

Длина слова минус 1

Регистр делителя тактовых импульсов S1CLKDIV, адрес памяти данных=0x3FF1

15…0

0

Делитель частоты тактовых импульсов = (CLKOUT/2*SCLK)-1

Регистр делителя кадровых импульсов приемника S1RFDIV, адрес памяти данных=0x3FF0

15…0

0

Делитель частоты тактовых импульсов = (SCLK/RFS)-1

Регистр управления автобуферизацией S1ABUF, адрес памяти данных=0x3FEF

15

0

Блокирование вывода XTAL в режиме пониженной мощности: 0 — активен, 1 — блокирован (этот вывод должен быть блокирован, если к процессору подключен генератор, а не кварцевый резонатор)

14

0

Разрешение задержки запуска процессора из режима пониженной мощности на 4096 циклов: 0 — запрещено, 1 — разрешено

13

0

Принудительный вход в режим пониженной мощности: 0 — нормальный режим, 1 — режим пониженной мощности (осуществляется переход на вектор прерывания пониженной мощности)

12

0

Принудительный перезапуск процессора при подаче питания: 0 — нормальный режим, 1 — программный перезапуск

11…9

0

Номер индексного регистра передатчика

8, 7

0

Номер регистра модификатора передатчика

6…4

0

Номер индексного регистра приемника

3, 2

0

Номер регистра модификатора приемника

1

0

Разрешение автобуферизации передатчика

0

0

Разрешение автобуферизации приемника

Таблица 4.2е Регистры управления программируемыми флагами

Разряд

Исходное состояние

Назначение

Регистр управления программируемыми флагами PFTYPE, адрес памяти данных=0x3FE6

15

0

Не используется

14…12

1

Циклы ожидания байтовой памяти данных BDMA от 0 до 7

11

1

Разрешение выборки портов ввода-вывода сигналом -CMS: 0 — запрещено, 1 — разрешено

10

0

Разрешение выборки байтовой памяти данных BDMA сигналом -CMS: 0 — запрещено, 1 — разрешено

9

1

Разрешение выборки памяти данных сигналом -CMS: 0 — запрещено, 1 — разрешено

8

1

Разрешение выборки памяти программ сигналом -CMS: 0 — запрещено, 1 — разрешено

7…0

0

Режим работы программируемых выводов флагов PF7…PF0: 0 — выход, 1 — вход

Регистр управления программируемыми флагами PFDATA, адрес памяти данных=0x3FE5

15…8

X

Не используются

7…0

X

Данные программируемых выводов флагов PF7…PF0 (чтение/запись)

Таблица 4.2ж Регистры управления портом байтовой памяти BDMA

Разряд

Исходное состояние

Назначение

Регистр-счетчик слов BWCOUNT, адрес памяти данных=0x3FE4

15, 14

0

Не используются

14…0

0x20/0

Значение счетчика (когда MMAP=0 и BMODE=0 значение счетчика = 0x20, когда MMAP=1 или BMODE=1 значение счетчика = 0)

Регистр управления BDMACR, адрес памяти данных = 0x3FE3

15…8

0

Номер страницы BDMA от 0 до 0xFFFF

7…4

0

Не используются

3

1

Режим работы процессора при выполнении циклов BDMA: 0 — работа, 1 — останов

2

0

Направление передачи данных: 0 — чтение из BDMA, 1 — запись в BDMA

1, 0

0

Тип данных: 00 — память программ 24 разрядов, 01 — память данных 16 разрядов, 10 — память данных 8 старших разрядов, 11 — память данных 8 младших разрядов

Регистр внешнего адреса BEAD, адрес памяти данных = 0x3FE2

15, 14

0

Не используются

13…0

0

Значение внешнего адреса на шине процессора, при обмене через BDMA (от 0 до 0x3FFF)

Регистр внутреннего адреса BIAD, адрес памяти данных = 0x3FE1

15, 14

0

Не используются

13…0

0

Значение внутреннего адреса памяти процессора при обмене через BDMA (от 0 до 0x3FFF)

Таблица 4.2з Регистр управления IDMACR

Разряд

Исходное состояние

Назначение

15

0

Не используется

14

0

Указатель типа памяти: 0 = память программ РМ, 1 = память данных DM

13...0

0

Значение начального адреса памяти процессора при обмене через IDMA (от 0 до 0x3FFF)

X — произвольное состояние после сброса.

Условные обозначения регистров в таблицах соответствуют их названиям на программно-логической модели, изображенной на рис. 4.1.

Все перечисленные выше регистры позволяют осуществлять полный контроль и управление над процессором со стороны программы.

Глава 5. Система прерываний

В этой главе описывается система прерываний процессора, позволяющая процессору оперативно реагировать на различные события.

Диспетчер прерываний позволяет процессору реагировать на одиннадцать возможных прерываний и сброс. Все векторы прерываний процессора ADSP-2181 представлены в табл. 5.1.

Таблица 5.1 Векторы прерываний сигнального процессора ADSP-2181

Приоритет

Источник прерывания

Адрес (HEX)

Высший приоритет 0

Сброс (или выход из режима пониженной мощности при установке 12-го разряда регистра S1ABUF=1)

0000

1

Снижение потребляемой мощности (немаскируемое прерывание)

002C

2

IRQ2

0004

3

IRQL1

0008

4

IRQL0

000C

5

SPORT0 Передатчик

0010

6

SPORT0 Приемник

0014

7

IRQE

0018

8

BDMA прерывание

001C

9

SPORT1 Передатчик или IRQ1

0020

10

SPORT1 Приемник или IRQ0

0024

11 Низший приоритет

Таймер

0028

Прерывания в процессоре имеют различную приоритетность, от 0 до 11. При возникновении любого из прерываний, процессор выполняет переход на подпрограмму обработки соответствующего прерывания, адрес которой заложен в векторе данного прерывания. Адреса векторов прерываний расположены в самом начале программной памяти процессора через четыре 24-разрядных слова команды, что позволяет производить простую обработку или выход из прерывания на месте, без перехода на подпрограмму обработчика прерывания. В противном случае может быть выполнен безусловный переход на подпрограмму обработчика прерывания командой jump.

Процессор ADSP-2181 имеет четыре вывода для поддержки внешних прерываний: IRQ2, IRQL0, IRQL1 и IRQE. Кроме того, благодаря возможности SPORT1 быть переконфигурированным на выводы флагов FLAG_IN, FLAG_OUT и прерываний IRQ0, IRQ1, процессор может иметь еще два входа внешних прерываний вместо внутренних прерываний SPORT1. В результате, в общей сложности процессор может иметь шесть внешних прерываний.

Помимо внешних прерываний, процессор имеет и внутренние источники прерываний. Источниками внутренних прерываний являются таймер, байтовый порт BDMA, два последовательных порта SPORT1 и SPORT2, программное прерывание сброса и прерывание, вызываемое снижением напряжения питания.

Все прерывания, кроме немаскируемого и сброса, можно запретить с помощью регистра IMASK (см. табл.1). Кроме того, можно программно сгенерировать или сбросить некоторые прерывания с помощью регистра IFC.

Процессор реагирует на уровень сигналов на выводах прерываний IRQL0 и IRQL1. Прерывание IRQE возникает по фронту изменения сигнала на этом выводе. Чувствительность процессора к сигналам IRQ0, IRQ1 и IRQ2 определяется программно, с помощью регистра ICNTL.

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

Часть II. Программирование

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

Глава 6. Первая программа

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

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

Введите текст этой программы в компьютер с помощью любого текстового редактора и сохраните в файле с именем mem_clr.dsp или скопируйте с компакт-диска, прилагаемого к данной книге.

/***********************************************************/

/* Программа mem_clr загружается в память программ и после */

/* запуска заполняет память данных сигнального процессора  */

/* с адреса 0x0000 по адрес 0x3fdf числовыми значениями    */

/*                                                         */

/* Версия: 1.0                                             */

/* Автор:  О.Д.Вальпа                                      */

/***********************************************************/

.module/RAM/ABS=0 mem_clr;       { Модуль памяти mem_clr с адреса 0  }

.include <def2181.h>;            { Включить файл определений         }

.var/dm/ram/circ buf_dm[0x3fdf]; { Циклический буфер в памяти данных }

jump BEGIN; nop; nop; nop; { Вектор прерывания сброса процессора }

rti; nop; nop; nop;        { Вектор прерывания IRQ2              }

rti; nop; nop; nop;        { Вектор прерывания IRQL1             }

rti; nop; nop; nop;        { Вектор прерывания IRQL0             }

rti; nop; nop; nop;        { Вектор прерывания SPORT0 TX         }

rti; nop; nop; nop;        { Вектор прерывания SPORT0 RX         }

rti; nop; nop; nop;        { Вектор прерывания IRQE              }

rti; nop; nop; nop;        { Вектор прерывания BDMA              }

rti; nop; nop; nop;        { Вектор прерывания SPORT1 TX (IRQ1)  }

rti; nop; nop; nop;        { Вектор прерывания SPORT1 RX (IRQ0)  }

rti; nop; nop; nop;        { Вектор прерывания TIMER             }

rti; nop; nop, nop;        { Вектор прерывания POWER DOWN        }

/************** начало программы ************************************/

BEGIN:                                      { Метка начала программы }

ax0 = b#0111111110000000; dm(pftype) = ax0; {Инициализация флагов PF}

{        │└┬┘││││76543210                                            }

{        │ │ ││││└+++++++ - PF0-PF7: 0-вход 1-выход                  }

{        │ │ │││└──────── - PM - выход -CMS                          }

{        │ │ ││└───────── - DM | 0-запрещен                          }

{        │ │ │└────────── - BM | 1-разрешен                          }

{        │ │ └─────────── - IOM--                                    }

{        │ └───────────── - От 0 до 7 циклов задержки BDMA           }

{        └ He используется, всегда=0                                 }

ax0 = b#0000000010000000; dm(PFDATA) = ax0;{Управление светодиодом }

{                76543210                                           }

{                │   └──┴ - Вход:Код клавиш                         }

{                └─────── - Выход:Светодиод                         }

i0 = ^buf_dm;       { Индексный регистр i0=адресу начала буфера     }

l0 = %buf_dm;       { Регистр длины l0=длине буфера                 }

m0 = 1;             { Регистр модификатора m0=1                     }

ar = 0x1234;        { Записать данные в рабочий регистр ar          }

cntr=10;            { Загрузить счетчик циклов                      }

do CLR_DM until се; { Выполнять до CLR_DM пока счетчик не обнулится }

dm(i0, m0) = ar;   { Заполнение очередной ячейки памяти данных     }

CLR_DM:nop;         { Пустая команда                                }

toggle fl2;         { Инвертировать вывод процессора FL2            }

dm(0) = ar;         { Заполнение ячейки памяти данных с адресом 0   }

ar = ar + 1;        {  увеличивающимися значениями                  }

ax0 = dm(PFDATA);   { Читать код клавиш                             }

dm(1) = ax0;        {  и записать в ячейку памяти данных по адресу 1}

jump CLR_DM;        { Зациклить программу                           }

.endmod;             { Конец программы                               }

Имя данного файла можно изменить на любое другое, длиной от одного до восьми символов, разрешенных для имен файлов. Расширение «dsp» выбрано не случайно. При трансляции программы, компилятор будет искать файл программы именно с таким расширением. Если он не найдет такой файл, то выведет сообщение Preprocessor failed to open mem_clr.dsp.

Рассмотрим структуру и состав приведенного выше файла. Как видно из примера, в начале файла программы находится описание назначения программы, ее версии и пр. атрибуты, заключенные между символами /* и */ в качестве комментариев. Далее следуют три строки директив с комментариями, описывающими назначение этих директив и заключенными между фигурными скобками. Фигурные скобки также предназначены для вставки комментариев в программу. Файл def2181.h, включаемый в файл программы с помощью директивы #include, состоит из строк, присваивающих символьным именам регистров значение их адресов в области памяти данных процессора.

Использование символьных имен позволяет записывать в программе не конкретные цифровые значения адресов или данных, а их словесные описания, более понятные и легче запоминающиеся. Это делается для придания программе наглядности, предотвращения машинальных ошибок во время ее создания и облегчения ее понимания. Содержимое файла def2181.h приведено ниже.

.const IDMA=                0x3fe0;

.const BDMA_BIAD=           0x3fe1;

.const BDMA_BEAD=           0x3fe2;

.const BDMA_BDMA_Ctrl=      0x3fe3;

.const BDMA_BWCOUNT=        0x3fe4;

.const PFDATA=              0x3fe5;

.const PFTYPE=              0x3fе6;

.const SPORT1_Autobuf=      0x3fef;

.const SPORT1_RFSDIV=       0x3ff0;

.const SPORT1_SCLKDIV=      0x3ff1;

.const SPORT1_Control_Reg=  0x3ff2;

.const SPORT0_Autobuf=      0x3ff3;

.const SPORT0_RFSDIV=       0x3ff4;

.const SPORT0_SCLKDIV=      0x3ff5;

.const SPORT0_Control_Reg=  0x3ff6;

.const SPORT0_TX_Channels0= 0x3ff7;

.const SPORT0_TX_Channels1= 0x3ff8;

.const SPORT0_RX_Channels0= 0x3ff9;

.const SPORT0_RX_Channels1= 0x3ffa;

.const TSCALE=              0x3ffb;

.const TCOUNT=              0x3ffс;

.const TPERIOD=             0x3ffd;

.const DM_Wait_Reg=         0x3ffe;

.const System_Control_Reg=  0x3fff;

Описание этих символьных имен и их соответствие адресам памяти данных процессора приведено в табл. 6.1.

Таблица 6.1 Описание символьных имен регистров управления и состояния процессора ADSP-2181

Имя

Описание

Адрес

IDMA

Регистр управления IDMA

0x3FE0

BDMA_BIAD

Регистр внутреннего адреса BDMA

0x3FE1

BDMA_BEAD

Регистр внешнего адреса BDMA

0x3FE2

BDMA_BDMA_Ctrl

Регистр управления BDMA

0x3FE3

BDMA_BWCOUNT

Регистр счетчика слов BDMA

0x3FE4

PFDATA

Регистр данных программируемых флагов

0x3FE5

PFTYPE

Регистр управления программируемыми флагами

0x3FE6

SPORT1_Autobuf

Регистр управления автобуферизацией SPORT1

0x3FEF

SPORT1_RFSDIV

Регистр делителя кадровых импульсов SPORT1

0x3FF0

SPORT1_SCLKDIV

Регистр делителя тактовых импульсов SPORT1

0x3FF1

SPORT1_Control_Reg

Регистр управления SPORT1

0x3FF2

SPORT0_Autobuf

Регистр управления автобуферизацией SPORT0

0x3FF3

SPORT0_RFSDIV

Регистр делителя кадровых импульсов SPORT0

0x3FF4

SPORT0_SCLKDIV

Регистр делителя тактовых импульсов SPORT0

0x3FF5

SPORT0_Control_Reg

Регистр управления SPORT0

0x3FF6

SPORT0_TX_Channels0

Регистр младшего слова передатчика SPORT0

0x3FF7

SPORT0_TX_Channels1

Регистр старшего слова передатчика SPORT0

0x3FF8

SPORT0_RX_Channels0

Регистр младшего слова приемника SPORT0

0x3FF9

SPORT0_RX_Channels1

Регистр старшего слова приемника SPORT0

0x3FFA

TSCALE

Регистр масштабирования таймера

0x3FFB

TCOUNT

Регистр счетчика таймера

0x3FFC

TPERIOD

Регистр периода таймера

0x3FFD

DM_Wait_Reg

Регистр тактов ожидания памяти данных

0x3FFE

System_Control_Reg

Регистр управления системой

0x3FFF

Как видно из содержимого данного файла, в каждой его строке производится директивное назначение определенному символьному имени конкретного числового значения. Символьные имена могут быть произвольными, важно только, чтобы они одинаково записывались в данном файле и в самой программе. В дальнейшем мы часто будем использовать символьное описание регистров, для обращения к ним по записи или чтению из программы. В частности, в нашей программе mem_clr.dsp содержатся строки команд для обращения к регистру конфигурирования PFTYPE и регистру данных PFDATA программируемых флагов PF процессора. Файл def2181.h должен находиться в том же каталоге, в котором будет храниться файл программы во время ее трансляции. Иначе компилятор выдаст сообщение об ошибке во время компиляции программы.

Далее, в файле программы начинается запись команд. Поскольку с нулевого адреса памяти программ должны быть записаны векторы прерываний или их обработчики, первой располагается команда перехода jump BEGIN на начало программы, а затем команды возврата из прерывания rti для каждого из прерываний процессора. Все команды должны заканчиваться точкой с запятой, в соответствии с требованиями синтаксиса ассемблера. Заметьте, что в одной строке присутствует сразу несколько команд. Такая запись допускается компилятором ассемблера. Так как для каждого вектора прерывания в памяти программ отведено по четыре 24-разрядных ячейки памяти, а каждая команда процессора занимает одну 24-разрядную ячейку памяти, то оставшиеся неиспользованные ячейки памяти заполняются пустыми командами пор. Сразу же после метки BEGIN записаны команды инициализации конфигурационного регистра флагов PFTYPE с помощью рабочего регистра ax0 блока ALU процессора. Непосредственная запись константы в память данных не поддерживается процессором. Ниже располагаются строки комментариев с пояснением назначения каждого бита регистра флагов PFTYPE. Подобные записи позволяют хорошо документировать программу и облегчают тем самым ее отладку и последующее сопровождение. Аналогично описанным выше записям, в программе присутствуют строки команд записи в регистр данных PFDATA программируемых флагов слова управления светодиодом. Далее следуют команды инициализации некоторых регистров сигнального процессора. В частности, команда i0 = ^buf_dm; производит инициализацию индексного регистра, входящего в блок DAG сигнального процессора, т.е. присваивает индексному регистру i0 значение адреса начала буфера buf_dm, располагающегося в памяти данных процессора. Аналогично происходит инициализация других регистров этого блока и инициализация регистра ar блока ALU. Я намеренно указал на принадлежность регистров блокам процессора, для того чтобы показать связь между архитектурой процессора и выполняемой программой и тем самым облегчить понимание того, что происходит в самом процессоре при выполнении перечисленных команд программы. Далее в программе организуется циклическое заполнение памяти данных процессора значением регистра ar. После чего организуется цикл, состоящий из команд инвертирования выходного флага FL2 процессора и заполнения нулевой ячейки памяти регулярно увеличивающимся значением из регистра ar. Кроме того, в данном цикле организовано чтение состояния входов PF0-PF3 процессора и запись этих значений в ячейку памяти данных по адресу 1. Это сделано для того, чтобы при работе программы можно было увидеть с помощью осциллографа генерацию сигнала на выводе FL2, а также следить за изменением значений ячеек памяти с помощью симулятора или других аппаратно-программных средств, убеждаясь тем самым в правильной работе программы и нормальном функционировании процессора. Завершает программу директива окончания модуля программы endmod. В общем случае структура файла должна быть следующей:

/* Строки комментариев, описывающие */

/* название и назначение программы */

.Директива начала и названия модуля программы

.Директива 1

.Директива 2

...

.Директива N

Метка1:  Команда1 и операторы; /*Комментарии*/

Метка2:  Команда2 и операторы; /*Комментарии*/

...

МеткаN:  КомандаN и операторы; /*Комментарии*/

.Директива окончания программы

Естественно, что комментарии, некоторые директивы, метки и команды с операторами могут отсутствовать в программе. Здесь приведен лишь общий пример записи программ.

Директивы и команды заранее определены языком программирования и не допускают произвольных записей. Метка может состоять из произвольного набора букв, символа подчеркивания и цифр без пробелов, начинающихся с буквы, длиной не более 32 символов, и должна заканчиваться двоеточием. Команды могут записываться в верхнем или нижнем регистре. Компилятор по умолчанию не распознает регистр записей программы, т.е. является контекстно-независимым, и допускает запись комментариев, директив, меток и команд с операторами в любом регистре. Это необходимо учитывать при задании имен меткам. Так, например, метка MET1: и met1: будут восприниматься компилятором как одна и та же, что приведет к сообщению об ошибке. Для того чтобы компилятор различал регистр букв, необходимо включить в строку его запуска ключ -с. Комментарии могут содержать любые наборы произвольных символов в одной или нескольких строчках, заключенных между открывающейся { и закрывающейся фигурной скобкой } или между символами /* и */.

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

Для трансляции программы с целью получения машинного загрузочного кода для процессора нам потребуются программные средства разработки. Семейство процессоров ADSP сопровождается полным набором программного обеспечения (трансляторы и эмуляторы) и аппаратных отладочных средств (отладочные комплекты и внутрисхемные эмуляторы), предоставляемые фирмой Analog Device для разработки программ и облегчения процесса освоения программирования на практике.

На сегодняшний день существует два программных пакета кросс средств для разработки и отладки программ для сигнального процессора ADSP-2181. С появлением новых процессоров продолжают добавляться дополнительные инструментарии разработки программ. Первый из этих пакетов входит в поставку отладочного комплекта EZ-KIT Lite и работает под управлением операционной системы DOS, или в режиме эмуляции DOS под Windows. Второй пакет Visual DSP, более позднего происхождения, распространяется самостоятельно и работает под управлением операционной системы Windows. Все кросс средства доступны на сайте компании Analog Device по адресу www.analog.com. Каким из этих пакетов пользоваться, обычно решает сам пользователь. Каждый из пакетов имеет свои преимущества и недостатки. Поэтому познакомим читателей с обоими пакетами поочередно, а они сами сделают свой выбор. Вначале рассмотрим пакет кросс средств для работы под DOS. Данные средства разработки для сигнальных процессоров ADSP-2181 включают в себя:

• System Builder (системный конфигуратор (построитель) программы). Это программный инструмент для описания особенностей оборудования. Он определяет структуру аппаратной системы, позволяя разработчику указать количество доступной памяти, местоположение программной памяти и памяти данных и любого отображенного в память порта ввода-вывода для аппаратного окружения. Данный построитель использует высокоуровневые конструкции, записываемые программистом в файле с расширением sys. После обработки данного файла построитель формирует файл архитектуры с расширением ach. Файл архитектуры используется в дальнейшем компоновщиком, симулятором и эмулятором. Допускается не выполнять процедуру системного конфигурирования при использовании готового файла архитектуры для конкретного процессора.

• C compiler (компилятор языка Си). Осуществляет проверку и преобразование текстов программы, написанных на языке Си формата ANSI, в тексты программ на языке ассемблер семейства ADSP-21XX. Кроме того, он поддерживает встроенный ассемблерный код. Данный компилятор необходим только для трансляции программ, написанных на языке Си. При создании программ на языке ассемблера компилятор Си не используется.

• Assembler (ассемблер-компилятор). Преобразует тексты программ, написанных на языке ассемблера, в объектный (машинный) код процессора. Он поддерживает высокоуровневый синтаксис набора команд и осуществляет полную проверку синтаксиса программы. Кроме того, компилятор поддерживает гибкую структуру макросов и включение дополнительных файлов с помощью директивы include с помощью программы препроцессора. Как правило, компилятор состоит из нескольких программных утилит.

• Linker (компоновщик). Объединяет отдельно ассемблированные модули программы (отдельные файлы с текстами программ) в единый связанный машинный код. При необходимости, на этапе компоновки программы используется программа библиотекаря, для создания законченных программных библиотек, включаемых впоследствии в основную программу.

• Simulators (симулятор). Позволяет отлаживать программы путем имитации работы сигнального процессора в памяти персонального компьютера. Интерактивный пользовательский интерфейс симулятора поддерживает полное символическое ассемблирование и дизассемблирование эмулируемых команд. Симулятор полностью эмулирует конфигурацию аппаратного обеспечения, описанную с помощью файла архитектуры. Он обеспечивает покомандное выполнение ассемблерного кода ADSP-2181 и позволяет отображать на экране монитора внутренние регистры и память процессора.

• Splitter («сплиттер» — распределитель). Эта программа-утилита по выходным данным компоновщика формирует файл для прошивки ПЗУ, из которой автоматически может производиться загрузка программы в память процессора через порт BDMA.

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

Полный пакет кросс средств можно приобрести вместе с отладочным комплектом EZ-Kit Lite у представителей фирмы Analog Device. Облегченную версию кросс средств, для сигнального процессора ADSP-2181 под управлением операционной системы DOS, можно скачать с сайта www.xxivek.narod.ru. В качестве отладочного средства при этом можно использовать тестовую плату, описанную в гл. 3.

Установка полного пакета на компьютер не вызывает сложностей. Его необходимо инсталлировать на диск С в корневой каталог ADI_DSP. Облегченная версия кросс средств с сайта www.xxivek.narod.ru просто распаковывается и копируется в каталог C:\ADI_DSP. После этого необходимо создать рабочий каталог для ваших будущих рабочих программ на любом диске. Для каждого нового проекта лучше всего создавать отдельный каталог или подкаталог, это позволит упорядочить все проекты.

После установки средств разработки, в каталоге ADI_DSP должны находиться подкаталоги с файлами транслятора, библиотеками и другими служебными файлами. Основные исполняемые файлы располагаются после инсталляции пакета в каталоге C:\ADI_DSP\21XX\BIN\. Перечень исполняемых файлов и их назначение приведены в табл. 6.2.

Таблица 6.2 Назначение исполняемых файлов

Имя файла

Назначение

bld21.exe

Системный конфигуратор (построитель) программы

cc1.exe, g21.exe

Компиляторы языка Си

asm21.exe

Компилятор ассемблера

asmpp.exe

Ассемблер препроцессор

asm2.exe

Ассемблер

ld21.exe

Компоновщик (редактор связей)

Iib21.exe

Библиотекарь (программа для работы с библиотеками программ)

spl21.exe

Разделитель программ для программирования ПЗУ (сплиттер)

sim2181.exe

Симулятор программ для процессора ADSP-2181

hexbin2.exe

Преобразователь HEX кода в двоичный формат

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

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

Создается командный файл, в начале которого записываются строки определения пути поиска файлов и установки переменных среды, а далее записываются строки команд для автоматизации необходимого процесса трансляции. После запуска такого командного файла, с именем файла транслируемой программы в качестве параметра, произойдет полная трансляция файла программы, с получением всех необходимых файлов для загрузки в процессор. Ниже приведен текст такого командного файла, специально созданного мною для облегчения и ускорения трансляции программ для сигнального процессора ADSP-2181. Данный командный файл позволяет выполнять трансляцию файлов программ, начиная с компилятора, минуя операции построителя системы System Builder и трансляции программы с языка Си.

@echo off

set path=c:\adi_dsp\21XX\bin

set adi_dsp=c:\adi_dsp

if %1 == goto no_file

echo Компиляция...

asm21 %1 -2181 -l

if not exist %1.obj goto error

echo ...завершена успешно pause

echo Компоновка...

ld21 %1 -a adsp2181 -e %1 -x -g

if not exist %1.lda goto next1

del %1.lda

:next1

ren %1.exe %1.lda

if not exist %1.lda goto error2

echo ...завершена успешно pause

echo Сплиттинг...

rem для загрузки через BDMA

spl21 %1.lda %1 -loader -2181 > %1.msg

echo ...завершен успешно

pause

echo Преобразование в бинарный файл...

hexbin2 %1.bnm %1.bin m 0 > %1.msg

echo ...завершено успешно

pause

goto end

:error

echo Ошибка компиляции!

pause

goto end

:error2

echo He найден файл %1.lda !

pause

goto end

:no_file

echo Используйте: asmdsp.bat имя файла без расширения

pause

:end

Введите текст этого файла с помощью любого текстового редактора с кодировкой DOS в компьютер и сохраните в файле с именем asmdsp.bat или скопируйте с компакт-диска, прилагаемого к книге. Он позволит автоматизировать процесс трансляции файлов с программами для сигнального процессора. Если просмотреть строки этого командного файла, то нетрудно понять что он делает. В первой строке командного файла находится команда запрета отображения командных строк на экран. Далее следуют две строки для установки пути к рабочему каталогу с файлами трансляции и переменной adi_dsp. Затем проверяется, было ли введено имя файла в командной строке при запуске данного файла. Если имени задано не было, производится переход на метку с названием no file, после которой на экран отобразится подсказка о правильном использовании командного файла. Команда pause выводит строку «Нажмите любую клавишу…» и ожидает соответствующее действие от пользователя. Если имя файла для трансляции было задано в строке при запуске командного файла, то переход на метку не производится и начинается процесс компиляции файла с программой. Все процессы трансляции предваряются соответствующим сообщением. Компиляция выполняется командой asm21 %1 -2181 -l. Здесь после вызова программы компилятора asm21.exe с именем файла из командной строки %1 используется ключ -2181 для задания типа процессора и ключ -I для генерации листинга программы. Список всех ключей для конфигуратора bld21.exe, компилятора asm21.exe, компоновщика ld21.exe, распределителя spl2.exe и симулятора sim2181.exe можно получить, запустив отдельно соответствующую программу без параметров или с ключом -help. Переведенный текст этих сообщений приведен в табл. 6.3.

Таблица 6.3 Формат записи программ и назначение ключей

bld21.exe [-ключ] имя_файла

-c

Установить чувствительность к регистру символов

-help

Вывести на экран справку о программе

asm21.exe [-ключ_1] [-ключ_2] … [-ключ_N] имя_файла

-Dvar[=exp]

Определить идентификатор для Си препроцессора, например -dten=10

-c

Установить чувствительность к регистру символов

-cp

Включить Си препроцессор

-I

Создать файл листинга программы

-i [глубина]

Раскрыть содержимое включенных файлов в листинге с указанной глубиной

-m [глубина]

Раскрыть макросы в файле листинга с указанной глубиной

-p

Использовать только препроцессор

-s

Отменить семантическую проверку много функциональных инструкций

-o имя_файла

Переименовать выходной файл

-2181

Поддержать специальные ассемблерные инструкции для процессора ADSP-2181

-help

Вывести на экран справку о программе

ld21.exe имя_файла1 [имя_файла2] … [имя_файлаN] [-ключ_1] [-ключ_2] … [-ключ_N]

-i имя_файла

Указать командный списочный файл

-e имя

Присвоить выходным файлам новое имя (по умолчанию 210x.exe)

-a имя_файла

Указать файл описания архитектуры

-user имя_файла

Поиск библиотечного файла, созданного утилитой построителя библиотеки Iib21.exe

-s размер

Задать размер динамической памяти

-dir путь

Указать пути каталога для поиска файлов библиотек

-lib

Компоновать программу с библиотекой Си

-g

Создать файл таблицы символов *.sym

-pmstack

Переместить стек в память программ (PM)

-rom

Использовать ПЗУ версии библиотечных программ Си

-c

Создать стек для компилированных Си программ (DM)

-dryrun

Быстрый запуск для теста на ошибки без создания файла загрузки

-x

Создать файл распределения памяти *.map

-p

Поместить копию библиотечной подпрограммы на загрузочных страницах

-group file

Использовать файл групповых модулей

-help

Вывести на экран справку о программе

spl21.exe входной_файл выходной_файл [-ключ_1] [-ключ_2] … [-ключ_N]

-dm

Распределить только память данных DM

-pm

Распределить только память программ РМ

-bm

Распределить только память загрузки BM

-bs #

Установить размер загрузочной памяти (2048, 1024, 512 или 256 байт)

-bb #

Установить размер границы загрузки (2048 или 1024 байт)

-u

Формат выходного файла Motorola S (по умолчанию)

-i

Формат выходного файла Intel Hex

-us

Формат Motorola S1, байтовый (только с ключами -pm или -dm)

-us2

Формат Motorola S2, байтовый (только с ключами -pm или -dm)

-ui

Формат Intel Hex, байтовый (только с ключами -pm или -dm)

-loader

Создать загрузочный файл

-bp #

Большие загрузочные страницы, где # как HEX адрес

-bi #

Большие загрузочные страницы, где # как HEX величина

-flag

Большие загрузочные страницы с использованием выходных флагов

-Id

Использовать специальный загрузчик

-2181

Создать код для процессора ADSP-2181

sim2181 [-a имя_файла] [-c] [-e имя_файла] [-h] [-k имя_файла] [-v] [-w имя_файла]

-a имя_файла

Считывать при запуске файл архитектуры

-c

Установить чувствительность к регистру символов

-e имя_файла

Загрузить при запуске входной файл с расширением exe (lda)

-h

Вывести на экран справку о программе

-k имя_файла

Загрузить и выполнить файл командных строк

-o имя_файла

Генерировать файл с сообщениями об ошибках

-v

Избыточность

-w имя_файла

Запустить симулятор с загрузкой ранее созданного файла конфигурации окон с расширением win

После компиляции программы будет создан файл с именем программы и расширением obj. Однако если на этапе компиляции будут обнаружены ошибки, этого не произойдет и с помощью команды if not exist %1.obj goto error будет осуществлен переход на метку error, для выдачи соответствующего сообщения. При успешной компиляции трансляция программы продолжится.

Компоновка программы выполняется с помощью командной строки: ld21 %1 -a adsp2181 -e %1 -x -g. Здесь после команды вызова компоновщика ld21.exe с именем файла из строки запуска командного файла %1, следует несколько ключей с параметрами. Ключ -a adsp2181 указывает имя файла архитектуры процессора adsp2181.ach. Данный файл создан с помощью построителя программ System Builder и входит в поставку пакета кросс средств. Он состоит из пяти следующих строк:

$2181

$ADSP2181

$0000 3FFF paxINT_PM_USER t

$0000 3FDF dadINT_DM_USER t

$

Этот файл содержит данные, определяющие тип процессора и структуру его памяти, и всегда должен находиться в том же каталоге, где находится файл транслируемой программы. Ключ -е %1 назначает имя выходного файла. Ключи -x и -g предназначены для генерации файла карты памяти *.map и файла с таблицей символьных имен *.sym соответственно. Эти файлы можно использовать в дальнейшем для анализа распределения памяти процессора. Файл с расширением sym необходим, кроме того, для отладки программы с помощью симулятора sim2181.exe. В результате компоновки будет получен файл с именем программы и расширением exe. Этот файл уже можно использовать для загрузки в симулятор или непосредственно в процессор, например через интерфейс IDMA. Формат данного файла приведен в табл. 6.4.

Таблица 6.4 Формат загрузочного файла

Символ

Описание назначения

←←i

Признак начала загрузочного файла

@PA

Признак блока памяти программ РМ

0000

Адрес загрузки кодов в память РМ

Символ

Описание назначения

123456

Первый код команды

789abc

Второй код команды

def012

Третий код команды

…

и т.д.

#123XXXXXXXX

Признак конца блока команд с контрольной суммой

@DA

Признак блока памяти данных DM

0000

Адрес загрузки данных в память DM

1234

Первое слово данных

5679

Второе слово данных

…

и т.д.

#123XXXXXXXX

Признак конца блока данных с контрольной суммой

←←o

Признак конца загрузочного файла

X — контрольная сумма адреса и данных.

Позже мы подробно рассмотрим способ его загрузки в процессор через интерфейс IDMA. Несмотря на то, что этот файл имеет расширение exe, он не имеет ничего общего с исполняемыми файлами для персональных компьютеров. Тем не менее, случайный его запуск на компьютере может привести к непредсказуемым результатам. Непонятно, чем руководствовалась фирма Analog Device, давая такое расширение этому файлу при разработке кросс средств. Для устранения таких неприятных моментов в командный файл включены следующие четыре строчки:

if not exist %1.lda goto next1

del %1.lda

:next1

en %1.exe %1.lda

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

При успешной генерации загрузочного файла будет выведено соответствующее сообщение и осуществлен переход к группе команд для формирования файла прошивки для ПЗУ, из которого может производиться автоматическая загрузка процессора через интерфейс BDMA. Данный процесс называется «сплиттингом» (распределением) и осуществляется командой: spl21 %1.lda %1 - loader-2181 > %1.msg.

Здесь после команды вызова сплиттера sp21.exe с именем файла из командной строки с расширением Ida, следует несколько ключей и команда перенаправления вывода сообщений, с помощью символа >, в файл с расширением msg. Ключ -loader предназначен для добавления в выходной файл кода загрузчика, а ключ -2181 позволяет формировать код загрузки для процессора ADSP-2181. О коде загрузки я расскажу чуть позже.

В результате работы сплиттера будет создан файл прошивки для ПЗУ, с расширением bnm HEX формата Motorola. На практике, для программирования микросхем памяти чаще пользуются бинарным форматом файлов. Поэтому в командном файле добавлено еще несколько строк, осуществляющих преобразование файла bnm в бинарный файл с расширением bin. Для этого используется распространенная программа hexbin2.exe. Эту программу также можно найти на компакт-диске.

Теперь, когда мы познакомились со всеми процедурами трансляции, выполняемыми с помощью командного файла asmdsp.bat, можно начать транслировать нашу программу. Не забудьте, что вместе с программой в каталоге проекта должен находиться файл описания def2181.h, файл архитектуры adsp2181.ach и созданный и описанный выше командный файл asmdsp.bat.

Выполните трансляцию программы mem_clr.dsp с помощью командной строки asmdsp.bat mem_clr. Обратите внимание на то, что в качестве параметра для командного файла используется имя нашей программы без расширения. Оно будет автоматически подставляться вместо символов %1 командного файла. В результате работы командного файла на экране должны последовательно появиться сообщения:

Компиляция...

...завершена успешно

Нажмите любую клавишу...

Компоновка...

...завершена успешно

Нажмите любую клавишу...

Сплиттинг...

...завершен успешно

Нажмите любую клавишу...

Преобразование в бинарный файл...

...завершено успешно

Нажмите любую клавишу...

По завершении работы командного файла в каталоге с программой должны появиться файлы с именем программы и расширениями int, lst, obj, lda, map, sym, msg, cde, bnl, bnm, bnu и bin. Описание назначения данных файлов проекта в краткой форме приведено в табл. 6.5.

Таблица 6.5 Описание расширений файлов проекта

Расширение

Описание

bat

Командный файл

sys

Исходный файл системной архитектуры

ach

Файл описания архитектуры

dsp

Файл ассемблерного модуля (текст программы)

lst

Файл листинга

int

Файл инициализации

obj

Объектный файл

cde

Файл кода

dat

Файл инициализации данных кода

exe (lda)

Файл загрузки образа памяти

map

Файл распределения памяти

sym

Файл символов

bnu

Выходной файл разделителя программ. Содержит старшие байты

bnm

Выходной файл разделителя программ. Содержит средние байты

bnl

Выходной файл разделителя программ. Содержит младшие байты

bin

Файл для программирования ПЗУ в двоичном формате

msg

Файл сообщений

Итак, с помощью приведенного выше командного файла мы получили необходимые нам файлы с расширениями lda и bin для непосредственной загрузки в память процессора и для прошивки ПЗУ соответственно. Файл с расширением sym понадобится нам для отладки программы с помощью программы симулятора sim2181.exe.

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

Для автоматического удаления этих файлов я рекомендую создать и использовать еще один командный файл asmclr.bat, состоящий из строк:

del *.map

del *.lst

del *.hex

del *.msg

del *.cde

del *.int

del *.obj

del *.bnl

del *.bnm

del *.bnu

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

Теперь можно приступить к отладке программы. Проследить за ходом выполнения программы и изменением состояния внутренних регистров и ячеек памяти процессора нам поможет программа симулятора sim2181.exe, входящая в состав средств разработки программ.

Данная программа работает только в операционной системе DOS и даже не допускает работу в режиме эмуляции DOS из Windows. Поэтому для запуска данного симулятора необходимо перегрузить компьютер в режим работы DOS, после чего необходимо запустить программу симулятора в командной строке sim2181.exe. После загрузки программы на экране монитора должно появиться окно с изображением названия и версии программы (рис. 6.1).

Рис. 6.1. Окно с изображением названия и версии программы

Несколько секунд спустя должно появиться окно с главным меню и приглашением к вводу команд в центре экрана (рис. 6.2).

Рис. 6.2. Окно с главным меню

Главное меню программы состоит из десяти раскрывающихся закладок команд. Симулятор имеет встроенную справочную систему по всем командам меню, вызываемую с помощью клавиши F1 клавиатуры. Назначение клавиш управления симулятора приведено в табл. 6.6.

Таблица 6.6. Назначение клавиш управления симулятора

Клавиша или комбинация

Описание выполняемой функции

Функции выполнения программы

F4

Запустить программу на выполнение

F10

Выполнять программу по шагам

Shift+F10

Выполнять N шагов программы

F9

Установить/сбросить точку останова программы

Shift+F9

Установить/сбросить специальную точку останова программы

Функции памяти

Ctrl+D

Дамп памяти

Ctrl+F

Заполнить память

Ctrl+G

Перейти по адресу памяти

Ctrl+M

Загрузить память

Функции размера окна

Shift+F5

Увеличить окно по вертикали

Shift+F6

Уменьшить окно по вертикали

Shift+F7

Увеличить окно по горизонтали

Shift+F8

Уменьшить окно по горизонтали

Функции перемещения окна

F5

Переместить окно вверх

F6

Переместить окно вниз

F7

Переместить окно влево

F8

Переместить окно вправо

Функции выбора окна

ESC

Закрыть текущее окно

F2

Выбрать следующее окно

F3

Выбрать окно главного меню

Ctrl+L

Показать список активных окон

Функции отображения окна

F1

Вызов окна помощи

Ctrl+T

Переключение формата отображения окна

Для перехода в главное меню и загрузки программы нажмите последовательно клавиши Esc и F3 на клавиатуре. С помощью стрелок курсора выделите закладку File главного меню и раскройте ее, нажав клавишу Enter. В раскрывшемся списке команд выберите команду Load Executable File (загрузить исполняемый файл), а в открывшемся окне ввода введите имя файла mem_clr.lda и завершите ввод, нажав клавишу Enter.

Откройте в пунктах главного меню Memory и Register окна памяти программ Program Memory, памяти данных Data Memory, флагов Flags, регистров генератора адреса DAG Registers и регистров арифметико-логического устройства Computational Alternate Registers. После чего разместите эти окна на экране с помощью клавиш управления окнами симулятора в соответствии с рис. 6.3, используя клавиши управления, описанные в табл. 6.6.

Рис. 6.3. Экран управления окнами симулятора

Данные окна позволят наблюдать за ходом выполнения программы и состоянием памяти и регистров процессора. Теперь можно выполнять программу по шагам, нажимая клавишу F10 на клавиатуре, или запустить автоматическое выполнение программы с помощью клавиши F4.

Останов программы производится повторным нажатием клавиши F4. Во время выполнения программы в окне памяти программ Program Memory можно наблюдать процесс выполнения ассемблерных команд, а в окнах регистров и памяти данных изменение значений регистров и ячеек памяти.

Для сохранения конфигурации окон и использования этой конфигурации при повторных запусках симулятора можно сохранить ее в файле с помощью команды Save Window File из закладки File главного меню. При сохранении конфигурации необходимо будет задать имя файла, например mem_clr. После сохранения конфигурации и выхода из симулятора в каталоге будет находиться файл с именем mem_clr.win. Для выхода из симулятора необходимо выбрать команду Exit или Quit из закладки Quit главного меню и в открывшемся окне подтверждения выхода нажать поочередно клавишу пробела Space, а затем клавишу Enter. При новом запуске симулятора, вместо повторного открытия окон, достаточно будет загрузить файл с помощью команды Load Window File из закладки File главного меню симулятора.

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

Глава 7. Порт BDMA

В этой главе описывается порт байтового прямого доступа к памяти процессора, под названием BDMA (Byte Data Memory Access).

Теперь можно приступить к загрузке транслированной и отлаженной программы непосредственно в сигнальный процессор. Для выполнения данной процедуры и практического освоения сигнального процессора с отладкой программ аппаратно можно воспользоваться тестовой платой, описанной в гл. 3.

Запрограммируйте флэш ПЗУ типа Am29F040 содержимым файла mem_clr.bin с помощью любого подходящего для этих целей программатора и вставьте запрограммированную микросхему в панельку на место микросхемы D7 тестовой платы. После подачи напряжения питания на тестовую плату произойдет автоматическая загрузка программы из ПЗУ через порт BDMA в память сигнального процессора, и ее выполнение. Убедиться в том, что программа работает, можно будет с помощью осциллографа, подключенного к выводу FL2 процессора. На этом выводе должен формироваться сигнал в виде меандра с частотой около 2МГц, а светодиод HL2 должен при этом светиться.

Рассмотрим подробнее механизм автоматической загрузки сигнального процессора из ПЗУ, для лучшего понимания происходящих при этом процессов. При подаче питания на тестовую плату, описанную в гл. 3, цепь сброса R1, CP1 формирует сигнал -RKEY, который устанавливает триггер, построенный на элементах D6.1 и D6.2, в состояние, при котором сигнал BMODE будет находиться в состоянии логического нуля. Сигнальный процессор анализирует состояние данного сигнала и сигнала на входе вывода MMAP после сброса и распознает, что загрузка программы в программную память процессора будет производиться из ПЗУ через интерфейс BDMA. При этом процессор автоматически заносит в регистры порта BDMA определенные значения, описанные в предыдущей главе, для того чтобы произвелась автоматическая загрузка 32 слов программы-загрузчика разрядностью 24 бита побайтно в программную память процессора и затем ей было передано управление для загрузки остальной части программы.

Как было сказано выше, программа-загрузчик автоматически записывается в начало файла прошивки ПЗУ с помощью сплиттера во время трансляции программы. После автоматической загрузки из ПЗУ в память программ процессора 32 слов программы- загрузчика через интерфейс BDMA происходит перезапуск процессора и начинает выполняться программа загрузчика, которая осуществляет полную загрузку основной рабочей программы из ПЗУ в процессор.

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

В файле mem_clr.bin и в ПЗУ все коды 24-разрядных слов команд процессора располагаются в строгом порядке. Первым располагается в ПЗУ старший байт команды, затем следует средний байт и последним записывается младший байт команды. Формат хранения слов программы в ПЗУ приведен в табл. 7.1.

Таблица 7.1 Формат хранения слов программы в ПЗУ

Адрес памяти программ

Слово программы

Адрес памяти ПЗУ

Байты программы

0x0000

0xABCDEF

0x00

0xAB

0x01

0xCD

0x02

0xEF

0x0001

0x123456

0x03

0x12

0x04

0x34

0x05

0x56

и т.д.

Способ загрузки процессора из ПЗУ хорошо применим для автономных процессорных устройств, работающих под управлением одной программы. Однако на практике довольно часто встречаются задачи, когда необходимо оперативно менять управляющую программу для процессора какого-либо электронного устройства. Это также необходимо при отладке программ с многочисленными итерациями трансляции и загрузки отлаживаемой программы в процессор. Удачным решением для такого рода задач является загрузка программ в сигнальный процессор через интерфейсный порт процессора IDMA. Но прежде чем начать освоение данной процедуры, необходимо подробнее познакомиться с этим интерфейсом. С этого мы продолжим изучение сигнального процессора в следующей главе.

Глава 8. Порт IDMA

В этой главе описывается интерфейсный порт IDMA и способы загрузки и отладки программ для сигнального процессора через этот порт.

Помимо порта прямого доступа к байтовой памяти BDMA (Byte Data Memory Access), сигнальный процессор ADSP-2181 имеет порт прямого доступа к внутренней памяти процессора IDMA (Internal Data Memory Access). Он представляет собой 16-разрядный параллельный порт, через который можно читать и записывать данные памяти процессора. Порт IDMA имеет 16-разрядную мультиплексированную шину адреса/данных IAD0–IAD15, 4 сигнала управления и 1 сигнал контроля. К сигналам управления относятся: сигнал выбора порта -IS, сигнал записи адреса ячейки памяти IAL, сигнал чтения -IRD и записи -IWR данных через порт. Сигнал контроля -IACK позволяет определить готовность порта IDMA. При чтении и записи памяти через IDMA данные транслируются через буферный регистр порта IDMA. В памяти данных процессора по адресу 0x3FE0 находится регистр управления IDMA, который предназначен для хранения адреса ячейки памяти, к которой будет производиться обращение через порт IDMA. Формат этого регистра представлен в табл. 8.1.

Таблица 8.1 Формат данных регистра управления IDMA

Разряд

Назначение

15

Не используется

14

Указатель типа памяти: 0=память программ (РМ) 1=память данных (DM)

13–0

Значение начального адреса памяти процессора при обмене через IDMA (от 0 до 0x3FFF)

Порт IDMA имеет встроенную функцию автоинкремента (автоматического увеличения на единицу адреса памяти), что позволяет ускорить выполнение блочных операций. Кроме того, порт IDMA позволяет выполнять загрузку памяти программ процессора с автоматическим запуском программы после заполнения нулевой ячейки памяти. Протокол обращения к памяти процессора через порт IDMA достаточно прост и показан на рис. 8.1.

Рис. 8.1. Алгоритм обращения к памяти процессора

Вначале все сигналы управления портом переводятся в пассивное состояние и проверятся готовность IDMA, путем ожидания установки сигнала -IACK в логический ноль. Затем осуществляется вывод на шину IAD0–15 сигналов адреса памяти процессора, к которой будет производиться обращение. После чего формируется строб сигнала записи адреса IAL в регистр управления порта IDMA. Временная диаграмма данной операции показана на рис. 8.2, а в табл. 8.2 приведены временные параметры для этой диаграммы.

Рис. 8.2. Временная диаграмма операции защелкивания адреса IDMA

Таблица 8.2 Временные параметры диаграммы защелкивания адреса IDMA

Параметр

Минимум

Защелкивание адреса IDMA

Требуемые длительности:

tIALP длительность защелкивания адреса, нс1,2

10

tIASU установка адреса перед окончанием защелкивания, нс^2

5

tIAH удержание адреса после защелкивания, нс^2

2

tIKA-IACK=0 перед защелкиванием, нс^1

0

tIALS начало записи или чтения после защелкивания, нс2,3

3

Примечания:

1 Начало защелкивания — IS=0 и IAL=1.

2 Конец защелкивания — IS=1 или IAL=0.

3 Начало записи или чтения — IS=0 и (IWR=0 или IRD=0).

Как видно из таблицы, минимальные временные значения сигналов не превышают 10 нс, что говорит о поддержке высокой скорости операций портом IDMA. Далее производится операция чтения или записи памяти. При операции чтения данные считываются с шины IAD0–IAD15 во время активизации управляющего сигнала -IRD.

При операции записи данные выставляются на шину IAD0–IAD15, и записываются в память процессора с помощью активизации сигнала -IWR.

Порт IDMA поддерживает короткий (быстрый) и длинный (долгий) циклы обращения к памяти. Во время короткого цикла данные читаются и записываются без ожидания готовности порта по сигналу -IACK, используя при этом буфер порта IDMA с данными. Временные диаграммы для данных циклов обращения показаны на рис. 8.3 и 8.4 соответственно. В табл. 8.3 и 8.4 приведены характеристики сигналов для этих диаграмм.

Рис. 8.3. Временные диаграммы короткого цикла чтения через порт IDMA

Рис. 8.4. Временные диаграммы короткого цикла записи через порт IDMA

Таблица 8.3 Временные параметры диаграммы короткого цикла чтения через порт IDMA

Параметр

Минимум

Максимум

Короткий цикл чтения через IDMA

Требуемые длительности:

tIKR-IACK=0 до начала чтения^1, нс

0

tIRP Продолжительность сигнала чтения, нс

15

Характеристики переключения:

tIKHR-IACK=0 после начала чтения^1, нс

15

tIKDH Удержание данных после окончания чтения^2, нс

0

tIKDD Сброс данных после окончания чтения^2, нс

10

tIRDE Активизация предыдущих данных, нс

0

tIRDV Достоверность предыдущих данных

15

Примечания:

1 Начало чтения: -IS=0 и -IRD=0.

2 Конец чтения: -IS=1 или -IRD=1.

Таблица 8.4 Временные параметры диаграммы короткого цикла записи через порт IDMA

Параметр

Минимум

Максимум

Короткий цикл записи через IDMA

Требуемые длительности:

tIKW-IACK=0 до начала записи^1, нс

0

tIWP Продолжительность записи1,2, нс

15

tIDSU Установка данных до окончания записи^2, нс

5

tIDH Удержание данных после окончания записи^2, нс

2

Характеристики переключения:

tIKHW от начала записи до -IACK=1, нс

15

Примечания:

1 Начало записи: -IS=0 и -IWR=0.

2 Конец записи: -IS=1 или -IWR=1.

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

Временные диаграммы для данных циклов обращения показаны на рис. 8.5 и 8.6 соответственно. В табл. 8.5 и 8.6 приведены характеристики сигналов для этих диаграмм.

Рис. 8.5. Временные диаграммы длинного цикла чтения через порт IDMA

Рис. 8.6. Временные диаграммы длинного цикла записи через порт IDMA

Таблица 8.5 Временные параметры диаграммы длинного цикла чтения через порт IDMA

Параметр

Минимум

Максимум

Длинный цикл чтения через IDMA

Требуемые длительности:

tIKR-IACK=0 до начала чтения^1, нс

0

tIRP Продолжительность сигнала чтения, нс

15

Характеристики переключения:

tIKHR-IACK=0 после начала чтения^1, нс

15

tIKDS Установка данных перед -IACK=0, нс

0,5 tCK^5-10

tIKDH Удержание данных после окончания чтения^2, нс

0

tIKDD Сброс данных после окончания чтения^2, нс

10

tIRDE Активизация предыдущих данных, нс

0

tIRDV Достоверность предыдущих данных, нс

15

tIRDH1 Удержание предыдущих данных (DM/PM1), нс

2 tCK-5

tIRDH2 Удержание предыдущих данных (PM2), нс

tCK-5

Примечания:

1 Начало чтения: -IS=0 и -IRD=0.

2 Конец чтения:-IS=1 или -IRD=1.

3 Чтение памяти DM или первой половины РМ.

4 Чтение второй половины РМ.

5 tCK — период тактовой частоты процессора.

Таблица 8.6 Временные параметры диаграммы длинного цикла записи через порт IDMA

Параметр

Минимум

Максимум

Длинный цикл записи через IDMA

Требуемые длительности:

tIKW-IACK=0 до начала записи^1, нс

0

tIKSU Установка данных перед -IACK=0, нс

0,5 tCK^2+1

tIKH Удержание данных после -IACK=0, нс

2

Характеристики переключения:

tIKLW От начала записи до -IACK=0, нс

1,5 tCK

tIKHW От начала записи до -IACK=1, нс

15

Примечания:

1 Начало записи: -IS=0 и -IWR=0.

2 tСK — период тактовой частоты процессора.

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

При обращении через порт IDMA к памяти данных операции чтения и записи выполняются за один цикл, поскольку разрядность порта составляет 16 бит. Однако при обращении к 24-разрядным данным памяти программ требуется два цикла обращения. В первом цикле происходит чтение или запись старших 16 бит слова памяти программ. Во втором цикле по линиям IAD0–IAD7 передаются младшие 8 бит слова. Линии IAD8–IAD15 при этом игнорируются. Автоинкремента адреса между этими циклами не происходит.

Через порт IDMA возможен доступ ко всей памяти процессора, за исключением регистров управления и состояния, отображенных на область памяти данных. При обращении через IDMA к области памяти данных, отведенной для регистров управления и состояния с адреса 0x3FE0 по адрес 0x3FFF, запись и чтение данных все же будет производиться. Но эта область памяти фактически будет дополнительной для пользователя, поскольку она дублирует системную область памяти данных, отведенную для регистров управления и состояния процессора.

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

Процессор ADSP-2181 поддерживает также начальную загрузку программ в память программ через порт IDMA. Для этого необходимо установить сигналы на выводах процессора BMODE=1 и MMAP=0. Затем необходимо произвести сброс процессора и загрузить программу в память программ процессора, начиная с адреса 1 через порт IDMA. Кроме того, можно записать произвольные данные в память данных процессора. После этого следует записать слово программы по адресу 0, и процессор запустит загруженную программу.

Глава 9. Адаптер LPT-IDMA

Теперь, после знакомства с портом IDMA, можно приступить к рассмотрению устройства, позволяющего загружать программы и редактировать данные памяти сигнального процессора через интерфейсный порт IDMA.

Для этих целей был разработан небольшой адаптер LPT-IDMA, который позволяет подключить порт IDMA сигнального процессора к LPT порту персонального компьютера. Схема этого адаптера приведена на рис. 9.1.

Рис. 9.1. Схема адаптера (начало)

Рис. 9.1. Схема адаптера (продолжение)

Рис. 9.1. Схема адаптера (окончание)

Адаптер выполнен на базе одной программируемой логической микросхемы D1 типа XC9536-15VQ44C фирмы XILINX. Схема внутреннего содержимого этой микросхемы представлена на рис. 9.2.

Рис. 9.2. Функциональная схема микросхемы (начало)

Рис. 9.2. Функциональная схема микросхемы (окончание)

Данная схема обеспечивает формирование 16-разрядной шины адреса и управляющих сигналов для порта IDMA с помощью 8-разрядной шины данных LPT порта. Чтение 16-разрядных данных из порта IDMA осуществляется через сигналы состояния LPT порта с использованием мультиплексоров M2_1, запрограммированных в схеме ПЛИС.

Прошивка для программирования данной ПЛИС в виде файла lpt_idma.jed находится на диске, прилагаемом к книге. Программирование ПЛИС осуществляется через соединитель J1 с помощью программатора, описываемого в приложении.

Все элементы адаптера можно распаять на небольшой макетной плате или изготовить для этих целей специальную печатную плату. Адаптер подключается к LPT порту компьютера с помощью ленточного 25-жильного кабеля, через разъем X1 «LPT». Чертеж такого кабеля изображен на рис. 9.3, а в табл. 9.1 приведено назначение цепей и соответствие контактов разъемов.

Рис. 9.3. Ленточный 25-жильный кабель

Таблица 9.1 Назначение цепей кабеля LPT

Цепь

Вилка DB-25M

Розетка DB-25F

Цепь

Вилка DB-25M

Розетка DB-25F

-STB

1

1

-AUTOLF

14

14

D0

2

2

-ERR

15

15

D1

3

3

-INIT

16

16

D2

4

4

-SELIN

17

17

D3

5

5

GND

18

18

D4

6

6

GND

19

19

D5

7

7

GND

20

20

D6

8

8

GND

21

21

D7

9

9

GND

22

22

-ACK

10

10

GND

23

23

BUSY

11

11

GND

24

24

РЕ

12

12

GND

25

25

SEL

13

13

-

-

-

С помощью разъемов XU и XP адаптер подключается непосредственно к устройству с сигнальным процессором через интерфейсный порт IDMA.

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

Все схемы и проект прошивки для ПЛИС прилагаются в виде соответствующих файлов на компакт-диске этой книги.

Глава 10. Менеджер памяти

В этой главе описывается программа под названием «Менеджер памяти», разработанная автором книги для загрузки в сигнальный процессор программ и их отладки.

Для того чтобы можно было использовать адаптер LPT-IDMA для загрузки программ и данных в сигнальный процессор, а также иметь возможность редактировать содержимое памяти сигнального процессора во время его работы, мною была написана программа менеджера памяти цифрового сигнального процессора «mngdsp». Эта программа является приложением DOS и может работать в режиме DOS под Windows95/98/Me. Данная программа в составе проекта для Borland С++ 3.1, с исходными текстами программы находится на диске, прилагаемом к книге.

После запуска программы mngdsp.exe на экране монитора должно появиться окно, изображенное на рис. 10.1.

Рис. 10.1. Экран монитора после запуска программы mngdsp.exe

Данное окно отображает содержимое памяти сигнального процессора в шестнадцатеричном формате. Внизу этого окна приведены команды управления программой. При перемещении маркера по окну с помощью клавиш управления, можно выбрать любую доступную ячейку памяти процессора, для записи в нее произвольных данных. Адрес выбранной ячейки памяти отображается слева вверху. Переключение между памятью данных и памятью программ процессора производится с помощью клавиши TAB клавиатуры. Адаптер позволяет подключаться параллельно к двум портам IDMA разных процессоров. Например, к мультипроцессорному устройству. Для этого он использует сигнал -SEL, подключаемый к выводу - IS порта IDMA. Поскольку при пассивном состоянии данного сигнала порт IDMA не активизируется, допускается запараллеливание всех сигналов IDMA двух процессоров, за исключением сигнала -IS, который позволит выбирать один из двух процессоров. При такой схеме включения необходимо к выводу -IS одного из двух процессоров подключать сигнал -SEL непосредственно, а к выводу -IS второго процессора через инвертор. Выбор процессора из программы производится клавишами F1 и F2. С помощью клавиши F3 можно заполнить всю память данных процессора произвольным числовым значением. Клавиша F4 позволяет очистить память данных процессора путем записи во всю область памяти нулевого значения. Клавиша F8 производит принудительный сброс процессора путем формирования сигнала сброса -INIT для процессора. Кроме того, программа менеджер позволяет загрузить программу в память процессора и запустить ее. Для этого используется клавиша F9. После нажатия этой клавиши, программа запросит имя загружаемого файла, а также предложит загрузить файл с именем dsp.lda, используемым в программе по умолчанию. Поэтому перед запуском программы можно переименовать файл, который должен загружаться в процессор, в файл с именем dsp.lda либо ввести имя загружаемого файла по запросу программы. О формате данного файла и о том, как получить такой файл, было рассказано ранее.

Таким образом, используя программу менеджера памяти DSP, можно загружать и отлаживать программы для сигнального процессора, пользуясь при этом многократными итерациями, высокой скоростью и удобством интерфейса программы.

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

Рис. 10.2. Структурная схема подключения двух процессоров

Как видно из схемы, ведущий процессор подключен к порту IDMA ведомого процессора с использованием сигнала обращения к портам ввода-вывода -IOMS, сигнала записи -IWR, двух сигналов программируемых флагов PF0 и PF2, адресного сигнала A0, шины данных D8–D23 и сигнала синхронизации тактовой частоты CLKOUT. Такая схема включения позволяет выполнять операцию записи данных через порт IDMA ведомого процессора с помощью одной команды записи данных в порт ввода-вывода io(address)=data. Сигнал CLKOUT обеспечивает маскирование адресной линии A0 при формировании сигнала защелки адреса IAL. Такое маскирование необходимо для блокировки переходных процессов на линии А0 при установке адреса. Это хорошо видно из временной диаграммы цикла записи данных процессором в порт ввода-вывода, приведенной на рис. 10.3.

Рис. 10.3. Временная диаграмма цикла записи

Сигнальные цепи PF2 и PF0 используются ведущим процессором для активизации схемы защелки адреса в порт IDMA и для анализа состояния готовности порта IDMA ведомого процессора.

Ниже приведен исходный текст программы idmaidma.dsp для ведущего процессора данной схемы, позволяющей ему загрузить в память программ ведомого процессора массив данных, размещенных в файле idmaidma.dat, являющихся программой для ведомого процессора.

Текст программы

/*********************************************************************/

/* Эта программа транслирует данные от ведущего процессора ADSP-2181 */

/* к ведомому процессору ADSP-2181 через IDMA порт                   */

/*********************************************************************/

.module/abs=0x0000 idma_transfer;

.include <def2181.h>;          { Включить файл определений         }

.const length=68;              { Десятичное значение длины вектора }

.var/pm/ram x_input[length];   { Описание массива данных           }

.init x_input: <idmaidma.dat>; { Файл передаваемых данных          }

jump start; nop; nop; nop;     { Таблица векторов прерываний       }

RTI; NOP; NOP; NOP;            { Прерывания не используются        }

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

RTI; NOP; NOP; NOP;

/*** Начало программы ***/

start:

ax0=0x0000;

dm(System_Control_Reg)=ax0; { Такты ожидания PM отключить     }

dm(PFTYPE)=ax0;             { Все флаги PF назначить выходами }

dm(DM_Wait_Reg)=ax0; {Такты ожидания DM и портов ввода-вывода отключить}

l6=0;          { Длина буфера данных                      }

i6=^x_input;   { Адрес начала буфера транслируемых данных }

m6=1;          { Приращение = 1                           }

modify(i6,m6); { Модификация адреса                       }

/*** Защелкнуть адрес 0x0001 ***/

call check_ack; { Проверить готовность к приему                       }

ax0=0x0001;     { Стартовый адрес для записи в ведомый процессор      }

io(0x0001)=ах0; { Запись этого адреса с переключением линий -IS и IAL }

/*** Запись всех данных начиная с адреса 0x0001 ***/

cntr=length-1;     { Установить счетчик транслируемых слов        }

do loop1 until се; { Организовать цикл записи                     }

call check_ack;   { Проверить готовность к приему                }

call format;      { Форматировать данные                         }

io(0x0100)=ay0;   { -IWR и IS записывают старшие 16 бит IAD 0-15 }

call check_ack;   { Проверить готовность к приему                }

io(0x0100)=ay1;   { -IWR и IS записывают младшие 8 бит IAD 0-15  }

loop1: nop;

/*** Защелкнуть адрес 0x0000 ***/

call check_ack; { Проверить готовность к приему                       }

ax0=0x0000;     { Стартовый адрес для записи в ведомый процессор      }

io(0x0001)=ax0; { Запись этого адреса с переключением линий -IS и IAL }

/*** Запись по адресу 0x0000 ***/

i6=^x_input;    { Указатель на начало буфера данных            }

call check_ack; { Проверить готовность к приему                }

call format;    { Форматировать данные                         }

io(0x0100)=ay0; { -IWR и IS записывают старшие 16 бит IAD 0-15 }

call check_ack; { Проверить готовность к приему                }

io(0x0100)=ay1; { -IWR и IS записывают младшие 8 бит IAD 0-15  }

idle;           { Режим ожидания                               }

/****************************************************************/

/* Подпрограмма переформатирования 24-бит слова памяти программ */

/****************************************************************/

format: ay0=pm(i6,m6); { 16 старших бит запомнить в регистре ay0 }

ay1=px;                {  8 младших бит запомнить в регистре ay1 }

rts;

/***************************************************************************/

/* Подпрограмма ожидания перехода состояния линии -IACK в низкое состояние */

/***************************************************************************/

check_ack:

ax0=dm(0x3fе5);       { Читать PF1, который подключен к -IACK             }

ar=tstbit 1 of ax0;   { Анализировать PF1                                 }

if ne jump check_ack; { Если процессор не готов вновь контролировать -IACK}

rts;

.endmod;

Многие директивы и команды данной программы уже знакомы читателям из описания предыдущей программы. Текст программы прокомментирован, что позволяет без труда понять алгоритм ее работы. Как видно из текста, в программе использован ряд подпрограмм, в которых сосредоточены часто используемые операции. Вызов данных подпрограмм осуществляется командой call, после которой записывается имя подпрограммы. Команда io(0x0001)=ax0 осуществляет запись содержимого регистра ax0 в порт ввода- вывода по адресу 0x0001. Команда ar=tstbit 1 of ax0 заносит в регистр ar результат тестирования первого разряда регистра ax0. Следующая за этой, команда if ne jump check_ack проверяет состояние флагов ALU и осуществляет переход на метку check_ack, если результат проверки предыдущей операции был отрицательным. Подробнее со всеми командами сигнального процессора ADSP-2181 мы познакомимся позже.

При компиляции этой программы, все данные из файла idmaidma.dat будут автоматически помещены в файл загрузки idmaidma.lda. В качестве файла данных idmaidma.dat можно использовать загрузочный файл рассмотренной нами ранее программы mem_clr.lda, из которого предварительно следует удалить первые три и последние две служебные строки. Данную операцию можно выполнить с помощью любого текстового редактора. После чего файл необходимо переименовать, задав ему имя idmaidma.dat. Кроме того, можно изменить имя загружаемого файла в самой программе.

Глава 11. Директивы ассемблера

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

На примере программ, рассмотренных ранее, было показано, что программа может включать в себя строки различных директив. Директивы управляют процессом ассемблирования. Они обрабатываются препроцессором, но в отличие от инструкций не генерируют при ассемблировании код. Любая директива ассемблера начинается с точки и заканчивается точкой с запятой. Некоторые директивы имеют параметры и аргументы. Параметры следуют сразу за директивой и разделяются косой чертой, аргументы следуют после параметров. Директивы ассемблера могут содержать однострочный комментарий, который не может быть продолжен на следующей строке. Если требуется многострочный комментарий, необходимо начать новый комментарий на следующей строке. В общем случае запись директив выглядит следующим образом:

.ДИРЕКТИВА [/ПАРАМЕТР1][/ПАРАМЕТР2] ... [АРГУМЕНТ]; {Комментарий}

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

Помимо директив ассемблера, в среде разработки программ для ADSP-2181 существует несколько директив для системного конфигуратора. Ранее говорилось о том, что системный конфигуратор можно не использовать, если имеется готовый файл описания архитектуры с расширением ach для конкретного устройства, построенного на определенном типе сигнального процессора. Этот файл используется компоновщиком и программой эмулятора для того, чтобы определить размер памяти системы, тип памяти процессора (ОЗУ или ПЗУ), какая часть памяти является внутренней и внешней и какая периферия отображена в памяти. При необходимости, можно воспользоваться системным конфигуратором с целью получения нового файла описания архитектуры для нового устройства или другого типа процессора.

Перед запуском системного конфигуратора необходимо создать файл с расширением sys, содержащим директивы описания устройства (системы). Запуск системного конфигуратора осуществляется командой:

bld21 имя_файла[sys] [-c]

Здесь имя_файла — это имя исходного файла системной конфигурации. Имя файла может быть указано с расширением. Если расширение отсутствует, системный конфигуратор добавляет по умолчанию расширение sys. Системный конфигуратор создает выходной файл описания архитектуры с именем входного файла и расширением ach. Ключ -с делает системный конфигуратор чувствительным к регистру символов, различающим использование верхнего или нижнего регистра (прописных или строчных) символов. Если ключ -с не используется, то на выходе системного конфигуратора будет создан файл с символами верхнего регистра. Для вызова справки системного конфигуратора, наберите команду:

bld21 -help

Этот ключ позволяет получить справку о версии программы и посмотреть список возможных команд. Ключ -help работает в большинстве программ средств разработки.

Рассмотрим более подробно основные директивы системного конфигуратора и ассемблера для сигнальных процессоров семейства ADSP.

Директива SYSTEM

Директива SYSTEM определяет имя (название) системы и должна быть первой командой в исходном файле системной конфигурации. Директива имеет формат:

.SYSTEM имя_системы;

В языке ассемблера допускается использовать в качестве имен набор символов, содержащий:

- прописные латинские буквы от «A» до «Z»;

- строчные латинские буквы от «a» до «z»;

- знак подчеркивания «_».

Имена не должны начинаться с цифры и могут иметь длину до 32 знаков. Ниже приведено несколько примеров имен с описанием их назначения:

Main_prog {Программный модуль на языке ассемблер}

var1 {Переменная};

buff {Буфер данных};

met173 {Программная метка};

DAC {Порт, отображенный в памяти}.

Директива ADSP21XX

Эта директива определяет, какой тип процессора семейства ADSP2100 используется в системе. Данная информация передается компоновщику (редактору связей) и симулятору через выходной файл с расширением ach. После этого редактор связей в состоянии определить место расположения программы и данных в соответствии с организацией памяти для конкретного типа процессора. Эта директива принимает одну из следующих форм:

.ADSP2100; {Для ADSP-2100 и ADSP-2100A}

.ADSP2101;

.ADSP2105;

.ADSP2111;

.ADSP2150; {Для ADSP-21msp50 и ADSP-21msp55}

.ADSP2151; {Для ADSP-21msp51 и ADSP-21msp56}

.ADSP2101MV; {Для вариантной системы ADSP-2101 (ADSP-2115)}

.ADSP2101P; {Для системы со страничной памятью ADSP-2101}

.ADSP2181; {Для ADSP-2181}

и т.п.

Директива MMAP

Эта директива определяет логическое состояние вывода MMAP процессора в системе. Она принимает одну из двух форм:

.MMAP0 {Вывод MMAP=0}

.MMAP1 {Вывод MMAP=1}

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

Директива SEG

Директива SEG определяет специальную секцию системной памяти и описывает ее атрибуты. Не существует разделения памяти по умолчанию, поэтому необходимо определить системную память с помощью директив SEG самостоятельно. Эта информация передается редактору связей, симулятору и эмулятору через выходной файл с расширением ach. Директива SEG имеет форму:

.SEG/параметр1/параметр2/... имя_сегмента[размер];

Сегменту присваивается символьное имя. Присвоенное имя позволяет разместить фрагменты программы и данных в памяти. На языке ассемблер это достигается параметром SEG. Размер сегмента указывается внутри скобок. Эта величина интерпретируется как количество 16-разрядных слов данных или 24-разрядных слов инструкций в сегменте.

Для директивы SEG необходимо указать два обязательных параметра:

PM, или DM, или BOOT=0-7 — тип сегмента памяти;

RAM или ROM — тип памяти процессора.

Четыре других параметра являются необязательными:

ABS=адрес — абсолютный стартовый адрес;

DATA, или CODE, или DATA/CODE — тип данных, хранимых в сегменте;

EMULATOR или TARGET — распределение памяти для эмулятора;

INTERNAL — расположение в памяти процессора ADSP-2101 с вариантной памятью.

Параметры PM, DM и BOOT определяют тип сегмента памяти, который может быть отведен под память программ, память данных или одну из восьми страниц памяти начальной загрузки. Остальные параметры определяют тип памяти процессора, начальный адрес сегмента, тип данных сегмента (данные и/или программы) и распределение памяти эмулятора.

Каждый сегмент памяти должен адресоваться раздельно, поскольку, например, адрес 0x10 в памяти программ отличается от адреса 0x10 в памяти данных из-за разной длины слов этих данных. Сегмент памяти программ PM может хранить только программы (CODE), данные (DATA) или одновременно программы и данные. Если не указать ни одну из опций, по умолчанию принимается хранение программ. Для сегмента PM, содержащего программу и данные, должны быть указаны оба параметра. Параметр памяти начальной загрузки должен определять только один номер страницы, например BOOT=0. Необходимо разделять объявление сегмента для каждой страницы памяти начальной загрузки системы. Система может иметь до 8 страниц памяти начальной загрузки с номерами от 0 до 7. Каждая страница памяти начальной загрузки для ADSP-2101, ADSP-2111, ADSP21ms50 может сохранять до 2К программ и данных. Каждая страница памяти начальной загрузки для ADSP-2105, ADSP-2115 может сохранять до 1К слов. Параметр ABS для страниц памяти начальной загрузки не используется, поскольку системный конфигуратор самостоятельно присваивает соответствующие адреса.

Примеры директивы SEG:

.SEG/PM/RAM/ABS=0/CODE/DATA start [2048];

Здесь объявлен сегмент памяти программ ОЗУ, называемый start, который расположен по адресу 0. Сегмент может содержать до 2048 слов программ и данных.

.SEG/ROM/BOOT=0 boot0[1536];

Здесь объявлен сегмент памяти начальной загрузки boot0, который расположен на странице номер 0 памяти начальной загрузки (автоматически соответствует адресу 0 в памяти начальной загрузки). Длина сегмента составляет 1536 слов. Сегменты памяти начальной загрузки должны всегда быть объявлены как ROM (ПЗУ).

Директива PORT

Директива PORT является директивой системного построителя и ассемблера. Она объявляет порт ввода/вывода отображенный в памяти процессора. Каждый порт должен иметь уникальное имя и адрес в системе. Порты могут быть определены в памяти данных или памяти программ. Для процессоров с внутренней памятью портам могут быть присвоены адреса только во внешней памяти.

Директива PORT принимает одну из двух форм:

.PORT/DM/ABS=адрес имя_порта;

или

.PORT/PM/ABS= адрес имя_порта;

Параметр DM показывает, что порт отображен в памяти данных. Параметр PM показывает, что порт отображен в памяти программ. Если параметр не задан, по умолчанию принимается DM. Порт располагается по абсолютному адресу, который определен параметром ABS, и присваивается символическому имени порта. Это имя используется в инструкциях ассемблера для доступа к порту, например:

.PORT/DM/ABS=0x0020 p1;

Объявляет имя порта p1, который отображен в памяти данных по адресу 0x0020 (шестнадцатеричный) или 32 (десятичный). Ассемблерная программа обращается к этому имени, чтобы представить его редактору связей, базирующемуся на содержании файла описания системной конфигурации с расширением ach. Отображение порта в памяти данных позволяет 16-и разрядное чтение/запись, в то время как отображение порта в памяти программ допускает 16- или 24-разрядный обмен данными.

В программе директива PORT повторяет директиву системного построителя без указания адреса порта. Например, в файле конфигурации системы для системного построителя директива PORT объявляет порты CODEC и DAC по адресам 0x3000 и 0x3800 соответственно:

.PORT/ABS=0x3000 CODEC;

.PORT/ABS=0x3800 DAC;

В программе директива PORT объявляет эти порты следующими строками:

.PORT CODEC;

.PORT DAC;

После чего в программе можно делать обращения к описанным портам с помощью команд, подобным следующим:

AR=DM(DAC);

DM(DAC)=AR;

AR=DM(CODEC);

DM(CODEC)=AR;

Директива ENDSYS

Директива ENDSYS должна быть последней командой в файле. Системный конфигуратор останавливает свою работу на директиве .ENDSYS. Директива имеет форму записи:

.ENDSYS;

Ниже приведен пример законченного файла example.sys для системного конфигуратора.

.SYSTEM example;

.ADSP2181;

.MMAP0;

.SEG/PM/RAM/ABS=0x0000/CODE/DATA mem_pm[0x4000];

.SEG/DM/RAM/ABS=0x0000/DATA mem_dm[0x3FE0];

.ENDSYS;

После обработки этого файла системным конфигуратором должен получиться файл example.ach с таким содержимым:

$EXAMPLE

$ADSP2181

$MMAP0

$0000 3FFF pax_PM t

$0000 3FDF dadMEM_DM t

$

Теперь рассмотрим основные директивы ассемблера, которые применяются в текстах программ для сигнальных процессоров семейства ADSP.

Директива MODULE

Директива MODULE обозначает начало программного модуля и определяет название модуля. Как было сказано ранее, программа для ADSP-2181 может состоять из одного или нескольких модулей, которые отдельно ассемблируются и затем связываются вместе. Каждый файл с исходным текстом программы может содержать только один программный модуль. Директива имеет следующую форму записи:

.МОDULЕ/ПАРАМЕТР1/ПАРАМЕТР2 ... ИМЯ_МОДУЛЯ;

Параметры могут быть следующими:

RAM или ROM — тип памяти для размещения программы;

ABS=адрес — абсолютный стартовый адрес (не используется вместе с директивой STATIC);

SEG=сегмент — размещение программы в указанном сегменте;

STATIC — статичное размещение модуля в памяти (не используется вместе с директивой ABS).

Параметр RAM (ОЗУ) или ROM (ПЗУ) определяет тип памяти процессора для размещения программы. Если тип памяти не определен, то по умолчанию принимается тип RAM.

Параметр ABS размещает коды модулей программ по определенным адресам памяти программ, что делает их не перемещаемыми компоновщиком. Это означает, что компоновщик резервирует память для модулей по указанным адресам. Модули, которые не имеют параметра ABS, распределяются компоновщиком в памяти процессора автоматически.

Параметр SEG размещает модуль в указанный сегмент памяти, который объявлен в файле системной конфигурации. Если определить оба параметра ABS и SEG и указать абсолютные адреса, которых нет в данном сегменте, компоновщик выдаст сообщение об ошибке.

Параметр STATIC сохраняет модуль в памяти программ, когда загружаются страницы начальной загрузки. Пример записи директивы:

.MODULE/RAM/ABS=0 demo;

{Определение имени demo программного модуля}

{с размещением в ОЗУ по абсолютному адресу 0}

Директива CONST

Директива CONST определяет соответствие между именем константы и ее значением. Данная директива имеет следующую форму записи:

.CONST имя_константы1 = значение1, имя_константы2 = значение2...;

Значения констант могут быть числовыми или символьными константами. Кроме того, допускается присваивать константам выражения. В выражениях разрешаются только арифметические или логические операции над двумя или более целыми константами. В качестве знаков выражений в ассемблере допускается использовать следующие символы:

+ — сложение;

- — вычитание;

* — умножение;

/ — деление;

% — модуль (целая часть от деления);

( — левая скобка;

) — правая скобка;

& — логическое «И» (AND);

| — логическое «ИЛИ» (OR);

~ — исключающее «ИЛИ» (XOR);

<< — логический сдвиг влево;

>> — логический сдвиг вправо.

Запись чисел в программах может осуществляться в нескольких форматах. Для записи шестнадцатеричных чисел используется префикс 0x (ноль и икс) или H#. Например:

0x24FF, H#CF8A

Для восьмеричных чисел применяется префикс 0 (ноль):

0777, 0123, 07777

Двоичные числа записываются с префиксом B#:

В#01110100

Десятичные числа записываются в программе без префиксов. Т.е. по умолчанию формат числа считается десятичным:

1024, -55, 0

Пример записи арифметического выражения:

X = (29+129)-(128-48)/3

Пример логического выражения:

Y = 0x55&0x0F

Пример записи директивы:

.CONST N=1024, LEN_BUF=N/2; {Число точек отсчета = 1024, длина буфера = 512}

Директива VAR

Директива VAR объявляет переменные и буферы переменных. Буфер переменных представляет собой набор ячеек памяти, расположенных упорядоченно друг за другом по смежным (соседним) адресам. Буфер может быть многомерным и одномерным, т.е. состоящим из нескольких или из одной переменной. Буфер должен быть объявлен до использования в программе. Буферы удобны для организации приема и передачи блочных данных и часто используются в программах.

Директива VAR имеет следующую форму записи:

.VAR/параметр1/параметр2 ... имя_буфера[длина],...;

С директивой могут использоваться следующие параметры:

PM или DM — тип памяти для размещения буфера;

RAM или ROM — тип памяти процессора;

ABS=адрес — абсолютный адрес (нельзя использовать вместе с директивой STATIC);

SEG=сегмент — размещение буфера в сегменте, объявленном системным конфигуратором;

CIRC — кольцевой буфер;

STATIC — предотвращает перезапись буфера во время загрузки начальной страницы.

Одна директива VAR позволяет объявить в одной строке длиной до 200 символов несколько буферов, разделенных запятыми.

Буферы могут быть линейными и кольцевыми. Буферы могут быть произвольной длины от единицы до размера, не превышающего объем памяти процессора. Линейный буфер размещается в памяти с любого адреса. Кольцевой буфер может быть размещен в памяти с некоторыми ограничениями, связанными с аппаратными особенностями памяти процессоров. Так, кольцевой буфер должен стартовать с базового адреса, который кратен 2 в степени n, где n — количество бит требуемых для представления длины буфера в двоичном виде. Это необходимо учитывать при создании кольцевых буферов с параметром ABS.

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

Буферы могут быть размещены как в памяти программ PM, так и в памяти данных DM, по умолчанию. Тип памяти по умолчанию устанавливается в RAM для памяти DM и PM.

Параметр ABS размещает буфер с указанного стартового адреса, делая его неперемещаемым.

Параметр SEG размещает буфер в указанном сегменте памяти, который был объявлен в файле системного конфигуратора.

Параметр CIRC определяет кольцевой буфер. Буфер будет организован как линейный, если не применен атрибут CIRC.

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

Пример объявления буфера:

.VAR/PM/RAM/SEG=segdata buffer[10];

Здесь линейный буфер объявлен в памяти программ RAM, который перемещаем в пределах сегмента с именем segdata. Буфер с именем buffer состоит из 10 ячеек в памяти программ. Длина буфера указывается в квадратных скобках.

Для объявления одномерных буферов, т.е. простых переменных, применяется директива VAR без указания длины буфера. Например:

.VAR/DM/RAM/ABS=0x000C xdata;

Данная директива объявляет однословную переменную с именем xdata в памяти данных RAM по шестнадцатеричному адресу 0x000C.

Ниже приведен пример объявления автоматически перемещаемого кольцевого буфера с именем buffer_c, длина которого определяется величиной константы size, объявленной директивой CONST.

.CONST size = 15;

.VAR/DM/CIRC buffer_c[size];

Ниже приведены примеры, позволяющие понять, как можно размещать циклические буферы в памяти. Следующий оператор объявляет кольцевой буфер с именем abuf из шести ячеек памяти:

.VAR/CIRC abuf[6];

Поскольку ближайшим числом больше шести и кратным двум является число 8, то базовый (стартовый) адрес буфера должен быть кратен 8. Три младших значимых разряда (МЗР) этого адреса будут равны нулю. В табл. 11.1 показано размещение этого буфера в памяти.

Таблица 11.1 Размещение одного циклического буфера в памяти сигнального процессора

Имя буфера

Элемент буфера

Двоичный адрес

…

abuf

abuf[0]

XXXXXXXXXX0000

abuf[1]

XXXXXXXXXX0001

abuf[2]

XXXXXXXXXX0010

abuf[3]

XXXXXXXXXX0011

abuf[4]

XXXXXXXXXX0100

abuf[5]

XXXXXXXXXX0101

XXXXXXXXXX0110

…

Если в одной строке объявлены несколько буферов с параметром CIRC, то будет создан один кольцевой буфер, вмещающий в себя все буферы. Первый из этих буферов будет кольцевым, а отдельные буферы будут простыми линейными буферами. Например, следующая директива создает один кольцевой буфер abuf и два линейных буфера с именами bbuf и cbuf.

.VAR/CIRC abuf[6], bbuf[3], cbuf[5];

Для размещения всех этих буферов в памяти процессора потребуется 6+3+5=14 ячеек памяти. Поскольку первым в директиве объявлен буфер abuf, то он будет кольцевым. Ближайшим числом больше 14 и кратным двум является число 16. Поэтому базовый адрес буфера abuf должен быть кратен 16 (четыре младших значащих разряда будут равны нулю). Базовый адрес буфера bbuf будет следовать сразу за адресом последнего элемента буфера abuf. Аналогично будет размещен и буфер cbuf. Размещение всех этих буферов в памяти процессора показано в табл. 11.2.

Таблица 11.2 Размещение трех буферов в памяти процессора

Имя буфера

Элемент буфера

Двоичный адрес

…

abuf

abuf[0]

XXXXXXXXXX0000

abuf[1]

XXXXXXXXXX0001

abuf[2]

XXXXXXXXXX0010

abuf[3]

XXXXXXXXXX0011

abuf[4]

XXXXXXXXXX0100

abuf[5]

XXXXXXXXXX0101

bbuf

bbuf[0]

XXXXXXXXXX0110

bbuf[1]

XXXXXXXXXX0111

bbuf[2]

XXXXXXXXXX1000

cbuf

cbuf[0]

XXXXXXXXXX1001

cbuf[1]

XXXXXXXXXX1010

cbuf[2]

XXXXXXXXXX1011

cbuf[3]

XXXXXXXXXX1100

XXXXXXXXXX1101

…

Следующий пример показывает использование трех директив для объявления трех различных кольцевых буферов:

.VAR/CIRC abuf[6];

.VAR/CIRC bbuf[3];

.VAR/CIRC cbuf[5];

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

Таблица 11.3 Размещение трех кольцевых буферов в памяти процессора

Имя буфера

Элемент буфера

Двоичный адрес

…

abuf

abuf[0]

XXXXXXXXX00000

abuf[1]

XXXXXXXXX00001

abuf[2]

XXXXXXXXX00010

abuf[3]

XXXXXXXXX00011

abuf[4]

XXXXXXXXX00100

abuf[5]

XXXXXXXXX00101

…

bbuf

bbuf[0]

XXXXXXXXX01000

bbuf[1]

XXXXXXXXX01001

bbuf[2]

XXXXXXXXX01010

…

cbuf

cbuf[0]

XXXXXXXXX10000

cbuf[1]

XXXXXXXXX10001

cbuf[2]

XXXXXXXXX10010

cbuf[3]

XXXXXXXXX10011

…

Чтобы получить доступ к буферу abuf из программы, необходимо инициализировать индексные регистры DAG и регистры длины буфера следующими инструкциями:

I0 = ^abuf; {Присвоить индексному регистру I0 базовый адрес буфера abuf}

L0 = %abuf; {Присвоить L0 длину буфера abuf}

M0 = 1; {Присвоить модификатору M0 значение наращивания

указателя адреса буфера abuf}

Далее в программе можно читать данные из буфера с помощью инструкции AR=DM(I0, L0) или записывать данные в буфер инструкцией DM(I0, L0)=AR. Естественно, вместо регистра AR могут применяться и некоторые другие регистры процессора. При размещении этих инструкций в цикле каждое обращение к буферу будет автоматически увеличивать индексный регистр адреса I0 на величину M0. При достижении регистром I0 величины, равной L0, индексный регистр I0 вновь загрузится базовым адресом буфера. Таким образом, обращения к буферу будут кольцевыми. Для линейных буферов регистр длины буфера должен быть установлен в ноль.

Директивы PMSEG и DMSEG

Данные директивы предназначены для размещения программ и данных в сегментах памяти. Директива PMSEG указывает редактору связей на необходимость разместить все программы и данные модуля в определенном сегменте памяти программ. Директива DMSEG указывает редактору связей на необходимость разместить все структуры данных модуля в определенном сегменте памяти данных. Сегменты должны быть предварительно определены в файле описания архитектуры системного конфигуратора. Директивы PMSEG и DMSEG подобно параметру SEG директив MODULE и VAR имеют следующий формат:

.PMSEG имя_сегмента_pm;

.DMSEG имя_сегмента_dm;

Обычно, чтобы расположить все программы и данные исходного модуля в определенном системным конфигуратором сегменте памяти, необходимо повторить параметр SEG в директиве MODULE и всех директивах VAR внутри модуля. Директивы PMSEG и DMSEG используются для исключения многократного повторения параметров SEG. Директивы PMSEG и DMSEG должны быть размещены в исходном файле программного модуля перед директивой MODULE. Ниже приводится пример, в котором модуль prog1, некоторые буферы и переменную var1 располагают в памяти данных в сегменте с именем seg1:

.DMSEG seg1;

.MODULE/RAM prog1;

.VAR/DM/RAМ/СIRС buf1[15];

.VAR/DM/RAM buf2[5];

.VAR/DM/RAM buf3[5];

.VAR/DM/RAM var1;

...

.ENDMOD;

Директива INIT

Директива INIT используется для инициализации переменных и буферов в ПЗУ. Редактор связей помещает данные инициализации в файл образа памяти, который затем используется разделителем программ (splitter) при подготовке данных для записи в ПЗУ. Разделитель трансформирует части этого файла в формат, совместимый с промышленным стандартом программатора ПЗУ.

Инициализирующие значения могут быть перечислены в директиве или указаны во внешнем файле. Директива INIT может иметь одну из следующих форм:

.INIT имя_буфера: значение1, значение2,...;

.INIT имя_буфера: ^другой_буфер или %другой_буфер,...;

.INIT имя_буфера: <имя_файла>;

Операторы ^ и % используются для инициализации буфера или переменной базовым адресом, или длиной, или даже другими буферами. Любые комбинации констант, указателей адресов буфера и величин длины буфера могут быть заданы через запятую. Примеры:

.INIT x: 0x3FFF;

Данный пример инициализирует переменную x шестнадцатеричной константой 0x3FFF.

.INIT buf: 9,0,3,5,7;

Эта директива инициализирует буфер buf списком констант.

.INIT ab: ^buf;

Здесь переменная ab инициализируется указателем стартового адреса буфера buf.

Допускается инициализировать только часть данных буфера, задавая смещение его базового адреса (индекса):

.INIT buf[2]: 3,5,7;

Так, инициализирующие величины будут размещены, начиная с элемента buf[2]. Здесь инициализируются второй, третий и четвертый элементы буфера buf величинами 3, 5 и 7 соответственно.

Третья форма директивы INIT указывает имя файла, который содержит инициализирующие величины. Ассемблер устанавливает указатель на этот файл, и данные присоединяются при запуске редактора связей. Следующий пример заставляет редактор связей инициализировать буфер sin содержимым файла sinus.dat:

.INIT sin: <sinus.dat>;

Если файл с данными находится в директории с программой, то необходимо указать в скобках только имя этого файла. Если файл находится в другом каталоге, необходимо указать путь к этому каталогу и имя файла. Например, если файл init.dat для буфера с именем buff размещен в директории C:\ADSP2181\PROG1\, тогда директива INIT должна быть применена следующим образом:

.INIT buff: <C:\ADSP2181\PROG1\init.dat>

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

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

Переменные данных и буферов могут быть инициализированы с помощью семиразрядного ASCII кода. Следующий пример инициализирует один четырехразмерный буфер input кодами ASCII для букв A, E, F, Z. ASCII коды размещаются в семи младших разрядах 16-разрядной памяти данных или 24-разрядной памяти программ. Символы необходимо заключать в апострофы.

.INIT input: 'AEFZ'; {Инициализировать буфер символами ASCII}

Специальный синтаксис директивы INIT24, позволяет сохранять 24-х разрядные данные в памяти программ. Это дает возможность получить доступ к младшим 8-и разрядам каждого 24-х разрядного слова памяти программ при инициализации буферов данных или переменных в исходной программе.

Например, эта директива позволяет вычислить 16-разрядный адрес для переменной var:

.INIT var: ^buff + 17;

А следующая директива вычисляет 24-разрядный адрес для этой же переменной:

.INIT24 var: ^buff + 17;

Директива GLOBAL

Директива GLOBAL обеспечивает доступ к переменным, буферам и портам из других модулей программы. Для доступа к одной из этих структур из других модулей необходимо объявить ее директивой GLOBAL. Директива GLOBAL имеет формат:

.GLOBAL внутренний_символ 1, внутренний_символ 2,...;

Пример:

.VAR/PM/RAM buff[10]; {Создать буфер buff размерностью

10 элементов}

.GLOBAL buff; {Объявить буфер видимым из других модулей}

После того как структура объявлена глобальной, другие модули могут обращаться к ней в программе. Предварительно эта структура в них должна быть объявлена как внешняя с помощью директивы EXTERNAL.

Директива ENTRY

Директива ENTRY позволяет обращаться к программным меткам в других модулях. Это позволяет использовать метку для вызова подпрограммы или межмодульных переходов. Директива ENTRY имеет формат:

.ENTRY метка 1, метка 2, ...;

Пример:

.ENTRY met; {Делает метку met доступной из других модулей}

С тех пор как метка объявлена директивой ENTRY, другие модули могут обращаться к ней, идентифицируя ее как внешнюю с помощью директивы EXTERNAL.

Директива EXTERNAL

Директива EXTERNAL позволяет программному модулю обращаться к глобальным структурам данных (переменным, буферам и портам) и программным меткам, объявленным в других модулях.

Структура должна быть определена до этого с помощью директивы GLOBAL или ENTRY в тех модулях, где она впервые объявлена. Другие модули должны использовать директиву EXTERNAL для открытия доступа к внешним структурам. Директива имеет формат:

.EXTERNAL структура 1, структура 2, ...;

Пример:

.EXTERNAL met; {Метка находится в другом модуле}

Директива INCLUDE

Директива INCLUDE используется для включения других исходных файлов в файл, предназначенный для ассемблирования. Ассемблер открывает, читает и ассемблирует указанный файл, когда он встречает строку оператора INCLUDE. Ассемблированный код объединяется в выходном файле с расширением obj. Когда ассемблер достигает конца включенного файла, он возвращается в первичный исходный файл и продолжает обработку. Директива INCLUDE имеет следующий формат:

.INCLUDE <имя_файла>;

Если файл, который должен быть включен директивой INCLUDE, находится в текущей директории вместе с программой, в угловых скобках требуется указать только имя файла. Если файл находится в другом каталоге, необходимо указать полный путь к этому каталогу и имя файла (или использовать переменную среды окружения ADII). Например, если файл, который должен быть включен, называется filter.dsp и расположен в директории C:\ADSP2181\PROG2\, тогда директива INCLUDE должна быть задана следующим образом:

.INCLUDE <C:\ADSP2181\PROG2\filter.dsp>;

Это позволит ассемблеру найти файл. Существует и другой способ указания пути к файлу. Так можно указать путь, используя переменную среды окружения ADII с помощью команды:

Set ADII=C:\ADSP2181\PROG2

Данная команда должна записываться в файле autoexec.bat операционной системы или в командном файле для трансляции программы. Установка ADII, равной пути к каталогу, позволит ассемблеру обнаружить файл. В этом случае можно задавать имя файла без указания полного пути. Файл, включенный директивой INCLUDE, может также содержать внутри себя директиву INCLUDE. Вложение файлов директивами INCLUDE ограничивается только размером свободной оперативной памяти.

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

Пример:

.INCLUDE <библиотека_макросов>;

Директива MACRO

Директива MACRO создает в программе макрос (набор инструкций). Макрос используется для повторения часто используемых последовательностей инструкций в исходном тексте программы. Передачей аргументов макросу реализуется подобие подпрограммы, которая может быть использована в различных программах. Допускается делать вложение макросов. Макровложения ограничены только размером свободной оперативной памяти. Вложенные макросы должны быть объявлены в определенной последовательности. Первым объявляется внутренний макрос. Внешний макрос объявляется последним. Все константы, используемые в макросах, должны быть объявлены перед объявлением макросов. Макрос определяется двумя директивами. Первая директива имеет формат:

.MACRO имя_макроса (аргумент1, аргумент2, ...);

Завершает макрос директива окончания макроса:

.ENDMACRO;

Каждый оператор внутри макроса может быть инструкцией, директивой или макровключением. Макрос вызывается по своему имени. Чтобы выполнить макрос с именем mac1, необходимо вставить в текст программы команду mac1;. Макровызов не должен содержать дополнительных операторов в строке вызова (т.е. инструкций, директив препроцессора или других макровключений).

Аргументы макроса имеют форму записи:

%n, где n = 0, 1, 2, …, 9;

Следующий пример определяет макрос sum с тремя аргументами:

.MACRO sum(%0, %1, %2);

В коде макроса аргументы маркируются служебными символами %1, %2, %3, и т.д. При вызове макроса служебные символы замещаются величинами аргументов, переданных в макрос. При вызове макроса ему должно быть передано правильное число аргументов. Допустимые передаваемые аргументы и исключения для них приведены в табл. 11.4.

Таблица 11.4 Допустимые передаваемые в макрос аргументы и исключения для них

Аргумент

Исключение

Константа или арифметическое выражение

Нет

Символы

MACRO, ENDMACRO, CONST, INCLUDE

^буфер

^%n

%буфер

%%n

Операторы ^ и % не могут быть использованы с аргументами, замещающими служебные символы в макроопределении. Тем не менее, аргументы, переданные в макрос, могут использовать эти операторы. Например: read_data(^input);

Директива LOCAL

Директива LOCAL задает программные метки, используемые в макросе. Данная директива указывает ассемблеру создавать уникальную версию метки при каждом включении макроса. Это предотвращает ошибку дублирования меток в случае, когда макрос вызывается несколько раз в одном программном модуле. Директива имеет формат записи:

.LOCAL метка1, метка2, ...;

Ассемблер создает уникальные версии меток макроса, добавляя к ним номер. Это можно увидеть в файле листинга с расширением lst. Помните, что для раскрытия макросов в листинге необходимо при запуске программы компилятора asm21 добавить ключ -m.

Ниже приведен простейший пример макроса, позволяющий вставить в любое место программы несколько пустых команд пор.

.MACRO nops;

nop; nop; nop; nop; nop; nop;

.ENDMACRO;

Вызов данного макроса в программе осуществляется командой nops;. Следующий пример показывает, как создать макрос wait с одним параметром и одной локальной меткой.

MACRO wait(%0);

local loop;

cntr=%0;

do loop until ce;

loop: nop;

ENDMACRO;

Этот макрос позволяет организовать в программе функцию задержки на 100 циклов лаконичной записью:

wait(100);

Естественно, что вместо числа 100 можно вписывать любое число в разрешенном диапазоне для счетчика циклов.

Ниже приведен пример макроса, реализующий подпрограмму, которая переносит содержимое буфера данных из одной области памяти в другую.

.MACRO mem_trans (%0, %1, %2, %3, %4) {Использует 5 аргументов}

.LOCAL trans;

I4=%0; {Установить I4 как адрес источника}

I5=%1; {Установить I5 как адрес приемника}

M4=1 {Установить указатель на инкремент 1}

CNTR=%2 {Установить длину буфера}

DO trans UNTIL СЕ; {Перенос данных}

si=%3(I4, M4) {Перенос данных из типа %3 памяти}

trans: %4(I5, M4)=si; {В тип %4 памяти}

.ENDMACRO

Пример вызова этого макроса в программе может быть таким:

mem_trans (^tabl_coef, ^buf, %buf, PM, DM);

Здесь в качестве аргументов в макрос передаются адреса буферов tabl_coef и but, длина буфера but и тип памяти. Заметьте, что зарезервированные ключевые слова PM и DM переданы как аргументы.

Несколько следующих директив определяют формат файла листинга. Файл листинга с расширением lst позволяет представить результаты процесса ассемблирования. Ниже показан пример файла листинга простейшей программы. В этом файле используются следующие информационные поля:

addr — смещение от базового адреса модуля;

inst — код операции;

source line — номер строки исходного файла и код.

Release 5.11 Assembler Version 1.34s 9/19/95

D:\TEMA\IKS\PROG\TEST.DSP\DOS.dsp Mon Jun 21 17:07:36 2004 Page 1

addr inst     source line

1 .module/RAM/ABS=0 example;

2 .PAGEWIDTH 70;

3 {Описание переменных}

4 .var/dm flag;

5

6 {Инициализация переменных}

7 .init flag: 0x000f;

8

9 again:

0000 02010F  10 toggle FL1; /* Инвертировать флаг */

0001 18000Fu 11 jump again; /* Зациклить */

12 .endmod;

Каждая строка в листинге этой программы имеет свой номер. При обнаружении ошибки в какой-либо строке программы компилятор выдает именно этот номер строки. Символ «u» в поле inst показывает, что код операции содержит адрес перехода.

Существует пять директив ассемблера для формирования выходного файла листинга.

Директива NEWPAGE

Директива NEWPAGE вставляет разделители страниц. После такой директивы листинг программы продолжится с новой страницы. Данная директива, как и последующие, применяется для выделения программных фрагментов и оформления листинга программы. Пример ее использования:

.NEWPAGE;

Директива PAGELENTH

Директива PAGELENTH регулярно вставляет разделитель страниц после указанного количества строк. Формат ее записи:

.PAGELENGTH число_строк;

Директива LEFTMARGIN

Директива LEFTMARGIN оставляет левое поле с указанным числом столбцов (знакомест символов). Формат ее записи:

.LEFTMARGIN число_столбцов;

Директива INDENT

Директива INDENT осуществляет отступ строк программы в исходном коде с указанным числом столбцов. Формат ее записи:

.INDENT число_столбцов;

Директива PAGEWIDTH

Директива PAGEWIDTH определяет ширину строк листинга с указанным числом столбцов. Формат ее записи:

.PAGEWIDTH число_столбцов;

Директивы NEWPAGE и PAGELENGTH могут быть использованы для нумерации страниц, в то время как директивы LEFTMARGIN, INDENT и PAGEWIDTH используются для того, чтобы сделать каждую страницу удобной для чтения. Эти директивы могут быть помещены в любом месте исходного файла.

Директива ENDMOD

Директива ENDMOD указывает на завершение программного модуля. Программа ассемблера останавливается, когда достигает директивы ENDMOD. Формат ее записи:

.ENDMOD;

Глава 12. Форматы данных

В этой главе говорится о форматах представления данных в сигнальном процессоре при выполнении вычислительных операций.

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

С форматом представления данных в процессоре тесно связаны такие понятия, как целочисленная и плавающая арифметика. Другими словами, арифметические операции, выполняемые процессором, могут производиться с целыми или с вещественными числами. Известно, что вещественные числа имеют целую и дробную части, отделяемые друг от друга запятой. Если запятая не меняет своего положения в формате представления чисел при выполнении арифметических операций, говорят, что данные представлены в формате с фиксированной запятой. Например: 7,4×0,5=3,7. Здесь положение запятой фиксировано как для операндов, так и для результата. Недостатком такого представления является небольшой диапазон обрабатываемых чисел, определяемый количеством разрядов шины данных. Другим форматом представления данных может служить формат с плавающей запятой, где используется показатель степени. Например: 1,8×10^3:2,0×10^2=9,0×10^0. Здесь существенно расширяется диапазон обрабатываемых чисел за счет введения показателя степени, но снижается точность результата.

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

Вспомним форматы представления данных в двоичной арифметике. Формат представления двоичного числа обычно включает в себя знак, запятую и величину. Знак показывает, является число положительным или отрицательным. Запятая отделяет целую и дробную части числа.

Знак двоичного числа может быть представлен одним битом. Как правило, ноль указывает на положительное значение числа, а единица на отрицательное его значение. Знаковый бит обычно крайний левый бит (старший бит).

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

Существует несколько форматов представления отрицательных чисел в дополнительном коде. Наиболее распространенным методом является дополнение до двух, который используется в семействе процессоров ADSP-21XX.

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

С помощью n бит в дополнительном коде можно представлять диапазон чисел от -2n-1 до 2n-1-1, где n-1 разрядов отводится под величину, а 1 разряд под знак числа. Например, с помощью 16-разрядной шины данных в дополнительном коде можно представить числа в диапазоне от -32768 до 32767.

Существует два способа перевода отрицательного числа в формат дополнения до двух. Первый способ состоит из инвертирования всех разрядов числа и прибавления к нему единицы. Второй способ заключается в инвертировании всех разрядов числа левее младшего единичного разряда. Положительные числа не требуется переводить в дополнительный код. Ниже приведен пример перевода отрицательного 16-разрядного числа -5 по первому способу:

Двоичная запись числа 5:0000 0000 0000 0101

Инверсия бит: 1111 1111 1111 1010

Добавление 1: 0000 0000 0000 0001

---------------------------------

Результат=-5: 1111 1111 1111 1011

Пример перевода отрицательного числа -5 по второму способу:

Двоичная запись числа 5:0000 0000 0000 0101

Инверсия бит: 1111 1111 1111 1011

---------------------------------

Результат=-5: 1111 1111 1111 1011

Если сложить число -5 в дополнительном коде с числом 6, получим:

Число -5: 1111 1111 1111 1011

Число 6: 0000 0000 0000 0110

----------------------------

Число 1: 0000 0000 0000 0001

Как видим, результат получился верным.

При записи числа в дробном формате предполагается, что запятая размещается между какими-то определенными двоичными разрядами в числе. Биты слева от запятой представляют целую часть числа, а биты справа от запятой дробную часть числа. Существует два способа указания местоположения запятой, в формате с фиксированной точкой и в формате с плавающей точкой.

Формат с фиксированной точкой располагает запятую в одном, предопределенном месте. Часто это местоположение слева от всех разрядов числа, когда все разряды отводятся под дробную часть, или справа от всех разрядов, когда все разряды отводятся под целую часть. Местоположение запятой устанавливается программным способом. Некоторые арифметические операции, например умножение, могут изменять позицию запятой, поэтому может понадобиться сдвиг, чтобы сохранить число в том же формате с фиксированной точкой.

Формат с плавающей точкой состоит из двух частей, которые представляют значение мантиссы и экспоненты числа. Экспонента указывает местоположение запятой. Она может храниться вместе с мантиссой или в отдельном регистре.

Семейство процессоров ADSP-21XX поддерживают операции с числами в формате с фиксированной точкой. В настоящем изложении при указании формата числа используется запись L.R, где L — число двоичных разрядов слева от запятой, a R — число разрядов справа от запятой. Например, формат записи 1.15 указывает на то, что дробное число имеет один знаковый разряд и 15 разрядов для представления величины дробной части. Целое число имеет для такого представления формат записи 16.0. Для большинства приложений обработки сигналов предполагается использование дробных чисел в формате 1.15, поскольку умножитель и делитель процессора ADSP-2181 оптимизированы для операций с числами именно в таком формате.

Ассемблер ADSP-21XX поддерживает четыре формата представления данных при вычислениях. Формат представления данных имеет следующие условные названия: двоичная строка, двоичные числа без знака, знаковые числа в дополнительном коде и дробное представление.

Двоичная строка является самым простым форматом представления чисел в процессорах семейства ADSP-21XX. Этот формат используется при выполнении элементарных логических операций типа NOT, OR, AND и XOR. Ниже приведены весовые значения битов для этого формата записи.

2^152^142^132^122^112^102^92^82^72^62^52^42^32^22^12^0

Под двоичными числами без знака понимаются положительные числа. Диапазон их представления в процессоре в два раза больше чем у чисел со знаком, за счет самого знакового разряда. Фактически они выглядят также, как двоичная строка.

Знаковые числа можно отнести к числам в дополнительном коде. Большинство операций процессора поддерживают работу с числами в дополнительном коде. Процессоры семейства ADSP-21XX не поддерживают работу с остатками и числами в двоично-десятичном формате BCD (Binary Coded Decimal), когда каждая десятичная цифра представляется 4-битным двоичным позиционным кодом. Ниже приведены весовые значения битов для этого формата знаковых чисел.

-2^02^142^132^122^112^102^92^82^72^62^52^42^32^22^12^0

Дробное представление чисел имеет формат записи 1.15. Это означает, что 16-разрядное число имеет один знаковый разряд и пятнадцать дробных битов. Ниже представлены весовые значения битов в формате 1.15.

-2^02-12-22-32-42-52-62-72-82-92-102-112-122-132-142-15

Для вычисления числа, записанного в этом формате, необходимо подставить вместо цифры 2 значение соответствующего разряда (0 или 1) и сложить все полученные значения. В табл. 12.1 приведены примеры соответствия чисел записанных в шестнадцатеричном виде формата 1.15 их десятичным значениям.

Таблица 12.1 Примеры соответствия чисел, записанных в шестнадцатеричном виде формата 1.15, их десятичным значениям

Число в формате 1.15

Число в HEX формате

Десятичное значение

0000 0000 0000 0000

0x0000

+0

0000 0000 0000 0001

0x0001

+0,000030517578125

0000 0000 0000 0010

0x0002

+0,00006103515625

1000 0000 0000 0000

0x8000

-1,000000

0111 1111 1111 1111

0x7FFF

+0,999969482421875

1111 1111 1111 1111

0xFFFF

-0,000030517578125

Как видно из таблицы, самый младший разряд эквивалентен десятичному значению 0,000030517578125. Это значение и определяет точность представления всех чисел в данном формате. Для достижения большей точности необходимо расширять разрядность числа, например программным образом размещая число в два или три 16-разрядных регистра. Аналогично можно увеличить и диапазон обрабатываемых чисел.

В табл. 12.2 приведены все возможные варианты форматов для 16-разрядного числа. Эта таблица дает наглядное представление о том, как изменяется, в зависимости от формата, диапазон представляемых чисел и их точность.

Таблица 12.2 Возможные варианты форматов для 16-разрядного числа

Формат

Количество целых разрядов

Количество дробных разрядов

Максимальное положительное значение

Максимальное отрицательное значение

Вес младшего разряда

1.15

1

15

0,999969482421875

-1,0

0.000030517578125

2.14

2

14

1,999938964843750

-2,0

0.000061035156250

3.13

3

13

3,999877929687500

-4,0

0.000122070312500

4.12

4

12

7,999755859375000

-8,0

0.000244140625000

5.11

5

11

15,999511718750000

-16,0

0.000488281250000

6.10

6

10

31,999023437500000

-32,0

0.000976562500000

7.9

7

9

63,998046875000000

-64,0

0.001953125000000

8.8

8

8

127,996093750000000

-128,0

0.003906250000000

9.7

9

7

255,992187500000000

-256,0

0.007812500000000

10.6

10

6

511,984375000000000

-512,0

0.015625000000000

11.5

11

5

1023,968750000000000

-1024,0

0.031250000000000

12.4

12

4

2047,937500000000000

-2048

0.062500000000000

13.3

13

3

4095,875000000000000

-4096,0

0.125000000000000

14.2

14

2

8191,750000000000000

-8192,0

0.250000000000000

15.1

15

1

16383,500000000000000

-16384,0

0.500000000000000

16.0

16

0

32767,000000000000000

-32768,0

1.000000000000000

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

В зависимости от типа решаемой задачи программист сам определяет, какой именно формат лучше использовать.

Глава 13. Система команд

В этой главе начинается изложение системы команд сигнального процессора.

Сигнальные процессоры семейства ADSP-21XX используют единую систему команд для совместимости с устройствами с более высокой интеграцией. Процессоры ADSP-2181 имеют ряд дополнительных команд. Каждая команда может быть выполнена в процессоре за один такт. Кроме того, система команд процессора позволяет выполнять за один такт многофункциональные команды. Как было сказано ранее, язык ассемблер семейства ADSP-21XX использует высокоуровневый алгебраический синтаксис записи команд, что облегчает их понимание и запоминание. Операнды источника и приемника команды явно присутствуют в ее записи в виде мнемоники. Мнемоника основных регистров процессора с описанием их назначения приводится в табл. 13.1.

Таблица 13.1 Мнемоника основных регистров процессора с описанием их назначения

Мнемоника

Определение

AX0, AX1, AY0, AY1

Входные регистры АЛУ

AR

Регистр результата АЛУ

AF

Регистр обратной связи АЛУ

MX0, MX1, MY0, MY1

Входные регистры умножителя MAC

MR0, MR1, MR2

Регистры результата умножителя

MF

Регистр обратной связи умножителя

SI

Входной регистр устройства сдвига Shifter

SE

Регистр экспоненты устройства сдвига

SR0, SR1

Регистры результата устройства сдвига

SB

Регистр блочного сдвига (используется в блочных операциях с плавающей точкой)

PX

Регистр шинного обмена памяти программ PM с памятью данных DM

I0–I7

Индексные регистры генераторов адреса DAG

M0–M7

Регистры модификации DAG

L0–L7

Регистры длины DAG (для циклических буферов)

PC

Программный счетчик

CNTR

Счетчик циклов

ASTAT

Регистр арифметического статуса

MSTAT

Регистр статуса режима

SSTAT

Регистр статуса стека

IMASK

Регистр маски прерываний

ICNTL

Регистр режимов управления прерываниями

RX0, RX1

Регистры приема данных последовательных портов SPORT

TX0, TX1

Регистры передачи данных последовательных портов SPORT

Набор команд ADSP-2181 совместим вверх с набором команд ADSP-21XX, поэтому, программы, написанные для ADSP-21XX, могут выполняться на ADSP-2181 с минимальными изменениями. Процессор ADSP-2181 имеет ряд дополнительных команд. Каждая команда может быть выполнена отдельно в своем такте. Кроме того, система команд позволяет выполнять за один такт процессора многофункциональные команды.

Язык ассемблера позволяет использовать в командах арифметические или логические выражения. Список этих выражений и выполняемых с их помощью действий приведен в табл. 13.2.

Таблица 13.2 Список арифметических или логических выражений и выполняемых с их помощью действий

Выражение

Действие

=

Присвоение

+

Сложение

-

Вычитание

*

Умножение

AND

Логическое «И»

OR

Логическое «ИЛИ»

NOT

Логическое отрицание

XOR

Исключающее «ИЛИ»

PASS

Пересылка

ABS

Абсолютное значение

Ниже приведены примеры записи некоторых команд языка ассемблера ADSP-21XX с объяснением их назначения.

DM(var1) = AX0;

Эта команда, знакомая читателям из предыдущих примеров программ, присваивает (записывает) значение регистра AX0 переменной var1, хранящейся в памяти данных.

MR = MR + MX1*MY1;

Данная команда выполняет операцию умножения и сложения. Он умножает входные значения из регистров MX1 и MY1, складывает результат умножения с текущим содержимым регистра MR (результат предыдущего умножения), а затем записывает результат в регистр MR.

При рассмотрении системы команд мы будем пользоваться условными обозначениями, приведенными в табл. 13.3. Эти обозначения позволяют сделать описание команд компактным.

Таблица 13.3 Условные обозначения системы команд

Обозначение

Описание

I0–I7

Индексные регистры DAG для косвенной адресации

M0–M7

Регистры модификации DAG для косвенной адресации

L0–L7

Регистры длины DAG для циклических буферов

<data>

Непосредственное значение данных

<addr>

Непосредственное значение адреса (абсолютный адрес или программная метка)

<exp>

Порядок (значение сдвига) в командах непосредственного сдвига (8-разрядное знаковое число)

cond

Код условия в условных командах

term

Код условия выхода из цикла DO UNTIL

dreg

Регистры данных (АЛУ, умножителя-накопителя или устройства сдвига)

reg

Любой регистр (включая регистры данных «dreg»)

;

Точка с запятой, разделитель команд

,

Запятая, разделитель нескольких операций в одной команде

[]

Квадратные скобки, содержащие дополнительные, необязательные части команд

[, …]

Запись нескольких операций или команд в любом порядке, разделенных запятыми

|опция1| |опция2| |опция3|

Список опций (в команде выбирается одна из опций)

xop

Операнд «x»

yop

Операнд «y»

constant

Операнд-константа

В табл. 13.4 приведен список регистров, допустимых к использованию в командах пересылки и многофункциональных командах.

Таблица 13.4 Список регистров допустимых к использованию в командах пересылки и многофункциональных командах

Регистр

Примечание

Регистры данных <dreg>

AX0, АХ1, AY0, AY1

–

AR

–

MX0, МХ1, MY0, MY1

–

MR0, MR1, MR2

–

SI, SE, SR0, SR1

–

Остальные регистры <reg>

I0, I1, I2, I3, I4, I5, I6, I7

–

M0, M1, M2, M3, M4, M5, M6, M7

–

L0, L1, L2, L3, L4, L5, L6, L7

–

TX0, TX1, RX0, RX1

–

SB, PX

–

ASTAT, MSTAT

–

SSTAT

Только чтение

IMASK, ICNTL

–

IFC

Только запись

CNTR

–

OWRCNTR

Только запись

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

Команда сложить или сложить с переносом, записанная с применением приведенных выше условных сокращений, будет выглядеть следующим образом:

[IF cond] |AR| = xop + | yop      |;

|AF|         | C        |

| yop + C  |

| constant |

Она означает, что если условие cond предыдущей команды выполняется, то в регистр AR или AF будет занесен результат сложения операнда xop с операндом yop или с переносом или с константой. Разрешенные операнды xop, yop и константы constant указываются для группы команд индивидуально, поскольку они не всегда могут быть произвольными. Например, для команд АЛУ разрешено использовать в качестве операнда xop регистры; AX0, АХ1, AR, MR0, MR1, MR2, SR0, SR1. В качестве операнда yop допускается использование регистров: AY0, AY1 и AF. Причем команда DIVS не может использовать регистр AY0.

Коды условий cond с описанием их назначения приведены в табл. 13.5.

Таблица 13.5 Коды условий cond с описанием их назначения

Код условия cond оператора IF

Описание

EQ

Равно нулю

NE

He равно нулю

LT

Меньше нуля

GE

Больше или равно нулю

LE

Меньше или равно нулю

GT

Больше нуля

AC

Перенос АЛУ

NOT AC

Нет переноса АЛУ

AV

Переполнение АЛУ

NOT AV

Нет переполнения АЛУ

MV

Переполнение умножителя

NOT MV

Нет переполнения умножителя

NEG

Входной операнд xop отрицателен

POS

Входной операнд xop положителен

NOT CE

Счетчик циклов не пуст

FLAG_IN*

Вывод FI = 1

NOT FLAG_IN*

Вывод FI = 0

* Только для команд JUMP и CALL.

Таким образом, предыдущая запись означает, что команда сложения может быть записана в одном из следующих вариантов:

IF EQ AR=AX0+AY1;

IF EQ AR=AR+AY1+C;

IF EQ AF=AX0+AY1;

IF NE AF=AX0+AY1;

AR=AX0+AF;

и т.п.

Обратите внимание на то, что оператор IF с кодом условия заключен в квадратные скобки, т.е. является не обязательным в команде и может быть исключен из нее.

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

Для завершения обзора команд сигнального процессора нам остается рассмотреть многофункциональные команды и команды, которые нельзя отнести к какой-либо конкретной группе в силу того, что они выполняют различные функции. Здесь они будут называться дополнительными командами.

Многофункциональные команды

В многофункциональных командах реализуются свойства параллелизма архитектуры процессоров ADSP2181. Благодаря чему становится возможным одновременное выполнение в одном цикле процессора пересылки данных, операций чтения/записи в память и вычислений.

Рассмотрим многофункциональную команду выполнения операций АЛУ и MAC с одновременным чтением операндов из памяти данных и памяти программ. Пример такой команды приведен ниже:

MR=MR+MX0*MY0(SS), MX0=DM(I3,M0), MY0=PM(I7,M4);

В первой части этой команды в регистр MR (регистр результата MAC), записывается сумма его предыдущего значения и произведения текущих значений входных регистров умножителя MX0 и MY0. Здесь оба слагаемых рассматриваются в знаковом формате.

Вторая и третья части данной многофункциональной команды осуществляют выбор двух новых операндов. Один операнд выбирается из памяти данных DM по адресу, указанному в индексном регистре I3, содержимое которого затем модифицируется с помощью значения регистра модификации M0. Второй операнд выбирается из памяти программы PM по адресу, указанному в регистре I7, содержимое которого затем модифицируется величиной, содержащейся в регистре модификации M4. Значения индексов берутся из регистров генераторов адреса данных. Любой индексный регистр I одного генератора адреса данных может использоваться в паре с любым регистром модификации M того же генератора адреса данных.

Поскольку считывание данных из регистров процессора производится в начале цикла, а запись в регистры - в конце цикла, операнды, находящиеся в регистрах MX0 и MY0 в начале командного цикла, перемножаются, а затем произведение добавляется к содержимому регистра результата умножителя MR. После окончания операции умножения операнды обновляются новыми значениями, которые были выбраны в конце того же командного цикла и становятся доступными для вычислений с ними в следующем цикле. Естественно, что одновременно с вычислением можно загрузить любой регистр данных, а не только регистры умножителя/накопителя, как в приведенном выше примере.

Рассмотренная команда является, пожалуй, самой распространенной в алгоритмах цифровой обработки сигналов операцией. Выполняется она следующим образом:

• осуществляется выбор двух операндов (например, коэффициента и данных);

• производится перемножение операндов и суммирование результата умножения с полученными до этого результатами.

Вычислительной частью данной многофункциональной команды может быть любая безусловно выполняемая команда АЛУ, за исключением деления, или любая команда умножителя, кроме насыщения. Имеются и некоторые другие исключения.

Например, следующий операнд X должен загружаться в регистр MX0 из памяти данных, а новый операнд Y должен загружаться в регистр MY0 из памяти программ (для команд данного уровня несущественно, из внутренней или из внешней памяти). Кроме того, результат вычисления должен записываться в регистр результата (MR или AR), ни в коем случае не в регистр обратной связи (MF или AF).

Теперь рассмотрим команды одновременного чтения из памяти данных и памяти программ. Эти команды представляют собой разновидность описанного выше вида многофункциональных команд. Их особенностью является отсутствие вычислений. Эти команды задают только одновременную выборку двух операндов. Пример такой команды приведен ниже:

AX0=DM(I2,M0), AY0=PM(I4,M6);

В данном примере в качестве регистров-приемников используются входные регистры АЛУ. Как и в предыдущем типе многофункциональных команд, здесь операнды X должны извлекаться из памяти данных, а операнды Y - из памяти программ (и в том и в другом случае из внешней или из внутренней памяти процессоров с внутренней памятью на кристалле).

Существуют многофункциональные команды выполнения вычислений с одновременным считыванием из памяти. Если, в отличие от описанных выше многофункциональных команд, вместо двойного считывания из памяти, команда задает выполнение только одной операции считывания из одного типа памяти, то одновременно с выборкой данных из памяти можно произвести различного рода вычисления. К числу таких разрешенных вычислений относятся все операции АЛУ, за исключением деления, все операции умножителя-накопителя MAC и все операции устройства сдвига, за исключением непосредственного сдвига SHIFT IMMEDIATE. Все вычисления должны быть безусловными. Пример многофункциональной команды такого типа приведен ниже:

AR=AX0+AY0, AX0=DM(I0,M3);

В этом примере в АЛУ выполняется операция сложения, в то время как из памяти данных выбирается один операнд. Этот тип многофункциональных команд имеет те же ограничения, что и предыдущий. Значение, хранящееся в регистре AX0 и используемое как исходное в ходе вычислений, представляет собой содержимое этого регистра в начале цикла. В конце цикла в результате операции считывания данных из памяти в регистр AX0 загружается новое значение. По этой же причине регистром назначения (в этом примере AR) не может быть регистр, указанный в качестве регистра назначения при считывании данных из памяти.

Следующий пример демонстрирует выполнение вычислений с одновременной записью данных в память. Команда вычисления с одновременной записью в память имеет ту же структуру, что и команда вычисления с одновременным считыванием из памяти. Однако порядок операторов в строке данной команды меняется на обратный. Сначала выполняется запись данных в память, а затем вычисление. Вот пример такой команды:

DM(I0,M0)=AR, AR=AX0+AY0;

В приведенном примере исходным значением для записи в память (значение, содержащееся в регистре AR) является значение, хранящееся в этом регистре в начале цикла. В результате произведенного вычисления в этот же регистр загружается новое значение, которое является содержимым регистра AR в конце цикла. При постановке операторов данной команды в обратном порядке, что является неразрешенным действием, ассемблер генерирует предупреждение, подразумевающее, что в память записывается результат вычисления, а не предыдущее значение регистра, которое должно было записываться в память. Использование при этом одного и того же регистра не является обязательным, хотя именно таким образом чаще всего организуется конвейер операндов для вычисления. Для вычислительных операций с помощью таких команд действуют те же ограничения, что и для команд, рассмотренных выше. Разрешенными являются все операции АЛУ, кроме деления, все операции умножителя-накопителя MAC и все операции устройства сдвига, кроме непосредственного сдвига. Вычисления должны быть безусловными.

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

AR=AX0+AY0, AX0=MR2;

В данном примере операция сложения в АЛУ производится одновременно с загрузкой в регистр AX0 нового значения, взятого из регистра MR2. Как и в предыдущих примерах, для вычисления используется значение, содержащееся в регистре AX0 в начале цикла. Данные могут между всеми регистрами ввода или вывода АЛУ, умножителя-накопителя MAC и устройства сдвига, за исключением регистров обратной связи (AF и MF) и регистра SB. В рассмотренном примере новое значение загружается в регистр AX0 из регистра данных в конце цикла. Разрешенными являются все операции АЛУ, кроме деления, все операции умножителя-накопителя и все операции устройства сдвига, кроме непосредственного сдвига. Вычисления должны быть безусловными.

Ниже приводится полный список многофункциональных команд в соответствии с принятыми ранее условными обозначениями. Назначение команд приводится в тексте описания этих команд. Вычисление с пересылкой регистр-регистр:

| <ALU> |, dreg = dreg;

| <MAC> |

|<SHIFT>|

Вычисление с чтением из памяти:

|<ALU>  |,dreg = |DM(|I0|,|M0|)|;

|<MAC>  |        |   |I1| |M1| |

|<SHIFT>|        |   |I2| |M2| |

|   |I3| |M3| |

|   |I4| |M4| |

|   |I5| |M5| |

|   |I6| |M6| |

|   |I7| |M7| |

|             |

|PM(|I4|,|M4|)|;

|   |I5| |M5| |

|   |I6| |M6| |

|   |I7| |M7| |

Вычисление с записью в память:

|DM(|I0|,|M0|)|=dreg, |<ALU>  |;

|   |I1| |M1| |       |<MAC>  |

|   |I2| |M2| |       |<SHIFT>|

|   |I3| |M3| |

|   |I4| |M4| |

|   |I5| |M5| |

|   |I6| |M6| |

|   |I7| |M7| |

|             |

|PM(|I4|,|M4|)|;

|   |I5| |M5| |

|   |I6| |M6| |

|   |I7| |M7| |

Чтение памяти данных и программ:

|AX0|=DM(|I0|,|M0|), |AY0|=PM(|I4|,|M4|);

|AX1|    |I1| |M1|   |AY1|    |I5| |M5|

|MX0|    |I2| |M2|   |MY0|    |I6| |M6|

|MX1|    |I3| |M3|   |MY1|    |I7| |M7|

Команда АЛУ или MAC с чтением памяти данных и программ:

|<ALU>|,|AX0|=DM(|I0|,|M0|), |AY0|=PM(|I4|,|M4|);

|<MAC>| |AX1|    |I1| |M1|   |AY1|    |I5| |M5|

|MX0|    |I2| |M2|   |MY0|    |I6| |M6|

|MX1|    |I3| |M3|   |MY1|    |I7| |M7|

В качестве регистров dreg могут быть использованы регистры: AX0, АХ1, AY0, AY1, AR, MX0, МХ1, MY0, MY1, MR0, MR1, MR2, SI, SE, SR0 и SR1.

Примечания:

<ALU>¹ — любая команда АЛУ (исключая DIVS и DIVQ);

<MAC>¹ — любая команда умножителя/накопителя;

<SHIFT>² — любая команда устройства сдвига (исключая непосредственный сдвиг);

где ¹ — должны использоваться только регистры результатов AR, MR, а не регистры обратных связей AF, MF; ² — не могут быть условными командами.

Дополнительные команды

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

Пустая команда:

NOP;

Модифицировать регистр адреса:

MODIFY(|I0|,|M0|);

|I1| |M1|

|I2| |M2|

|I3| |M3|

|I4| |M4|

|I5| |M5|

|I6| |M6|

|I7| |M7|

Управление стеками:

[|PUSH| STS] [,POP CNTR] [,POP PC] [,POP LOOP];

|POP |

Управление режимом:

|ENA| |SEC_REG | [, ...];

|DIS| |BIT_REV |

|AV_LATCH|

|AR_SAT  |

|M_MODE  |

|TIMER   |

|G_MODE  |

|INTS    |

Ключевые слова означают следующие режимы:

SEC_REG — фоновый регистровый файл;

BIT_REV — бит-реверс адреса генератора DAG1;

AV_LATCH — защелка статуса переполнения АЛУ (AV);

AR_SAT — насыщение регистра AR;

M_MODE — режим размещения результата MAC;

TIMER — разрешить работу таймера;

G_MODE — разрешить режим «Go mode»;

INTS — разрешить прерывания.

NOP — это команда отсутствия операций. Она часто применяется для выполнения холостого цикла процессора в качестве задержки на один такт.

Команда MODIFY позволяет модифицировать указатель адреса в заданном регистре I на величину, которая содержится в заданном регистре M, не обращаясь при этом к памяти. Как и во всех других случаях, регистры I и M должны быть регистрами одного и того же генератора адреса данных; любой регистр I0–I3 может использоваться в комбинации с любым регистром M0–M3, а любой регистр I4–I7 — с любым регистром M4–M7.

Команды PUSH и POP позволяют непосредственно управлять содержимым стеков состояния, счетчика, счетчика программ (PC) и циклов. Некоторые из этих стеков автоматически заполняются и опустошаются во время обслуживания прерываний.

Команды управления режимом разрешают и блокируют режимы некоторых операций процессора. Эта команды управляют режимами реверсной адресации в генераторе адреса данных 1, фиксацией переполнения АЛУ, насыщением регистра результата АЛУ, выбором набора основных или теневых регистров, режимом GO для непрекращающейся работы процессора во время предоставления шины, режимом сдвига в умножителе для выполнения целочисленных или дробных вычислений и активизацией таймера. За операторами ENA или DIS может следовать через запятую сколько угодно идентификаторов. Команды ENA и DIS могут повторяться в командной строке. Кроме того, все семь режимов могут разрешаться, блокироваться или изменяться при помощи всего одной команды.

Часть III. Вычислительные и аппаратные устройства

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

Глава 14. Устройство АЛУ

Назначение

Как уже говорилось ранее, процессор ADSP-2181 содержит три независимых вычислительных устройства (рис. 14.1). К их числу относятся: арифметико-логическое устройство (ALU), умножитель с накопителем (MAC) и устройство сдвига (SHIFTER). Эти устройства работают с 16-разрядными данными и имеют аппаратную поддержку обмена данными, позволяющую обеспечить многопоточность.

Рис. 14.1. Процессор ADSP-2181

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

Вычислительные модули размещаются последовательно друг за другом таким образом, чтобы выход одного мог стать входом другого в следующем цикле. Результаты работы вычислительных устройств собираются на 16-разрядную шину R-BUS.

Все три устройства содержат входные и выходные регистры, которые доступны через 16-разрядную шину данных. Команды, выполняемые в устройствах, берут в качестве операндов данные, находящиеся в регистрах ввода, и после выполнения операции записывают результат в регистры вывода. Регистры являются как бы промежуточным хранилищем между памятью и вычислительной схемой. Шина R-BUS позволяет результату одного вычисления стать операндом для другой операции. Это экономит время благодаря исключению лишних пересылок данных между устройствами и памятью.

Структура устройства ALU

Рассмотрим подробнее ALU. Его структурная схема приведена на рис. 14.2.

Рис. 14.2. Структурная схема ALU

Арифметико-логическое устройство является 16-разрядным устройством с двумя 16-разрядными входными портами данных X и Y и одним выходным портом результата R. ALU генерирует шесть сигналов состояния: ноль (AZ), негатив (AN), перенос (AC), переполнение (AV), знак (AS) и частное (AQ). В конце каждого цикла процессора эти сигналы сохраняются в регистре состояния процессора ASTAT. Описание назначения этих сигналов состояния приведено в табл. 14.1.

Таблица 14.1 Описание назначения сигналов состояния

Сигнал

Расшифровка

Назначение

AZ

ZERO (НОЛЬ)

Разряд нулевого результата. Устанавливается в 1, если результат операции равен нулю. Является результатом логического сложения всех битов регистра результатов ALU

AN

NEGATIV (НЕГАТИВ)

Знаковый разряд результата ALU. Устанавливается в 1, если результат отрицательный

AV

OVERFLOW (ПЕРЕПОЛНЕНИЕ)

Разряд переполнения. Устанавливается в 1, если происходит переполнение ALU путем переноса 1 в знаковый разряд при сложении чисел

AC

CARRY (ПЕРЕНОС)

Разряд переноса. Устанавливается в 1 при сложении беззнаковых чисел, если происходит переполнение ALU путем переноса 1 из старшего разряда

AS

SIGN (ЗНАК)

Знаковый разряд. Определяется при операции вычисления абсолютного значения числа ABS. Устанавливается в 1, если операнд имеет отрицательное значение

AQ

QUOTIENT (ЧАСТНОЕ)

Разряд состояния частного. Формируется только командами DIVS и DIVQ

Порт ввода X может принимать данные от двух источников: из блока регистров АХ или с шины результата R-BUS. Шина R-BUS обеспечивает обмен данными между всеми вычислительными устройствами. Блок регистров АХ состоит из двух регистров: AX0 и AX1. Эти регистры подключены к шине памяти данных DMD-BUS. Система команд позволяет читать содержимое регистра АХ и на шину памяти программ PMD-BUS, для этого используется устройство обмена между шинами. Выводы регистров AX0 и AX1 реализованы таким образом, чтобы один из них служил операндом для ALU, а другой в это время мог считываться на шину DMD-BUS.

Порт ввода Y также принимает данные от двух источников: из блока регистров AY и регистра обратной связи AF. Блок регистров AY состоит из двух регистров AY0 и AY1. Эти регистры доступны для чтения и записи с шиной DMD-BUS. Система команд процессора позволяет читать регистры AY0 и AY1 с помощью шины PMD-BUS, но также с использованием устройства обмена между шинами. Выводы регистров AY0 и AY1 реализованы аналогично регистрам AX0 и AX1.

Выход ALU подключен к выходному регистру результата AR и через регистр обратной связи AF на вход ALU через мультиплексор. Регистр AF позволяет результату вычисления использоваться в качестве следующего операнда. Регистр AR имеет выход на шину DMD-BUS и R-BUS. В системе команд предусмотрена возможность чтения регистра AR посредством шины PMD-BUS аналогично двум предыдущим вариантам.

Любой из регистров ALU доступен для записи и чтения в течение цикла процессора (для чтения — в начале цикла, и для записи - в конце процессорного цикла). Таким образом, новое значение, записанное в конце одного цикла, может быть прочитано лишь в начале следующего. Это позволяет входным регистрам записать в ALU операнд в начале цикла и считать следующий операнд в конце того же цикла. Это также позволяет сохранить содержимое регистра результата в памяти и оперировать со следующим результатом в одном цикле.

Арифметико-логическое устройство имеет альтернативные (теневые) банки регистров AX, AY, AF и AR. На структурной схеме они изображены в виде теней. В конкретный момент времени доступен только один из типов банков. Дополнительный банк может быть использован для автоматического сохранения данных в регистрах ALU при быстром переключении на выполнение подпрограммы. В этом случае экономится время на сохранение текущих данных в памяти процессора.

Выбор главного или альтернативного банка регистров определяется битом 0 регистра режимов процессора MSTAT. Если этот разряд равен 0, то выбран главный банк, если он равен 1, то выбирается дополнительный банк.

Арифметико-логическое устройство выполняет набор стандартных арифметических и логических операций. Из арифметических операций АЛУ выполняет сложение, вычитание, отрицание, инкремент, декремент и вычисление модуля. Эти операции дополнены двумя примитивами деления, с помощью которых возможна реализация цикла многократного деления. Из логических операций АЛУ выполняет логическое сложение (OR), логическое умножение (AND), исключающее ИЛИ (XOR), и логическое отрицание (NOT). Стандартные операции ALU приведены в табл. 14.2.

Таблица 14.2 Стандартные операции ALU

Операция

Назначение

R=X+Y

Сложение операндов X и Y

R=X+Y+CI

Сложение операндов X и Y с переносом

R=X-Y

Вычитание операнда Y из X

R=Y-X

Вычитание операнда X из Y

R=X-Y+CI-1

Вычитание операнда Y из X с заемом

R=Y-X+CI-1

Вычитание операнда X из Y с заемом

R= -X

Инверсия операнда X

R= -Y

Инверсия операнда Y

R=X+1

Инкремент операнда X

R=Y+1

Инкремент операнда Y

R=X-1

Декремент операнда X

R=Y-1

Декремент операнда Y

R=PASS X

Результат равен операнду X с установкой флагов регистра статуса ASTAT

R=PASS Y

Результат равен операнду Y с установкой флагов регистра статуса ASTAT

R=0

Очистка результата

R=ABS X

Результат равен абсолютному значению операнда X (значение по модулю)

R=X AND Y

Логическое умножение операндов X и Y

R=X OR Y

Логическое сложение операндов X и Y

R=X XOR Y

Исключающее «ИЛИ» операндов X и Y

R=NOT X

Логическое отрицание X

R=NOT Y

Логическое отрицание Y

В качестве условных записей операндов X, Y и R ALU, указанных в табл. 14.2, могут выступать следующие регистры:

- для X: AX0, АХ1, AR, MR0, MR1, MR2, SR0, SR1;

- для Y: AY0, AY1, AF;

- для R: AR и AF.

Регистры MR0, MR1, MR2 принадлежат умножителю MAC, а регистры SR0, SR1 устройству сдвига Shifter. Они доступны ALU по шине данных.

С целью обработки чисел с повышенной точностью, в ALU используются сигнал переноса CI (carry-in) и бит переноса AC (ALU carry). Операция сложения с переносом предназначена для сложения старших частей чисел, а операция вычитания с заемом — для их вычитания.

Регистр AR может работать в режиме насыщения. В этом режиме он принимает максимально возможное отрицательное или положительное значение, если операция заканчивается переполнением. Эта функция регистра AR становится возможной при установке в единицу разряда 3 регистра MSTAT. В табл. 14.3 показано содержимое регистра AR ALU в зависимости от флагов регистра состояния ASTAT при включенном, с помощью регистра MSTAT, режиме насыщения.

Таблица 14.3 Содержимое регистра AR ALU в зависимости от флагов регистра состояния

AV (переполнение)

АС (перенос)

Содержимое AR

0

0

В соответствии с результатом ALU

0

1

В соответствии с результатом ALU

1

0

0111111111111111 (максимальное положительное число)

1

1

1000000000000000 (минимальное отрицательное число)

Режим блокировки переполнения ALU разрешается при установке в единицу бита 2 регистра MSTAT. В этом режиме при переполнении ALU разряд AV устанавливается в единицу и при последующих операциях остается в этом состоянии. Таким образом, последующее переполнения уже не генерируются. Бит состояния AV можно очистить непосредственно с DMD шины путем записи в регистр состояния ASTAT нуля.

Арифметико-логическое устройство поддерживает операции деления. Деление осуществляется путем сложения и циклического сдвига чисел с помощью двух специальных примитивов деления DIVS и DIVQ. Команда DIVS вычисляет знаковый бит частного, а DIVQ вычисляет один бит частного. Данные команды применяются для деления знаковых или беззнаковых чисел. Алгоритм деления выполняет либо сложение, либо вычитание, основываясь на знаках делителя и частичного остатка. Остаток при этих операциях недоступен. При этом делитель и делимое должны быть одного типа. Обычная точность деления для 32-разрядного делимого, 16-разрядного делителя и 16-разрядного остатка реализуется за 16 циклов. Делитель может быть сохранен в регистре AX0, АХ1 или в любом регистре результатов R. Старший байт знакового делителя должен находиться либо в регистре AY1, либо в AF, а беззнакового делителя — в регистре AF. Младший байт делителя любого типа должен находиться в AY0. Остаток после деления будет записан в регистр AY0.

Первый из двух примитивов — это команда DIVS (деление-знак). Она предназначена для деления чисел со знаком. Структура операции DIVS показана на рис. 14.3.

Рис. 14.3. Структура операции DIVS

Данная операция вычисляет знаковый бит остатка, выполняя операцию «ИСКЛЮЧАЮЩЕЕ ИЛИ» для знаковых разрядов делителя и делимого.

Регистр AY0 сдвигается на одну позицию таким образом, чтобы знаковый разряд переместился в позицию LSB. Вычисленный знаковый разряд сохраняется в бит AQ регистра состояния. При делении чисел без знака операция DIVS не применяется. В этом случае бит AQ устанавливается в 0. Он показывает, что остаток должен быть положительным.

Второй примитив деления — это команда DIVQ (деление-частное), которая выполняется многократно и генерирует по одному биту частного после очередного выполнения. При простой точности деления чисел без знака команда DIVQ выполняется 16 раз, для такой же точности деления чисел со знаком операция выполняется 15 раз после вычисления знакового разряда с помощью команды DIVS. Операция DIVQ проиллюстрирована на рис. 14.4. DIVQ сдвигает регистр AY0 влево на один разряд так, чтобы новый бит частного оказался в позиции младшего разряда (LSB). Состояние бита AQ, которое генерируется предыдущей операцией, определяет операцию ALU для вычисления частичного результата. Если AQ=1, то ALU добавляет делитель к частичному результату в AF. Если AQ=0, то ALU вычитает делитель из частичного результата в AF. Так же как и в операции DIVS, ALU выводит результат в регистр AF. Формат результата при любом числовом представлении определяется форматом делителя и делимого.

Рис. 14.4. Операция DIVQ

Пусть NL — число разрядов влево и NR — число разрядов вправо от двоичной точки делимого, DL и DR — соответственно то же самое, только для делителя. Тогда частное состоит из NL-DL+1 битов слева от двоичной точки и содержит NR-DR-1 битов справа. Ниже показан пример формата чисел при выполнении операции деления.

Делимое: XXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXX

NL=5 бит NR=27 бит

Делитель: XX.XXXXXXXXXXXXXX

DL=2 бит DR=14 бит

Частное: XXXX.XXXXXXXXXXXX

(NL-DL+1)=4 бит (NR-DR-1)=12 бит

Иногда необходимо некоторое изменение формата делимого и делителя. Например, если оба операнда знаковые и дробные (делимое в формате 1.31, а делитель в формате 1.15), то результат запишется в формате 1.15. Таким образом, для получения правильного результата операции деления необходимо, чтобы делимое было меньше делителя.

Чтобы разделить два целых числа (делимое в формате 32, а делитель в формате 16), необходимо перед делением привести делимое к формату 31, т.е. сдвинуть его влево на один разряд. Если результат не может быть представлен в формате частного, как сказано выше, или когда делитель равен нулю или меньше делимого по абсолютному значению, происходит переполнение.

При реализации алгоритма деления для знаковых операндов делитель должен храниться в AX0 и AX1 или в любом регистре с шины R. Старшее слово делимого может быть загружено в AY1 или AF, и младшее слово делимого загружается в AY0. Чтобы вычислить частное, сначала выполняется команда DIVS, которая вычисляет знак частного, за которой следуют 15 команд DIVQ, для вычисления 15 бит частного. Пример подпрограммы знакового деления с фиксированной точкой показан ниже. Эта подпрограмма берет делитель из регистра AX0, старшее слово делимого из AF и младшее слово делимого из AY0. Частное возвращается в AY0.

.MODULE Sig_Div_FP; {

Входные данные:

AF = старшее слово делимого

AY0 = младшее слово делимого

AX0 = 16-битный делитель

Выходные данные:

AY0 = 16-битный результат

Изменяемые регистры:

AY0, AF

Время вычисления=17 циклов

}

.ENTRY sdivfp;

sdivfp: DIVS AF, AX0; {Вычисление знакового бита}

DIVQ AX0; DIVQ AX0; DIVQ AX0; {Вычисление 15 бит частного}

DIVQ AX0; DIVQ AX0; DIVQ AX0;

DIVQ AX0; DIVQ AX0; DIVQ AX0;

DIVQ AX0; DIVQ AX0; DIVQ AX0;

DIVQ AX0; DIVQ AX0; DIVQ AX0;

RTS;

.ENDMOD;

Ниже приводится полный список команд ALU в соответствии с принятыми ранее условными сокращениями. Назначение команд очевидно из их записи и комментариев для некоторых из команд. Команды сложения и сложения с переносом:

[IF cond] |AR| = xop + |yop     |;

|AF|         |C       |

|yop + C |

|constant|

Команды вычитания и вычитания с займом:

[IF cond] |AR| = xop - |yop     |;

|AF|         |yop+С-1 |

|constant|

[IF cond] |AR| = yop - |xop     |;

|AF|         |xop+C-1 |

|constant|

Команды логических операций И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ:

[IF cond] |AR| = xop |AND| yop;

|AF|       |OR |

|XOR|

Команды передачи:

[IF cond] |AR| = PASS|xop     |;

|AF|       |yop     |

|constant|

Команды смены знака:

[IF cond] |AR| = - |xop|;

|AF|     |yop|

Команды логического отрицания HE:

[IF cond] |AR| = NOT |xop|;

|AF|       |yop|

|0  |

Команды вычисления абсолютного значения:

[IF cond] |AR| = ABS |xop|;

|AF|

Команды инкремента:

[IF cond] |AR| = |yop+1|;

|AF|

Команды декремента:

[IF cond] |AR| = |yop-1|;

|AF|

Команды битовых операций:

[IF cond] |AR| = |TSTBIT n xop|; {операция логического «И» разряда n с 1}

|SETBIT n xop|; {операция установки разряда n в 1}

|CLBIT  n xop|; {операция установки разряда n в 0}

|TGBIT  n xop|; {операция «ИСКЛЮЧАЮЩЕЕ ИЛИ» бита n с 1}

Здесь n могут принимать значения от 0 до 15

Команды поразрядного деления:

[IF cond] |AR| = DIVS yop, xop;

[IF cond] |AR| = DIVQ xop;

Команды тестирования результата:

NONE = <ALU>;

Последняя команда выполняет заданную команду АЛУ, устанавливает флаги и сбрасывает значение результата. Она позволяет тестировать значения в регистрах без изменения содержимого AR или AF. Строка <ALU> — это любая безусловная команда АЛУ, кроме DIVS, DIVQ и дополнительных команд АЛУ с константами.

Для всех приведенных выше команд ALU разрешено использовать следующие операнды:

xop: AX0, АХ1, AR, MR0, MR1, MR2, SR0, SR1; yop: AY0, AY1, AF;

constant: 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32767, -2, -3, -5, -9, -17, -33, -65, -129, -257, -513, -1025, -2049, -4097, -8193, -16385, -32768.

Команда DIVS не может использовать регистр AY0 как оператор yop. Коды условия IF соответствуют кодам, приведенным ранее в табличном виде.

Примеры записи команд:

AR=AX0+AY0+C; /* Присвоить регистру AR значение суммы регистров AX0, AY0

и переноса*/

IF EQ AR=AX0+AY0+C; /* Выполнение описанной выше операции при условии

равенства нулю предыдущего результата */

AF=TSTBIT 7 AX; /* Занести в регистр AF значение результата операции

логического «И» разряда 7 с единицей */

Глава 15. Устройство MAC

В этой главе говорится о вычислительном устройстве MAC (умножителя с накопителем) сигнального процессора и выполняемых в нем командах.

Структура устройства MAC

Свое название устройство MAC получило от сокращения английских слов: multiplier (умножитель) и accumulator (накопитель). Устройство MAC выполняет быстрые одноцикловые операции умножения, умножения с добавлением, умножения с вычитанием, функции насыщения и очистку результата. Функция обратной связи позволяет части результата в одном цикле быть одним из сомножителей в следующем цикле.

Операции в MAC производятся над числами, представленными в виде двоичных последовательностей. Результат выдается в том же виде.

Процессор ADSP-2181 поддерживает два режима корректировки формата: дробный режим для дробных операндов формата 1.15 и целочисленный режим для целых чисел формата 16.0.

Когда процессор умножает два операнда в формате 1.15, в результате получается число в формате 2.30 (два знаковых и 30 дробных разрядов).

В дробном режиме MAC автоматически сдвигает результат на один бит влево перед пересылкой его в регистр результата MR. Этим сдвигом результат приводится к виду 1.31, который может быть округлен до формата 1.15.

В целочисленном режиме сдвига влево не происходит. Например, при умножении операндов в формате 16.0 результат представляется в виде 32.0.

Сдвиг влево в этом случае не нужен, т.к. он изменит числовое представление результата. В табл. 15.1 показаны форматы данных операндов и результата для вычислительных устройств процессора ADSP-2181.

Таблица 15.1 Форматы данных операндов и результата для вычислительных устройств процессора ADSP-2181

Операции

Арифметические форматы

Операнды

Результат

Устройство ALU

Сложение

Знаковые числа или без знака

Установка флагов

Вычитание

Знаковые числа или без знака

Установка флагов

Логические операции

Двоичные строки

Тот же, что и операнды

Деление

Знаковые числа или без знака

Тот же, что и операнды

Переполнение ALU

Знаковые числа

Тот же, что и операнды

Бит коррекции ALU

16-разрядные числа без знака

Тот же, что и операнды

Насыщение ALU

Знаковые числа

Тот же, что и операнды

Устройство MAC (дробные числа)

Умножение (P)

1.15 знаковые числа /без знака

32 разряда (2.30)

Умножение (MR)

1.15 знаковые числа /без знака

2.30, сдвинутый к 1.31

Умножение с накоплением

1.15 знаковые числа /без знака

2.30, сдвинутый к 1.31

Умножение с вычитанием

1.15 знаковые числа /без знака

2.30, сдвинутый к 1.31

Насыщение MAC

Знаковые числа

Тот же, что и операнды

Устройство MAC (целые числа)

Умножение (P)

1.15 знаковые числа /без знака

32 разряда (32.0)

Умножение (MR)

16.0 знаковые числа /без знака

32.0 без сдвига

Умножение с накоплением

16.0 знаковые числа /без знака

32.0 без сдвига

Умножение с вычитанием

16.0 знаковые числа /без знака

32.0 без сдвига

Насыщение MAC

Знаковые числа

Тот же, что и операнды

Устройство сдвига Shifter

Логические сдвиги

Баз знака/двоичные строки

Тот же, что и операнды

Арифметические сдвиги

Знаковые числа

Тот же, что и операнды

Определение порядка

Знаковые числа

Тот же, что и операнды

Структура MAC

Рассмотрим подробнее содержимое устройства MAC. Его структурная схема приведена на рис. 15.1.

Рис. 15.1. Структурная схема MAC

MAC имеет два входных 16-разрядных порта X и Y и один 32-разрядный порт вывода результата P. 32-разрядный результат поступает в 40-разрядный блок сложения/вычитания, который либо прибавляет, либо вычитает текущий результат из регистра результата MR, либо передает текущий результат непосредственно в MR. Регистр MR имеет 40 разрядов. Фактически регистр MR состоит из трех регистров. Два из них, MR0 и MR1, являются 16-разрядными, а регистр MR2 8-разрядный. Мультиплексоры MUX позволяют коммутировать внутри устройства один из нескольких операндов.

Блок сложения/вычитания имеет более 32 разрядов для того, чтобы учесть промежуточные переполнения в ряде операций умножения с накоплением. Флаг MV (переполнение) устанавливается в единицу, если значение аккумулятора превышает 32 разряда.

Регистры ввода-вывода подобны регистрам ALU. Порт X может принимать данные из регистра MX или из любого другого регистра на R-шине результата. R-шина соединяет выходные регистры всех вычислительных модулей для непосредственного использования результатов вычислений в качестве входных операндов. Регистр MX состоит из двух регистров (MX0 и MX1).

Эти регистры читаются и записываются с DMD-шины. Организованы регистры MX0 и MX1 таким образом, что один из них поставляет множитель в блок умножения, а другой управляет DMD-шиной.

Порт Y принимает данные из регистра MY или регистра обратной связи MF. Регистр MY также разбит на два регистра (MY0 и MY1), доступ к которым осуществляется с DMD-шины и возможна запись с PMD-шины. Система команд предусматривает чтение этих регистров с помощью PMD-шины, но прямого доступа для этой операции нет, в этом случае используется устройство DMD-PMD обмена. Выводы регистра MY устроены аналогично MX.

Результат умножения поступает либо в блок сложения/вычитания, либо в регистры MY или MF. Регистр обратной связи MF позволяет результату вычисления в предыдущем цикле становиться операндом умножения на входе Y, в последующей операции. 40-разрядный регистр MR разделен на три регистра (MR0, MR1, MR2). Содержимое любого из них может быть выведено на DMD-шину или R-шину и записано с DMD-шины.

Любой из регистров MAC может быть прочитан и записан в одном цикле. Чтение данных происходит в начале цикла, а запись - в конце цикла. Прочитанное содержимое регистра в начале одного цикла записывается в конце предыдущего, следовательно, новое значение регистра может быть прочитано только в течение следующего цикла. Такой механизм позволяет входному порту предоставлять операнд для MAC в начале цикла и оперировать со следующим значением из памяти в конце того же цикла. Это относится и к выходному регистру.

Регистры MR, MF, MX, MY продублированы в теневых банках. Одновременно процессору может быть доступен лишь один из банков. Теневой банк регистров может быть активизирован для чрезвычайно быстрого контекстного переключения. Таким образом, новая задача, типа подпрограммы обработки прерывания, может выполняться без сохранения текущих данных в памяти, благодаря использованию теневых банков. Выбор первичного или теневого банка регистров определяется установкой нулевого разряда в регистре MSTAT состояний процессора. Если этот разряд установлен в 0, то выбран первичный банк.

Операции MAC

Теперь рассмотрим операции вычислительного устройства MAC, входные форматы данных, обработку переполнения и насыщения.

Набор стандартных операций MAC приведен в табл. 15.2.

Таблица 15.2 Набор стандартных операций MAC

Операция

Назначение

X*Y

Умножение X на Y

MR+X*Y

Умножение X на Y и сложение с MR

MR-X*Y

Умножение X на Y и вычитание из MR

0

Очистка MR

Как было сказано выше, сигнальный процессор ADSP-2181 обеспечивает два режима работы операций умножения с накоплением. Первый из них — режим работы с дробными числами в формате 1.15. Второй — режим работы с целыми числами в формате 16.0.

В дробном режиме выходной регистр P корректирует формат, т.е. прежде чем добавить значение в MR, оно сдвигается на один разряд влево. Таким образом, бит 31 регистра P запишется в 32-й разряд регистра MR, а 0-й разряд — в первый. В позицию младшего разряда (LSB) при этом записывается ноль. На рис. 15.2 показан дробный формат работы модуля умножения.

Рис. 15.2. Дробный формат работы модуля умножения

В целочисленном формате (рис. 15.3) регистр P не сдвигается, прежде чем прибавиться к MR.

Рис. 15.3. Целочисленный формат

Выбор режима осуществляется установкой 4-го разряда регистра MSTAT процессора. Если этот разряд установлен в 1, то выбран целочисленный режим. В любом формате блок умножения формирует 32-разрядный результат и передает его в блок сложения/вычитания, где получается конечное значение операции, которое записывается в MR.

Регистры ввода-вывода MAC

В операциях MAC обрабатываются данные, которые поступают на порты X и Y, а результат операций выводится на шину R. Ниже приведен перечень регистров, доступных для этих портов.

Регистры для входного порта X — MX0, МХ1, AR, MR0, MR1, MR2, SR0, SR1.

Регистры для входного порта Y — MY0, MY1, MF.

Регистры для выходного порта R — MR (MR0, MR1, MR2), MF.

Входные форматы данных

Для облегчения умножения входные операнды могут находиться в любых форматах. Входные форматы определяются как часть команды и выбираются динамически при обращении к блоку умножения.

Формат: «знаковый * знаковый» — используется при умножении двух знаковых чисел простой точности или двух старших частей знаковых чисел двойной точности.

Формат: «без знака * знаковый» или «знаковый * без знака» — используется при умножении верхней части знакового числа на нижнюю часть другого или для умножения знакового числа простой точности с числом той же точности без знака.

Формат: «без знака * без знака» — используется при умножении чисел простой точности без знака или нижних частей знаковых чисел двойной точности.

Операции над регистром MR

Как показано на рис. 15.1, регистр MR разбит на три регистра: MR0 (биты 0-15), MR1 (биты 16-31) и MR2 (биты 32-39). Каждый из этих регистров может быть загружен с DMD-шины и выведен на R-шину или DMD-шину. Регистр MR2 связан с младшими восемью разрядами этих шин. Во время передачи данных MR2 на R-шину или DMD-шину происходит добавление 8 знаковых разрядов для расширения числа до 16 разрядов. Кроме того, при загрузке данных с DMD-шины в регистр MR1 регистр MR2 служит как добавление регистра MR1, и заполняется значением старшего знакового разряда MR1. Для того чтобы загрузить в регистр MR2 данные, отличные от знакового разряда MR1, необходимо загружать MR2 после загрузки MR1. Загрузка регистра MR0 не влияет на регистры MR0 и MR1.

Насыщение и переполнение MAC

После каждой операции блок сложения/вычитания генерирует сигнал переполнения MV, который подключен к регистру состояния арифметики процессора ASTAT. Бит MV устанавливается в единицу, если результат сложения выходит за границы регистров MR1/MR2 — 32 бита, т.е. если все девять старших разрядов регистра MR одновременно не нули или не единицы.

Регистр MR имеет возможность насыщения в определенном положительном или отрицательном значении, если происходит переполнение. Насыщение зависит от состояния бита MV регистра состояний арифметики ASTAT и бита MSB регистра MR2. Операцию насыщения описывает табл. 15.3.

Таблица 15.3 Описание операции насыщения

Флаг MV

Старший разряд MR2

Содержимое регистра MR после операции

0

0 или 1

Без изменений

1

0

00000000 0111111111111111 1111111111111111 (положительное)

1

1

11111111 1000000000000000 0000000000000000 (отрицательное)

Насыщение в MAC является скорее командой, чем режимом, как в ALU. Она используется при завершении последовательности умножений с накоплением, таким образом, чтобы промежуточные переполнения не привели сумматор к насыщению.

Переполнение больше старшего разряда MSB недопустимо. В обратном случае знаковый разряд будет потерян, и насыщение не будет правильным. Однако, чтобы достигнуть этого состояния, требуется 255 циклов переполнения.

Округление

В сумматоре MAC можно округлять 40-разрядный результат на границе между 15-м и 16-м разрядами. Округление относится к системе команд процессора. Округленный результат направляется либо в регистр MR, либо в регистр обратной связи MF. Когда для вывода используется MF, в него записывается 16-разрядный округленный результат. Аналогично, если для вывода выбран MR, то в MR1 записываются 16 разрядов округленного результата, а в регистр MR2 результат округления, таким образом, получается 24-разрядный округленный результат.

Сумматор производит процедуру округления без смещения. Стандартный метод смещенного округления состоит в записи единицы в 15-й разряд. Этот метод вызывает положительное смещение, так как срединное значение числа, когда MR=0x8000 округляется в сторону увеличения. Сумматор устраняет это смещение, принудительно устанавливая шестнадцатый разряд в ноль, когда значение регистра MR достигает середины. При этом четные значения MR1 округляются в сторону уменьшения, а нечетные в сторону увеличения. Таким образом достигается нулевое смещение при выборе множества равномерно распределенных значений. Для наглядности сказанного выше, в табл. 15.4 приведено два примера операций округления результата.

Таблица 15.4 Примеры операций округления результата

Операнды и операции

Регистры

MR2

MR1

MR0

Пример 1

Неокругленное значение, где 15-й разряд равен 1

xxxxxxxx

xxxxxxxx 00100101

1xxxxxxxxxxxxxxx

Прибавление 1 к 15-му разряду и учет переноса

100000000 0000000

Округленное значение

xxxxxxxx

хххххххх 00100110

0xxxxxxxxxxxxxxx

Пример 2

Неокругленное значение, где 15-й разряд равен 1, а разряды с 0-го по 14-й равны нулю

xxxxxxxx

хххххххх 00100110

100000000 0000000

Прибавление 1 к 15-му разряду и учет переноса

100000000 0000000

Неокругленное значение, где бит 16 равен 1

xxxxxxxx

хххххххх 00100111

00000000 00000000

Установка 16-го разряда в ноль и получение округленного значения

xxxxxxxx

хххххххх 00100110

00000000 00000000

x — произвольное значение (0 или 1).

В первом примере число не является срединным и производится его стандартное округление.

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

Смещенное округление

В процессорах ADSP-2181 возможен режим смещенного округления. Этот режим выбирается путем установки 12-го бита (BIARND) регистра управления SPORT0. Если BIARND=0, то используется операция несмещенного округления, если BIARND=1, то смещенного. Примеры таких операций приведены в табл. 15.5.

Таблица 15.5 Примеры операций округления

Значение регистра MR до округления

Результат округления со смещением

Результат округления без смещения

00-0000-8000

00-0001-8000

00-0000-8000

00-0001-8000

00-0002-8000

00-0002-8000

00-0000-8001

00-0001-8001

00-0001-8001

00-0001-8001

00-0002-8001

00-0002-8001

00-0000-7FFF

00-0000-7FFF

00-0000-7FFF

00-0001-7FFF

00-0001-7FFF

00-0001-7FFF

Этот режим действует только в том случае, когда значение регистра MR0 больше 0x8000. Во всех других случаях работают обычные операции округления. Этот режим позволяет более эффективно реализовывать алгоритмы, использующие смещенное округление, например подпрограммы речевого сжатия GSM.

Полный список команд

Ниже приводится полный список команд устройства умножителя-накопителя MAC, также в соответствии с принятыми ранее условными сокращениями. Назначение команд приводится в тексте описания этих команд и комментариях для некоторых из команд.

Команды умножения:

[IF cond] |MR| = xop * |yop| |(SS) |;

|MF|         |xop| |(SU) |

|(US) |

|(UU) |

|(RND)|

Здесь присутствуют новые символы, которые имеют следующее назначение:

S — входной операнд xop или yop знаковый;

U — входной операнд xop или yop беззнаковый;

RND — выходное значение округляется.

Например, команда:

MR=MX0*MY0(SU);

означает, что в регистр MR будет занесен результат умножения знакового значения из регистра MX0 на беззнаковое значение из регистра MY0.

Команда:

MR=SR1 *MY0(RND);

означает, что в регистр MR будет занесен результат умножения значения из регистра SR1 на значение из регистра MY0 и результат вычисления будет округлен.

Команды умножения с накоплением:

[IF cond] |MR| = MR + xop * |yop| |(SS) |;

|MF|              |xop| |(SU) |

|(US) |

|(UU) |

|(RND)|

Пример:

MR=MR+MX0*MY0 (SS);

Здесь в регистр MR будет занесен результат сложения предыдущего значения регистра MR с результатом умножения знакового значения из регистра MX0 на знаковое значение из регистра MY0.

Команды умножения с вычитанием:

[IF cond] |MR| = MR - xop * |yop| |(SS) |;

|MF|              |xop| |(SU) |

|(US) |

|(UU) |

|(RND)|

Команды пересылки MR:

[IF cond] |MR| = MR |(RND)|;

|MF|

Фактически эти команды осуществляют пересылку содержимого регистра MR в регистр MR или в регистр MF с округлением значения.

Команды очистки:

[IF cond] |MR| = 0;

|MF|

Команда условного насыщения регистра MR:

IF MV SAT MR;

Здесь MV — код условия переполнения умножителя.

Для всех команд MAC разрешено использовать следующие операнды:

xop: MX0, МХ1, AR, MR0, MR1, MR2, SR0, SR1;

yop: MY0, MY1, MF;

Коды условия IF соответствуют кодам, приведенным ранее в табличном виде.

Примеры записи команд:

MR=MR+MX0*MY0(SS); /* Присвоить регистру MR значение суммы регистров MR и

произведения MX0 на MY0, где оба операнда произведения знаковые*/

MF=AR*MY0(RND) /* Присвоить регистру MF значение произведения регистра AR на

MY0, с округлением результата*/

MF=AR*MY0(RND), MY1=DM(I3,M3); /* Мультипроцессорная команда вычисления

произведения и одновременной пересылки данных из памяти в регистр*/

MF=MR(RND); /* Осуществить пересылку содержимого регистра MR в регистр MF с

округлением значения */

IF EQ MR=0; /* Очистить регистр MR, если предыдущий результат равен нулю */

Глава 16. Устройство сдвига

В этой главе говорится об устройстве сдвига сигнального процессора и выполняемых с его помощью командах.

Устройство сдвига именуется как Shifter и обеспечивает полный набор сдвиговых функций для 16-разрядных операндов, результатом которых является 32-разрядное слово данных. К числу сдвиговых функций относятся арифметические сдвиги, логические сдвиги и нормализация. Кроме того, shifter позволяет вычислить порядок (экспоненту) числа и порядок для целого массива (блока) чисел. Эти базовые функции могут быть объединены для быстрого преобразования любого формата чисел, в том числе и чисел с плавающей точкой.

Структура устройства сдвига

На рис. 16.1 представлена структурная схема устройства сдвига. Shifter включает в себя следующие основные блоки: массив сдвига, логику OR/PASS (ИЛИ/ПЕРЕДАЧА), детектор порядка и логику сравнения порядка.

Рис. 16.1. Структурная схема устройства сдвига

Массив сдвига состоит из шестнадцати 32-разрядных регистров. Он принимает 16-разрядные данные и в одном цикле может поместить их в любой позиции 32-разрядного поля вывода, начиная с данных, полностью сдвинутых влево, и кончая данными, полностью сдвинутыми вправо, за один цикл. Это дает 49 вариантов возможных размещений 16-разрядных входных данных в 32- разрядном поле вывода, как показано в табл. 16.1.

Таблица 16.1 Варианты возможных размещений 16-разрядных входных данных в 32-разрядном поле вывода

N

Разряды

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

1

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

2

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

15

3

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

15

14

…

17

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

18

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

X

…

33

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

34

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

…

47

1

0

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

48

0

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

49

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

X

Z

X

X

X

Размещение 16 входных разрядов определяется кодом управления «С» и сигналом ссылки HI/LO. Код управления «С» является 8-битным значением, которое указывает направление сдвига и число разрядов, на которое необходимо будет сдвинуть данные.

Положительные значения кода управления указывают на сдвиг данных влево, а отрицательные на сдвиг вправо. Код управления может быть взят из регистра экспоненты SE или непосредственно из инструкции команды. Сигнал ссылки HI/LO определяет начальную точку сдвига. В состоянии HI все сдвиги производятся относительно регистра SR1 (старшей половины выходных данных), а в состоянии LO все сдвиги производятся относительно регистра SR0 (младшей половины выходных данных). В табл. 16.2 показаны все возможные комбинации сдвигов данных для сигналов ссылки LO и HI.

Таблица 16.2 Возможные комбинации сдвигов данных для сигналов ссылки L0 и HI

Управляющий код для сигнала сдвига

Выходное значение массива сдвига

HI

LO

+16…+127

+32…+127

00000000

00000000

00000000

00000000

+15

+31

R0000000

00000000

00000000

00000000

+14

+30

PR000000

00000000

00000000

00000000

+13

+29

NPR00000

00000000

00000000

00000000

+12

+28

MNPR0000

00000000

00000000

00000000

+11

+27

LMNPR000

00000000

00000000

00000000

+10

+26

KLMNPR00

00000000

00000000

00000000

+9

+25

JKLMNPR0

00000000

00000000

00000000

+8

+24

IJKLMNPR

00000000

00000000

00000000

+7

+23

HIJKLMNP

R0000000

00000000

00000000

+6

+22

GHIJKLMN

PR000000

00000000

00000000

+5

+21

FGHIJKLM

NPR00000

00000000

00000000

+4

+20

EFGHIJKL

MNPR0000

00000000

00000000

+3

+19

DEFGHIJK

LMNPR000

00000000

00000000

+2

+18

CDEFGHIJ

KLMNPR00

00000000

00000000

+1

+17

BCDEFGHI

GKLMNPR0

00000000

00000000

0

+16

ABCDEFGH

IJKLMNPR

00000000

00000000

-1

+15

XABCDEFG

HIJKLMNP

R0000000

00000000

-2

+14

XXABCDEF

GHIJKLMN

PR000000

00000000

-3

+13

XXXABCDE

FGHIJKLM

NPR00000

00000000

-4

+12

XXXXABCD

EFGHIJKL

MNPR0000

00000000

-5

+11

ХХХХХАВС

DEFGHIJK

LMNPR000

00000000

-6

+10

ХХХХХХАВ

CDEFGHIJ

KLMNPR00

00000000

-7

+9

XXXXXXXA

BCDEFGHI

JKLMNPR0

00000000

-8

+8

XXXXXXXX

ABCDEFGH

IJKLMNPR

00000000

-9

+7

XXXXXXXX

XABCDEFG

HIJKLMNP

R0000000

-10

+6

XXXXXXXX

XXABCDEF

GHIJKLMN

PR000000

-11

+5

XXXXXXXX

XXXABCDE

FGHIJKLM

NPR00000

-12

+4

XXXXXXXX

XXXXABCD

EFGHIJKL

MNPR0000

-13

+3

XXXXXXXX

ХХХХХАВС

DEFGHIJK

LMNPR000

-14

+2

XXXXXXXX

ХХХХХХАВ

CDEFGHIJ

KLMNPR00

-15

+1

XXXXXXXX

ХХХХХХХА

BCDEFGHI

JKLMNPR0

-16

0

XXXXXXXX

ХХХХХХХХ

ABCDEFGH

IJKLMNPR

-17

-1

XXXXXXXX

ХХХХХХХХ

XABCDEFG

HIJKLMNP

-18

-2

XXXXXXXX

ХХХХХХХХ

XXABCDEF

GHIJKLMN

-19

-3

XXXXXXXX

ХХХХХХХХ

XXXABCDE

FGHIJKLM

-20

-4

XXXXXXXX

ХХХХХХХХ

XXXXABCD

EFGHIJKL

-21

-5

XXXXXXXX

ХХХХХХХХ

ХХХХХАВС

DEFGHIJK

-22

-6

XXXXXXXX

ХХХХХХХХ

ХХХХХХАВ

CDEFGHIJ

-23

-7

XXXXXXXX

ХХХХХХХХ

XXXXXXXA

BCDEFGHI

-24

-8

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

ABCDEFGH

-25

-9

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

XABCDEFG

-26

-10

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

XXABCDEF

-27

-11

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

XXXABCDE

-28

-12

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

XXXXABCD

-29

-13

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

ХХХХХАВС

-30

-14

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

ХХХХХХАВ

-31

-15

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

ХХХХХХХА

-32…-128

-16…-128

XXXXXXXX

ХХХХХХХХ

XXXXXXXX

ХХХХХХХХ

Массив сдвига и связанная с ним логика OR/PASS находятся в окружении набора регистров. Входной регистр SI (Shifter Input) содержит данные для массива сдвига и детектора порядка. Разрядность регистра SI составляет 16 бит.

Этот регистр записывается с DMD-шины. В качестве входных регистров для массива сдвига и детектора порядка могут служить регистры AR, SR или MR, подключенные через R-шину. Выходной 32-разрядный регистр SR (Shifter Result) разделен на два 16- разрядных регистра SR0 и SR1. Загрузка данных в эти регистры может производиться с DMD-шины, а результат выводится на R-шину или DMD-шину. Регистр SR подключен к блоку OR/PASS логики для проведения сдвигов двойной точности.

Регистр SE (Shifter Exponent) состоит из 8 разрядов и содержит порядок во время нормализации и денормализации данных. Он доступен через 8 младших разрядов DMD-шины. Его формат 8.0 в дополнительном коде.

Регистр SB (Shifter Block) используется в блочных операциях для чисел с плавающей точкой. Его значение определяет сдвиг для нормализации чисел в блоке данных, т.е. значение, на которое должен произойти сдвиг для нормализации самого большого числа в блоке данных. Разрядность регистра SB составляет 5 бит. Он доступен через 5 младших разрядов DMD-шины. Его формат 5.0 в дополнительном коде.

При чтении регистров SE и SB на DMD-шину числа автоматически дополняются знаковыми битами до 16-разрядного значения. Любой из регистров SI, SE, SR может быть прочитан или записан в одном и том же цикле.

Shifter также имеет банк теневых регистров SI, SE, SR и SB. Выбор банка регистров производится установкой нулевого бита регистра режима MSTAT процессора.

Устройство сдвига заполняет все биты 32-разрядного результата правее сдвига нулями, а левее сдвига битом расширения. Бит расширения может принимать значение знакового бита, бита флага АС из регистра ASTAT или нулевое значение, в зависимости от выполняемой инструкции.

Логика OR/PASS позволяет правильно комбинировать сдвинутые секции числа с двойной точностью. При выборе инструкции PASS результат массива сдвигов загружается в регистр SR без изменения. При выборе инструкции OR результат массива сдвигов подвергается операции «ЛОГИЧЕСКОЕ ИЛИ» с предыдущим значением регистра SR и после этого вновь помещается в SR.

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

В режиме HI входной операнд воспринимается как число с одинарной точностью или как старшая половина числа с двойной точностью. Детектор степени определяет количество знаковых разрядов и формирует код, который будет служить для сдвига данных влево так, чтобы оставить в данных только один знаковый разряд.

В режиме HIX входной операнд воспринимается как результат сложения или вычитания, выполненного в ALU, когда могло произойти переполнение. Поэтому детектор степени берет в учет значение флага AV регистра ASTAT. Если он установлен, формируется дополнительный бит для нормирования данных. Если флаг сброшен, отличий между режимами HI и HIX нет. В режимах HI и HIX детектор степени формирует бит знака SS (Shifter Sing), который помещается в регистр ASTAT устройства ALU. Он соответствует старшему разряду входного операнда, за исключением тех случаев, когда установлен флаг AV в режиме HIX. В этом случае формируется отрицание старшего разряда входного операнда, для сохранения знака переполненного значения.

В режиме LO входной операнд интерпретируется как младшая половина числа с двойной точностью. В этом режиме детектор степени интерпретирует бит SS как знак числа. Регистр SE загружается результатом детектора порядка только в том случае, если регистр SE равен минус 15. Это происходит в тех случаях, когда старшая часть числа содержит лишь знаковые разряды. При этом выходное значение детектора порядка сдвигается на 16 разрядов влево, для того чтобы определить, что операнд является младшей половиной 32-разрядного числа.

Для наглядности, в табл. 16.3–16.5 показаны все три режима работы детектора порядка. В таблицах приняты следующие условные обозначения: S — знаковый бит, N — знаковый бит, D — незначащий бит.

Таблица 16.3 Детектор порядка в режиме работы HI

Старший байт

Младший байт

Степень

SNDDDDDD

DDDDDDDD

0

SSNDDDDD

DDDDDDDD

-1

SSSNDDDD

DDDDDDDD

-2

SSSSNDDD

DDDDDDDD

-3

SSSSSNDD

DDDDDDDD

-4

SSSSSSND

DDDDDDDD

-5

SSSSSSSN

DDDDDDDD

-6

SSSSSSSS

NDDDDDDD

-7

SSSSSSSS

SNDDDDDD

-8

SSSSSSSS

SSNDDDDD

-9

SSSSSSSS

SSSNDDDD

-10

SSSSSSSS

SSSSNDDD

-11

SSSSSSSS

SSSSSNDD

-12

SSSSSSSS

SSSSSSND

-13

SSSSSSSS

SSSSSSSN

-14

SSSSSSSS

SSSSSSSS

-15

Таблица 16.4 Детектор порядка в режиме работы HIX

Флаг AV

Старший байт

Младший байт

Степень

1

DDDDDDDD

DDDDDDDD

+1

0

SNDDDDDD

DDDDDDDD

0

0

SSNDDDDD

DDDDDDDD

-1

0

SSSNDDDD

DDDDDDDD

-2

0

SSSSNDDD

DDDDDDDD

-3

0

SSSSSNDD

DDDDDDDD

-4

0

SSSSSSND

DDDDDDDD

-5

0

SSSSSSSN

DDDDDDDD

-6

0

SSSSSSSS

NDDDDDDD

-7

0

SSSSSSSS

SNDDDDDD

-8

0

SSSSSSSS

SSNDDDDD

-9

0

SSSSSSSS

SSSNDDDD

-10

0

SSSSSSSS

SSSSNDDD

-11

0

SSSSSSSS

SSSSSNDD

-12

0

SSSSSSSS

SSSSSSND

-13

0

SSSSSSSS

SSSSSSSN

-14

0

SSSSSSSS

SSSSSSSS

-15

Таблица 16.5 Детектор порядка в режиме работы LO

Флаг SS

Старший байт

Младший байт

Степень

S

DDDDDDDD

DDDDDDDD

-15

S

SNDDDDDD

DDDDDDDD

-16

S

SSNDDDDD

DDDDDDDD

-17

S

SSSNDDDD

DDDDDDDD

-18

S

SSSSNDDD

DDDDDDDD

-19

S

SSSSSNDD

DDDDDDDD

-20

S

SSSSSSND

DDDDDDDD

-21

S

SSSSSSSN

DDDDDDDD

-22

S

SSSSSSSS

NDDDDDDD

-23

S

SSSSSSSS

SNDDDDDD

-24

S

SSSSSSSS

SSNDDDDD

-25

S

SSSSSSSS

SSSNDDDD

-26

S

SSSSSSSS

SSSSNDDD

-27

S

SSSSSSSS

SSSSSNDD

-28

S

SSSSSSSS

SSSSSSND

-29

S

SSSSSSSS

SSSSSSSN

-30

S

SSSSSSSS

SSSSSSSS

-31

Источниками входных данных в устройстве сдвига могут служить регистры SI, AR, MR0, MR1, MR2, SR0 и SR1. Результат работы устройства сдвига всегда помещается в регистр SR (SR0, SR1).

Команды устройства сдвига

Как было сказано выше, устройство сдвига выполняет следующие функции:

• Арифметический сдвиг (ASHIFT)

• Логический сдвиг (LSHIFT)

• Нормализация числа (NORM)

• Определение экспоненты (ЕХР)

• Блочное изменение экспоненты (EXPADJ)

Данные команды устройства сдвига применяются при выполнении арифметических операций над числами. С их помощью производится определение порядка блока, немедленные сдвиги, нормализация и денормализация чисел.

Ниже приводится полный список команд устройства сдвига Shifter в соответствии с принятыми ранее условными сокращениями. Назначение команд приводится в тексте описания этих команд и комментариях для некоторых из команд.

Команды арифметического сдвига:

[IF cond] SR = |SR OR| ASHIFT xop |(HI)|;

|(LO)|

Команды логического сдвига:

[IF cond] SR = |SR OR| LSHIFT xop |(HI)|;

|(LO)|

Команды нормализации:

[IF cond] SR = |SR OR| NORM xop |(HI)|;

|(LO)|

Команды выделения порядка:

[IF cond] SR = EXP xop |(HI) |;

|(LO) |

|(HIX)|

Команды выравнивания блочного порядка:

[IF cond] SR = EXPADJ xop;

Команды арифметического непосредственного сдвига:

[IF cond] SR = |SR OR| ASHIFT xop BY <exp> |(HI)|;

|(LO)|

Команды логического непосредственного сдвига:

[IF cond] SR = |SR OR| LSHIFT xop BY <exp> |(HI)|;

|(LO)|

В записях некоторых команд присутствуют символы, которые имеют следующее назначение:

HI — сдвиг выполняется относительно старших 16 разрядов (SR1);

LO — сдвиг выполняется относительно младших 16 разрядов (SR0);

HIX — расширенный режим HI (при выделении порядка учитывается бит переполнения AV).

Например, команда:

SE=EXP AR (HIX);

означает, что в регистр SE будет занесен результат выделения порядка из регистра AR в расширенном режиме, т.е. с учетом бита переполнения AV.

Команда:

SR=NORM AR (HI); {Нормализация}

означает, что в регистр SR будет занесен результат нормализации регистра AR, причем сдвиг при нормализации будет выполняться относительно старших 16 разрядов.

Для всех команд устройства сдвига разрешено использовать следующие операнды xop: SI, SR0, SR1, AR, MR0, MR1, MR2, а в качестве ЕХР может быть любое целое число от -128 до 127.

Коды условия IF соответствуют кодам, приведенным ранее в табличном виде.

Ниже приведен пример программы для вычисления разницы двух чисел в формате с плавающей точкой, с применением устройства сдвига.

.MODULE float_point_sub;

{

Программный модуль вычисления z = x - y в формате с плавающей точкой

Входные операнды:

AX0 = показатель x, АХ1 = мантисса x, AY0 = показатель y, AY1 = мантисса y.

Выходные данные: AR = показатель z, SR1 = мантисса z

Изменяются регистры: AX0,AY1,AY0,AF,AR,SI,SE,SR

Время вычисления = 11 циклов

}

.ENTRY fps;

fps : AF=AX0-AY0;   {Показатель x > показателя y?}

IF GT JUMP shifty;  {Если да - переход на сдвиг y}

SI=AX1, AR=PASS AF; {Иначе - сдвиг x}

SE=AR;

SR=ASHIFT SI (HI);

AR=SR1-AY1; {Вычисление мантиссы}

JUMP subt;

shifty: SI=AY1, AR=-AF; SE=AR;

SR=ASHIFT SI (HI);

AY1=SR1;

AY0=AX0, AR=AX1-AY1; {Вычисление мантиссы}

subt: SE=EXP AR (HIX);

AX0=SE, SR=NORM AR (HI); {Нормализация}

AR=AX0+AY0; {Вычисление показателя}

RTS;

.ENDMOD;

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

Глава 17. Устройство обмена между шинами

В этой главе говорится об устройстве обмена между шинами памяти программ PMD и памяти данных DMD.

В операциях обмена данными и при загрузке данных вычислительными устройствами процессора, часто используется устройство обмена между шиной памяти программ PMD и шиной памяти данных DMD. Это устройство позволяет передавать данные между упомянутыми выше шинами в обоих направлениях. Рассмотрим работу данного устройства. Его структурная схема приведена на рис. 17.1.

Рис. 17.1. Устройство обмена между шинами памяти программ PMD и памяти данных DMD

Как видно из рисунка, устройство состоит из нескольких буферов, мультиплексора и регистра PX. Регистр PX используется для временного хранения 8 разрядов данных. Он необходим для обеспечения корректной передачи данных между 16-разрядной шиной DMD и 24-разрядной шиной PMD. При этом старшие 16 разрядов 24-разрядной шины PMD передаются на 16 разрядов шины DMD непосредственно, а 8 младших разрядов записываются в регистр PX, а затем передаются на младшие 8 разрядов шины DMD.

Из структурной схемы устройства видно, что данные между шинами передаются двумя путями. Первый путь позволяет осуществлять прямую пересылку старших 16 разрядов данных между шинами через буферные регистры. Второй путь служит для пересылки младших 8 разрядов данных между шинами.

Рассмотрим механизм обмена данными с использованием регистра PX.

Когда данные считываются из памяти программ в любой регистр, происходит автоматическая загрузка регистра PX младшими 8 разрядами 24-разрядного слова. Например:

AX0 = PM(I7,M7);

При выполнении этой команды старшие 16 разрядов 24-разрядного слова памяти программы загружаются в регистр AX0, а младшие 8 разрядов автоматически загружаются в регистр PX.

При записи данных в память программ содержимое регистра PX автоматически считывается в младшие 8 разрядов памяти программ. Например:

PM(I7,M7) = AX0;

Здесь данные регистра AX0 записываются в старшие 16 разрядов 24-разрядного слова памяти программы, а 8 разрядов, хранящиеся в регистре PX от предыдущей команды, автоматически записываются в младшие 8 разрядов этого же слова. Таким образом, достигается автоматическая пересылка данных между 16- и 24-разрядными шинами.

Кроме того, существуют команды прямого доступа к регистру PX с шины памяти данных. При этом используются только младшие 8 разрядов шины данных, а старшие 8 разрядов данных отбрасываются или заполняются нулями. Например:

PX = AX0;

Эта команда передает в регистр PX 8 младших разрядов из регистра AX0 через шину данных. Восемь старших разрядов 16-разрядного слова при этом отбрасываются.

Следующая команда передает содержимое регистра PX в 8 младших разрядов регистра AX0. При этом старшие 8 разрядов регистра AX0 заполняются нулями.

AX0 = PX;

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

Ниже приведен модуль программы, предназначенной для пересылки 24-разрядных данных из одной области памяти программ в другую при помощи 16-разрядного регистра.

.MODULE copy_pdm;

{

Входные данные:

I4= адрес источника данных

L4 = длина буфера данных

I5= адрес приемника данных

Выходные данные:

Перемещенные данные

Изменяемые регистры:

AR, M4

}

.ENTRY COPY_PMDAT;

COPY_PMDAT:

M4=1;

CNTR = L4;

DO COPY_MEM UNTIL СЕ;

AR=PM(I4, M4);

PM(I5, M4)=AR;

COPY_MEM:

RTS;

.ENDMOD;

Обратите внимание, что в этой программе регистр PX не используется явным образом в командах, тем не менее, пересылка 24-разрядных данных через 16-разрядный регистр AR осуществляется корректно, благодаря автоматическому режиму работы устройства обмена данными с применением регистра PX.

Глава 18. Программный автомат

В этой главе говорится о программном автомате сигнального процессора и выполняемых с его помощью командах.

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

Рис. 18.1. Программный автомат сигнального процессора

Основным блоком программного автомата является программный счетчик (PC-program counter). Он представляет собой 14- разрядный регистр, в котором постоянно содержится адрес текущей выполняемой команды. Это значение инкрементируется (увеличивается на 1) каждый раз при выполнении очередной последовательной команды.

Стек программного счетчика служит для временного хранения адреса очередной команды при переходе на обработку подпрограммы, цикловой операции или прерывания. Он позволяет хранить до шестнадцати 14-разрядных слов. Таким образом, уровень вложенности подпрограмм не должен превышать 16.

Контроллер прерываний формирует адрес подпрограммы обработчика прерывания. Он использует данные регистров статуса и влияет на выбор источника следующего адреса.

Блоки счетчика циклов, стека счетчика, компаратора циклов и стека циклов позволяют организовать цикловые операции в программе, не привлекая для этого другие регистры процессора.

Логика выбора формирует сигнал для выбора источника следующего адреса команды.

Команды управления программой

Ниже приводится полный список команд, выполняемых программным автоматом в соответствии с принятыми ранее условными сокращениями. Назначение команд приводится в тексте описания этих команд и комментариях для некоторых из команд.

Выполнять цикл до определенного условия:

DO <addr> [UNTIL term];

Условный (безусловный) переход:

[IF cond] JUMP |(I4)  |;

|(I5)  |

|(I6)  |

|(I7)  |

|<addr>|

Вызов подпрограммы:

[IF cond] CALL |(I4)  |;

|(I5)  |

|(I6)  |

|(I7)  |

|<addr>|

Переход (вызов подпрограммы) по состоянию вывода флага Flag In:

[IF] |FLAG_IN        | |JUMP| <addr>;

|IF NOT FLAG_IN | |CALL|

Изменение состояния вывода флагов:

[IF cond] |SET    | |FLAG_OUT | [,...]; {установка флага}

|RESET  | |FL0      |         {сброс флага}

|TOGGLE | |FL1      |         {инверсия флага}

|FL2      |

Возврат из подпрограммы:

[IF cond] RTS;

Возврат из подпрограммы прерывания:

[IF cond] RTI;

Ожидание прерываний:

IDLE;

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

Допустимые значения <term> и <cond> приведены в табл. 18.1 и табл. 18.2 соответственно. Запись <addr> может быть меткой или числовым значением от 0 до 0x3FFF. Примеры команд управления программой:

CNTR=100; {Заполнить счетчик циклов}

DO Met1 UNTIL CE; {Выполнить цикл до метки Met1, пока счетчик циклов не пуст}

AX0 = DM(I0,M0); {Переслать данные через регистр AX0}

Met1: DM(I1 ,M1 )=AX0; {в новую область памяти}

JUMP(I4); {Осуществить переход по адресу в индексном регистре I4}

CALL (I6); {Вызвать подпрограмму по адресу в индексном регистре I6}

SET FLAG_OUT; {Установить в 1 вывод FLAG_OUT}

RESET FL2 {Сбросить флаг FL2}

TOGGLE FL0 {Инвертировать флаг FL0}

Met2: IDLE; {Режим ожидания прерывания}

JUMP Met2:

Таблица 18.1 Допустимые значения <term>

Значение <term>

Пояснение

CE

Счетчик циклов пуст

EQ

Равно нулю

NE

Не равно нулю

LT

Меньше нуля

GE

Больше или равно нулю

LE

Меньше или равно нулю

GT

Больше нуля

АС

Перенос АЛУ

NOT AC

Нет переноса АЛУ

AV

Переполнение АЛУ

NOT AV

Нет переполнения АЛУ

MV

Переполнение умножителя

NOT MV

Нет переполнения умножителя

NEG

Входной операнд «xop» отрицателен

POS

Входной операнд «xop» положителен

FOREVER

Бесконечный цикл

Таблица 18.2 Допустимые значения <cond>

Значение <cond>

Пояснение

EQ

Равно нулю

NE

He равно нулю

LT

Меньше нуля

GE

Больше или равно нулю

LE

Меньше или равно нулю

GT

Больше нуля

AC

Перенос АЛУ

NOT AC

Нет переноса АЛУ

AV

Переполнение АЛУ

NOT AV

Нет переполнения АЛУ

MV

Переполнение умножителя

NOT MV

Нет переполнения умножителя

NEG

Входной операнд «xop» отрицателен

POS

Входной операнд «xop» положителен

NOT CE

Счетчик циклов не пуст

FLAG_IN*

Вывод FI=1

NOT FLAG_IN*

Вывод FI=0

*Только для команд JUMP, CALL

Глава 19. Генераторы адресов

В этой главе говорится об устройствах генераторов адресов сигнального процессора и выполняемых с его помощью командах.

Ранее мы уже рассматривали назначение генераторов адресов (DAG). На этот раз рассмотрим их структуру и команды, которые они позволяют выполнять.

Сигнальный процессор имеет в своем составе два независимых генератора адреса данных, обеспечивающих одновременный доступ к памяти данных и памяти программ. Генераторы адреса осуществляют косвенную адресацию данных. Оба генератора могут выполнять автоматическую модификацию адреса данных. С помощью циклических буферов, они могут выполнять модификацию адреса по модулю. Отличие генераторов адреса друг от друга состоит в следующем. Первый генератор адреса (DAG1) генерирует только адреса памяти данных, но обеспечивает при этом изменение порядка разрядов в адресе на обратный (реверс разрядов). Второй генератор адреса (DAG2) генерирует как адреса памяти данных, так и адреса памяти программы, но не способен поддерживать реверсную адресацию.

Структурная схема генератора адреса приведена на рис. 19.1. Отличия структуры DAG1 от DAG2 показаны на самой схеме.

Рис. 19.1. Структурная схема генератора адреса

Каждый генератор имеет в своем составе три регистровых блока: блок регистров модификации (M), блок индексных регистров (I) и блок регистров длины (L). Каждый из регистровых блоков состоит из четырех регистров разрядностью 14 бит. Чтение и запись данных в эти регистры осуществляется через шину данных DMD. Индексные регистры I содержат действительные адреса, используемые для доступа к памяти. При косвенной адресации данных адрес, находящийся в выбранном индексном регистре, становится адресом памяти. Разряды адреса на выходе DAG1 могут быть переставлены в обратном порядке за счет установки соответствующего бита режима в регистре состояний режима MSTAT или при помощи команды ENA BIT_REV. Реверс адреса (адресация с перестановкой разрядов в обратном порядке) необходим для выполнения операций БПФ (быстрого преобразования Фурье) для цифровых значений сигнала. Данную операцию часто называют скремблированием (от английского слова scramble — смешивать). Сброс бита режима реверса адреса в регистре состояний режима MSTAT производится командой DIS BIT_REV. Для наглядности сказанного в табл. 19.1 приведен нормальный и реверсивный порядок адресов для 2-, 3- и 4-разрядных адресов. Из таблицы видно, каким образом при этом перемешиваются значения адреса.

Таблица 19.1 Нормальный и реверсивный порядок адресов для 2-, 3- и 4-разрядных адресов

Значение адреса

Нормальный порядок

Реверсивный порядок

Значение адреса

2-разрядный адрес

0

00

00

0

1

01

10

2

2

10

01

1

3

11

11

3

3-разрядный адрес

0

000

000

0

1

001

100

4

2

010

010

2

3

011

110

6

4

100

001

1

5

101

101

5

6

110

011

3

7

111

111

7

4-разрядный адрес

0

0000

0000

0

1

0001

1000

8

2

0010

0100

4

3

0011

1100

12

4

0100

0010

2

5

0101

1010

10

6

0110

0110

6

7

0111

1110

14

8

1000

0001

1

9

1001

1001

9

10

1010

0101

5

11

1011

1101

13

12

1100

0011

3

13

1101

1011

11

14

1110

0111

7

15

1111

1111

15

Генераторы адреса используют пост-модификацию. Т.е. после доступа к данным при использовании косвенной адресации содержимое заданного регистра модификации M прибавляется к содержимому индексного регистра I для формирования нового значения регистра I. Выбор регистров M и I в пределах одного DAG произволен. Т.е. любой из индексных регистров I0–I3 DAG1 может быть модифицирован содержимым любого из регистров модификации M0–M3. Для DAG2 аналогично используются регистры I4–I7 и M4–M7. Значения модификации, содержащиеся в регистрах модификации M, являются знаковыми числами, поэтому следующий вычисленный адрес может быть больше или меньше предыдущего.

Генераторы адреса поддерживают адресацию линейных и циклических буферов данных. Содержимое регистра длины L определяет режим адресации для соответствующего индексного регистра I. При адресации циклических буферов регистр L инициализируется длиной буфера. При адресации линейных буферов регистр L инициализируется нулем. Для каждого регистра I соответствующий регистр L несет информацию о длине буфера. Если сумма значений регистра модификации M и индексного регистра I превышает значение длины циклического буфера, модифицированное значение регистра I вычисляется логическим устройством адресации по модулю с использованием значения регистра длины L.

Поскольку регистры I и L содержат беззнаковые числа, два старших разряда шины данных заполняются при чтении этих регистров нулями. Регистры модификации M хранят числа со знаком, поэтому старшие два разряда шины данных дополняются знаковым расширением при их чтении.

Реверсная адресация

Логическое устройство инвертирования разрядов адреса предназначено для вычислений БПФ, когда разряды двоичных значений данных вводятся или генерируются в обратном порядке. Постановка разрядов в обратном порядке возможна только для адресов, генерируемых DAG1. Точкой поворота является средняя точка 14-разрядного адреса, между разрядами 6 и 7, как показано ниже:

Нормальный порядок разрядов:

13 12 11 10 09 08 07 06 05 04 03 02 01 00.

Реверсный порядок разрядов:

00 01 02 03 04 05 06 07 08 09 10 11 12 13.

Реверсная адресация разрешается при установке соответствующего бита в регистре состояния режима MSTAT. При разрешении данного режима работы DAG1 разряды всех адресов, сгенерированных с использованием индексных регистров I0–I3, ставятся в обратном порядке на выходе. При этом значения адресов в индексных регистрах хранятся в нормальном порядке, а преобразование адреса происходит только при выводе на шину адреса. Этот режим сохраняется до сброса соответствующего бита состояния MSTAT.

В DAG1 можно также инвертировать значения адресов с разрядностью менее 14 бит. Для этого необходимо определить первый адрес и записать при инициализации в регистр модификации M значение, вычисляемое для модификации инвертированного выходного значения регистра I в нужном интервале. Это значение равно 214-N, где N - число разрядов, которое необходимо поставить в обратном порядке.

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

Команды пересылки данных

Чтение из памяти данных (косвенная адресация):

dreg = DM(|I0|,|M0|);

|I1|,|M1|

|I2|,|M2|

|I3|,|M3|

|I4|,|M4|

|I5|,|M5|

|I6|,|M6|

|I7|,|M7|

Чтение из памяти программ (косвенная адресация):

dreg = PM(|I4|,|M4|);

|I5|,|M5|

|I6|,|M6|

|I7|,|M7|

Запись в память данных (косвенная адресация):

DM(|I0|,|M0|) = dreg;

|I1|,|M1|

|I2|,|M2|

|I3|,|M3|

|I4|,|M4|

|I5|,|M5|

|I6|,|M6|

|I7|,|M7|

Запись в память программ (косвенная адресация):

PM(|I4|,|M4|) = dreg;

|I5|,|M5|

|I6|,|M6|

|I7|,|M7|

Запись в память данных (прямая адресация):

DM(<addr>) = reg;

Запись содержимого регистров оверлеев в память данных:

DM(<addr>) = DMOVLAY;

Запись в область ввода/вывода (прямая адресация):

IO(<addr>) = dreg;

Пересылка регистр-регистр:

reg = reg;

Непосредственная загрузка регистра:

reg = <data>;

dreg = <data>;

Чтение регистра оверлеев:

dreg = DMOVLAY;

Запись в регистр оверлеев:

DMOVLAY = dreg;

Чтение из памяти данных (прямая адресация):

reg = DM (<addr>);

Чтение из памяти ввода/вывода (прямая адресация):

dreg = IO(<addr>);

Символьная запись <addr> для команд ввода/вывода может принимать значения адреса в диапазоне от 0 до 2048, а для команд обращения к памяти данных от 0 до 16383 (0x3FFF).

Вместо записи dreg могут быть использованы регистры: AX0, АХ1, AY0, AY1, AR, MX0, МХ1, MY0, MY1, MR0, MR1, MR2, SI, SE, SR0, SR1.

Вместо записи reg могут быть использованы все регистры dreg и регистры: I0–I7, M0–M7, L0–L7, TX0, ТХ1, RX0, RX1, SB, PX, ASTAT, MSTAT, SSTAT(только чтение), IMASK, ICNTL, IFC (только запись), CNTR, OWRCNTR (только запись).

Примеры команд пересылки данных:

AX0=АХ1; {Переслать содержимое регистра AX1 в AX0}

AY0=0xA37F; {Загрузить в регистр 16-разрядное число 0xA37F}

AY0=DM(1247); {Прочесть данные из ячейки памяти с адресом 1247 в регистр AY0}

PM(I7, M7) = AX0; {Записать в память программ значение регистра AX0,

используя индексные регистры I7 и M7}

Ниже приведен пример подпрограммы реверсирования разрядов адреса. Данная программа служит для размещения данных по адресам, в которых изменен нормальный порядок разрядов на обратный порядок.

.MODULE scram;

{

Вход: Буфер данных input

Выход: Буфер данных output

Используемые регистры: I0, I4, M0, М4, AY1

}

.CONST N=1025, mv=H#0010; {Инициализация констант mv=16384/N}

.EXTERNAL input, output;

.ENTRY scramble;

scramble: I4=^input; {I4 присвоить адрес начала буфера входных данных}

I0=^output; {I0 присвоить адрес начала буфера выходных данных}

M4=1;

M0=mv; {M0=модификатор для реверса}

L4=0; {Линейные буферы}

L0=0;

ENA BIT_REV; {Разрешение инвертирования разрядов}

CNTR=N;

DO Met UNTIL СЕ; {Организация цикла}

AY1 =DM(I4,M4); {Чтение последовательно организованных данных}

Met: DM(I0,M0)=AY1; {Запись данных в ячейки в обратном порядке}

DIS BIT_REV; {Запрещение инвертирования разрядов}

RTS; {Возврат в вызывающую программу}

.ENDMOD;

Глава 20. Таймер

В этой главе говорится об устройстве таймера сигнального процессора и его назначении.

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

Программируемый таймер сигнального процессора позволяет циклически генерировать прерывания через определенные промежутки времени, кратные циклам процессора. Структурная схема таймера представлена на рис. 20.1.

Рис. 20.1. Структурная схема таймера

Как видно из рисунка, таймер включает в себя 16-разрядный регистр периода TPERIOD, 8-разрядный регистр масштабирования TSCALE, 16-разрядный регистр-счетчик TCOUNT и логику управления. Все три регистра отображены на область памяти данных процессора в соответствии с табл. 20.1.

Таблица 20.1 Формат регистров таймера, отображенных на память данных процессора

Разряды регистров

Адрес

15

14

13

12

11

10

9

8

TPERIOD

0x3FFD

TCOUNT

0x3FFC

0

0

0

0

0

0

0

0

0x3FFB

Разряды регистров

Адрес

7

6

5

4

3

2

1

0

TPERIOD

0x3FFD

TCOUNT

0x3FFC

TSCALE

0x3FFB

Разрешение работы таймера производится установкой в единицу 5-го разряда регистра состояния процессора MSTAT. Когда работа таймера разрешена, регистр-счетчик TCOUNT декрементируется сигналами от логики масштабирования. При достижении счетчиком нуля, формируется прерывание таймера для процессора. После чего в регистр-счетчик TCOUNT автоматически загружается значение регистра периода TPERIOD и работа таймера продолжается.

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

Значения регистров TPERIOD и TSCALE могут загружаться с шины DMD. Таким образом, с помощью таймера можно генерировать прерывания каждые (TPERIOD+1)*(TSCALE+1) циклов, т.е. от 1 до FFFFFF_16=16777215_10 циклов. При тактовой частоте процессора 40МГц таймер может формировать прерывания с периодом от 20 нс до 0,3 с.

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

Ниже приведен пример команд инициализации таймера:

{Регистр таймера TPERIOD=0x3FFD (Регистр периода)}

AX0=0X7FFF; DM(TPERIOD)=AX0;

{Регистр таймера TCOUNT=0x3FFC (Регистр счетчика)}

AX0=0X7FFF; DM(TCOUNT)=AX0;

{Регистр таймера TSCALE=0x3FFB (Регистр масштабирования)}

AX0=255; {ОТ 0 ДО 255} DM(TSCALE)=AX0;

Строка обработки прерывания в программе может иметь следующий вид:

jump V_TIMER; nop; nop; nop; {Вектор прерывания таймера}

Следующий пример обработчика прерывания таймера позволяет автоматически наращивать значения ячейки памяти 0x3000 и выводить эти значения в порт ввода-вывода по адресу 2000.

{===== Обработчик прерывания таймера =====}

V_TIMER:

ENA SEC_REG;

AX0=DM(0X3000);

AR=AX0 + 1;

DM(0X3000)=AR;

IO(2000)=AR;

RTI;

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

Глава 21. Синхронные последовательные порты

В этой главе говорится о двух синхронных последовательных портах, входящих в состав сигнального процессора, об их устройстве, назначении и использовании.

Кроме рассмотренных нами вычислительных и других устройств, сигнальный процессор имеет встроенные коммуникационные средства в виде двух синхронных последовательных портов, называемых SPORT0 и SPORT1. Данные порты поддерживают множество последовательных протоколов обмена данными и, кроме того, обеспечивают прямое соединение процессоров в многопроцессорной системе. Рассмотрим подробнее эти устройства и команды, которыми они управляются.

Каждый SPORT имеет пять интерфейсных линий:

SCLK — тактовый сигнал;

RFS — прием кадровых синхроимпульсов;

TFS — передача кадровых синхроимпульсов;

DR — прием данных;

DT — передача данных.

SPORT1, в отличие от SPORT0, имеет возможность программно переназначать все сигнальные линии, кроме SCLK. Описание выводов последовательных портов сигнального процессора ADSP-2181 приведено в табл. 21.1.

Таблица 21.1 Описание выводов последовательных портов сигнального процессора ADSP-2181

Сигнал

Направление

Назначение

DT0

О

Передача данных

TFS0

I/O

Кадровая синхронизация передачи

RFS0

I/O

Кадровая синхронизация приема

DR0

I

Прием данных

SCLK0

I/O

Программируемый генератор порта 0

DT1/FO

O

Передача данных или выходной флаг

TFS1/IRQ1

I/O

Кадровая синхронизация передачи или внешний запрос прерывания 1

RFS1/IRQ0

I/O

Кадровая синхронизация приема или внешний запрос прерывания 0

DR1/FI

I

Прием данных или входной флаг

SCLK1

I/O

Программируемый генератор порта 1

I — вход, O — выход, I/O — вход/выход.

SPORT0 и SPORT1 способны одновременно принимать последовательный поток данных на входе DR и передавать последовательный поток через выход DT, обеспечивая тем самым дуплексный режим работы. Кроме того, передаваемые и принимаемые данные могут быть аппаратно запакованы и распакованы с помощью аппаратного блока компандирования. Данная процедура широко применяется в аппаратуре цифровой связи. Биты данных синхронизируются тактовыми синхроимпульсами SCLK внутреннего генератора, если процессор запрограммирован как источник синхронизации. Если порт запрограммирован в режим внешней синхронизации, SCLK становится входом для внешних импульсов синхронизации.

Сигналы кадровой синхронизации RFS и TFS используются для указания начала слова последовательно передаваемых данных или потока последовательно передаваемых слов. Эти сигналы также могут генерироваться внутри процессора или формироваться извне.

На рис. 21.1 показана структурная схема последовательного порта.

Рис. 21.1. Структурная схема последовательного порта

Данные, предназначенные для передачи, записываются через шину данных DMD из внутреннего регистра процессора в регистр данных передатчика порта TX. Эти данные могут перед передачей сжиматься в блоке компандирования (упаковки-распаковки) при задании такого режима. После чего данные автоматически передаются в сдвиговый регистр передатчика. Из регистра сдвига биты передаются на вывод последовательного порта DT, начиная со старшего разряда, синхронно с тактовыми синхроимпульсами SCLK. Приемник последовательного порта принимает данные с вывода DR, также синхронно с тактовыми синхроимпульсами SCLK. После приема одного слова данные распаковываются в блоке компандирования (если такая процедура была предварительно программно задана), а затем передаются в регистр данных приемника RX последовательного порта. Таким образом, происходит аппаратная одновременная передача и прием последовательных данных в обоих портах.

После записи данных в регистр TX последовательного порта этот порт готов к передаче данных. Передача начинается синхронно с сигналом TFS. После начала передачи каждое слово, записанное в регистр TX, подается во внутренний сдвиговый регистр передатчика, откуда оно передается на выход последовательно по битам, начиная с самого старшего бита. Каждый бит сдвигается по переднему фронту тактового синхроимпульса. После окончания передачи первого (самого старшего) бита слова последовательный порт генерирует прерывание передатчика. Несмотря на то, что передача первого слова продолжается, становится возможной запись нового слова данных в регистр TX.

В приемнике последовательного порта биты накапливаются в том же порядке, как они поступают во внутренний сдвиговый регистр приемника. По окончании приема одного целого слова оно записывается в регистр RX, и последовательный порт генерирует прерывание приемника.

Благодаря имеющейся возможности программной настройки конфигурации портов, достигается их гибкость в работе и совместимость с другими типами последовательных портов. Режим работы каждого последовательного порта задается программно с помощью регистров управления. Назначение регистров управления последовательных портов сигнального процессора, а также назначение и приоритетность прерываний последовательных портов SPORT0 и SPORT1 были подробно описаны ранее.

Кроме дуплексного режима работы, каждый SPORT имеет двойную буферизацию. Т.е. приемник и передатчик последовательного порта имеют регистр данных для передачи слов данных в процессор и из него, а также сдвиговые регистры данных. Двойная буферизация сокращает время для обслуживания последовательного порта.

SPORT0 и SPORT1 могут самостоятельно формировать тактовые импульсы синхронизации последовательных потоков данных в широком диапазоне частот или использовать внешние тактовые синхроимпульсы.

Каждый последовательный порт поддерживает длину слова последовательно передаваемых и принимаемых данных от трех до шестнадцати бит.

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

Сигналы кадровой синхронизации могут быть активными по высокому или по низкому уровню и с программируемой длительностью.

SPORT0 и SPORT1 могут выполнять аппаратное компандирование по А-закону или Мю-закону, согласно рекомендациям Международного консультативного комитета по телеграфии и телефонии (МККТТ) G.711.

Каждый последовательный порт может работать в режиме автобуферизации. Используя генераторы адреса данных, каждый последовательный порт может автоматически принимать и передавать весь циклический буфер со скоростью: одно слово данных за один процессорный цикл.

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

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

Пример диаграмм работы порта в различных режимах работы при передаче и приеме слов длиной в четыре бита информации показан на рис. 21.2–21.13. Описание рисунков диаграмм для удобства пользования сведено в табл. 21.2.

Таблица 21.2 Описание рисунков диаграмм

Номер рисунка

Направление потока

Режим кадровой синхронизации

Поток данных

Наличие синхронизации

21.2

Прием

Нормальный

С интервалами

Есть

21.3

Прием

Нормальный

Непрерывный

Есть

21.4

Прием

Альтернативный

С интервалами

Есть

21.5

Прием

Альтернативный

Непрерывный

Есть

21.6

Прием

Нормальный

Непрерывный

Нет

21.7

Прием

Альтернативный

Непрерывный

Нет

21.8

Передача

Нормальный

С интервалами

Есть

21.9

Передача

Нормальный

Непрерывный

Есть

21.10

Передача

Альтернативный

С интервалами

Есть

21.11

Передача

Альтернативный

Непрерывный

Есть

21.12

Передача

Нормальный

Непрерывный

Нет

21.13

Передача

Альтернативный

Непрерывный

Нет

Рис. 21.2

Рис. 21.3

Рис. 21.4

Рис. 21.5.

Рис. 21.6

Рис. 21.7

Рис. 21.8

Рис. 21.9

Рис. 21.10

Рис. 21.11

Рис. 21.12

Рис. 21.13

SPORT0 в отличие от SPORT1 может кроме того работать в режиме многоканальности. Т.е. он может избирательно принимать и передавать данные последовательного потока с использованием мультиплексирования 24 или 32 каналов с временным разделением информации. Это необходимо для использования цифровых коммуникационных интерфейсов T1 и E1, а также может использоваться для сетевой коммуникации нескольких процессоров. В одноканальном режиме сигналы кадровой синхронизации обозначают начало слова или непрерывного потока слов. В многоканальном режиме сигнал кадровой синхронизации приема данных RFS0 обозначает начало конкретного слова в потоке данных, состоящих из 24 или 32 слов, для одновременного приема и передачи этого слова по раздельным линиям приемопередатчика. Многоканальный режим разрешается установкой в единичное состояние 15-го разряда в регистре управления SPORT0 по адресу 0x3FF6. Формат пакетов при этом определяется разрядом 9 этого же регистра. Если он установлен в единицу, будет задан 32-словный формат, при установке в ноль задается 24-словный формат данных. Кроме того, разряды с 10-го по 13-й этого же регистра, с условным названием MFD, устанавливают задержку сигнала кадровой синхронизации в многоканальном режиме для того, чтобы кадровый синхроимпульс обозначал необходимое для приема и передачи слово в потоке данных. Диаграмма задержки сигнала кадровой синхронизации для нескольких значений MFD при работе SPORT0 в многоканальном режиме показана на рис. 21.14.

Рис. 21.14. Диаграмма задержки сигнала кадровой синхронизации

Сигнал кадровой синхронизации передатчика TFS0 в многоканальном режиме работает как сигнал TDV (Transmit Data Valid), переводимый как правильные данные передачи и предназначенный для управления включением и отключением внешней буферной логики передатчика. Фактически этот сигнал осуществляет стробирование тех слов данных, которые были разрешены в конфигурационном регистре для передачи. В зависимости от установки 7-го разряда в регистре управления SPORT0 по адресу 0x3FF6 описанный сигнал может иметь активное значение с высоким или с низким уровнем потенциала. На рис. 21.15 приведен пример диаграммы работы SPORT0 в многоканальном режиме.

Рис. 21.15. Пример диаграммы работы SPORT0 в многоканальном режиме

Рассмотрим пример программного конфигурирования обоих последовательных портов сигнального процессора, приведенный ниже.

{ ============================= SPORT0 ============================= }

{ Регистры разрешения мультиканального приема/передачи данных SPORT0 }

{ Регистр разрешения приема SPORT0_RX_Channels1 = 0x3ffa             }

{ Биты:   FEDCBA9876543210 0-игнорирован 1-доступен                  }

{ Каналы: 3322222222211111                                           }

{         1098765432109876                                           }

ax0 = b#0000000000000000; DM(SPORT0_RX_Channels1) = ax0;

{ Регистр разрешения приема SPORT0_RX_Channels0 = 0x3ff9             }

{ Биты:   FEDCBA9876543210 0-игнорирован 1-доступен                  }

{ Каналы: 111111                                                     }

{         5432109876543210                                           }

ax0 = b#0000000000000010; DM(SPORT0_RX_Channels0) = ax0;

{ Регистр разрешения передачи SPORT0_TX_Channels1 = 0x3ff8           }

{ Биты:   FEDCBA9876543210 0-игнорирован 1-доступен                  }

{ Каналы: 3322222222211111                                           }

{         1098765432109876                                           }

ax0 = b#0000000000000000; DM(SPORT0_TX_Channels1) = ax0;

{ Регистр разрешения передачи SPORT0_TX_Channels0 = 0x3ff7           }

{ Биты:   FEDCBA9876543210 0-игнорирован 1-доступен                  }

{ Каналы: 111111                                                     }

{         5432109876543210                                           }

ax0 = b#0000000000000011; DM(SPORT0_TX_Channels0) = ax0;

{ Регистр SPORT0_Control_Reg = 0x3FF6 (Регистр управления SPORT0)    }

{ Биты:     FEDCBA9876543210                                         }

{ Исх.сост: 0000000000000000                                         }

ax0 = b#1100011100110111; DM(SPORT0_Control_Reg) = ax0;

{ Регистр SPORT0_SCLKDIV = 0x3FF5 (Модуль деления последов. такт. импульсов) }

{           частота CLKOUT внутренняя удвоенная частота процессора           }

{ SCLKDIV = ------------------------------------------------------ - 1;      }

{(кадр.с.и.)      2*(частота SCLK синхронизация бит порта)                   }

{                                                                            }

{ SCLKDIV =(( 2*16384КГц ) / ( 2*2048КГц )) -1=8-1=7                         }

ax0 = 7; DM(SPORT0.SCLKDIV) = ax0;

{Регистр SPORT0_RFSDIV = 0x3FF4 (Модуль деления последоват. такт. импульсов) }

{          частота SCLK                                                      }

{ RFSDIV = ------------ - 1;                                                 }

{          частота RFC                                                       }

{ RFSDIV = 2048КГц / 8КГц - 1 = 256-1 = 255                                  }

ax0 = 255; DM(SPORT0_RFSDIV) = ах0;

{Регистр SPORT0_Autobuf = 0x3FF3 (Регистр управления автобуферизацией SPORT0)}

{ Биты:     FEDCBA9876543210                                                 }

{ Исх.сост: 0000XXXXXXXXXX00                                                 }

ax0 = b#0000011110101011; DM(SPORT0_Autobuf) = ах0;

{ Регистр SPORT1_Control_Reg = 0x3ff2 (Регистр управления SPORT1)            }

{ Биты:     FEDCBA9876543210                                                 }

{ Исх.сост: 0000000000000000                                                 }

ax0 = b#0111101001001001; DM(SPORT1_Control_Reg) = ах0;

{Регистр SPORT1_SCLKDIV = 0x3FF1 (Модуль деления последоват. такт. импульсов)}

{           частота CLKOUT внутренняя удвоенная частота процессора           }

{ SCLKDIV = ------------------------------------------------------ - 1;      }

{(кадр.с.и.)       2*(частота SCLK синхронизация бит порта)                  }

{                                                                            }

{ SCLKDIV = (( 2 *16384КГц ) / ( 2*115200 Гц )) -1 = 142-1 = 852             }

ax0 = 141; DM(SPORT1_SCLKDIV) = ax0; { 115200 бод }

{ Регистр SPORT1_RFSDIV = 0x3FF0 (Модуль деления последоват. такт, импульсов)}

{          частота SCLK                                                      }

{ RFSDIV = ------------ - 1; (или число бит в пакете -1)                     }

{          частота RFC                                                       }

{ RFSDIV = 19200 Гц / 1920 Гц - 1 = 10-1 = 9                                 }

ax0 = 9; DM(SPORT1_RFSDIV) = ax0;

{Регистр SPORT1_Autobuf = 0x3FEF (Регистр управления автобуферизацией SPORT1)}

{ Биты:     FEDCBA9876543210                                                 }

{ Исх.сост: 0000XXXXXXXXXX00                                                 }

ax0 = b#0000000000000000; DM(SPORT1_Autobuf) = ax0;

В первых двух блоках программы разрешается работа первого канала приемника SPORT0. В следующих двух блоках программы разрешается работа нулевого и первого канала передатчика SPORT0. Далее в регистр SPORT0_Control_Reg заносится информация о длине слова, формате данных, выравнивании слова, типе компандирования, инвертировании кадровых импульсов и др. режимов работы порта. После чего вычисляется коэффициент деления для тактовой частоты синхронизации SCLK и записывается в регистр SPORT0_SCLKDIV. Аналогично, в следующем блоке программы, производится вычисление коэффициента деления для тактовой частоты кадровых импульсов и запись этого значения в регистр SPORT0_RFSDIV. Завершается конфигурирование SPORT0 записью режима работы порта в регистр управления автобуферизацией SPORT0_Autobuf. Аналогично производится конфигурирование порта SPORT1.

Прием и передача данных через порты могут осуществляться с помощью регистров передатчика TX0, TX1 и регистров приемника RX0, RX1 в портах SPORT0 и SPORT1 соответственно. Эти регистры не отображены в карте памяти процессора, но распознаются мнемоникой ассемблера. Доступ к этим регистрам обеспечивается в произвольный момент во время выполнения программы. Например, следующая команда записывает данные из регистра AX0 в регистр передатчика SPORT1:

TX1 = AX0; {Содержимое регистра AX0 передается в порт SPORT1}

Естественно, что перед этим SPORT1 должен быть программно сконфигурирован ранее описанными командами.

Следующая команда запишет принятые данные из регистра приемника порта SPORT0 в регистр AX0:

AX0 = RX0; {Содержимое регистра приема SPORT0 записывается в регистр AX0}

Часть IV. Среда разработки Visual DSP++

В этой части книги говорится об установке на компьютер современного средства разработки программ для сигнальных процессоров — программного пакета Visual DSP++, его запуске и работе. Приводятся примеры программ и их отладка в среде разработки. Демонстрируется спектральный анализ сигнала с помощью Visual DSP++. Рассказывается о программировании на Си в данной среде разработки.

Глава 22. Установка

В этой главе говорится об установке на компьютер современного средства разработки программ для сигнальных процессоров — программного пакета Visual DSP++.

Введение

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

В предыдущих материалах мы рассмотрели средства программирования сигнальных процессоров для операционной системы MS DOS. В настоящее время существует более мощное и современное средство программирования для операционной системы Windows, которое носит название Visual DSP++.

Для знакомства с новыми примерами программ удобнее использовать Visual DSP++, поскольку он имеет интегрированный интерфейс разработчика и обладает мощными средствами визуализации и отладки программ. В этом читатели вскоре смогут убедиться самостоятельно.

Программный пакет Visual DSP++ свободно распространяется фирмой Analog Device со своего сервера в Интернете. Он представляет собой тестовую (trial) версию и может быть загружен по адресу http://www.analog.com/processors/resources/crosscore.

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

Тестовую версию Visual DSP++, кроме Интернета, можно получить в представительстве компании Analog Device, или у официальных дистрибьюторов компании на компакт-диске. Фирма Analog Device периодически создает новые версии Visual DSP++, тем не менее при этом соблюдается совместимость с предыдущими программными продуктами, и интерфейс данного пакета легко узнаваем для любой версии. Поскольку описываемый программный пакет не русифицирован и содержит всю информацию на английском языке, ниже дается методика установки программного пакета Visual DSP++, с целью избавления от ошибок при установке пакета и экономии времени читателей.

Установка

Рассмотрим поэтапно установку программного пакета Visual DSP++ на примере версии 3.0.

Вначале необходимо загрузить файл программы установки пакета и файл программы его лицензирования с источника, указанного выше. После успешной загрузки программ установки и лицензирования, необходимо получить серийный номер для последующей регистрации пакета, зайдя в Интернет по ссылке http://forms.analog.сom/Form_Pages/processors/visualDSPTestDrive.sp и заполнив одностраничную форму. Серийный номер пакета будет выслан вам по электронной почте на адрес, который вы укажете в анкете.

Для установки пакета на компьютер необходимо иметь не менее 100 Мб свободного дискового пространства. Процесс установки Visual DSP++ начинается с запуска самораспаковывающегося файла VisualDSP++3.0for21xx.exe. При этом на экране монитора отобразится окно (рис. 22.1), текст которого сообщает о том, что вам будет предложен каталог для распаковки пакета перед его установкой.

Рис. 22.1

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

Если вы установили ранее любое из аппаратных устройств (например, такое, как EZ-KIT Lite, или аппаратные средства ICE), вам понадобится в дальнейшем указать «Мастеру Новых Устройств» на этот каталог, когда Windows пытается установить драйверы устройств.

Ознакомившись с данным сообщением, необходимо нажать программную кнопку «Далее». При этом появится новое окно (рис. 22.2), в котором предлагается ввести название временного каталога, куда будут распакованы файлы программы. Если указанный каталог не существует, его необходимо будет создать. Вы можете вручную подкорректировать указанный каталог или выбрать его из созданных ранее, нажав кнопку «Browse». После чего необходимо нажать кнопку «Continue».

Рис. 22.2

Далее программа предложит создать несуществующий каталог (рис. 22.3) и начнет распаковку файлов в этот каталог (рис. 22.4), если будет нажата кнопка «Да».

Рис. 22.3

Рис. 22.4

После чего на экране кратковременно отобразится окно с цветной заставкой программного пакета Visual DSP++ (рис. 22.5) и откроется окно с приглашением процедуры установки пакета (рис. 22.6). В этом окне сообщается о том, что на вашу систему будет произведена установка программного обеспечения для сигнальных процессоров семейства 218x и 219x, инструменты, спецификации и документация.

Рис. 22.5

Рис. 22.6

После нажатия на кнопку «Next» установка будет продолжена и на экране отобразится лицензионное соглашение (рис. 22.7), определяющее права и обязанности пользователя данного продукта. Для продолжения установки необходимо подтвердить свое согласие с условиями использования пакета путем нажатия кнопки «Yes».

Рис. 22.7

Далее будет предложено ввести ваше имя и название компании (рис. 22.8). Здесь необходимо ввести те имена, которые вы использовали при заполнении анкеты на получение серийного номера для регистрации пакета, например Ivan Soft.

Рис. 22.8

Нажмите на кнопку «Next», и перед вами откроется новое окно установки (рис. 22.9), в котором предлагается ввести рабочий каталог программы, куда будет установлен сам программный пакет Visual DSP++.

Рис. 22.9

Здесь можно оставить все без изменений или выбрать другой каталог, по аналогии с процедурой определения временного каталога для установки программы.

Для продолжения установки нажмите кнопку «Next». Теперь откроется окно выбора устанавливаемых компонентов (рис. 22.10).

Рис. 22.10

Здесь необходимо отметить те вспомогательные компоненты, которыми вы располагаете. В нашем случае можно отметить ADSP 2181 EZ-KIT Lite, поскольку тестовая плата, описанная ранее, совместима с указанным устройством, и ею можно пользоваться, так же как отладочным средством ADSP 2181 EZ-KIT Lite. В принципе, можно отметить все компоненты или, наоборот, не отмечать ни одного дополнительного компонента, поскольку сам программный пакет Visual DSP++ в любом случае все равно будет работоспособен. Установка компонентов влияет лишь на присутствие или отсутствие дополнительных функций пакета.

После нажатия кнопки «Next» процесс инсталляции продолжится, и на экране начнется отображение окон, подобных представленным на рис. 22.11 и рис. 22.12, в которых сообщается об именах распаковываемых файлов и краткая информация о самом пакете соответственно.

Рис. 22.11

Рис. 22.12

Заканчивается первый этап установки отображением окна приведенного на рис. 22.13, в котором сообщается об успешном окончании установки и предлагается нажать кнопку «Finish» для завершения установки.

Рис. 22.13

Следующим шагом в установке пакета является его регистрация. Для выполнения этой процедуры необходимо запустить файл лицензирования LicenseInstaller5RC45.exe, который после запуска отобразит окно (рис. 22.14) с сообщением, в котором предлагается выбрать тип лицензии.

Рис. 22.14

Самым простым и распространенным видом лицензирования является установка одиночного пользователя лицензии (Install Single User License).

Для выполнения этого выбора необходимо нажать соответствующую надпись в окне. После нажатия программной кнопки «Next» на экране появится окно с содержанием лицензионных прав (рис. 22.15).

Рис. 22.15

Для продолжения установки необходимо подтвердить свое согласие с условиями использования пакета путем нажатия программной кнопки «Yes». После этого появится окно (рис. 22.16) с предложением ввести серийный номер продукта, который был выслан вам по электронной почте и обычно представляет собой строку, состоящую из 3 букв и 15 цифр.

Рис. 22.16

После введения номера и нажатия кнопки «Next» появится окно с сообщением о том, что данный серийный номер позволяет вам использовать установленный продукт, включающий в себя среду Visual DSP++, симулятор, компилятор, ассемблер и компоновщик, в течение 30 дней с момента регистрации (рис. 22.17).

Рис. 22.17

Нажмите на кнопку «Next». В результате на экране появится окно, сообщающее об успешном лицензировании пакета Visual DSP++ (рис. 22.18). Здесь необходимо нажать кнопку «Finish».

Рис. 22.18

На этом процесс установки программного пакета Visual DSP++ заканчивается, и можно приступать к его использованию. Кроме того, теперь можно удалить все файлы из временного каталога, поскольку программа инсталляции не делает этого самостоятельно.

Глава 23. Запуск VisualDSP++

В этой главе говорится об использовании современного средства разработки программ для сигнальных процессоров — программного пакета VisualDSP++.

После установки программного пакета VisualDSP++ на компьютер можно начать работу с ним. Установленная программа находится по умолчанию в каталоге «C:\Program_Files\Analog Devices\VisualDSP\System\ldde.exe» и запускается по пути: Пуск→Программы→VisualDSP→VisualDSP++ Environment.

При первом запуске этой программы на экране монитора отобразится окно (рис. 23.1), текст которого сообщает о том, что ваша лицензия на использование VisualDSP++ истечет через 30 дней. После чего необходимо будет либо купить, либо вновь зарегистрировать данный программный пакет.

Рис. 23.1

Окно, появляющееся после истечения срока лицензии, приведено на рис. 23.2. В нем сообщается об окончании срока лицензии и предлагается посетить в Интернете страницу по адресу: http://www.analog.com/dsp/tools/register\VisualDSP\System\reg_info.txt, содержащую регистрационную информацию.

Рис. 23.2

До истечения лицензии данное окно не появляется, и после нажатия программной кнопки «OK» на экране появится окно новой сессии (рис. 23.3), в котором необходимо выбрать семейство процессоров, платформу и тип процессора, с которым будет выполняться работа.

Рис. 23.3

Здесь можно выбрать вариант, представленный на рис. 23.3 для работы с устройством EZ-KIT Lite или тестовой платой, описанной ранее, либо задать вариант, представленный на рис. 23.4 для работы в режиме программной эмуляции процессора. Во втором случае никаких аппаратных средств при использовании VisualDSP++ не потребуется.

Рис. 23.4

Среда разработки VisualDSP++ предполагает работу как с отдельными файлами, так и с проектами, включающими в себя набор файлов, различных по назначению и содержанию. Это могут быть файлы с программами, входными и выходными данными, настройками среды разработки и т.п.

После нажатия кнопки «OK» откроется основное рабочее окно программы (рис. 23.5), представляющее собой среду разработки.

Рис. 23.5

Рассмотрим интерфейс пользователя VisualDSP++. В верхней части программы находится главное меню, с помощью которого можно выполнять различные программные действия. Ниже размещаются кнопки меню инструментов, дублирующие некоторые команды главного меню. В левой части программы размещается окно проекта, в котором содержатся сведения о файлах проекта. Справа находится окно дизассемблированного кода. Окно выходной информации, содержащее стандартные текстовые сообщения ввода-вывода, сообщения об ошибках и др. сообщения, находится внизу. Средняя часть экрана отведена под окно редактирования. Внешний вид среды разработки может настраиваться по вкусу пользователя, позволяя отображать необходимую для отладки программы информацию. Более детально познакомиться с интерфейсом среды можно, изучая примеры программ, входящих в состав самого пакета, и с помощью встроенной электронной справки.

Установленный на компьютере программный пакет VisualDSP++ включает в себя множество готовых примеров программ и большой объем справочной информации. Файлы с примерами программ и справкой находятся в каталогах

«C:\Program_Files\AnalogDevices\VisualDSP\218x\Examples»

и

«C:\Program_Files\AnalogDevices\VisualDSP\Help».

Рассмотрим работу программы на основе готового примера из самого пакета. Выберите в главном меню программы команду: Project→Open и в открывшемся окне диалога (рис. 23.6) укажите путь к проекту с именем Example1 в каталоге

«C:\Program_Files\Analog Devices\VisualDSP\218x\Examples\Example1».

Рис. 23.6

Откройте каталог «Example1», выделите в нем файл проекта «Example1» и нажмите кнопку «Открыть». После этого найдите в открывшемся проекте файл с названием «Vectadd.asm» и щелкните по нему дважды левой кнопкой мыши.

В центре экрана откроется новое окно, для редактирования выбранного файла. Разверните это окно, щелкнув кнопку разворота окна, и закройте окно дизассемблирования, если оно открыто.

Это позволит увеличить область редактирования, для удобства восприятия информации. Среда разработки примет при этом вид, подобный тому, что изображен на рис. 23.7.

Рис. 23.7

Данный проект содержит программу, предназначенную для сложения двух векторов (массивов) данных x_input[n] и y_input[n] и размещения результата по адресу ввода-вывода z_out. В программе иллюстрируется начальная инициализация входных массивов и настройка генераторов адреса. Среда разработки VisualDSP++ позволяет по шагам посмотреть процедуру инициализации массивов, выборки чисел из памяти и их сложения в цикле. Массивы имеют длину n=10, объявленную в самом начале программы с помощью оператора: #define n10. Результат сложения будет пересылаться в область ввода-вывода с адресом z_out=0x100, объявленным в программе с помощью оператора: #define z_out x100. Массив данных x_input[n] будет храниться в памяти данных процессора после загрузки из файла «xin.dat», что определено строками программы:

.section/data data1;

.VAR x_input[n] = "xin.dat";

Второй массив данных y_input[n] будет храниться в памяти программ процессора после загрузки из файла «yin.dat», что определяется строками программы:

.section/pm pm_da;

.VAR y_input[n] = "yin.dat";

Далее в программе размещаются векторы прерываний. Тело основной программы состоит из строк:

.section/pm program;

start: I2=x_input; /*pointer to x input buffer*/

L2=0; /*noncircular buffer*/

I6=y_input; /*pointer to y input buffer*/

L6=0;

M0=1; L0=0;

M5=1; L5=0;

CNTR=n-1;

AX0=DM(I2,M0), AY0=PM(I6,M5); /*Get first data*/

DO add_loop UNTIL CE;

AR=AX0+AY0, AX0=DM(I2,M0), AY0=PM(I6,M5);

add_loop: io(z_out)=AR; /*Write output*/

AR=AX0+AY0;

io(z_out)=AR;

IDLE;

Выполним данную программу в пошаговом режиме. Для этого вначале произведем компиляцию программы, нажав на клавиатуре клавишу F7. В результате программа будет скомпилирована, и отобразится окно, приведенное на рис. 23.8.

Рис. 23.8

Этот же результат можно получить, выполнив команду главного меню Project→Build project или нажав соответствующую ей кнопку на панели инструментов. Из рисунка видно, что стрелка, показывающая очередную выполняемую программу, располагается напротив строки с меткой «reset». Кроме того, справа автоматически открывается окно дизассемблированных команд программы. Выполнять программу в пошаговом режиме можно, нажимая клавишу F11, выполнив команду Debug→Step Into или нажав соответствующую ей кнопку на панели инструментов.

При каждом таком действии будет выполняться очередная строка команд. Результат работы программы можно наблюдать по изменению содержимого памяти и регистров процессора. Окна, отображающие память процессора, вызываются с помощью главного меню «Memory». Для отображения окон с содержимым регистров процессора используется кнопка главного меню «Register». Для отображения регистров удобно воспользоваться командой Register→Custom, которая позволяет выбрать только те регистры, которые необходимо видеть пользователю. При выполнении этой команды откроется окно, изображенное на рис. 23.9.

Рис. 23.9

Выделяя в этом окне с помощью мышки необходимые для контроля регистры и щелкая по кнопке «Add», можно создать набор регистров для отображения на дисплее в одном окне. Кроме того, в строке «Title of window» можно задать название отображаемого окна. Таким образом, можно создать несколько окон для отображения различных групп регистров для контроля их состояния. Создав такое окно, можно продолжать выполнение программы по шагам. При этом в окне регистром будет видно изменение содержимого регистров, которые участвовали в выполнении очередной строки команд программы. Текущие изменения будут выделяться красным цветом. Выполнение программы завершается оператором IDLE, который переводит процессор в режим энергосбережения. Для повторного запуска программы необходимо вновь выполнить команду Project→Build. Перед повторной компиляцией проекта в программу можно вносить собственные изменения с целью получения практики программирования. Можно, например, изменить программу таким образом, чтобы результат сложения массивов записывался не по адресу ввода-вывода, а в память данных. Закрытие проекта производится командой Project→Close.

Глава 24. Работа с VisualDSP++

В этой главе рассматриваются очередные примеры программ, способы настройки симулятора и получение загрузочного файла в среде разработки VisualDSP++.

Рассмотрим еще один пример программы, который демонстрирует работу с последовательным портом и предназначен для освоения работы с симулятором и потоками ввода-вывода.

Откройте в установленном пакете Visual DSP++ каталог с примером проекта программы «Example2», выделите в нем файл проекта «Example2» и нажмите кнопку «Открыть». После этого найдите в открывшемся проекте файл с названием «Sport.asm» и щелкните по нему дважды левой кнопкой мыши. В центре экрана откроется новое окно, позволяющее просматривать и редактировать выбранный файл. Разверните это окно, щелкнув кнопку развертывания окна.

В этой программе выполняется инициализация последовательных портов SPORT0 и SPORT1 с последующей передачей данных, используя процедуру прерываний.

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

sample: AX0=RX1; /*принять данные в AX0*/

TX1=АХ0; /*передать данные из AX0*/

RTI;

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

Для этого необходимо подключить ко входу и выходу порта файлы, которые будут содержать входные и выходные данные. Выполните команду главного меню: «Setting→Streams2». После этого на дисплее откроется окно «Streams», показанное на рис. 24.1.

Рис. 24.1

Щелкните в открывшемся окне по кнопке «Add» (добавить). Во вновь открывшемся окне «Add New Streams» (рис. 24.2) в группе настроек «Source» выберите группу «File» и, щелкнув по кнопке «Browse» (обзор), найдите, выделите и откройте файл «Serin.dat» с помощью кнопки «Open» (открыть).

Рис. 24.2

После чего выберите в списке «Format» строку «Binary». Остальные настройки данной группы оставьте без изменений. Теперь в группе настроек «Destination» выберите в списке «Device» устройство Sport1 и нажмите кнопку «OK». После этого вновь открывается окно «Streams», в котором будет присутствовать заданная нами настройка.

Далее необходимо подключить выходной файл. Вновь щелкните в окне «Streams» по кнопке «Add». В открывшемся окне «Add New Streams» в группе настроек «Source» переключитесь на группу «Debug target» и выберите в списке «Device» устройство «Sport1». Теперь в группе настроек «Destination» выберите группу «File» и, щелкнув по кнопке «Browse», найдите, выделите и откройте файл «Serout.dat» с помощью кнопки «Save» (сохранить) или задайте это имя для выходного файла. В списке «Format» выберите строку «Binary» и нажмите кнопку «OK».

Теперь в открывшемся окне «Streams» будут присутствовать две записи настроек, показанные на рис. 24.3. Нажмите в окне «Streams» кнопку «OK», и оно закроется.

Рис. 24.3

Перед запуском программы создайте с помощью команды меню Register→Custom окно, в котором будут отображаться регистры AX0, RX1, TX1. Кроме того, откройте еще одно с помощью команды меню Register→Program Control для отображения содержимого регистров управления процессора. Изменение содержимого этих регистров можно будет наблюдать в процессе пошагового выполнения программы. Допускается добавление окон для отображения и других регистров, но помните, что избыточная информация загромождает экран и затрудняет изучение программы.

Теперь можно скомпилировать и запустить программу в пошаговом режиме, с помощью клавиш F7 и F11 соответственно. Кроме того, программу можно запустить в непрерывном режиме, используя команду Debug→Run, или клавишу F5, или соответствующую кнопку на панели инструментов. В результате выполнения программы, данные из входного файла Serin.dat должны без изменений переписаться в выходной файл Serout.dat. После окончания работы программы в окне выходной информации появится сообщение: «Error in reading from stream for Sport 1», которое означает, что отладчик достиг конца входного файла при чтении данных.

При выполнении программы в непрерывном режиме допускается устанавливать точки останова в тех местах программы, где необходимо проконтролировать значение каких-либо данных в регистрах или памяти процессора. Для этих целей используются кнопки панели инструментов в виде кисти руки или синих флажков. Для установки точки останова необходимо выделить какую-либо строку программы и нажать кнопку с именем «Toggle Bookmark». Снятие любой точки останова производится повторным нажатием этой же кнопки. Для снятия всех точек останова в программе используется кнопка с именем «All Clear Bookmark». Переход между точками останова вверх или вниз производится с помощью кнопок «Next Bookmark» и «Prevision Bookmark» соответственно.

В исследуемом примере программы, инициализация SPORT1 задает формирование внутреннего кадрового сигнала порта. Программный пакет Visual DSP++ позволяет симулировать внешний кадровый сигнал для порта, с заданными временными параметрами. Для того чтобы задействовать данный механизм, произведите небольшую корректировку программы, изменив настройку кадровой синхронизации для порта SPORT1. Затем установите параметры внешнего прерывания кадровым сигналом с помощью команды главного меню «Setting→Interrupts». В открывшемся окне (рис. 24.4) выберите в качестве источника внешнего прерывания (External Interrupts) кадровый сигнал приемника RFS1 и задайте число циклов Min cycles=0 a Max cycles=10. Нажмите кнопку «Add», а затем «OK». Теперь на панели инструментов найдите и нажмите кнопку «Restart» и выполните программу по шагам, нажимая клавишу F11.

Рис. 24.4

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

В программном пакете Visual DSP++ можно создавать новые проекты. Для этого необходимо закрыть открытый ранее проект с помощью команды Project→Close и выполнить команду Project→New. При этом откроется окно «Save New Project As» для создания нового проекта (рис. 24.5).

Рис. 24.5

Нажмите в этом окне кнопку создания нового каталога и задайте ему новое имя. Теперь откройте вновь созданный каталог и задайте имя нового проекта. После чего нажмите кнопку «Save» (сохранить). При этом откроется окно свойств проекта «Project Options» (рис. 24.6). Выберите в этом окне в списке «Processor» тип ADSP-2181 и закройте окно с помощью кнопки «OK».

Рис. 24.6

Далее создайте новый файл программы с помощью команды «File→New» и введите в него текст программы, подобный тому, что приведен ниже:

.section/pm interrupts;

__reset: JUMP start; NOP; NOP; NOP; /*reset vector*/

RTI; NOP; NOP; NOP; /*IRQ2*/

RTI; NOP; NOP; NOP; /*IRQL1*/

RTI; NOP; NOP; NOP; /*IRQL2*/

RTI; NOP; NOP; NOP; /*SPORT0 transmit*/

RTI; NOP; NOP; NOP; /*SPORT0 receive*/

RTI; NOP; NOP; NOP; /*IRQE*/

RTI; NOP; NOP; NOP; /*BDMA*/

RTI; NOP; NOP; NOP; /*SPORT1 transmit*/

RTI; NOP; NOP; NOP; /*SPORT1 receive*/

RTI; NOP; NOP; NOP; /*Timer*/

RTI; NOP; NOP; NOP; /*Power down*/

.section/pm program;

start: nop;

jump start;

Этот текст в дальнейшем можно использовать в качестве шаблона (заготовки) новой программы для сигнального процессора. Сохраните созданный файл с каким-либо допустимым именем и расширением «asm» и выполните команду Project→Add to Project→File(s). Выберите сохраненный файл с программой и нажмите кнопку «Add». Теперь необходимо добавить в каталог с проектом файл Adsp-2189.ldf, который можно взять из рассмотренных ранее каталогов с примерами проектов. Данный файл необходим для определения типа процессора и трансляции программы. После этого программу можно транслировать и запускать на выполнение. При успешной компиляции проекта, в подкаталоге «Debug» проекта должен появиться исполняемый файл с расширением «dxe», который автоматически загружается в отладчик-симулятор при запуске программы.

Для получения файла в рассмотренном нами ранее формате «lda» можно воспользоваться специальной утилитой elf2aexe.exe, входящей в состав Visual DSP++. С целью автоматизации этого процесса предлагаю использовать командный файл, имеющий следующее содержание:

cls

elf2aexe.exe %1.dxe %1

del %1.lda

del %1.sym

ren %1.exe %1.lda

Здесь вначале производится очистка дисплея, затем вызывается утилита elf2aexe.exe с именем преобразовываемого файла в качестве входного параметра. После чего выполняются операции удаления вспомогательных файлов и переименования полученного файла. Данный командный файл можно назвать именем dxe_lda.bat и использовать для его вызова команду: dxe_lda.bat имя_файла.

Полученный таким образом файл с расширением «lda» можно использовать для загрузки в аппаратный эмулятор или тестовую плату через интерфейс IDMA.

Глава 25. Спектральный анализ сигнала в среде Visual DSP++

В этой главе рассматривается программный метод спектрального анализа цифрового сигнала на примере программы, выполняемой в среде разработки Visual DSP++.

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

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

ДПФ позволяет преобразовать N комплексных отсчетов сигнала во временной области в N комплексных отсчетов спектра в частотной области. Из многих теоретических источников известно, что во временной области входному сигналу с частотой, равной f, в частотной области соответствует спектр сигнала, отображаемый в диапазоне от -f/2 до f/2, где отрицательные значения составляют мнимую, а положительные значения — действительную часть спектра сигнала. Причем действительная часть спектра обладает четной симметрией, а мнимая часть нечетной. С целью сокращения количества операций и ускорения тем самым расчетов спектра сигнала, обычно ограничиваются вычислением модуля спектра сигнала в области частот от 0 до f/2.

Вычисление N отсчетов спектра сигнала с помощью ДПФ производится с помощью уравнения, приведенного на рис. 25.1. Здесь X(k) являются искомыми отсчетами спектра сигнала, а x(n) — исходными отсчетами сигнала во временной области. N представляет собой количество отсчетов при вычислении ДПФ.

Рис. 25.1. Вычисление N отсчетов спектра сигнала с помощью ДПФ

В квадратных скобках уравнения присутствуют коэффициенты для действительной и мнимой частей.

Рассмотрим очередной пример программы, демонстрирующей реализацию метода дискретного преобразования Фурье для получения спектра сигнала в среде Visual DSP++. Откройте в программном пакете Visual DSP++ очередной проект из каталога C:\Program Files\AnalogDevices\VisualDSP\218x\Examples\Example4 и разверните в нем программу, находящуюся в файле с именем «Dft.asm». В этой программе производится расчет спектра сигнала по N отсчетам сигнала, используя алгоритм дискретного преобразования Фурье. Текст этой программы с переведенными автором книги комментариями приведен ниже:

/*====================================================================

Файл:DFT.ASM Процессор:ADSP-218х Дискретное Преобразование Фурье (ДПФ)

Эта программа выполняет ДПФ для N точек согласно следующему уравнению:

N-1

real(k)+j *imag(k) = SUM input(n) [С - j*S]; k=0 до N-1

n=0

где: C=cos(2*pi*k*n/N), S=sin(2*pi*k*n/N), j=sqrt(-1)

====================================================================*/

#define N   64      /* Константа - количество входных отсчетов * /

#define COS 0x000C1 /* Адрес буфера временных данных COS */

#define SIN 0x000C5 /* Адрес буфера временных данных SIN */

.section/data data1;

.VAR input[N]=etest64.date; /* Таблица данных тестируемого сигнала */

.VAR real[N];               /* Буфер действительных значений спектра * /

.VAR imag[N];               /* Буфер мнимых значений спектра */

.section/pm pm_da;

.VAR sine[N]="sine64.dat";/* Таблица данных гармонического сигнала */

.section/pm interrupts;

__reset: JUMP start; rti; rti; rti; /* 0x0000: reset */

rti; rti; rti; rti;                 /* 0x0004: IRQ2 */

rti; rti; rti; rti;                 /* 0x0008: IRQL1 */

rti; rti; rti; rti;                 /* 0x000c: IRQL0 */

rti; rti; rti; rti;                 /* 0x0010: SPORT0 tx */

rti; rti; rti; rti;                 /* 0x0014: SPORT1 rx */

rti; rti; rti; rti;                 /* 0x0018: IRQE */

rti; rti; rti; rti;                 /* 0x001c: BDMA */

rti; rti; rti; rti;                 /* 0x0020: SPORT1 tx or IRQ1 */

rti; rti; rti; rti;                 /* 0x0024: SPORT1 rx or IRQ0 */

rti; rti; rti; rti;                 /* 0x0028: timer */

rti; rti; rti; rti;                 /* 0x002c: power down */

.section/pm seg_code; /* Пример установки программы ДПФ */

start:

M1=1;

M2=0;

M7=1;

M5=0;

I0=input;

L0=64; /* Входной буфер циклический */

I1=imag;

L1=0; /* Нециклический буфер Image */

I2=real;

L2=0; /* Нециклический буфер Real */

/* ______________Подпрограмма ДПФ_____________________ */

dft:

I6=sine; /* Указатель на Sine */

L6=64;   /* Для N=64 значений */

I7=sine + N/4; /* Получение косинуса из синуса */

L7=64; /* Сдвиг указателя на pi/2 */

/* и использование циклического буфера.*/

I4=COS;

L4=2;

I3=SIN;

L3=2;

I5=0;

L5=0;

CNTR=N;

DO outer UNTIL CE;

M6=I5;

DM(I4,M7)=0; DM(I4,M7)=0;/* Очистка буфера временных данных COS */

DM(I3,M1)=0; DM(I3,M1)=0;/* Очистка буфера временных данных SIN */

CNTR=N;

DO calc UNTIL CE;

MX0=DM(I0,M1), MY0=PM(I7,M6); /* Чтение input, чтение COS */

MX1=MX0 /* Копирование input */

MY1=PM(I6,M6); /* Чтение SIN */

MR1=DM(I4,M7); /* Чтение текущего значения COS и суммирование */

MR0=DM(I4,M7);

MR=MR+MX0*MY0(SS);/* Мультисуммирование COS */

DM(I4,M7)=MR1; /* Запись нового накопленного значения COS */

DM(I4,M7)=MR0;

MR1=DM(I3,M1); /* Чтение текущего значения SIN и суммирование */

MR0=DM(I3,M1);

MR=MR-MX1*MY1(SS);/* Мультисуммирование SIN */

DM(I3,M1)=MR1; /* Запись нового накопленного значения SIN */

calc : DM(I3,M1)=MR0;

AR=DM(I4,M5);

DM(I2,M1)=AR; /* Запись результата действующей величины * /

AR=DM(I3,M2);

DM(I1,M1)=AR; /* Запись результата мнимой величины */

outer: MODIFY(I5,M7); /* Модификация указателей циклической таблицы */

end: IDLE;

Как видно из текста программы, в ней задействованы регистры генераторов адреса DAG для задания указателей на буфер данных тестируемого сигнала, таблицу значений гармонического сигнала, буферы результата и другие вспомогательные буферы. Вычисление значений спектра производится в двух циклах, счетчики которых инициализируются числом отсчетов N = 64. Вся программа выполняется за N*N групп операций. Результат работы программы заносится в выходные буферы действительных значений real и мнимых значений imag спектра.

Для выполнения программы выполните ее трансляцию с помощью клавиши F7. Затем установите точку останова на последнем операторе программы и запустите ее с помощью клавиши F5. Через несколько секунд программа выполнит свою работу и остановится. Визуальный просмотр тестируемого сигнала, а также результатов работы программы и других вспомогательных буферов данных можно осуществлять с помощью открытия окна памяти данных процессора, используя для этого команду Memory→Data. Кроме того, эти данные можно просматривать в графическом виде. Для этого необходимо выполнить команду: View→Debug Windows→Plot→New. При этом откроется окно конфигурации графического построителя Plot Configuration, показанное на рис. 25.2.

Рис. 25.2. Окно конфигурации графического построителя Plot Configuration

Рассмотрим работу с данным конфигуратором на примере просмотра буфера данных тестируемого сигнала. Оставьте в открывшемся окне конфигуратора без изменений строку Line Plot в поле Type группы настроек Plot. В поле Title введите имя графика «Input» или другое схожее по смыслу.

В группе Data Setting оставьте без изменений имя Data Set1 в поле Name и тип памяти DM в поле Memory. Нажмите на кнопку Browse в поле Address и выделите в открывшемся окне Browse for Symbol строку с именем input (рис. 25.3), после чего нажмите кнопку OK.

Рис. 25.3

В поле смещения данных Offset оставьте нулевое значение, а в поле счетчика Count замените значение 100 на 64, что соответствует количеству отсчетов в программе. Оставьте шаг сетки в поле Stride по умолчанию равным 1, а формат данных в поле Data целочисленным int. Нажмите на кнопку Add для добавления заданных установок в поле Data sets графического построителя. При желании, в это поле можно добавить и другие данные для отображения, а затем установить или снять перед соответствующим именем графика флажок для отображения этого графика. Теперь, нажмите на кнопку OK, после чего в правой части окна Visual DSP++ отобразится график заданных данных (рис. 25.4).

Рис. 25.4.

Для разворачивания и сворачивания окно графика имеет кнопку в виде стрелки. Аналогично можно построить и рассмотреть график, сформированный из буфера синусоидальных значений и хранящихся после выполнения программы в области памяти программ PM процессора с именем «sin» (рис. 25.5).

Рис. 25.5

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

После выполнения программы результат ее работы будет храниться в буферах с именами real и imag и также может быть визуально изучен.

Встроенный в программный пакет Visual DSP++ графопостроитель обладает рядом дополнительных функций. Эти функции доступны с помощью контекстного меню (рис. 25.6), открываемого щелчком правой кнопки мыши на окне графика.

Рис. 25.6

Первой в этом меню присутствует команда Data Cursor, которая позволяет узнать координатное значение любой точки графика, щелкая по нему левой кнопкой мыши. Следующая команда Reset Zoom приводит вид графика в исходное состояние. Команда Configure вызывает окно сконфигурированный графопостроителя, рассмотренное выше. Команда Modify Setting вызывает окно установок Plot Setting построителя (рис. 25.7).

Рис. 25.7

Данное окно состоит из пяти закладок и позволяет настроить изображение графопостроителя по вкусу пользователя.

Закладка General позволяет задать имя Title и вспомогательное имя Subtitle для графика. В группе Grid Lines этой закладки можно задать цвет Grid color и присутствие сетки графика по осям X, Y, обеим осям (Both) или их отсутствие (None). Группа Background Color задает цвет графика Plot и фона окна Window. Группа Margins позволяет изменить масштаб графика или произвести сброс пользовательских установок масштаба с помощью кнопки Reset. Наконец, группа Option позволяет отображать рядом с графиком его имя и статистические данные с помощью флажков, устанавливаемых в поле Legend и Statistics соответственно.

Следующая закладка 2-D Axis (рис. 25.8) позволяет задать имя осей X и Y графика в полях Title, а также начальное значение оси X в поле Start value и ее шаг в поле Increment value.

Рис. 25.8

Для оси Y можно задать линейный или логарифмический вид представления графика с помощью поля Linear/Log. Для обеих осей имеются группы Scale для задания автоматического (Auto) или ручного (Manual) масштабирования осей. При этом параметры Min value и Max value задают соответственно минимальное и максимальное значение по осям ординат, а параметр Multiplier определяет множитель шкалы.

Закладка Font (рис. 25.9) позволяет задать имя (Font name), цвет (Font color) и размер (Font size) шрифта для отображения надписей на графике.

Рис. 25.9

Очередная закладка Style (рис. 25.10) кон фигурирует линии графика с помощью полей типа линии (Line type), ее ширины (Line width), цвета (Line color) и символов (Symbol) для отображения линии с их размерами (Symbol size).

Рис. 25.10

Наконец, последняя закладка Data Processing (рис. 25.11) позволяет задать для любого графика с именем, выбранным в поле Data Sets, формат его преобразования, определяемый в поле Data Process. При этом допускается отображение графика без преобразования (None), с преобразованием в шкалу децибел (Convert to dB), преобразованием Фурье (FF Magnitude) или двумерным преобразованием Фурье (D FF Magnitude). Кроме того, на этой закладке можно задать частоту преобразования в поле Sample rate и сохранение следов в поле Stored traces. Поле Trigger позволяет задать нарастание (Rising), спадание (Falling) и величину порога триггера (Threshold value) для исследуемого сигнала, наподобие установок осциллографа.

Рис. 25.11

Следующая команда Save Settings контекстного меню (см. рис. 25.6) позволяет сохранить заданные выше настройки Plot Setting.

Очередная команда Export контекстного меню вызывает окно Export Plot (рис. 25.12), которое позволяет задать приемник для экспорта данных графопостроителя. В качестве такого приемника может быть буфер обмена (Clip Board), файл (File), принтер (Printer) или звуковая карта (Sound Card). При экспорте данных в файл пользователю предоставляется возможность выбрать любой из следующих форматов файла: jpg, bmp, gif, tif, eps, txt или dat.

Рис. 25.12

Снятие флажка перед командой Allow Docking приводит к преобразованию окна графика в перемещаемое окно.

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

Команда Close контекстного меню закрывает график.

Наконец, команда Float In Main Window вызывает перемещение графика в главное окно среды Visual DSP++.

Время вычисления спектра сигнала является основной характеристикой спектрального анализатора. Чем оно меньше, тем производительнее анализатор. Поэтому для ускорения вычисления спектра используют метод быстрого преобразования Фурье (БПФ).

Фактически БПФ является модернизацией ДПФ за счет сокращения количества операций умножения и сложения. Это стало возможным благодаря использованию свойств симметрии и периодичности коэффициентов уравнения преобразования, представляющих собой базовые гармонические функции. Если для вычисления N отсчетов спектра сигнала при использовании ДПФ требуется N*N операций умножения комплексных чисел, то при использовании БПФ количество операций сокращается до (N/2)log2(N). Эффективность БПФ по сравнению с ДПФ становится существенной, когда количество точек увеличивается до нескольких тысяч.

В табл. 25.1 приведено соотношение объема вычислительных затрат при различном объеме входных данных.

Таблица 25.1 Соотношение объема вычислительных затрат при различном объеме входных данных

Количество отсчетов N

Количество умножений

Коэффициент эффективности

ДПФ

БПФ

2

4

1

4

4

16

4

4

8

64

12

5

16

256

32

8

32

1024

80

13

64

4096

192

21

128

16384

448

37

256

65536

1024

64

1024

1048576

5120

205

2048

4194304

11264

372

4096

16777216

24576

683

При вычислении спектра сигнала методом БПФ используют различные алгоритмы. Алгоритм по основанию два (Radix2) разделяет полное вычисление ДПФ на комбинацию двухточечных ДПФ. Каждое двухточечное ДПФ использует базовую операцию умножения с накоплением (так называемую «бабочку»). При этом число точек в БПФ должно быть степенью двойки. Если количество точек является степенью числа четыре, то можно использовать алгоритм по основанию четыре (Radix4). Эти алгоритмы хорошо реализуются в программах для сигнальных процессоров, поскольку в них имеются генераторы адреса с битреверсивной адресацией, предназначенной как раз для реализации подобных алгоритмов.

Глава 26. Программирование на языке СИ

Это заключительная глава книги, в которой рассматриваются примеры программ на языке программирования Си и их выполнение в среде разработки Visual DSP++.

Кроме ассемблерных программ, среда разработки Visual DSP++ позволяет транслировать программы, написанные на языке программирования «Си». Рассмотрим пример простой программы, написанной на языке «Си», которая вычисляет значения тригонометрической функции синуса для четырех заданных значений аргумента.

Создайте новый проект с именем «С» и подключите к проекту новый файл с именем «c1.c», набрав в нем текст программы, приведенный ниже:

#include <math.h>

#define PI 3.14159 /* Число Пи */

int y1, y2, y3, y4;

main() {

y1 = sin(0);

y2 = sin(PI/2.0);

y3 = sin(PI);

y4 = sin(PI+PI/2.0);

}

Здесь используются стандартные директивы и операторы языка «Си». В начале программы оператор включения подключает библиотеку математических функций math.h. Далее производится определение символьного имени PI. Ниже объявляются целочисленные переменные y1–y4. В данном примере переменные объявлены целочисленными для наглядности представления результата работы программы. Главный цикл программы main состоит из четырех однотипных операций вычисления значений функции синуса для различных значений аргумента. В данном случае аргумент принимает значения, кратные PI/2. Результатом данной программы будут значения функции синус, которые очевидно должны принимать значения 0, 1, 0 и -1.

Выполните трансляцию этой программы, нажав клавишу F7. Затем выполните ее, нажав клавишу F5. После выполнения программы в правой части экрана откроется окно дизассемблера, в котором будет присутствовать текст программы на языке ассемблера. Этот текст позволяет увидеть соответствие операторов языка «Си» набору ассемблерных инструкций. Для просмотра результата работы программы необходимо открыть окно памяти данных с помощью команды Memory→Data. По умолчанию, в этом окне данные отображаются в шестнадцатеричном виде. Для отображения результатов в знаковом целочисленном виде щелкните на окне правой кнопкой мыши и в открывшемся контекстном меню (рис. 26.1) выберите формат Select Format→Signed Integer.

Рис. 26.1. Контекстное меню

В результате данные в окне будут представлены в более привычном для человека виде (рис. 26.2).

Рис. 26.2. Данные в окне представлены в более привычной для человека форме

Как видно, результат работы программы оказался абсолютно точен. Заметьте, что благодаря лаконичности записи, присущей языку высокого уровня «Си», программа для вычисления тригонометрических функций состоит всего лишь из несколько строк. Для написания подобной программы на ассемблере понадобилось бы несколько десятков строк.

Теперь немного усложним программу, изменив ее текст на тот, что приведен ниже:

#include <math.h>

#define PI 3.14159 /* Число Пи */

#define D PI/180.0 /* Число Дельта */

#define N 100 /* Число отсчетов */

float y1[N], y2[N];

main() {

int i;

for (i=0; i<N; i++) {

y1[i] = sin(10.0*i*D);

y2[i] = cos(10.0*i*D);

}

}

Здесь определены два массива y1 и y2 с данными в формате float. Значения этих массивов будут вычисляться в цикле for для N значений аргумента функций синуса и косинуса.

Выполните трансляцию программы и установите точку останова на последней строчке программы. После чего запустите программу на выполнение. Через несколько секунд выполнение программы завершится. Для просмотра результата ее работы откройте новое окно графопостроителя. Для этого выполните команду View→Debug Windows→Plot→New. В открывшемся окне задайте значения всех полей в соответствии с рис. 26.3 и нажмите программную кнопку «Browse».

Рис. 26.3. Окно для задания значений полей

В новом открывшемся окне (рис. 26.4) найдите и выделите в памяти данных строку с массивом y1, после чего нажмите кнопку «OK».

Рис. 26.4. Окно для сопровождения работы программы

Нажмите в окне Plot Configuration программную кнопку «Add». При этом в поле Data sets появится запись Data set1. Теперь еще раз нажмите программную кнопку «Browse» и выделите в памяти данных строку с массивом y2, после чего нажмите кнопку «OK». Вновь нажмите в окне Plot Configuration программную кнопку Add. После этих действий в поле Data sets появится новая запись Data set2. Убедитесь, что строке Data set1 соответствует адрес y1, а строке Data set2 — адрес y2, выделяя по очереди каждую из строк в окне Plot Configuration. Для обеих строк данные должны иметь тип float. Если это не так — исправьте формат данных на float.

Теперь нажмите в окне кнопку «OK», разверните окно с графиками результатов работы программы (рис. 26.5).

Рис. 26.5. Кривые функций синуса и косинуса

Как видно из рисунка, графики представляют собой кривые функций синуса и косинуса, полученные из результатов работы программы.

С помощью графопостроителя можно увидеть и спектр сигналов. Для этого необходимо щелкнуть правой кнопкой мыши по окну с графиками и в открывшемся контекстном меню выбрать команду Modify Setting.

Далее в открывшемся окне Plot Setting открыть закладку Data Processing и выделить в поле Data Process строку FF Magnitude (рис. 26.6).

Рис. 26.6. Окно для сопровождения дальнейшей работы программы

После чего закрыть окно, нажав кнопку OK. В результате график преобразуется к виду, приведенному на рис. 26.7.

Рис. 26.7. Функция косинуса и спектр функции синуса

Здесь отображены одновременно функция косинуса и спектр функции синуса.

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

Заключение

Дорогие читатели, вы познакомились с материалами, посвященными сигнальному процессору ADSP2181 и средствам для его программирования.

Данная книга позволяет пройти путь изучения сигнального процессора от самых основ до самостоятельного программирования и разработки на его базе устройств с цифровой обработкой сигнала.

В ней были изложены как схемотехнические решения, так и программные материалы. Однако возможности сигнальных процессоров фирмы Analog Devices, а также средств разработки Visual DSP++ не исчерпываются приведенными в этой книге материалами и примерами. Это связано не только с краткостью изложения материала, но и с непрерывным развитием, как самих процессоров, так и программных средств для них.

Появление на рынке электроники новых процессоров приводит к необходимости постоянного обновления и углубления знаний в этой области.

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

Список литературы

1. http://www.analog.com/

2. ADSP-2181 DSP Microcomputer. Data Sheet. Rev.B., Analog Devices Inc.

3. ADSP-2100 Family User's Manual. Edition 3, Analog Devices Inc.

4. Сато Ю. Обработка сигналов. Первое знакомство./Пер. с яп.; под ред. Есифуми Амэмия. — М.: Издательский дом «Додэка-XXI», 2002. — 176 с.: ил.

5. Калабеков Б.А. Микропроцессоры и их применение в системах передачи и обработки сигналов. — М.: Радио и связь, 1988.

Content

Разработка устройств на основе цифровых сигнальных процессоров фирмы Analog Devices с использованием Visual DSP++

Предисловие

Часть I. Схемотехника

Глава 1. Обзор

Глава 2. Архитектура

Глава 3. Практические схемы включения

Глава 4. Программно-логическая модель

Глава 5. Система прерываний

Часть II. Программирование

Глава 6. Первая программа

Глава 7. Порт BDMA

Глава 8. Порт IDMA

Глава 9. Адаптер LPT-IDMA

Глава 10. Менеджер памяти

Глава 11. Директивы ассемблера

Глава 12. Форматы данных

Глава 13. Система команд

Часть III. Вычислительные и аппаратные устройства

Глава 14. Устройство АЛУ

Глава 15. Устройство MAC

Глава 16. Устройство сдвига

Глава 17. Устройство обмена между шинами

Глава 18. Программный автомат

Глава 19. Генераторы адресов

Глава 20. Таймер

Глава 21. Синхронные последовательные порты

Часть IV. Среда разработки Visual DSP++

Глава 22. Установка

Глава 23. Запуск VisualDSP++

Глава 24. Работа с VisualDSP++

Глава 25. Спектральный анализ сигнала в среде Visual DSP++

Глава 26. Программирование на языке СИ

Заключение

Список литературы