Bird
Raised Fist0
VHDLprogramming~5 mins

Up-down counter with control in VHDL

Choose your learning style10 modes available
Introduction

An up-down counter counts numbers up or down based on a control signal. It helps track quantities that can increase or decrease.

Counting items that can be added or removed, like people entering or leaving a room.
Tracking score in a game where points can go up or down.
Measuring steps forward or backward in a process.
Controlling position in a menu that moves up or down.
Keeping track of stock levels that can increase or decrease.
Syntax
VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity up_down_counter is
  port(
    clk     : in std_logic;
    reset   : in std_logic;
    up_down : in std_logic; -- '1' for up, '0' for down
    count   : out unsigned(3 downto 0)
  );
end up_down_counter;

architecture Behavioral of up_down_counter is
  signal counter : unsigned(3 downto 0) := (others => '0');
begin
  process(clk, reset)
  begin
    if reset = '1' then
      counter <= (others => '0');
    elsif rising_edge(clk) then
      if up_down = '1' then
        counter <= counter + 1;
      else
        counter <= counter - 1;
      end if;
    end if;
  end process;
  count <= counter;
end Behavioral;

The up_down input controls counting direction: '1' means count up, '0' means count down.

Reset sets the counter back to zero immediately.

Examples
Set control to '1' to count upwards.
VHDL
up_down <= '1'; -- counter will increase by 1 on each clock
Set control to '0' to count downwards.
VHDL
up_down <= '0'; -- counter will decrease by 1 on each clock
Use reset to clear the counter to zero.
VHDL
reset <= '1'; -- counter resets to zero immediately
Sample Program

This program defines an up-down counter and a testbench that first resets the counter, then counts up 5 times, then counts down 3 times. The count value is reported on each clock.

VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity up_down_counter is
  port(
    clk     : in std_logic;
    reset   : in std_logic;
    up_down : in std_logic;
    count   : out unsigned(3 downto 0)
  );
end up_down_counter;

architecture Behavioral of up_down_counter is
  signal counter : unsigned(3 downto 0) := (others => '0');
begin
  process(clk, reset)
  begin
    if reset = '1' then
      counter <= (others => '0');
    elsif rising_edge(clk) then
      if up_down = '1' then
        counter <= counter + 1;
      else
        counter <= counter - 1;
      end if;
    end if;
  end process;
  count <= counter;
end Behavioral;

-- Testbench to simulate counting up then down
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_up_down_counter is
end tb_up_down_counter;

architecture test of tb_up_down_counter is
  signal clk     : std_logic := '0';
  signal reset   : std_logic := '1';
  signal up_down : std_logic := '1';
  signal count   : unsigned(3 downto 0);

  constant clk_period : time := 10 ns;
begin
  uut: entity work.up_down_counter
    port map(clk => clk, reset => reset, up_down => up_down, count => count);

  clk_process : process
  begin
    while true loop
      clk <= '0';
      wait for clk_period / 2;
      clk <= '1';
      wait for clk_period / 2;
    end loop;
  end process;

  stim_proc: process
  begin
    wait for 20 ns;
    reset <= '0'; -- release reset

    -- count up for 5 clock cycles
    up_down <= '1';
    wait for clk_period * 5;

    -- count down for 3 clock cycles
    up_down <= '0';
    wait for clk_period * 3;

    wait;
  end process;

  -- Monitor output
  monitor_proc: process(clk)
  begin
    if rising_edge(clk) then
      report "Count = " & integer'image(to_integer(count));
    end if;
  end process;
end test;
OutputSuccess
Important Notes

Make sure the counter does not underflow below zero or overflow beyond its max value.

Use unsigned type for natural counting numbers.

Reset is asynchronous here, so it works immediately when set.

Summary

An up-down counter changes its count based on a control signal.

Use 'up_down' input to decide counting direction.

Reset clears the count to zero quickly.

Practice

(1/5)
1. What does an up-down counter do in VHDL when the control signal is set to '1'?
easy
A. It counts down by decreasing the value on each clock pulse.
B. It resets the counter to zero immediately.
C. It holds the current count value without change.
D. It counts up by increasing the value on each clock pulse.

Solution

  1. Step 1: Understand the control signal meaning

    In an up-down counter, the control signal '1' usually means count up.
  2. Step 2: Identify the counting behavior

    When control is '1', the counter increments its value on each clock pulse.
  3. Final Answer:

    It counts up by increasing the value on each clock pulse. -> Option D
  4. Quick Check:

    Control '1' means count up [OK]
Hint: Control '1' means count up, '0' means count down [OK]
Common Mistakes:
  • Confusing control '1' with reset signal
  • Thinking control '1' holds the value
  • Mixing up count up and count down signals
2. Which of the following is the correct VHDL syntax to declare a 4-bit up-down counter signal named count?
easy
A. signal count : bit_vector(4 downto 1);
B. signal count : std_logic_vector(3 downto 0);
C. signal count : integer range 0 to 15;
D. signal count : std_logic_vector(0 to 3);

Solution

  1. Step 1: Identify correct type and range for 4-bit vector

    std_logic_vector(3 downto 0) is the standard way to declare a 4-bit vector from bit 3 down to 0.
  2. Step 2: Check other options for errors

    signal count : integer range 0 to 15; uses integer, not vector; signal count : bit_vector(4 downto 1); uses bit_vector with wrong range; signal count : std_logic_vector(0 to 3); uses ascending range which is less common and may cause confusion.
  3. Final Answer:

    signal count : std_logic_vector(3 downto 0); -> Option B
  4. Quick Check:

    4-bit vector uses std_logic_vector(3 downto 0) [OK]
Hint: Use std_logic_vector(3 downto 0) for 4-bit signals [OK]
Common Mistakes:
  • Using integer instead of vector for bit signals
  • Incorrect range direction (0 to 3 instead of 3 downto 0)
  • Using bit_vector instead of std_logic_vector
3. Given the following VHDL process for a 3-bit up-down counter with control signal up_down and synchronous reset rst, what is the value of count after 3 clock cycles if rst = '0' and up_down = '0' initially?
process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      count <= "000";
    else
      if up_down = '1' then
        count <= count + 1;
      else
        count <= count - 1;
      end if;
    end if;
  end if;
end process;
medium
A. "111"
B. "011"
C. "101"
D. "001"

Solution

  1. Step 1: Understand initial conditions and counting direction

    Reset is '0', so no reset occurs. up_down = '0' means count down. Initial count is unknown but assumed 0 at start.
  2. Step 2: Calculate count after each clock cycle

    Cycle 1: count = 0 - 1 = 7 (since 3-bit unsigned wraps around)
    Cycle 2: count = 7 - 1 = 6
    Cycle 3: count = 6 - 1 = 5 (binary "101")
  3. Final Answer:

    "101" -> Option C
  4. Quick Check:

    Counting down 3 times from 0 wraps to 5 [OK]
Hint: Count down wraps around 0 to max value in unsigned [OK]
Common Mistakes:
  • Assuming count starts at zero without reset
  • Ignoring wrap-around behavior in unsigned counters
  • Mixing up count up and count down logic
4. Identify the error in this VHDL snippet for an up-down counter process:
process(clk)
begin
  if clk'event and clk = '1' then
    if rst = '1' then
      count <= (others => '0');
    elsif up_down = '1' then
      count <= count + 1;
    else
      count <= count - 1;
    end if;
  end if;
end process;
medium
A. Using clk'event and clk = '1' instead of rising_edge(clk)
B. Missing asynchronous reset handling
C. Incorrect use of (others => '0') for resetting count
D. No error; code is correct

Solution

  1. Step 1: Check clock edge detection method

    Using clk'event and clk = '1' is legal but less safe and less recommended than rising_edge(clk) in modern VHDL.
  2. Step 2: Identify best practice for clock edge

    rising_edge(clk) is preferred for clarity and synthesis compatibility.
  3. Final Answer:

    Using clk'event and clk = '1' instead of rising_edge(clk) -> Option A
  4. Quick Check:

    Use rising_edge(clk) for clock detection [OK]
Hint: Use rising_edge(clk) for reliable clock detection [OK]
Common Mistakes:
  • Using clk'event instead of rising_edge(clk)
  • Confusing synchronous and asynchronous reset
  • Incorrect reset assignment syntax
5. You want to design a 4-bit up-down counter in VHDL with a control signal dir where dir = '1' counts up and dir = '0' counts down. The counter should reset to "1000" on reset. Which code snippet correctly implements this behavior inside a synchronous process?
process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      count <= "1000";
    else
      if dir = '1' then
        count <= count + 1;
      else
        count <= count - 1;
      end if;
    end if;
  end if;
end process;
hard
A. Correct implementation for the described behavior.
B. Reset value should be "0000" instead of "1000".
C. Counting direction logic is reversed; dir='1' should count down.
D. Process should use asynchronous reset instead of synchronous.

Solution

  1. Step 1: Check reset behavior

    Reset sets count to "1000" as required, synchronously on rising clock edge.
  2. Step 2: Verify counting direction logic

    dir='1' triggers count increment, dir='0' triggers decrement, matching the requirement.
  3. Step 3: Confirm synchronous reset usage

    Reset is synchronous, which is acceptable and matches the problem statement.
  4. Final Answer:

    Correct implementation for the described behavior. -> Option A
  5. Quick Check:

    Synchronous reset and correct dir logic [OK]
Hint: Match reset value and dir logic exactly as specified [OK]
Common Mistakes:
  • Using wrong reset value
  • Reversing count up/down logic
  • Confusing synchronous and asynchronous reset
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard