1
\$\begingroup\$

I need to design frequency divider from 50MHz to 200Hz using FPGA. I'm using Xilinx and the language that I used is VHDL language. I got stuck because I can't get the output. So, anyone can help me? Here I attach my code.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FreqDivider is
port(
    clock   : in STD_LOGIC; -- 50 Mhz
    clear    : in STD_LOGIC;
      adjclk : out STD_LOGIC
);
end FreqDivider;

architecture Behavioral of FreqDivider is
signal adjfreq: STD_LOGIC_VECTOR(17 downto 0) := "000000000000000000";
signal adjcntr: STD_LOGIC_VECTOR(2 downto 0) := (others => '0');
signal adjclock : std_logic := '0';

begin

adjclk <= adjclock;

countClock: process(clock,clear,adjfreq)
begin
    if (clear = '1') then
            adjfreq <= "000000000000000000";
        elsif(clock'event and clock = '1') then
        if (adjfreq = "111101000010010000") then  --50MHz/250000=200Hz
                adjfreq <= "000000000000000000";
                adjclock <= '1';
            else adjfreq <= adjfreq+1;
                adjclock <= '0';
            end if;
    end if;
end process;

process(adjclock)
    begin
            if (adjclock 'event and adjclock ='1') then
                    if adjcntr = "101" then
                    adjcntr <= "000";
                    else adjcntr <= adjcntr+1;
                    end if;
            end if;
    end process;
end Behavioral;

Below is for testbench,

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

ENTITY FreqDivider_tb IS
END FreqDivider_tb;

ARCHITECTURE behavior OF FreqDivider_tb IS 

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT FreqDivider
PORT(
     clock : IN  std_logic;
     clear : IN  std_logic;
     adjclk : OUT  std_logic
    );
END COMPONENT;


--Inputs
signal clock : std_logic := '0';
signal clear : std_logic := '0';

--Outputs
signal adjclk : std_logic;

-- Clock period definitions
constant clock_period : time := 40 ns;  --50MHz
constant adjclk_period : time := 40 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: FreqDivider PORT MAP (
      clock => clock,
      clear => clear,
      adjclk => adjclk
    );

-- Clock process definitions
clock_process :process
begin
    clock <= '0';
    wait for clock_period/2;  --for 20ns signal is '0'.
    clock <= '1';
    wait for clock_period/2;  --for 20ns signal is '1'.
end process;

adjclk_process :process
begin
    adjclk <= '0';
    wait for adjclk_period/2;
    adjclk <= '1';
    wait for adjclk_period/2;
end process;


-- Stimulus process
stim_proc: process
begin       
  -- hold reset state for 100ms.
  wait for 40 ms;clear <= '1';  
    wait for 80 ms;clear <= '0';
  wait for clock_period*10;

  -- insert stimulus here 

  wait;
end process;

END;
\$\endgroup\$
  • \$\begingroup\$ You should add why it isn't working? Is the output the wrong frequency? Are there errors at compile time? Etc. \$\endgroup\$ – uint128_t Mar 26 '16 at 15:07
  • \$\begingroup\$ There is no error at compile time, but for the ISIM simulator, I think there is something wrong with the waveform. \$\endgroup\$ – Min_ah Mar 26 '16 at 15:20
  • \$\begingroup\$ What do you think is wrong with the waveform? Since you are toggeling adjclock at a rate of 200 Hz the clock frequency of adjclock will in fact only be 100 Hz. \$\endgroup\$ – damage Mar 26 '16 at 15:47
0
\$\begingroup\$

Well, since unfortunately it isn't caught at compile time by your toolchain (which seems strange to me, but oh well):

Your FreqDivider component has an output port adjclk, and it is being driven by your countClock process. This is all very well and fine, no problem here.

However, your stimulus process has a signal called adjclk that is mapped to the adjclk port of your FreqDivider and this signal is being driven by a stimulus process adjclk_process. You cannot assign values to a signal that is being driven by a component. Most toolchains (at least, the ones I am familiar with) would identify this as bad, and complain loudly, but it seems your simulator only indicates this by an X or something in the output.

So, the solution: eliminate adjclk_process. It doesn't make sense to drive the output of a frequency divider that's supposed to be at 200Hz with a 25MHz signal.

Oh, and, as an aside, your math is a bit off on this line:

constant clock_period : time := 40 ns;  --50MHz

\$\frac{1}{50\text{MHz}} = 20\text{ns}\$, and each half-period would be 10ns, not 20ns.

\$\endgroup\$

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.