# 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

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

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