-- countermem: if addressed counter has wrapped the upper part is incremented -- and stored, to be controlled by fsm. Needs 8ns for calculation library IEEE; use IEEE.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity countermem is generic ( counterwidth : integer := 16); port ( clk : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; memin_zero : in std_logic; -- from fsm we : in std_logic; -- from fsm, write hold_cntval : in std_logic; -- from fsm to dpmem calculator address : in std_logic_vector(9 downto 0); -- from fsm fromcounter : in std_logic_vector(counterwidth-1 downto 0); -- from counter block cpuaddress : in std_logic_vector(9 downto 0); cpudata : out std_logic_vector(47 downto 0) ); end countermem; architecture behv of countermem is component memblock port ( addra : in std_logic_vector(9 downto 0); addrb : in std_logic_vector(9 downto 0); clka : in std_logic; clkb : in std_logic; dina : in std_logic_vector(47 downto 0); douta : out std_logic_vector(47 downto 0); doutb : out std_logic_vector(47 downto 0); wea : in std_logic); end component; signal din_i, dout_i : std_logic_vector(47 downto 0); signal cntval_reg : std_logic_vector(counterwidth-1 downto 0); signal dout_low : std_logic_vector(counterwidth-1 downto 0); signal dout_high : std_logic_vector(47-counterwidth downto 0); signal calcout : std_logic_vector(47-counterwidth downto 0); signal counter_wrapped : std_logic; begin -- behv memblock_1 : memblock port map ( addra => address, addrb => cpuaddress, clka => clk, clkb => cpuclk, dina => din_i, douta => dout_i, doutb => cpudata, wea => we); dout_low <= dout_i(counterwidth-1 downto 0); dout_high <= dout_i(47 downto counterwidth); -- countervalue "latch", synced to clk cntval_p : process (clk, reset_n) begin -- process cntval_p if reset_n = '0' then -- asynchronous reset (active low) cntval_reg <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge if hold_cntval = '1' then cntval_reg <= fromcounter; end if; end if; end process cntval_p; -- comparator: if latched cntval >= stored cntval, the counter did not wrap. if -- latched cntval < stored cntval, the counter wrapped and we can add 1 to the -- upper bits. counter_wrapped <= '1' when (cntval_reg < dout_low) else '0'; -- adder: add one to the upper stored memory, if counter_wrapped. calcout <= dout_high + ((calcout'high downto calcout'low+1 => '0') & counter_wrapped); -- input selector for datain -- all zero for reset or result from addonemux concatenated with the latched -- countervalue dinmux : process (memin_zero, calcout, cntval_reg) begin -- process dinmux case memin_zero is when '1' => din_i <= (others => '0'); when others => din_i <= calcout & cntval_reg; end case; end process dinmux; end behv;