Skip Navigation

Hi, I'm not quite sure if this vhdl code and testbench is correct for the given task. Can you take a look?

Hi, I'm not quite sure if this vhdl code and testbench is correct for the given task. Can you take a look?

Design a one-hour kitchen timer. The device should have buttons/switches to start and stop the timer, as well as to set the desired time interval for the alarm. Realize the task using the software package Quartus or in GHDL, confirm the correctness of the project task by simulation.

This is VHDL code:

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Kitchen_Timer is
  port (
    clk   : in std_logic;    -- Clock input
    reset : in std_logic;    -- Reset input
    start : in std_logic;    -- Start button input
    stop  : in std_logic;    -- Stop button input
    alarm : out std_logic    -- Alarm output
  );
end entity Kitchen_Timer;

-- Declare the architecture for the kitchen timer
architecture Behavioral of Kitchen_Timer is
  signal count     : integer range 0 to 3600 := 0;   -- Counter for timer
  signal alarming  : std_logic := '0';               -- Signal to indicate alarming interval
  signal alarm_en  : std_logic := '0';               -- Signal to enable alarming interval
  signal alarm_cnt : integer range 0 to 600 := 0;    -- Counter for alarming interval
begin
  -- Process to control the kitchen timer and alarming interval
  process (clk, reset)
  begin
    if (reset = '1') then
      count     <= 0;
      alarming  <= '0';
      alarm_en  <= '0';
      alarm_cnt <= 0;
    elsif (rising_edge(clk)) then
      if (stop = '1') then
        count     <= 0;
        alarming  <= '0';
        alarm_en  <= '0';
        alarm_cnt <= 0;
      elsif (start = '1' and count < 3600) then
        count <= count + 1;
        if (count = 3600) then
          count     <= 0;
          alarming  <= '0';
          alarm_en  <= '0';
          alarm_cnt <= 0;
        elsif (count > 0) then
          alarm_en <= '1';
        end if;
      end if;

      if (alarm_en = '1') then
        if (alarm_cnt < 600) then
          alarm_cnt <= alarm_cnt + 1;
        else
          alarm_cnt <= 0;
          alarming  <= '1';
        end if;
      end if;
    end if;
  end process;

  -- Assign the alarm output
  alarm <= alarming;
end architecture Behavioral; ```

This is Testbench:

```library ieee;
use ieee.std_logic_1164.all;

entity tb_Kitchen_Timer is
end tb_Kitchen_Timer;

architecture tb of tb_Kitchen_Timer is

    component Kitchen_Timer
        port (clk   : in std_logic;
              reset : in std_logic;
              start : in std_logic;
              stop  : in std_logic;
              alarm : out std_logic);
    end component;

    signal clk   : std_logic;
    signal reset : std_logic;
    signal start : std_logic;
    signal stop  : std_logic;
    signal alarm : std_logic;

    constant TbPeriod : time := 1000 ns; -- EDIT Put right period here
    signal TbClock : std_logic := '0';
    signal TbSimEnded : std_logic := '0';

begin

    dut : Kitchen_Timer
    port map (clk   => clk,
              reset => reset,
              start => start,
              stop  => stop,
              alarm => alarm);

    -- Clock generation
    TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';

    -- EDIT: Check that clk is really your main clock signal
    clk <= TbClock;

    stimuli : process
    begin
        -- EDIT Adapt initialization as needed
        start <= '0';
        stop <= '0';

        -- Reset generation
        -- EDIT: Check that reset is really your reset signal
        reset <= '1';
        wait for 100 ns;
        reset <= '0';
        wait for 100 ns;

        -- EDIT Add stimuli here
        wait for 100 * TbPeriod;

        -- Stop the clock and hence terminate the simulation
        TbSimEnded <= '1';
        wait;
    end process;

end tb;

-- Configuration block below is required by some simulators. Usually no need to edit.

configuration cfg_tb_Kitchen_Timer of tb_Kitchen_Timer is
    for tb
    end for;
end cfg_tb_Kitchen_Timer;```

 #science

23

You're viewing part of a thread.

Show Context
23 comments
  • @T4V0 I
    In the meantime, I worked on improving the code.

    VHDL code:
    llibrary ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity Kitchen_Timer is
    port (
    clk : in std_logic; -- Clock input
    reset : in std_logic; -- Reset input
    start : in std_logic; -- Start button input
    stop : in std_logic; -- Stop button input
    adjust_interval_up : in std_logic; -- Button for increasing alarm interval
    adjust_interval_down : in std_logic; -- Button for decreasing alarm interval
    alarm : out std_logic -- Alarm output
    );
    end entity Kitchen_Timer;
    architecture Behavioral of Kitchen_Timer is
    signal count : integer range 0 to 3600000 := 0; -- Adjust range for 1 hour
    signal alarming : std_logic := '0';
    signal alarm_interval : integer range 600 to 3600000 := 600; -- Adjust range for 1 hour
    begin
    process (clk, reset)
    begin
    if reset = '1' then
    count &lt;= 0;
    alarm_interval &lt;= 600;
    elsif rising_edge(clk) then
    if start = '1' then
    count &lt;= count + 1;
    end if;
    if stop = '1' or count = alarm_interval then
    count &lt;= 0;
    end if;
    if adjust_interval_up = '1' then
    if alarm_interval &lt; 3600000 then
    alarm_interval &lt;= alarm_interval + 600; -- Adjust increment for 1 minute
    end if;
    count &lt;= 0; -- Reset count when adjusting interval
    elsif adjust_interval_down = '1' then
    if alarm_interval > 600 then
    alarm_interval &lt;= alarm_interval - 600; -- Adjust decrement for 1 minute
    end if;
    count &lt;= 0; -- Reset count when adjusting interval
    end if;
    end if;
    end process;
    alarming &lt;= '1' when count >= alarm_interval else '0';
    alarm &lt;= alarming;
    end architecture Behavioral;

    Testbench:

    library ieee;
    use ieee.std_logic_1164.all;

    entity tb_Kitchen_Timer is
    end tb_Kitchen_Timer;
    architecture tb of tb_Kitchen_Timer is
    component Kitchen_Timer
    port (
    clk : in std_logic;
    reset : in std_logic;
    start : in std_logic;
    stop : in std_logic;
    adjust_interval_up : in std_logic;
    adjust_interval_down : in std_logic;
    alarm : out std_logic
    );
    end component;
    signal clk : std_logic := '0';
    signal reset : std_logic := '0';
    signal start : std_logic := '0';
    signal stop : std_logic := '0';
    signal adjust_interval_up : std_logic := '0';
    signal adjust_interval_down : std_logic := '0';
    signal alarm : std_logic;
    constant TbPeriod : time := 20 ns;
    signal TbClock : std_logic := '0';
    signal TbSimEnded : std_logic := '0';
    begin
    dut : Kitchen_Timer
    port map (
    clk => clk,
    reset => reset,
    start => start,
    stop => stop,
    adjust_interval_up => adjust_interval_up,
    adjust_interval_down => adjust_interval_down,
    alarm => alarm
    );
    -- Clock generation
    TbClock &lt;= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
    clk &lt;= TbClock;
    stimuli : process
    variable num_ticks : natural;
    begin
    -- Reset generation
    reset &lt;= '1';
    wait for 200 us;
    reset &lt;= '0';
    wait for 200 us;
    -- Start the timer
    start &lt;= '1';
    wait for 500 us;
    -- Adjust interval up and down
    adjust_interval_up &lt;= '1';
    wait for 100 us;
    adjust_interval_up &lt;= '0';
    wait for 100 us;
    adjust_interval_down &lt;= '1';
    wait for 100 us;
    adjust_interval_down &lt;= '0';
    wait for 100 us;
    -- Wait for the timer to reach the alarm interval (3600000 clocks)
    wait for 72 ms; -- Simulate for the required time
    -- Stop the timer
    start &lt;= '0';
    wait for 300 us;
    -- Stop the clock and terminate the simulation
    TbSimEnded &lt;= '1';
    wait;
    end process;
    end tb;

    And this is simulation:

    • @dejo I have made a few changes to your code:

      Kitchen_Timer.vhd

      library ieee;
      use ieee.std_logic_1164.all;
      use ieee.numeric_std.all;
      
      entity Kitchen_Timer is
          port
          (
              clk                  : in std_logic; -- Clock input
              reset                : in std_logic; -- Reset input
              start                : in std_logic; -- Start button input
              stop                 : in std_logic; -- Stop button input
              adjust_interval_up   : in std_logic; -- Button for increasing alarm interval
              adjust_interval_down : in std_logic; -- Button for decreasing alarm interval
              alarm                : out std_logic -- Alarm output
          );
      end entity Kitchen_Timer;
      architecture Behavioral of Kitchen_Timer is
          signal count          : integer range 0 to 60 := 0; -- Adjust range for 1 hour
          signal alarming       : std_logic             := '0';
          signal alarm_interval : integer range 1 to 60 := 1; -- Adjust range for 1 hour
      begin
          process (clk, reset)
          begin
              if reset = '1' then
                  count          &lt;= 0;
                  alarm_interval &lt;= 1;
              elsif rising_edge(clk) then
                  if start = '1' then
                      count &lt;= count + 1;
                  end if;
                  if stop = '1' then
                      count    &lt;= 0;
                      alarming &lt;= '0';
                  end if;
                  if count = alarm_interval then
                      alarming &lt;= '1';
                  end if;
                  if adjust_interval_up = '1' then
                      if alarm_interval &lt; 60 then
                          alarm_interval &lt;= alarm_interval + 1; -- Adjust increment for 1 minute
                      end if;
                      count &lt;= 0; -- Reset count when adjusting interval
                  elsif adjust_interval_down = '1' then
                      if alarm_interval > 60 then
                          alarm_interval &lt;= alarm_interval - 1; -- Adjust decrement for 1 minute
                      end if;
                      count &lt;= 0; -- Reset count when adjusting interval
                  end if;
              end if;
          end process;
          alarm &lt;= alarming;
      end architecture Behavioral;
      
      

      tb_Kitchen_Timer.vhd

      library ieee;
      use ieee.std_logic_1164.all;
      use ieee.numeric_std.all;
      
      entity tb_Kitchen_Timer is
      end tb_Kitchen_Timer;
      
      architecture tb of tb_Kitchen_Timer is
          signal clk                  : std_logic := '0';
          signal reset                : std_logic := '0';
          signal start                : std_logic := '0';
          signal stop                 : std_logic := '0';
          signal adjust_interval_up   : std_logic := '0';
          signal adjust_interval_down : std_logic := '0';
          signal alarm                : std_logic;
          constant TbPeriod           : time      := 10 ns;
          signal TbClock              : std_logic := '0';
          signal TbSimEnded           : std_logic := '0';
      begin
          dut : entity work.Kitchen_Timer
          port map
          (
              clk                  => clk,
              reset                => reset,
              start                => start,
              stop                 => stop,
              adjust_interval_up   => adjust_interval_up,
              adjust_interval_down => adjust_interval_down,
              alarm                => alarm
          );
      
          -- Clock generation
          TbClock &lt;= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
      
          -- EDIT: Check that clk is really your main clock signal
          clk &lt;= TbClock;
      
          stimuli : process
              variable num_ticks : natural;
          begin
              -- Reset generation
              reset &lt;= '1';
              wait for 20 ns;
              reset &lt;= '0';
              wait for 20 ns;
              -- Start the timer
              start &lt;= '1';
              wait for 20 ns;
              start &lt;= '0';
              stop  &lt;= '1';
              -- Adjust interval up and down
              adjust_interval_up &lt;= '1';
              wait for 10 ns;
              start              &lt;= '1';
              stop               &lt;= '0';
              adjust_interval_up &lt;= '0';
              wait for 30 ns;
              start                &lt;= '0';
              stop                 &lt;= '1';
              adjust_interval_down &lt;= '1';
              wait for 10 ns;
              start                &lt;= '1';
              stop                 &lt;= '0';
              adjust_interval_down &lt;= '0';
              wait for 20 ns;
              start              &lt;= '0';
              stop               &lt;= '1';
              adjust_interval_up &lt;= '1';
              wait for 600 ns;
              start              &lt;= '1';
              stop               &lt;= '0';
              adjust_interval_up &lt;= '0';
              -- Wait for the timer to reach the alarm interval (60 clocks)
              wait for 600 ns; -- Simulate for the required time
              -- Stop the timer
              start &lt;= '0';
              stop  &lt;= '1';
              wait for 100 ns;
              -- Stop the clock and terminate the simulation
              TbSimEnded &lt;= '1';
              wait;
          end process;
      end tb;
      
      

      This should be easier to simulate, I've included a simulation done with Questa.

      • @T4V0 I just now see your messages, thank you..
        In the meantime, I made something like this...
        What do you think about the specifications that the project requires, should I stick to your code or should I add something from my own code?
        Does your simulation correspond to a time of 1 hour and should there be alarming on the simulation?

        Vhdl code:

        library ieee;
        use ieee.std_logic_1164.all;
        use ieee.numeric_std.all;
        entity Kitchen_Timer is
        port (
        clk : in std_logic; -- Clock input
        reset : in std_logic; -- Reset input
        start : in std_logic; -- Start button input
        stop : in std_logic; -- Stop button input
        adjust_interval_up : in std_logic; -- Button for increasing alarm interval
        adjust_interval_down : in std_logic; -- Button for decreasing alarm interval
        alarm : out std_logic -- Alarm output
        );
        end entity Kitchen_Timer;
        architecture Behavioral of Kitchen_Timer is
        signal count : integer range 0 to 3600000 := 0; -- Adjust range for 1 hour
        signal alarming : std_logic := '0';
        signal alarm_interval : integer range 600 to 3600000 := 600; -- Adjust range for 1 hour
        begin
        process (clk, reset)
        begin
        if reset = '1' then
        count &lt;= 0;
        alarm_interval &lt;= 600;
        elsif rising_edge(clk) then
        if start = '1' then
        count &lt;= count + 1;
        end if;
        if stop = '1' or count = alarm_interval then
        count &lt;= 0;
        end if;
        if adjust_interval_up = '1' then
        if alarm_interval &lt; 3600000 then
        alarm_interval &lt;= alarm_interval + 600; -- Adjust increment for 1 minute
        end if;
        count &lt;= 0; -- Reset count when adjusting interval
        elsif adjust_interval_down = '1' then
        if alarm_interval > 600 then
        alarm_interval &lt;= alarm_interval - 600; -- Adjust decrement for 1 minute
        end if;
        count &lt;= 0; -- Reset count when adjusting interval
        end if;
        end if;
        end process;
        alarming &lt;= '1' when count >= alarm_interval else '0';
        alarm &lt;= alarming;
        end architecture Behavioral;

        Testbench:

        library ieee;
        use ieee.std_logic_1164.all;
        entity tb_Kitchen_Timer is
        end tb_Kitchen_Timer;
        architecture tb of tb_Kitchen_Timer is
        component Kitchen_Timer
        port (
        clk : in std_logic;
        reset : in std_logic;
        start : in std_logic;
        stop : in std_logic;
        adjust_interval_up : in std_logic;
        adjust_interval_down : in std_logic;
        alarm : out std_logic
        );
        end component;
        signal clk : std_logic := '0';
        signal reset : std_logic := '0';
        signal start : std_logic := '0';
        signal stop : std_logic := '0';
        signal adjust_interval_up : std_logic := '0';
        signal adjust_interval_down : std_logic := '0';
        signal alarm : std_logic;
        constant TbPeriod : time := 20 ns;
        signal TbClock : std_logic := '0';
        signal TbSimEnded : std_logic := '0';
        begin
        dut : Kitchen_Timer
        port map (
        clk => clk,
        reset => reset,
        start => start,
        stop => stop,
        adjust_interval_up => adjust_interval_up,
        adjust_interval_down => adjust_interval_down,
        alarm => alarm
        );
        -- Clock generation
        TbClock &lt;= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
        clk &lt;= TbClock;
        stimuli : process
        variable num_ticks : natural;
        begin
        -- Reset generation
        reset &lt;= '1';
        wait for 200 us;
        reset &lt;= '0';
        wait for 200 us;
        -- Start the timer
        start &lt;= '1';
        wait for 500 us;
        -- Adjust interval up and down
        adjust_interval_up &lt;= '1';
        wait for 100 us;
        adjust_interval_up &lt;= '0';
        wait for 100 us;
        adjust_interval_down &lt;= '1';
        wait for 100 us;
        adjust_interval_down &lt;= '0';
        wait for 100 us;
        -- Wait for the timer to reach the alarm interval (3600000 clocks)
        wait for 72 ms; -- Simulate for the required time
        -- Stop the timer
        start &lt;= '0';
        wait for 300 us;
        -- Stop the clock and terminate the simulation
        TbSimEnded &lt;= '1';
        wait;
        end process;
        end tb;

You've viewed 23 comments.