I'm starting out trying to learn VHDL after doing a little bit of Verilog.
This is my attempt at creating a clock divider: (largely taken from Making a clock divider)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity clock_192 is
Port ( clk : in STD_LOGIC;
clr : in STD_LOGIC;
clk_out : out STD_LOGIC);
end clock_192;
architecture Behavioral of clock_192 is
signal q : std_logic_vector (23 downto 0);
begin
clk_out <= q(23);
process(clk,clr)
begin
if clr = '1' then
q <= "000000000000000000000000";
elsif clk'event and clk = '1' then
q <= std_logic_vector(unsigned(q)+1);
end if;
end process;
end Behavioral;
And here is the test bench I'm using:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY test_clock_192 IS
END test_clock_192;
ARCHITECTURE behavior OF test_clock_192 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT clock_192
PORT(
clk : IN std_logic;
clr : IN std_logic;
clk_out : OUT std_logic
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal clr : std_logic := '0';
--Outputs
signal clk_out : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
constant clk_out_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: clock_192 PORT MAP (
clk => clk,
clr => clr,
clk_out => clk_out
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
clk_out_process :process
begin
clk_out <= '0';
wait for clk_out_period/2;
clk_out <= '1';
wait for clk_out_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
clr <= '1';
wait for 97 ns;
clr <= '0';
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
The trouble is my clk_out signal keeps flipping between 0 and X with every cycle of clk. As seen here:
Does anyone have an idea of what is going on?
EDIT: To fix the problem I had to change my test bench to look like this:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY test_clock_192 IS
END test_clock_192;
ARCHITECTURE behavior OF test_clock_192 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT clock_192
PORT(
clk : IN std_logic;
clr : IN std_logic;
clk_out : OUT std_logic
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal clr : std_logic := '0';
--Outputs
signal clk_out : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
constant clk_out_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: clock_192 PORT MAP (
clk => clk,
clr => clr,
clk_out => clk_out
);
-- 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.
clr <= '1';
wait for 97 ns;
clr <= '0';
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
rising_edge(clk)
function instead ofclk'event and clk='1'
(2) use types rather than fighting them : makeq
unsigned, then the clocked line simplifies toq <= q + 1;
(3) to clearq
useq <= (others => '0');
it saves counting bits, and still works if you change the size ofq
. – user_1818839