library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Numeric_Std.all;
use WORK.MokuSupport.all;

entity {{top_entity}} is
    generic (
        NUM_AIN : integer;
        NUM_AOUT : integer;
        NUM_CBUFS : integer
        -- add custom generics here
    );
    port (
        -- This interface must match the platform as cannot be modified
        Clk : in std_logic;
        Reset : in std_logic;
        Sync : in std_logic;

        AIn : in AInChannelArray(0 to NUM_AIN - 1);
        AOut : out AInChannelArray(0 to NUM_AOUT - 1);
        BufData : out DataChannelArray(0 to NUM_CBUFS - 1);

        SPI_MISO : out std_logic;
        SPI_MOSI : in std_logic;
        SPI_SClk : in std_logic;
        SPI_CS : in std_logic
    );
end entity;

architecture Behavioural of {{top_entity}} is
    constant NUM_REGS : integer := 16;

    signal IntReset, IntSync : std_logic;
begin
    process(Clk) is
    begin
        if rising_edge(Clk) then
            -- These globals must be replicated within the RM
            IntReset <= Reset;
            IntSync <= Sync;
        end if;
    end process;

    REGS: block is
        signal Control : ControlRegisterArray(0 to NUM_REGS - 1);
        signal Status : StatusRegisterArray(Control'range);
    begin
        MMAP: entity WORK.SPIMemoryMap
            generic map (
                NUM_REGS => Control'length,
                STROBE_DELAY => true
            )
            port map (
                Clk => Clk,
                Reset => IntReset,

                MISO => SPI_MISO,
                MOSI => SPI_MOSI,
                SClk => SPI_SClk,
                CS => SPI_CS,

                Control => Control,
                Status => Status
            );

        Status(Status'range) <= to_status_array(Control(Control'range));

        -- define register map here
    end block;

    -- add implementation here

    AOut <= (others => AIN_ZERO);
    BufData <= (others => DATA_CHANNEL_ZERO);
end architecture;
