I have made a clk divider using a ring johnson counter with D flip flop in VHDL. The point is that the signal output makes a momentary and unexpected rise during a change of period. As you can see in the red circle, there is a momentary rise close to the change of period that I can't explain: Moreover, pointing the cursor on that rise, modelsim doesn't perceive 1 in the box on the left. And this makes all more weird.
The following is the code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity even_divider is
port(
clk : in std_logic;
divide_by : in std_logic_vector(4 downto 0);
out_clk : out std_logic
);
end even_divider;
architecture even_divider_behaviour of even_divider is
signal filoFlottante : std_logic;
component Multiplexer_VHDL is
port
(
due, quattro, sei, otto, dieci, dodici, quattordici, sedici : in std_logic;
Sel : in std_logic_vector(4 downto 0);
Output : out std_logic
);
end component;
component ffd is
port(
clk : in std_logic;
din : in std_logic;
reset : in std_logic;
dout : out std_logic
);
end component;
signal dInternal : std_logic_vector(7 downto 0);
signal dFirst : std_logic;
signal reset : std_logic;
signal resetN : std_logic;
signal ring_wire : std_logic;
signal selection : std_logic_vector(4 downto 0);
begin
process(clk, divide_by)
begin
if divide_by'event then
--selection <= "11111";
reset <= '1';
ring_wire <= dFirst;
selection <= divide_by;
else
selection <= divide_by;
ring_wire <= dFirst;
reset <= '0';
end if;
end process;
f0 : ffd port map(clk, ring_wire, reset, dInternal(0));
f1 : ffd port map(clk, dInternal(0), reset, dInternal(1));
f2 : ffd port map(clk, dInternal(1), reset, dInternal(2));
f3 : ffd port map(clk, dInternal(2), reset, dInternal(3));
f4 : ffd port map(clk, dInternal(3), reset, dInternal(4));
f5 : ffd port map(clk, dInternal(4), reset, dInternal(5));
f6 : ffd port map(clk, dInternal(5), reset, dInternal(6));
f7 : ffd port map(clk, dInternal(6), reset, dInternal(7));
multiplexer : Multiplexer_VHDL port map(dInternal(0), dInternal(1), dInternal(2), dInternal(3), dInternal(4), dInternal(5), dInternal(6), dInternal(7), selection, dFirst);
out_clk <= not dFirst;
end even_divider_behaviour;
The following is the D flip flop code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ffd is
port(
clk : in std_logic;
din : in std_logic;
reset : in std_logic;
dout : out std_logic
);
end ffd;
architecture ffd_behaviour of ffd is
begin
process(clk, reset)
variable qvar : std_logic := '0';
begin
if rising_edge(reset) then
qvar := '0';
elsif rising_edge(clk) then
qvar := din;
end if;
dout <= qvar;
end process;
end ffd_behaviour;
The following is the Multiplexer code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Multiplexer_VHDL is
port
(
due, quattro, sei, otto, dieci, dodici, quattordici, sedici : in std_logic;
Sel : in std_logic_vector(4 downto 0);
Output : out std_logic
);
end entity Multiplexer_VHDL;
architecture Behavioral of Multiplexer_VHDL is
begin
process (due, quattro, sei, otto, dieci, dodici, quattordici, sedici, Sel) is
begin
case Sel is
when "00010" => Output <= not due;
when "00100" => Output <= not quattro;
when "00110" => Output <= not sei;
when "01000" => Output <= not otto;
when "01010" => Output <= not dieci;
when "01100" => Output <= not dodici;
when "01110" => Output <= not quattordici;
when "10000" => Output <= not sedici;
when others => Output <= '0';
end case;
end process;
end architecture Behavioral;
The following is the testbench code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity even_dividerTB is
end even_dividerTB;
architecture even_dividerTB_behaviour of even_dividerTB is
component even_divider is
port(
clk : in std_logic;
divide_by : in std_logic_vector(4 downto 0);
out_clk : out std_logic
);
end component;
signal clk : std_logic;
signal divide_by : std_logic_vector(4 downto 0);
signal out_clk : std_logic;
--signal dExternal_out : std_logic_vector(7 downto 0);
begin
process
begin
clk <= '0'; wait for 10 ns;
clk <= '1'; wait for 10 ns;
end process;
process
begin
divide_by <= "01000"; wait for 300 ns;
divide_by <= "00010"; wait for 300 ns;
end process;
ed : even_divider port map(clk, divide_by, out_clk);
end even_dividerTB_behaviour;