3
\$\begingroup\$

I'm sending data to and A/D converter and I need the command data to be delayed at least 50ns from clk_19khz. Here is what I have so far. How do I insert a delay of 50ns which is a requirement for the A/D between the clk_19khz and my first Dout bit to the A/D? I'm using a Xilinx FPGA in ISE. The completed project will use vivado as the IDE Thanks for the help!

         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;
\$\endgroup\$
  • \$\begingroup\$ Put a counter there. \$\endgroup\$ – Eugene Sh. Nov 4 '15 at 21:38
  • \$\begingroup\$ How do I know what to set the counter too? The 50ns I needs is shorter than the period on my clock. \$\endgroup\$ – hfbroady Nov 4 '15 at 21:48
  • \$\begingroup\$ You can not wait times shorter than your clock. What is the clock frequency anyway? Please do not use temp2'event. Only with clock signals on clock nets should be used on edges. \$\endgroup\$ – Botnic Nov 4 '15 at 21:50
  • \$\begingroup\$ temp2 is my new clock generated for the serial clock transmission and it is a 19khz clock. \$\endgroup\$ – hfbroady Nov 4 '15 at 21:55
  • \$\begingroup\$ You should not use clocks this way. This is really bad design. If you want to make a new clock use a PLL (or different clock module). But in your case this is not necessary. What you need is some kind of enable that enables your state machine only 19k per second. \$\endgroup\$ – Botnic Nov 4 '15 at 22:05
1
\$\begingroup\$

I have changes your code in some parts (I hope your ok with that). Why do I think this version is better?

  • Now all process are clocked by real clock.
  • Each process has a name.
  • Signals are written on one place only

The code could be made even better:

  • What you are using in process "output_generator" is some kind of state machine to generate your pattern. Have a look at the examples of Altera how to make it more readable and easier to debug.
  • We could transform some signals into variables (temp, count, dcount). They they would be visible only in the area needed and would not clutter our definitions section.
  • What are the start / stop signals for? They lead no where.

-

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;

Simulation

\$\endgroup\$
  • \$\begingroup\$ I don't mind you editing my code, trying to learn this as I go thanks. The start and stop bits are place holds for now. Later they will be used to tell me when a new command starts and stops. The output bits are clocked on the falling edge of the generated clock and bits are clocked into the FPGA in the rising edge. \$\endgroup\$ – hfbroady Nov 5 '15 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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