# Case Study Module 6 - LFSR (Linear Feedback Shift Register) ``` Name : Evandra Rasya Fadhillah NPM : 2406450352 ``` ## What is LFSR? Imagine you have a **chain of boxes** containing 0s or 1s. Every second: 1. All numbers **shift right** by one box 2. The number in the rightmost box **comes out** 3. The leftmost box is filled with a new number calculated from **certain boxes** That's LFSR! Shift Register with feedback. ### Simple Example (4-bit) Suppose we have 4 boxes: `[1][0][1][1]` **Rule:** New number = box 3 XOR box 2 ``` Start: [1][0][1][1] Step 1: Calculate new number = 1 XOR 1 = 0 Shift right: [0][1][0][1] (1 comes out, 0 comes in) Step 2: Calculate new number = 0 XOR 1 = 1 Shift right: [1][0][1][0] (1 comes out, 1 comes in) Step 3: Calculate new number = 1 XOR 0 = 1 Shift right: [1][1][0][1] (0 comes out, 1 comes in) ``` The numbers change like **random numbers**, but actually follow a definite rule. ### Important Terms - **Seed** = Initial value (starting value). Like `[1][0][1][1]` in the example. - **Tap** = Which boxes are used to calculate feedback. In the example: box 3 and 2. - **Feedback** = New number that comes in from the calculation. --- ## Task 1 (70 points) Create an **8-bit LFSR** that works like this: ``` [Bit 7][Bit 6][Bit 5][Bit 4][Bit 3][Bit 2][Bit 1][Bit 0] ↓ ↓ Feedback = bit 7 XOR bit 5 XOR bit 4 XOR bit 3 out ``` ### Input/Output Specification **Input:** - `clk` = Clock signal (every rising edge = 1 step) - `reset` = Synchronous reset, when '1' -> load seed value - `seed` = std_logic_vector 8-bit -> initial value of LFSR `(Enable is OPTIONAL! Not required, but recommended)` - `enable` = std_logic, when '1' -> LFSR runs, when '0' -> LFSR stops (pause button) **Output:** - `lfsr_out` = std_logic_vector 8-bit -> current contents of LFSR - `random_bit` = std_logic -> rightmost bit (bit 0) that comes out ### Detailed Operation **Every clock cycle (when enable = '1'):** 1. **Calculate feedback:** ``` feedback = lfsr_reg(7) XOR lfsr_reg(5) XOR lfsr_reg(4) XOR lfsr_reg(3) ``` **MUST use a FOR LOOP to calculate this XOR!** 2. **Shift right:** ``` lfsr_reg(7) <- feedback (new bit comes in) lfsr_reg(6) <- lfsr_reg(7) (shift) lfsr_reg(5) <- lfsr_reg(6) (shift) ... lfsr_reg(0) <- lfsr_reg(1) (shift, this bit comes out as random_bit which is shown in the output) ``` 3. **Output:** ``` lfsr_out = lfsr_reg (show all bits) random_bit = lfsr_reg(0) (the bit that comes out) ``` ### Complete Example **Seed = `10110100`** ``` Clock 1 (Reset) lfsr_out = 10110100 random_bit = 0 Clock 2 (Enable = 1) Calculate feedback: feedback = bit[7] XOR bit[5] XOR bit[4] XOR bit[3] feedback = 1 XOR 1 XOR 0 XOR 1 = 1 Before shift: [1][0][1][1][0][1][0][0] After shift: [1][1][0][1][1][0][1][0] ↑ feedback ↑ out lfsr_out = 11011010 random_bit = 0 Clock 3 (Enable = 1) feedback = 1 XOR 0 XOR 1 XOR 1 = 1 Before shift: [1][1][0][1][1][0][1][0] After shift: [1][1][1][0][1][1][0][1] lfsr_out = 11101101 random_bit = 1 Clock 4 (Enable = 1) feedback = 1 XOR 1 XOR 0 XOR 1 = 1 lfsr_out = 11110110 random_bit = 0 ``` ### Code to Complete ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lfsr_8bit is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; seed : in std_logic_vector(7 downto 0); lfsr_out : out std_logic_vector(7 downto 0); random_bit : out std_logic ); end lfsr_8bit; architecture Behavioral of lfsr_8bit is signal lfsr_reg : std_logic_vector(7 downto 0) := (others => '0'); begin process(clk) variable feedback : std_logic; variable temp : std_logic_vector(7 downto 0); begin if rising_edge(clk) then if reset = '1' then -- TODO: Load seed to lfsr_reg elsif enable = '1' then -- TODO: Calculate feedback using FOR LOOP (REQUIRED!) -- Tap positions: bit 7, 5, 4, 3 -- feedback = bit[7] XOR bit[5] XOR bit[4] XOR bit[3] -- Example loop structure: -- feedback := lfsr_reg(7); -- start with bit 7 -- for i in ... loop -- if i is a tap position then -- feedback := feedback xor lfsr_reg(i); -- end if; -- end loop; -- TODO: Shift right -- temp(7) := feedback; -- temp(6 downto 0) := lfsr_reg(7 downto 1); -- lfsr_reg <= temp; end if; end if; end process; -- Output lfsr_out <= lfsr_reg; random_bit <= lfsr_reg(0); end Behavioral; ``` ### Testbench Hints Create a testbench that: 1. Set seed = "10110100", reset = '1' for 1 cycle 2. Set reset = '0', enable = '1' (optional), run for 15 clock cycles ## Task 1 Questions 1. **[50 points] Include:** - Complete VHDL code (entity + architecture) - Testbench code - Screenshot of ModelSim wave diagram ![image](https://hackmd.io/_uploads/SktFf3lpgg.png) lfsr_8bit Code: ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lfsr_8bit is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; seed : in std_logic_vector(7 downto 0); lfsr_out : out std_logic_vector(7 downto 0); random_bit : out std_logic); end lfsr_8bit; architecture Behavioral of lfsr_8bit is signal lfsr_reg : std_logic_vector(7 downto 0) := (others => '0'); begin process(clk) variable feedback : std_logic; variable temp : std_logic_vector(7 downto 0); begin if rising_edge(clk) then if reset = '1' then lfsr_reg <= seed; elsif enable = '1' then feedback := '0'; for i in 0 to 7 loop if (i = 7) or (i = 5) or (i = 4) or (i = 3) then feedback := feedback xor lfsr_reg(i); end if; end loop; temp(7) := feedback; temp(6 downto 0) := lfsr_reg(7 downto 1); lfsr_reg <= temp; end if; end if; end process; lfsr_out <= lfsr_reg; random_bit <= lfsr_reg(0); end Behavioral; ``` tb_lfsr_8bit code: ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity tb_lfsr_8bit is end tb_lfsr_8bit; architecture sim of tb_lfsr_8bit is signal clk : std_logic := '0'; signal reset : std_logic := '0'; signal enable : std_logic := '0'; signal seed : std_logic_vector(7 downto 0) := "10110100"; signal lfsr_out : std_logic_vector(7 downto 0); signal random_bit : std_logic; constant T : time := 10 ns; begin clk <= not clk after T/2; uut: entity work.lfsr_8bit port map ( clk => clk, reset => reset, enable => enable, seed => seed, lfsr_out => lfsr_out, random_bit => random_bit); stim: process begin reset <= '1'; enable <= '0'; wait for T; reset <= '0'; enable <= '1'; wait for 15*T; enable <= '0'; wait for 5*T; wait; end process; end sim; ``` **Wave diagram requirements:** - At least 15 clock cycles visible - All signals displayed: clk, reset, enable (optional), seed, lfsr_out, random_bit - Use Binary radix for lfsr_out for clarity - Add marker/comment on 2-3 important transitions 2. **[10 points] Why can't the seed be `00000000`?** ``` Cant be 0000 because the LSFT logic is linear and make 0 so the register always zero state or its locked ``` Hint: Try calculating feedback if all bits are 0. What happens in the next cycle? 3. **[10 points] From your wave diagram, does lfsr_out ever return to the seed value?** ``` Infinite not visible after wave 15 wave form the maximum length return the original seed 255 ``` If yes, after how many clock cycles? If not visible in the wave, how many cycles are needed for an 8-bit LFSR with taps (7,5,4,3)? Hint: With correct taps, an 8-bit LFSR will generate a maximum-length sequence = 2^8 - 1 = 255 states. --- ## Task 2 (25 points) Now create the same LFSR, but using **D Flip-Flop components** and a **for generate loop**. ### Concept Instead of writing behavioral code, we will: 1. Create 8 D Flip-Flops 2. Connect them in a chain (output of one DFF to input of the next) 3. Feedback goes into the leftmost DFF ``` Feedback ──-> [DFF7] ──-> [DFF6] ──-> [DFF5] ──-> ... ──-> [DFF0] ──-> Output ↑ ↓ └──────────────────────────────────────────┘ (calculated from taps) ``` ### Step 1: Create D Flip-Flop Component **New file:** `dff_enable.vhd` ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity dff_enable is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; d : in std_logic; q : out std_logic ); end dff_enable; architecture Behavioral of dff_enable is signal q_reg : std_logic := '0'; begin process(clk) begin if rising_edge(clk) then if reset = '1' then -- Load the d value during reset (for seed loading) q_reg <= d; elsif enable = '1' then q_reg <= d; end if; end if; end process; q <= q_reg; end Behavioral; ``` **Explanation:** - D Flip-Flop stores 1 bit - Every clock cycle: - If reset=1: Load the `d` input value (this allows seed loading) - Else if enable=1: Store the `d` input value to `q` output ### Step 2: Create LFSR Generator **New file:** `lfsr_generator.vhd` ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lfsr_generator is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; seed : in std_logic_vector(7 downto 0); lfsr_out : out std_logic_vector(7 downto 0) ); end lfsr_generator; architecture Structural of lfsr_generator is -- D Flip-Flop component declaration component dff_enable is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; d : in std_logic; q : out std_logic ); end component; -- Internal signals signal q_out : std_logic_vector(7 downto 0); -- output from 8 DFFs signal feedback : std_logic; signal dff_input : std_logic_vector(7 downto 0); -- input to each DFF begin -- Calculate feedback (same as Task 1) feedback <= q_out(7) xor q_out(5) xor q_out(4) xor q_out(3); -- Multiplexer: select between seed (during reset) or shift data (normal operation) -- When reset=1, we load the seed value into all DFFs -- When reset=0 and enable=1, we shift the register process(reset, seed, feedback, q_out) begin if reset = '1' then -- Load seed during reset dff_input <= seed; else -- Normal shift operation dff_input(7) <= feedback; -- Bit 7 gets feedback dff_input(6) <= q_out(7); -- Bit 6 gets from bit 7 dff_input(5) <= q_out(6); -- Bit 5 gets from bit 6 dff_input(4) <= q_out(5); -- Bit 4 gets from bit 5 dff_input(3) <= q_out(4); -- Bit 3 gets from bit 4 dff_input(2) <= q_out(3); -- Bit 2 gets from bit 3 dff_input(1) <= q_out(2); -- Bit 1 gets from bit 2 dff_input(0) <= q_out(1); -- Bit 0 gets from bit 1 (shifts out) end if; end process; -- USE FOR GENERATE to create 8 D Flip-Flops -- Each DFF will store 1 bit of the LFSR gen_dff: for i in 0 to 7 generate dff_inst: dff_enable port map ( clk => clk, reset => reset, enable => enable, d => dff_input(i), -- input q => q_out(i) -- output ); end generate; -- Output lfsr_out <= q_out; end Structural; ``` **Explanation of for generate:** ```vhdl gen_dff: for i in 0 to 7 generate -- This will create 8 instances of DFF -- i=0 -> create DFF for bit 0 -- i=1 -> create DFF for bit 1 -- ... -- i=7 -> create DFF for bit 7 end generate; ``` **Compared to manual way:** ```vhdl -- Without generate (manual, longer) dff0: dff_enable port map (clk, reset, enable, dff_input(0), q_out(0)); dff1: dff_enable port map (clk, reset, enable, dff_input(1), q_out(1)); dff2: dff_enable port map (clk, reset, enable, dff_input(2), q_out(2)); -- ... 8 lines total! -- With generate (shorter) gen_dff: for i in 0 to 7 generate dff: dff_enable port map (clk, reset, enable, dff_input(i), q_out(i)); end generate; ``` ### Testbench for Task 2 Use the same testbench as Task 1, but instantiate `lfsr_generator` instead of `lfsr_8bit`. --- ## Task 2 Questions 1. **[15 points] Include:** - Complete code for `dff_enable.vhd` - Complete code for `lfsr_generator.vhd` - Screenshot of wave diagram ![image](https://hackmd.io/_uploads/SkrOv2eTel.png) dff_enable code: ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity dff_enable is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; d : in std_logic; q : out std_logic); end dff_enable; architecture Behavioral of dff_enable is signal q_reg : std_logic := '0'; begin process(clk) begin if rising_edge(clk) then if reset = '1' then q_reg <= d; elsif enable = '1' then q_reg <= d; end if; end if; end process; q <= q_reg; end Behavioral; ``` lfsr_generator code: ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lfsr_generator is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; seed : in std_logic_vector(7 downto 0); lfsr_out : out std_logic_vector(7 downto 0)); end lfsr_generator; architecture Structural of lfsr_generator is component dff_enable is Port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; d : in std_logic; q : out std_logic); end component; signal q_out : std_logic_vector(7 downto 0); signal dff_input : std_logic_vector(7 downto 0); signal feedback : std_logic; begin feedback <= q_out(7) xor q_out(5) xor q_out(4) xor q_out(3); process(reset, seed, feedback, q_out) begin if reset = '1' then dff_input <= seed; else dff_input(7) <= feedback; dff_input(6) <= q_out(7); dff_input(5) <= q_out(6); dff_input(4) <= q_out(5); dff_input(3) <= q_out(4); dff_input(2) <= q_out(3); dff_input(1) <= q_out(2); dff_input(0) <= q_out(1); end if; end process; gen_dff: for i in 0 to 7 generate dff_i: dff_enable port map ( clk => clk, reset => reset, enable => enable, d => dff_input(i), q => q_out(i)); end generate; lfsr_out <= q_out; end Structural; ``` **Make sure the result is the SAME as Task 1!** 2. **[15 points] Explain the difference:** - **For loop** (Task 1): What is it used for? When is it executed? - **For generate loop** (Task 2): What is it used for? When is it executed? ``` For loop is used for sequential statement and its executed during the first code on Wait for T which is looping executing during the simulation The For generator is used for generation of statement after the initial executions and it used during exeuciton of the lsfr generator ``` --- ### Tips **If LFSR is stuck (not changing):** - Check if feedback calculation is correct - Make sure shift operation is correct - Check if enable signal is active **If result does not match the example:** - Check tap positions (7, 5, 4, 3) - Make sure to XOR all taps, not just some - Check shift order (right/left) **If generate does not compile:** - Make sure component is declared - Check port map syntax - Make sure d_in and q_out signals are defined