Главная страница

Учебник по языку ahdl оглавление Введение 2 Элементы языка ahdl 3 Структура описания проекта на языке ahdl 25


Скачать 0.61 Mb.
НазваниеУчебник по языку ahdl оглавление Введение 2 Элементы языка ahdl 3 Структура описания проекта на языке ahdl 25
Дата28.04.2019
Размер0.61 Mb.
Формат файлаdoc
Имя файлаahdl.doc
ТипУчебник
#75494
страница16 из 18
1   ...   10   11   12   13   14   15   16   17   18

1.33.Управление логическим синтезом с помощью примитивов LCELL & SOFT


Вы можете ограничить размер (масштаб) логического синтеза путем изменения переменных NODE на SOFT и LCELL примитивы. NODE переменные и LCELL примитивы обеспечивают наибольшее управление всем логическим синтезом. SOFT примитивы не предусмотрены для управления всем логическим синтезом.

NODE переменные, объявленные с помощью объявления Node в разделе Variable налагают несколько ограничений на логический синтез. Во время синтеза логический синтезатор заменяет каждый экземпляр переменной NODE логикой, которая представляет переменную. Затем он минимизирует логику для подгонки в одну логическую ячейку. Обычно этот метод дает самую большую скорость, но может приводить к слишком сложной логике.

SOFT буферы обеспечивают больший контроль по использованию ресурсов, чем NODE переменные. Логический синтезатор выбирает, когда заместить экземпляры SOFT примитивов с помощью LCELL примитивов. SOFT буферы могут помочь в исключении слишком сложной логики и упрощении подгонки проекта, но могут увеличить использование логических ячеек и уменьшить быстродействие.

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

MAX+PLUS II обеспечивает несколько логических опций, которые автоматически вставляют или удаляют SOFT и LCELL буферы в соответствующих местах проекта.

Следующая иллюстрация демонстрирует два варианта TDF файла: один реализуется с помощью NODE переменных, а другой с SOFT примитивами. В nodevar переменная odd_parity объявлена как NODE и затем ей присвоено значение булева выражения d0 $ d1 $ ... $ d8. В softbuf компилятор замещает некоторые SOFT примитивы на LCELL примитивы во время обработки для улучшения использования устройства.
TDF с NODE переменными: TDF с SOFT примитивами:
SUBDESIGN nodevar SUBDESIGN softbuf

( (

) )

VARIABLE VARIABLE

odd_parity : NODE; odd_parity : NODE;

BEGIN BEGIN

odd_parity = odd_parity =

d0 $ d1 $ d2$ SOFT(d0 $ d1 $ d2) $

d3 $ d4 $ d5$ SOFT(d3 $ d4 $ d5) $

d6 $ d7 $ d8; SOFT(d6 $ d7 $ d8);

END; END;

1.34.Реализация комбинационной логики


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

1.34.1.Реализация логических выражений и уравнений


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

Файл boole1.tdf, приведенный ниже, демонстрирует два простых булевых выражения, представляющие два логических вентиля.

SUBDESIGN boole1

(

a0, a1, b : INPUT;

out1, out2 : OUTPUT;

)

BEGIN

out1 = a1 & !a0;

out2 = out1 # b;

END;
В этом файле выход out1 является логическим И входов а1 и инверсии а0, а выход out2 логическим ИЛИ out1 и b. Порядок следования их в файле не важен.

1.34.2.Именование логических операторов и компараторов


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

Файл boole3.tdf, приведенный ниже, идентичен с файлом boole1.tdf, но использует именованные операторы. Имя оператора отделяется от оператора знаком двоеточия; имя может содержать до 32 символов.
SUBDESIGN boole3

(

a0, a1, b : INPUT;

out1, out2 : OUTPUT;

)

BEGIN

out1 = a1 tiger:& !a0;

out2 = out1 panther:# b;

END;
Следующие отрывки из файла отчета показывают различие между boole3.rpt и boole1.rpt для первых двух уравнений.
-- boole3.rpt equations:

-- Node name is 'out1' from file "boole3.tdf" line 7, col 2

-- Equation name is 'out1', location is LC3_A1, type is output

out1 = tiger0;
-- Node name is 'tiger0' from file "boole3.tdf" line 7, column 18

-- Equation name is 'tiger0', location is LC2_A1, type is buried

tiger0 = LCELL( _EQ002);

_EQ002 = !a0 & a1;
-- boole1.rpt equations:

-- Node name is 'out1' from file "boole1.tdf" line 7, col 2

-- Equation name is 'out1', location is LC3_A1, type is output

out1 = _LC2_A1;
-- Node name is ':33' from file "boole1.tdf" line 7, col 12

-- Equation name is '_LC2_A1', type is buried
LC2_A1 = LCELL( _EQ001);

_EQ001 = !a0 & a1;
В зависимости от логики уравнения именованный оператор может представлять несколько имен узлов, однако, все имена относятся к имени оператора и, поэтому, узлы легче распознаются в файле отчета. В файле boole3.rpt единственный узел, tiger0, создается для первого уравнения. В файле boole1.tdf компилятор связывает цепь ID :33 с тем же самым узлом.

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

1.34.3.Использование узлов


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

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

Файл boole2.tdf, приведенный ниже, содержит ту же самую логику что и файл boole1.tdf, но имеет только один выход.
SUBDESIGN boole2

(

a0, a1, b : INPUT;

out : OUTPUT;

)

VARIABLE

a_equals_2 : NODE;

BEGIN

a_equals_2 = a1 & !a0;

out = a_equals_2 # b;

END;
Этот файл объявляет узел a_equals_2 и связывает его с выражением a1 & !a0. При использовании узлов можно сохранять ресурсы устройства, когда узел используется в нескольких выражениях.

Можно использовать как обычные узлы (NODE), так и тристабильные узлы (TRI_STATE_NODE). NODE и TRI_STATE_NODE различаются в том, что несколько присваиваний на них дают различные результаты.

Присваивания на узлы типа NODE связывают сигналы вместе с помощью функций ПРОВОДНОЕ-И или ПРОВОДНОЕ-ИЛИ. Значения по умолчанию, объявленные в операторах Defaults, определяют поведение: VCC представляет функцию ПРОВОДНОЕ-И, а GND представляет функцию ПРОВОДНОЕ-ИЛИ.

Присваивания на TRI_STATE_NODE привязывают сигналы к одному и тому же узлу.

Если только одной переменной назначается тип TRI_STATE_NODE, то она трактуется как NODE.

1.34.4.Использование шин


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

В булевых уравнениях шина может приравниваться булеву выражению, другой шине, единственному узлу, VCC, GND, 1 или 0. В каждом из этих случаев значение шины различно. Оператор Options можно использовать для определения того, каким будет самый младший бит: наиболее значимым битом(MSB) или наименее значимым битом(LSB) или каким-либо другим.

Как только шина определена, скобки [ ] являются коротким способом определения всего диапазона. Например, a[4..1] можно также указать как a[]; b[5..4][3..2] можно представить как b[][].

Файл group1.tdf, приведенный ниже, демонстрирует булевы выражения, которые определяют несколько шин.
OPTIONS BIT0 = MSB;

CONSTANT MAX_WIDTH = 1+2+3-3-1;

% MAX_WIDTH = 2 %

SUBDESIGN group1

(

a[1..2], use_exp_in[1+2-2..MAX_WIDTH] : INPUT;

d[1..2],use_exp_out[1+2*2-4..MAX_WIDTH] : OUTPUT;

dual_range[5..4][3..2] : OUTPUT;

)

BEGIN

d[] = a[] + B"10";

use_exp_out[] = use_exp_in[];

dual_range[][] = VCC;

END;
В этом примере оператор Options используется для определения того, что самый правый бит шины будет MSB, а десятичная 1 прибавляется к шине a[]. Если ко входу a[] прикладывается 00, то результатом этой программы будет d[] == 1. Шины use_exp_in[] и use_exp_out[] показывают как константы и арифметические выражения можно использовать для ограничения диапазонов шин.

Следующие примеры иллюстрируют использование шин:

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

  • Когда шина приравнивается к VCC или GND, все биты шины соединяются с этим значением.

  • Когда шина приравнивается к 1, только наименее значимый бит шины соединяется со значением VCC. Остальные биты шины соединяются с GND.

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


a[4..1] = b[2..1] правильно.
В этом уравнении биты отображаются следующим образом:
a4 = b2

a3 = b1

a2 = b2

a1 = b1

1.34.5.Реализация условной логики


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

Условную логику, реализуемую с помощью операторов If Then и Case, не следует путать с логикой, создаваемой условно оператором If Generate. Эта логика не обязательно является условной.

1.34.5.1.1.Оператор If Then


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

(

low, middle, high : INPUT;

highest_level[1..0] : OUTPUT;

)

BEGIN

IF high THEN

highest_level[] = 3;

ELSIF middle THEN

highest_level[] = 2;

ELSIF low THEN

highest_level[] = 1;

ELSE

highest_level[] = 0;

END IF;

END;
В этом примере входы high, middle, и low оцениваются для определения того, является ли их уровни равными VCC. Оператор If Then активизирует уравнения, которые следуют за активной IF или ELSE областями и, если вход high высокий, то highest_level[] равен 3.

Если активизируется более одного входа, то оператор If Then оценивает приоритет входов в порядке следования областей IF и ELSIF ( первая область имеет наивысший приоритет).

Если ни один из входов не активизирован, по срабатывает уравнение, следующие за ключевым словом ELSE.

1.34.5.2.1.Оператор Case


Файл decoder.tdf, приведенный ниже, описывает дешифратор 2 в 4 бита. Он преобразует 2-битный код в унарный код.
SUBDESIGN decoder

(

code[1..0] : INPUT;

out[3..0] : OUTPUT;

)

BEGIN

CASE code[] IS

WHEN 0 => out[] = B"0001";

WHEN 1 => out[] = B"0010";

WHEN 2 => out[] = B"0100";

WHEN 3 => out[] = B"1000";

END CASE;

END;
В этом примере входной код шины имеет значения 0, 1, 2 или 3. В операторе Case за символом => следует активизируемое уравнение. Например, если code[] равен 1, то выход out1 устанавливается в B"0010". Поскольку все значения выражения различны, в одно время можно активизировать только одну область WHEN

1.34.5.3.1.Оператор If Then против оператора Case


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

Но между ними существует важное различие:


  • В операторе If Then можно использовать любые виды булевых выражений. Каждое выражение, следующее за IF или ELSIF областями, может быть несвязанно с другими выражениями в операторе. В операторе Case, напротив, только одно булево выражение сравнивается с константой в каждой WHEN области.

  • Использование ELSIF предложения может привести к логике, которая слишком сложна для компилятора, так как каждое следующее друг за другом предложение ELSIF должно еще проверять, ложность предыдущих IF/ELSIF предложений. Следующий пример показывает как компилятор интерпретирует оператор If Then. Если a и b сложные выражения, тогда инверсия этих выражений даст, возможно, даже более сложные выражения.


Оператор If Then Интерпретация компилятора
IF a THEN IF a THEN

c = d; c = d;

END IF;
ELSIF b THEN IF !a & b THEN

c = e; c = e;

END IF;
ELSE IF !a & !b THEN

c = f; c = f;

END IF; END IF;

1.34.6.Создание дешифраторов


В AHDL для создания дешифратора Вы можете использовать или оператор Truth Table или lpm_compare или lpm_decode функции.

Файл 7segment.tdf, приведенный ниже, является дешифратором для комбинации светоизлучающих диодов (LED). LED отображают шестнадцатеричные числа.
SUBDESIGN 7segment

(

i[3..0] : INPUT;

a, b, c, d, e, f, g : OUTPUT;

)

BEGIN

TABLE

i[3..0] => a, b, c, d, e, f, g;
H"0" => 1, 1, 1, 1, 1, 1, 0;

H"1" => 0, 1, 1, 0, 0, 0, 0;

H"2" => 1, 1, 0, 1, 1, 0, 1;

H"3" => 1, 1, 1, 1, 0, 0, 1;

H"4" => 0, 1, 1, 0, 0, 1, 1;

H"5" => 1, 0, 1, 1, 0, 1, 1;

H"6" => 1, 0, 1, 1, 1, 1, 1;

H"7" => 1, 1, 1, 0, 0, 0, 0;

H"8" => 1, 1, 1, 1, 1, 1, 1;

H"9" => 1, 1, 1, 1, 0, 1, 1;

H"A" => 1, 1, 1, 0, 1, 1, 1;

H"B" => 0, 0, 1, 1, 1, 1, 1;

H"C" => 1, 0, 0, 1, 1, 1, 0;

H"D" => 0, 1, 1, 1, 1, 0, 1;

H"E" => 1, 0, 0, 1, 1, 1, 1;

H"F" => 1, 0, 0, 0, 1, 1, 1;

END TABLE;

END;
В этом примере выходной набор для всех 16 возможных входных наборов i[3..0] описан в операторе Truth Table

Файл decode3.tdf, приведенный ниже, является дешифратором адреса для реализации 16-битной микропроцессорной системы.
SUBDESIGN decode3

(

addr[15..0], m/io : INPUT;

rom, ram, print, sp[2..1] : OUTPUT;

)

BEGIN

TABLE

m/io, addr[15..0] => rom, ram, print, sp[];

1, B"00XXXXXXXXXXXXXX" => 1, 0, 0, B"00";

1, B"100XXXXXXXXXXXXX" => 0, 1, 0, B"00";

0, B"0000001010101110" => 0, 0, 1, B"00";

0, B"0000001011011110" => 0, 0, 0, B"01";

0, B"0000001101110000" => 0, 0, 0, B"10";
END TABLE;

END;
В этом примере существуют тысячи входных наборов и описывать их все в операторе Truth Table непрактично. Вместо этого Вы можете использовать логический уровень Х для указания того, что выход не зависит от соответствующего входа. Например, в первой строчке оператора TABLE выход rom должен быть высоким для всех 16,384 входных наборов addr[15..0], начинающихся с 00. Следовательно Вам необходимо точно определить только общую часть входного набора, а для остальных входов использовать символ Х.

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

Файл decode4.tdf, приведенный ниже, использует функцию lpm_decode для получения такой же функциональности как и файл decode1.tdf.
INCLUDE "lpm_decode.inc";
SUBDESIGN decode4

(

address[15..0] : INPUT;

chip_enable : OUTPUT;

)

BEGIN

chip_enable = lpm_decode(.data[]=address[])

WITH (LPM_WIDTH=16, LPM_DECODES=2^10)

RETURNS (.eq[H"0370"]);

END;

1.34.7.Использование значений переменных по умолчанию


Вы можете определить значение по умолчанию для узла или шины, который используете, когда его величина не указана где-нибудь в другом месте файла. AHDL позволяет Вам также присваивать значение узлу или шине более одного раза в одном файле. Если эти присваивания конфликтуют, то значение по умолчанию используется для разрешения конфликтов. При отсутствии определения значения по умолчанию ему присваивается значение GND.

Значение по умолчанию определяется с помощью оператора Defaults для переменных, использующихся в операторах Truth Table, If Then, и Case.

Вы не должны путать значения по умолчанию для переменных со значениями по умолчанию для портов, которые присваиваются в разделе Subdesign.

Файл default1.tdf, приведенный ниже, оценивает входы и выбирает один из пяти ASCII кодов, основываясь на входах.
SUBDESIGN default1

(

i[3..0] : INPUT;

ascii_code[7..0] : OUTPUT;

)

BEGIN

DEFAULTS

ascii_code[] = B"00111111"; % ASCII код "?" %

END DEFAULTS;
TABLE

i[3..0] => ascii_code[];

B"1000" => B"01100001"; % "a" %

B"0100" => B"01100010"; % "b" %

B"0010" => B"01100011"; % "c" %

B"0001" => B"01100100"; % "d" %

END TABLE;

END;
Когда входной набор совпадает с одним из наборов, приведенным с левой стороны оператора Truth Table, выходы устанавливаются в соответствии с комбинацией справа. Если совпадения не происходит, выходы принимают значения по умолчанию B"00111111".

Файл default2.tdf, приведенный ниже, иллюстрирует как возникают конфликты, когда одному узлу присваивается более одного значения и как эти конфликты разрешаются языком AHDL.
SUBDESIGN default2

(

a, b, c : INPUT;

select_a, select_b, select_c : INPUT;

wire_or, wire_and : OUTPUT;

)

BEGIN

DEFAULTS

wire_or = GND;

wire_and = VCC;

END DEFAULTS;
IF select_a THEN

wire_or = a;

wire_and = a;

END IF;
IF select_b THEN

wire_or = b;

wire_and = b;

END IF;
IF select_c THEN

wire_or = c;

wire_and = c;

END IF;

END;
В этом примере wire_or присваиваются значения a, b, или c, в зависимости от значений сигналов select_a, select_b, и select_c. Если ни один из этих сигналов не равен VCC, тогда wire_or принимает значение GND.

Если больше одного из сигналов select_a, select_b, или select_c принимают значение VCC, тогда сигнал wire_or является логическим ИЛИ соответствующих входных значений .

Сигнал wire_and работает таким же образом, за исключением того, что по умолчанию он устанавливается в VCC, когда ни один из "select" сигналов не равен VCC и равен логическому И соответствующих входов, когда более одно сигнала принимает значение VCC.

1.34.8.Реализация логики с активными низкими уровнями


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

Файл daisy.tdf, приведенный ниже, является модулем схемы арбитра по методу дейзи-цепочки. Он принимает запросы на доступ к шине от самого себя и от следующего модуля в цепочке. Доступ к шине предоставляется модулю с наивысшим приоритетом, запросившим его.
SUBDESIGN daisy

(

/local_request : INPUT;

/local_grant : OUTPUT;

/request_in : INPUT; % от младшего приоритета %

/request_out : OUTPUT; % к старшему приоритету %

/grant_in : INPUT; % от старшего приоритета %

/grant_out : OUTPUT;% к младшему приоритету %

)

BEGIN

DEFAULTS

/local_grant = VCC;% активные низкие выходы %

/request_out=VCC;

%должны быть равны по умолчанию %

/grant_out = VCC; % VCC %

END DEFAULTS;

IF /request_in == GND # /local_request == GND THEN

/request_out = GND;

END IF;
IF /grant_in == GND THEN

IF /local_request == GND THEN

/local_grant = GND;

ELSIF /request_in == GND THEN

/grant_out = GND;

END IF;

END IF;

END;

Все сигналы в этом файле активные низкие. Altera рекомендует, чтобы Вы выбирали схему именования узлов, ясно указывающую имена активных низких сигналов, например, начальное "n" или слеш (/).

Операторы If Then используются для определения активности модулей, т.е. равен ли сигнал GND. Если сигнал активный, то активизируются уравнения, следующие за соответствующим оператором If Then.

1.34.9.Реализация двунаправленных выводов


MAX+PLUS II позволяет конфигурировать выводы I/O как двунаправленные. Двунаправленные выводы можно определить с помощью порта BIDIR, который соединяется с выходом примитива TRI. Сигнал между выводом и примитивом TRI является двунаправленным и может использоваться для управления другой логикой проекта.

Файлы bus_reg2.tdf и bus_reg3.tdf, приведенные ниже, оба реализуют регистр, который фиксирует значение, обнаруженное на тристабильной шине. Также они могут выдавать запомненное значение обратно на шину. Один файл реализует DFF и TRI функции с помощью ссылок на логические функции. Другой файл использует объявления Register и Instance, соответственно, в разделе Variable.
SUBDESIGN bus_reg2 SUBDESIGN bus_reg3

( (

clk : INPUT; clk : INPUT;

oe : INPUT; oe : INPUT;

io : BIDIR; io : BIDIR;

) )

VARIABLE VARIABLE

dff_out : NODE; my_dff : DFF;

my_tri : TRI;

BEGIN BEGIN
dff_out = DFF(io, clk, ,); my_dff.d = io;

io = TRI(dff_out, oe); my_dff.clk = clk;

my_tri.in = my_dff.q;

END; my_tri.oe = oe;

io = my_tri.out;
END;
Двунаправленный сигнал io, управляемый примитивом TRI, используется в качестве входа d триггера D (DFF).
Также Вы можете присоединить двунаправленный вывод из TDF файла нижнего уровня к выводу верхнего уровня. Двунаправленный выходной порт подпроекта должен соединяться с двунаправленным выводом с верхнего уровня иерархии. Прототип Function для TDF файла нижнего уровня должен включать двунаправленный вывод в предложении RETURNS. Файл bidir1.tdf, приведенный ниже, включает четыре экземпляра функции bus_reg2, упомянутой выше.
FUNCTION bus_reg2 (clk, oe)

RETURNS (io);
SUBDESIGN bidir1

(

clk, oe : INPUT;

io[3..0] : BIDIR;

)

BEGIN

io0 = bus_reg2(clk, oe);

io1 = bus_reg2(clk, oe);

io2 = bus_reg2(clk, oe);

io3 = bus_reg2(clk, oe);

END;

1.34.10.Реализация тристабильных шин


Примитивы TRI, которые управляют портами OUTPUT или BIDIR, имеют вход разрешения выхода (Output Enable), который переводит выход в высокоимпедансное состояние.

Вы можете создать тристабильную шину путем соединения примитивов TRI и портов OUTPUT или BIDIR вместе с помощью узла TRI_STATE_NODE типа. Схема управления должна обеспечивать разрешение не более одного выхода в одно и тоже время.

Файл tri_bus.tdf, приведенный ниже, реализует тристабильную шину, используя узел TRI_STATE_NODE типа, созданный в объявлении Node.
SUBDESIGN tri_bus

(

in[3..1], oe[3..1] : INPUT;

out1 : OUTPUT;

)
VARIABLE

tnode : TRI_STATE_NODE;

BEGIN

tnode = TRI(in1, oe1);

tnode = TRI(in2, oe2);

tnode = TRI(in3, oe3);

out1 = tnode;

END;
В этом примере несколько присваиваний узлу tnode, связывают сигналы вместе. Для реализации тристабильной шины требуется тип TRI_STATE_NODE, вместо типа NODE: для типа NODE сигналы связываются вместе с помощью проводного И или проводного ИЛИ, тогда как для типа TRI_STATE_NODE сигналы соединяются с тем же самым узлом. Однако, если только одна переменная присваивается узлу TRI_STATE_NODE, то она трактуется как переменная обычного типа NODE.
1   ...   10   11   12   13   14   15   16   17   18


написать администратору сайта