We use FIFO full and empty flags to know when the FIFO memory is full or empty. This helps control data flow safely without losing or overwriting data.
FIFO full and empty flags in VHDL
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fifo_flags is port( clk : in std_logic; reset : in std_logic; write_en : in std_logic; read_en : in std_logic; full : out std_logic; empty : out std_logic ); end fifo_flags; architecture behavioral of fifo_flags is constant FIFO_DEPTH : integer := 8; signal write_pointer : integer range 0 to FIFO_DEPTH - 1 := 0; signal read_pointer : integer range 0 to FIFO_DEPTH - 1 := 0; signal count : integer range 0 to FIFO_DEPTH := 0; begin process(clk, reset) variable temp_count : integer range 0 to FIFO_DEPTH; begin if reset = '1' then write_pointer <= 0; read_pointer <= 0; count <= 0; elsif rising_edge(clk) then temp_count := count; if write_en = '1' and full = '0' then write_pointer <= (write_pointer + 1) mod FIFO_DEPTH; temp_count := temp_count + 1; end if; if read_en = '1' and empty = '0' then read_pointer <= (read_pointer + 1) mod FIFO_DEPTH; temp_count := temp_count - 1; end if; count <= temp_count; end if; end process; full <= '1' when count = FIFO_DEPTH else '0'; empty <= '1' when count = 0 else '0'; end behavioral;
The count signal tracks how many items are in the FIFO.
The full flag is high when count equals the FIFO size.
-- Case: FIFO is empty count <= 0; full <= '0'; empty <= '1';
-- Case: FIFO has one element count <= 1; full <= '0'; empty <= '0';
-- Case: FIFO is full count <= FIFO_DEPTH; full <= '1'; empty <= '0';
-- Case: Write when full if full = '1' then -- do not write, prevent overflow end if;
This testbench resets the FIFO, writes data until full, tries to write when full, reads all data until empty, and tries to read when empty. It reports the full and empty flags each clock cycle.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fifo_flags_tb is end fifo_flags_tb; architecture testbench of fifo_flags_tb is signal clk : std_logic := '0'; signal reset : std_logic := '1'; signal write_en : std_logic := '0'; signal read_en : std_logic := '0'; signal full : std_logic; signal empty : std_logic; constant CLK_PERIOD : time := 10 ns; component fifo_flags is port( clk : in std_logic; reset : in std_logic; write_en : in std_logic; read_en : in std_logic; full : out std_logic; empty : out std_logic ); end component; begin uut: fifo_flags port map(clk, reset, write_en, read_en, full, empty); clk_process : process begin clk <= '0'; wait for CLK_PERIOD/2; clk <= '1'; wait for CLK_PERIOD/2; end process; stim_proc: process begin -- Reset FIFO reset <= '1'; wait for 20 ns; reset <= '0'; -- Initially FIFO is empty write_en <= '0'; read_en <= '0'; wait for 10 ns; -- Write 8 times to fill FIFO for i in 1 to 8 loop write_en <= '1'; wait for 10 ns; end loop; write_en <= '0'; wait for 10 ns; -- Try to write when full (should not increase count) write_en <= '1'; wait for 10 ns; write_en <= '0'; wait for 10 ns; -- Read 8 times to empty FIFO for i in 1 to 8 loop read_en <= '1'; wait for 10 ns; end loop; read_en <= '0'; wait for 10 ns; -- Try to read when empty (should not decrease count) read_en <= '1'; wait for 10 ns; read_en <= '0'; wait; end process; monitor_proc: process(clk) begin if rising_edge(clk) then report "Full flag: " & std_logic'image(full) & ", Empty flag: " & std_logic'image(empty); end if; end process; end testbench;
Time complexity: O(1) for checking full and empty flags.
Space complexity: O(1) for the flags and counters.
Common mistake: Forgetting to update the count correctly when writing or reading.
Use full and empty flags to prevent overflow and underflow in FIFO buffers.
FIFO full flag is high when the buffer is full and no more data can be written.
FIFO empty flag is high when the buffer has no data to read.
These flags help control safe data flow in hardware designs.
Practice
Solution
Step 1: Understand FIFO full flag meaning
The FIFO full flag signals when the buffer has reached its maximum capacity.Step 2: Interpret the flag's implication
When full, no more data can be written safely to the FIFO.Final Answer:
The buffer is full and cannot accept more data -> Option DQuick Check:
FIFO full flag = buffer full [OK]
- Confusing full flag with empty flag
- Thinking full means partially filled
- Assuming full flag resets the buffer
Solution
Step 1: Identify flag signal requirements
Flags represent binary states: high or low (1 or 0).Step 2: Choose suitable VHDL type
std_logic is used for single-bit signals representing logic levels.Final Answer:
std_logic -> Option AQuick Check:
Flags use std_logic type [OK]
- Using integer or real for binary flags
- Using string type for flags
- Confusing std_logic_vector with std_logic
full_flag <= '1' when (write_ptr + 1) mod depth = read_ptr else '0';
What does this expression check?
Solution
Step 1: Analyze the condition
The expression checks if incrementing write_ptr wraps to read_ptr.Step 2: Understand FIFO full logic
When next write position equals read pointer, FIFO is full to avoid overwrite.Final Answer:
If the next write position equals the read position, indicating full -> Option BQuick Check:
Next write = read pointer means full [OK]
- Confusing full condition with empty condition
- Ignoring modulo wrap-around
- Assuming write_ptr = read_ptr means full
empty_flag <= '1' when write_ptr = read_ptr + 1 else '0';
Solution
Step 1: Recall FIFO empty condition
FIFO is empty when write_ptr equals read_ptr, no data to read.Step 2: Compare given condition
The condition uses write_ptr = read_ptr + 1, which is incorrect for empty.Final Answer:
The condition should be write_ptr = read_ptr for empty -> Option CQuick Check:
Empty flag triggers when pointers are equal [OK]
- Using offset in empty condition
- Confusing full and empty pointer conditions
- Incorrect flag signal type
Using this full flag logic:
full_flag <= '1' when (write_ptr + 1) mod 8 = read_ptr else '0';
What is the value of full_flag?
Solution
Step 1: Calculate (write_ptr + 1) mod depth
(7 + 1) mod 8 = 8 mod 8 = 0.Step 2: Compare with read_ptr
read_ptr = 6, so 0 != 6, condition false, full_flag = '0'.Final Answer:
'0', FIFO is not full -> Option AQuick Check:
Next write pointer != read pointer means not full [OK]
- Forgetting modulo wrap-around
- Assuming full when pointers differ
- Mixing up read and write pointers
Ready to prove it?
Pass the test and this pattern moves unknown
