Ну вот вроде и все про атрибуты в языке VHDL. — КиберПедия 

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

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Ну вот вроде и все про атрибуты в языке VHDL.

2022-11-27 38
Ну вот вроде и все про атрибуты в языке VHDL. 0.00 из 5.00 0 оценок
Заказать работу

Так вот, чтобы поймать строб сигнала, нам как раз подходит атрибут S'event. Посмотрите в таблице 1. S'event дает TRUE, если происходит изменение сигнала, а это ни что иное как фронт сигнала (строб). Такой атрибут любой синтезатор воспримет правильно и подключит его ко входу синхронизации тригера, что нельзя сказать о других атрибутах, которые в основном используются для моделирования или носят вспомогательные функции.

Итак, мы выбрали атрибут, но этого мало. Еще нужно указать какой фронт ALE мы будем ловить. Для определенности, пусть нам нужно срабатывание по переднему фронту - ----/----. Тогда это будет соответствовать выражению clk'event and clk = '1'. Только не будем торопиться писать код, это мы сделаем в следующем разделе.

ПОДПРОГРАММЫ VHDL

...

В VHDL используется два вида подпрограмм - это функции и процедуры. В библиотеке std_logic_1164 описаны различные функции, в том числе и rising_edge()/falling_edge() определение которых выглядит так:

· function rising_edge (signal s: std_ulogic) return boolean is

· begin

· return (s'event and s = '1');

· end;

· function falling_edge (signal s: std_ulogic) return boolean is

· begin

· return (s'event and s = '0');

· end;

А так как мы используем библиотеку std_logic_1164, то спокойно можем задействовать эти функции. Теперь давайте напишем наш дешифратор 16-ти разрядного адреса:

· library ieee;

· use ieee.std_logic_1164.all;

· ---------------------------------

· entity dec is

· port (res, ale: in std_logic;

· addr: in std_logic_vector(15 downto 2);

· cs: out std_logic);

· end dec;

· ---------------------------------

· architecture dec_arch of dec is

· begin

· process (res, ale)

· begin

· if (res = '1') then

· cs <= '0';

· elsif rising_edge(ale) then

· if (addr = "11000011110000") then -- Это наше адресное пространство

· cs <= '1';

· else

· cs <= '0';

· end if;

· end if;

· end process;

· end dec_arch;

У нас получился работоспособный дешифратор адреса, а теперь приведем пример ошибки, которую часто допускают начинающие разработчики:

· architecture dec_arch of dec is

· signal addr_valid: std_logic_vector(15 downto 2);

· begin

· process (res, ale)

· begin

· if (res = '1') then

· addr_valid <= "00000000000000";

· elsif rising_edge(ale) then

· addr_valid <= addr;

· end if;

· if (addr_valid = "11000011110000") then -- Это наше адресное пространство

· cs <= '1';

· else

· cs <= '0';

· end if;

· end process;

· end dec_arch;

Для начинающих и поясним. Ошибка не в VHDL-коде, такой код пропустит любой САПР без запинки. Но дело в том, что в момент переключения по стробу addr_valid будет принимать всевозможные "случайные" значения, так называемый "дребезг". И есть шанс, что в какой-то момент addr_valid примет значение "11_0000_1111_0000", тогда cs примет валидное значение и неизвестно что будет с нашей схемой обработки ошибки. Подобные ошибки очень коварны, они не всегда о себе дают знать, моделирование может не выявить их, даже в железе может все работать нормально. Но изменение температурного режима, переход на другой тип микросхемы и т. п. может сразу привести к негативному результату.

Давайте продолжим развивать наш проект. Было бы расточительным, если бы наш дешифратор адреса выбирал бы только одно устройство. Пускай он еще выбирает внешнее статическое ОЗУ 32х8, согласно рисунку 15.

Давайте перепишем наш дешифратор:

· library ieee;

· use ieee.std_logic_1164.all;

· ---------------------------------

· entity dec is

· port (res, ale, cs: in std_logic;

· addr: in std_logic_vector(15 downto 5);

· cs_er, cs_ram: out std_logic);

· end dec;

· ---------------------------------

· architecture dec_arch of dec is

· begin

· process (res, ale)

· signal s_cs_ram, s_cs_er: std_logic;

· begin

· if (res = '1') then

· s_cs_ram <= '0';

· s_cs_er <= '0';

· elsif rising_edge(ale) then

· if (addr = "00000000000") then -- Адресное пространство ОЗУ

· s_cs_ram <= '1';

· s_cs_er <= '0';

· elsif (addr = "00000000001") then -- Адресное пространство устройства

· s_cs_ram <= '0';

· s_cs_er <= '1';

· else

· s_cs_ram <= '0';

· s_cs_er <= '0';

· end if;

· end if;

· end process;

· cs_ram <= s_cs_ram and cs;

· cs_er <= s_cs_er and cs;

· end dec_arch;

На рисунке 16 показано, как данный VHDL-код был воспринят квартусом. Обратите внимание, что код elsif rising_edge(ale) then реализован в виде входов синхронизации триггеров, на которые заводится сигнал ale, чего мы в принципе и хотели.

Сделаем соответствующие изменения в нашем устройстве, подключив дешифратор:

· library ieee;

· use ieee.std_logic_1164.all;

· ---------------------------------

· entity ERR_LED is

· port (

· -- Сигналы управления и шины процессора

· res, wr, oe, cs, ale: in std_logic;

· addr: in std_logic_vector(15 downto 0);

· data: in std_logic_vector(7 downto 0);

· -- Сигналы управления ОЗУ

· cs_ram, wr_ram, oe_ram: out std_logic;

· -- Сигналы управления индикацией

· ERR1, ERR2: in std_logic;

· LED: out std_logiс

· );

· constant GND: std_logic:='0';

· constant TRI: std_logic:='Z';

· end ERR_LED;

· ---------------------------------

· architecture led_arch of ERR_LED is

· signal serror, en1, en2, s_cs_er: std_logic;

· signal addr_h: std_logic_vector(15 downto 5);

· signal addr_l: std_logic_vector(1 downto 0);

· begin

· addr_h <= addr(15 downto 5);

· addr_l <= addr(1 downto 0);

· C0: entity WORK.dec(dec_arch) port map(res => res, ale => ale, cs => cs, addr => addr_h, cs_er => s_cs_er, cs_ram => cs_ram);

· C1: entity WORK.RegUpr(arch) port map(wr => wr, cs => s_cs_er, en1 => en1, en2 => en2, datain => data, addr => addr_l);

· C2: entity WORK.NAND2X3(bbb) port map(a => ERR1, b => en1, c => ERR2, d => en2, q => serror);

· LED <= GND when serror = '1' else TRI;

· wr_ram <= wr;

· oe_ram <= oe;

· end led_arch;

Для того чтобы смоделировать работу ПЛИС в схеме, показанной на рисунке 15, нам нужно иметь модели процессора и ОЗУ. Но если модель ОЗУ мы легко можем написать на VHDL сами, то модель процессора написать достаточно долго и трудно, если у Вас есть деньги, то модель можно купить у производителя. Но по большому счету, чтобы проверить работу ПЛИС, нам необязательно иметь модель процессора, достаточно имитировать его сигналы в соответствии с временными диаграммами, взятыми из DATASHEET. Реальным DATASHEET мы пользоваться не будем, а воспользуемся упрощенными временными диаграммами (рисунки 17, 18).


Поделиться с друзьями:

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.019 с.