Browse over 10,000 Electronics Projects

Working with the Xilinx Virtex-E FPGA in a huge BGA package

Working with the Xilinx Virtex-E FPGA in a huge BGA package

Xilinx ISE 10.1

The latest version of ISE to support the Virtex-E is 10.1 and that’s only supposed to work on Windows XP. There are forum posts from people who’ve managed to get it working on more recent Windows editions but since it only takes half an hour to spin up an XP virtual machine using the free VMWare Player then that’s what I did.

The final link is the JTAG programmer used to upload the design bitstream to the FPGA. I have a Platform USB programmer that I got on ebay from, yes you guessed it, China for about 20 quid. It features the Xilinx logo on the box but I’d be surprised to find that it’s genuine because I don’t think Xilinx have ever charged as little as 20 quid for anything frankly.


Genuine Xilinx? Hmmm.

This’ll be the first time that I’ve used it so we’ll see if it works. Now all I need is an FPGA design to exercise the board. There’s a row of five LEDs on this board so I decided to go for a PWM flashing thing. I’d bring the LEDs up to 100% brightness and then fade them down to zero with a little delay between each one so it looks a bit like a progression along the line of LEDs.

To do the fading effect I’ll need a process that can output a PWM signal on one of the GPIO lines. Here’s what it looks like.

library ieee;

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


-- Very simple PWM implementation. The 50MHz clock on the
-- virtex-e development board will yield a frequency of 500kHz
-- Frequency = clk_in / 100
-- Duty cycle = 0..100

entity pwm is
  port(
    clk_in     : in  std_logic;
    duty_cycle : in  std_logic_vector(6 downto 0);
    pwm_signal : out std_logic
  );
end pwm;

architecture behavioral of pwm is

  -- a 7 bit counter is wide enough to hold 0..100
  
  signal counter_i : std_logic_vector(6 downto 0) := (others => '0');
  signal pwm_signal_i : std_logic := '0';

begin

  -- wire up the output

  pwm_signal <= pwm_signal_i;

  process(clk_in)
  begin

    if rising_edge(clk_in) then

      -- if the counter has passed the current dury cycle percentage then set the signal low
      -- otherwise it remains high

      if counter_i >= duty_cycle  then
        pwm_signal_i <= '0';
      else 
        pwm_signal_i <= '1';
      end if;

      -- if the counter is at 99 then reset it back to 0 for the next PWM clock cycle
      -- otherwise just increment it.

      if counter_i >= std_logic_vector(to_unsigned(99,counter_i'length)) then
        counter_i <= (others => '0');
      else
        counter_i <= std_logic_vector(unsigned(counter_i)+1);
      end if;

    end if;
    
  end process;

end behavioral;

Now I need a process that will use the PWM component to fade a LED from 100% duty cycle down to zero. Here it is.



Advertisement1


library ieee;

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- The fader component manages resetting a LED to 100% duty cycle and then fading
-- it down to zero using the PWM component. The fade time is about 1.6s

entity fader is
  port (
    clk_in  : in  std_logic;
    restart : in  std_logic;  
    led_out : out std_logic
--add a few more signals to the simulator
--pragma synthesis_off
    ;
    duty_cycle_sim : out std_logic_vector(6 downto 0);
    fader_clk_sim : out std_logic
--pragma synthesis_on
  );
end fader;

architecture behavioral of fader is

  component pwm port(
    clk_in     : in  std_logic;
    duty_cycle : in  std_logic_vector(6 downto 0);
    pwm_signal : out std_logic
  );
  end component;

  -- 7 bit duty cycle and 18 bit counter

  signal duty_cycle_i : std_logic_vector(6 downto 0) := (others => '0');
  signal clk_gen_counter_i : std_logic_vector(17 downto 0) := (others => '0');
  signal fader_clk_i : std_logic := '0';

begin

--pragma synthesis_off
  duty_cycle_sim <= duty_cycle_i;
  fader_clk_sim <= fader_clk_i;
--pragma synthesis_on

  -- instantiate a PWM component to manage the fade to zero

  inst_pwm : pwm port map(
    clk_in     => clk_in,
    duty_cycle => duty_cycle_i,
    pwm_signal => led_out
  );

  -- generate a slow clock from the 50MHz input clock using a prescaler

  slow_clk_gen: process(clk_in)
  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(150000,clk_gen_counter_i'length)) then
        fader_clk_i <= not fader_clk_i;
        clk_gen_counter_i <= (others => '0');
      end if;

    end if;

  end process;


  -- Manage the fade process. If restart is asserted then the duty cycle
  -- is reset back to 100. Otherwise we slowly fade down to zero then stop.
  
  fade_process: process(fader_clk_i)
  begin

    if rising_edge(fader_clk_i) then

      if restart = '1' then
        duty_cycle_i <= std_logic_vector(to_unsigned(100,duty_cycle_i'length));
      else

        if duty_cycle_i /= "0000000" then
          duty_cycle_i <= std_logic_vector(unsigned(duty_cycle_i) - 1);
        end if;

      end if;
    end if;

  end process;

end behavioral;

Now I have the ability to fade a LED from 100% down to zero I need to instantiate five copies of it and manage the timing so that each of the five LEDs starts slightly after the previous one. This is the main, top-level VHDL module and it looks like this:

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

 


Top