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

Здравствуйте. Помогите разобраться с логикой работы VHDL...Что-то вообще я её не понимаю...почитал...вроде всё логично, а начинаю делать - вообще никак...

Вот например:

На вход схемы приходит сигнал IRDYn, я его сразу же передаю на выход схемы RST:

 

RST<=IRDYn;

 

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

 

Или вот ещё:

 

Создаю компонент, который будет сравнивать приходящий адрес (ADR1) и содержание BAR в конфигурационном пространстве для PCI:

 

ARCHITECTURE behavior OF ADR_CMP IS

 

begin

process(ADR1)

begin

if (ADR1 = BAR) then --Если адрес совпадает, то разрешаем доступ

ADREN<='1';

else

ADREN<='0'; ---Если нет - то нет...

end if;

end process;

end behavior;

 

В программе пишу:

 

SET_SIGNALS: process(ADREN)

begin

if (ADREN='1') then --Если разрешён доступ, то выставляем соответствующие сигналы

DEVSELn<='0';

TRDYn<='0';

DIREN_in<='1'; --Открытие буферных элементов для входнях сигналов

else

DEVSELn<='1';

TRDYn<='1';

DIREN_in<='0';

end if;

end process SET_SIGNALS;

 

 

Так вот, если в DIREN_in писать '1', то адрес не совпадает...но он же (DIREN_in) выставляется после того, как адрес определился...непонятно...

 

P.S. DIREN_in так же изменяет направление передачи данных с двунаправленой шины AD, по которой в фазе адреса приходит тот самый адрес, а в фазе данных должны уходить данные....Может поэтому глючит... :wacko:

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


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

Вы забываете про тактовую частоту и строку "if clk'event and clk = '1' then" иначе у Вас будут не тригеры, а защелки. Должно быть наподобии

 

SET_SIGNALS: process(ADREN, clk)
begin
if clk'event and clk = '1' then
if (ADREN='1') then --Если разрешён доступ, то выставляем соответствующие сигналы
DEVSELn<='0';
TRDYn<='0';
DIREN_in<='1'; --Открытие буферных элементов для входнях сигналов
else
DEVSELn<='1';
TRDYn<='1';
DIREN_in<='0';
end if; end if;
end process SET_SIGNALS;

Передачу сигналов с входа на выход можно делать и вне процесса. В VHDL кроме сигналов есть и переменные(variable), которые видны внутри данного процесса и переменным присвоение происходит без всяких задержек.

 

P.S. Если это для контролёра PCI зайдите на opencores.org и скачайте реализацию ядра интерфейса шины PCI и посмотрите, как там это сделано. Просто PCI это не для новичка который только начинает разбираться в VHDL - это мое субъективное мнение :)

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


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

Вы забываете про тактовую частоту и строку "if clk'event and clk = '1' then" иначе у Вас будут не тригеры, а защелки. Должно быть наподобии

 

SET_SIGNALS: process(ADREN, clk)
begin
if clk'event and clk = '1' then
if (ADREN='1') then --Если разрешён доступ, то выставляем соответствующие сигналы
DEVSELn<='0';
TRDYn<='0';
DIREN_in<='1'; --Открытие буферных элементов для входнях сигналов
else
DEVSELn<='1';
TRDYn<='1';
DIREN_in<='0';
end if; end if;
end process SET_SIGNALS;

Передачу сигналов с входа на выход можно делать и вне процесса. В VHDL кроме сигналов есть и переменные(variable), которые видны внутри данного процесса и переменным присвоение происходит без всяких задержек.

 

P.S. Если это для контролёра PCI зайдите на opencores.org и скачайте реализацию ядра интерфейса шины PCI и посмотрите, как там это сделано. Просто PCI это не для новичка который только начинает разбираться в VHDL - это мое субъективное мнение :)

 

 

 

использование переменных внутри процесса это заморочки кривого языка си (языка программирования) и не более того - hdl языки не языки программирования - они языки описания аппаратуры, что с программированием разные вещи.

 

от того что все переменные будут глобальными ничего кроме пользы не будет

 

на какой частоте симулируете???

 

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

и его не обязательно тактировать

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


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

2 Maverick - касательно

if (ADREN='1') then --Если разрешён доступ, то выставляем соответствующие сигналы
    DEVSELn<='0';
    TRDYn<='0';
    DIREN_in<='1'; --Открытие буферных элементов для входнях сигналов
else
    DEVSELn<='1';
    TRDYn<='1';
    DIREN_in<='0';
els if;

и

if (ADR1 = BAR) then --Если адрес совпадает, то разрешаем доступ
    ADREN<='1'; 
else 
    ADREN<='0'; ---Если нет - то нет...
end if;

Это можно сделать на простой логике , не включая тактовую в разбор полётов :)

 

2 hynter - если вы роутите сигнал со входа на выход в architecture - то на выходе сигнал будет иметь только задержку , кторая равна времени прохождяния сигнала по пути внутри кристала - как роутер положит - если у вас большая частота и путь кривоватый - то оно может выйти так , что сигнал выйдет гораздо позже чем зашёл смотря по тактовой..

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


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

Ага. Спасибо большое за разъяснение!! Очень помогло!!=)

Такой вопрос, всё-таки, остался...Вот есть кусок проги:

 

ST: process(CLK)

Begin

if CLK'event and CLK='1' then

CASE STAT is

when IDLE => If (FRAMEn='0') then

If (AD1=BAR) then STAT<=S_DATA; DEVSELn<='0';
else STAT<=B_BUSY; DEVSELn<='Z'; end if;

else STAT<=IDLE; AD1<=ZST; end if;

.................................

end case;

end if;

end process ST;

 

Сигналу DEVSELn значение упорно присваивается на целый такт позже чем это надо...То есть через такт после того, как выполняется условие AD1=BAR. Подскажите, пожалуйста, как этого избежать?

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


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

2 hynter - а вы проведите эксперимент - сделайте простой сравнитель - без тактовых - и посмотрите когда на выходе будет 0 а когда 1 в зависимости от подаваемых данных - в принципе вы увидите что есть задержка - не сразу после подачи на вход данных у вас выставляется нужное значание. Ну а данные в тригере защёлкиваются по rising_edge вашего CLK. Видимо данне тоже меняются в момент переднего фронта и тригер просто защёлкивает предыдущее значение.

 

В обсчем загоните в Quartus или ISE или есчё куда нить - на какой кристал вы там ориентируетесь - и посмотрите в RTL-въювере - там тогда всё понятно станет ..

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


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

Подскажите, пожалуйста, а как сохранить в переменную..или ещё куда данные?

В определённый момент приходят данные на вход CBEn, которые потом теряются с него => их необходимо сохранить.

Пишу:

 

------

shared variable CMD : std_logic_vector(3 downto 0):="ZZZZ";

------

Process(FRAMEn)

begin

if falling_edge(framen) then CMD:=CBEn; end if;

end process;

 

В результате в CMD не сохранятеся

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


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

2 hynter - ну для начала

signal CMD : std_logic_vector(3 downto 0):="0000";--initial value
...
Process(framen)
begin
    if ( falling_edge(framen) ) then 
    CMD <= CBEn;
    end if;
end process;

это вы сварганили тригер, который срабатывает по falling_edge framen - данные заносятся в CMD - но если вы их выводить куда то или использовать далее не будете - то ессно синтезатор это выкинет - оптимизация понимаеш....

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


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

Обьясните, пожалуйста, как же всё-такие это работает...В книжках одно пишут...на деле - другое...

Квартус половину функций не пропускает (например несколько WAITов в одном процессе)...список чувствиетльности вообще какая-то непонятная вещь...что туда ни пиши - получается, что он всё равно реагирует на все сигналы, которые в этом процессе проверяются...

 

Самый главный вопрос такой:

 

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

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

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


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

Обьясните, пожалуйста, как же всё-такие это работает...В книжках одно пишут...на деле - другое...

Квартус половину функций не пропускает (например несколько WAITов в одном процессе)...список чувствиетльности вообще какая-то непонятная вещь...что туда ни пиши - получается, что он всё равно реагирует на все сигналы, которые в этом процессе проверяются...

 

Самый главный вопрос такой:

 

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

 

чето вы совсем темните

 

выход <= вход;

 

на самом деле порядка 3-5 наносекунд задержка на уровне вывода

сколько у вас задержка

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


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

2 hynter - отвыкайте от wait - какпо мне - не сильно удобочитаемо - как то потыкался я в квартусе с этими вейтами - ни туда не сюда - да и забыл про них.

На счёт списка чувствительности - всё что читается в процессе или проверяется. Хотя если вы туда что то не напишите - нечего страшного не будет.

А на счёт

как передать данные, при их поступлении, сразу на выход

ну так вам rv3dll(lex) написал

out <= in;

Всё прекрасно работает и в планнере видится :)

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


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

Ага...понятно в чём косяк=) Оно так и должно задерживаться...а у нас же 33MHz...оно медленней и поэтому всё хорошо=) Спасибо большое!

Но вот такой теперь косяк:

Всё работает!

Комментирую подачу в выходной сигнал переменной, которая НИГДЕ НЕ ИСПОЛЬЗУЕТСЯ! ей просто присваивается значение - всё!! Летит вся прога вообще!! Одни неопределённые сигналы....вся диаграмма в крестах...

 

Как такое вообще может быть? Чего не так-то??

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


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

2 hynter - ну что значит

НИГДЕ НЕ ИСПОЛЬЗУЕТСЯ

понимаете в HDL языках понятие переменной немного не такое как в C++ ...

Посмотрите внимательно код - возможно она муксится где то или семафорит кому либо.

 

Или приведите код - телепаты то в отпуске - лето , море, пляж :wassat: ....

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


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

Или приведите код....

 

Вот он код=)

Речь шла о сигналах RD_TX и CNF_RD (вывод, без которого не работает, помечен коментарием "--NEED")

 

Помогите пожалуйста разобраться...а то 24 сдавать уже всё это дело...а я недели 3 уже над этим бьюсь и никак не рвублюсь :crying:

VHDL.txt

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


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

2 hynter - посмотримс на досуге ..

 

А кому сдавать то - не диплом хоть ?

 

------------------

навскидку что видно , пока не ушёл домой:

--*********
--*SIGNALS*
--*********
NOT_WE    <= '0' when (FRAMEn='0' and AD1=ADR ) else '1' when (DONE='0') else 'Z';   --Не распознан адрес
RD_TX     <= '1' when (FRAMEn='0' and CNF(4)=AD1) else '0';                          --Транзакция чтения данных  and CBEn="0010"
CNF_RD    <= '1' when (FRAMEn='0' and IDSEL='1' and CBEn="1010") else '0';           --Транзакция чтения конфигурации
CNF_WR    <= '1' when (FRAMEn='0' and IDSEL='1' and CBEn="1011") else '0';           --Транзакция записи конфигурации
DONE      <= '1' when (FRAMEn='1' and IRDYn='1') else '0';                           --Транзакция Закончена

А далее

OUT2(0)<=NOT_WE;
OUT2(1)<=RD_TX;  ---NEED!!
OUT2(2)<=CNF_RD; ---NEED!!
OUT2(3)<=CNF_WR;

Сделайте

OUT2(0)<=NOT_WE;
OUT2(1)<='0';
OUT2(2)<='0';
OUT2(3)<=CNF_WR;

И будет вам счастие - выводы 1 и 2 порта OUT будут в нуле вечно, и синтезатор по идее должен выкинуть RD_TX и CNF_RD вообсче как ненужные..

 

Или тут должно быть чтото хитрей ?

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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