Jump to content

    
Sign in to follow this  
evgforum

Странно работает VHDL код в симуляторе

Recommended Posts

Имеется простой D-триггер (цепочка триггеров), написанный на VHDL с целью создать модуль задержки сигнала на несколько тактов (количество тактов задержки - параметр level). Ожидаю на выходе Q увидеть синхронный сигнал, меняющийся по фронту CLK, который почему-то переключается по спаду CLK (см. рисунок из Active-HDL). Что я делаю не так, у кого какие соображения? Т.е. в данном случае, как мне думается, должно быть Q = BUF(1).

 

 

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity pipeline is
generic(level: natural := 1);
port(
	 CLK : in STD_LOGIC;
	 D : in STD_LOGIC;
	 RST : in STD_LOGIC;
	 Q : out STD_LOGIC;
	 nQ : out STD_LOGIC
     );
end pipeline;

architecture pipeline of pipeline is
type dff_array is array(integer range 0 to level) of STD_LOGIC;
signal BUF: dff_array;
begin

process(CLK, RST, D)	
begin
if RST = '1' then
	for i in 1 to level loop
		BUF(i) <= '0';
	end loop;
elsif CLK'event and CLK = '1' then
	for i in 1 to level loop
		BUF(i) <= BUF(i-1);
	end loop;
end if;

BUF(0) <= D;
Q <= BUF(level);
nQ <= not BUF(level);
end process;

end pipeline;

 

из симулятора:

 

d2fb560c634dcaf7662426d42dc9f842.jpg

 

Share this post


Link to post
Share on other sites
ошибка в тестбенче, не правильно ставите сигнал D

А как его правильно ставить? Сейчас его изменение строго совпадает с фронтом CLK.

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

 

В качестве эксперимента поместил присвоение выхода внутрь условия elsif CLK..., т.е. сделал его синхронным - все работает как надо.

 

    elsif CLK'event and CLK = '1' then
        for i in 1 to level loop
            BUF(i) <= BUF(i-1);
        end loop;
        
        Q <= BUF(level-1);
    end if;

Edited by evgforum

Share this post


Link to post
Share on other sites
В качестве эксперимента поместил присвоение выхода внутрь условия elsif CLK..., т.е. сделал его синхронным - все работает как надо.

что написали, то и получили. не надо мешать в одну кучу синхронное и асинхронное. либо засовывайте внутрь elsif CLK, либо делайте отдельный процесс.

Share this post


Link to post
Share on other sites
что написали, то и получили. не надо мешать в одну кучу синхронное и асинхронное. либо засовывайте внутрь elsif CLK, либо делайте отдельный процесс.

Не знал, что запись вида

process(CLK, RST, D)    
begin
    elsif CLK'event and CLK = '1' then
        if D = ...
            sync_signal <= ....
            ...
        end if;
    end if;
    
    OUTPORT <= sync_signal;
end process;

является ошибочной и OUTPORT может измениться на спаде CLK. Ведь он должен полностью повторять сигнал sync_signal (казалось бы)

Share this post


Link to post
Share on other sites
OUTPORT может измениться на спаде CLK. Ведь он должен полностью повторять сигнал sync_signal (казалось бы)

ну так у вас CLK в списке чувствительности стоит, чего вы хотите

process(CLK, RST, D)
...
OUTPORT <= sync_signal;
...

 

присваивание (я так понял) предполагается асинхронным - так на кой вы его в процесс запихали?

Share this post


Link to post
Share on other sites
Не знал, что запись вида

process(CLK, RST, D)    
begin
    elsif CLK'event and CLK = '1' then
        if D = ...
            sync_signal <= ....
            ...
        end if;
    end if;
    
    OUTPORT <= sync_signal;
end process;

является ошибочной и OUTPORT может измениться на спаде CLK. Ведь он должен полностью повторять сигнал sync_signal (казалось бы)

 

Не путайте моделирование с синтезом. Синтезатору, грубо говоря, на список чувствительности наплевать и поэтому OUTPORT будет "повторять" sync_signal, а вот при моделировании список чувствительности играет ключевую роль. Симулятор будет пересчитывать значение OUTPORT только если изменился какой либо сигнал из списка чувствительности. Вот и получается, что по фронту у Вас меняет свое значение sync_signal, но он меняет его не мгновенно, а через некоторое время дельта, поэтому в момент фронта, когда происходит расчет значения OUTPORT sync_signal еще не изменился. Далее симулятор не "заходит" в процесс до изменения одного из сигналов CLK, RST или D. Когда происходит спад CLK OUTPORT обновляет свое значение. Если Вы, например, измените значение D между фронтом и спадом CLK, то увидите, что OUTPORT будет меняться не по клоку вообще, а по изменению D.

 

Поэтому, в данном случае, для корректной симуляции в списке чувствительности не хватает sync_signal.

 

Но если честно, то OUTPORT <= sync_signal; внутри процесса - очень "криво", так никто не пишет. Этому присвоению там нечего делать, его нужно вынести за процесс.

Share this post


Link to post
Share on other sites
Поэтому, в данном случае, для корректной симуляции в списке чувствительности не хватает sync_signal.
Если вы в список чувствительности процесса внесёте сигнал, который в этом же процессе генерируется, то увидите много интересного.

Share this post


Link to post
Share on other sites
Если вы в список чувствительности процесса внесёте сигнал, который в этом же процессе генерируется, то увидите много интересного.

 

А что будет интересного для синхронной схемы? Да и для асинхронной, впрочем, тоже?

Share this post


Link to post
Share on other sites
Но если честно, то OUTPORT <= sync_signal; внутри процесса - очень "криво", так никто не пишет. Этому присвоению там нечего делать, его нужно вынести за процесс.

Все понятно, спасибо всем за подробные разъяснения!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this