2013-07-28 16 views
16

Jak utworzyć zegar w testbench? Ja już znalazłem jedną odpowiedź, ale inni na przepełnienie stosu sugerują, że istnieją alternatywne lub lepsze sposoby osiągnięcia tego:VHDL - Jak utworzyć zegar w testbench?

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 

ENTITY test_tb IS 
END test_tb; 

ARCHITECTURE behavior OF test_tb IS 

    COMPONENT test 
     PORT(clk : IN std_logic;) 
    END COMPONENT; 

    signal clk : std_logic := '0'; 
    constant clk_period : time := 1 ns; 

BEGIN 

    uut: test PORT MAP (clk => clk);  

    -- Clock process definitions(clock with 50% duty cycle is generated here. 
    clk_process :process 
    begin 
     clk <= '0'; 
     wait for clk_period/2; --for 0.5 ns signal is '0'. 
     clk <= '1'; 
     wait for clk_period/2; --for next 0.5 ns signal is '1'. 
    end process; 

END; 

(źródło here)

+0

Ta metoda działa dobrze. – Qiu

+0

http://electronics.stackexchange.com/questions/148320/proper-clock-generation-for-vhdl-testbenches –

Odpowiedz

17

Moim ulubionym technika:

signal clk : std_logic := '0'; -- make sure you initialise! 
... 
clk <= not clk after half_period; 

zwykle przedłużyć ten z sygnałem finished aby mnie zatrzymać zegar:

clk <= not clk after half_period when finished /= '1' else '0'; 
alert

Gotcha: ostrożność należy podjąć jeśli obliczyć half_period z innej stałej przez podzielenie przez 2. Symulator ma ustawienie "Rozdzielczość czasowa", które często jest domyślnie n anoseconds ... W takim przypadku 5 ns/2 wychodzi na numer 2 ns, więc kończy się okres 4ns! Ustaw symulator na pikosekundy i wszystko będzie dobrze (dopóki nie potrzebujesz ułamka pikosekundy, aby w ten sposób przedstawić czas zegarowy!)

7

Równoczesne przypisanie sygnału:

library ieee; 
use ieee.std_logic_1164.all; 

entity foo is 
end; 
architecture behave of foo is 
    signal clk: std_logic := '0'; 
begin 
CLOCK: 
clk <= '1' after 0.5 ns when clk = '0' else 
     '0' after 0.5 ns when clk = '1'; 
end; 

ghdl -a foo.vhdl
ghdl -r foo --stop czasie = 10ns --wave = foo.ghw
ghdl: info: s imulation zatrzymany przez --stop czasie
gtkwave foo.ghw

enter image description here

Symulatory symulować procesy i byłoby przekształcony w procesie równoważnym do wyciągu procesowego. Czas symulacji oznacza użycie oczekiwania na lub po wystąpieniu zdarzeń sterujących dla klauzul wrażliwości lub list czułości.

12

Jeśli generowanych jest wiele zegarów o różnych częstotliwościach, generowanie zegara można uprościć, jeśli zostanie wywołana procedura jako współbieżne wywołanie procedury. Rozdzielczość czasowa, o której wspominał Martin Thompson, może zostać nieco złagodzona przez zastosowanie innego wysokiego i niskiego czasu w procedurze. Ławka Test z procedury generacji zegara wynosi:

library ieee; 
use ieee.std_logic_1164.all; 

entity tb is 
end entity; 

architecture sim of tb is 

    -- Procedure for clock generation 
    procedure clk_gen(signal clk : out std_logic; constant FREQ : real) is 
    constant PERIOD : time := 1 sec/FREQ;  -- Full period 
    constant HIGH_TIME : time := PERIOD/2;   -- High time 
    constant LOW_TIME : time := PERIOD - HIGH_TIME; -- Low time; always >= HIGH_TIME 
    begin 
    -- Check the arguments 
    assert (HIGH_TIME /= 0 fs) report "clk_plain: High time is zero; time resolution to large for frequency" severity FAILURE; 
    -- Generate a clock cycle 
    loop 
     clk <= '1'; 
     wait for HIGH_TIME; 
     clk <= '0'; 
     wait for LOW_TIME; 
    end loop; 
    end procedure; 

    -- Clock frequency and signal 
    signal clk_166 : std_logic; 
    signal clk_125 : std_logic; 

begin 

    -- Clock generation with concurrent procedure call 
    clk_gen(clk_166, 166.667E6); -- 166.667 MHz clock 
    clk_gen(clk_125, 125.000E6); -- 125.000 MHz clock 

    -- Time resolution show 
    assert FALSE report "Time resolution: " & time'image(time'succ(0 fs)) severity NOTE; 

end architecture; 

rozdzielczość czasowa jest drukowana na terminalu do informacji za pomocą jednoczesnego assert ostatni w stanowisku badawczym.

Jeśli procedura clk_gen zostanie umieszczona w oddzielnym opakowaniu, ponowne użycie z stanowiska testowego na stanowisku badawczym stanie się proste.

Kształt fali dla zegarów pokazano na poniższym rysunku.

Waveforms for clk_166 and clk_125

bardziej zaawansowany generator zegara mogą być również tworzone w procedurze, która może dostosować okres w czasie, aby dopasować żądaną częstotliwość mimo ograniczenia przez rozdzielczością czasową.Jest to pokazane tutaj:

-- Advanced procedure for clock generation, with period adjust to match frequency over time, and run control by signal 
procedure clk_gen(signal clk : out std_logic; constant FREQ : real; PHASE : time := 0 fs; signal run : std_logic) is 
    constant HIGH_TIME : time := 0.5 sec/FREQ; -- High time as fixed value 
    variable low_time_v : time;     -- Low time calculated per cycle; always >= HIGH_TIME 
    variable cycles_v : real := 0.0;    -- Number of cycles 
    variable freq_time_v : time := 0 fs;   -- Time used for generation of cycles 
begin 
    -- Check the arguments 
    assert (HIGH_TIME /= 0 fs) report "clk_gen: High time is zero; time resolution to large for frequency" severity FAILURE; 
    -- Initial phase shift 
    clk <= '0'; 
    wait for PHASE; 
    -- Generate cycles 
    loop 
    -- Only high pulse if run is '1' or 'H' 
    if (run = '1') or (run = 'H') then 
     clk <= run; 
    end if; 
    wait for HIGH_TIME; 
    -- Low part of cycle 
    clk <= '0'; 
    low_time_v := 1 sec * ((cycles_v + 1.0)/FREQ) - freq_time_v - HIGH_TIME; -- + 1.0 for cycle after current 
    wait for low_time_v; 
    -- Cycle counter and time passed update 
    cycles_v := cycles_v + 1.0; 
    freq_time_v := freq_time_v + HIGH_TIME + low_time_v; 
    end loop; 
end procedure; 

Ponownie wykorzystanie przez pakiet będzie miłe.

0

Jak korzystać z zegara i zrobić twierdzeń

Ten przykład pokazuje, jak wygenerować zegar i dać wejść i wyjść dochodzić do każdego cyklu. Tutaj testowany jest prosty licznik.

Kluczową ideą jest to, że bloki process działają równolegle, więc zegar jest generowany równolegle z wejściami i asercjami.

library ieee; 
use ieee.std_logic_1164.all; 

entity counter_tb is 
end counter_tb; 

architecture behav of counter_tb is 
    constant width : natural := 2; 
    constant clk_period : time := 1 ns; 

    signal clk : std_logic := '0'; 
    signal data : std_logic_vector(width-1 downto 0); 
    signal count : std_logic_vector(width-1 downto 0); 

    type io_t is record 
     load : std_logic; 
     data : std_logic_vector(width-1 downto 0); 
     count : std_logic_vector(width-1 downto 0); 
    end record; 
    type ios_t is array (natural range <>) of io_t; 
    constant ios : ios_t := (
     ('1', "00", "00"), 
     ('0', "UU", "01"), 
     ('0', "UU", "10"), 
     ('0', "UU", "11"), 

     ('1', "10", "10"), 
     ('0', "UU", "11"), 
     ('0', "UU", "00"), 
     ('0', "UU", "01") 
    ); 
begin 
    counter_0: entity work.counter port map (clk, load, data, count); 

    process 
    begin 
     for i in ios'range loop 
      load <= ios(i).load; 
      data <= ios(i).data; 
      wait until falling_edge(clk); 
      assert count = ios(i).count; 
     end loop; 
     wait; 
    end process; 

    process 
    begin 
     for i in 1 to 2 * ios'length loop 
      wait for clk_period/2; 
      clk <= not clk; 
     end loop; 
     wait; 
    end process; 
end behav; 

Licznik będzie wyglądać następująco:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; -- unsigned 

entity counter is 
    generic (
     width : in natural := 2 
    ); 
    port (
     clk, load : in std_logic; 
     data : in std_logic_vector(width-1 downto 0); 
     count : out std_logic_vector(width-1 downto 0) 
    ); 
end entity counter; 

architecture rtl of counter is 
    signal cnt : unsigned(width-1 downto 0); 
begin 
    process(clk) is 
    begin 
     if rising_edge(clk) then 
      if load = '1' then 
       cnt <= unsigned(data); 
      else 
       cnt <= cnt + 1; 
      end if; 
     end if; 
    end process; 
    count <= std_logic_vector(cnt); 
end architecture rtl; 
Powiązane problemy