¿Es normal que un divisor de reloj hecho con el contador de johnson del anillo haya salido No definido si clk comienza alto?

0

EstoycreandoundivisordefrecuenciaylaformamássencillaesusarelcontadordeJohnstonconDflipflop.Elpuntoesquesihagoqueelclkcomiencealto,elcontadortieneunasalidaindefinida,mientrasquesihagoqueelclkcomiencebajo,tododeberíaestarbien.

Códigodelanillodelcontadordejohnson("divide_by no está en uso en este momento"):

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity double_period is
    port(
        clk : in std_logic;
        --i 3 bit seguenti rappresentano 8 stati (stato 0 : divisione frequenza per     2, stato 1: divione per 4, stato 3 : divione per 6, etc...)
        divide_by : in std_logic_vector(2 downto 0);
        out_clk : out std_logic
    );
end double_period;

architecture double_period_behaviour of double_period is
signal filoFlottante : std_logic;
component ffd is
    port(
        clk : in std_logic;
        din : in std_logic;
        dout : out std_logic
    );
end component;
signal dInternal : std_logic_vector(8 downto 0);
signal dFirst : std_logic;
begin
dFirst <= not(dInternal(2));
f0 : ffd port map(clk, dFirst, dInternal(0));
f1 : ffd port map(clk, dInternal(0), dInternal(1));
f2 : ffd port map(clk, dInternal(1), dInternal(2));
--f3 : ffd port map(clk, dInternal(2), dInternal(3));
--f4 : ffd port map(clk, dInternal(3), dInternal(4));
--f5 : ffd port map(clk, dInternal(4), dInternal(5));
--f6 : ffd port map(clk, dInternal(5), dInternal(6));
--f7 : ffd port map(clk, dInternal(6), dInternal(7));
--f8 : ffd port map(clk, dInternal(7), dInternal(8));
out_clk <= dInternal(0);
end double_period_behaviour;

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;
        dout : out std_logic
    );
end ffd;

architecture ffd_behaviour of ffd is
begin
process(clk)
variable qvar : std_logic := '0';
begin
    if clk'event and clk='1' then
        qvar := din;
    end if;
dout <= qvar;
end process;
end ffd_behaviour;

El siguiente es el TESTBENCH:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity double_periodTB is

end double_periodTB;

architecture double_periodTB_behaviour of double_periodTB is
component double_period is
    port(
        clk : in std_logic;

        divide_by : in std_logic_vector(2 downto 0);
        out_clk : out std_logic
    );
end component;
signal clk : std_logic;
signal out_clk : std_logic;
signal divide_by : std_logic_vector(2 downto 0);
begin
process
begin
clk <= '1'; wait for 10 ns;
clk <= '0'; wait for 10 ns;
end process;
process
begin
divide_by(0) <= '0'; wait for 10 ns;
divide_by(0) <= '0'; wait for 10 ns;
end process;
process
begin
divide_by(1) <= '0'; wait for 10 ns;
divide_by(1) <= '0'; wait for 10 ns;
end process;
process
begin
divide_by(2) <= '0'; wait for 10 ns;
divide_by(2) <= '0'; wait for 10 ns;
end process;
sg : double_period port map(clk, divide_by, out_clk);
end double_periodTB_behaviour;

"DIVIDE_BY" NO SE UTILIZA EN EL MOMENTO !!!!

    
pregunta StackUser

1 respuesta

1

¿Es normal que un divisor de reloj hecho con el contador de johnson del anillo haya salido No definido si el clk comienza alto?

La respuesta corta es Sí.

Obtienes un evento en clk asignando un valor inicial de '1' , satisfaciendo la condición if, asignando el valor de din a qvar .

En el caso de sus tres flip flops f0 , f1 y f2 , los puertos din están asociados con los elementos dInternal o la expresión not de dInternal(2) usando la señal intermedia. dFirst .

Si tuviera que mostrar los ciclos delta en su forma de onda, vería que la causa de su problema es que la asignación a dFirst ocurre un ciclo delta más adelante.

Para aquellos de nosotros que no podemos mostrar los ciclos delta podemos ver que dFirst ( not dInternal(2) ) propagó una 'U' en el estado de dbInternal debido al retraso del ciclo delta:

(clickable)

Unavezdentro,'U'recircula.

Puedecorregirelproblemautilizandolafuncióndeaumentodecoberturaqueseencuentraenelpaquetestd_logic_1164ensumodelodeflipflop:

libraryieee;useieee.std_logic_1164.all;entityffdisport(clk:instd_logic;din:instd_logic;dout:outstd_logic);endentityffd;architecturefooofffdisbeginprocess(clk)variableqvar:std_logic:='0';beginifrising_edge(clk)then--clk'eventandclk='1'thenqvar:=din;endif;dout<=qvar;endprocess;endarchitecture;

Lafunciónrising_edgecalificasuentradaconunallamadaalafunciónTO_01yusaelatributo'LAST_VALUEparadeterminarqueenrealidadhayunflancoascendente,loquesignificaquenoseactivaráerróneamente:

FUNCTIONrising_edge(SIGNALs:std_ulogic)RETURNBOOLEANISBEGINRETURN(s'EVENTAND(To_X01(s)='1')AND(To_X01(s'LAST_VALUE)='0'));END;

Estoda:

( clickable)

En caso de que alguna vez se haya preguntado por qué se incluyeron las funciones rising_edge y falling_edge en el paquete std_logic_1164, ahora tiene un ejemplo concreto.

    
respondido por el user8352

Lea otras preguntas en las etiquetas