Cómo implementar un retraso en VHDL

3

Estoy enviando datos al convertidor A / D y necesito que los datos del comando se retrasen al menos 50ns desde clk_19khz. Esto es lo que tengo hasta ahora. ¿Cómo inserto un retraso de 50 ns, que es un requisito para el A / D entre el clk_19khz y mi primer bit Dout en el A / D? Estoy usando un FPGA Xilinx en ISE. El proyecto completado utilizará vivado como IDE. ¡Gracias por la ayuda!

         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;

            -- Uncomment the following library declaration if instantiating
             -- any Xilinx primitives in this code.
              --library UNISIM;
              --use UNISIM.VComponents.all;

       entity PSOL is
          Port ( clk : in  STD_LOGIC;
                 clk_19khz : OUT std_logic;
                 Dout :out std_logic);
          end PSOL;

      architecture Behavioral of PSOL is
         signal temp : std_logic;
         signal count : integer range 0 to 1301 := 0; --1301
       --signal temp2 : std_logic;
         signal dcount : integer range 0 to 11 := 0; --
         signal start : std_logic  := '1'; -- indicates the start of 
         signal parity : std_logic := '1'; --used to varify data sent
         signal stop : std_logic := '0'; --indicate when word/command has 
         signal enable : std_logic;
       --signal chip_select : bit :='1'; -- active low



    begin
         process (clk)
             begin
          if (clk' EVENT AND clk='1') then
            if (count = 1301) then --1301
                temp <= not(temp);
                count <=0;
                clk_19khz <= temp;
                enable <= '1';
            else
                count <= count + 1;     
            end if;
             if (enable = '1') then

               dcount <= dcount + 1;
               parity <= '1';
               stop <= '0';
               start <='1';

                 if (dcount < 12 and start = '1' and stop = '0') then
                    CASE dcount is
                     when 1 => Dout <= start;
                     when 2 => Dout <= '0';
                     when 3 => Dout <= '1';
                     when 4 => Dout <= '0';
                     when 5 => Dout <= '1';
                     when 6 => Dout <= '0';
                     when 7 => Dout <= '0';
                     when 8 => Dout <= '1';
                     when 9 => Dout <= '1';
                     when 10 => Dout <= parity;
                     when 11 => Dout <= stop;
                     when others => null;
                    end case;
                 end if;
                  enable <= '0';
         end if;                

        end if;
end process;



 end Behavioral;
    
pregunta hfbroady

1 respuesta

1

He cambiado tu código en algunas partes (espero que estés de acuerdo con eso). ¿Por qué creo que esta versión es mejor?

  • Ahora todos los procesos están sincronizados por un reloj real.
  • Cada proceso tiene un nombre.
  • Las señales están escritas en un solo lugar

El código podría ser aún mejor:

  • Lo que estás usando en el proceso "output_generator" es una clase de máquina de estado para generar tu patrón. Eche un vistazo a los ejemplos de Altera cómo hacerlo más legible y más fácil de depurar.
  • Podríamos transformar algunas señales en variables (temp, count, dcount). Serían visibles solo en el área necesaria y no saturarían nuestra sección de definiciones.
  • ¿Para qué sirven las señales de inicio / parada? No llevan a ningún lado.

-

architecture Behavioral of PSOL is
   signal temp : std_logic := '0';
   signal count : integer range 0 to 1301 := 0; --1301
   signal dcount : integer range 0 to 11 := 0; --
   signal start : std_logic  := '1'; -- indicates the start of 
   signal parity : std_logic := '1'; --used to varify data sent
   signal stop : std_logic := '0'; --indicate when word/command has 
   signal enable : std_logic := '0';


begin

-- The clock divider generates a 50% duty cycle signal with 19kHz as clock for the output. 
-- and a enable signal that is high for one clock cyncle on each rising edge of clk_19kHz
clockdivider: process (clk)
begin
    if rising_edge(clk) then
        if (count = 1301) then --1301
            temp <= not(temp);
            count <=0;
            clk_19khz <= temp;

            if temp = '1' then -- only on rising edge 
                enable <= '1';
            end if;
        else
            enable <= '0';    -- make it a puls
            count <= count + 1;     
        end if;
    end if;
end process clockdivider;

-- Here we generate the dout signal. 
output_generator: process(clk)
begin
    if rising_edge(clk) then
        if enable = '1' then  -- use only the clocks where enable is 1
            dcount <= dcount + 1;
            parity <= '1';
            stop <= '0';
            start <='1';

            if (dcount < 12 and start = '1' and stop = '0') then
                CASE dcount is
                    when 0 => Dout <= start; -- what happens with dcount = 0?
                    when 1 => Dout <= start;
                    when 2 => Dout <= '0';
                    when 3 => Dout <= '1';
                    when 4 => Dout <= '0';
                    when 5 => Dout <= '1';
                    when 6 => Dout <= '0';
                    when 7 => Dout <= '0';
                    when 8 => Dout <= '1';
                    when 9 => Dout <= '1';
                    when 10 => Dout <= parity;
                    when 11 => Dout <= stop;
                    when others => null;
                end case;
            end if; 
        end if; 
    end if;
end process output_generator;

end Behavioral;

    
respondido por el Botnic

Lea otras preguntas en las etiquetas