- •Мова опису апаратури ahdl
- •1. Опис комбінаційних схем
- •1.1. Шифратор
- •1.2. Дешифратор
- •1.3. Мультиплексор
- •1.4. Демультиплексор
- •1.5. Перетворювач коду
- •1.6. Компаратор
- •1.7. Суматор
- •1.8. Шинні приймачі-передавачі
- •1.9. Схеми монтажного «і» і «або»
- •2.1. Регістри
- •2.1.1. Паралельний регістр
- •2.1.2. Регістр зсуву
- •2.1.3. Регістр зсуву з паралельним завантаженням даних
- •2.1.4. Універсальний регістр
- •2.1.5. Циклічний регістр зсуву
- •Часть 2. Практическое использование языка ahdl. М. 2005.- 34 с.
- •1. Опис комбінаційних схем……………………………… 3
- •1.1. Шифратор ………………………………………………………………. 3
1.7. Суматор
Суматор - комбінаційний пристрій, що виконує операцію арифметичного додавання двох N-розрядних двійкових чисел А[], В[] і вхідного коду переносу Cin.
Нижче наведений опис N-розрядного суматора. Опис виконаний на вентильному рівні.
CONSTANT NUM_OF_ADDERS=8;
SUBDESIGN ADD_GATE
(
a[NUM_OF_ADDERS..1], b[NUM_OF_ADDERS..1], cin: INPUT;
c[NUM_OF_ADDERS..1], cout : OUTPUT;
)
VARIABLE
carry_out [(NUM_OF_ADDERS+1)..1] :NODE;
BEGIN
carry_out[1]=cin;
FOR i IN 1 TO NUM_OF_ADDERS GENERATE
c[i]=(a[i] $ b[i]) $ carry_out[i];
carry_out[i+1] = CARRY(a[i] & b[i] # carry_out[i] & (a[i] $ b[i]));
END GENERATE;
cout = carry_out[NUM_OF_ADDERS+1];
END;
Примітив CARRY явно вказує компілятору на необхідність використання схеми ланцюгового переносу логічного елемента НВІС сімейств FLEX. При розміщенні модуля в НВІС сімейств МАХ компілятор ігнорує примітив CARRY.
Результати моделювання модуля add_gate представлені на рис. 15.
Рис.3.15.
Розглянемо параметризований опис WIDTH-розрядного арифметичного пристрою.
Параметри:
WIDTH — розрядність,
Module_Type - тип пристрою (ADD - суматор, SUB - віднімач, ADD_SUB - сумматор-віднімач).
Виводи:
ADD_nSUB - вхід режиму роботи: 0 - віднімання; 1 - додавання. Даний вхід повинен бути використаний тільки в тому випадку, коли параметр Module_Type має значення ADD_SUB.
A[WIDTH..l], B[WIDTH..l] - входи даних, розрядність яких визначається значенням параметра WIDTH.
CLK - вхід тактових сигналів. Якщо цей вхід використовується, то на виході арифметичного пристрою буде розміщений N-розрядний регістр, що запам'ятовує вихідні дані по фронту тактового імпульсу.
Res[WIDTH..l] - вихід результату, розрядність якого визначається значенням параметра WIDTH. Якщо отриманий результат додатне число або нуль, то він поданий у прямому коді. Якщо ж він менше нуля, то для його подання використається доповняльний код.
Cout — вихід переносу. При реалізації віднімання даний вихід може служити знаковим розрядом результату: 0 — результат додатний, 1 — результат від’ємний.
Р – вхід переносу з попереднього розряду. Даний сигнал використовується при нарощуванні розрядності пристрою шляхом послідовного включення декількох пристроїв.
SUM[WIDTH..0] – сигнал, що знімається безпосередньо з виходу суматора-віднімача.
PARAMETERS
(
WIDTH = 7, Module_Type = "ADD_SUB"
);
ASSERT (WIDTH > 0)
REPORT "Width must be moro then %" WIDTH
SEVERITY ERROR;
ASSERT (Module_Type == "ADD_SUB") # (Module_Type == "ADD") # (Module_Type == "SUB")
REPORT "Module_Type can be ADD, SUB or ADD_SUB, but not %" Module_Type
SEVERITY ERROR;
SUBDESIGN ADD_BHV
(
A[WIDTH..0], B[WIDTH..0], ADD_nSUB, CLK: INPUT = GND;
P : INPUT;
RES[WIDTH..0], Cout, SUM[WIDTH..0]: OUTPUT;
)
VARIABLE
IF USED (CLK) GENERATE
RG[WIDTH+1..0] : DFF;
S[WIDTH..0] : NODE;
Cout_int : NODE;
Cout1_int[WIDTH..0] : NODE;
END GENERATE;
BEGIN
Cout1_int[] = GND;
ASSERT (Module_Type == "ADD_SUB") !$ USED (ADD_nSUB)
REPORT "Input ADD_nSUB can be used only with Module_Type = ADD_nSUB"
SEVERITY ERROR;
IF Module_Type == "ADD_SUB" GENERATE
IF ADD_nSUB == 1
THEN
(Cout_int, S[]) = (GND, A[]) + (GND, B[]) + (Cout1_int[], P);
ELSE
(Cout_int, S[]) = (GND, A[]) - (GND, B[]) - (Cout1_int[], P);
END IF;
END GENERATE;
IF Module_Type=="ADD" GENERATE
(Cout_int, S[]) = (GND, A[]) + (GND, B[]) + (Cout1_int[], P);
END GENERATE;
IF Module_Type=="SUB" GENERATE
(Cout_int, S[]) = (GND, A[]) - (GND, B[]) - (Cout1_int[], P);
END GENERATE;
IF USED (CLK) GENERATE
RG[].CLK = CLK;
RG[].D = (Cout_int, S[]);
(Cout, Res[]) = RG[].Q;
ELSE GENERATE
(Cout, Res[]) = (Cout_int, S[]);
END GENERATE;
SUM[] = S[];
END;
Для контролю правильності використання входу ADD_nSUB служить оператор:
ASSERT (Module_Type == "ADD_SUB") !$ USED (ADD_nSUB)
REPORT "Input ADD_nSUB can be used only with Module_Type = ADD_nSUB"
SEVERITY ERROR;
Контрольована оператором умова буде виконана якщо:
■ значення Module_Type дорівнює "ADD_SUB" і використовується вхід ADD_nSUB;
■ значення Module_Type не дорівнює "ADD SUB' і не використовується вхід ADD_nSUB.
Використання ж входу при інших значеннях параметра Module_Type веде до зупинки компіляції й появи повідомлення про помилку:
"Error; Line 30, File c:\max_work\prim_book2\add_bhv.dir\add_bhv.tdf:
INPUT ADD_nSUB CAN BE USED ONLY WITH Module_Type=ADD_SUB".
Оператори IF GENERATE дозволяють компіляторові:
інтерпретувати вихідний текстовий опис як опис арифметичного пристрою, тип якого заданий параметром Module_Type;
помістити на виході модуля WIDTH-розрядний синхронний регістр у тому випадку, якщо використовується вхід CLK модуля.
На рис. 16 наведено результати моделювання восьмирозрядного арифметичного пристрою типу «ADD_SUB» (суматор-віднімач) вихідні дані якого запам'ятовуються в регістрі по додатному перепаді (фронту) тактового сигналу CLK.
Рис. 16.
З наведених часових діаграм видно, що, оскільки результат виконуваної операції знімається з виходу комбінаційного пристрою (SUM[7..0]), то його поява відбувається через час, рівний часу затримки поширення сигналу в цьому пристрої. При цьому, оскільки значення різних розрядів з'являються на виході суматора не одночасно, то на виході суматора формується кілька помилкових кодів, тобто кінцевий результат формується не відразу.
Сигнал RES[7..1] знімається з виходу додаткового регістра, у який значення коду з виходу суматора SUM[7..0] переписується в тактові моменти часу, задані сигналом CLK. До моменту формування фронту сигналу CLK перехідний процес на виході суматора вже завершився й у регістр записується істинний результат виконаної операції.
