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

entity dsp_test is
end dsp_test;

architecture rtl of dsp_test is

  component clock is port(clk: out std_logic);
  end component;

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

          led: out std_logic_vector(7 downto 0);

          uart0_rx: in std_logic;
          uart0_tx: out std_logic;

          pdmout0_pin: out std_logic;

          uart1_rx: in std_logic;
          uart1_tx: out std_logic
        );
  end component;

  signal finished, clk, rst: std_logic := '0';

  signal led: std_logic_vector(7 downto 0);

  signal uart0_rx: std_logic;
  signal uart0_tx: std_logic;
  signal uart1_rx: std_logic;
  signal uart1_tx: std_logic;
  signal pdmout0: std_logic;

  type str is array(integer range <>) of std_logic_vector(7 downto 0);
  signal prog: str(0 to 7) := (
        x"63", x"11", x"00", x"04", x"e0", x"00", x"5e", x"00");
  signal jump: str(0 to 2) := (
        x"6a", x"11", x"00");

  constant UART_PERIOD: time := 1000 ns;

  procedure uart_send(
                       signal s: in str;
                       signal o: out std_logic
                     ) is
  begin
    for i in s'range loop
      o <= '0';  -- start bit
      wait for UART_PERIOD;

      for j in 0 to 7 loop
        o <= s(i)(j);
        wait for UART_PERIOD;
      end loop;

      o <= '1';  -- stop bit
      wait for UART_PERIOD;
    end loop;
  end procedure;

begin
  dut: dsp port map(clk => clk, rst => rst,
                    led => led, uart0_rx => uart0_rx, uart0_tx => uart0_tx,
                    uart1_rx => uart1_rx, uart1_tx => uart1_tx,
                    pdmout0_pin => pdmout0);


  clk <= not clk after 5 ns when finished /= '1' else '0';

  process
  begin
    rst <= '1';

    uart0_rx <= '1';

    wait for 15 ns;
    assert(led=x"00") report "Fail rst" severity error;

    rst <= '0';

    wait for 20 us;
    uart_send(prog, uart0_rx);
    wait for 2 us;
    assert(led = x"f0") report "Fail prog" severity error;
--    uart_send(jump, uart0_rx);
--    wait for 2 us;
--    assert(led = x"2a") report "Fail prog" severity error;

--    wait for 200 us;

--    uart_send(midi, uart1_rx);

    assert false report "Test done." severity note;

    finished <= '1';
    wait;
  end process;
end rtl;