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

entity dds_pulse_intfc_v1_0 is
  generic (
    -- Users to add parameters here
    -- User parameters ends
    -- Do not modify the parameters beyond this line


    -- Parameters of Axi Slave Bus Interface S00_AXI
    C_S00_AXI_DATA_WIDTH                : integer := 32;
    C_S00_AXI_ADDR_WIDTH                : integer := 8
  );
  port (
    -- Users to add ports here
    m_axis_aclk_in                      : in  std_logic;
    m_axis_aresetn_in                   : in  std_logic;
    m0_axis_tdata_out                   : out std_logic_vector(127 downto 0);
    m0_axis_tvalid_out                  : out std_logic;
    m0_axis_tready_in                   : in  std_logic;

    m1_axis_tdata_out                   : out std_logic_vector(127 downto 0);
    m1_axis_tvalid_out                  : out std_logic;
    m1_axis_tready_in                   : in  std_logic;
    -- User ports ends
    -- Do not modify the ports beyond this line


    -- Ports of Axi Slave Bus Interface S00_AXI
    s00_axi_aclk_in                     : in std_logic;
    s00_axi_aresetn_in                  : in std_logic;
    s00_axi_awaddr                      : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0);
    s00_axi_awprot                      : in std_logic_vector(2 downto 0);
    s00_axi_awvalid                     : in std_logic;
    s00_axi_awready                     : out std_logic;
    s00_axi_wdata                       : in std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0);
    s00_axi_wstrb                       : in std_logic_vector((C_S00_AXI_DATA_WIDTH/8)-1 downto 0);
    s00_axi_wvalid                      : in std_logic;
    s00_axi_wready                      : out std_logic;
    s00_axi_bresp                       : out std_logic_vector(1 downto 0);
    s00_axi_bvalid                      : out std_logic;
    s00_axi_bready                      : in std_logic;
    s00_axi_araddr                      : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0);
    s00_axi_arprot                      : in std_logic_vector(2 downto 0);
    s00_axi_arvalid                     : in std_logic;
    s00_axi_arready                     : out std_logic;
    s00_axi_rdata                       : out std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0);
    s00_axi_rresp                       : out std_logic_vector(1 downto 0);
    s00_axi_rvalid                      : out std_logic;
    s00_axi_rready                      : in  std_logic
  );
end dds_pulse_intfc_v1_0;

architecture arch_imp of dds_pulse_intfc_v1_0 is

  signal cmd_send_0_r                   : std_logic_vector(0 to 2) := (others => '0');
  signal cmd_send_1_r                   : std_logic_vector(0 to 2) := (others => '0');
  signal cmd_send_2_r                   : std_logic_vector(0 to 2) := (others => '0');
  signal cmd_send_3_r                   : std_logic_vector(0 to 2) := (others => '0');

  signal dac_holdoff                    : std_logic;

  signal m0_axis_tvalid_cnt             : std_logic_vector(31 downto 0);
  signal m0_dds_pulse_data_cnt          : std_logic_vector(31 downto 0);

  signal m1_axis_tvalid_cnt             : std_logic_vector(31 downto 0);
  signal m1_dds_pulse_data_cnt          : std_logic_vector(31 downto 0);

  signal scale_0                        : std_logic_vector(15 downto 0);
  signal dds_phase_inc_dwell_time_0     : std_logic_vector(31 downto 0);
  signal dds_phase_inc_step_size_0      : std_logic_vector(31 downto 0);
  signal idle_samples_0                 : std_logic_vector(31 downto 0);
  signal dds_samples_0                  : std_logic_vector(31 downto 0);
  signal phase_inc_0                    : std_logic_vector(31 downto 0);
  signal phase_off_0                    : std_logic_vector(31 downto 0);
  signal swap_sf_0                      : std_logic_vector(31 downto 0);

  signal scale_1                        : std_logic_vector(15 downto 0);
  signal dds_phase_inc_dwell_time_1     : std_logic_vector(31 downto 0);
  signal dds_phase_inc_step_size_1      : std_logic_vector(31 downto 0);
  signal idle_samples_1                 : std_logic_vector(31 downto 0);
  signal dds_samples_1                  : std_logic_vector(31 downto 0);
  signal phase_inc_1                    : std_logic_vector(31 downto 0);
  signal phase_off_1                    : std_logic_vector(31 downto 0);
  signal swap_sf_1                      : std_logic_vector(31 downto 0);

  signal scale_2                        : std_logic_vector(15 downto 0);
  signal dds_phase_inc_dwell_time_2     : std_logic_vector(31 downto 0);
  signal dds_phase_inc_step_size_2      : std_logic_vector(31 downto 0);
  signal idle_samples_2                 : std_logic_vector(31 downto 0);
  signal dds_samples_2                  : std_logic_vector(31 downto 0);
  signal phase_inc_2                    : std_logic_vector(31 downto 0);
  signal phase_off_2                    : std_logic_vector(31 downto 0);
  signal swap_sf_2                      : std_logic_vector(31 downto 0);

  signal scale_3                        : std_logic_vector(15 downto 0);
  signal dds_phase_inc_dwell_time_3     : std_logic_vector(31 downto 0);
  signal dds_phase_inc_step_size_3      : std_logic_vector(31 downto 0);
  signal idle_samples_3                 : std_logic_vector(31 downto 0);
  signal dds_samples_3                  : std_logic_vector(31 downto 0);
  signal phase_inc_3                    : std_logic_vector(31 downto 0);
  signal phase_off_3                    : std_logic_vector(31 downto 0);
  signal swap_sf_3                      : std_logic_vector(31 downto 0);

  signal slv_reg0                       : std_logic_vector(31 downto 0);
  signal slv_reg1                       : std_logic_vector(31 downto 0);
  signal slv_reg2                       : std_logic_vector(31 downto 0);
  signal slv_reg3                       : std_logic_vector(31 downto 0);
  signal slv_reg4                       : std_logic_vector(31 downto 0);
  signal slv_reg5                       : std_logic_vector(31 downto 0);
  signal slv_reg6                       : std_logic_vector(31 downto 0);
  signal slv_reg7                       : std_logic_vector(31 downto 0);
  signal slv_reg8                       : std_logic_vector(31 downto 0);
  signal slv_reg9                       : std_logic_vector(31 downto 0);
  signal slv_reg10                      : std_logic_vector(31 downto 0);
  signal slv_reg11                      : std_logic_vector(31 downto 0);
  signal slv_reg12                      : std_logic_vector(31 downto 0);
  signal slv_reg13                      : std_logic_vector(31 downto 0);
  signal slv_reg14                      : std_logic_vector(31 downto 0);
  signal slv_reg15                      : std_logic_vector(31 downto 0);
  signal slv_reg16                      : std_logic_vector(31 downto 0);
  signal slv_reg17                      : std_logic_vector(31 downto 0);
  signal slv_reg18                      : std_logic_vector(31 downto 0);
  signal slv_reg19                      : std_logic_vector(31 downto 0);
  signal slv_reg20                      : std_logic_vector(31 downto 0);
  signal slv_reg21                      : std_logic_vector(31 downto 0);
  signal slv_reg22                      : std_logic_vector(31 downto 0);
  signal slv_reg23                      : std_logic_vector(31 downto 0);
  signal slv_reg24                      : std_logic_vector(31 downto 0);
  signal slv_reg25                      : std_logic_vector(31 downto 0);
  signal slv_reg26                      : std_logic_vector(31 downto 0);
  signal slv_reg27                      : std_logic_vector(31 downto 0);
  signal slv_reg28                      : std_logic_vector(31 downto 0);
  signal slv_reg29                      : std_logic_vector(31 downto 0);
  signal slv_reg30                      : std_logic_vector(31 downto 0);
  signal slv_reg31                      : std_logic_vector(31 downto 0);
  signal slv_reg32                      : std_logic_vector(31 downto 0);
  signal slv_reg33                      : std_logic_vector(31 downto 0);
  signal slv_reg34                      : std_logic_vector(31 downto 0);
  signal slv_reg35                      : std_logic_vector(31 downto 0);
  signal slv_reg36                      : std_logic_vector(31 downto 0);
  signal slv_reg37                      : std_logic_vector(31 downto 0);
  signal slv_reg38                      : std_logic_vector(31 downto 0);
  signal slv_reg39                      : std_logic_vector(31 downto 0);

  signal cnt_reset                      : std_logic;
  
  signal dds_enable                     : std_logic;
  signal dds_reset_n                    : std_logic;
  
begin

  -- Instantiation of Axi Bus Interface S00_AXI
  dds_pulse_intfc_v1_0_S00_AXI_inst : entity work.dds_pulse_intfc_v1_0_S00_AXI
    generic map (
      C_S_AXI_DATA_WIDTH              => C_S00_AXI_DATA_WIDTH,
      C_S_AXI_ADDR_WIDTH              => C_S00_AXI_ADDR_WIDTH
    )
    port map (
      slv_reg0_out                    => slv_reg0,
      slv_reg1_out                    => slv_reg1,
      slv_reg2_out                    => slv_reg2,
      slv_reg3_out                    => slv_reg3,
      slv_reg4_out                    => slv_reg4,
      slv_reg5_out                    => slv_reg5,
      slv_reg6_out                    => slv_reg6,
      slv_reg7_out                    => slv_reg7,
      slv_reg8_out                    => slv_reg8,
      slv_reg9_out                    => slv_reg9,
      slv_reg10_out                   => slv_reg10,
      slv_reg11_out                   => slv_reg11,
      slv_reg12_out                   => slv_reg12,
      slv_reg13_out                   => slv_reg13,
      slv_reg14_out                   => slv_reg14,
      slv_reg15_out                   => slv_reg15,
      slv_reg16_out                   => slv_reg16,
      slv_reg17_out                   => slv_reg17,
      slv_reg18_out                   => slv_reg18,
      slv_reg19_out                   => slv_reg19,
      slv_reg20_out                   => slv_reg20,
      slv_reg21_out                   => slv_reg21,
      slv_reg22_out                   => slv_reg22,
      slv_reg23_out                   => slv_reg23,
      slv_reg24_out                   => slv_reg24,
      slv_reg25_out                   => slv_reg25,
      slv_reg26_out                   => slv_reg26,
      slv_reg27_out                   => slv_reg27,
      slv_reg28_out                   => slv_reg28,
      slv_reg29_out                   => slv_reg29,
      slv_reg30_out                   => slv_reg30,
      slv_reg31_out                   => slv_reg31,
      slv_reg32_out                   => slv_reg32,
      slv_reg33_out                   => slv_reg33,
      slv_reg34_out                   => slv_reg34,
      slv_reg35_out                   => slv_reg35,
      slv_reg36_in                    => slv_reg36,
      slv_reg37_in                    => slv_reg37,
      slv_reg38_in                    => slv_reg38,
      slv_reg39_in                    => slv_reg39,

      S_AXI_ACLK                      => s00_axi_aclk_in,
      S_AXI_ARESETN                   => s00_axi_aresetn_in,
      S_AXI_AWADDR                    => s00_axi_awaddr,
      S_AXI_AWPROT                    => s00_axi_awprot,
      S_AXI_AWVALID                   => s00_axi_awvalid,
      S_AXI_AWREADY                   => s00_axi_awready,
      S_AXI_WDATA                     => s00_axi_wdata,
      S_AXI_WSTRB                     => s00_axi_wstrb,
      S_AXI_WVALID                    => s00_axi_wvalid,
      S_AXI_WREADY                    => s00_axi_wready,
      S_AXI_BRESP                     => s00_axi_bresp,
      S_AXI_BVALID                    => s00_axi_bvalid,
      S_AXI_BREADY                    => s00_axi_bready,
      S_AXI_ARADDR                    => s00_axi_araddr,
      S_AXI_ARPROT                    => s00_axi_arprot,
      S_AXI_ARVALID                   => s00_axi_arvalid,
      S_AXI_ARREADY                   => s00_axi_arready,
      S_AXI_RDATA                     => s00_axi_rdata,
      S_AXI_RRESP                     => s00_axi_rresp,
      S_AXI_RVALID                    => s00_axi_rvalid,
      S_AXI_RREADY                    => s00_axi_rready
    );

  -- Add user logic here

--slv_reg0                                                   --0x8300_0000
  process (s00_axi_aclk_in)
  begin
    if rising_edge(s00_axi_aclk_in) then
      if (slv_reg0(0) = '1') then                                     
        cmd_send_0_r      <= "111";
      else
        cmd_send_0_r      <= cmd_send_0_r(1 to 2) & '0';
      end if;

      if (slv_reg0(4) = '1') then
        cmd_send_1_r      <= "111";
      else
        cmd_send_1_r      <= cmd_send_1_r(1 to 2) & '0';
      end if;

      if (slv_reg0(8) = '1') then
        cmd_send_2_r      <= "111";
      else
        cmd_send_2_r      <= cmd_send_2_r(1 to 2) & '0';
      end if;

      if (slv_reg0(12) = '1') then
        cmd_send_3_r      <= "111";
      else
        cmd_send_3_r      <= cmd_send_3_r(1 to 2) & '0';
      end if;

    end if;
  end process;

  dac_holdoff                 <= slv_reg1(0);                       --0x8300_0004

--                            <= slv_reg2(3 downto 0);              --0x8300_0008

  cnt_reset                   <= slv_reg3(0);                       --0x8300_000C
  dds_enable                  <= slv_reg3(31);                      

  scale_0                     <= slv_reg4(15 downto 0);             --0x8300_0010
  dds_phase_inc_dwell_time_0  <= slv_reg5;                          --0x8300_0014
  dds_phase_inc_step_size_0   <= slv_reg6;                          --0x8300_0018 
  idle_samples_0              <= slv_reg7;                          --0x8300_001C
  dds_samples_0               <= slv_reg8;                          --0x8300_0020 
  phase_inc_0                 <= slv_reg9;                          --0x8300_0024
  phase_off_0                 <= slv_reg10;                         --0x8300_0028
  swap_sf_0                   <= slv_reg11;                         --0x8300_002C

  scale_1                     <= slv_reg12(15 downto 0);            --0x8300_0030
  dds_phase_inc_dwell_time_1  <= slv_reg13;                         --0x8300_0034
  dds_phase_inc_step_size_1   <= slv_reg14;                         --0x8300_0038 
  idle_samples_1              <= slv_reg15;                         --0x8300_003C
  dds_samples_1               <= slv_reg16;                         --0x8300_0040 
  phase_inc_1                 <= slv_reg17;                         --0x8300_0044
  phase_off_1                 <= slv_reg18;                         --0x8300_0048
  swap_sf_1                   <= slv_reg19;                         --0x8300_004C

  scale_2                     <= slv_reg20(15 downto 0);            --0x8300_0050
  dds_phase_inc_dwell_time_2  <= slv_reg21;                         --0x8300_0054
  dds_phase_inc_step_size_2   <= slv_reg22;                         --0x8300_0058 
  idle_samples_2              <= slv_reg23;                         --0x8300_005C
  dds_samples_2               <= slv_reg24;                         --0x8300_0060 
  phase_inc_2                 <= slv_reg25;                         --0x8300_0064
  phase_off_2                 <= slv_reg26;                         --0x8300_0068
  swap_sf_2                   <= slv_reg27;                         --0x8300_006C

  scale_3                     <= slv_reg28(15 downto 0);            --0x8300_0070
  dds_phase_inc_dwell_time_3  <= slv_reg29;                         --0x8300_0074
  dds_phase_inc_step_size_3   <= slv_reg30;                         --0x8300_0078 
  idle_samples_3              <= slv_reg31;                         --0x8300_007C
  dds_samples_3               <= slv_reg32;                         --0x8300_0080 
  phase_inc_3                 <= slv_reg33;                         --0x8300_0084
  phase_off_3                 <= slv_reg34;                         --0x8300_0088
  swap_sf_3                   <= slv_reg35;                         --0x8300_008C

  slv_reg36                   <= m0_dds_pulse_data_cnt;              --0x8300_0090     
  slv_reg37                   <= m0_axis_tvalid_cnt;                 --0x8300_0094    
  slv_reg38                   <= m1_dds_pulse_data_cnt;              --0x8300_0098     
  slv_reg39                   <= m1_axis_tvalid_cnt;                 --0x8300_009C    


  dds_reset_n  <= '0' when m_axis_aresetn_in = '0' or dds_enable = '0' else '1';
  
  i_dds_pulse_intfc_x4 : entity work.dds_pulse_intfc_x4 
    port map ( 
      s_axi_aclk_in                     => s00_axi_aclk_in,          
      s_axi_aresetn_in                  => s00_axi_aresetn_in,    

      cmd_idx_in                        => "000",
      dac_holdoff_in                    => dac_holdoff,
      
      cmd_send_0_in                     => cmd_send_0_r(0),  
      scale_0_in                        => scale_0,                   
      dds_phase_inc_dwell_time_0_in     => dds_phase_inc_dwell_time_0,
      dds_phase_inc_step_size_0_in      => dds_phase_inc_step_size_0, 
      idle_samples_0_in                 => idle_samples_0,            
      dds_samples_0_in                  => dds_samples_0,             
      phase_inc_0_in                    => phase_inc_0,               
      phase_off_0_in                    => phase_off_0,               
      swap_sf_0_in                      => swap_sf_0,                 

      cmd_send_1_in                     => cmd_send_1_r(0),  
      scale_1_in                        => scale_1,                   
      dds_phase_inc_dwell_time_1_in     => dds_phase_inc_dwell_time_1,
      dds_phase_inc_step_size_1_in      => dds_phase_inc_step_size_1, 
      idle_samples_1_in                 => idle_samples_1,            
      dds_samples_1_in                  => dds_samples_1,             
      phase_inc_1_in                    => phase_inc_1,               
      phase_off_1_in                    => phase_off_1,               
      swap_sf_1_in                      => swap_sf_1,                 

      cmd_send_2_in                     => cmd_send_2_r(0),  
      scale_2_in                        => scale_2,                   
      dds_phase_inc_dwell_time_2_in     => dds_phase_inc_dwell_time_2,
      dds_phase_inc_step_size_2_in      => dds_phase_inc_step_size_2, 
      idle_samples_2_in                 => idle_samples_2,            
      dds_samples_2_in                  => dds_samples_2,             
      phase_inc_2_in                    => phase_inc_2,               
      phase_off_2_in                    => phase_off_2,               
      swap_sf_2_in                      => swap_sf_2,                 

      cmd_send_3_in                     => cmd_send_3_r(0),  
      scale_3_in                        => scale_3,                   
      dds_phase_inc_dwell_time_3_in     => dds_phase_inc_dwell_time_3,
      dds_phase_inc_step_size_3_in      => dds_phase_inc_step_size_3, 
      idle_samples_3_in                 => idle_samples_3,            
      dds_samples_3_in                  => dds_samples_3,             
      phase_inc_3_in                    => phase_inc_3,               
      phase_off_3_in                    => phase_off_3,               
      swap_sf_3_in                      => swap_sf_3,                 

      m_axis_aclk_in                    => m_axis_aclk_in,     
      m_axis_aresetn_in                 => dds_reset_n, ---m_axis_aresetn_in,
      m0_axis_tdata_out                 => m0_axis_tdata_out,            
      m0_axis_tvalid_out                => m0_axis_tvalid_out,         
      m0_axis_tready_in                 => m0_axis_tready_in,          

      m1_axis_tdata_out                 => m1_axis_tdata_out,            
      m1_axis_tvalid_out                => m1_axis_tvalid_out,         
      m1_axis_tready_in                 => m1_axis_tready_in,          

      cnt_reset_in                      => cnt_reset,
      m0_axis_tvalid_cnt_out            => m0_axis_tvalid_cnt,        
      m0_dds_pulse_data_cnt_out         => m0_dds_pulse_data_cnt,
      m1_axis_tvalid_cnt_out            => m1_axis_tvalid_cnt,        
      m1_dds_pulse_data_cnt_out         => m1_dds_pulse_data_cnt
      );
  -- User logic ends

end arch_imp;
