So it has been just over a week since I started my journey into FPGAs and so far so good. As a starting point I decided I would work my way through Mike Fields ebook Introducing the Spartan 3E FPGA and VHDL which I must say is an excellent resource and I thoroughly recommend it to anybody wanting to learn about FPGAs from a hands on point of view.
For the last week or so I have spent most of my lunch breaks working my way through the course. It begins with the basics, why choose FPGAs, what development tools etc and then moves quickly onto the hands on stuff like turning on LEDs, binary operations, using signals, clock sources, simulation and much more. Coming from an embedded software background I did find adapting my mindset to a non-procedural way of thinking a bit of a challenge.
Getting to grips with VHDL is fun though, I love the that a digital circuit may be fully realized in a descriptive programming language. What is great about this whole experience though is recalling all those digital electronics fundamentals that have been relegated to the back of my mind.
Below I have posted my attempt at one of the mini projects in Mikes guide. This project implements two up counters using separate 30 bit counter modules. The counters are enabled via an external signal (one of the switches on the LogicStart board) and are clocked via the Papilios 32MHz oscillator. The upper 4 bits of each counter are connected to LEDs on the LogicStart board.
Firstly the project file “Switches_LEDs_Counter.vhd”.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity Switches_LEDs_Counter is Port ( LEDs : out STD_LOGIC_VECTOR(7 downto 0); Switches : in STD_LOGIC_VECTOR(1 downto 0); clk : in STD_LOGIC ); end Switches_LEDs_Counter; architecture Behavioral of Switches_LEDs_Counter is signal count1 : STD_LOGIC_VECTOR(29 downto 0) := (others => '0'); signal count2 : STD_LOGIC_VECTOR(29 downto 0) := (others => '0'); COMPONENT Counter30 PORT( clk : IN std_logic; enable : IN std_logic; count : OUT std_logic_vector(29 downto 0) ); END COMPONENT; begin LEDs(3 downto 0) <= count1(27 downto 24); LEDs(7 downto 4) <= count2(27 downto 24); Inst_Counter30_1: Counter30 PORT MAP( clk => clk, enable => Switches(0), count => count1 ); Inst_Counter30_2: Counter30 PORT MAP( clk => clk, enable => Switches(1), count => count2 ); end Behavioral;
Secondly the 30 bit counter module “Switches_LEDs_Counter_Module.vhd”.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Counter30 is Port ( clk : in STD_LOGIC; enable : in STD_LOGIC; count : out STD_LOGIC_VECTOR (29 downto 0)); end Counter30; architecture Behavioral of Counter30 is signal my_count : STD_LOGIC_VECTOR(29 downto 0) := (others => '0'); begin count <= my_count; clk_proc: process(clk) begin if rising_edge(clk) then if enable = '1' then my_count <= my_count+1; else my_count <= (others => '0'); end if; end if; end process; end Behavioral;
OK so its not some fancy all singing all dancing SDRAM controller but we all have to start somewhere right.