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

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

entity wb_vic_regs is
  port (
    rst_n_i              : in    std_logic;
    clk_i                : in    std_logic;
    wb_cyc_i             : in    std_logic;
    wb_stb_i             : in    std_logic;
    wb_adr_i             : in    std_logic_vector(7 downto 2);
    wb_sel_i             : in    std_logic_vector(3 downto 0);
    wb_we_i              : in    std_logic;
    wb_dat_i             : in    std_logic_vector(31 downto 0);
    wb_ack_o             : out   std_logic;
    wb_err_o             : out   std_logic;
    wb_rty_o             : out   std_logic;
    wb_stall_o           : out   std_logic;
    wb_dat_o             : out   std_logic_vector(31 downto 0);

    -- VIC Enable
    CTL_ENABLE_o         : out   std_logic;

    -- VIC output polarity
    CTL_POL_i            : in    std_logic;

    -- VIC output polarity
    CTL_POL_o            : out   std_logic;

    -- Emulate Edge sensitive output
    CTL_EMU_EDGE_o       : out   std_logic;

    -- Emulated Edge pulse timer
    CTL_EMU_LEN_o        : out   std_logic_vector(15 downto 0);
    CTL_wr_o             : out   std_logic;

    -- Raw Interrupt Status Register
    RISR_i               : in    std_logic_vector(31 downto 0);

    -- Interrupt Enable Register
    IER_o                : out   std_logic_vector(31 downto 0);
    IER_wr_o             : out   std_logic;

    -- Interrupt Disable Register
    IDR_o                : out   std_logic_vector(31 downto 0);
    IDR_wr_o             : out   std_logic;

    -- Interrupt Mask Register
    IMR_i                : in    std_logic_vector(31 downto 0);

    -- Vector Address Register
    VAR_i                : in    std_logic_vector(31 downto 0);

    -- Software Interrupt Register
    SWIR_o               : out   std_logic_vector(31 downto 0);
    SWIR_wr_o            : out   std_logic;

    -- End Of Interrupt Acknowledge Register
    EOIR_o               : out   std_logic_vector(31 downto 0);
    EOIR_wr_o            : out   std_logic;

    -- Interrupt Vector Table
    IVT_RAM_addr_o       : out   std_logic_vector(6 downto 2);
    IVT_RAM_data_i       : in    std_logic_vector(31 downto 0);
    IVT_RAM_data_o       : out   std_logic_vector(31 downto 0);
    IVT_RAM_wr_o         : out   std_logic
  );
end wb_vic_regs;

architecture syn of wb_vic_regs 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 CTL_ENABLE_reg                 : std_logic;
  signal CTL_EMU_EDGE_reg               : std_logic;
  signal CTL_EMU_LEN_reg                : std_logic_vector(15 downto 0);
  signal IVT_RAM_rack                   : std_logic;
  signal IVT_RAM_re                     : 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_cyc_i and wb_stb_i;

  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then
      wb_rip <= '0';
    elsif rising_edge(clk_i) then
      wb_rip <= (wb_rip or (wb_en and not wb_we_i)) and not rd_ack_int;
    end if;
  end process;
  rd_int <= (wb_en and not wb_we_i) and not wb_rip;

  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then
      wb_wip <= '0';
    elsif rising_edge(clk_i) then
      wb_wip <= (wb_wip or (wb_en and wb_we_i)) and not wr_ack_int;
    end if;
  end process;
  wr_int <= (wb_en and wb_we_i) and not wb_wip;

  ack_int <= rd_ack_int or wr_ack_int;
  wb_ack_o <= ack_int;
  wb_stall_o <= not ack_int and wb_en;
  wb_rty_o <= '0';
  wb_err_o <= '0';

  -- Assign outputs
  CTL_ENABLE_o <= CTL_ENABLE_reg;
  CTL_EMU_EDGE_o <= CTL_EMU_EDGE_reg;
  CTL_EMU_LEN_o <= CTL_EMU_LEN_reg;
  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then
      IVT_RAM_rack <= '0';
    elsif rising_edge(clk_i) then
      IVT_RAM_rack <= IVT_RAM_re and not IVT_RAM_rack;
    end if;
  end process;
  IVT_RAM_data_o <= wb_dat_i;
  IVT_RAM_addr_o <= wb_adr_i(6 downto 2);

  -- Process for write requests.
  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then
      wr_ack_int <= '0';
      CTL_wr_o <= '0';
      CTL_ENABLE_reg <= '0';
      CTL_EMU_EDGE_reg <= '0';
      CTL_EMU_LEN_reg <= "0000000000000000";
      IER_wr_o <= '0';
      IDR_wr_o <= '0';
      SWIR_wr_o <= '0';
      EOIR_wr_o <= '0';
      IVT_RAM_wr_o <= '0';
    elsif rising_edge(clk_i) then
      wr_ack_int <= '0';
      CTL_wr_o <= '0';
      IER_wr_o <= '0';
      IDR_wr_o <= '0';
      SWIR_wr_o <= '0';
      EOIR_wr_o <= '0';
      IVT_RAM_wr_o <= '0';
      case wb_adr_i(7 downto 7) is
      when "0" => 
        case wb_adr_i(6 downto 2) is
        when "00000" => 
          -- Register CTL
          CTL_wr_o <= wr_int;
          if wr_int = '1' then
            CTL_ENABLE_reg <= wb_dat_i(0);
            CTL_POL_o <= wb_dat_i(1);
            CTL_EMU_EDGE_reg <= wb_dat_i(2);
            CTL_EMU_LEN_reg <= wb_dat_i(18 downto 3);
          end if;
          wr_ack_int <= wr_int;
        when "00001" => 
          -- Register RISR
        when "00010" => 
          -- Register IER
          IER_wr_o <= wr_int;
          if wr_int = '1' then
            IER_o <= wb_dat_i;
          end if;
          wr_ack_int <= wr_int;
        when "00011" => 
          -- Register IDR
          IDR_wr_o <= wr_int;
          if wr_int = '1' then
            IDR_o <= wb_dat_i;
          end if;
          wr_ack_int <= wr_int;
        when "00100" => 
          -- Register IMR
        when "00101" => 
          -- Register VAR
        when "00110" => 
          -- Register SWIR
          SWIR_wr_o <= wr_int;
          if wr_int = '1' then
            SWIR_o <= wb_dat_i;
          end if;
          wr_ack_int <= wr_int;
        when "00111" => 
          -- Register EOIR
          EOIR_wr_o <= wr_int;
          if wr_int = '1' then
            EOIR_o <= wb_dat_i;
          end if;
          wr_ack_int <= wr_int;
        when others =>
          wr_ack_int <= wr_int;
        end case;
      when "1" => 
        -- Submap IVT_RAM
        IVT_RAM_wr_o <= wr_int;
        wr_ack_int <= wr_int;
      when others =>
        wr_ack_int <= wr_int;
      end case;
    end if;
  end process;

  -- Process for registers read.
  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then
      rd_ack1_int <= '0';
      reg_rdat_int <= (others => 'X');
    elsif rising_edge(clk_i) then
      reg_rdat_int <= (others => '0');
      case wb_adr_i(7 downto 7) is
      when "0" => 
        case wb_adr_i(6 downto 2) is
        when "00000" => 
          -- CTL
          reg_rdat_int(0) <= CTL_ENABLE_reg;
          reg_rdat_int(1) <= CTL_POL_i;
          reg_rdat_int(2) <= CTL_EMU_EDGE_reg;
          reg_rdat_int(18 downto 3) <= CTL_EMU_LEN_reg;
          rd_ack1_int <= rd_int;
        when "00001" => 
          -- RISR
          reg_rdat_int <= RISR_i;
          rd_ack1_int <= rd_int;
        when "00010" => 
          -- IER
          rd_ack1_int <= rd_int;
        when "00011" => 
          -- IDR
          rd_ack1_int <= rd_int;
        when "00100" => 
          -- IMR
          reg_rdat_int <= IMR_i;
          rd_ack1_int <= rd_int;
        when "00101" => 
          -- VAR
          reg_rdat_int <= VAR_i;
          rd_ack1_int <= rd_int;
        when "00110" => 
          -- SWIR
          rd_ack1_int <= rd_int;
        when "00111" => 
          -- EOIR
          rd_ack1_int <= rd_int;
        when others =>
          rd_ack1_int <= rd_int;
        end case;
      when "1" => 
      when others =>
        rd_ack1_int <= rd_int;
      end case;
    end if;
  end process;

  -- Process for read requests.
  process (wb_adr_i, reg_rdat_int, rd_ack1_int, rd_int, rd_int, IVT_RAM_data_i, IVT_RAM_rack) begin
    -- By default ack read requests
    wb_dat_o <= (others => '0');
    IVT_RAM_re <= '0';
    case wb_adr_i(7 downto 7) is
    when "0" => 
      case wb_adr_i(6 downto 2) is
      when "00000" => 
        -- CTL
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00001" => 
        -- RISR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00010" => 
        -- IER
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00011" => 
        -- IDR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00100" => 
        -- IMR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00101" => 
        -- VAR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00110" => 
        -- SWIR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "00111" => 
        -- EOIR
        wb_dat_o <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when others =>
        rd_ack_int <= rd_int;
      end case;
    when "1" => 
      -- Submap IVT_RAM
      wb_dat_o <= IVT_RAM_data_i;
      rd_ack_int <= IVT_RAM_rack;
      IVT_RAM_re <= rd_int;
    when others =>
      rd_ack_int <= rd_int;
    end case;
  end process;
end syn;
