Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

opóźnienie czasowe w vhdl'u

28 Maj 2007 21:43 2321 2
  • Poziom 11  
    Witam
    Czy wie ktoś może jak zrobić w vhdl'u układ który będzie generował impuls wyzwalany narastającym zboczem sygnału wejściowego, a czas trwania tego impulsu żeby był ustawiany na 4 bitach wejściowych. Zależy mi na czasach do 3 sekund i koniecznie aby układ zliczał od początku gdy przyjdzie kolejny impuls wyzwolenia a jeszcze nie skończył generować poprzedniego impulsu - tak jak układ 74123.
    Myślałem aby zrobić licznik, który będzie zliczał impulsy z generatora. Próbowałem coś takiego ale kompilator wyświetla komunikat "Process clocking is too complex"

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.STD_LOGIC_UNSIGNED.all;
    use IEEE.STD_LOGIC_ARITH.all;

    entity timer123 is port (
    CLK, CLR, A, B, S0,S1,S2,S3: in std_logic;
    Q, NQ: out std_logic
    );
    end timer123;

    architecture arch_timer123 of timer123 is
    signal wyzwolenie: std_logic;
    signal liczba: std_logic_vector(3 downto 0);

    begin
    wyzwolenie <= not A and B and CLK;

    process (CLR,CLK,wyzwolenie)
    begin
    if (CLR='0') then
    Q <= '0';
    NQ <= '1';
    elsif (wyzwolenie'event and wyzwolenie='1') then
    liczba <= S3 & S2 & S1 & S0;
    Q <= '1';
    NQ <= '0';
    elsif (CLK'event and CLK='1') then
    if liczba = "0000" then
    Q <= '0';
    NQ <= '1';
    else
    liczba <= liczba-1;
    end if;
    end if;
    end process;

    end;
  • Poziom 15  
    Soker napisał:

    Czy wie ktoś może jak zrobić w vhdl'u układ który będzie generował impuls wyzwalany narastającym zboczem sygnału wejściowego, a czas trwania tego impulsu żeby był ustawiany na 4 bitach wejściowych. Zależy mi na czasach do 3 sekund i koniecznie aby układ zliczał od początku gdy przyjdzie kolejny impuls wyzwolenia a jeszcze nie skończył generować poprzedniego impulsu - tak jak układ 74123.
    Myślałem aby zrobić licznik, który będzie zliczał impulsy z generatora. Próbowałem coś takiego ale kompilator wyświetla komunikat "Process clocking is too complex"


    nie możesz używać konstrukcji ('event) do kilku sygnałów na raz. Kompilator nie potrafi wygenerować poprawnie równań - a tym bardziej taki zapis nie przejdzie przez syntezę.
    Przyjęło się, że zbocze wykrywa się tylko dla zegara - clk jest jedynym sygnałem czułym na zbocze (w większości projektów), a przyjamniej minimalizuje się liczbę zegarów - najlepiej jak jest tylko 1. Wszystkie inne sygnały mogą być synchronizowane w takt zegara - ale same nie powinny wypracowywać zboczy sterujących innymi blokami logicznymi.
    W HDL możesz napisać każdą bzdurę, poprawną pod kątem składni, ale w rzeczywistym układzie prawdopodobnie niedziałającą (jeśli w ogóle przejdzie to przez syntezę).

    Poniżej kod mojego pomysłu. Sygnały wejściowe synchronizowane zegarem (eliminacja skew). Detekcja zbocza w triggerze przez róźniczkowanie. Odmierzanie czasu licznikiem - zegar np. 1 Mhz => odmierzone czasy 1, 2, 3 sekund to jest ileś taktów clk wpisanych jako wartość początkowa do licznika. Najstarszy bit licznika jako flaga - sygnalizuje niedomiar licznika podczas zliczania i zatrzymuje zabawę.

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.STD_LOGIC_UNSIGNED.all;
    use IEEE.STD_LOGIC_ARITH.all;

    entity DelayCircuit is
    port(
    clk : in STD_LOGIC;
    Trigger : in STD_LOGIC;
    rst : in STD_LOGIC;
    S : in STD_LOGIC_VECTOR(1 downto 0);
    Q : out STD_LOGIC
    );
    end DelayCircuit;

    architecture RTL of DelayCircuit is
    signal TriggerRisingEdge, rst_sync: std_logic;
    signal tmp1: std_logic_vector(2 downto 0);
    signal tmp2: std_logic_vector(1 downto 0);
    signal cnt: std_logic_vector(23 downto 0);

    begin

    --synchronizacja triggera, rst
    process(clk)
    begin
    if (clk'event and clk = '1') then
    tmp1 <= tmp1(1 downto 0) & Trigger;
    tmp2 <= tmp2(0) & rst;
    end if;
    end process;

    rst_sync <= tmp2(1);

    --detekcja zbocza narastajacego
    process(clk)
    begin
    if (clk'event and clk = '1') then
    TriggerRisingEdge <= (not tmp1(2)) and tmp1(1);
    end if;
    end process;

    --odmierzanie czasu
    process(clk)
    begin
    if (clk'event and clk = '1') then
    if (rst_sync = '1') then
    cnt <= (others => '1');
    elsif (TriggerRisingEdge = '1') then
    case S is
    -- inicjalizacja licznika, zegar 1 MHz
    when "11" => cnt <= X"2dc6be"; -- 3 sekundy => (3 * 10^6) clk - 2
    when "10" => cnt <= X"1e847e"; -- 2 sekundy => (3 * 10^6) clk - 2
    when "01" => cnt <= X"0f423e"; -- 1 sekunda => (3 * 10^6) clk - 2
    when others => cnt <= (others => '1'); -- odmierzanie czasu zatrzymane
    end case;
    elsif (cnt(cnt'left) = '0') then
    cnt <= cnt - 1;
    end if;
    end if;
    end process;

    --sterowanie wyjsciem
    Q <= cnt(cnt'left);

    end RTL;
  • Poziom 11  
    Wielkie dzięki za wyjaśnienie problemu a przede wszystkim za programik.