--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
use ieee.STD_LOGIC_UNSIGNED.all;

--LIBRARY sercon;
USE work.sercon_types.all;


entity sercon_reg is

  generic(
    reset_value:integer:=0;
    bit_width:natural:=sercon_bit_width
    );
  
  port(
    ctrl: in sercon_ctrl;
    --
    sbus_in: in sercon_bus;
    sbus_out: out sercon_bus;
    
    --
    -- parallel data output/input.
    pdout: out std_logic_vector(bit_width-1 downto 0);
    pdin: in std_logic_vector(bit_width-1 downto 0):=(others=>'0')
    
    );
  
end entity sercon_reg;

--
architecture v0 of sercon_reg is
  signal rst: std_logic;
  signal clk: std_logic;
--      
  signal wload: std_logic;
  signal rload: std_logic;
  signal sclk_en: std_logic;
-- serial data input
  signal sdin: std_logic;
-- serial data output
  signal sdout: std_logic;
-- serial mask input 
  signal smin: std_logic;
-- serial mask output: 
  signal smout: std_logic;
  
  signal int_data: std_logic_vector(bit_width-1 downto 0);
  signal int_dsreg: std_logic_vector(bit_width-1 downto 0);
  signal int_msreg: std_logic_vector(bit_width-1 downto 0);
begin

  rst<=ctrl.rst;
  clk<=ctrl.clk;
  sclk_en<=ctrl.cen;
  wload<=ctrl.wload;
  rload<=ctrl.rload;

  sdin<=sbus_in.sdata;
  smin<=sbus_in.smask;
  
  sbus_out.sdata<=sdout;
  sbus_out.smask<=smout;
    
  smout<=int_msreg(bit_width-1);
  sdout<=int_dsreg(bit_width-1);

  pdout<=int_data;
  
  sercon_slave:process(rst, clk)

  begin
    if(rst='1')then 
      int_data<=conv_std_logic_vector(reset_value, bit_width);
      int_msreg<=(others=>'0');
      int_dsreg<=(others=>'0');

      --smout<='0';
      --sdout<='0';
      
    elsif(clk='1' and clk'event)then
      
      if(sclk_en='1')then
        int_msreg<=int_msreg(bit_width-2 downto 0)&smin;
        int_dsreg<=int_dsreg(bit_width-2 downto 0)&sdin;

     
      elsif(rload='1')then
        int_dsreg<=pdin;
      elsif(wload='1')then
        int_dsreg<=(others=>'0');
        int_msreg<=(others=>'0');        
      end if;

      
      for i in 0 to (bit_width-1)loop
        if(wload='1' and int_msreg(i)='1')then
          int_data(i)<=int_dsreg(i);
        end if;
      end loop;
      
    end if;
  end process sercon_slave;     
  
end architecture v0;


