2
\$\begingroup\$

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: enter image description here 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;
\$\endgroup\$
5
  • \$\begingroup\$ If you mean the output changes when the divide_by register is changed, then that is not at all surprising. It typically takes extra logic to implement some scheme of "introducing" the new divisor to the running counter. You can, for example, look at using a synchronizing register to hold the new value and only apply it after the conclusion of a previous period. Or maybe you don't care about glitches in the output and can apply it immediately. \$\endgroup\$ Commented Jul 18, 2015 at 15:51
  • \$\begingroup\$ "You can, for example, look at using a synchronizing register to hold the new value and only apply it after the conclusion of a previous period." You are right, but doing so, you are losing a clock cycle, right? \$\endgroup\$
    – StackUser
    Commented Jul 18, 2015 at 15:54
  • \$\begingroup\$ I wouldn't say you are losing one, but you are delaying the application of the change until after the next output. Ultimately, you can't build something like this until you write an unambiguous rule about what should happen when the divisor changes. Or else you have some sort of system that can tolerate grunge when its configuration changes. \$\endgroup\$ Commented Jul 18, 2015 at 15:58
  • \$\begingroup\$ what's the meaning of grunge? \$\endgroup\$
    – StackUser
    Commented Jul 18, 2015 at 17:23
  • \$\begingroup\$ Have you read my edit? "Moreover, pointing the cursor on that rise, modelsim doesn't perceive 1 in the box on the left. And this makes all more weird." \$\endgroup\$
    – StackUser
    Commented Jul 18, 2015 at 17:29

1 Answer 1

3
\$\begingroup\$

The simulator is showing you that you have a potential glitch.

For each of its internal time steps, the simulator evaluates one signal change event at a time, and repeats the evaluations until all signals reach a stable value.

When you change the selection input on your multiplexer, the simulator evaluates the 5 bits separately, and in the course of doing this, it discovered that the output changes state more than once. It indicates this by showing a "zero width" pulse on the output display. Since this transient output didn't persist after all of the evaluations were done for that time step, it does not represent an actual signal change.

In a real physical implementation, with variable gate delays and variable skews among the multiple signals of a bus, you may or may not see an actual glitch. The simulator is showing you that there's at least the possibility of a glitch in your design.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.