Microprocessors
Programs

Simple Flashing LED Program for the VC707: Part 5

5.0 Looking at the Source Code for the LED Controller

Next we'll take a look at the source code for led_ctl.vhd. After the library include lines, you'll see the entity definition for the component:

        entity led_ctl is
            Port ( rst_clk_rx   : in  std_logic;  
                   clk_rx       : in  std_logic;                   
                   led_o        : out std_logic_vector(7 downto 0)
             );
        end led_ctl;
        

This should already be familiar to you after looking at the definition of the clocked_led entity in clocked_led.vhd. We're just one level down in the hierarchy.


The architecture section for this module is very different, though:

            architecture Behavioral of led_ctl is
   begin

     LEDCtrl: process (clk_rx)
       variable cnt : integer := 0;
       variable led_buf : std_logic_vector(7 downto 0);
       begin
         if rising_edge(clk_rx) then
           if (rst_clk_rx = '1') then
             led_o        <= (others=>'0');
             led_buf      := (others=>'0');
             cnt          := 0;
           else
             cnt          := cnt+1;

             -- Flash the 1st LED
             if ((cnt mod 5000000) = 0) then
                 led_buf(0) := NOT led_buf(0);
             end if;
             -- Flash the 2nd LED
             if ((cnt mod 10000000) = 0) then
                 led_buf(1) := NOT led_buf(1);
             end if;
             -- Flash the 3rd LED
             if ((cnt mod 20000000) = 0) then
                 led_buf(2) := NOT led_buf(2);
             end if;
             -- Flash the 4th LED
             if ((cnt mod 40000000) = 0) then
                 led_buf(3) := NOT led_buf(3);
             end if;
             -- Flash the 5th LED
             if ((cnt mod 80000000) = 0) then
                 led_buf(4) := NOT led_buf(4);
             end if;
             -- Flash the 6th LED
             if ((cnt mod 160000000) = 0) then
                 led_buf(5) := NOT led_buf(5);
             end if;
             -- Flash the 7th LED
             if ((cnt mod 320000000) = 0) then
                 led_buf(6) := NOT led_buf(6);
             end if;
             -- Flash the 8th LED
             if ((cnt mod 640000000) = 0) then
                 led_buf(7) := NOT led_buf(7);
             end if;

             -- Now output the internal buffered version to the port
             led_o <= led_buf;

           end if;
         end if;
       end process LEDCtrl;

end Behavioral;

Here we are declaring a "process", which in VHDL is a way of executing sequential statements in a pseudo-software type way. The behavioral process is basically an infinite loop that can be paused with wait statements. In ours, we are asking the FPGA to check the rising edge of the input clock. Every time we get the rising edge, we increment a counter and check what its value is. If it divides evenly into a certain number, we'll toggle an LED.


There's also a check for the reset clock. If we see a high level on it, we will reset the counter and turn all of the LEDs off.

There are a couple of other important things to note about this section of code:

  1. We are declaring "cnt" as a 32-bit integer. We only set its value at reset, so eventually it will roll over when it reaches 2^32-1.
  2. It might be tempting to just grab the levels of the LED using the led_o std_logic_vector. Unfortunately, you can't directly access the value of an output signal in VHDL. You'll get an error message if you try to do something like led_o(0) := NOT led_o(0). That's why I'm using the temporary led_buf std_logic_vector.

So at this point, you may be saying to yourself, "We've declared all these input and output signals, but I haven't seen one pin assignment yet. Where does that happen?"



← Previous    ...    Next →

Table Of Contents