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
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?
I would stick to my code, your alarm isn't going to work properly due to its comparisons as I mentioned in my previous comments. But if you want to improve the code I modified, you can change the adjust_interval_up and adjust_interval_down buttons to be synchronized to their own states rather than the clock (make their own process with their signals added to the signal sensitivity list and add an extra asynchronous condition to zero the counter on the original process). If you don't make a change like this your alarm is going to take up to an hour to adjust its timer range.
Does your simulation correspond to a time of 1 hour and should there be alarming on the simulation?
Yes, if you have a 1/60 Hertz clock signal. And you must have alarming on the simulation as it is crucial to show that it works.
@T4V0
Is the 1/60 Hz set somewhere or is it set in the code itself?
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?
And, do I need to have count signal in simulation?
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.
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
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.