-- 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 work.lt16x32_global.all; use work.wishbone.all; use work.config.all; entity wb_segment_adv is generic( memaddr : generic_addr_type; --:= CFG_BADR_SEG; addrmask : generic_mask_type --:= CFG_MADR_SEG; ); port( clk : in std_logic; rst : in std_logic; wslvi : in wb_slv_in_type; wslvo : out wb_slv_out_type; anodes : out std_logic_vector(7 downto 0); cathodes : out std_logic_vector(7 downto 0) ); end wb_segment_adv; architecture Behavioral of wb_segment_adv is signal ack : std_logic; signal hex_register : std_logic_vector(63 downto 0); signal data_out : std_logic_vector(31 downto 0); signal data_in : std_logic_vector(31 downto 0); signal data_in_changed : std_logic; signal hex : std_logic_vector(4 downto 0); signal timer_overflow : std_logic; signal overflow_counter : integer range 0 to 7; component hex2physical port( hex : in std_logic_vector(4 downto 0); cathodes : out std_logic_vector(7 downto 0) ); end component; component simple_timer generic( timer_start : std_logic_vector (31 downto 0) ); port( clk : in std_logic; rst : in std_logic; timer_overflow : out std_logic ); end component; begin converter : hex2physical port map( hex => hex, cathodes => cathodes ); timer: simple_timer generic map (timer_start => x"00000008") -- for simulation -- generic map (timer_start => x"00000F00") -- for board port map( clk => clk, rst => rst, timer_overflow => timer_overflow ); process(clk) begin if clk'event and clk='1' then if rst = '1' then ack <= '0'; data_out <= (others=>'0'); data_in <= (others=>'0'); data_in_changed <= '0'; else data_out <= (others=>'0'); data_in <= (others=>'0'); data_in_changed <= '0'; if wslvi.stb = '1' and wslvi.cyc = '1' then if wslvi.we='0' then -- data_out will stay 0 else -- Write enable data_in <= dec_wb_dat(wslvi.sel,wslvi.dat); data_in_changed <= '1'; end if; if ack = '0' then ack <= '1'; else ack <= '0'; end if; else ack <= '0'; end if; end if; end if; end process; process(clk) variable v_data : std_logic_vector(3 downto 0); variable v_off : std_logic; variable v_write : std_logic; variable v_clear : std_logic; variable v_shift : std_logic; begin if clk'event and clk='1' then if rst = '1' then hex_register <= (others=>'0'); else if data_in_changed = '1' and ack = '1' then -- only check if ack was just raised v_data := data_in(3 downto 0); v_off := data_in(4); v_write := data_in(8); v_clear := data_in(16); v_shift := data_in(24); -- No special care has to be taken to support -- writing and shifting at the same time. if v_shift = '1' then hex_register(63 downto 56) <= (others => '0'); hex_register(55 downto 0) <= hex_register(63 downto 8); end if; if v_write = '1' then hex_register(59 downto 56) <= v_data; hex_register(60) <= not v_off; -- unclear if this should only be set when write is 1 end if; if v_clear = '1' then hex_register <= (others => '0'); end if; end if; end if; end if; end process; process(clk) begin if clk'event and clk='1' then if rst = '1' then hex <= hex_register(4 downto 0); anodes <= (others => not '0'); overflow_counter <= 0; else if timer_overflow = '1' then if overflow_counter = 7 then overflow_counter <= 0; else overflow_counter <= overflow_counter + 1; end if; anodes <= (others => not '0'); anodes(overflow_counter) <= not '1'; hex <= hex_register(overflow_counter * 8 + 4 downto overflow_counter * 8); end if; end if; end if; end process; wslvo.dat <= data_out; wslvo.ack <= ack; wslvo.wbcfg <= wb_membar(memaddr, addrmask); end Behavioral;