~ruther/vhdl-fir-filters

8eec5b61dd2ed188f948ffacd379a7ccf97c824f — Rutherther 1 year, 2 months ago 3ab43db
tests: add signal generator, signal adder, adc and xtal models
A tb/model/tb_adc_mod.vhd => tb/model/tb_adc_mod.vhd +100 -0
@@ 0,0 1,100 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.numeric_std.all;

use work.tb_adc_pkg.all;

library vunit_lib;
context vunit_lib.com_context;
context vunit_lib.vunit_context;
-- use vunit_lib.sync_pkg.all;

-- set sampling period
-- set current time
-- run, pause

entity tb_adc_mod is
  generic (
    inst_name : string := C_DEFAULT_INST_NAME;
    RESOLUTION : natural);

  port (
    clk_i          : in  std_logic;
    signal_i       : in  real;
    signal_o       : out std_logic_vector(RESOLUTION - 1 downto 0);
    clamped_o      : out std_logic;
    current_time_o : out time);

end entity tb_adc_mod;

architecture behav of tb_adc_mod is

  signal current_time       : time := 0 ns;

  signal sampling_frequency : real := 0.0;
  signal running            : std_logic := '0';

  signal max : real := 1.0;
  signal min : real := -1.0;

  signal set_time_to : time;
  signal set_time_request : event_t := new_event("set_time_request");
begin  -- architecture behav
  current_time_o <= current_time;

  set_output_time: process is
  begin  -- process set_output_time
    wait until rising_edge(clk_i) or is_active(set_time_request);

    if is_active_msg(set_time_request) then
      current_time <= set_time_to;
    elsif running = '1' then
      current_time <= current_time + (1_000_000_000.0 / sampling_frequency) * 1 ns;
    end if;
  end process set_output_time;

  sample: process (clk_i) is
  begin  -- process sample
    if rising_edge(clk_i) then          -- rising clock edge
      if signal_i < min then
        signal_o <= (others => '0');
        clamped_o <= '1';
      elsif signal_i > max then
        signal_o <= (others => '1');
        clamped_o <= '1';
      else
        signal_o <= std_logic_vector(to_unsigned(integer((signal_i - min) / (max - min) * (real(2 ** RESOLUTION) - 1.0)), RESOLUTION));
        clamped_o <= '0';
      end if;
    end if;
  end process sample;

  message_handler: process is
    constant actor : actor_t := new_actor(inst_name);
    variable request_msg : msg_t;
    variable msg_type : msg_type_t;
  begin  -- process message_handler
    receive(net, actor, request_msg);
    msg_type := message_type(request_msg);

    -- handle_sync_message(net, msg_type, request_msg);

    if msg_type = set_sampling_rate_msg then
      sampling_frequency <= pop(request_msg);
    elsif msg_type = set_current_time_msg then
      set_time_to <= pop(request_msg);
      notify(set_time_request);
    elsif msg_type = set_min_max_msg then
      min <= pop(request_msg);
      max <= pop(request_msg);
    elsif msg_type = run_msg then
      running <= '1';
    elsif msg_type = pause_msg then
      running <= '0';
    else
      unexpected_msg_type(msg_type);
    end if;
  end process message_handler;

end architecture behav;

A tb/model/tb_adc_pkg.vhd => tb/model/tb_adc_pkg.vhd +110 -0
@@ 0,0 1,110 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.com_context;
-- use vunit_lib.sync_pkg.all;

package tb_adc_pkg is
  constant set_sampling_rate_msg : msg_type_t := new_msg_type("adc set sampling rate");
  constant set_current_time_msg : msg_type_t := new_msg_type("adc set current time");
  constant set_min_max_msg : msg_type_t := new_msg_type("adc set min max");
  constant run_msg : msg_type_t := new_msg_type("adc run");
  constant pause_msg : msg_type_t := new_msg_type("adc pause");

  constant C_DEFAULT_INST_NAME : string := "adc_mod";

  impure function get_actor (
    constant inst_name : string := C_DEFAULT_INST_NAME)
    return actor_t;

  procedure run (
    signal net : inout network_t;
    constant inst_name : in string := C_DEFAULT_INST_NAME);

  procedure pause (
    signal net : inout network_t;
    constant inst_name : in string := C_DEFAULT_INST_NAME);

  procedure set_current_time (
    signal net : inout network_t;
    constant current_time : in time;
    constant inst_name : in string := C_DEFAULT_INST_NAME);

  procedure set_sampling_rate (
    signal net : inout network_t;
    constant sampling_frequency : in real;
    constant inst_name : in string := C_DEFAULT_INST_NAME);

  procedure set_min_max (
    signal net : inout network_t;
    constant min : in real;
    constant max : in real;
    constant inst_name : in string := C_DEFAULT_INST_NAME);

end package tb_adc_pkg;

package body tb_adc_pkg is


  impure function get_actor (
    constant inst_name : string := C_DEFAULT_INST_NAME)
    return actor_t is
  begin
    return find(inst_name);
  end function get_actor;

  procedure run (
    signal net : inout network_t;
    constant inst_name : in string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(run_msg);
  begin
    send(net, actor, msg);
  end procedure run;

  procedure pause (
    signal net : inout network_t;
    constant inst_name : in string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(pause_msg);
  begin
    send(net, actor, msg);
  end procedure pause;

  procedure set_current_time (
    signal net : inout network_t;
    constant current_time : in time;
    constant inst_name : in string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(set_current_time_msg);
  begin
    push(msg, current_time);
    send(net, actor, msg);
  end procedure set_current_time;

  procedure set_sampling_rate (
    signal net : inout network_t;
    constant sampling_frequency : in real;
    constant inst_name : in string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(set_sampling_rate_msg);
  begin
    push(msg, sampling_frequency);
    send(net, actor, msg);
  end procedure set_sampling_rate;

  procedure set_min_max (
    signal net : inout network_t;
    constant min : in real;
    constant max : in real;
    constant inst_name : in string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(set_sampling_rate_msg);
  begin
    push(msg, min);
    push(msg, max);
    send(net, actor, msg);
  end procedure set_min_max;

end package body tb_adc_pkg;

A tb/model/tb_sig_adder_mod.vhd => tb/model/tb_sig_adder_mod.vhd +76 -0
@@ 0,0 1,76 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;

library vunit_lib;
context vunit_lib.com_context;

use work.tb_sig_adder_pkg.all;

entity tb_sig_adder_mod is

  generic (
    inst_name : string := C_DEFAULT_INST_NAME;
    MAX_GENERATORS : natural);

  port (
    current_time_i : in  time;
    signal_o       : out real);

end entity tb_sig_adder_mod;

architecture behav of tb_sig_adder_mod is
  signal active_gen_count : integer range 0 to MAX_GENERATORS := 0;

  type real_arr_t is array (natural range <>) of real;
  signal outputs : real_arr_t(1 to MAX_GENERATORS);
begin  -- architecture behav

  generators: for i in 1 to MAX_GENERATORS generate
    generator: entity work.tb_sig_gen_mod
      generic map (
        inst_name => get_gen_inst_name(i, inst_name))
      port map (
        current_time_i => current_time_i,
        signal_o => outputs(i)
    );
  end generate generators;

  summer: process (all) is
    variable sum : real := 0.0;
  begin  -- process sum_output
    sum := 0.0;
    for i in 1 to active_gen_count loop
      sum := sum + outputs(i);
    end loop;  -- i

    signal_o <= sum;
  end process summer;

  message_handler: process is
    constant actor : actor_t := new_actor(inst_name);
    variable request_msg, reply_msg : msg_t;
    variable msg_type : msg_type_t;
  begin  -- process message_handler
    receive(net, actor, request_msg);
    msg_type := message_type(request_msg);

    -- handle_sync_message(net, msg_type, request_msg);

    if msg_type = push_msg then
      reply_msg := new_msg;
      push(reply_msg, active_gen_count + 1);

      active_gen_count <= active_gen_count + 1;

      reply(net, request_msg, reply_msg);
    elsif msg_type = pop_msg then
      active_gen_count <= active_gen_count - 1;
    elsif msg_type = clear_msg then
      active_gen_count <= 0;
    else
      unexpected_msg_type(msg_type);
    end if;
  end process message_handler;

end architecture behav;

A tb/model/tb_sig_adder_pkg.vhd => tb/model/tb_sig_adder_pkg.vhd +109 -0
@@ 0,0 1,109 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.com_context;

use work.tb_sig_gen_pkg;

package tb_sig_adder_pkg is

  constant push_msg : msg_type_t := new_msg_type("adder push");
  constant pop_msg : msg_type_t := new_msg_type("adder pop");
  constant clear_msg : msg_type_t := new_msg_type("adder pop");

  constant C_DEFAULT_INST_NAME : string := "sig_adder_mod";

  impure function get_actor (
    constant inst_name : string := C_DEFAULT_INST_NAME)
    return actor_t;

  procedure push_gen (
    signal net         : inout network_t;
    variable gen_actor : out   actor_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  procedure pop_gen (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  procedure clear_gens (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  impure function get_gen_actor (
    constant index     : in    natural;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return actor_t;

  function get_gen_inst_name (
    constant index     : in    natural;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return string;

end package tb_sig_adder_pkg;

package body tb_sig_adder_pkg is

  impure function get_actor (
    constant inst_name : string := C_DEFAULT_INST_NAME)
    return actor_t is
  begin
    return find(inst_name);
  end function get_actor;

  procedure push_gen (
    signal net         : inout network_t;
    variable gen_actor : out   actor_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);

    variable msg : msg_t := new_msg(push_msg);
    variable reply_msg : msg_t;
    variable retrieved_index : natural;

  begin
    request(net, actor, msg, reply_msg);

    retrieved_index := pop(reply_msg);
    delete(reply_msg);

    gen_actor := get_gen_actor(retrieved_index, inst_name);

  end procedure push_gen;

  procedure pop_gen (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is

    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(pop_msg);

  begin
    send(net, actor, msg);
  end procedure pop_gen;

  procedure clear_gens (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is

    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(clear_msg);

  begin
    send(net, actor, msg);
  end procedure clear_gens;

  impure function get_gen_actor (
    constant index     : in    natural;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return actor_t is
  begin
    return tb_sig_gen_pkg.get_actor(get_gen_inst_name(index, inst_name));
  end function get_gen_actor;

  function get_gen_inst_name (
    constant index     : in    natural;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return string is
  begin
    return inst_name & ":generator:" & natural'image(index);
  end function get_gen_inst_name;

end package body tb_sig_adder_pkg;

A tb/model/tb_sig_gen_mod.vhd => tb/model/tb_sig_gen_mod.vhd +167 -0
@@ 0,0 1,167 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.float_pkg.all;

library vunit_lib;
context vunit_lib.com_context;
-- use vunit_lib.sync_pkg.all;

use work.tb_sig_gen_pkg.all;

-- set frequency
-- set phase
-- set delay
-- set low level, high level
-- set shape (triangle, rectangle, sine)

entity tb_sig_gen_mod is

  generic (
    inst_name : string := C_DEFAULT_INST_NAME);

  port (
    current_time_i : in time;
    signal_o : out real);

end entity tb_sig_gen_mod;

architecture behav of tb_sig_gen_mod is
  signal shape : sig_gen_shape_t := SIG_SHAPE_NONE;

  signal frequency : real := 0.0;

  signal min_level : real := -1.0;
  signal max_level : real := 1.0;

  signal delay : time := 0 ns;

  signal phase : real := 0.0;

  function to_seconds_real (
    t : time)
    return real is
  begin
    return real(t / 1 ns) / 1_000_000_000.0;
  end function to_seconds_real;

  function get_period (
    frequency : real)
    return real is
  begin  -- function get_period
    if frequency = 0.0 then
      return 0.0; -- should be inifity
    end if;

    return 1.0 / frequency;
  end function get_period;

  function get_triangle_value (
    t   : time;
    frequency: real;
    min : real;
    max: real;
    delay: time)
    return real is
    constant period : real := get_period(frequency);
    constant position : real := to_seconds_real(t - delay) mod period / period;
  begin
    if position < 0.5 then
      -- go up
      return 2.0 * position * (max - min) + min;
    else
      -- go down
      return 2.0 * (position - 0.5) * (min - max) + max;
    end if;
  end function get_triangle_value;

  function get_rectangle_value (
    t : time;
    frequency: real;
    min : real;
    max: real;
    delay: time)
    return real is
    constant period : real := get_period(frequency);
    constant position : real := to_seconds_real(t - delay) mod period;
  begin
    if position < period / 2.0 then
      return max;
    else
      return min;
    end if;
  end function get_rectangle_value;

  function get_sine_value (
    t   : time;
    frequency: real;
    min : real;
    max: real;
    delay: time;
    phase: real)
    return real is
  begin
    return SIN(2.0 * MATH_PI * frequency * (to_seconds_real(t - delay)) + phase);
  end function get_sine_value;

begin  -- architecture behav

  signal_gen: process (all) is
    variable sig : real := 0.0;
  begin  -- process signal_gen
    case shape is
      when SIG_SHAPE_NONE => sig := 0.0;
      when SIG_SHAPE_TRIANGLE => sig := get_triangle_value(current_time_i, frequency => frequency, min => min_level, max => max_level, delay => delay);
      when SIG_SHAPE_RECTANGLE => sig := get_rectangle_value(current_time_i, frequency => frequency, min => min_level, max => max_level, delay => delay);
      when SIG_SHAPE_SINE => sig := get_sine_value(current_time_i, frequency => frequency, min => min_level, max => max_level, delay => delay, phase => phase);
      when others => report "Unknown signal shape" severity failure;
    end case;

    signal_o <= sig;
  end process signal_gen;

  message_handler: process is
    constant self : actor_t := new_actor(inst_name);

    variable request_msg : msg_t;
    variable msg_type : msg_type_t;

    variable request_frequency : real;
    variable request_min_level : real;
    variable request_max_level : real;
    variable request_delay : time;
    variable request_phase : real;
    variable request_shape : integer;
  begin  -- process command_bus
    report "Reporting for duty """ & name(self) & """";
    receive(net, self, request_msg);
    msg_type := message_type(request_msg);

    report "Got msg";

    if msg_type = set_frequency_msg then
      request_frequency := pop(request_msg);
      frequency <= request_frequency;
    elsif msg_type = set_min_level_msg then
      request_min_level := pop(request_msg);
      min_level <= request_min_level;
    elsif msg_type = set_max_level_msg then
      request_max_level := pop(request_msg);
      max_level <= request_max_level;
    elsif msg_type = set_delay_msg then
      request_delay := pop(request_msg);
      delay <= request_delay;
    elsif msg_type = set_phase_msg then
      request_phase := pop(request_msg);
      phase <= request_phase;
    elsif msg_type = set_shape_msg then
      report "Setting shape";
      request_shape := pop(request_msg);
      shape <= sig_gen_shape_t'val(request_shape);
    else
      unexpected_msg_type(msg_type);
    end if;

  end process message_handler;

end architecture behav;

A tb/model/tb_sig_gen_pkg.vhd => tb/model/tb_sig_gen_pkg.vhd +141 -0
@@ 0,0 1,141 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.com_context;

package tb_sig_gen_pkg is
  constant set_frequency_msg : msg_type_t := new_msg_type("gen set frequency");
  constant set_min_level_msg : msg_type_t := new_msg_type("gen set min level");
  constant set_max_level_msg : msg_type_t := new_msg_type("gen set max level");
  constant set_delay_msg : msg_type_t := new_msg_type("gen set delay");
  constant set_phase_msg : msg_type_t := new_msg_type("gen set phase");
  constant set_shape_msg : msg_type_t := new_msg_type("gen set shape");

  constant C_DEFAULT_INST_NAME : string := "sig_gen_mod";

  type sig_gen_shape_t is (
    SIG_SHAPE_NONE,
    SIG_SHAPE_TRIANGLE,
    SIG_SHAPE_RECTANGLE,
    SIG_SHAPE_SINE
  );

  impure function get_actor (
    constant inst_name : in string := C_DEFAULT_INST_NAME) return actor_t;

  procedure set_frequency (
    signal net         : inout network_t;
    constant frequency : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

  procedure set_min_level (
    signal net         : inout network_t;
    constant min_level : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

  procedure set_max_level (
    signal net         : inout network_t;
    constant max_level : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

  procedure set_delay (
    signal net     : inout network_t;
    constant delay : in    time;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

  procedure set_phase (
    signal net     : inout network_t;
    constant phase : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

  procedure set_shape (
    signal net     : inout network_t;
    constant shape : in    sig_gen_shape_t;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME));

end package tb_sig_gen_pkg;

package body tb_sig_gen_pkg is

  impure function get_actor (
    constant inst_name : in string := C_DEFAULT_INST_NAME) return actor_t is
  begin
    return find(inst_name);
  end function get_actor;

  procedure set_frequency (
    signal net         : inout network_t;
    constant frequency : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_frequency_msg);

  begin
    push(msg, frequency);
    send(net, actor, msg);
  end procedure set_frequency;

  procedure set_min_level (
    signal net         : inout network_t;
    constant min_level : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_min_level_msg);

  begin
    push(msg, min_level);
    send(net, actor, msg);
  end procedure set_min_level;

  procedure set_max_level (
    signal net         : inout network_t;
    constant max_level : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_max_level_msg);

  begin
    push(msg, max_level);
    send(net, actor, msg);
  end procedure set_max_level;

  procedure set_delay (
    signal net     : inout network_t;
    constant delay : in    time;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_delay_msg);

  begin
    push(msg, delay);
    send(net, actor, msg);
  end procedure set_delay;

  procedure set_phase (
    signal net     : inout network_t;
    constant phase : in    real;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_phase_msg);

  begin
    push(msg, phase);
    send(net, actor, msg);
  end procedure set_phase;

  procedure set_shape (
    signal net     : inout network_t;
    constant shape : in    sig_gen_shape_t;
    constant actor : in actor_t := get_actor(C_DEFAULT_INST_NAME)) is

    variable msg : msg_t := new_msg(set_shape_msg);

  begin

    push(msg, sig_gen_shape_t'pos(shape));
    send(net, actor, msg);
  end procedure set_shape;


end package body tb_sig_gen_pkg;

A tb/model/tb_xtal_mod.vhd => tb/model/tb_xtal_mod.vhd +67 -0
@@ 0,0 1,67 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.com_context;

use work.tb_xtal_pkg.all;

entity tb_xtal_mod is

  generic (
    default_frequency : real;
    inst_name         : string := C_DEFAULT_INST_NAME);

  port (
    clk_o : out std_logic);

end entity tb_xtal_mod;

architecture behav of tb_xtal_mod is
  function get_period (
    constant frequency : real)
    return time is
  begin  -- function get_period
    return (1_000_000_000.0 / frequency) * 1 ns;
  end function get_period;

  signal frequency : real := default_frequency;
  signal enabled : std_logic := '1';
begin  -- architecture behav

  set_clk: process is
    variable curr_period : time;
  begin  -- process set_clk
    curr_period := get_period(frequency);

    if enabled = '0' then
      wait until enabled = '1';
    end if;

    wait for curr_period / 2;
    clk_o <= '1';
    wait for curr_period / 2;
    clk_o <= '0';
  end process set_clk;

  message_handler: process is
    constant actor : actor_t := new_actor(inst_name);

    variable request_msg : msg_t;
    variable msg_type : msg_type_t;
  begin  -- process message_handler
    receive(net, actor, request_msg);
    msg_type := message_type(request_msg);

    if msg_type = enable_msg then
      enabled <= '1';
    elsif msg_type = disable_msg then
      enabled <= '0';
    elsif msg_type = set_frequency_msg then
      frequency <= pop(request_msg);
    else
      unexpected_msg_type(msg_type);
    end if;
  end process message_handler;

end architecture behav;

A tb/model/tb_xtal_pkg.vhd => tb/model/tb_xtal_pkg.vhd +69 -0
@@ 0,0 1,69 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.com_context;
-- use vunit_lib.sync_pkg.all;

package tb_xtal_pkg is
  constant enable_msg : msg_type_t := new_msg_type("xtal enable");
  constant disable_msg : msg_type_t := new_msg_type("xtal disable");
  constant set_frequency_msg : msg_type_t := new_msg_type("xtal set frequency");

  constant C_DEFAULT_INST_NAME : string := "xtal_mod";

  procedure enable (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  procedure disable (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  procedure set_frequency (
    signal net         : inout network_t;
    constant frequency : in    real;
    constant inst_name : in    string := C_DEFAULT_INST_NAME);

  impure function get_actor (
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return actor_t;

end package tb_xtal_pkg;

package body tb_xtal_pkg is
  impure function get_actor (
    constant inst_name : in    string := C_DEFAULT_INST_NAME) return actor_t is
  begin
    return find(inst_name);
  end function get_actor;

  procedure enable (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(enable_msg);
  begin
    send(net, actor, msg);
  end procedure enable;

  procedure disable (
    signal net         : inout network_t;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(disable_msg);
  begin
    send(net, actor, msg);
  end procedure disable;

  procedure set_frequency (
    signal net         : inout network_t;
    constant frequency : in    real;
    constant inst_name : in    string := C_DEFAULT_INST_NAME) is
    constant actor : actor_t := get_actor(inst_name);
    variable msg : msg_t := new_msg(set_frequency_msg);
  begin
    push(msg, frequency);
    send(net, actor, msg);
  end procedure set_frequency;

end package body tb_xtal_pkg;

A tb/test.vhd => tb/test.vhd +97 -0
@@ 0,0 1,97 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.com_context;

use work.tb_sig_adder_pkg;
use work.tb_sig_gen_pkg;
use work.tb_adc_pkg;

library filter;

entity test is

  generic (
    runner_cfg : string);

end entity test;

architecture tb of test is
  constant frequency : real := 1_000_000.0;

  signal current_time : time;

  signal sig : real;
  signal sampled_sig  : std_logic_vector(11 downto 0);
  signal filtered_sig : std_logic_vector(11 downto 0);

  signal clk : std_logic;
  signal rst_n : std_logic := '0';
begin  -- architecture tb

  main: process is
    variable generator : actor_t;
  begin  -- process main
    test_runner_setup(runner, runner_cfg);

    wait until rst_n = '1';
    wait until clk = '0';

    while test_suite loop
      if run("test") then
        tb_sig_adder_pkg.push_gen(net, generator);
        tb_sig_gen_pkg.set_frequency(net, 1000.0, actor => generator);
        tb_sig_gen_pkg.set_shape(net, tb_sig_gen_pkg.SIG_SHAPE_SINE, actor => generator);

        tb_sig_adder_pkg.push_gen(net, generator);
        tb_sig_gen_pkg.set_frequency(net, 2000.0, actor => generator);
        tb_sig_gen_pkg.set_shape(net, tb_sig_gen_pkg.SIG_SHAPE_SINE, actor => generator);

        tb_adc_pkg.set_min_max(net, -2.0, 2.0);
        tb_adc_pkg.set_sampling_rate(net, frequency);
        tb_adc_pkg.run(net);

        wait for 100 ms;
      end if;
    end loop;

    report "Ending";
    test_runner_cleanup(runner);
  end process main;

  rst_n <= '1' after 10 us;

  dut: entity filter.filter
    generic map (
      RESOLUTION => 12)
    port map (
      clk_i    => clk,
      rst_in   => rst_n,
      signal_i => sampled_sig,
      signal_o => filtered_sig);

  adder: entity work.tb_sig_adder_mod
    generic map (
      MAX_GENERATORS => 5)
    port map (
      current_time_i => current_time,
      signal_o       => sig);

  adc: entity work.tb_adc_mod
    generic map (
      RESOLUTION => 12)
    port map (
      clk_i          => clk,
      signal_i       => sig,
      signal_o       => sampled_sig,
      current_time_o => current_time);

  xtal: entity work.tb_xtal_mod
    generic map (
      default_frequency => frequency)
    port map (
      clk_o => clk);

end architecture tb;

Do not follow this link