Обзор семейства ADSP–21XX – как устроен и из чего состоит

Пример HTML-страницы

Обзор семейства ADSP21XXОбщие сведения.

Цифровые сигнальные процессоры (Digital Signal Proces­sors — DSP) представляют собой самостоятельный класс специализированных процессоров с RISC–архитектурой, предназначенных для решения задач цифро­вой обработки сигналов, к которым относятся распознавание звука и речи, циф­ровая звукотехника, обработка изображений, цифровая фильтрация, спектраль­ный анализ и др.

Цифровая обработка сигналов требует большого объема вычис­лений, выполняемых, как правило, в реальном времени. Основными отличитель­ными особенностями DSP от обычных микропроцессоров являются:

● использование гарвардской архитектуры, при которой для хранения про­грамм и данных используются раздельные запоминающие устройства, A также раздельные шины данных и адреса, что позволяет совмещать выборку и ис­полнение команд;

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

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

● наличие специальных команд для цифровой обработки сигналов: умножение с накоплением и адресация к кольцевым буферам (для цифровой фильтра­ции); изменение порядка бит адреса на обратный (для быстрого преобразо­вания Фурье); битовые операции (для графики) и др. В этом разделе рассмотрено семейство процессоров ADSP–21XX фирмы Analog Devices, которые относятся к классу процессоров с фиксированной точкой и являются наиболее оптимальными по соотношению цена/качество. Кроме того, для семейства ADSP–21XX имеется полный набор программных и аппарат­ных средств поддержки разработчика, включающий в себя:

● построитель систем для определения архитектуры проектируемой цифровой системы (размера внешней RAM/ROM памяти, расположения памяти данных и команд, отображение портов ввода/вывода);

● ассемблер, поддерживающий высокоуровневый набор команд и модульное программирование;

● линкер (компоновщик), позволяющий оптимально расположить данные и команды по аппаратным узлам проектируемой системы;

● эмулятор для проведения интерактивной покомандной эмуляции аппаратной конфигурации, описанной в построителе систем;

● программатор ППЗУ для чтения вывода линкера и формирования файлов, со­вместимых с программаторами. Общая характеристика семейства ADSP–21XX. Семейство ADSP–21XX вклю­чает в себя набор однокристальных процессоров с общей базовой архитектурой, оптимизированной для цифровой обработки сигналов и других приложений, тре­бующих быстрых вычислений. В табл. 8.2.1 приведен ряд показателей для микро­схем процессоров ADSP–21XX. табл. 8.2.1

Процессоры семейства ADSP–21ХХ позволяют

● в течение одного процессорного цикла выполнить стандартные арифметиче­ские и логические операции, операции умножения и умножения с накоплением, арифметические и логические сдвиги и другие операции;

● вести обработку данных с повышенной точностью. В частности использова­ние 40–битного регистра–аккумулятора дает возможность накапливать расши­ренные суммы произведений, достаточно часто встречающиеся при цифро­вой обработке сигналов, что обеспечивает 8–битную защиту от потери данных при переполнениях. При последовательном выполнении операций умножения со сложением должно произойти 255 переполнений регистра–аккумулятора и только 256–е переполнение приведет к потере данных;

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

● организовать (с помощью генератора адресов команд) циклы и переходы, широко используемые при цифровой обработке сигналов, без дополнитель­ных процессорных циклов ожидания;

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

● сформировать адрес следующей команды;

● загрузить из памяти следующую команду;

● загрузить два операнда из внутренней и/или внешней памяти;

● обновить два указателя на данные;

● выполнить вычислительную операцию;

● принять и/или передать данные через последовательный порт, через интер­фейс с ведущим процессором (при наличии) и аналоговый интерфейс (при наличии). рис. 8.2.1

Состав ADSP

Для выявления особенностей структурно–функциональной орга­низации процессоров семейства ADSP–21ХХ воспользуемся обобщенной схемой, представленной на рис. 8.2.1. В процессоре можно выделить следующие основные блоки:

● вычислительный блок;

● блок генераторов адресов;

● блок внутренней памяти;

● таймер;

● блок последовательного интерфейса;

● устройство обмена между шинами данных;

● блок интерфейса с ведущим процессором;

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

Вычислительный блок

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

арифметическо–логическое устройство (Arithmetic/Logic Unit — ALU), выпол­няющее стандартный набор арифметических и логических операций, A также примитивы деления;

умножитель–аккумулятор (Multiplier/Accumulator — MAC), или накопитель, обеспечивающий выполнение операции умножения двоичных чисел за один процессорный цикл, A также совмещенных операций сложения с умножением и вычитания с умножением;

устройство сдвига (SHIFTER), предназначенное для выполнения логических и арифметических сдвигов, операций нормализации и денормализации чисел (операндов), экспоненциальных операций, A также операций над числами бо­лее одного слова с плавающей точкой. Вычислительный блок непосредственно обрабатывает 16–разрядные данные следующих типов:

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

знаковые числа, использующие для записи дополнительный код;

числа без знака, принимающие только положительные значения и имеющие диапазон вдвое больший, чем знаковые. Примером беззнаковых чисел явля­ются младшие слова чисел с двойной точностью;

дробный формат 1.15, в котором левый крайний бит числа обозначает его знак, A остальные 15 бит — значение числа. Ниже приведены пределы изме­нения положительных и отрицательных чисел в дробном формате и их деся­тичные значения. Пределы чисел в формате 1.15 Пределы десятичных значений 0000 0000 0000 0001 …0l11 1111 1111 1111 0.000031.. .0.999969 или 0x0001…0x7FFF 1111 1111 1111 1111..1000 0000 0000 0000 –0.000031…–1.000000 или 0xFFFF…0x8000 Блок генераторов адресов. Этот блок имеется в каждом процессоре. В его состав входят:

генератор адресов команд (Program Sequencer — PS), формирующий адреса команд для памяти программ;

два генератора адресов данных DAG1, DAG2 (Data Address Generators — DAG), обеспечивающие адресацию при пересылке данных в вычислительное устройство. При этом DAG1 формирует адреса только для памяти данных, позволяя изменять порядок следования бит в адресе. Генератор DAG2 спо­собен формировать адреса, как для памяти данных, так и для памяти про­грамм. Оба генератора эффективно используются для адресации кольцевых буферов;

● генератор адреса загрузки, используемый для аппаратного формирования последовательности адресов при начальной загрузке внутренней RAM–памяти программ из внешней ROM–памяти.

Блок внутренней памяти

Этот блок содержат все процессоры, кроме ADSP–2100. В него входят расположенные на кристалле RAM–память данных и RAM–память (в некоторых сериях микросхем ROM–память) программ. Внутренняя память отображается на часть общего адресного пространства памяти данных и программ.

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

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

Таймер

Все процессоры семейства ADSP–21XX содержат программируемый таймер/счетчик с 8–битным масштабированием. После каждого процессорного цикла содержимое 16–разрядного регистра–счетчика декрементируется и по до­стижении нулевого значения таймер генерирует прерывание. Затем регистр–счетчик автоматически загружается из 16–разрядного регистра интервала и про­цесс повторяется.

Блок последовательного интерфейса

Этот блок имеется в каждом процессоре семейства ADSP–21XX и содержит два двунаправленных последова­тельных порта SPORT0, SPORT1 (за исключением ADSP–2105) с двойной буфери­зацией и устройство компрессии/декомпрессии данных. Порт SPORT0 способен работать в многоканальном режиме с организацией обмена по 24 или 32 управ­ляемым (с возможностью блокировки) каналам. Порт SPORT1 допускает альтер­нативное использование четырех линий, которые помимо основного назначения могут быть сконфигурированы для приема внешних сигналов запроса прерыва­ний ¯IRQ0, ¯IRQ1 и входного флага FI (Flag In) и выдачи выходного флага FO (Flag Out). Каждый порт может тактироваться от собственного таймера или от внешне­го источника тактовой частоты. При передаче слов может быть использована кад­ровая синхронизация. С помощью устройства компрессии/декомпрессии могут быть реализованы алгоритмы сжатия/восстановления данных по А– и μ–законам. Различные режимы работы последовательных портов подробно изложены ниже.

Устройство обмена между шинами

Это устройство позволяет произ­вести обмен данными между шиной данных памяти данных DMD и шиной данных памяти программ РМD.

Блок интерфейса с ведущим процессором

Этот блок имеется в процессорах ADSP–2111, ADSP–21msp50, ADSP–21msp58, ADSP–2171, ADSP–2172, ADSP–2173. Блок интерфейса позволяет организовать обмен информацией меж­ду ведомым (содержащим этот блок) и внешним ведущим процессорами. Интер­фейс с ведущим процессором (Host Interface Processor — HIP) представляет со­бой параллельный порт ввода/вывода, к которому подсоединяется ведущий про­цессор.

В качестве ведущего процессора может быть использован как процессор семейства ADSP–21XX, так и другой, например, Intel 8051.

Интерфейс HIP состоит из блока управления и ряда регистров, имеет 16–разрядную шину для ввода/вы­вода данных и 11 управляющих выводов. Интерфейс может быть настроен на обмен 8– или 16–разрядными операндами;

на мультиплексированную шину адреса/данных или раздельные шины; на раздельные строб–импульсы для чтения/записи иди на строб–импульс чтения/записи и строб–импульс данных.

Блок аналогового интерфейса

Этот блок имеется только в процессо­рах ADSP–21msp50, ADSP–21msp58. Он обладает средствами для работы со сме­шенными аналого–цифровыми сигналами.

Шины процессора

В процессах семейства ADSP–21XX для связи между внутренними блоками используются пять шин (рис. 8.2.1):

● 14–разрядные шина адреса памяти данных (Data Memory Address — DMA) и шина адреса памяти программ (Program Memory Address — PMA), обеспечива­ющие доступ соответственно к 16–разрядным ячейкам памяти данных и 24–раз­рядным ячейкам памяти программ. Адрес памяти данных может быть задан непосредственно в команде (непосредственная адресация) или сформирован генератором адресов данных (косвенная адресация);

● 16–разрядная шина данных памяти данных (Data Memory Data — DMD) и 24–раз­рядная шина данных памяти программ (Program Memory Date — PMD), пред­назначенные для пересылки из памяти или в память соответственно данных и команд/данных;

● 16–разрядная шина результатов (Result — R), предназначенная для обмена результатами между вычислительными устройствами блока вычислений. С помощью мультиплексоров (рис. 8.2.1) линии четырех внутренних шин адреса и данных подключены к внешним выводам, образующим соответственно 24–раз­рядную внешнюю шину данных и 14–разрядную внешнюю шину адреса. рис. 8.2.2

Системный интерфейс

Синхронизация процессора

Для синхрониза­ции процессора могут быть использованы внешние синхроимпульсы, подаваемые на его внешний вывод CLKIN. Однако в большинстве случаев для формирования синхроимпульсов CLKIN к выводам CLKIN и XTAL процессора подключается квар­цевый резонатор.

Период следования синхроимпульсов CLKIN (или тактовая час­тота) определяет длительность процессорного (командного) цикла.

Для разделе­ния последовательности выполняемых микроопераций в течение процессорного цикла используются внутренние фазовые циклы с частотой в четыре раза превы­шающей тактовую частоту (рис. 8.2.2). Процессоры генерируют также внешние синхроимпульсы CLKOUT с периодом следования, равным длительности процес­сорного цикла.

Сброс

Операция сброса, выполняемая под действием сигнала ¯RESET = 0, предназначена для начальной загрузки, или инициализации, процессора, т. е. для приведения всех узлов процессора в исходное состояние, при котором возможно нормальное его функционирование. При включении питания на вывод ¯RESET микросхемы должен быть подан сигнал ¯RESET = 0. Сброс может осуществляться и при включенном питании. Сигнал CLKOUT во время сброса генерируется процессором.

Состояние реги­стров после сброса приводится в таблицах (графа «Сброс») при рассмотрении их функций по мере изучения структурно–функциональной организации процессо­ров семейства ADSP–21XX.

Содержимое памяти программ и данных, задейство­ванной под регистры, после сброса (если он происходит при включенном пита­нии) остается неизменным. Содержимое регистров вычислительных устройств после сброса может быть любым. Если состояние вывода управления картой па­мяти ММАР = 0, после сброса происходит начальная загрузка внутренней памяти программ из внешней загрузочной памяти. Для процессоров, содержащих интер­фейс с ведущим процессором, сброс может быть также выполнен установкой со­ответствующего бита в статусном регистре HSR7.

Программная начальная загрузка

Операция программной начальной загрузки, инициируемая установкой бита BFORCE = 1 в позиции SR.9 системного регистра (табл. 8.2.2), очищает контекст (содержимое регистров) процессора и инициализирует некоторые регистры (ASTSAT, SSTAT, IMASK, IFC, RBUF, TBUF). При выполнении этой операции все прерывания маскируются, автобуферизация выключается, последовательные порты и таймер остаются активными. табл. 8.2.2

Внешние прерывания

В процессорах семейства ADSP–21XX предусмот­рены средства для обслуживания внешних запросов на прерывание. Сигналы запроса прерывания подаются на отдельный вывод микросхемы ¯IRQ2 и альтер­нативные выводы ¯IRQ0, ¯IRQ1 порта SPORTI. Запрос на прерывание обслуживает­ся, если прерывание не замаскировано (соответствующий бит в регистре разре­шения прерываний IMASK установлен в 1) и отсутствуют прерывания с более вы­соким приоритетом.

Процессор не распознает запрос, если он поступил во время исполнения команды, при которой происходит обращение к внешней памяти более одного раза. Прерывания фиксируются, но не обрабатываются в режиме предоставления внешних шин (¯BG = 0) при отключенном режиме GO.

Обслуживание прерывания состоит в передаче управления по адресу вектора прерывания. Прерывания могут быть сконфигурированы как прерывания по уровню или как прерывания по спаду.

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

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

Выводы флагов

Входной флаг FI может использоваться в командах CALL и JUMP, характер выполнения которых зависит от состояния флага и определяет­ся следующими условиями: IF FLAG_IN, IF NOT FLAG_IN. При этом учитывается последнее состояние флага. Например, условие IF FLAG_IN выполнено, если по­следнее состояние флага FI = 1. Выходные флаги FO и FL0, FL1, FL2 (в процессорах ADSP–21mps50, adsp–2111) могут использоваться для различных целей как выходной сигнал. Интерфейс с памятью.

Семейство процессоров ADSP–21XX использует мо­дифицированную гарвардскую архитектуру, в которой память данных (RAM) хранит данные, A память программ (RAM и/или ROM) — команды и данные. Все версии кристаллов за исключением ADSP–2100 имеют внутреннюю память данных и программ. При необходимости объем памяти данных и программ может быть увеличен путем подключения внешней памяти. Если в кристаллах внутрен­няя память программ выполнена в виде RAM, используется процедура ее началь­ной загрузки из внешней загрузочной памяти.

Схема процессора с внешней па­мятью приведена на рис. 8.2.3.

Интерфейс с загрузочной памятью

Если во время сброса сигнал уп­равления картой памяти ММАР = 0 (Memory Map Control Signal — MMAP), началь­ная загрузка внутренней памяти начинается сразу после сброса из внешней за­грузочной памяти. При ММАР = 1 начальную загрузку следует активизировать программно. Объем загрузочной памяти может составлять до 64К слов. Поэтому при обра­щении к ней используется 16–разрядный адрес.

Как видно из рис. 8.2.3, младшие 14 бит адреса выводятся с 14–разрядной шины адреса (A13–A0), старшие 2 бита — со старших двух линий шины данных (D23–D22). Байт данных считывается со средних восьми бит шины данных. рис. 8.2.3 Загрузочная память состоит из восьми страниц длиной до 8К. Четвертый байт страницы содержит информацию о длине страницы: длина загрузочной страницы = (число 24–битных слов памяти команд/8) – 1. Каждый последующий четвертый байт страницы пустой.

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

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

Если сигнал управления картой памяти ММАР = 1, возможна программная реа­лизация начальной загрузки с любой из восьми страниц загрузочной памяти. Но­мер страницы задается битами BRAGE.0–BRAGE.2 (позиции SR.6–SR.8) системного регистра (табл. 8.2.2). Для инициирования загрузки следует установить бит BFORCE = 1 (позиция SR.9). В этом случае процессором автоматически вырабатывается строб ¯ВМS = 0, который подается на вход выбора кристалла ¯СS (рис. 8.2.3).

Число циклов ожи­дания (от 0 до 7, по умолчанию 3) для доступа к загрузочной памяти устанавлива­ется трехразрядным кодом BWAIT.2…BWAIT.0 (позиции SR.3–SR5) системного ре­гистра. При выполнении операции начальной загрузки генератор адресов загрузочной памяти формирует последовательность адресов для считывания соответству­ющих байтов из загрузочной памяти и записи их во внутреннюю память, начиная со старших адресов. Формат загрузочного адреса приведен на рис. 8.2.4.

Код загрузочного адреса состоит из четырех полей. В 3–битное поле старших разрядов из системного регистра заносится номер страницы. С

ледующее тюле; представляет собой 8–битную длину страницы, задаваемую в четвертом байте страницы.

В поле кода слова задается порядковый номер считываемого слова. В исходном состоянии поле содержит код 111, что соответствует 8–му слову.

Поле из двух младших разрядов задает код байта, считываемого из загрузочной памяти: старший байт USB = 00, средний байт MSB = 01 и младший байт LSB = 10. Байты учитываются в следующем порядке: старший, младший, средний. Пример. Рассмотрим операцию начальной загрузки восьми 24–разрядных слов (Слово 7, Слово 0) с самой короткой страницы, длина которой равна 0. Размещение слов В загрузочной памя­ти приведено в Табл. 8.2.3. Последовательность загрузки:

● шаг 1: читается четвертый байт, расположенный по адресу 0003. В этом байте указана длина страницы;

● шаг 2: считывается старший байт USB Слова 7, расположенный по адресу 001С;

● шаг 3: считывается младший байт LSB Слова 7, расположенный по адресу 001Е;

● шаг 4: считывается средний байт MSB Слова 7, расположенный по адресу 001D.

● после загрузки байта MSB Слова 7 во внутреннюю память программ происходит декрементация кода слова (пропускается ячейка с адресом 000В). Затем генерируются три последовательных адреса 0018, 001А, 0019 (шаги 5,6,7, см. табл. 8.2.3) для считы­вания трех байтов Слова 6 и т. д.

Процесс продолжается до тех пор, пока не будет счи­тан средний байт MSB Слова 0 (шаг 25). Начальная загрузка внутренней памяти программ после сброса происходит так же, как программно–инициированная загрузка за исключением мелких деталей.

Интерфейс с памятью программ

В процессоре ADSP–21XX преду­смотрены средства для обращения к внутренней и внешней памяти программ об­щим объемом 16К 24–битных слов (рис. 8.2.3). При обращении к внешней памяти программ используются:

● выход ¯PMS процессора, на который выставляется строб ¯PMS = 0 для активи­зации памяти программ;

● выходы ¯RD/¯WR процессора для чтения/записи памяти программ;

● 14–битная внешняя шина адреса (ВША) для адресации;

● 24–битная внешняя шина данных (ВШД) для вывода данных. При одновременном обращении к внешней памяти программ и памяти данных данные из памяти программ считываются первыми. С помощью трех бит PWAIT0–PWAIT2 в позициях SR0–SR2 системного регистра (табл. 8.2.2) задается число циклов ожидания для памяти программ. При обращении к внутренней памяти программ сигналы ¯PMS, ¯DMS. ¯RD, ¯WR имеют высокий уровень, исключающий возможность активизации микросхем внешней памяти, A внешние шины адреса и данных принимают высокоомное со­стояние. В этом режиме процессор способен за один цикл загрузить два операн­да и следующую команду. Отображение адресного пространства памяти программ зависит от состояния вывода управления картой памяти ММАР. При ММАР = 0 в процессе начальной загрузки внутренней памяти программ внутренняя память (например, 2К) распо­лагается по младшим адресам, A внешняя (14К) — по старшим; при ММАР = 1 — наоборот.

Интерфейс с памятью данных

 В процессоре ADSP–21XX предусмотрены средства для обращения к внешней и внутренней памяти данных общим объемом 16К 16–битных слов. При обращении к внешней памяти данных используются (рис. 8.2.3):

● выход ¯DMS процессора, на который выставляется строб ¯DMS = 0 для акти­визации памяти программ;

● выходы ¯RD/¯WR процессора для чтения/записи памяти программ;

● 14–битная внешняя шина адреса (ВША) для адресации;

● 24–битная внешняя шина данных (ВШД) для вывода 16 старших бит данных. При обращении к внутренней памяти данных сигналы ¯PMS, ¯DMS, ¯RD, ¯WR имеют высокий уровень, исключающий возможность активизации микросхем внешней памяти, A внешние шины адреса и данных принимают высокоомное со­стояние.

Предоставление внешних шин периферийным устройствам (рис. 8.2.3).

Для получения контроля над внешними шинами периферийное уст­ройство посылает сигнал запроса шины ¯BR = 0 (Bus Request — BR), который в те­кущем или следующем цикле распознается процессором. В следующем цикле после распознавания процессор устанавливает сигнал предоставления шины ¯BG = 0 (Bus Grant — BG), переводит шины адреса и данных в высокоомное состо­яние, A выводы ¯PMS, ¯DMS, ¯RD, ¯WR в единичное состояние.

После этого управ­ление шинами передается периферийному устройству. В режиме предоставления шин (Grant Out — GO) последовательные порты и интерфейс HIP остаются активными. табл. 8.2.3 Разрешение режима GO (бит G_MODE = 1 в позиции MSTAT.6 регистра режима и статуса процессора, табл. 8.3.3) позволяет процессору выполнить коман­ды из внутренней памяти программ в то время, когда шина предоставлена друго­му устройству. Процессор перейдет в состояние ожидания только тогда, когда по­требуется доступ к внешней памяти.

При выключенном режиме GO процессор всегда переходит в состояние ожидания во время предоставления шины другому устройству. Внутреннее состояние процессора при этом не изменяется. После удовлетворения запроса процессор возобновляет работу с того места, где она была прервана. После сброса периферийным устройством сигнала запроса шины (¯BR = 1) про­цессор отвечает сбросом сигнала предоставления шины (¯BG = 1) и возвращает себе контроль над внешними шинами.


Понравилась статья? Поделиться с друзьями:
Все об энергетике, электротехнике и электронике
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: