Главная страница
Навигация по странице:

  • Global Signal

  • Global Project Logic Synthesis

  • Учебник по языку 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
    страница17 из 18
    1   ...   10   11   12   13   14   15   16   17   18

    1.35.Реализация последовательностной логики


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

    1.35.1.Объявление регистров


    Регистры запоминают значения данных и синхронизируют их с помощью сигнала Clock. Вы можете объявить экземпляр регистра с помощью объявления Register в разделе Variable. ( Вы можете также реализовать регистр используя ссылки на функции в разделе Logic). AHDL предлагает несколько примитивов регистров, а также поддерживает регистровые LPM функции.

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

    <имя экземпляра>.<имя порта>

    Файл bur_reg.tdf, приведенный ниже, использует объявление Register для создания байтного регистра, который фиксирует значения входов d на переднем фронте Clock, когда вход загрузки высокий.
    SUBDESIGN bur_reg

    (

    clk, load, d[7..0] : INPUT;

    q[7..0] : OUTPUT;

    )

    VARIABLE

    ff[7..0] : DFFE;
    BEGIN

    ff[].clk = clk;

    ff[].ena = load;

    ff[].d = d[];

    q[] = ff[].q;

    END;
    Регистры объявляются в разделе Variable как DFFE(D триггер с сигналом разрешения). Первое булево уравнение в разделе Logic соединяет вход clk с портами Clock триггеров ff[7..0].

    Второе уравнение соединяет вход загрузки с портами разрешения тактовой частоты. Третье уравнение соединяет входы данных d[7..0] с входными портами триггеров ff[7..0]. И четвертое уравнение соединяет выходы с выходными портами триггеров. Все четыре уравнения оцениваются совместно.

    Вы можете также объявить T, JK, и SR триггеры в разделе Variable, а затем использовать в разделе Logic.

    Если Вы хотите загрузить регистр на определенном переднем фронте глобального сигнала Clock, Altera рекомендует использовать вход разрешения тактовой частоты одного из DFFE, TFFE, JKFFE, или SRFFE триггеров для управления загрузкой регистра.

    Файл lpm_reg.tdf, приведенный ниже, использует ссылку для реализации экземпляра функции lpm_dff, который обладает такой же функциональностью, как и файл bur_reg.tdf.
    INCLUDE "lpm_dff.inc";

    SUBDESIGN lpm_reg

    (

    clk, load, d[7..0] : INPUT;

    q[7..0] : OUTPUT;

    )

    BEGIN

    q[] = lpm_dff (.clock=clk, .enable=load, .data[]=d[])

    WITH (LPM_WIDTH=8)

    RETURNS (.q[]);

    END;

    1.35.2.Объявление регистровых выходов


    Вы можете объявить регистровые выходы TDF файла путем объявления выходных портов как триггеров в разделе Variable. Файл reg_out.tdf, приведенный ниже, имеет туже самую функциональность, что и файл bur_reg.tdf, но обладает регистровыми выходами.
    SUBDESIGN reg_out

    (

    clk, load, d[7..0] : INPUT;

    q[7..0] : OUTPUT;

    )

    VARIABLE

    q[7..0] : DFFE; % также объявлены как регистровые %

    BEGIN

    q[].clk = clk;

    q[].ena = load;

    q[] = d[];

    END;

    Когда Вы присваиваете значение регистровым выходам в разделе Logic, то значение с d входов направляется в регистр. Выходы регистра не изменяются до тех пор, пока не появится возрастающий фронт сигнала Clock. Для определения тактового входа регистра используйте конструкцию <имя регистра>.clk в разделе Logic. Вы можете реализовать глобальный тактовый сигнал Clock, используя примитив GLOBAL с помощью логической опции Global Signal в диалоговом окне Individual Logic Options, которое Вы можете открыть из окна Logic Options ( меню Assign), или с помощью опции Automatic Global Clock из диалогового окна Global Project Logic Synthesis( меню Assign).

    В файле, приведенном ниже, каждый DFFE триггер, объявленный в разделе Variable, запитывает выход с тем же именем, поэтому Вы можете обратиться к выходам q триггеров без использования порта q.

    В TDF файле высокого уровня выходные порты синхронизируются с выходными выводами. Когда Вы объявляете одинаковое имя для выходного порта и регистра, присваивания опций probe и logic применяются к выводу, а не регистру (за исключением логической опции Fast I/O). Поэтому, если Вы хотите протестировать регистр или использовать специфические для регистра логические опции, Вы должны по разному назвать регистры и порты.

    1.35.3.Создание счетчиков


    Счетчики можно определить с помощью D триггеров (DFF и DFFE) и операторов If Then или с помощью функции lpm_counter.

    Файл ahdlcnt.tdf, приведенный ниже, реализует 16-битный суммирующий счетчик с загрузкой, который можно сбросить в ноль.
    SUBDESIGN ahdlcnt

    (

    clk, load, ena, clr, d[15..0] : INPUT;

    q[15..0] : OUTPUT;

    )

    VARIABLE

    count[15..0] : DFF;

    BEGIN

    count[].clk = clk;

    count[].clrn = !clr;
    IF load THEN

    count[].d = d[];

    ELSIF ena THEN

    count[].d = count[].q + 1;

    ELSE

    count[].d = count[].q;

    END IF;
    q[] = count[];

    END;
    В этом файле в разделе Variable объявляется 16 триггеров с имена count0 по count15. Оператор If Then определяет значение, которое загружается в триггеры на возрастающем фронте Clock.

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

    SUBDESIGN lpm_cnt

    (

    clk, load, ena, clr, d[15..0] : INPUT;

    q[15..0] : OUTPUT;

    )

    VARIABLE

    my_cntr: lpm_counter WITH (LPM_WIDTH=16);
    BEGIN

    my_cntr.clock = clk;

    my_cntr.aload = load;

    my_cntr.cnt_en = ena;

    my_cntr.aclr = clr;

    my_cntr.data[] = d[];

    q[] = my_cntr.q[];

    END;

    1.35.4.Конечные автоматы


    В языке AHDL конечные автоматы реализуются также легко как таблицы истинности и булевы уравнения. Язык структурирован настолько, что Вы можете или сами присвоить значения состояниям или позволить компилятору MAX+PLUS II сделать эту работу за Вас.

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

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


    • назначит биты, выбирая или T или D триггер (TFF или DFF) для каждого бита

    • присвоит значения состояниям

    • применит сложную технику логического синтеза для получения уравнений возбуждения


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


    • объявление конечного автомата (раздел Variable)

    • булевы уравнения управления (раздел Logic)

    • переходы между состояниями в операторе Table или Case (раздел Logic)


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

    1.35.5.Реализация конечных автоматов


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

    Файл simple.tdf, приведенный ниже, обладает такой же функциональностью как D триггер (DFF).
    SUBDESIGN simple

    (

    clk, reset, d : INPUT;

    q : OUTPUT;

    )

    VARIABLE

    ss: MACHINE WITH STATES (s0, s1);
    BEGIN

    ss.clk = clk;

    ss.reset = reset;

    CASE ss IS

    WHEN s0 =>

    q = GND;
    IF d THEN

    ss = s1;

    END IF;

    WHEN s1 =>

    q = VCC;
    IF !d THEN

    ss = s0;

    END IF;

    END CASE;

    END;
    В файле simple.tdf конечный автомат с именем ss объявлен в разделе Variable. Состояния автомата определены как s0 и s1, а биты состояния не объявлены.

    Переходы конечного автомата определяют условия изменения к новому состоянию. Вы должны условно присвоить состояния в пределах одной поведенческой конструкции для определения переходов конечного автомата. Для этой цели рекомендуются операторы Case или Table. Например, в simple.tdf переходы из каждого состояния определяются в предложениях WHEN оператора Case.

    Вы можете также определить выходное значение для состояния с помощью оператора If Then или Case. В операторах Case эти присваивания выполняются в предложениях WHEN. Например, в simple.tdf выход q присваивается GND, когда конечный автомат ss находится в состоянии s0 и VCC, когда автомат находится в состоянии s1.

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

    1.35.6.Управление записью, сбросом и разрешением (Clock, Reset & Enable)


    Сигналы Clock, Reset, и Clock Enable управляют триггерами регистра состояний конечного автомата. Эти сигналы определяются с помощью булевых уравнений управления в разделе Logic.

    В файле simple.tdf, приведенном ниже, Clock конечного автомата управляется входом clk. Сигнал асинхронного сброса конечного автомата Reset управляется сигналом reset, который является активным высоким. В этом файле проекта объявление входа ena в разделе Subdesign и булева уравнения ss.ena = ena в разделе Logic подсоединяет сигнал Clock Enable.
    SUBDESIGN simple

    (

    clk, reset, ena, d : INPUT;

    q : OUTPUT;

    )

    VARIABLE

    ss: MACHINE WITH STATES (s0, s1);
    BEGIN

    ss.clk = clk;

    ss.reset = reset;

    ss.ena = ena;

    CASE ss IS

    WHEN s0 =>

    q = GND;
    IF d THEN

    ss = s1;

    END IF;

    WHEN s1 =>

    q = VCC;
    IF !d THEN

    ss = s0;

    END IF;

    END CASE;

    END;

    1.35.7.Присваивание состояний


    Бит состояния - это выход триггера, который используется конечным автоматом для запоминания однобитного значения. В большинстве случаев Вы должны разрешить компилятору MAX+PLUS II присвоить биты состояния и значения для минимизации требующихся логических ресурсов: логический синтезатор автоматически минимизирует количество необходимых битов состояния, оптимизируя как использование устройства так и производительность.

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

    Команда Global Project Logic Synthesis (меню Assign) включает опцию One-Hot State Machine Encoding (позиционное кодирование состояний), которая автоматически реализует этот тип кодирования для проекта. Кроме того, компилятор автоматически реализует позиционное кодирование для устройств FLEX 6000, FLEX 8000, и FLEX 10K, несмотря на то, включена или нет эта опция. Если Вы точно назначили биты состояния, в добавление к использованию автоматического позиционного кодирования, логика Вашего проекта может быть реализована неэффективно.
    Файл stepper.tdf, приведенный ниже, реализует контроллер шагового двигателя.
    SUBDESIGN stepper

    (

    clk, reset : INPUT;

    ccw, cw : INPUT;
    phase[3..0] : OUTPUT;

    )

    VARIABLE

    ss: MACHINE OF BITS (phase[3..0])

    WITH STATES (

    s0 = B"0001",

    s1 = B"0010",

    s2 = B"0100",

    s3 = B"1000");

    BEGIN

    ss.clk = clk;

    ss.reset = reset;

    TABLE

    ss, ccw, cw => ss;

    s0, 1, x => s3;

    s0, x, 1 => s1;

    s1, 1, x => s0;

    s1, x, 1 => s2;

    s2, 1, x => s1;

    s2, x, 1 => s3;

    s3, 1, x => s2;

    s3, x, 1 => s0;

    END TABLE;

    END;
    В этом примере выходы phase[3..0], объявленные в разделе Subdesign, также объявлены как биты конечного автомата ss в объявлении конечного автомата. Заметьте, что ccw и cw никогда не должны одновременно равняться 1 в одной и той же таблице. AHDL предполагает, что только одно условие в таблице истинности является истинным в одно и тоже время, следовательно, перекрытие комбинаций битов может привести к непредсказуемым результатам.

    1.35.8.Конечные автоматы с синхронными выходами


    Если выходы конечного автомата зависят только от состояний автомата, Вы можете определить его выходы в предложении WITH STATES объявления конечного автомата.

    Файл moore1.tdf, приведенный ниже, реализует автомат Мура на четыре состояния.
    SUBDESIGN moore1

    (

    clk : INPUT;

    reset : INPUT;

    y : INPUT;

    z : OUTPUT;

    )

    VARIABLE

    ss: MACHINE OF BITS (z)

    WITH STATES (s0 = 0,

    s1 = 1,

    s2 = 1,

    s3 = 0);

    BEGIN

    ss.clk = clk;

    ss.reset = reset;
    TABLE

    % текущее текущий следующее %

    % состояние вход состояние %

    ss, y => ss;
    s0, 0 => s0;

    s0, 1 => s2;

    s1, 0 => s0;

    s1, 1 => s2;

    s2, 0 => s2;

    s2, 1 => s3;

    s3, 0 => s3;

    s3, 1 => s1;

    END TABLE;

    END;
    Этот пример определяет состояния конечного автомата с помощью объявления конечного автомата. Переходы между состояниями определены в таблице переходов, которая реализована с помощью оператора Table. В этом примере автомат ss имеет 4 состояния, но только один бит состояния (z). Компилятор автоматически добавляет другой бит и создает соответствующие присваивания для синтезированной переменной для представления автомата на 4 состояния. Этот автомат требует не менее 2 битов.

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

    Другим способом проектирования конечного автомата с синхронными выходами является опускание присваиваний значений состояниям и точное объявление выходных триггеров. Файл moore2.tdf, приведенный ниже, иллюстрирует этот альтернативный метод.
    SUBDESIGN moore2

    (

    clk : INPUT;

    reset : INPUT;

    y : INPUT;

    z : OUTPUT;

    )

    VARIABLE

    ss: MACHINE WITH STATES (s0, s1, s2, s3);

    zd: NODE;

    BEGIN

    ss.clk = clk;

    ss.reset = reset;

    z = DFF(zd, clk, VCC, VCC);

    TABLE

    % состояние вход состояние выход %

    ss, y => ss, zd;
    s0, 0 => s0, 0;

    s0, 1 => s2, 1;

    s1, 0 => s0, 0;

    s1, 1 => s2, 1;

    s2, 0 => s2, 1;

    s2, 1 => s3, 0;

    s3, 0 => s3, 0;

    s3, 1 => s1, 1;

    END TABLE;

    END;
    Вместо определения выхода с помощью присваиваний значений состояниям в объявлении конечного автомата, этот пример включает столбец ‘‘ следующий выход ’’, после столбца ‘‘ следующее состояние ’’ в операторе Table. Этот метод использует D триггер (DFF), вызванный с помощью ссылки, для синхронизации выходов с тактовой частотой.

    1.35.9.Конечные автоматы с асинхронными выходами


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

    Файл mealy.tdf, приведенный ниже, реализует автомат Мили на 4 состояния с асинхронными выходами.
    SUBDESIGN mealy

    (

    clk : INPUT;

    reset : INPUT;

    y : INPUT;

    z : OUTPUT;

    )

    VARIABLE

    ss: MACHINE WITH STATES (s0, s1, s2, s3);

    BEGIN

    ss.clk = clk;

    ss.reset = reset;

    TABLE

    % состояние вход выход состояние %

    ss, y => z, ss;
    s0, 0 => 0, s0;

    s0, 1 => 1, s1;

    s1, 0 => 1, s1;

    s1, 1 => 0, s2;

    s2, 0 => 0, s2;

    s2, 1 => 1, s3;

    s3, 0 => 0, s3;

    s3, 1 => 1, s0;

    END TABLE;

    END;

    1.35.10.Выход из некорректных состояний


    Логика, созданная для конечного автомата компилятором MAX+PLUS II, будет вести себя так, как Вы описали в файле TDF. Тем не менее проекты конечных автоматов, которые точно объявляют биты состояния, и которые не используют позиционного кодирования, часто допускают значения битов состояния, которые не связаны с действительными состояниями. Эти не присвоенные значения называются не корректными состояниями. Проект, который вводит некорректные состояния, например, в результате нарушений времени предустановки и удержания, может приводить к неверным выходам. Хотя Altera рекомендует, чтобы входы конечного автомата удовлетворяли всем временным требованиям, Вы можете заставить конечный автомат принудительно вернуться из некорректного состояния в известное состояние с помощью оператора Case.

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

    Для n-битного конечного автомата, существует 2n возможных состояний. Если Вы объявили n бит Вы должны продолжать добавлять имена фиктивных состояний до тех пор, пока количество состояний не достигнет степени 2. Файл recover.tdf, приведенный ниже, содержит автомат, который может возвращаться из некорректных состояний.
    SUBDESIGN recover

    (

    clk : INPUT;

    go : INPUT;

    ok : OUTPUT;

    )

    VARIABLE

    sequence : MACHINE

    OF BITS (q[2..0])

    WITH STATES (

    idle,

    one,

    two,

    three,

    four,

    illegal1,

    illegal2,

    illegal3);
    BEGIN

    sequence.clk = clk;

    CASE sequence IS

    WHEN idle =>

    IF go THEN

    sequence = one;

    END IF;

    WHEN one =>

    sequence = two;

    WHEN two =>

    sequence = three;

    WHEN three =>

    sequence = four;

    WHEN OTHERS =>

    sequence = idle;

    END CASE;

    ok = (sequence == four);

    END;
    Этот пример содержит 3 бита: q2, q1, и q0. Следовательно существует 8 состояний. Так как объявлено только 5 состояний, были добавлены 3 фиктивных состояния.
    1   ...   10   11   12   13   14   15   16   17   18


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