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

  • T4V0@kbin.social
    link
    fedilink
    arrow-up
    1
    ·
    1 year ago

    @dejo

    Is the 1/60 Hz set somewhere or is it set in the code itself?

    You would set that on the testbench or on your synthesis code, but that is unnecessary, I only said that in case if you tested it on a actual FPGA. If you do that on your testbench, it would take a very long time to simulate.

    When you say that I must have an “alarming” signal on the simulation, is it actually this “alarm” signal that is presented on the simulation or?

    The alarm signal. The “alarming” is when the alarm signal is in a high logic state.

    And, do I need to have count signal in simulation?

    I wouldn’t say it’s mandatory, but it is a good addition to the simulation, keep it.

        • T4V0@kbin.social
          link
          fedilink
          arrow-up
          1
          ·
          1 year ago

          @dejo No, the alarm signal takes a longer time to start rather than the interval when it’s set.

          You seem to have some trouble picturing the Kitchen Timer itself.

          Kitchen timer

          Here, when you change the time interval it’s the same as when you turn the knob. So it doesn’t last longer when you increase the timer, it just takes longer for it to activate.

      • T4V0@kbin.social
        link
        fedilink
        arrow-up
        1
        ·
        1 year ago

        @dejo In your .do script file add this line:

        add wave -label "count" -radix unsigned /dut/Kitchen_Timer/count
        
        
        • dejo@kbin.socialOP
          link
          fedilink
          arrow-up
          1
          ·
          edit-2
          1 year ago

          @T4V0 I use Notepad to write scripts.I don’t think it works that way with the code written like this

          **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
          )
          TbClock &lt;= not TbClock after TbPeriod/2 when TbSimEnded /= ‘1’ else ‘0’; – Clock generation
          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;
          **

          • T4V0@kbin.social
            link
            fedilink
            arrow-up
            1
            ·
            1 year ago

            @dejo Whoops, I made a mistake, you don’t need to include the entity when simulating. This line bellow should be the correct one:

            add wave -label "count" -radix unsigned /dut/count
            
            

            This is my .do file (when using Modelsim or Questa, change to the directory with all the .vhd files and the .do file and execute the command do tb.do):

            tb.do

            #Creates project's library
            vlib work
            
            #Compiles project with VHDL93 standard: all files used in the testbench. They should be compiled in order of dependency.
            vcom -93 Kitchen_Timer.vhd testbench.vhd
            
            #Simulates (work is the directory, tb_Kitchen_Timer is the entity's name).
            #The argument -voptargs="+acc" is necessary to disable signal optimization in Questa.
            vsim -voptargs="+acc" -t ns work.tb_Kitchen_Timer
            
            #Show waveforms.
            view wave
            
            #Add specific signals.
            # -radix: binary, hex, dec, unsigned.
            # -label: wave's name.
            add wave -label "clk" -radix binary /clk
            add wave -label "reset" -radix binary /reset
            add wave -label "start" -radix binary /start
            add wave -label "stop" -radix binary /stop
            add wave -label "adjust_interval_up" -radix binary /adjust_interval_up
            add wave -label "adjust_interval_down" -radix binary /adjust_interval_down
            add wave -label "alarm" -radix binary /alarm
            add wave -label "count" -radix unsigned /dut/count
            add wave -label "TbClock" -radix binary /TbClock
            add wave -label "TbSimEnded" -radix binary /TbSimEnded
            
            #Simulate for 1500 ns.
            run 1500ns
            
            # Zoom to fit entire window.
            wave zoomfull
            write wave wave.ps
            
            

            I’ve also included the simulation result.