Last active
March 16, 2017 12:00
-
-
Save jgibbard/532a4ff0c4115a5a3f33 to your computer and use it in GitHub Desktop.
VHDL Counter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; USE ieee.std_logic_arith.all; | |
--This example shows how different speed signals can be created using both a counter method and a PLL | |
--PLL are very powerful and can be used to generate both fast or slower clk speeds as well as changing the phase of the signal. | |
--There are a limited amount of PLLs on an FPGA however a single PLL block in the FPGA can often be used to generate several different frequencies. | |
entity pll_test is port ( | |
CLOCK_50 : in std_logic; | |
SW : in std_logic_vector(9 downto 0); | |
LEDG : OUT std_logic_vector(9 downto 0) | |
); | |
end pll_test; | |
architecture rtl of pll_test is | |
--Signals for 50MHz clk divider | |
signal clk_divide_count1 : std_logic_vector(31 downto 0) := (others => '0'); | |
signal counter1 : std_logic_vector(9 downto 0) := (others => '0'); | |
signal slow_clk1 : std_logic := '0'; | |
--Signals for 100MHz clk divider | |
signal clk_divide_count2 : std_logic_vector(31 downto 0) := (others => '0'); | |
signal counter2 : std_logic_vector(9 downto 0) := (others => '0'); | |
signal slow_clk2 : std_logic := '0'; | |
signal pll_clk : std_logic := '0'; | |
begin | |
--Generates a slower clk so that the counting can be seen at human speeds! | |
slow_clock_gen_process1 : process(CLOCK_50) | |
begin | |
if rising_edge(CLOCK_50) then | |
if (clk_divide_count1 >= 5000000) then --50MHz clock counting to 5 million, therefore slow clock will have period of 0.1s [(1/(50*10^6))*(5*10^6) = 0.1] | |
clk_divide_count1 <= (others => '0'); --Reset clock divider | |
slow_clk1 <= '1'; --Pulse slow_clk for one clock period | |
else | |
clk_divide_count1 <= clk_divide_count1 + 1 ; --Increment clk_divide_count, NB this is not the output counter | |
slow_clk1 <= '0'; | |
end if; | |
end if; | |
if rising_edge(CLOCK_50) then | |
if (slow_clk1 = '1') then | |
counter1 <= counter1 + 1 ; --Increment the output counter every 0.1s | |
end if; | |
end if; | |
end process; | |
--Identical process to above, however runs off 100MHz clk instead of 50MHz | |
slow_clock_gen_process2 : process(pll_clk) | |
begin | |
if rising_edge(pll_clk) then | |
if (clk_divide_count2 >= 5000000) then --100MHz clock counting to 5 million, therefore slow clock will have period of 0.05s | |
clk_divide_count2 <= (others => '0'); --Reset clock divider | |
slow_clk2 <= '1'; --Pulse slow_clk for one clock period | |
else | |
clk_divide_count2 <= clk_divide_count2 + 1 ; --Increment clk_divide_count, NB this is not the output counter | |
slow_clk2 <= '0'; | |
end if; | |
end if; | |
if rising_edge(pll_clk) then | |
if (slow_clk2 = '1') then | |
counter2 <= counter2 + 1 ; --Increment the output counter every 0.05s | |
end if; | |
end if; | |
end process; | |
--Generates 100MHz clk from 50MHz clk via PLL | |
pll_inst : entity work.mw_pll port map (inclk0 => CLOCK_50, c0 => pll_clk); | |
LEDG(9 downto 0) <= counter1 when sw(0) = '1' else counter2; --Set LEDs to value of counter. Speed of counter depends on position of switch 0 | |
end rtl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--This VHDL example outputs a binary count to 10 leds. | |
--The counter increases at the rate of 0.1s when the input clk is 50MHz. | |
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; USE ieee.std_logic_arith.all; | |
entity test_design is port( | |
--These must match the names of the pins set in the pin asignment file | |
CLOCK_50 : in std_logic; | |
SW : in std_logic_vector(9 downto 0); | |
LEDG : out std_logic_vector(9 downto 0) | |
); | |
end test_design; | |
architecture rtl of test_design is | |
signal clk_divide_count : std_logic_vector(31 downto 0); --Stores the current count of the clock divider counter | |
signal counter : std_logic_vector(9 downto 0); --Stores the value of the output counter displayed on the LEDs | |
signal slow_clk : std_logic; --The new slow clock (Period set to 0.1s) | |
begin | |
slow_clock_gen_process : process(CLOCK_50) | |
begin | |
if rising_edge(CLOCK_50) then | |
if (clk_divide_count >= 5000000) then --50MHz clock counting to 5 million, therefore slow clock will have period of 0.1s [(1/(50*10^6))*(5*10^6) = 0.1] | |
clk_divide_count <= (others => '0'); --Reset clock divider | |
slow_clk <= '1'; --Pulse slow_clk for one clock period | |
else | |
clk_divide_count <= clk_divide_count + 1 ; --Increment clk_divide_count, NB this is not the output counter | |
slow_clk <= '0'; | |
end if; | |
end if; | |
if rising_edge(CLOCK_50) then | |
if (slow_clk = '1') then | |
counter <= counter + 1 ; --Increment the output counter every 0.1s | |
end if; | |
end if; | |
end process; | |
LEDG(9 downto 0) <= counter; --Set LEDs to value of counter | |
end rtl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; USE ieee.std_logic_arith.all; | |
ENTITY test_design_tb IS | |
END test_design_tb; | |
ARCHITECTURE behavior OF test_design_tb IS | |
component test_design PORT( | |
CLOCK_50 : in std_logic; | |
reset : in std_logic; | |
LEDG : out std_logic_vector(9 downto 0) | |
); | |
end component; | |
signal clk : std_logic := '0'; | |
signal rst : std_logic := '0'; | |
signal led_out : std_logic_vector(9 downto 0) := (others => '0'); | |
constant clk_period : time := 1 ns; | |
BEGIN | |
uut: test_design PORT MAP (CLOCK_50 => clk, reset => rst, LEDG => led_out); | |
reset_process : process | |
begin | |
wait for 10 ns; | |
rst <= '1'; | |
wait for 2 ns; | |
rst <= '0'; | |
wait; | |
end process; | |
-- Clock process definitions( clock with 50% duty cycle is generated here. | |
clk_process :process | |
begin | |
clk <= '0'; | |
wait for clk_period/2; --for 0.5 ns signal is '0'. | |
clk <= '1'; | |
wait for clk_period/2; --for next 0.5 ns signal is '1'. | |
end process; | |
END; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment