----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    
-- Design Name: 
-- Module Name:    ChlngLFSR - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------

-- ===================================================================================================
-- LFSR -- modeled after the version available in OpenCores. If set_seed is 1, then load seed. If set_seed is 
-- 0 and gen_bit is 1, do a 1-bit shift 
-- ===================================================================================================

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;

entity LFSR12_A is
   generic (LFSR_LEN_NB: integer := 12);
   port (
      Clk: in std_logic;
      RESET: in std_logic;
      request: in std_logic_vector(1 downto 0);
      seed: in std_logic_vector(LFSR_LEN_NB-1 downto 0);
      LFSR_out: out std_logic_vector(LFSR_LEN_NB-1 downto 0)
      );
end LFSR12_A;

architecture beh of LFSR12_A is
   signal LFSR_reg, LFSR_next: std_logic_vector(LFSR_LEN_NB-1 downto 0);
   signal next_bit: std_logic;
   
   begin

-- state and register logic
   process(Clk, RESET)
      begin
      if ( RESET = '1' ) then
         LFSR_reg <= (LFSR_LEN_NB-1 downto 1 =>'0') & (0=>'1');
      elsif ( Clk'event and Clk = '1' ) then
         LFSR_reg <= LFSR_next;
      end if; 
   end process;

-- Confirmed this is a primitive in a C code implementation.
   next_bit <= LFSR_reg(11) xor LFSR_reg(8) xor LFSR_reg(6) xor LFSR_reg(0);

-- Preserve contents or put the seed in or shift the LSFR to generate the new bit 
   LFSR_next <= LFSR_reg when (request = "00") else
                seed when (request(1) = '1') else
                next_bit & LFSR_reg(LFSR_LEN_NB-1 downto 1); 

   LFSR_out <= LFSR_reg;

end beh;
