-------------------------------------------------------------------------------
-- Title      : get White Rabbit status through wishbone interface
-- Project    : 
-------------------------------------------------------------------------------
-- File       : wr_status_wb.vhd
-- Author     : CC
-- Company    : CNRS
-- Created    : 2016-05-17
-- Last update: 2016-05-17
-- Platform   : Xilinx Spartan 6
-- Standard   : VHDL'93
-------------------------------------------------------------------------------
-- Description: Get WR status(locked) through wishbone interface.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN
--
-- This source file is free software; you can redistribute it   
-- and/or modify it under the terms of the GNU Lesser General   
-- Public License as published by the Free Software Foundation; 
-- either version 2.1 of the License, or (at your option) any   
-- later version.                                               
--
-- This source is distributed in the hope that it will be       
-- useful, but WITHOUT ANY WARRANTY; without even the implied   
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
-- PURPOSE.  See the GNU Lesser General Public License for more 
-- details.                                                     
--
-- You should have received a copy of the GNU Lesser General    
-- Public License along with this source; if not, download it   
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author          Description
-- 2016-05-17  1.0      CC           	Created
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;

entity wr_status_wb is
port(
    clk_sys_i        :  in std_logic;
    rst_n_i          :  in std_logic;
    ----
    rd_status_i		 :  in std_logic;
    wr_locked_o 	 :  out std_logic;
    rd_status_done_o :  out std_logic;
    ----
    wb_o             :  out t_wishbone_master_out;
    wb_i             :  in  t_wishbone_master_in
);
end wr_status_wb;

architecture behav of wr_status_wb is

type t_rd_status_state is (IDLE, RD_LOCKED, DONE);
signal rd_status_state : t_rd_status_state;

signal rdreq : std_logic;
signal init_cnt : unsigned(31 downto 0);
signal wr_locked : std_logic_vector(7 downto 0);

begin

wr_locked_o <= wr_locked(0);
   
p_wb_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
    if rst_n_i = '0' then
        wb_o.cyc <= '0';
        wb_o.stb <= '0';
        wb_o.sel <= "1111";
        wb_o.we  <= '0';
        wb_o.dat <= (others => '0');
    else
        if rdreq = '1' then 
            wb_o.cyc <= '1';
        elsif wb_i.ack = '1' or wb_i.err = '1' then
            wb_o.cyc <= '0';
        end if;

        if rdreq = '1' then
            wb_o.stb <= '1';
        elsif wb_i.stall = '0' then
            wb_o.stb <= '0';
        end if;
    end if;
end if;
end process p_wb_fsm;


wb_o.adr(31 downto 0) <=  X"00020220"  -- locked register (softPLL)


p_rd_config : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
    if rst_n_i = '0' then
        rd_status_state   <= IDLE;
        init_cnt          <= (others => '0');
        ip_config_done_o  <= '0';
        rdreq             <= '0';

    else
        case rd_status_state is
        when IDLE =>   
            rd_status_done_o <= '0';
            if rd_status_i	<= '1' then  
                rd_status_state <= RD_LOCKED; 
                rdreq <= '1';
            else
               rd_status_state <= IDLE;      
            end if;          
         
        when RD_LOCKED =>
            rdreq <= '0';
            if wb_i.ack = '1' then
                rd_status_state <= DONE;
                wr_locked <= wb_i.dat(23 downto 16);
            end if;

        when DONE => 
            rd_status_done_o <= '1';
				--init_cnt          <= (others => '0');
				rd_status_state      <= IDLE;
          
        when others => 
            rd_status_state <= IDLE;
        
        end case;
    end if;
end if;
end process p_rd_config;

end behav;
