Перейти к содержанию
    

Тестова задачка на VHDL

Решил осваивать VHDL. В первом же примере столкнулся с проблемкой, которую самому не получается решить. В чем суть задачи:

по нарастающему фронту nAds устанавливается pci_transaction в "1" .

по нарастающему фронту nBlast сбрасывается pci_transaction в "0".

nRst также сбрасывает pci_transaction в "0".

Не разобрался как в конструкции условного присваивания ( if then else) в секции else написать что значение не изменяется? (Я написал присвоение 'Z', но это наверно не правильно)

Исправте плиз мой мега-исходник, бо самому опыта не хватает :)

 

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

 

entity PLXstrobe is

port (

nAds : in std_logic;

nBlast : in std_logic;

Lclk : in std_logic;

LWR : in std_logic; -- (1 - WR, 0 - RD)

nReady : in std_logic;

nWait : in std_logic;

nRst : in std_logic;

nWr : out std_logic;

nRd : out std_logic );

end PLXstrobe;

 

architecture first of PLXstrobe is

signal pci_transaction;

begin

 

--pci_transaction <= '0' when nRst = '0' else 'Z';

 

ads: process (nAds)

begin

--if rising_edge(nAds) then

if nAds = '1' then

pci_transaction <= '1';

else

pci_transaction <= 'Z'; -- не изменяет значения

--pci_transaction <= pci_transaction;

end if;

end process ads;

 

blast: process (nBlast)

begin

--if rising_edge(nBlast) then

if nBlast = '1' then

pci_transaction <= '0';

else

pci_transaction <= 'Z'; -- не изменяет значения

end if;

end process blast;

 

rst: process (nRst)

begin

if nRst = '0' then

pci_transaction <= '0';

else

pci_transaction <= 'Z'; -- не изменяет значения

end if;

end process rst;

 

nWr <= not pci_transaction or nReady or not nWait or Lclk or not LWR;

nRd <= not pci_transaction or nReady or not nWait or Lclk or LWR;

 

end first;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Типичные ошибки начинающих....

Выходной сигнал должен обрабатываться в одном процессе.

Ну в самом деле - ты же не соединяешь несколько выходов вместе!

 

Видимо есть несколько путей

В комбинаторике:

pci_transaction <= nAds and nRst and (not nBlast);

Недостаток - если между входными сигналами есть гонки - получишь "иголки" на выходе.

Поэтому часто рекомендуют делать синхронные схемы.

Соответственно, нужен Clock.

В твоем тексте есть Lclk - это видимо он и есть?

Если да, тогда должно быть что-то типа такого:

process(nRst, Lclk,nAds,nBlast)

begin

if(nRst='0') then

pci_transaction <= '0';

elsif (Lclk'event and Lclk='1') then

if(nAds='1') then pci_transaction <= '1';

elsif(nBlast='1') then pci_transaction <= '0';

-- else pci_transaction <= еще что нибудь;

end if;

end if;

end process;

если сброс - понятно, держим выходной сигнал.

по фронту (можно по спаду) смотрим на nAds и nBlast и пытаемся выходной сигнал привести в соответствие.

Обрати внимание, в описаном примере схема получилась приоритетная - активный nAds будет иметь приоритет над активным nBlast.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если да, тогда должно быть что-то типа такого:

process(nRst, Lclk,nAds,nBlast)

Это неправильно. Правильно:

process(nRst, Lclk)

Изменено пользователем andrew_b

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понял, на эту штуку обращает внимание симулятор,

синтезатору пофиг.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как написать что значение не изменяется?

Если уж хочешь явно обозначить сие событие, то присваивай NULL.

 

по нарастающему фронту nAds устанавливается pci_transaction в "1" .

по нарастающему фронту nBlast сбрасывается pci_transaction в "0".

При составлении VHDL описания корректнее всего отталкиваться от той схемы, которую желаешь получить. Не существует триггеров, работающих по двум фронтам. А следовательно и синтезаторов, которые смогут развести в ПЛИС подобные синтаксические конструкции. Уточни ТЗ - какова функция сигналов nAds и nBlast.

 

Я написал присвоение 'Z'

Высокоимпедансное состояние (aka 'Z') используется, например, при описании двунаправленных линий.

 

P.S.: IMHO освоение VHDL лучше начинать с более простых примеров.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как написать что значение не изменяется?

Если уж хочешь явно обозначить сие событие, то присваивай NULL.

null ничему присвоить нельзя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если проделывать все в одном процессе ничего сложного нету. А как с нескольких процессов управлять внутренним сигналом (так как в моем примере) ? Этот принцип вроди называется управление сигналом с несколькими драйверами.

И еще вопросик:

Конструкция IF THEN ELSE. Когда вызываю ф-ю rising_edge(nAds) в секции IF - выдается ошибка,

а когда в ELSEIF - ошибки нету. Это с конкретным компилятором связано ? В книге не нашел ответа на этот вопрос...

 

Зараннее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен что не стоит в одном процессе присваивать сигналу значения по разным фронтам.

Надо сделать отдельные процессы для каждого clock'а, в каждом процессе присваивать значения отдельным переменным. И только потом в отдельном процессе управлять pci_transaction.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как из нескольких процессов управлять одним сигналом ? Можете кусочек кода выложить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"А как из нескольких процессов управлять одним сигналом ? Можете кусочек кода выложить."

 

Ну не делается так.

Основная причина - процессы выполняются параллельно. Это означает, что значение выходному сигналу может присвоить несколько процессов сразу. Что получится на выходе?

Как разрулить?

Делаются промежуточные выходные сигналы, каждый в своем процессе.

Потом в специально выделенном процессе получаешь из промежуточных один выходной(ные).

Да, можно использовать Z состояние, но, опять-таки внутри одного процесса. Только для того, чтоб иметь в каждый момент времени определенное состояние выходного сигнала.

Пример:

entity DataBus is

port

(

Data : inout std_logic_vector (3 downto 0);

Rd : in std_logic;

Wr : in std_logic;

Res : in std_logic;

Clk : in std_logic

);

End DataBus;

 

architecture behav of DataBus is

 

signal WrData : std_logic_vector (3 downto 0);

signal RdData : std_logic_vector (3 downto 0);

 

process(Res,Clk,Data,Rd,Wr)

begin

if(Res='0') then

Data <="ZZZZ";

else

if(Clk'event and Clk='1') then

if(Rd='0') then Data <=RdData;

elsif (Wr='0') then WrData <= Data; Data <="ZZZZ";

else Data <= "ZZZZ";

end if;

end if;

end if;

end process;

end behav;

Примитивная шина данных.

По сбросу - в Z состоянии.

По клоку -

По сигналу Rd - выдаем на шина волшебное число.

По сигналу Wr - Выходные буфера - в Z, со входных читаем в переменную WrData.

Во всех остальных случаях - Z.

Этот же пример можно развить в твой вопрос (см начало) - данные для записи на шину и прочитанные с шины обрабатываются (готовятся) без проблем в других процессах.

Опять-таки примитивный пример:

process (Res,Clk,Data,Rd,Wr)

begin

if(Res='0') then RdData <="0000"; WrData <="0000";

else

if(Clk'event and Clk='1') then

if(Wr='1' and Rd='1') then

if(WrData="1010") then RdData <="0101";

else RdData <="1111";

end if;

end if;

end if;

end if;

end process;

Вот, получи. Данные готовятся в одном процессе, на улицу выводятся в другом процессе. И т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как написать что значение не изменяется?

Если уж хочешь явно обозначить сие событие, то присваивай NULL.

null ничему присвоить нельзя.

 

A null statement performs no action (цитата из стандарта VHDL). И вы по-прежнему утверждаете, что null'а не существует?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не существует триггеров, работающих по двум фронтам. А следовательно и синтезаторов, которые смогут развести в ПЛИС подобные синтаксические конструкции.

 

хмм а тригеры в холодных бегунах фикция ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как написать что значение не изменяется?

Если уж хочешь явно обозначить сие событие, то присваивай NULL.

null ничему присвоить нельзя.

 

A null statement performs no action (цитата из стандарта VHDL). И вы по-прежнему утверждаете, что null'а не существует?

Этого я не утверждаю. Я утверждаю, что

null ничему присвоить нельзя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не существует триггеров, работающих по двум фронтам. А следовательно и синтезаторов, которые смогут развести в ПЛИС подобные синтаксические конструкции.

 

хмм а тригеры в холодных бегунах фикция ?

Если можно, то поясните подробнее чего они там придумали. С семейством холодных спортсменов сталкиваться еще не приходилось. Как выглядят такие триггеры?

 

Этого я не утверждаю. Я утверждаю, что
null ничему присвоить нельзя.

Т.е. по вашему получается, что так писать нельзя?:

 

...

SIGNAL temp: std_logic;

...

process(...)

begin

...

temp <= NULL;

...

end process;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...