-- Do not edit; this file was generated by Cheby using these options:
--  -i svec_carrier_csr.cheby --gen-hdl=svec_carrier_csr.vhd

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

package svec_carrier_csr_pkg is
  type t_carrier_csr_master_out is record
    ctrl_fp_leds_man : std_logic_vector(15 downto 0);
    rst_fmc0         : std_logic;
    rst_fmc1         : std_logic;
  end record t_carrier_csr_master_out;
  subtype t_carrier_csr_slave_in is t_carrier_csr_master_out;

  type t_carrier_csr_slave_out is record
    carrier_pcb_rev  : std_logic_vector(4 downto 0);
    carrier_reserved : std_logic_vector(10 downto 0);
    carrier_type     : std_logic_vector(15 downto 0);
    stat_fmc0_pres   : std_logic;
    stat_fmc1_pres   : std_logic;
    stat_sys_pll_lck : std_logic;
    stat_ddr0_cal_done : std_logic;
    stat_ddr1_cal_done : std_logic;
  end record t_carrier_csr_slave_out;
  subtype t_carrier_csr_master_in is t_carrier_csr_slave_out;
end svec_carrier_csr_pkg;

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

entity svec_carrier_csr is
  port (
    rst_n_i              : in    std_logic;
    clk_i                : in    std_logic;
    wb_i                 : in    t_wishbone_slave_in;
    wb_o                 : out   t_wishbone_slave_out;

    -- Wires and registers
    carrier_csr_i        : in    t_carrier_csr_master_in;
    carrier_csr_o        : out   t_carrier_csr_master_out
  );
end svec_carrier_csr;

architecture syn of svec_carrier_csr is
  signal rd_int                         : std_logic;
  signal wr_int                         : std_logic;
  signal rd_ack_int                     : std_logic;
  signal wr_ack_int                     : std_logic;
  signal wb_en                          : std_logic;
  signal ack_int                        : std_logic;
  signal wb_rip                         : std_logic;
  signal wb_wip                         : std_logic;
  signal ctrl_fp_leds_man_reg           : std_logic_vector(15 downto 0);
  signal rst_fmc0_reg                   : std_logic;
  signal rst_fmc1_reg                   : std_logic;
  signal reg_rdat_int                   : std_logic_vector(31 downto 0);
  signal rd_ack1_int                    : std_logic;
begin

  -- WB decode signals
  wb_en <= wb_i.cyc and wb_i.stb;

  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        wb_rip <= '0';
      else
        wb_rip <= (wb_rip or (wb_en and not wb_i.we)) and not rd_ack_int;
      end if;
    end if;
  end process;
  rd_int <= (wb_en and not wb_i.we) and not wb_rip;

  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        wb_wip <= '0';
      else
        wb_wip <= (wb_wip or (wb_en and wb_i.we)) and not wr_ack_int;
      end if;
    end if;
  end process;
  wr_int <= (wb_en and wb_i.we) and not wb_wip;

  ack_int <= rd_ack_int or wr_ack_int;
  wb_o.ack <= ack_int;
  wb_o.stall <= not ack_int and wb_en;
  wb_o.rty <= '0';
  wb_o.err <= '0';

  -- Assign outputs
  carrier_csr_o.ctrl_fp_leds_man <= ctrl_fp_leds_man_reg;
  carrier_csr_o.rst_fmc0 <= rst_fmc0_reg;
  carrier_csr_o.rst_fmc1 <= rst_fmc1_reg;

  -- Process for write requests.
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        wr_ack_int <= '0';
        ctrl_fp_leds_man_reg <= "0000000000000000";
        rst_fmc0_reg <= '0';
        rst_fmc1_reg <= '0';
      else
        wr_ack_int <= '0';
        case wb_i.adr(3 downto 2) is
        when "00" => 
          -- Register carrier
        when "01" => 
          -- Register stat
        when "10" => 
          -- Register ctrl
          if wr_int = '1' then
            ctrl_fp_leds_man_reg <= wb_i.dat(15 downto 0);
          end if;
          wr_ack_int <= wr_int;
        when "11" => 
          -- Register rst
          if wr_int = '1' then
            rst_fmc0_reg <= wb_i.dat(0);
            rst_fmc1_reg <= wb_i.dat(1);
          end if;
          wr_ack_int <= wr_int;
        when others =>
          wr_ack_int <= wr_int;
        end case;
      end if;
    end if;
  end process;

  -- Process for registers read.
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        rd_ack1_int <= '0';
      else
        reg_rdat_int <= (others => '0');
        case wb_i.adr(3 downto 2) is
        when "00" => 
          -- carrier
          reg_rdat_int(4 downto 0) <= carrier_csr_i.carrier_pcb_rev;
          reg_rdat_int(15 downto 5) <= carrier_csr_i.carrier_reserved;
          reg_rdat_int(31 downto 16) <= carrier_csr_i.carrier_type;
          rd_ack1_int <= rd_int;
        when "01" => 
          -- stat
          reg_rdat_int(0) <= carrier_csr_i.stat_fmc0_pres;
          reg_rdat_int(1) <= carrier_csr_i.stat_fmc1_pres;
          reg_rdat_int(2) <= carrier_csr_i.stat_sys_pll_lck;
          reg_rdat_int(3) <= carrier_csr_i.stat_ddr0_cal_done;
          reg_rdat_int(4) <= carrier_csr_i.stat_ddr1_cal_done;
          rd_ack1_int <= rd_int;
        when "10" => 
          -- ctrl
          reg_rdat_int(15 downto 0) <= ctrl_fp_leds_man_reg;
          rd_ack1_int <= rd_int;
        when "11" => 
          -- rst
          rd_ack1_int <= rd_int;
        when others =>
          reg_rdat_int <= (others => 'X');
          rd_ack1_int <= rd_int;
        end case;
      end if;
    end if;
  end process;

  -- Process for read requests.
  process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
    -- By default ack read requests
    wb_o.dat <= (others => '0');
    case wb_i.adr(3 downto 2) is
    when "00" => 
      -- carrier
      wb_o.dat <= reg_rdat_int;
      rd_ack_int <= rd_ack1_int;
    when "01" => 
      -- stat
      wb_o.dat <= reg_rdat_int;
      rd_ack_int <= rd_ack1_int;
    when "10" => 
      -- ctrl
      wb_o.dat <= reg_rdat_int;
      rd_ack_int <= rd_ack1_int;
    when "11" => 
      -- rst
      wb_o.dat <= reg_rdat_int;
      rd_ack_int <= rd_ack1_int;
    when others =>
      rd_ack_int <= rd_int;
    end case;
  end process;
end syn;
