---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: -- Design Name: -- Module Name: LFSR12_wZERO - 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 except that I have added the all 0 case -- and changed the shift right to a shift left. If set_seed is 1, then load seed. If set_seed is 0 -- and gen_bit is 1, do a 1-bit shift. -- NOTE: We could include several 12-bit LFSRs that implement a different primitive. Just note that it is -- possible at one or more iterations that the two LFSRs (which now each cycle through the 4095 number space -- in a different fashion) that both LFSRs generate the same number, which of course would specify the same -- SMC. This would obviously generate an 'invalid' bit during enrollment but otherwise would be harmless. -- =================================================================================================== library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.all; entity LFSR12_wZERO is generic (LFSR_LEN_NB: integer := 12); port ( Clk: in std_logic; RESET: in std_logic; set_seed: in std_logic; gen_bit: in std_logic; 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_wZERO; architecture beh of LFSR12_wZERO is signal LFSR_reg, LFSR_next: std_logic_vector(LFSR_LEN_NB-1 downto 0); signal next_bit: std_logic; signal nor_bit: std_logic; signal request: std_logic_vector(1 downto 0); 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; -- Set seed takes priority if both are set request <= set_seed & gen_bit; -- Add the 'all zero' state. Simply the bitwise nor of the lower 11 bits. See -- LFSR_C_Validation/VHDL_NO_NORM_wZERO.c for a C implementation of this LFSR. nor_bit <= not(LFSR_reg(10) or LFSR_reg(9) or LFSR_reg(8) or LFSR_reg(7) or LFSR_reg(6) or LFSR_reg(5) or LFSR_reg(4) or LFSR_reg(3) or LFSR_reg(2) or LFSR_reg(1) or LFSR_reg(0)); -- Confirmed this is a primitive in a C code implementation. NOTE: Implementation in -- /home/research/research/FPGAs/HELP/VHDL_HELP/contrib/lfsr_randgen/trunk/lfsr_pkg.vhd -- shifts the new bit on the right, as we do here. This is important -- if reversed, -- you need to reverse the tap points. -- xor_out := rand(11) xor rand(5) xor rand(3) xor rand(0); next_bit <= LFSR_reg(11) xor LFSR_reg(5) xor LFSR_reg(3) xor LFSR_reg(0) xor nor_bit; -- Preserve contents or put the seed in or shift the LSFR to generate the new bit. Reversed -- bit shift on 9/27/2013 to match that in above C file. LFSR_next <= LFSR_reg when (request = "00") else seed when (request(1) = '1') else LFSR_reg(LFSR_LEN_NB-2 downto 0) & next_bit; LFSR_out <= LFSR_reg; end beh;