He hecho un divisor de clk usando un contador de johnson de anillo con D flip flop en VHDL. El punto es que la salida de la señal hace un aumento momentáneo e inesperado durante un cambio de período. Como puede ver en el círculo rojo, hay un aumento momentáneo cerca del cambio de período que no puedo explicar: Además,apuntandoconelcursorenesasubida,modelsimnopercibe1enelcuadrodelaizquierda.Yestohacequetodoseamásextraño.
Elsiguienteeselcódigo:
libraryieee;useieee.std_logic_1164.all;useieee.std_logic_arith.all;useieee.std_logic_unsigned.all;entityeven_dividerisport(clk:instd_logic;divide_by:instd_logic_vector(4downto0);out_clk:outstd_logic);endeven_divider;architectureeven_divider_behaviourofeven_dividerissignalfiloFlottante:std_logic;componentMultiplexer_VHDLisport(due,quattro,sei,otto,dieci,dodici,quattordici,sedici:instd_logic;Sel:instd_logic_vector(4downto0);Output:outstd_logic);endcomponent;componentffdisport(clk:instd_logic;din:instd_logic;reset:instd_logic;dout:outstd_logic);endcomponent;signaldInternal:std_logic_vector(7downto0);signaldFirst:std_logic;signalreset:std_logic;signalresetN:std_logic;signalring_wire:std_logic;signalselection:std_logic_vector(4downto0);beginprocess(clk,divide_by)beginifdivide_by'eventthen--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;
El siguiente es el código D flip flop:
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;
El siguiente es el código del multiplexor:
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;
El siguiente es el código de banco de pruebas:
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;