Papilio Plus/Fading counter

From Hamsterworks Wiki!

Jump to: navigation, search

This Papilio S6 project is a fancy binary counter that fades from one value to the other.

It was initially called "ClockTest" as it was used to test that the clock was working.

The project has two 12 bit counters, when one (counter1) is zero the counter that drives the LEDs is incremented, the counter2 is zero the counter that drives the LEDs decremented.

One counter counts all the way to 4095, but the other is reset to zero when it reaches 4094. The small difference in periods causes the LED counter to rapidly cycle between two adjacent values, causing a nice soft transition between values as it counts up.

I use 'two process' VHDL for my projects, which makes small projects even more verbose than they need to be, but quickly pays off in larger projects.

ClockTest.ucf

CONFIG PROHIBIT=P144;
CONFIG PROHIBIT=P69;
CONFIG PROHIBIT=P60;

NET CLK  LOC = "P94" | IOSTANDARD = LVCMOS25 | PERIOD = 31.25ns;

NET LED(0)    LOC="P75"  | IOSTANDARD=LVTTL; # A7  LED1
NET LED(1)    LOC="P67"  | IOSTANDARD=LVTTL; # A6  LED2
NET LED(2)    LOC="P66"  | IOSTANDARD=LVTTL; # A5  LED3
NET LED(3)    LOC="P61"  | IOSTANDARD=LVTTL; # A4  LED3

ClockTest.vhd

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz>
-- 
-- Create Date:    21:02:33 09/29/2011 
-- Module Name:    ClockTest - Behavioral 
-- Description:  Test the clock by flashing LEDs.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ClockTest is
    Port ( Clk : in  STD_LOGIC;
           LED : out STD_LOGIC_VECTOR (3 downto 0));
end ClockTest;

architecture Behavioral of ClockTest is
   type reg is record 
      counter1 : std_logic_vector(11 downto 0);
      counter2 : std_logic_vector(11 downto 0);
      leds     : std_logic_vector(4 downto 0);
   end record;
 
   signal r : reg := ( (others =>'0'), (others =>'0'), (others =>'0'));
   signal n : reg;
begin
   -- Assign the outputs - I ignore bit 0 so the LSB of the counter stays 'stable' for 50% of the time
   LED <= r.leds(4 downto 1);
 
   -- Process one, combinatorial logic to work out the next state
   process(r)
   begin
      -- Work out the next value to assign to the registers
      n.counter1 <= r.counter1 + 1;
      n.counter2 <= r.counter2 + 1;

      if r.counter2 = "111111111110" then
         n.counter2 <= (others => '0');
      end if;
  
      if r.counter1 = "000000000000" then
         if r.counter2 = "000000000000" then
            n.leds <= r.leds;
         else
            n.leds <= r.leds-1; -- Count down
         end if;
      else
         if r.counter2 = "000000000000" then
            n.leds <= r.leds+1; -- Count up
         else
            n.leds <= r.leds;
         end if;
      end if;
   end process;

   -- Process two, when the clock rises assign the next state
   process(n,clk)
   begin
      -- When the clock rises, update the registers
      if rising_edge(clk) then
         r <= n;
      end if;
   end process;
end Behavioral;

Bitstream file

File:ClockTest.bit

Personal tools