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.
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: