VHDL - 我应该如何在测试平台中创建时钟?

ale*_*vey 21 simulation clock vhdl hardware-programming

我应该如何在测试平台中创建时钟?我已经找到了一个答案,但是有关堆栈溢出的其他人已经建议有其他或更好的方法来实现这一点:

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;
Run Code Online (Sandbox Code Playgroud)

(来源这里)

Mar*_*son 26

我最喜欢的技术:

signal clk : std_logic := '0'; -- make sure you initialise!
...
clk <= not clk after half_period;
Run Code Online (Sandbox Code Playgroud)

我通常用一个finished信号来扩展它以允许我停止时钟:

clk <= not clk after half_period when finished /= '1' else '0';
Run Code Online (Sandbox Code Playgroud)

疑难杂症警报:护理需要采取如果你计算half_period通过除以2,从另一个常量模拟器有一个"时间分辨率"设置,通常默认为纳秒......在这种情况下,5 ns / 2出来是2 ns那么你最终一段时间4ns!将模拟器设置为皮秒,一切都会很好(直到你需要一个皮秒的分数代表你的时钟时间!)


Mor*_*mer 18

如果以不同的频率生成多个时钟,则如果将过程称为并发过程调用,则可以简化时钟生成.Martin Thompson提到的时间分辨率问题可以通过在程序中使用不同的高低时间来缓解.具有时钟生成程序的测试平台是:

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;
Run Code Online (Sandbox Code Playgroud)

时间分辨率打印在终端上以供参考,使用测试台中的并发断言.

如果clk_gen程序放在一个单独的包中,那么从测试台到测试台的重用变得简单.

时钟波形如下图所示.

clk_166和clk_125的波形

在该过程中还可以创建更高级的时钟发生器,其可以随时间调整周期以匹配所请求的频率,尽管受到时间分辨率的限制.这显示在这里:

-- 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;
Run Code Online (Sandbox Code Playgroud)

再次通过包重用将是很好的.


use*_*120 9

并发信号分配:

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;
Run Code Online (Sandbox Code Playgroud)

ghdl -a foo.vhdl
ghdl -r foo --stop-time = 10ns --wave = foo.ghw
ghdl:info:模拟停止--stop-time
gtkwave foo.ghw

在此输入图像描述

模拟器模拟流程,并将其转换为流程语句的等效流程.模拟时间意味着在为敏感子条款或敏感性列表驱动事件时使用等待或之后.