how to generate in vhdl in my testbench using a procedure two signals with different frequencies and delays

huangapple go评论64阅读模式
英文:

how to generate in vhdl in my testbench using a procedure two signals with different frequencies and delays

问题

我目前正在尝试在我的测试台(VHDL)中生成两个信号,这两个信号具有不同的延迟、不同的占空比和两个不同的周期。这两个信号必须并行执行,而不是按顺序执行,它们需要在单个主过程中进行,包含这两个信号的6个参数(周期1、延迟1、占空比1、周期2、延迟2和占空比2)。我的问题是第二个信号不是在期望的时刻激活,而是在第一个信号被执行之后才被激活,这是合理的,因为执行是顺序的。我如何能够让第二个信号在期望的延迟时间激活?

我已经为每个信号编写了两个过程和一个用于将它们一起调用的主过程。我希望能够让两个信号都在它们各自的延迟时间独立激活。

以下是您提供的代码的翻译部分:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;

library work;
use work.all;

entity paralell is
end paralell;

architecture paralell_arch of paralell is

constant c_CLOCK_PERIOD : time := 40 ns;
signal  L1   : std_logic := '0';
signal  L2  : std_logic := '0';  

begin
    UUT : entity work.paralel
     port map (
       clk => r_CLOCK,
        sig1 => L1,
       sig2 => L2,
       
       );   
  p_CLK_GEN : process is
  begin
    wait for c_CLOCK_PERIOD/2;
    r_CLOCK <= not r_CLOCK;
  end process p_CLK_GEN;

-- 以下为您提供的其他代码部分,包括 parametre_2、parametre_1 和 parametre 过程,以及主测试过程。
-- 请注意,这里只提供翻译,不包括代码内容。

如果您需要进一步的帮助或翻译其他部分,请告诉我。

英文:

I am currently trying to generate two signals in my testbench (VHDL) with a different delay, a different duty cycle and two different periods. The two signals must be carried out in parallel and not sequentially in a single main procedure containing the 6 parameters of the two signals (period1, delay1, duty cycle1, period2, delay2 and duty circle2). My problem is that the second signal is not activated at the desired moment but after the first signal has been exercised, which is logical since the execution is sequential. How can I get the second signal to activate at the desired Delay?

I've written two procedures for each signal and a main procedure for recalling them together. I hope to be able to have both signals activated at their respective delays independently of each other.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;

library work;
use work.all;

entity paralell is
end paralell;

architecture paralell_arch of paralell is

constant c_CLOCK_PERIOD : time := 40 ns;
signal  L1   : std_logic := &#39;0&#39;;
signal  L2  : std_logic := &#39;0&#39;;  
 	
begin
    UUT : entity work.paralel
     port map (
       clk =&gt; r_CLOCK,
        sig1 =&gt; L1,
	   sig2 =&gt; 	L2,
       
       );   
  p_CLK_GEN : process is
  begin
    wait for c_CLOCK_PERIOD/2;
    r_CLOCK &lt;= not r_CLOCK;
  end process p_CLK_GEN;
Simulation : process   -- main testing
procedure parametre_2(T6 : time; D6 : time; Delay6 : time) is
  begin
    L2 &lt;= &#39;0&#39;;
    if Delay6 &gt;= 0 ns then
    wait for Delay6;
    end if;
    L2 &lt;= &#39;1&#39;;
    wait for D6;
    L2 &lt;= &#39;0&#39;;
    wait for (T6 - D6);
  end procedure parametre_2;
  
  procedure parametre_1(T5 : time; D5 : time; Delay5 : time) is
        begin
          L1 &lt;= &#39;0&#39;;
        if Delay5 &gt;= 0 ns then
          wait for Delay5;
        end if;
          L1 &lt;= &#39;1&#39;;
        if D5 &gt;= 0 ns then
          wait for D5;
        end if;
          L1 &lt;= &#39;0&#39;;
          wait for (T5 - D5);
        end procedure parametre_1;
  	``` 
      ``` 
 procedure parametre(T3 : time; D3 : time; Delay1 : time; T4 : time; D4 :time; Delay2 : time)is
  begin
   for i in 0 to 1 loop
     if i = 0 then 
         parametre_1(T3, D3, Delay1);
  		elsif i= 1 then
         parametre_2(T4, D4, Delay2);
  	   end if;
  	   end loop;
  	   
end procedure parametre;
begin
parametre(400 us, 200 us, 10 ns , 100 us , 50 us,20 ns);
  report &quot; Simulation finished successfully!&quot; severity note;
  wait;
end process;
end paralell_arch;

答案1

得分: 1

首先,对于不是学院练习的情况,请使用两个单独的时钟生成器。OSVVM库提供了以下功能(请参阅https://github.com/OSVVM/OsvvmLibraries)。在架构中进行调用,而不是在进程中。

osvvm.TbUtilPkg.CreateClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ; 
osvvm.TbUtilPkg.CreateClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ; 

如果出于某种原因,学院练习要求我从同一个进程中调用它们,我会采取以下步骤。作为一种替代方法,不需要在ClockProc的开头将Clk1和Clk2驱动到'1',你可以在声明中将它们初始化为'1'。虽然这对于有经验的VHDL人来说是一个有趣的挑战,但如果有人对VHDL不熟悉的话,能够完成这个任务会让我印象深刻。但是,我要警告你,这可能是一个测试,用来检查你是否在SO上提问了一个作业问题。我建议提交与我上面推荐的类似的内容,因为这在新手的能力范围内。

library IEEE ;
use ieee.std_logic_1164.all ; 
entity TwoClockOneProcess is 
end entity TwoClockOneProcess ; 
architecture test of TwoClockOneProcess is 
  signal Clk1, Clk2 : std_logic := '1' ; 
  constant PERIOD_1 : time := 8 ns ;
  constant DUTY_CYCLE_1 : real := 0.5 ; 
  constant PERIOD_2 : time := 5 ns ; 
  constant DUTY_CYCLE_2 : real := 0.75 ; 
begin
 ClockProc : process
    procedure LocalClock(
      signal Clk         : inout std_logic ; 
      constant Period    : in    time ; 
      constant DutyCycle : in    real 
    ) is 
    begin
      Clk <= transport '0' after Period * DutyCycle, '1' after Period ;
    end procedure LocalClock ; 
  begin
    Clk1 <= '1' ; 
    LocalClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ;
    Clk2 <= '1' ; 
    LocalClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ; 
    loop 
      wait on Clk1, Clk2 ; 
      if rising_edge(Clk1) then 
        LocalClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ;
      end if ; 
      if rising_edge(Clk2) then 
        LocalClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ;
      end if ; 
    end loop ; 
  end process ClockProc ; 
end architecture test ; 
英文:

First, for something that is not a college exercise, use two separate clock generators. OSVVM library provides the following (see https://github.com/OSVVM/OsvvmLibraries). Do the calls in the architecture, not a process.

osvvm.TbUtilPkg.CreateClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ; 
osvvm.TbUtilPkg.CreateClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ; 

If for some reason a college exercise required me to dispatch these from the same process, I would do the following. As an alternative to driving Clk1 and Clk2 to a '1' in the beginning of ClockProc, you could have initialized them to '1' in the declaration. While this is an interesting challenge for an experienced VHDL person, I would impressed if someone new to VHDL were able to accomplish this - that said, I will warn you that this may be a test to see if you asked a homework question on SO. I would recommend turning in something similar to what I recommended above as that is well within a new person's capability.

library IEEE ;
use ieee.std_logic_1164.all ; 
entity TwoClockOneProcess is 
end entity TwoClockOneProcess ; 
architecture test of TwoClockOneProcess is 
  signal Clk1, Clk2 : std_logic := &#39;1&#39; ; 
  constant PERIOD_1 : time := 8 ns ;
  constant DUTY_CYCLE_1 : real := 0.5 ; 
  constant PERIOD_2 : time := 5 ns ; 
  constant DUTY_CYCLE_2 : real := 0.75 ; 
begin
 ClockProc : process
    procedure LocalClock(
      signal Clk         : inout std_logic ; 
      constant Period    : in    time ; 
      constant DutyCycle : in    real 
    ) is 
    begin
      Clk &lt;= transport &#39;0&#39; after Period * DutyCycle, &#39;1&#39; after Period ;
    end procedure LocalClock ; 
  begin
    Clk1 &lt;= &#39;1&#39; ; 
    LocalClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ;
    Clk2 &lt;= &#39;1&#39; ; 
    LocalClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ; 
    loop 
      wait on Clk1, Clk2 ; 
      if rising_edge(Clk1) then 
        LocalClock(Clk1, PERIOD_1, DUTY_CYCLE_1) ;
      end if ; 
      if rising_edge(Clk2) then 
        LocalClock(Clk2, PERIOD_2, DUTY_CYCLE_2) ;
      end if ; 
    end loop ; 
  end process ClockProc ; 
end architecture test ; 

答案2

得分: 0

我同意Jim的简化方法,但以下是一种备选方法,用于从一个进程中安排所有事件,如果有许多时钟,则可以很好地扩展:

    architecture test of two_clocks_in_one_process is
      signal clocks : std_logic_vector(1 to 2) := "00";
      constant delays : time_vector(clocks'range) := (10 ns, 20 ns);
      constant high_widths : time_vector(clocks'range) := (200 ns, 50 ns);
      constant periods : time_vector(clocks'range) := (400 ns, 100 ns);
    begin
      clock_driver : process is
        variable next_event : time_vector(clocks'range) := delays;
      begin
        wait for minimum(next_event) - now;
        for idx in clocks'range loop
          if now = next_event(idx) then
            clocks(idx) <= '1', '0' after high_widths(idx);
            next_event(idx) := now + periods(idx);
          end if;
        end loop;
      end process;
    end architecture;
英文:

I would agree with Jim on the simpler approach but here is an alternative for scheduling all events from one process that scales well if there are many clocks:

architecture test of two_clocks_in_one_process is
  signal clocks : std_logic_vector(1 to 2) := &quot;00&quot;;
  constant delays : time_vector(clocks&#39;range) := (10 ns, 20 ns);
  constant high_widths : time_vector(clocks&#39;range) := (200 ns, 50 ns);
  constant periods : time_vector(clocks&#39;range) := (400 ns, 100 ns);
begin
  clock_driver : process is
    variable next_event : time_vector(clocks&#39;range) := delays;
  begin
    wait for minimum(next_event) - now;
    for idx in clocks&#39;range loop
      if now = next_event(idx) then
        clocks(idx) &lt;= &#39;1&#39;, &#39;0&#39; after high_widths(idx);
        next_event(idx) := now + periods(idx);
      end if;
    end loop;
  end process;
end architecture;

huangapple
  • 本文由 发表于 2023年7月10日 19:03:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定