I am new to VHDL and trying to generate 1 second counter. For simplicity, I am using the clock frequency of 10 Hz. For this purpose I am using a clk as an input and LED as an output. My VHDL code is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
entity tick_counter is
generic(FrequencyHz : integer := 10);
Port ( clk : in STD_LOGIC;
led : out STD_LOGIC);
end tick_counter;
architecture Behavioral of tick_counter is
signal tick :integer;
signal counter :integer;
begin
process(clk, tick, counter)
begin
if rising_edge(clk) then
if tick = FrequencyHz - 1 then
tick <= 0;
counter <= counter + 1;
else
tick <= tick + 1;
end if;
end if;
end process;
led <= '1' when counter = 3 else '0';
end Behavioral;
I tried to write the code in such a way so that, when three seconds pass, the LED turns ON. My test bench code is given below:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY tick_counter_tb IS
END tick_counter_tb;
ARCHITECTURE behavior OF tick_counter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
-- We're slowing down the clock to speed up simulation time
constant FrequencyHz : integer := 10; -- 10 Hz
constant clk_period : time := 1000 ms / FrequencyHz;
COMPONENT tick_counter
PORT( clk : IN std_logic;
led : OUT std_logic);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
--Outputs
signal led : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut : entity work.tick_counter
generic map(FrequencyHz => FrequencyHz)
PORT MAP (clk => clk,
led => led);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait until rising_edge(clk);
-- insert stimulus here
wait;
end process;
END;
But in the simulation result, I am just seeing a blank diagram as shown below (link given):
I don't understand where I am making a mistake. Any help would be highly appreciated.
The default initial value of an integer is INTEGER'LOW (a very negative number).
That means counter won't become 3 for a very long time (as the busybee
indicated).
You can constrain and/or provide an initial value for tick
. counter
appears to be meant as a modulo counter range 0 to 3. It's modulus could be passed identically to tick
which uses FrequencyHZ
. Also note that any integer counter needs explicit roll over, it's an error if the result of an addition doesn't fall with the range INTEGER'LOW to INTEGER'HIGH or the constrained range.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- USE ieee.std_logic_unsigned.ALL;
-- use ieee.numeric_std.all;
entity tick_counter is
generic(FrequencyHz : integer := 10);
Port ( clk : in STD_LOGIC;
led : out STD_LOGIC);
end tick_counter;
architecture Behavioral of tick_counter is
-- Initial value of integers is INTEGER'LOW (a large negative number)
signal tick: integer range 0 to FrequencyHz - 1 := 0;
signal counter: integer := 0; -- ADDED default initial value
begin
process(clk, tick, counter)
begin
if rising_edge(clk) then
if tick = FrequencyHz - 1 then
tick <= 0;
if counter = 3 then -- ADDED MODULUS 4 test for counter
counter <= 0;
else
counter <= counter + 1;
end if;
else
tick <= tick + 1;
end if;
end if;
end process;
led <= '1' when counter = 3 else '0';
end Behavioral;
With the changes the simulation will cause led
to be a '1' for one second every four seconds.