---
# System prepended metadata

title: Case Study Module 6 - LFSR (Linear Feedback Shift Register)

---

# 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