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

entity pdmout_test is
end pdmout_test;

architecture rtl of pdmout_test is

  component pdmout is
    port
    (
      clk     : in std_logic;
      rst     : in std_logic;

    -- hardware
      out_pin  : out std_logic;

    -- bus interface
      we      : in std_logic;
      addr    : in std_logic_vector(15 downto 0);
      din     : in std_logic_vector(15 downto 0)
    );
  end component;

  signal finished: std_logic := '0';
  signal clk: std_logic := '0';
  signal rst, bus_we, pdm_out: std_logic;
  signal bus_miso, bus_mosi, bus_addr: std_logic_vector(15 downto 0);

begin
  dut: pdmout port map(clk => clk, rst => rst, out_pin => pdm_out,
                       we => bus_we, addr => bus_addr,
                       din => bus_mosi);

  process
  begin
    if finished = '0' then
      clk <= not clk;
      wait for 5 ns;
    else
      clk <= '0';
      wait;
    end if;
  end process;

  process
  begin
    rst <= '1';

    wait for 1 ns;
    assert(pdm_out='0') report "Fail rst" severity error;

    rst <= '0';

    wait for 10 ns;

    bus_addr <= x"0000";
    bus_mosi <= x"8000";
    bus_we <= '1';

    wait for 10 ns;
    assert(pdm_out='0') report "enabled didn't work?" severity error;

    bus_addr <= x"0002";
    bus_mosi <= x"0001";
    bus_we <= '1';

    wait for 10 ns;

    bus_addr <= x"0000";
    bus_we <= '0';

    wait for 20 ns;
    assert(pdm_out='1') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='1') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='1') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;

    bus_addr <= x"0000";
    bus_mosi <= x"0000";
    bus_we <= '1';

    wait for 10 ns;

    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;

    bus_addr <= x"0000";
    bus_mosi <= x"4000";
    bus_we <= '1';
    wait for 10 ns;

    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='1') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='1') report "output is wrong" severity error;
    wait for 10 ns;
    assert(pdm_out='0') report "output is wrong" severity error;


    assert false report "Test done." severity note;

    finished <= '1';
    wait;

  end process;
end rtl;