Jump to content
    

Таймер задержки на VHDL

Недавно начал программировать на VHDL, поэтому пока не всё получается, а проект горит, выручайте.

Нужно описать на VHDL таймер задержки, имеющий три входа:

set - входной импульс

prog[15:0] - количество тактовых импульсов на которое необходимо задержать входной сигнал set на выходе

clk - тактовые импульсы

и один выход:

pout

По длительности set аналогичен тактовому.

Вот привожу вам мой вариант, он очень глючный, при prog="0000000000000001" на выходе отсутствует задержка, и при синтезе вылазит куча варнингов. SOS! HELP! ПОМОГИТЕ ПОЖАЛУСТА!

----------------------------------------глючный листинг-----------------------------------------------------------------

ibrary IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity timedel is

Port ( set : in STD_LOGIC;

pinout : out STD_LOGIC;

clk : in STD_LOGIC;

prog : in STD_LOGIC_VECTOR (15 downto 0));

end timedel;

 

architecture Behavioral of timedel is

signal st : STD_LOGIC_VECTOR (15 downto 0):="0000000000000000";

signal outsig : STD_LOGIC:='0';

signal setup : STD_LOGIC:='0';

begin

process(set,outsig)

variable crt : integer:=0;

begin

if set='1' then

crt := crt + 1;

end if;

if outsig = '1' then

crt := crt - 1;

end if;

if crt=0 then

setup<='0';

else

setup<='1';

end if;

end process;

process(clk)

begin

if setup='1' then

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

if st=prog-1 then

st<= conv_std_logic_vector(0,16);

else st<=st+1;

end if;

end if;

end if;

if (st=prog-1 and clk='1') then

pinout <= '1';

outsig <= '1';

else

pinout <= '0';

outsig <= '0';

end if;

end process;

end Behavioral;

Share this post


Link to post
Share on other sites

Вы б хоть книжки почитали для начала что ли?

 

architecture Behavioral of timedel is

signal st : STD_LOGIC_VECTOR (15 downto 0):="0000000000000000";

....

 

ни как не катит по тому что при синтезе начальные значения игнорируются.

 

process(clk)

begin

if setup='1' then

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

....

 

то же шедевр еще тот. Интересно как вы себе представляете это на схеме.

 

Для первых экскриментов схема должна быть с правильным ресетом. xHDLи не отменяют цифровую схемотехнику.

Share this post


Link to post
Share on other sites

ИМХО, для реализации Вашей задачи, Вам как минимум ещё необходима подсветка SET_EN для сигнала SET,чтобы захватить сигнала, иначе простым счётчиком не отделаешься.

 

По длительности set аналогичен тактовому.

Извините, не совсем понятно...

Share this post


Link to post
Share on other sites

Давайте я вам на верилоге напишу, а на ВХДЛ вы сами переложите.

вход prog захватывается только в момент выставления set. set должен стоять минимум такт, отсчет начинается с момента снятия set

 

reg [15:0] main_counter; 

always @ (posedge clk)
if (set)
    main_counter <= prog + 1; 
else 
if (main_counter != 0)
    main_counter <= main_counter - 1'b1; 

assign pout = (main_counter == 1);

 

не очень оптимально, но все же...

Share this post


Link to post
Share on other sites

Вы б хоть книжки почитали для начала что ли?

 

architecture Behavioral of timedel is

signal st : STD_LOGIC_VECTOR (15 downto 0):="0000000000000000";

....

 

ни как не катит по тому что при синтезе начальные значения игнорируются.

Не факт. Например XST поддерживает присвоение начального значения, в месте декларации. Хотя для этого ИМХО лучше пользоваться глобальным сбросом.

Share this post


Link to post
Share on other sites

не очень оптимально, но все же...////////////////////

Дело не в оптимальности. Такая конструкция здесь не проходит: if (main_counter != 0)

Потому что порождает одно запрещенное состояние. И никакой сумматор на входе не поможет. В данном случае при prog ffff никогда не получите этого отсчета. Ну и комбинаторная логика на выходе.

выход весь в пичках. Придется рассказывать. что это только enable. Да и задержки в 0 тактов наверно не бывает.

Share this post


Link to post
Share on other sites

ИМХО, для реализации Вашей задачи, Вам как минимум ещё необходима подсветка SET_EN для сигнала SET,чтобы захватить сигнала, иначе простым счётчиком не отделаешься.

 

По длительности set аналогичен тактовому.

Извините, не совсем понятно...

Например,

__ __ __ clk

__ set верно

_____ set неверно

Share this post


Link to post
Share on other sites

Дело не в оптимальности. Такая конструкция здесь не проходит: if (main_counter != 0)

Потому что порождает одно запрещенное состояние. И никакой сумматор на входе не поможет. В данном случае при prog ffff никогда не получите этого отсчета. Ну и комбинаторная логика на выходе.

выход весь в пичках. Придется рассказывать. что это только enable. Да и задержки в 0 тактов наверно не бывает.

 

согласен, поторопился - хотел триггер на выходе сэкономить не знаю зачем.

Да и сброс не мешало бы добавить.

Если предусмотрена задержка в ноль тактов (выход в этом же такте) - будет комбинаторный выход, в противном случае:

prog : in unsigned (15 downto 0);
... 
signal main_counter : unsigned (15 downto 0); 
... 
process(clk)
begin
if (clk'event and clk='1') then 
    if (set='1' and (prog != (0 => '1', others => '0'))) then
        main_counter <= prog; 
    elsif (main_counter /= (others => '0'))
        main_counter <= main_counter - '1'; 
    end if;  --  counter 
    if (main_counter = (0 => '1', others => '0') ) then 
        pinout <= '1';
    elsif (set='1' and (prog = (0 => '1', others => '0'))) 
                pinout <= '1'; 
        else 
                pinout <= '0'; 
    end if;  --  output  
end if; -- clk'event 
end process;

надеюсь с типами не попутал.

 

ps добавил еще логики для задержки в "1"

Share this post


Link to post
Share on other sites

to id_gene

теперь у Вас вполне рабочая схема. И все же хочу повториться. Теперь у Вас не рабочее состояние: все нули. Если по каким либо причинам на схему подать все нули, реакции на входное воздействие не будет. Пока кто то prog отличный от нуля не запишет. А вот этого не должно быть никогда. Систему нельзя вводить в ступор. Я бы оформир Вашу схему так:

module zader_i

(

input clk,

input set,

input [15:0] prog,

output reg out_clk

);

 

reg [15:0] ct;

 

always @ (posedge clk)

begin

if (set)

ct <= (prog == 0) ? 16'd1 : prog;

else if (ct != 0)

ct <= ct - 1'b1;

out_clk <= (ct == 1);

end

endmodule

Я в таких случаях использую другую реализацию: конечно в этой реализации при всех нулях получиться максимальная задержка импульса. Но схема никогда не введет систему в ступор, потому что у нее нет запрещенного состояния. при желании все нули также можно озвучить как и в первой схеме.

module zader_i

(

input clk,

input set,

input [15:0] prog, //// >=1

output reg out_clk

);

 

reg [15:0] ct;

reg enable;

 

always @ (posedge clk)

begin

if (set) begin

enable <= 1'b1;

ct <= prog; end

else begin

if (enable)

ct <= ct - 1'b1;

if (ct == 16'd1)

enable <= 1'b0; end

out_clk <= (ct == 16'd1);

end

 

endmodule

Share this post


Link to post
Share on other sites

to darkniisiis

Если в тексте тестбенча нет команды стоп. то это можно обойти. Все время нажимать только Run.

если нажали Run_all, нажмите Break и смотрите, что за это время насимулировали.

Share this post


Link to post
Share on other sites

Смотрю и плачу, ну почему на VHDL ничего нормального никто написать не может, а на верилоге пожалуста!!! Если кто нибудь знает два языка переведите мне верилог на VHDL , пожалуста!!!!А то мои переводы заканчиваются полным аутом.А верилог я промоделировать не могу, у меня только VHDL поддерживается.

to id_gene

к сожелению на Ваш синтаксис VHDL ругается,а когда я пытаюсь его подправить то при моделировании ничего не получается :(

Share this post


Link to post
Share on other sites

2 sazh:

согласен полностью.

Я для этого и приписал насчет нулевой задержки и комбинаторного выхода - я бы добавил мультиплексор на выходе выводя set наружу, чтобы соответствовать условиям задачи (задержке в ноль тактов).

Но это уже мелочи и условия реальной задачи...

Share this post


Link to post
Share on other sites

Код sazh в вольном переводе на VHDL. Отсутствие ошибок не гарантирую.

 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity timedel is
    port (
        clk    : in  STD_LOGIC;
        set    : in  STD_LOGIC;
        prog   : in  STD_LOGIC_VECTOR ( 15 downto 0 );
        pinout : out STD_LOGIC
    );
end timedel;

architecture timedel_arch of timedel is

signal cnt : std_logic_vector( 15 : 0 );
signal enable;
signal delayed_set;

begin

pinout <= delayed_set;

process( CLK )
begin
    if CLK'event and CLK = '1' then

        if ( set = '1' ) then
            enable <= '1';
        elsif ( cnt = 1 )
            enable <= '0';
        end if;
        
        if ( set = '1' ) then
            cnt <= prog;
        elsif ( enable = '1' ) then
            cnt <= cnt - 1;
        end if;
        
        if ( cnt = 1 )
            delayed_set <= '1';
        else
            delayed_set <= '0';
        end if;

    end if;
end process;

end timedel_arch;

Share this post


Link to post
Share on other sites

я думаю в идеале должно быть так

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

 

entity TIMER_AGAIN is

Port ( set : in STD_LOGIC;

prog : in STD_LOGIC_VECTOR (15 downto 0);

clk : in STD_LOGIC;

pinout : out STD_LOGIC);

end TIMER_AGAIN;

 

 

architecture Behavioral of TIMER_AGAIN is

signal cnt : std_logic_vector( 15 downto 0 );

signal enable : std_logic;

signal delayed_set : std_logic;

 

begin

 

process( CLK )

begin

if CLK'event and CLK = '1' then

 

if ( set = '1' ) then

enable <= '1';

elsif ( cnt = "0000000000000001" )then

enable <= '0';

end if;

 

if ( set = '1' ) then

cnt <= prog;

elsif ( enable = '1' ) then

cnt <= cnt - 1;

end if;

 

if ( cnt = 1 )then

delayed_set <= '1';

else

delayed_set <= '0';

end if;

 

end if;

end process;

pinout <= delayed_set;

end Behavioral;

Берём моделируем этот текст.

Похоже , но не то в СNT PROG загружается только спустя один такт, схема работает при условии что set больше либо равен двум тактовым импульсам, а у нас set = по длительности clk/

Как быть в таком случае?Помогите разобраться до конца,я начинаю видеть свет в конце тоннеля.Времени у меня осталось совсем мало, спасите мою бедную голову.

Share this post


Link to post
Share on other sites

Похоже , но не то в СNT PROG загружается только спустя один такт, схема работает при условии что set больше либо равен двум тактовым импульсам, а у нас set = по длительности clk/

///////////////

Рабочая у вас схема. Схема работает только при условии что set равен по длительности одному периоду clk.

Если этот set по длительности больше одного периода clk, то в зависимости от prog она работает некорректно или НЕПРАВИЛЬНО.

Эта схема при моделировании везде дает один и тот же результат.

Так как prog записывается в регистр ct по переднему фронту clk, а у Вас в тестбенче значение prog наверно смещено относительно фронта clk, получается дополнительная задержка.

В реальной схеме сигнал set должен формироваться по переднему фронту clk.

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

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

А что мешает в ISE просимулировать. Тот же результат получите.

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.

×
×
  • Create New...