library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- Top level component. clk_in is bound to the onboard 50MHz oscillator that is routed
-- to one of the GCLK inputs. The 5 LED outputs are wired up to the 5 red LEDs on
-- the development board
entity main is
port (
clk_in : in std_logic;
led_1_out : out std_logic;
led_2_out : out std_logic;
led_3_out : out std_logic;
led_4_out : out std_logic;
led_5_out : out std_logic
);
end main;
architecture behavioral of main is
-- definition of the fader component
component fader port(
clk_in : in std_logic;
restart : in std_logic;
led_out : out std_logic
);
end component;
-- we need a 23 bit counter to generate the slow clock
signal clk_gen_counter_i : std_logic_vector(22 downto 0) := (others => '0');
signal led_restart_i : std_logic_vector(4 downto 0) := (others => '0');
signal led_clk_i : std_logic := '0';
begin
-- instantiate 5 copies of the fader component, one for each of
-- the onboard LEDs. Each of the restart signals is bound to a
-- bit in the led_restart array.
inst_fader_1 : fader port map(
clk_in => clk_in,
restart => led_restart_i(4),
led_out => led_1_out
);
inst_fader_2 : fader port map(
clk_in => clk_in,
restart => led_restart_i(3),
led_out => led_2_out
);
inst_fader_3 : fader port map(
clk_in => clk_in,
restart => led_restart_i(2),
led_out => led_3_out
);
inst_fader_4 : fader port map(
clk_in => clk_in,
restart => led_restart_i(1),
led_out => led_4_out
);
inst_fader_5 : fader port map(
clk_in => clk_in,
restart => led_restart_i(0),
led_out => led_5_out
);
-- generate a slow clock from the onboard 50MHz oscillator using a prescaler
process(clk_in,led_clk_i)
begin
if rising_edge(clk_in) then
clk_gen_counter_i <= std_logic_vector(unsigned(clk_gen_counter_i) + 1); if clk_gen_counter_i > std_logic_vector(to_unsigned(6250000,clk_gen_counter_i'length)) then
led_clk_i <= not led_clk_i;
clk_gen_counter_i <= (others => '0');
end if;
end if;
end process;
-- use the slow clock to advance through the LEDs one at time. A shift register
-- moves a single 'restart' bit from left to right causing the fader component
-- that's listening on that bit to restart its fade
process(led_clk_i)
begin
if rising_edge(led_clk_i) then
if led_restart_i = "00000" or led_restart_i = "00001" then
led_restart_i <= "10000";
else
-- this is a right shift
led_restart_i <= '0' & led_restart_i(4 downto 1);
end if;
end if;
end process;
end behavioral;
That’s about all really. The only other important file is the .ucf
file that defines which pads the nets are connected to as well as any timing constraints that I might have. Here’s what it looks like.
NET "clk_in" LOC = E13;
NET "led_1_out" LOC = J1;
NET "led_2_out" LOC = K2;
NET "led_3_out" LOC = K1;
NET "led_4_out" LOC = L3;
NET "led_5_out" LOC = L1;
NET "clk_in" TNM_NET = "clk_in";
TIMESPEC TS_clk_in = PERIOD "clk_in" 20ns HIGH 50 %;
Five LEDs and the 50MHz oscillator input on a GCLK net. That’s all there is. Just to be sure I added a timing constraint that tells the compiler the frequency of my oscillator so that it can make sure that my timing constraints are met. Not that there’s much danger of me tripping over that one with this simple design.