-------------------------------------------------------------------------------
--
--  File          : multadd_ctrl.vhd
--  Related files : multadd.vhd
--
--  Author(s)     : stephane Domas (sdomas@univ-fcomte.fr)
--
--  Creation Date : 2015/04/27
--
--  Description   : This component is generated automatically.
--                  It contains processes to r/w registers defined for multadd
--                  via wishbone.
--
--  Note          : No notes
--
-------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

-------------------------------------------------------------------------------
--  wishbone registers
-------------------------------------------------------------------------------
--  name               bits            address  R/W         
--  wb_do_op           0               0x0000    W
--  wb_c               (15 downto 0)   0x0001    W
--  wb_d               (15 downto 0)   0x0002    R
--  wb_d               (31 downto 0)   0x0003    R
--
-------------------------------------------------------------------------------

entity multadd_ctrl is
  generic (
    wb_data_width : integer := 16;
    wb_addr_width : integer := 2
    );
  port (
    -- clk/rst from interconnector
    rst : in std_logic;
    clk : in std_logic;

    -- addr/data from interconnector
    addr_i : in  std_logic_vector(wb_addr_width-1 downto 0);
    dat_i  : in  std_logic_vector(wb_data_width-1 downto 0);
    dat_o  : out std_logic_vector(wb_data_width-1 downto 0);
    cyc_i  : in  std_logic;
    stb_i  : in  std_logic;
    we_i   : in  std_logic;
    ack_o  : out std_logic;

    -- registers r/w via wishbone that are forwarded to the block
    wb_do_op : out  std_logic;
    wb_c     : out  std_logic_vector(wb_data_width-1 downto 0);
    wb_d     : in std_logic_vector(2*wb_data_width-1 downto 0)

    );
end multadd_ctrl;


architecture multadd_ctrl1 of multadd_ctrl is

  -- signals : registers r/w via wishbone
  signal wb_do_op_s : std_logic;
  signal wb_c_s     : std_logic_vector(wb_data_width-1 downto 0);
  signal wb_d_s     : std_logic_vector(2*wb_data_width-1 downto 0);

  -- signals : wishbone related
  signal read_data : std_logic_vector(wb_data_width-1 downto 0);
  signal read_ack  : std_logic;
  signal write_ack : std_logic;
  signal write_rise : std_logic;

begin
-- ----------------------------------------------------------------------------
--  signals from/to ports
-- ----------------------------------------------------------------------------
  wb_d_s <= wb_d;
  wb_c <= wb_c_s;
  wb_do_op <= wb_do_op_s;
  
-- ----------------------------------------------------------------------------
--  write rising edge detection
-- ----------------------------------------------------------------------------
  detection_front : process(gls_clk, gls_reset)
    variable signal_old : std_logic;
  begin
    if (gls_reset = '1') then
      signal_old := '0';
      write_rise <= '0';
    elsif rising_edge(gls_clk) then
      if (signal_old = '0' and stb_i = '1' and cyc_i = '1' and we_i = '1') then
        write_rise <= '1';
      else
        write_rise <= '0';
      end if;
      signal_old := we_i;
    end if;
  end process detection_front;

-- ----------------------------------------------------------------------------
--  Register reading process
-- ----------------------------------------------------------------------------
  reading_reg : process(clk, rst)
  begin
    if(rst = '1') then
      read_ack  <= '0';
      read_data <= (others => '0');
    elsif(rising_edge(clk)) then
      read_ack <= '0';
      if (stb_i = '1' and cyc_i = '1' and we_i = '0') then
        read_ack <= '1';
        if(addr_i = "10") then
          read_data <= wb_d_s(15 downto 0);
        elsif(addr_i = "11") then
          read_data <= wb_d_s(31 downto 16);
        else
          read_data <= (others => '0');
        end if;
      end if;
    end if;
  end process reading_reg;

-- ----------------------------------------------------------------------------
--  Register writing process
-- ----------------------------------------------------------------------------
  writing_reg : process(clk, rst)
  begin
    if(rst = '1') then
      write_ack <= '0';
      wb_do_op_s  <= '0';
      wb_c_s      <= (others => '0');
    elsif(rising_edge(clk)) then
      write_ack <= '0';
      wb_do_op_s  <= '0';
      if (write_rise = '1') then
        write_ack <= '1';
        if (addr_i = "00") then
          wb_do_op_s <= '1';
        elsif (addr_i = "01") then
          wb_c_s <= dat_i;
        end if;
      end if;
    end if;
  end process writing_reg;

-- ----------------------------------------------------------------------------
-- assignations for wishbone outputs
-- ----------------------------------------------------------------------------
  ack_o <= read_ack or write_ack;
  dat_o <= read_data when (stb_i = '1' and cyc_i = '1' and we_i = '0') else (others => '0');

end multadd_ctrl1;