LFSR Using D Flip Flops

flipflopvhdl

I am fairly new to the VHDL language and I will admit that I primarily use it for educational purposes. I have been attempting to design a data encryption circuit using D flip flops. Obviously, an important component in the design of the encryption is the key.

My overall goal is to create a unique key for every input using a LFSR (linear feedback shift register). Hence, I'd have an initial value (8 bits) fed in as my input and then a new key would be generated every time a "push" signal is sent.

The issue that I'm having is that every subsequent key is going to be a shifted version of the current contents of the D flip flops. I was wondering if there is a way to access the current contents of the D flip flops? I have defined my D flip flop as follows:

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity DFlipFlop is
    Port ( D : in  STD_LOGIC;
           EN : in  STD_LOGIC;
              CLK : in STD_LOGIC;
           Q : out  STD_LOGIC);
end DFlipFlop;

architecture Behavioral of DFlipFlop is

begin

process (EN, CLK)

begin
    if CLK = '1' and CLK'event and EN = '1' then
        Q <= D;
    end if;
end process;


end Behavioral;

I'd hope to keep the enable input because it will be useful in other modules that will be based on the LFSR. Any assistance on this would be appreciated.

Update #1

Here's something to give everyone a better idea on what I am trying to achieve. Please refer to the image below:

enter image description here

What I hope to achieve with my enable input is for the input data to be fed into the LFSR and also perform the function in the image above. Otherwise, perform the function using only the current data in the FFs, ignoring whatever the input data may be. I have created a test bench of my FF and it seemed to work fine. I have also created a potential LFSR:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity LFSR_NoPush is
    Port ( KeySet : in  STD_LOGIC;
              EN_FF : in STD_LOGIC;
           DataIn : in  STD_LOGIC_VECTOR (7 downto 0);
              CLK : in STD_LOGIC;
           DataOut : out  STD_LOGIC_VECTOR (7 downto 0));
end LFSR_NoPush;

architecture Behavioral of LFSR_NoPush is

component DFlipFlop is
    Port ( D : in  STD_LOGIC;
           EN : in  STD_LOGIC;
              CLK : in STD_LOGIC;
           Q : out  STD_LOGIC);
end component;

signal Key5, Key4, Key3 : STD_LOGIC;
signal LFSRData : STD_LOGIC_VECTOR(7 downto 0);

begin

process (DataIn, LFSRData)
begin
    if KeySet = '1' then
        LFSRData <= DataIn;
    end if;
end process;

    Key5 <= LFSRData(6) xnor LFSRData(0);
    Key4 <= LFSRData(5) xnor LFSRData(0);
    Key3 <= LFSRData(4) xnor LFSRData(0);

    LFSR7 : DFlipFlop
    port map (LFSRData(0), EN_FF, CLK, DataOut(7));

    LFSR6 : DFlipFlop
    port map (LFSRData(7), EN_FF, CLK, DataOut(6)); 

    LFSR5 : DFlipFlop
    port map (Key5, EN_FF, CLK, DataOut(5)); 

    LFSR4 : DFlipFlop
    port map (Key4, EN_FF, CLK, DataOut(4)); 

    LFSR3 : DFlipFlop
    port map (Key3, EN_FF, CLK, DataOut(3)); 

    LFSR2 : DFlipFlop
    port map (LFSRData(3), EN_FF, CLK, DataOut(2)); 

    LFSR1 : DFlipFlop
    port map (LFSRData(2), EN_FF, CLK, DataOut(1));

    LFSR0 : DFlipFlop
    port map (LFSRData(1), EN_FF, CLK, DataOut(0));     

end Behavioral;

However, for whatever reason, my input data is never fed into the FFs based on my test bench. Again, any help on this would be appreciated.

Update #2

The top module of my circuit will have the following inputs/outputs:

Inputs:

  1. Data In
  2. Key set
  3. Push

Outputs:

  1. Ciphered text

The process I'd hope for my circuit to have is as follows:

  1. If key set is high, data in is the initial key value. If not, it is the text to be encrypted.
  2. If data in is the initial key value, then it will be fed into the FFs. If not, data in will be XOR'd by the key to create the encrypted text.
  3. Once data in arrives in the FFs, it will remain unaltered until push is high. Once push is high, the procedure in the image will occur to generate the key.
  4. Key set should only be set to high once. Then, subsequent keys will be created based on the previous key value. Therefore, every time push is high, the DataOut (based on my code) of the previous key should be the input of the FFs for the next key and then the process in the image should be followed.

Step #4 is where I am struggling the most.

Is this at all possible with D FFs?

Best Answer

I think the things that is really missing from your design are signals, signals exist inside the architecture and can be assigned in much the same way as a port but without an interface to the outside world, a signal can be written to and read from and can be any type you like and an output can be assigned a signal of the same type so for your design consider using an internal register and then assigning it to your output.

Here's an example of what I mean:

library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;

entity lfsr is

    port (

        -- Clocks
        clkin                                   :in  STD_LOGIC; 

        -- Initialisation data
        first_key                               :in  STD_LOGIC_VECTOR(3 downto 0);

        -- Control Signals
        key_set                                 :in  STD_LOGIC;
        push                                    :in  STD_LOGIC;

        -- Outputs
        data_out                                :out STD_LOGIC_VECTOR(3 downto 0);              
        );

end lfsr;   

architecture RTL1 of lfsr is    

    signal key                      :STD_LOGIC_VECTOR(3 downto 0);

begin                                                                                                               

    -- Generate a key every time the push signal is asserted
    process(clkin)
    begin

        if rising_edge(clkin) then

            if key_set = '1' then -- Initialises the key

                key <=  first_key; 

            elsif push = '1' then -- Generate a new key

                key(2 downto 0) <=  key(3 downto 1);
                key(3)          <=  key(1) XOR key(0);

            end if;

        end if;

    end process;

    -- Send internal key to output port
    data_out    <=  key;

end RTL1;

so the signal that I have created is key, it is internal to the architecture and what it actually represents is a block of memory 4 bits wide. This code actually does what you want, it is a LFSR that will generate pseudo random data but I have made it 4 bits wide instead of 8 because I didn't want to just give you the answer and if you can understand what this code does, you will be able to understand how to expand it to 8-bits and it will be a great start to understanding VHDL.

If you have any questions about my code then please ask,

Gipsy

Related Topic