-- See the file "LICENSE" for the full license governing this code. -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; use work.lt16x32_global.all; use work.wishbone.all; use work.config.all; entity wb_timer is generic( memaddr : generic_addr_type; --:= CFG_BADR_TIMER; addrmask : generic_mask_type --:= CFG_MADR_TIMER; ); port( clk : in std_logic; rst : in std_logic; wslvi : in wb_slv_in_type; wslvo : out wb_slv_out_type; interrupt : out std_logic ); end wb_timer; architecture Behavioral of wb_timer is constant TARGET_COUNT_DEFAULT : integer := 32 - 1; signal ack : std_logic; signal counter : integer range 0 to 65535; signal counter_target_value : integer range 0 to 65535; signal enable : std_logic; signal repeat : std_logic; signal reset : std_logic; signal counter_vector : std_logic_vector(31 downto 0); signal status_register : std_logic_vector(31 downto 0); signal data_in : std_logic_vector(2 downto 0); signal data_in_changed : std_logic; begin process(clk) begin if clk'event and clk='1' then if rst = '1' then counter <= 0; else if reset = '1' then -- reset register counter <= 0; else if enable = '1' then if counter = counter_target_value then counter <= 0; else counter <= counter + 1; end if; end if; end if; end if; end if; end process; process(clk) begin if clk'event and clk='1' then if rst = '1' then enable <= '0'; repeat <= '0'; reset <= '0'; else reset <= '0'; if data_in_changed = '1' then enable <= data_in(0); repeat <= data_in(1); reset <= data_in(2); end if; -- Reset enable bit if counter = counter_target_value and repeat = '0' then enable <= '0'; end if; end if; end if; end process; process(clk) begin if clk'event and clk='1' then if rst = '1' then ack <= '0'; data_in <= (others => '0'); data_in_changed <= '0'; counter_target_value <= TARGET_COUNT_DEFAULT; else data_in <= (others => '0'); data_in_changed <= '0'; if wslvi.stb = '1' and wslvi.cyc = '1' then if wslvi.we='1' and wslvi.adr(2) = '1' then data_in <= dec_wb_dat(wslvi.sel,wslvi.dat)(2 downto 0); data_in_changed <= '1'; end if; if wslvi.we='1' and wslvi.adr(2) = '0' then counter_target_value <= to_integer(unsigned(dec_wb_dat(wslvi.sel,wslvi.dat))); end if; if ack = '0' then ack <= '1'; else ack <= '0'; end if; else ack <= '0'; end if; end if; end if; end process; counter_vector <= std_logic_vector(to_unsigned(counter_target_value, counter_vector'length)); status_register(0) <= enable; -- enable status_register(1) <= repeat; -- repeat status_register(31 downto 2) <= (others => '0'); -- reset bit always reads as 0 wslvo.dat <= counter_vector when wslvi.adr(2) = '0' else status_register when wslvi.adr(2) = '1' else (others => '0'); interrupt <= '1' when counter = counter_target_value else '0'; wslvo.ack <= ack; wslvo.wbcfg <= wb_membar(memaddr, addrmask); end Behavioral;