Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм»




НазваниеМетодические указания к выполнению курсовых работ по курсу «Схемотехника эвм»
страница4/7
Дата конвертации26.10.2012
Размер1.1 Mb.
ТипМетодические указания
1   2   3   4   5   6   7
AHDL

AHDL (язык описания аппаратуры фирмы Altera) является высокоуровневым, модульным языком, полностью интегрированным в систему MAX+PLUS II. Он особенно хорошо подходит для проектирования сложной комбинационной логики, шин, конечных автоматов, таблиц истинности и параметрической логики.

Операторы и элементы AHDL являются мощным, многогранным и легким в использовании средством.

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

Зарезервированные ключевые слова отличаются от зарезервированных идентификаторов тем, что ключевые слова можно использовать как символьные имена при заключении их в одиночные кавычки ('), в то время как зарезервированные идентификаторы нельзя. Как те так и другие можно свободно использовать в комментариях.

Желательно вводить все ключевые слова с заглавных букв для удобства чтения.

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

_ (подчеркивание) - идентификаторы, описанные пользователем и используемые как допустимые символы в символьных именах;

- (тире);

/ (прямой слеш);

-- (два тире) - начинает однострочный комментарий в VHDL стиле;

% (процент) - ограничивает комментарий в AHDL стиле;

( ) (круглые скобки) - ограничивают и определяют последовательные имена шин.

[ ] (скобки) - ограничивают диапазон шины;

'...' (кавычки) - ограничивают символьные имена;

"..." (двойные кавычки) - ограничивают строки в операторах Title, Parameters, Assert.

. (точка) - Оотделяет символьные имена переменных логической функции от имен портов;

.. (эллипс) - отделяет старший бит от младшего;

; (точка с запятой) - канчивает операторы и разделы AHDL;

, (запятая) - отделяет символьные имена от типов в объявлениях;

= (равно) - присваивает входам значения по умолчанию GND и VCC в разделе Subdesign.

=> (стрелка) - отделяет входы от выходов в операторах Truth Table;

+ (плюс) - оператор сложения;

- (минус) - оператор вычитания;

== (два знака равенства) – оператор эквивалентности строк или чисел;

! (восклицательный знак) - оператор НЕ;

!= (знак восклицание равно) - оператор неравенства;

> (больше чем) - компаратор больше чем;

>= (больше или равно) - компаратор больше чем или равно;

< (меньше чем) - компаратор меньше чем;

<= (меньше или равно) - компаратор меньше чем или равно;

& (амперсант) - оператор И;

!& (восклицание амперсант) - оператор И-НЕ;

$ (знак доллара) - оператор исключающее – ИЛИ;

!$ (восклицание доллар) - оператор исключающее - ИЛИ - НЕ

# (знак фунта) - оператор ИЛИ;

!# (восклицание фунт) - оператор ИЛИ-НЕ;

? (вопрос) - тернарный оператор. Он использует следующий формат:

<выражение 1> ? < выражение 2> : < выражение 3>

Если первое выражение не ноль (истина), то вычисляется второе выражение и результат возвращается тернарному выражению. В противном случае возвращается значение третьего выражения.

В AHDL существует три типа имен:

  • символьные имена являются идентификаторами, описываемыми пользователем.

  • имена подпроектов - это имена, которые пользователь определил для файлов проекта более низкого уровня.

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

Компилятор генерирует имена содержащие символ тильда (~).

Для трех типов имен доступны два вида представления: с использованием кавычек и без них. Строковые имена заключаются в одиночные кавычки ('), а символьные имена без них.

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

Шина, которая может содержать до 256 членов (или битов), рассматривается как коллекция узлов и действует как одно целое.

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

Порт - это вход или выход логической функции. Порт может находится в двух местах:

• Порт, который является входом или выходом текущего файла, объявляется в разделе Subdesign.

• Порт, который является входом или выходом экземпляра примитива или файла разработки более низкого уровня, используется в разделе Logic.

Порты текущего файла

Порт, который является входом или выходом текущего файла объявляется в следующем формате в разделе Subdesign:

<имя порта>: <тип порта> [ = <значение по умолчанию> ]

Доступны следующие типы портов:

INPUT MACHINE INPUT

OUTPUT MACHINE OUTPUT

BIDIR

Необязательный раздел Variable используется для описания и/или генерации переменных, используемых в разделе Logic. Переменные языка AHDL сходны с переменными, используемыми в языках высокого уровня; они используются для определения внутренней логики.

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

При необходимости реализации объекта мега- или макрофункции надо убедиться в существовании соответствующего ей файла с описанием ее логического функционирования. Затем используется оператор Function Prototype для описания портов и параметров функции и производится реализация функции посредством подставляемой ссылки или объявления объекта.

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

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

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

AHDL поддерживает два типа узлов : NODE и TRI_STATE_NODE.

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

Объявление регистров используется для определения регистров, включая D, T, JK и SR триггеры (DFF, DFFE, TFF, TFFE, JKFF, JKFFE, SRFF и SRFFE) и защелки (LATCH). Следующий пример демонстрирует описание регистра:

VARIABLE

ff : TFF;

Именем объекта, представляющего собой Т - триггер, является ff. После данного объявления можно использовать входной и выходной порты объекта ff с использованием следующего формата:

ff.t

ff.clk

ff.clrn

ff.prn

ff.q

Поскольку все примитивы имеют только один выход можно использовать имя примитива без указания имени его выходного порта (например, без .q или .out) в правой части выражений. Аналогично, если примитив имеет лишь один вход (т.е. все примитивы за исключением примитивов JKFF, JKFFE, SRFF и SRFFE), то можно использовать имя примитива без указания имени его входного порта в левой части выражений (т.е., без .d, .t или .in).

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

Раздел Logic определяет логическое функционирование текстового файла проекта (TDF) и является собственно его телом.

Раздел Logic заключается в ключевые слова BEGIN и END. За ключевым словом END следует символ (;), заканчивающий раздел. Если используется оператор Defaults, то он должен предшествовать всем другим операторам в этом разделе.

AHDL является параллельным языком. Компилятор анализирует поведенческую модель, описанную в разделе Logic, параллельно. Выражения, осуществляющие множественные присваивания объекту, имеющему тип NODE или переменной, объединяются в соответствии с функцией монтажное ИЛИ.

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

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

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




Рис. 7. Функциональная схема устройства для работы с ЖКИ на языке AHDL

CONSTANT str_high = X"20312032203320342035203620372038203920313020313120313220313320313420313520313620";

CONSTANT str_low = X"205045A3A54D203C544543543E205045A3A54D203C544543543E205045A3A54D203C544543543E20";


SUBDESIGN lcd_main_ahdl

(

CLK : INPUT; -- входной тактовый сигнал я частотой 40 МГц и периодом 25нс

SBUSY : INPUT; -- сигнал занятости подчиненного устройства

STR[319..0] : OUTPUT; -- строка для вывода значений пересылаемого символа,для записи во внутренний регистр хранения

REFRESH : OUTPUT; -- обновление строки в LCD DRAM

INSTR[7..0] : OUTPUT; -- инструкция LCD контроллеру

DELAY[27..0] : OUTPUT; -- задержка между инструкциями

ONE_CYCLE : OUTPUT; -- (1) 4-битная или (0) 8-битная команда (данные)

WRITE_COMMAND : OUTPUT; -- запуск процесса загрузки команды в LCD

LCD_STATE_OUT : OUTPUT; -- номер состояния переключающего устройства

LED[7..0] : OUTPUT; -- номер состояния переключающегося устройства между инициализируемым и рабочим автоматами

)


VARIABLE

lcd_state : MACHINE OF BITS(lcd_state_reg[4..0]) WITH STATES(s0 = X"00", s1 = X"01", s2 = X"02", s3 = X"03", s4 = X"04", s5 = X"05", s6 = X"06", s7 = X"07", s8 = X"08", s9 = X"09", s10 = X"0A", s11 = X"0B", s12 = X"0C", s13 = X"0D", s14 = X"0E", s15 = X"0F",

s16 = X"10", s17 = X"11", s18 = X"12", s19 = X"13", s20 = X"14", s21 = X"15", s22 = X"16", s23 = X"17", s24 = X"18", s25 = X"19", s26 = X"1A", s27 = X"1B", s28 = X"1C", s29 = X"1D", s30 = X"1E", s31 = X"1F"); -- номер состояния переключающего устройства


STR[319..0] : DFF; -- строка для вывода на LCD

REFRESH : DFF; -- обновление строки в LCD DRAM

INSTR[7..0] : DFF; -- инструкция LCD контроллеру

DELAY[27..0] : DFF; -- задержка между инструкциями

ONE_CYCLE : DFF; -- (1) 4-битная или (0) 8-битная команда (данные)

WRITE_COMMAND : DFF; -- запуск процесса загрузки команды в LCD

LED[7..0] : DFF; -- регистр для хранения данных для вывода на светодиоды

position_flag : DFF; -- регистр для временного хранения состояний автомата

char_cnt[5..0] : DFF; -- переменная состояния автомата выбора и загрузки исходной строки

str_tmp[319..0] : DFF; -- регистр строки значений пересылаемого символа

char_tmp[7..0] : DFF; -- переменная состояния автомата выбора и загрузки исходной строки

BEGIN


STR[].clk = CLK;

REFRESH.clk = CLK;

INSTR[].clk = CLK;

DELAY[].clk = CLK;

ONE_CYCLE.clk = CLK;

WRITE_COMMAND.clk = CLK;

LED[].clk = CLK;


position_flag.clk = CLK;

char_cnt[].clk = CLK;

char_tmp[].clk = CLK;

str_tmp[].clk = CLK;

lcd_state.clk = CLK;


LCD_STATE_OUT = NOT SBUSY;

LED[4..0] = NOT lcd_state_reg[];

LED[5] = NOT WRITE_COMMAND;

LED[6] = NOT REFRESH;

LED[7] = NOT REFRESH;

CASE lcd_state IS

-- Инициализация дисплея

WHEN s0 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s1;

END IF;

WHEN s1 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s2;

END IF;

WHEN s2 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s3;

END IF;

WHEN s3 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s4;

END IF;

WHEN s4 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s5;

END IF;

WHEN s5 =>

INSTR[] = B"00110000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s6;

END IF;

-- Переключение в 4-битный режим

WHEN s6 =>

INSTR[] = B"00100000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s7;

END IF;

WHEN s7 =>

INSTR[] = B"00100000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"1";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s8;

END IF;

-- Определение количеств строк(2) и шрифта дисплея(5х8 точек)

WHEN s8 =>

INSTR[] = B"00101000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s9;

END IF;

WHEN s9 =>

INSTR[] = B"00101000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s10;

END IF;

-- Включение дисплея, выключение курсора и его мигание

WHEN s10 =>

INSTR[] = B"00001100";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s11;

END IF;

WHEN s11 =>

INSTR[] = B"00001100";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s12;

END IF;

-- Очищение дисплея

WHEN s12 =>

INSTR[] = B"00000001";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s13;

END IF;

WHEN s13 =>

INSTR[] = B"00000001";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s14;

END IF;

-- выбор режима сдвига курсора вправо при записи в(чтении из) DDRAM

WHEN s14 =>

INSTR[] = B"00000110";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s15;

END IF;

WHEN s15 =>

INSTR[] = B"00000110";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

-- инициализация регистров значениями по умолчанию

char_cnt[] = X"0";

str_tmp[] = str_low;

lcd_state = s16;

END IF;

-- Выполнение основных функций устройства

-- Смещение указателя памяти DDRAM на верхнюю строку

WHEN s16 =>

INSTR[] = B"10000000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s17;

END IF;

WHEN s17 =>

INSTR[] = B"10000000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s18;

END IF;

-- Пересылка верхней строки через блок lcd_DRAM в память LCD контроллера

WHEN s18 =>

INSTR[] = X"00";

STR[] = str_high;

REFRESH = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s19;

END IF;

WHEN s19 =>

INSTR [] = X"00";

STR[] = str_high;

REFRESH = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s20;

END IF;

-- Смещение указателя памяти DDRAM на нижнюю строку

WHEN s20 =>

INSTR[] = B"11000000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s21;

END IF;

WHEN s21 =>

INSTR[] = B"11000000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s22;

END IF;

-- Пересылка нижней строки через блок lcd_DRAM в память LCD контроллера

WHEN s22 =>

INSTR[] = X"00";

STR[] = str_low;

REFRESH = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s23;

END IF;

WHEN s23 =>

INSTR[] = X"00";

STR[] = str_low;

REFRESH = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s24;

END IF;

-- Постоянное смещение окна вправо

WHEN s24 =>

INSTR[] = B"00011000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"1";

IF (SBUSY == B"1") THEN

lcd_state = s25;

END IF;

WHEN s25 =>

INSTR[] = B"00011000";

DELAY[] = X"2625A00";

ONE_CYCLE = B"0";

WRITE_COMMAND = B"0";

IF (SBUSY == B"0") THEN

lcd_state = s24;

END IF;

END CASE;

END;


--CONSTANT con_str_high = X"20312032203320342035203620372038203920313020313120313220313320313420313520313620";

--CONSTANT con_str_low = X"205045A3A54D203C544543543E205045A3A54D203C544543543E205045A3A54D203C544543543E20";


SUBDESIGN lcd_DRAM_ahdl

(

STR[319..0]: INPUT; --строка для вывода на LCD

REFRESH: INPUT; --обновление строки в LCD DRAM

SBUSY: INPUT; --сигнал занятости подчиненного устройства

CLK: INPUT; --входной тактовый сигнал с частотой 40МГц и периодом 25нс

START_ACTION: OUTPUT; --сигнал запуска lcd_loader

DATA[7..0]: OUTPUT; --инструкция LCD контроллеру

BUSY: OUTPUT; --сигнал занятости устройства (0) свободен, (1) занят

REG_SELECT: OUTPUT; --флаг выбор регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)

ONE_CYCLE: OUTPUT; --(1) 4-битная или (0) 8-битная команда (данные)

)


--Автомат записи строк в память контроллера LCD

VARIABLE

dram_state : MACHINE OF BITS(lcd_state_reg[4..0]) WITH STATES(s0 = X"00", s1 = X"01", s2 = X"02", s3 = X"03", s4 = X"04", s5 = X"05", s6 = X"06", s7 = X"07", s8 = X"08", s9 = X"09", s10 = X"0A", s11 = X"0B", s12 = X"0C", s13 = X"0D", s14 = X"0E", s15 = X"0F",

s16 = X"10", s17 = X"11", s18 = X"12", s19 = X"13", s20 = X"14", s21 = X"15", s22 = X"16", s23 = X"17", s24 = X"18", s25 = X"19", s26 = X"1A", s27 = X"1B", s28 = X"1C", s29 = X"1D", s30 = X"1E", s31 = X"1F");


START_ACTION : DFF; -- сигнал запуска lcd_loader

DATA[7..0] : DFF; -- внутренний регистр для приема байт

BUSY : DFF; -- сигнал занятости текущего устройста (0-свободен, 1-занят)

REG_SELECT : DFF; -- флаг выбора регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)

ONE_CYCLE : DFF; -- (1) 4-битная или (0)битная команда (данные)


str_low[319..0] : DFF; -- регистр для хранения символов нижней строки

str_high[319..0] : DFF; -- регистр для хранения символов верхней строки

echo_delay[21..0] : DFF; -- счетчик колличества символов

char_cnt[5..0] : DFF; -- переменная состояния автомата выбора и загрузки исходной строки

data_tmp[7..0] : DFF; -- регистр для временного хранения байт

str_tmp[319..0] : DFF; -- регистр строки значений пересылаемого символа

BEGIN

START_ACTION.clk = CLK;

DATA[].clk = CLK;

BUSY.clk = CLK;

REG_SELECT.clk = CLK;

ONE_CYCLE.clk = CLK;

echo_delay[].clk = CLK;

char_cnt[].clk = CLK;

dram_state.clk = CLK;

data_tmp[].clk = CLK;

str_tmp[].clk = CLK;

CASE dram_state IS

WHEN s0 =>

START_ACTION = B"0";

DATA[] = X"00";

REG_SELECT = B"0";

ONE_CYCLE = B"0";

BUSY = B"0";

REG_SELECT = B"0";

char_cnt[] = X"00";

echo_delay[] = X"000000";

IF (REFRESH == B"1") THEN dram_state = s1;

END IF;


WHEN s1 =>

BUSY = B"1";

REG_SELECT = B"1";

ONE_CYCLE = B"0";

START_ACTION = B"0";

DATA[] = X"00";

echo_delay[] = X"000000";

char_cnt[] = X"00";

str_tmp[] = STR[];

dram_state = s4;

--начало рабочего цикла

WHEN s2 =>

BUSY = B"1";

REG_SELECT = B"1";

ONE_CYCLE = B"0";

DATA[] = str_tmp[319..312];

START_ACTION = B"1";

data_tmp[] = str_tmp[319..312];

echo_delay[] = X"000000";

char_cnt[] = char_cnt[];

str_tmp[] = str_tmp[];


IF (SBUSY == B"1") THEN

dram_state = s3;

END IF;

WHEN s3 =>

BUSY = B"1";

REG_SELECT = B"1";

ONE_CYCLE = B"0";

DATA[] = data_tmp[];

START_ACTION = B"0";

data_tmp[] = data_tmp[];

echo_delay[] = X"000000";

IF (SBUSY == B"0") THEN

char_cnt[] = char_cnt[] + 1;

str_tmp[319..8] = str_tmp[311..0];

str_tmp[7..0] = data_tmp[];

dram_state = s4;

ELSE

char_cnt[] = char_cnt[];

str_tmp[] = str_tmp[];

END IF;

WHEN s4 =>

BUSY = B"1";

REG_SELECT = B"1";

ONE_CYCLE = B"0";

DATA[] = X"00";

START_ACTION = B"0";

echo_delay[] = echo_delay[] + 1;

char_cnt[] = char_cnt[];

str_tmp[] = str_tmp[];

IF (echo_delay[] == X"1FFFFF") THEN

IF (char_cnt[] == X"28") THEN

dram_state = s0;

ELSE

dram_state = s2;

END IF;

END IF;

WHEN others =>

dram_state = s0;

END case;


END;


SUBDESIGN lcd_command_ahdl

(

CLK: INPUT; -- входной тактовый сигнал с частотой 40МГц и периодом 25 нс

SBUSY: INPUT; -- сигнал занятости подчиненного устройства

WRITE_COMMAND: INPUT; -- запуск процесса загрузки команды в LCD

DELAY[27..0]: INPUT; -- задержка между инструкциями

START_ACTION: OUTPUT; -- сигнал запуска lcd_loader

BUSY: OUTPUT; -- сигнал занятости текущего устройства (0-свободен, 1-занят)

REG_SELECT: OUTPUT; -- флаг выбор регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)

)

--Автомат записи строк в память контроллера LCD

VARIABLE

command_state : MACHINE OF BITS(cmd_state_reg[1..0]) WITH STATES(s0 = X"00", s1 = X"01", s2 = X"02", s3 = X"03"); --описание состояний цифрового автомата


START_ACTION : DFF; -- сигнал запуска lcd_loader

BUSY : DFF; -- сигнал занятости текущего устройста (0-свободен, 1-занят)

REG_SELECT : DFF; -- флаг выбора регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)


delay_command[27..0]: DFF; -- регистр для хранения величины задержки между командами

BEGIN

START_ACTION.clk = CLK;

BUSY.clk = CLK;

REG_SELECT.clk = CLK;

delay_command[].clk = CLK;

command_state.clk = CLK;

CASE command_state IS

WHEN s0 =>

BUSY = B"0";

START_ACTION = B"0";

delay_command[] = X"00000";

IF (WRITE_COMMAND == B"1") THEN command_state = s1;

END IF;

WHEN s1 =>

BUSY = B"1";

REG_SELECT = B"0";

command_state = s2;

WHEN s2 =>

BUSY = B"1";

IF (SBUSY == B"0") THEN

START_ACTION = B"1";

ELSE

START_ACTION = B"0";

command_state = s3;

END IF;

WHEN s3 =>

BUSY = B"1";

IF (SBUSY == B"0") THEN

delay_command[] = delay_command[] + 1;

IF (delay_command[] == DELAY[]) THEN command_state = s0;

END IF;

END IF;

WHEN OTHERS =>

command_state = s0;

END CASE;

END;


SUBDESIGN lcd_loader_ahdl

(

CLK: INPUT; --входной тактовый сигнал с частотой 40МГц и периодос 25 нс

REG_SELECT: INPUT; --флаг выбор регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)

START_ACTION: INPUT; --сигнал запуска lcd_loader

ONE_CYCLE: INPUT; --(1) 4-битная или (0) 8-битная команда (данные)

INSTR_DATA[7..0]: INPUT; --инструкция/команда LCD контроллеру от вышестоящих устройств

DATA_OUT[3..0]: BIDIR; --4-х битный двунаправленный канал связи с контроллером LCD

BUSY: OUTPUT; --запуск процесса загрузки команды в LCD

RW: OUTPUT; --флаг чтения/записи из двунаправленного канала связи с контроллером LCD

RS: OUTPUT; --флаг выбор регистра - переключает между записью команд и записью данных в память

E: OUTPUT; --старт бит при пересылки команд и данных в контроллер

)


--блок lcd_loader

VARIABLE

proc_state : MACHINE OF BITS(proc_state_reg[2..0]) WITH STATES(s0 = X"00", s1 = X"01", s2 = X"02", s3 = X"03", s4 = X"04", s5 = X"05");--описание состояний цифрового автомата

DATA_OUT[3..0] : DFF;--4-х битный двунаправленный канал связи с контроллером LCD

BUSY : DFF;--запуск процесса загрузки команды в LCD

RW : DFF;--флаг чтения/записи из двунаправленного канала связи с контроллером LCD (0-запись, 1-чтение)

RS : DFF;--флаг выбор регистра - переключает между записью команд и записью данных в память (0-команд, 1-данных)

E : DFF;--старт бит при пересылки команд и данных в контроллер

epw[4..0] : DFF; --задержка, организующая нужную длительность сигнала Е

delay_proc[5..0] : DFF; --задержка, организующая ожидания установки данных на выходных контактах (RS, RW)

first_cycle : DFF; --флаг первого цикла - если 1, то идёт загрузка первой части команды (данных)


BEGIN

DATA_OUT[3..0].clk = CLK;

BUSY.clk = CLK;

RW.clk = CLK;

RS.clk = CLK;

E.clk = CLK;

epw[].clk = CLK;

delay_proc[].clk = CLK;

first_cycle.clk = CLK;

proc_state.clk = CLK;


CASE proc_state IS

WHEN s0 =>

RW = B"0";

BUSY = B"0";

RS = B"0";

E = B"0";

IF (START_ACTION == B"1") THEN proc_state = s1; END IF;

WHEN s1 =>

RW = B"0";

BUSY = B"1";

RS = REG_SELECT;

E = B"0";

first_cycle = B"1";

delay_proc[] = X"00";

proc_state = s2;

WHEN s2 =>

RW = B"0";

BUSY = B"1";

RS = REG_SELECT;

E = B"0";

first_cycle = B"1";

delay_proc[] = delay_proc[] + 1;

IF (delay_proc[] == X"1C") THEN --задержка, организующая ожидания установки данных на выходных контактах (RS, RW)

proc_state = s3;

END IF;

WHEN s3 =>

RW = B"0";

BUSY = B"1";

RS = REG_SELECT;

E = B"0";

first_cycle = first_cycle;

epw[] = X"00";

IF (first_cycle == B"1") THEN

DATA_OUT[] = INSTR_DATA [7..4];

ELSE

DATA_OUT[] = INSTR_DATA [3..0];

END IF;

proc_state = s4;

WHEN s4 =>

RW = B"0";

--выдерживаем длительность высокого уровня сигнала Е == min 230 ns

BUSY = B"1";

RS = REG_SELECT;

E = B"1";


first_cycle = first_cycle;

IF (first_cycle == B"1") THEN

DATA_OUT[] = INSTR_DATA [7..4];

ELSE

DATA_OUT[] = INSTR_DATA [3..0];

END IF;

epw[] = epw[] + 1;

IF (epw[] == X"19") THEN

epw[] = X"00";

proc_state = s5;

END IF;

WHEN s5 =>

RW = B"0";

--выдерживаем длительность низкого уровня сигнала Е == min 230 ns

BUSY = B"1";

RS = REG_SELECT;

E = B"0";


IF (first_cycle == B"1") THEN

DATA_OUT[] = INSTR_DATA [7..4];

ELSE

DATA_OUT[] = INSTR_DATA [3..0];

END IF;


epw[] = epw[] + 1;

IF (epw[] == X"19") THEN

IF ((ONE_CYCLE == B"1") OR (ONE_CYCLE == B"0" AND first_cycle == B"0")) THEN

proc_state = s0;

ELSIF (ONE_CYCLE == B"0" AND first_cycle == B"1") THEN

first_cycle = B"0"; --первая половина команды/данных отправлена

proc_state = s3;

END IF;

ELSE

first_cycle = first_cycle;

END IF;

WHEN OTHERS =>

proc_state = s0;

END CASE;

END;

1   2   3   4   5   6   7

Похожие:

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Экономика на предприятиях туризма...

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Маркетинг на предприятиях туризма...

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Экономика на предприятиях туризма...

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Экономика на предприятиях туризма...

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Абдуллина И. А., Глобов К. С. Методические указания по выполнению курсовых работ. – Казань: Познание 2009–26 с

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры психологии

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Менеджмент»

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ
Методические указания по выполнению курсовых работ рассмотрены и утверждены на заседании кафедры «Менеджмент»

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ 1,75
Организация производства и менеджмент в машиностроении: методические указания по выполнению курсовых работ

Методические указания к выполнению курсовых работ по курсу «Схемотехника эвм» iconМетодические указания по выполнению курсовых работ Красноярск 2004 ^ I. Цель и задачи курсовой работы
Криминалистика. Методика расследования отдельных видов преступлений: Методические указания по выполнению курсовых работ / Сост. И....


Разместите кнопку на своём сайте:
lib.convdocs.org


База данных защищена авторским правом ©lib.convdocs.org 2012
обратиться к администрации
lib.convdocs.org
Главная страница