Skip to content
Snippets Groups Projects
Select Git revision
  • fdf1c7cb47eba7d5427d55201bc9ca7c29b9ab56
  • main default protected
  • 65_async_query
  • 169_codemeta
  • issue/152_cleaning_up
  • adex-main protected
  • sdc380-aladin-cone-search
  • sdc-222_multi_archive_query_review
  • 69_add_diracIAM
  • dev-nico
  • dev-dirac
  • acceptance
  • dev-zooniverse
13 results

GlobalContext.js

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    st_histogram.vhd 19.91 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright 2020
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    -- 
    -- Licensed under the Apache License, Version 2.0 (the "License");
    -- you may not use this file except in compliance with the License.
    -- You may obtain a copy of the License at
    -- 
    --     http://www.apache.org/licenses/LICENSE-2.0
    -- 
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    --
    -------------------------------------------------------------------------------
    
    -------------------------------------------------------------------------------
    -- 
    -- Author: J.W.E. Oudman
    -- Purpose: Create a histogram from the input data and present it to the MM bus
    -- Description: 
    --   The histogram component separates it's input samples in counter bins based
    --   on the value of the MSbits of the input. These bins are adresses on a RAM
    --   block that is swapped with another RAM block at every sync pulse plus 2 
    --   cycles. While one RAM block is used to count the input samples, the other
    --   is read by the MM bus through a fifo.
    --
    -- 
    --           ram_pointer        ram_pointer
    --               |                  |
    --               | /o--- RAM_0 ---o |
    --               |/                 |
    --               /                  |
    --  snk_in ----o/                   | /o----- FIFO to MM ---- MM
    --                                  |/
    --                                  /
    --                  o--- RAM_1 ---o/
    --
    --
    -- The input data is a dp stream which obviously uses a dp_clk. Because the
    -- RAM is swapped after every sync both RAM blocks need to use the dp_clk.
    -- Because the MM bus needs to access one RAM block but can't use it's mm_clk
    -- on it a FIFO is used.
    -- 
    -- Remarks:
    -- . Because the values of the generics g_nof_bins depends on g_in_data_w
    --   (you should not have more bins than data values) an assert is made to
    --   warn in the simulation when the maximum value of g_nof_bins is reached.
    --   If exceeded the simulator will throw fatal error ("...Port length (#) does
    --   not match actual length (#)...")
    --
    -- . when an adress is determined it takes 1 cycle to receive it's value and
    --   another cycle before the calculated value can be written into that RAM
    --   adress. There is also the limitation of not being able to read and write 
    --   on the same adress at the same time. These limitations cause the following
    --   complications in the implementation:
    --   . repeating samples of the same adress have to be counted first till 
    --     another adress appears before written (as you would miss the second and
    --     further consecutive samples and have the read/write limitation)
    --   . If adresses are toggling at every cycle (e.g. adress 0; 1; 0; 1) you
    --     have to remember the data to be written and increment it as you have the
    --     read/write limitation and writing takes priority in this case
    --   . When a sync signal appears the RAM has to be swapped 2 cycles later so 
    --     the first 2 cycles may not be read from the old RAM block 
    -- 
    -------------------------------------------------------------------------------
    
    LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
    USE IEEE.std_logic_1164.ALL;
    USE common_lib.common_pkg.ALL;
    USE common_lib.common_mem_pkg.ALL;
    USE dp_lib.dp_stream_pkg.ALL;
    USE technology_lib.technology_select_pkg.ALL;
    
    ENTITY st_histogram IS
      GENERIC (
        g_in_data_w     : NATURAL := 14;   -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768)
        g_nof_bins      : NATURAL := 512;  -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
        g_nof_data      : NATURAL;         -- any use?
        g_str           : STRING  := "freq.density"  -- to select output to MM bus ("frequency" or "freq.density")
      );                
      PORT (            
        mm_rst          : IN  STD_LOGIC;
        mm_clk          : IN  STD_LOGIC;
        dp_rst          : IN  STD_LOGIC;
        dp_clk          : IN  STD_LOGIC;
                        
        -- Streaming    
        snk_in      : IN  t_dp_sosi;
        
        -- Memory Mapped
        ram_mosi : IN  t_mem_mosi;  
        ram_miso : OUT t_mem_miso
      );
    END st_histogram;
    
    
    ARCHITECTURE str OF st_histogram IS
    
      CONSTANT c_data_span    : NATURAL  := pow2(g_in_data_w);      -- any use?
      CONSTANT c_bin_w        : NATURAL  := ceil_log2(g_nof_data);  -- any use?
      CONSTANT c_adr_w        : NATURAL  := ceil_log2(g_nof_bins);
      CONSTANT c_adr_low_calc : INTEGER  := g_in_data_w-c_adr_w;          -- Calculation might yield a negative number
      CONSTANT c_adr_low      : NATURAL  := largest(0, c_adr_low_calc);   -- Override any negative value of c_adr_low_calc
      
      CONSTANT c_ram          : t_c_mem := (latency  => 1,
                                            adr_w    => c_adr_w,          -- 9 bits needed to adress/select 512 adresses
                                            dat_w    => c_word_w,         -- 32bit, def. in common_pkg; >= c_bin_w
                                            nof_dat  => g_nof_bins,       -- 512 adresses with 32 bit words, so 512
                                            init_sl  => '0');             -- MM side : sla_in, sla_out
      
      SIGNAL dp_pipeline_src_out_p : t_dp_sosi;
      SIGNAL dp_pipeline_src_out_pp : t_dp_sosi;
      
      SIGNAL adr_b_cnt         : NATURAL  := 1;
      SIGNAL nxt_adr_b_cnt     : NATURAL;
      SIGNAL prev_adr_b        : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
      
      -- Toggle implementation signals
      SIGNAL prev_same_r_w_adr : STD_LOGIC  := '0';
      SIGNAL same_r_w_adr      : STD_LOGIC  := '0';
      SIGNAL nxt_same_r_w_adr  : STD_LOGIC  := '0';
    
      
      SIGNAL ram_pointer      : STD_LOGIC  := '0';
      SIGNAL wr_en_a          : STD_LOGIC  := '0';
      SIGNAL nxt_wr_en_a      : STD_LOGIC;
      SIGNAL wr_dat_a         : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
      SIGNAL nxt_wr_dat_a     : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
      SIGNAL adr_a            : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
      SIGNAL adr_b            : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
      SIGNAL rd_en_b          : STD_LOGIC  := '0';
      SIGNAL rd_dat_b         : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
      SIGNAL rd_val_b         : STD_LOGIC;
      
      SIGNAL ram_0_rst_a      : STD_LOGIC;
      SIGNAL ram_0_rst_b      : STD_LOGIC;
      SIGNAL ram_0_clk_a      : STD_LOGIC;
      SIGNAL ram_0_clk_b      : STD_LOGIC;
    
      SIGNAL ram_0_wr_en_a    : STD_LOGIC;
      SIGNAL ram_0_wr_en_b    : STD_LOGIC  := '0'; -- pointer=1, temp'0'
      SIGNAL ram_0_wr_dat_a   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
      SIGNAL ram_0_wr_dat_b   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0) := (OTHERS =>'0'); -- pointer=1, temp'0'
      SIGNAL ram_0_adr_a      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
      SIGNAL ram_0_adr_b      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
      SIGNAL ram_0_rd_en_b    : STD_LOGIC;
      SIGNAL ram_0_rd_dat_b   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
      SIGNAL ram_0_rd_val_b   : STD_LOGIC;
      
    BEGIN 
      
      -----------------------------------------------------------------------------
      -- Check Generics
      -----------------------------------------------------------------------------
      ASSERT c_adr_low_calc>0 REPORT "ceil_log2(g_nof_bins) is as large as g_in_data_w, don't increase g_nof_bins" SEVERITY WARNING;
      
      -----------------------------------------------------------------------------
      -- Assign inputs of RAM:
      -- . Determine address based on input data
      -- . Compare adress with the two previous adresses and if:
      --   . it is the same as the last adress increase a counter
      --   . it is the same as 2 cycles back but not the last copy the data to be 
      --     written directly into the counter instead of trying to read (ask) it 
      --     back from RAM at the same clock cycle (which is impossible)
      --   . it is not the same enable the nxt_wr_dat_a data to be written
      --     at the next cycle by making nxt_wr_en_a high
      -- . Write the wr_dat_a data to the RAM
      -- . At the snk_in.sync pulse:
      --   . let first 2 cycles start counting from 0 again
      --   . (plus 2 cycles) let counting depend on values in RAM (which should
      --     be 0)
      -- . Restart or pause counting when a snk_in.valid = '0' appears:
      --   . pause when adress is the same as the previous adress
      --   . restart from 0 when adress is not the same as previous adress
      --   . restart from 0 when also a sync appears
      -- 
      ----------------------------------------------------------------------------
    
      p_bin_cnt_switch : PROCESS(snk_in) IS
      BEGIN
        adr_b <= (OTHERS =>'0');
        IF g_nof_bins>1 THEN -- IF snk_in.valid='1' AND
          adr_b <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low);-- WHEN snk_in.valid='1' ELSE (OTHERS =>'0'); -- AND dp_rst='0';
        END IF;
      END PROCESS;
      
      p_rd_en_b : PROCESS(dp_pipeline_src_out_p.sync, snk_in.valid, wr_en_a, adr_a, adr_b, prev_adr_b) IS
      BEGIN
        rd_en_b <= '1';
        IF dp_pipeline_src_out_p.sync = '1' AND wr_en_a = '1' THEN  --
          rd_en_b <= '0';
        ELSIF adr_a = adr_b AND adr_a /= prev_adr_b THEN  -- toggle implementation
          rd_en_b <= '0';                                 -- toggle implementation  
        ELSIF snk_in.valid = '0' AND wr_en_a = '1' THEN
          rd_en_b <= '1';
        END IF;
      END PROCESS;
    
      p_nxt_wr_dat : PROCESS(rd_dat_b, adr_b_cnt, rd_val_b, dp_pipeline_src_out_p.sync, dp_pipeline_src_out_pp.sync, wr_en_a) IS
      BEGIN
        nxt_wr_dat_a <= (OTHERS => '0');
        IF dp_pipeline_src_out_p.sync = '1' THEN
          nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w);
        ELSIF dp_pipeline_src_out_pp.sync = '1' THEN
          nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w);
        ELSIF same_r_w_adr = '1' AND rd_val_b = '0' THEN    -- toggle implementation: same adress forced rd_val to 0, counter instead of ram knows what to write
          nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w);     -- toggle implementation
        ELSIF dp_pipeline_src_out_pp.valid = '0' AND prev_same_r_w_adr = '1' THEN  -- toggle implementation: prevent 2* rd_dat_b
          nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w);     -- toggle implementation
        ELSIF rd_val_b = '1' THEN
          nxt_wr_dat_a <= INCR_UVEC(rd_dat_b, adr_b_cnt);
        END IF;
      END PROCESS;
      
      p_nxt_wr_en : PROCESS(prev_adr_b, adr_b, snk_in.sync) IS
      BEGIN
        nxt_wr_en_a <= '0';
        IF adr_b /= prev_adr_b THEN
          nxt_wr_en_a <= '1';
        ELSIF snk_in.sync = '1' AND g_nof_bins = 1 THEN
          nxt_wr_en_a <= '1';
        ELSIF snk_in.sync = '1' THEN
          nxt_wr_en_a <= '1';
        END IF;
      END PROCESS;
        
      p_prev_adr_cnt : PROCESS(adr_a, adr_b, prev_adr_b, adr_b_cnt, snk_in.sync, snk_in.valid, dp_pipeline_src_out_p.valid, dp_pipeline_src_out_p.sync) IS
      BEGIN
        nxt_adr_b_cnt <= 1;
        IF adr_b = prev_adr_b AND snk_in.valid = '1' AND snk_in.sync = '0' THEN
          nxt_adr_b_cnt <= adr_b_cnt + 1 ;
        ELSIF snk_in.valid = '0' AND snk_in.sync = '1' THEN  --address doesn't matter at unvalid and sync, removed: adr_b = prev_adr_b AND
          nxt_adr_b_cnt <= 0;
        ELSIF adr_b = prev_adr_b AND snk_in.valid = '0' THEN
          nxt_adr_b_cnt <= adr_b_cnt;
        ELSIF adr_b = prev_adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' AND snk_in.sync = '1' THEN  -- toggle implementation; do the adresses even matter?
          nxt_adr_b_cnt <= 1;                                                                                             -- toggle implementation
        ELSIF adr_b = prev_adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' THEN  -- toggle implementation
          nxt_adr_b_cnt <= adr_b_cnt + 1;                                                           -- toggle implementation
        ELSIF adr_a = adr_b AND snk_in.valid = '1' AND snk_in.sync = '1' THEN    -- toggle implementation; do the adresses even matter?
          nxt_adr_b_cnt <= 1;                                                    -- toggle implementation
        ELSIF adr_a = adr_b AND adr_b /= prev_adr_b AND snk_in.valid = '0' THEN  -- toggle implementation: disable count; -2 cycles count + 0
          nxt_adr_b_cnt <= TO_UINT(wr_dat_a);                                    -- toggle implementation
        ELSIF adr_a = adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.sync = '0' THEN  -- toggle implentation
          nxt_adr_b_cnt <= TO_UINT(wr_dat_a) + 1;        -- toggle implentation
        ELSIF adr_a = adr_b AND snk_in.valid = '0' THEN  -- toggle implentation
          nxt_adr_b_cnt <= adr_b_cnt;                    -- toggle implentation
        ELSIF snk_in.valid = '0' AND adr_b /= prev_adr_b AND adr_a /= adr_b THEN
          nxt_adr_b_cnt <= 0;
        END IF;
      END PROCESS;
      
      p_nxt_same_r_w_adr : PROCESS(adr_a, adr_b) IS  -- toggle implentation
      BEGIN
        nxt_same_r_w_adr <= '0';
        IF adr_a = adr_b AND g_nof_bins > 1 THEN
          nxt_same_r_w_adr <= '1';
        END IF;
      END PROCESS;
    
      p_clk : PROCESS(dp_clk, dp_rst)
      BEGIN
      IF dp_rst='1' THEN
        adr_b_cnt <= 0;
        wr_en_a <= '0';
      ELSIF rising_edge(dp_clk) THEN
        adr_b_cnt <= nxt_adr_b_cnt;
        wr_dat_a <= nxt_wr_dat_a;
        wr_en_a <= nxt_wr_en_a;
        same_r_w_adr <= nxt_same_r_w_adr;
      END IF; 
      END PROCESS;  
      
      
      -----------------------------------------------------------------------------
      -- RAM selector
      -----------------------------------------------------------------------------
      
      p_ram_pointer : PROCESS(ram_pointer, dp_rst, dp_clk, wr_en_a, wr_dat_a, adr_a, adr_b, rd_en_b, ram_0_rd_dat_b, ram_0_rd_val_b) IS
      BEGIN
        -- Default / init values
    --    ram_miso <= c_mem_miso_rst;
    --    ram_0_mosi <= c_common_pipelinemem_mosi_rst;
    
        IF ram_pointer='0' THEN
        
          -- ST side (RAM 0)
    --      ram_0_rst_a <= dp_rst;
    --      ram_0_rst_b <= dp_rst;
    --      ram_0_clk_a <= dp_clk;
    --      ram_0_clk_b <= dp_clk;
        
          ram_0_wr_en_a <= wr_en_a;
          ram_0_wr_dat_a <= wr_dat_a;
          ram_0_adr_a <= adr_a;
          ram_0_adr_b <= adr_b;
          ram_0_rd_en_b <= rd_en_b;
          rd_dat_b <= ram_0_rd_dat_b;
          rd_val_b <= ram_0_rd_val_b;
          
          
    --      -- MM side (RAM 1)
    --      ram_1_rst_a <= dp_rst;
    --      ram_1_clk_a <=common_pipeline dp_clk;
    --      ram_1_wr_en_a <= clear_en_a;
    --      ram_1_wr_dat_a <= clear_dat_a;
    --      ram_1_adr_a <= clear_adr_a;
    --      
    --2
    --      ram_1_rst_b <= mm_rst;
    --      ram_1_clk_b <= mm_clk;
    --      ram_1_wr_en_b <= ram_mosi.wr;                               -- only for diagnostic purposes, typically statistics are read only
    --      ram_1_wr_dat_b <= ram_mosi.wrdata(c_ram.dat_w-1 DOWNTO 0);
    --      ram_1_adr_b <= ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
    --      ram_1_rd_en_b <= ram_mosi.rd;
    --      ram_miso.rddata <= ram_1_rd_dat_b(c_ram.dat_w-1 DOWNTO 0);  -- needs 'histogram/frequency' switch
    --      ram_miso.rdval <= ram_1_rd_val_b;
          
        ELSE -- ram_pointer='1'
    --      ram_1_wr_en_a <= wr_en_a;
    --      ram_1_wr_dat_a <= wr_dat_a;
    --      ram_1_adr_a <= adr_a;
    --      ram_1_adr_b <= adr_b;
    --      ram_1_rd_en_b <= rd_en_b;
    --      rd_dat_b <= ram_1_rd_dat_b;
    --      rd_val_b <= ram_1_rd_val_b;
    --      
    --      
    --      ram_miso <= ram_0_miso;
    --      ram_0_mosi <= ram_mosi;2
        END IF;
      END PROCESS;
      
      
      
      
      
      -----------------------------------------------------------------------------
      -- Pipeline for adress
      -----------------------------------------------------------------------------
      
      u_common_pipeline_adr : ENTITY common_lib.common_pipeline
      GENERIC MAP (
        g_representation => "UNSIGNED", --orig. signed
        g_pipeline       => 2,
        g_in_dat_w       => c_adr_w,
        g_out_dat_w      => c_adr_w
      )
      PORT MAP (
        clk     => dp_clk,
        clken   => '1',
        in_dat  => STD_LOGIC_VECTOR(adr_b),
        out_dat => adr_a
      );
      
      
      
      
      
      
      -----------------------------------------------------------------------------
      -- Pipeline for toggle issue
      -----------------------------------------------------------------------------
      
      u_common_pipeline_sl_same_r_w_adr : ENTITY common_lib.common_pipeline_sl
      GENERIC MAP(
        g_pipeline       => 1 -- 0 for wires, > 0 for registers, 
      )
      PORT MAP (
        clk     => dp_clk,
        in_dat  => same_r_w_adr,
        out_dat => prev_same_r_w_adr
      );
      
      
      
      
      
      
      -----------------------------------------------------------------------------
      -- Pipeline for adresscounter
      -----------------------------------------------------------------------------
      
      u_common_pipeline_adr_cnt : ENTITY common_lib.common_pipeline
      GENERIC MAP (
        g_representation => "UNSIGNED", --orig. signed
        g_pipeline       => 1,
        g_in_dat_w       => c_adr_w,
        g_out_dat_w      => c_adr_w
      )
      PORT MAP (
        clk     => dp_clk,
        clken   => '1',
        in_dat  => STD_LOGIC_VECTOR(adr_b),
        out_dat => prev_adr_b
      );
      
      
      
      
      
      
      -----------------------------------------------------------------------------
      -- Pipeline for cycles after sync
      -----------------------------------------------------------------------------
      
      u_dp_pipeline_snk_in_1_cycle : ENTITY dp_lib.dp_pipeline
      GENERIC MAP (
        g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
      )
      PORT MAP (
        rst          => dp_rst,
        clk          => dp_clk,
        snk_in       => snk_in,
        src_out      => dp_pipeline_src_out_p
      );
      
      u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline
      GENERIC MAP (
        g_pipeline   => 2   -- 0 for wires, > 0 for registers, 
      )
      PORT MAP (
        rst          => dp_rst,
        clk          => dp_clk,
        snk_in       => snk_in,
        src_out      => dp_pipeline_src_out_pp
      );
      
      
      
      
      
      
      -----------------------------------------------------------------------------
      -- Dual swapped RAM instance
      -----------------------------------------------------------------------------
      
      ram_0: ENTITY common_lib.common_ram_r_w
      GENERIC MAP (
        g_technology     => c_tech_select_default,
        g_ram            => c_ram,
        g_init_file      => "UNUSED"
      )
      PORT MAP (
        rst      => dp_rst, 
        clk      => dp_clk,
        clken    => '1',            -- only necessary for Stratix iv
        wr_en    => ram_0_wr_en_a,
        wr_adr   => ram_0_adr_a,
        wr_dat   => ram_0_wr_dat_a,
        rd_en    => ram_0_rd_en_b,
        rd_adr   => ram_0_adr_b,
        rd_dat   => ram_0_rd_dat_b,
        rd_val   => ram_0_rd_val_b
      );
      
    --  ram_0: ENTITY common_lib.common_ram_crw_crw
    --  GENERIC MAP (
    --    g_technology     => c_tech_select_default,
    --    g_ram            => c_ram,
    --    g_init_file      => "UNUSED",
    --    g_true_dual_port => FALSE
    --  )
    --  PORT MAP (
    --    rst_a     => ram_0_rst_a,
    --    rst_b     => ram_0_rst_b,
    --    clk_a     => ram_0_clk_a,
    --    clk_b     => ram_0_clk_b,
    --    clken_a   => '1',            -- only necessary for Stratix iv
    --    clken_b   => '1',
    --    wr_en_a   => ram_0_wr_en_a,
    --    wr_en_b   => ram_0_wr_en_b, -- pointer=1, temp'0'
    --    wr_dat_a  => ram_0_wr_dat_a,
    --    wr_dat_b  => ram_0_wr_dat_b, -- pointer=1, temp'0'
    --    adr_a     => ram_0_adr_a,
    --    adr_b     => ram_0_adr_b,
    --    rd_en_a   => '0',
    --    rd_en_b   => ram_0_rd_en_b,
    --    rd_dat_a  => OPEN,
    --    rd_dat_b  => ram_0_rd_dat_b,
    --    rd_val_a  => OPEN,
    --    rd_val_b  => ram_0_rd_val_b
    --  );
    --  
    --  ram_1: ENTITY common_lib.common_ram_crw_crw
    --  GENERIC MAP (
    --    g_technology     => c_tech_select_default,
    --    g_ram            => c_ram,
    --    g_init_file      => "UNUSED",
    --    g_true_dual_port => TRUE
    --  )
    --  PORT MAP (
    --    rst_a     => ram_1_rst_a,
    --    rst_b     => ram_1_rst_b,
    --    clk_a     => ram_1_clk_a,
    --    clk_b     => ram_1_clk_b,
    --    clken_a   => '1',
    --    clken_b   => '1',
    --    wr_en_a   => ram_1_wr_en_a,
    --    wr_en_b   => ram_1_wr_en_b,
    --    wr_dat_a  => ram_1_wr_dat_a,
    --    wr_dat_b  => ram_1_wr_dat_b,
    --    adr_a     => ram_1_adr_a,
    --    adr_b     => ram_1_adr_b,
    --    rd_en_a   => '0',
    --    rd_en_b   => ram_1_rd_en_b,
    --    rd_dat_a  => OPEN,
    --    rd_dat_b  => ram_1_rd_dat_b,
    --    rd_val_a  => OPEN,
    --    rd_val_b  => ram_1_rd_val_b
    --  );
      
      
      
      
      -----------------------------------------------------------------------------
      -- Connect MM interface to DUAL swapped RAM read out histogram statistics
      -----------------------------------------------------------------------------
      
      
      
      
      
          
    
    END str;