LIBRARY IEEE; use IEEE.std_logic_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; entity top_counters is generic(Na : Integer := 8; Nm : Integer := 4; Nbit : Integer := 32; shortpulse : boolean := false; areg : Boolean := true; mreg : Boolean := true; qreg : Boolean := true); port( clk : in std_logic; srst : in std_logic; glb_en : in std_logic; cntin : in std_logic_vector(2**Na-1 downto 0); raddr : in std_logic_vector(Na-1 downto 0); q : out std_logic_vector(Nbit-1 downto 0)); end top_counters; architecture a of top_counters is component counter_block is generic(Na : Integer := 8; Nbit : Integer := 32; shortpulse : boolean := false; areg : Boolean := true; qreg : Boolean := true); port( clk : in std_logic; srst : in std_logic; glb_en : in std_logic; cntin : in std_logic_vector(2**Na-1 downto 0); raddr : in std_logic_vector(Na-1 downto 0); q : out std_logic_vector(Nbit-1 downto 0)); end component; constant blocks : Natural := 2**Nm; constant ra_sub : Natural := Na-Nm; constant cntpbl : Natural := 2**ra_sub; signal raddr_hi : Integer range 0 to blocks-1; signal raddr_hi2: Integer range 0 to blocks-1; signal raddr_lo : std_logic_vector(ra_sub-1 downto 0); subtype cnt_out is std_logic_vector(Nbit-1 downto 0); type cnt_arr is array(0 to blocks-1) of cnt_out; signal cnt_blk : cnt_arr; signal glb_en_r : std_logic; begin ra_reg : if areg generate process(clk) begin if rising_edge(clk) then raddr_hi <= conv_integer(raddr(Na-1 downto Na-Nm)); raddr_lo <= raddr(ra_sub-1 downto 0); end if; end process; end generate; ra_dir : if not areg generate raddr_hi <= conv_integer(raddr(Na-1 downto Na-Nm)); raddr_lo <= raddr(Na-Nm-1 downto 0); end generate; cnt: for i in 0 to 2**Nm-1 generate cntb: counter_block generic map( Na => Na-Nm, Nbit => Nbit, shortpulse => shortpulse, areg => areg, qreg => mreg) port map( clk => clk, srst => srst, glb_en => glb_en, cntin => cntin(i*cntpbl+cntpbl-1 downto i*cntpbl), raddr => raddr_lo, q => cnt_blk(i) ); end generate; ra_mreg : if mreg generate process(clk) begin if rising_edge(clk) then raddr_hi2 <= raddr_hi; end if; end process; end generate; ra_mdir : if not mreg generate raddr_hi2 <= raddr_hi; end generate; q_reg : if qreg generate process(clk) begin if rising_edge(clk) then q <= cnt_blk(raddr_hi2); end if; end process; end generate; q_dir : if not qreg generate q <= cnt_blk(raddr_hi2); end generate; end;