| 
     
      
      
      From: Pierre C. <Sup...@us...> - 2010-01-25 23:12:32
      
     
   | 
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "krobot-resources".
The branch, master has been updated
       via  1e545ef9f7ae38acea030fec3f15b1c1a9fb5e58 (commit)
      from  32e007d2e96e6c74fb68e0e935756940639e23e9 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 1e545ef9f7ae38acea030fec3f15b1c1a9fb5e58
Author: chambart <cha...@cr...>
Date:   Tue Jan 26 00:11:47 2010 +0100
    add a begining of a pong game example
-----------------------------------------------------------------------
Changes:
diff --git a/fpga/examples/pong/Makefile b/fpga/examples/pong/Makefile
new file mode 100644
index 0000000..73a6756
--- /dev/null
+++ b/fpga/examples/pong/Makefile
@@ -0,0 +1,35 @@
+PART=xc3s1200e-fg320-5
+
+XST=xst
+NGDBUILD=ngdbuild
+PAR=par
+BITGEN=bitgen
+MAP=map
+
+FILE=truc2
+UCF=pong.ucf
+
+.PHONY: all clean
+all: out.bit
+
+%.ngc : %.vhd
+	echo "run -ifn " $< " -p " $(PART) " -ofn " $@ " -opt_mode AREA -opt_level 0 -ifmt VHDL" | $(XST)
+
+pong.ngc : vga.ngc keyboard.ngc ps2.ngc draw.ngc simple_7seg.ngc game.ngc
+
+pong.ngd : pong.ngc
+	$(NGDBUILD) -p $(PART) -uc $(UCF) $<
+
+tmp.ncd : pong.ngd
+	$(MAP) -p $(PART) -o $@ $<
+
+out.ncd : tmp.ncd
+	$(PAR) -w $< $@
+
+out.bit: out.ncd
+	$(BITGEN) -w out.ncd
+
+clean:
+	rm -fr *.ncd *.ngc *.ngd *.bit *.pcf *.map *.mrp \
+	*.lso *.xml *.xrpt *.bgn *.drc *.bld *.ngm *.lst \
+	xst out* *.log *.twr xlnx_auto*
diff --git a/fpga/examples/pong/draw.vhd b/fpga/examples/pong/draw.vhd
new file mode 100644
index 0000000..57fe679
--- /dev/null
+++ b/fpga/examples/pong/draw.vhd
@@ -0,0 +1,99 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+
+entity draw is
+  generic (
+    size_x : positive := 400;
+    size_y : positive := 400
+  );
+  port (
+    update : in std_logic;
+    x_pos : in  integer range 0 to 639;
+    y_pos : in  integer range 0 to 479;
+    ball_x : in integer range 0 to size_x - 1;
+    ball_y : in integer range 0 to size_y - 1;
+
+    color : out std_logic_vector (7 downto 0));
+
+end draw;
+
+architecture draw of draw is
+  type rom_type is array (0 to 3, 0 to 3) of integer range 0 to 3;
+  signal px : integer;
+  signal py : integer;
+  signal locx : integer range 0 to 3;
+  signal locy : integer range 0 to 3;
+  signal tmpx : natural;
+  signal tmpy : natural;
+  constant rom : rom_type :=
+    ((1,3,0,0),
+     (2,1,3,0),
+     (0,2,1,3),
+     (0,0,0,1));
+begin
+
+  px <= ball_x;
+  py <= ball_y;
+
+  tmpx <= abs (x_pos - px);
+  tmpy <= abs (y_pos - py);
+
+  
+  --locx <= tmpx when tmpx <= 3 else 3;
+  --locy <= tmpy when tmpy <= 3 else 0;
+
+  --with rom(locx,locy) select
+  --  color <=
+  --  "00000000" when 0,
+  --  "11100000" when 1,
+  --  "00011100" when 2,
+  --  "00000011" when 3;
+
+  color <= "11111111" when (tmpx <= 3) and (tmpy <= 3)
+                      else "00000000";
+
+--update_process: process (update)
+--  variable x : integer := 100;
+--  variable y : integer := 100;
+--  variable direction_x : std_logic := '1';
+--  variable direction_y : std_logic := '1';
+--begin
+--  if rising_edge(update) then
+--    if x >= 639 and direction_x = '1'
+--    then
+--      direction_x := '0';
+--    end if;
+--    if x <= 0 and direction_x = '0'
+--    then
+--      direction_x := '1';
+--    end if;
+--    if y >= 479 and direction_y = '1'
+--    then
+--      direction_y := '0';
+--    end if;
+--    if y <= 0 and direction_y = '0'
+--    then
+--      direction_y := '1';
+--    end if;
+
+--    if direction_x = '0' then
+--      x := x - 1;
+--    else
+--      x := x + 1;
+--    end if;
+--    if direction_y = '0' then
+--      y := y - 1;
+--    else
+--      y := y + 1;
+--    end if;
+
+--  end if;
+
+--  px <= x;
+--  py <= y;
+
+--end process update_process;
+    
+end draw;
diff --git a/fpga/examples/pong/game.vhd b/fpga/examples/pong/game.vhd
new file mode 100644
index 0000000..d3da725
--- /dev/null
+++ b/fpga/examples/pong/game.vhd
@@ -0,0 +1,120 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+
+entity game is
+    generic (
+      size_x : positive := 400;
+      size_y : positive := 400);
+    port (
+    clk : in std_logic;
+    scan_code : in std_logic_vector ( 7 downto 0 );
+    up_key : in std_logic;
+    extended_key : in std_logic;
+    key_int : in std_logic;
+    ball_x : out integer range 0 to size_x - 1;
+    ball_y : out integer range 0 to size_y - 1;
+    keys : out std_logic_vector ( 3 downto 0 )
+    );
+end entity game;
+
+architecture game of game is
+  signal game_clk : std_logic;
+  signal key_up : std_logic;
+  signal key_down : std_logic;
+  signal key_left : std_logic;
+  signal key_right : std_logic;
+  signal px : integer;
+  signal py : integer;
+begin
+
+  keys <= key_up & key_down & key_left & key_right;
+
+  ball_x <= px;
+  ball_y <= py;
+
+  process (key_int)
+    variable up : std_logic := '0';
+    variable down : std_logic := '0';
+    variable left_dir : std_logic := '0';
+    variable right_dir : std_logic := '0';
+  begin
+    if rising_edge(key_int) then
+      if (up_key = '0' and scan_code = "0111"&"0101" ) then
+        up := '1';
+      end if;
+      if (up_key = '1' and scan_code = "0111"&"0101" ) then
+        up := '0';
+      end if;
+      if (up_key = '0' and scan_code = "0111"&"0010" ) then
+        down := '1';
+      end if;
+      if (up_key = '1' and scan_code = "0111"&"0010" ) then
+        down := '0';
+      end if;
+      if (up_key = '0' and scan_code = "0111"&"0100" ) then
+        right_dir := '1';
+      end if;
+      if (up_key = '1' and scan_code = "0111"&"0100" ) then
+        right_dir := '0';
+      end if;
+      if (up_key = '0' and scan_code = "0110"&"1011" ) then
+        left_dir := '1';
+      end if;
+      if (up_key = '1' and scan_code = "0110"&"1011" ) then
+        left_dir := '0';
+      end if;
+    end if;
+
+    key_up <= up;
+    key_down <= down;
+    key_left <= left_dir;
+    key_right <= right_dir;
+    
+  end process;
+
+
+  process (clk)
+    constant length : integer := 1_000_000;
+    variable counter : integer range 0 to length:= 0;
+    variable tmp : std_logic := '0';
+  begin
+    if rising_edge(clk) then
+      counter := counter + 1;
+      if counter = length / 2 then
+        tmp := not tmp;
+        counter := 0;
+      end if;
+    end if;
+    game_clk <= tmp;
+  end process;
+
+  update_process: process (game_clk)
+    variable x : integer := 100;
+    variable y : integer := 100;
+  begin
+    if rising_edge(game_clk) then
+
+      if key_up = '1' and y > 0 then
+        y := y - 1;
+      end if;
+      if key_down = '1' and y < size_y then
+        y := y + 1;
+      end if;
+      if key_left = '1' and x > 0 then
+        x := x - 1;
+      end if;
+      if key_right = '1' and x < size_x then
+        x := x + 1;
+      end if;
+
+    end if;
+
+    px <= x;
+    py <= y;
+
+  end process update_process;
+
+  
+end architecture;
diff --git a/fpga/examples/pong/keyboard.vhd b/fpga/examples/pong/keyboard.vhd
new file mode 100644
index 0000000..88a8882
--- /dev/null
+++ b/fpga/examples/pong/keyboard.vhd
@@ -0,0 +1,57 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+entity keyboard is
+    port (clk : in std_logic;
+          data_in : in std_logic_vector ( 0 to 7 );
+          int_in : in std_logic;
+
+          extended : out std_logic;
+          up : out std_logic;
+          code : out std_logic_vector ( 0 to 7 );
+          int : out std_logic );
+end entity keyboard;
+
+architecture keyboard of keyboard is
+  type state_type is ( waiting, end_state );
+  signal tmp_extended, tmp_up : std_logic;
+begin
+
+process (clk)
+  variable state : state_type := end_state;
+  variable old_int_in : std_logic := '0';
+begin
+  if(rising_edge(clk))
+  then
+    case state is
+      when end_state =>
+        state := waiting;
+        int <= '0';
+        tmp_extended <= '0';
+        tmp_up <= '0';
+      when waiting =>
+        if(int_in = '1' and old_int_in = '0')
+        then
+          case data_in is 
+            when "11100000" =>
+              tmp_extended <= '1';
+              state := waiting;
+            when "11110000" =>
+              tmp_up <= '1';
+              state := waiting;
+            when others =>
+              code <= data_in;
+              extended <= tmp_extended;
+              up <= tmp_up;
+              state := end_state;
+              int <= '1';
+          end case;
+        end if;
+    end case;
+
+    old_int_in := int_in;
+  end if;
+end process;
+
+end keyboard;
diff --git a/fpga/examples/pong/nexys2prog b/fpga/examples/pong/nexys2prog
new file mode 100755
index 0000000..89eb742
--- /dev/null
+++ b/fpga/examples/pong/nexys2prog
@@ -0,0 +1,345 @@
+#!/usr/bin/perl -w
+# Copyright 2009, Andrew Ross <an...@pl...>
+# Distributable under the terms of the GNU GPL licence version 2 or later.
+use strict;
+use POSIX qw(isatty);
+use Time::HiRes qw(usleep);
+
+# nexys2prog - program a Digilent Nexys 2 FPGA board over USB
+#
+# Usage: nexys2prog [-v|--verbose] <Bitstream File>
+#
+# This script automatically finds an attached Nexys 2 board and loads
+# it with the specified Xilinx bitstream with a minimum of fuss,
+# configuration, and external dependencies.  Specifically, the
+# hacked/patched firmware for the Cypress FX2 chip is stored inline.
+# The user only needs user-level software installed and a single local
+# configuration change (optional, for the USB device files -- the lazy
+# can just run the script as root).
+#
+# Prerequisites:
+#
+# 1. A working Xilinx ISE installation.  This was tested against 10.1,
+#    but I believe older versions share the same iMPACT syntax and
+#    BSDL file locations.
+#
+# 2. The "fxload" utility is required to reprogram the board's FX2 USB
+#    chip, available in Debian and Ubuntu via "apt-get install
+#    fxload".  Note that fxload requires write access to the raw USB
+#    device files under /dev/bus/usb, and that these are by default
+#    read-only on Ubuntu Intrepid.  You can either run the script as
+#    root, or else set the files to be owned by the "plugdev" group by
+#    adding the GROUP field to this line in
+#    /etc/udev/rules.d/40-basic-permissions.rules:
+#    SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="plugdev"
+#
+# 3. UrJTAG, available from http://urjtag.org.  UrJTAG is an active
+#    fork of the moribund openwince-jtag project.  Note that
+#    openwince-jtag is still an available Debian/Ubuntu package, that
+#    it shares the same "jtag" binary name and most of its syntax, and
+#    that IT DOES NOT WORK with the firmware in this script.  You need
+#    to install UrJTAG.  Also note that you will need libftdi
+#    installed for the protocol handler, again available on
+#    Debian/Ubuntu via "apt-get install libftdi1".  UrJTAG will build
+#    without this, but you won't be able to program the Nexys 2
+#    without libftdi.
+#
+# Note that this script contains a binary firmware blob built from
+# free software sources.  See the note above it for source
+# information.
+
+
+# TODO:
+# + Figure out the JTAG interface for the boot PROM, so it can be
+#   flashed with the bitstream instead of (or in addition to) doing a
+#   direct load to the FPGA.
+# + Pull down and parse the JTAG chain from the device to verify that
+#   it's actually a Nexys 2 and not another device sharing the same
+#   firmware family and bus ID.  Kolja's firmware runs on other
+#   devices too...
+# + Extend the script to recognize arbitrary JTAG chains and find the
+#   appropriate part number automatically.  So you'd just specify a
+#   .bit file (which contains the FPGA type) and it would crawl the
+#   JTAG bus looking for a matching FPGA to program.
+
+my $USBID_KOLJA = "16c0:06ad";
+my $USBID_DIGILENT = "1443:0005";
+my $XILINX;
+my $TMPID = sprintf("/tmp/nexys2prog-%8.8X-%4.4X", time(), $$);
+
+my $verbose = 0;
+my $filebase;
+my $bit;
+
+# Parse the command line
+while(@ARGV) {
+    my $arg = shift;
+    if($arg eq "-v" or $arg eq "--verbose") { $verbose = 1; }
+    elsif(!defined $bit and -f $arg and -R $arg) {
+	$bit = $arg;
+	$filebase = $bit;
+	$filebase =~ s/\.bit$//i;
+    } else { usage(); }
+}
+usage() if !defined $bit;
+
+# Find the tools
+check_tools();
+find_xilinx();
+
+# If needed, convert the .bit file to .svf using Xilinx's iMPACT tool.
+update_svf();
+
+# Locate and configure the board's USB interface
+find_board();
+
+# Do it
+play_svf();
+
+########################################################################
+
+sub usage { die "Usage:\n  $0 [-v|--verbose] <Bitstream File>\n"; }
+sub vlog { print join("", @_) if $verbose; }
+
+# Idiot-proofing, to help mitigate the Rube Goldbergisms inherent in
+# this process.
+sub check_tools {
+    system("which impact >/dev/null") == 0 or die
+	("Cannot find iMPACT executable.  The Xilinx ISE development kit\n".
+	 "must be installed and its settings32.sh script sourced in the\n".
+	 "current shell.\n");
+    system("which jtag >/dev/null") == 0 or die
+	("Cannot find jtag executable.  The UrJTAG tools (http://urjtag.org)\n".
+	 "must be built, installed, and on the PATH.  You will also need to\n".
+	 "install libftdi as a prerequisite: \"apt-get install libftdi-dev\" if\n".
+	 "needed.\n");
+    system("jtag --version | grep UrJTAG >/dev/null") == 0 or die
+	("Installed jtag executable is the wrong version.  You probably have the\n".
+	 "openwince-jtag tools installed.  The Nexys2 loader requires UrJTAG\n".
+	 "(http://urjtag.org) instead, which is a fork that, sadly, shares the\n".
+	 "same command names.  Uninstall the existing software, or (carefully!)\n".
+	 "install UrJTAG such that it lives before the old tool on your PATH.\n");
+}
+
+sub find_board {
+    my $nx = find_nexys2();
+    die "Cannot find a Nexys 2 board on the USB bus.  Plug it in?\n"
+	if(!defined $nx);
+    my ($bus, $dev, $id) = @$nx;
+    if($id ne $USBID_KOLJA) {
+	$dev = blasterize($bus, $dev);
+    } else {
+	vlog("Found already-configured board on bus $bus dev $dev\n");
+    }
+}
+
+sub update_svf {
+    my $svf = "$filebase.svf";
+    if((!-f $svf) or (stat($svf))[9] <= (stat($bit))[9]) {
+	vlog("Generating SVF file...\n");
+	my $impactrc = "$TMPID.impact";
+	open RC, ">$impactrc" or die "can't write to $TMPID.impact";
+	print RC "setMode -bs\n";
+	print RC "setCable -port svf -file $svf\n";
+	print RC "addDevice -p 1 -file $XILINX/xcf/data/xcf04s.bsd\n";
+	print RC "addDevice -p 2 -file $bit\n";
+	print RC "program -p 2\n";
+	print RC "closeCable\n";
+	print RC "quit\n";
+	close RC;
+	if($verbose) { system("sed 's/^/  /' $impactrc"); }
+	run("impact -batch $impactrc");
+	die "iMPACT failed to generate $svf" if ! -f $svf;
+    } else {
+	vlog("$svf is current, not regenerating.\n");
+    }
+}
+
+sub find_xilinx {
+    my $ise = `which impact`;
+    $ise = qx(cd `dirname $ise`; /bin/pwd);
+    chomp $ise;
+    die "Cannot find Xilinx ISE installation directory.\n"
+	if $ise !~ /ISE\/bin\/lin$/;
+    $ise =~ s/\/bin\/lin$//;
+    die "Cannot understand Xilinx ISE installation tree.\n"
+	if !-d "$ise/spartan3e/data" or !-f "$ise/xcf/data/xcf04s.bsd";
+    $XILINX = $ise;
+    vlog("Located Xilinx ISE installation in $XILINX.\n");
+}
+
+# Run an external tool, emitting the output only if it fails.  iMPACT
+# and UrJTAG are annoyingly verbose...
+sub run {
+    my $cmd = shift;
+    print($cmd, "\n") if $verbose;
+    open CMD, "$cmd 2>&1|" or die;
+    # FIXME: if the subprocess crashes (as jtag does without a cable),
+    # we get incomplete output...
+    my $out = join "", <CMD>;
+    close CMD;
+    die "Command failure:\n  $cmd\n\n$out" if $?;
+}
+
+sub find_nexys2 {
+    my ($bus, $dev, $id);
+    open LSUSB, "lsusb|" or die "Cannot run lsusb";
+    while(<LSUSB>) {
+	next if ! /Bus (\d+) Device (\d+): ID ([0-9a-f]{4}:[0-9a-f]{4})/;
+	next if !($3 eq $USBID_DIGILENT or $3 eq $USBID_KOLJA);
+	($bus, $dev, $id) = ($1, $2, $3);
+    }
+    close LSUSB;
+    if(defined $bus) {
+	vlog("Found USB device $id on bus $bus device $dev\n");
+	return [$bus, $dev, $id];
+    }
+    return undef;
+}
+
+# Reprogram a connected FX2 device with Kolja Waschk's usb_jtag
+# firmware, patched to support the Nexys 2 pin assignments and FPGA
+# bitstream sizes as per Morgan Delahaye's instructions at
+# http://m-del.net/info.html. Uses the fxload tool from the
+# linux-hotplug project.  The end result is an interface compatible
+# with the FTDI-based Altera USBBlaster product.
+sub blasterize {
+    my ($bus, $dev) = @_;
+    my $usbfile = "/dev/bus/usb/$bus/$dev";
+    if(!-w $usbfile) {
+	die ("Cannot write to $usbfile.\n\n" .
+	     "Either run this tool as root or modify your udev settings to\n" .
+	     "allow write access to USB device files.\n");
+    }
+    my $firmware = gen_fx2();
+    vlog("Loading 8051 firmware into board...\n");
+    run("/sbin/fxload -t fx2 -D $usbfile -I $firmware");
+    my $nx;
+    # Wait for it to reboot, renumerate and appear on the bus.
+    for(my $i=0; $i<20; $i++) {
+	usleep 10000;
+	last if defined($nx = find_nexys2()) and $nx->[2] eq $USBID_KOLJA;
+    }
+    if(!defined $nx or $nx->[2] ne $USBID_KOLJA) {
+	die ("Reprogrammed FX2 device not found on USB bus.\n",
+	     "fxload failure? device unplugged? ... !?\n");
+    }
+    return $nx->[1];
+}
+
+sub play_svf {
+    open JTAG, ">$TMPID.jtag" or die "cannot write to $TMPID.jtag";
+    # Just the BSDL directories needed for the 2 chips on the Nexys2...
+    print JTAG "bsdl path $XILINX/spartan3e/data;$XILINX/xcf/data\n";
+    print JTAG "cable usbblaster\n";
+    print JTAG "detect\n";
+    print JTAG "part 1\n";
+    print JTAG "svf $filebase.svf\n";
+    print JTAG "quit\n";
+    close JTAG;
+    run("jtag $TMPID.jtag");
+}
+
+
+# Firmware for the FX2 chip
+# Original source (GPLv2) -- http://www.ixo.de/info/usb_jtag
+# Modifications:
+#   hw_nexys.c     -- http://www.m-del.net/files/nexys/hw_nexys2.c
+#   bit_fpga.patch -- http://www.m-del.net/files/nexys/big_fpga.patch
+# It was built with the sdcc-nf ("non-free") compiler from Ubuntu 8.10
+# multiverse, and the resulting Intel hex file was filtered through
+# bzip2 and then base64 to produce the string below.
+sub gen_fx2 {
+    my $filename = "$TMPID.fx2";
+    vlog("Unpacking FX2 firmware to $filename\n");
+    open FX2, "|base64 -d | bzip2 -d > $filename"
+	or die "cannot write to $filename";
+    print FX2 <<__EOF__
+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
+__EOF__
+;
+    close FX2;
+    return $filename;
+}
+
diff --git a/fpga/examples/pong/pong.ucf b/fpga/examples/pong/pong.ucf
new file mode 100644
index 0000000..785eb95
--- /dev/null
+++ b/fpga/examples/pong/pong.ucf
@@ -0,0 +1,56 @@
+# NET "sw<0>" LOC= "G18";
+# NET "sw<1>" LOC= "H18";
+# NET "sw<2>" LOC= "K18";
+# NET "sw<3>" LOC= "K17";
+# NET "sw<4>" LOC= "L14";
+# NET "sw<5>" LOC= "L13";
+# NET "sw<6>" LOC= "N17";
+# NET "sw<7>" LOC= "R17";
+
+# NET "btn<0>" LOC= "B18"; # Bank = 1 , Pin name = IP , Type = INPUT , Sch name = BTN0
+# NET "btn<1>" LOC= "D18"; # Bank = 1 , Pin name = IP/VREF_1 , Type = VREF , Sch name = BTN1
+# NET "btn<2>" LOC= "E18"; # Bank = 1 , Pin name = IP , Type = INPUT , Sch name = BTN2
+# NET "btn<3>" LOC= "H13"; # Bank = 1 , Pin name = IP , Type = INPUT , Sch name = BTN3
+
+# Pin assignment for Leds 
+# Connected to Nexys 2 
+NET "Led<0>" LOC= "J14"; # Bank = 1 , Pin name = IO_L14N_1/A3/RHCLK7 , Type = RHCLK/DUAL , Sch name = JD10/LD0
+NET "Led<1>" LOC= "J15"; # Bank = 1 , Pin name = IO_L14P_1/A4/RHCLK6 , Type = RHCLK/DUAL , Sch name = JD9/LD1
+NET "Led<2>" LOC= "K15"; # Bank = 1 , Pin name = IO_L12P_1/A8/RHCLK2 , Type = RHCLK/DUAL , Sch name = JD8/LD2 
+NET "Led<3>" LOC= "K14"; # Bank = 1 , Pin name = IO_L12N_1/A7/RHCLK3/TRDY1 , Type = RHCLK/DUAL , Sch name = JD7/LD3 
+NET "Led<4>" LOC= "E16"; # Bank = 1 , Pin name = N.C. , Type = N.C. , Sch name = LD4? other than s3e500
+NET "Led<5>" LOC= "P16"; # Bank = 1 , Pin name = N.C. , Type = N.C. , Sch name = LD5? other than s3e500
+NET "Led<6>" LOC= "E4"; # Bank = 3 , Pin name = N.C. , Type = N.C. , Sch name = LD6? other than s3e500
+NET "Led<7>" LOC= "P4"; # Bank = 3 , Pin name = N.C. , Type = N.C. , Sch name = LD7? other than s3e500
+
+ NET "seg<0>" LOC= "L18"; # Bank = 1 , Pin name = IO_L10P_1 , Type = I/O , Sch name = CA
+ NET "seg<1>" LOC= "F18"; # Bank = 1 , Pin name = IO_L19P_1 , Type = I/O , Sch name = CB
+ NET "seg<2>" LOC= "D17"; # Bank = 1 , Pin name = IO_L23P_1/HDC , Type = DUAL , Sch name = CC
+ NET "seg<3>" LOC= "D16"; # Bank = 1 , Pin name = IO_L23N_1/LDC0 , Type = DUAL , Sch name = CD
+ NET "seg<4>" LOC= "G14"; # Bank = 1 , Pin name = IO_L20P_1 , Type = I/O , Sch name = CE
+ NET "seg<5>" LOC= "J17"; # Bank = 1 , Pin name = IO_L13P_1/A6/RHCLK4/IRDY1 , Type = RHCLK/DUAL , Sch name = CF
+ NET "seg<6>" LOC= "H14"; # Bank = 1 , Pin name = IO_L17P_1 , Type = I/O , Sch name = CG
+ NET "dp" LOC= "C17"; # Bank = 1 , Pin name = IO_L24N_1/LDC2 , Type = DUAL , Sch name = DP
+
+ NET "an<0>" LOC= "F17"; # Bank = 1 , Pin name = IO_L19N_1 , Type = I/O , Sch name = AN0
+ NET "an<1>" LOC= "H17"; # Bank = 1 , Pin name = IO_L16N_1/A0 , Type = DUAL , Sch name = AN1
+ NET "an<2>" LOC= "C18"; # Bank = 1 , Pin name = IO_L24P_1/LDC1 , Type = DUAL , Sch name = AN2
+ NET "an<3>" LOC= "F15"; # Bank = 1 , Pin name = IO_L21P_1 , Type = I/O , Sch name = AN3
+
+NET "clk" LOC= "B8"; # Bank = 0 , Pin name = IP_L13P_0/GCLK8 , Type = GCLK , Sch name = GCLK0
+
+NET "PS2C" LOC= "R12" | PULLUP; # Bank = 2 , Pin name = IO_L20N_2 , Type = I/O , Sch name = PS2C
+NET "PS2D" LOC= "P11" | PULLUP; # Bank = 2 , Pin name = IO_L18P_2 , Type = I/O , Sch name = PS2D
+
+ NET "vga_out<0>" LOC= "R9"; # Bank = 2 , Pin name = IO/D5 , Type = DUAL , Sch name = RED0
+ NET "vga_out<1>" LOC= "T8"; # Bank = 2 , Pin name = IO_L10N_2 , Type = I/O , Sch name = RED1
+ NET "vga_out<2>" LOC= "R8"; # Bank = 2 , Pin name = IO_L10P_2 , Type = I/O , Sch name = RED2
+ NET "vga_out<3>" LOC= "N8"; # Bank = 2 , Pin name = IO_L09N_2 , Type = I/O , Sch name = GRN0
+ NET "vga_out<4>" LOC= "P8"; # Bank = 2 , Pin name = IO_L09P_2 , Type = I/O , Sch name = GRN1
+ NET "vga_out<5>" LOC= "P6"; # Bank = 2 , Pin name = IO_L05N_2 , Type = I/O , Sch name = GRN2
+ NET "vga_out<6>" LOC= "U5"; # Bank = 2 , Pin name = IO/VREF_2 , Type = VREF , Sch name = BLU1
+ NET "vga_out<7>" LOC= "U4"; # Bank = 2 , Pin name = IO_L03P_2/DOUT/BUSY , Type = DUAL , Sch name = BLU2
+ 
+ NET "Hsync" LOC= "T4" | PULLUP; # Bank = 2 , Pin name = IO_L03N_2/MOSI/CSI_B , Type = DUAL , Sch name = HSYNC
+ NET "Vsync" LOC= "U3" | PULLUP; # Bank = 2 , Pin name = IO_L01P_2/CSO_B , Type = DUAL , Sch name = VSYNC
+
diff --git a/fpga/examples/pong/pong.vhd b/fpga/examples/pong/pong.vhd
new file mode 100644
index 0000000..e41641e
--- /dev/null
+++ b/fpga/examples/pong/pong.vhd
@@ -0,0 +1,211 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+
+entity pong is
+    port (
+    clk : in std_logic;
+
+--    btn : in  std_logic_vector(3 downto 0);
+    Led : out std_logic_vector(7 downto 0);
+--    usb : in std_logic;
+--    sw : in std_logic_vector(7 downto 0);
+
+    seg : out std_logic_vector(6 downto 0);
+    dp : out std_logic;
+    an : out std_logic_vector(3 downto 0);
+
+    ps2c : in std_logic;
+    ps2d : in std_logic;
+
+    vga_out : out std_logic_vector(7 downto 0);
+    hsync : out std_logic;
+    vsync : out std_logic
+    );
+end entity pong;
+
+architecture pong of pong is
+
+  component draw is
+    generic (
+      size_x : positive := 400;
+      size_y : positive := 400
+      );
+    port (
+      update : in std_logic;
+      x_pos : in  integer range 0 to 639;
+      y_pos : in  integer range 0 to 479;
+      ball_x : in integer range 0 to size_x - 1;
+      ball_y : in integer range 0 to size_y - 1;
+      color : out std_logic_vector (7 downto 0));
+  end component;
+
+  component vga is
+  port(clk : in std_logic;
+       hsync : out std_logic;
+       vsync : out std_logic;
+       active : out std_logic;
+       pixel_clk : out std_logic;
+       x_pos : out integer range 0 to 639;
+       y_pos : out integer range 0 to 479
+       );
+  end component;
+
+  component driver_ps2 is
+    port (clk : in std_logic;
+          ps2d : in std_logic;
+          ps2c : in std_logic;
+          data : out std_logic_vector ( 0 to 7 );
+          int : out std_logic );
+  end component;
+
+  component keyboard is
+    port (clk : in std_logic;
+          data_in : in std_logic_vector ( 0 to 7 );
+          int_in : in std_logic;
+          extended : out std_logic;
+          up : out std_logic;
+          code : out std_logic_vector ( 0 to 7 );
+          int : out std_logic );
+  end component;
+
+  component simple_7seg is
+    port(clk : in  std_logic;
+         value : in std_logic_vector (15 downto 0);
+         pti : in std_logic_vector(3 downto 0);
+         seg : out std_logic_vector(6 downto 0);
+         pto : out std_logic;
+         an : out std_logic_vector(3 downto 0) );
+  end component;
+
+  component game is
+    generic (
+      size_x : positive := 400;
+      size_y : positive := 400);
+    port (
+    clk : in std_logic;
+    scan_code : in std_logic_vector ( 7 downto 0 );
+    up_key : in std_logic;
+    extended_key : in std_logic;
+    key_int : in std_logic;
+    ball_x : out integer range 0 to size_x - 1;
+    ball_y : out integer range 0 to size_y - 1;
+    keys : out std_logic_vector ( 3 downto 0 )
+    );
+  end component;
+
+  constant size_x : integer := 400;
+  constant size_y : integer := 400;
+
+  signal vga_color : std_logic_vector ( 7 downto 0 );
+  signal internal_vsync : std_logic;
+  signal vga_x : integer range 0 to 639;
+  signal vga_y : integer range 0 to 479;
+
+  signal active_output : std_logic;
+  signal pixel_clk : std_logic;
+
+-- ps2 keyboard signals
+  signal ps2_data : std_logic_vector ( 7 downto 0 );
+  signal scan_code : std_logic_vector ( 7 downto 0 );
+  signal ps2_int : std_logic;
+  signal key_up : std_logic;
+  signal key_extended : std_logic;
+  signal key_int : std_logic;
+
+  signal slow_clk : std_logic;
+  signal value_7seg : std_logic_vector ( 15 downto 0 );
+  signal point_7seg : std_logic_vector ( 3 downto 0 );
+
+-- game data
+  signal ball_x : integer range 0 to size_x - 1;
+  signal ball_y : integer range 0 to size_y - 1;
+begin
+
+  vsync <= internal_vsync;
+  vga_out <= vga_color;
+
+  draw_1 : draw
+    generic map
+    (
+      size_x,
+      size_y
+      )
+    port map
+    ( internal_vsync,
+      vga_x,
+      vga_y,
+      ball_x,
+      ball_y,
+      vga_color
+      );
+
+  game_1 : game
+    generic map (
+      size_x,
+      size_y)
+    port map (
+    clk,
+    scan_code,
+    key_up,
+    key_extended,
+    key_int,
+    ball_x,
+    ball_y,
+    led ( 3 downto 0 )
+    );
+
+  led ( 7 downto 4 ) <= "0000";
+
+  vga_1 : vga port map
+    ( clk,
+      hsync,
+      internal_vsync,
+      active_output,
+      pixel_clk,
+      vga_x,
+      vga_y
+      );
+
+  driver_ps2_1 : driver_ps2 port map
+    ( clk,
+      ps2d,
+      ps2c,
+      ps2_data,
+      ps2_int
+      );
+
+  keyboard_1 : keyboard port map
+    ( clk,
+      ps2_data,
+      ps2_int,
+      key_extended,
+      key_up,
+      scan_code,
+      key_int
+      );
+
+  simple_7seg_1 : simple_7seg port map
+    ( slow_clk,
+      value_7seg,
+      point_7seg,
+      seg,
+      dp,
+      an
+      );
+
+
+  process (clk)
+    variable count : integer range 0 to 65535 := 0;
+    variable tmp_std : std_logic_vector ( 15 downto 0 );
+  begin
+    if rising_edge(clk) then
+      count := count + 1;
+    end if;
+    tmp_std := conv_std_logic_vector(count,16);
+    slow_clk <= tmp_std(15);
+  end process;
+
+end architecture;
+
diff --git a/fpga/examples/pong/ps2.vhd b/fpga/examples/pong/ps2.vhd
new file mode 100644
index 0000000..1981c56
--- /dev/null
+++ b/fpga/examples/pong/ps2.vhd
@@ -0,0 +1,95 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+entity driver_ps2 is
+    port (clk : in std_logic;
+          ps2d : in std_logic;
+          ps2c : in std_logic;
+          data : out std_logic_vector ( 0 to 7 );
+          int : out std_logic );
+end entity driver_ps2;
+
+architecture driver_ps2 of driver_ps2 is
+type state_type is ( bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7,
+                     bit8, bit9, end_state, error_state );
+signal tmp : std_logic_vector ( 8 downto 1 ) := "00000000";
+signal state : state_type := bit0;
+signal int_l : std_logic := '0';
+signal data_l : std_logic_vector ( 0 to 7 ) := "00000000";
+signal ps2_clk : std_logic := '1';
+signal ps2_data : std_logic := '1';
+begin
+
+process (clk)
+begin
+  if (rising_edge(clk)) then
+    ps2_clk <= ps2c;
+  end if;
+end process;
+
+process (clk)
+begin
+  if (rising_edge(clk)) then
+    ps2_data <= ps2d;
+  end if;
+end process;
+
+int <= int_l;
+data <= data_l;
+
+process (ps2_clk)
+begin
+  if (falling_edge(ps2_clk))
+  then
+    case state is
+      when bit0 =>
+        if ps2_data = '0'
+        then state <= bit1;
+        else state <= error_state;
+        end if;
+      when bit1 =>
+        state <=  bit2;
+        tmp(1) <= ps2_data;
+      when bit2 =>
+        state <=  bit3;
+        tmp(2) <= ps2_data;
+      when bit3 =>
+        state <=  bit4;
+        tmp(3) <= ps2_data;
+      when bit4 =>
+        state <=  bit5;
+        tmp(4) <= ps2_data;
+      when bit5 =>
+        state <=  bit6;
+        tmp(5) <= ps2_data;
+      when bit6 =>
+        state <=  bit7;
+        tmp(6) <= ps2_data;
+      when bit7 =>
+        state <=  bit8;
+        tmp(7) <= ps2_data;
+      when bit8 =>
+        state <= bit9;
+        tmp(8) <= ps2_data;
+      when bit9 =>
+        state <= end_state;
+        -- tmp(9) <= ps2_data;
+        -- should verify parity
+        int_l <= '1';
+        data_l <= tmp(8 downto 1);
+      when end_state =>
+        int_l <= '0';
+        if ps2_data = '1'
+        then state <= bit0;
+        else state <= error_state;
+        end if;
+      when error_state =>
+        state <= error_state;
+        -- should make something to recover
+    end case;
+
+  end if;
+end process;
+
+end driver_ps2;
diff --git a/fpga/examples/pong/simple_7seg.vhd b/fpga/examples/pong/simple_7seg.vhd
new file mode 100644
index 0000000..32bdc6d
--- /dev/null
+++ b/fpga/examples/pong/simple_7seg.vhd
@@ -0,0 +1,97 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+package decoder is
+
+  function decoder (
+    signal val : std_logic_vector (3 downto 0))
+    return std_logic_vector;
+
+end decoder;
+
+package body decoder is
+
+  function decoder (signal val : std_logic_vector(3 downto 0))
+    return std_logic_vector is
+    variable tmp : std_logic_vector ( 6 downto 0 );
+  begin
+    case val is
+      when "0000" => tmp := "0111111";
+      when "0001" => tmp := "0000110";
+      when "0010" => tmp := "1011011";
+      when "0011" => tmp := "1001111";
+      when "0100" => tmp := "1100110";
+      when "0101" => tmp := "1101101";
+      when "0110" => tmp := "1111101";
+      when "0111" => tmp := "0000111";
+      when "1000" => tmp := "1111111";
+      when "1001" => tmp := "1101111";
+      when "1010" => tmp := "1110111";
+      when "1011" => tmp := "1111100";
+      when "1100" => tmp := "0111001";
+      when "1101" => tmp := "1011110";
+      when "1110" => tmp := "1111001";
+      when "1111" => tmp := "1110001";
+      when others => tmp := "0000000"; -- shouldn't happen
+    end case;
+    return (not tmp);
+  end function decoder;  
+
+end decoder;
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+use work.decoder.ALL;
+
+entity simple_7seg is
+  port(clk : in  std_logic;
+       value : in std_logic_vector (15 downto 0);
+       pti : in std_logic_vector(3 downto 0);
+       seg : out std_logic_vector(6 downto 0);
+       pto : out std_logic;
+       an : out std_logic_vector(3 downto 0) );
+end simple_7seg;
+
+architecture simple_7seg of simple_7seg is
+signal selected_value : std_logic_vector ( 3 downto 0 );
+begin
+
+seg <= decoder(selected_value);
+  
+process (clk)
+  variable state : std_logic_vector (3 downto 0) := "0111";
+  variable out_value : std_logic_vector (3 downto 0) := "0000";
+  variable out_pt : std_logic;
+begin
+  if rising_edge(clk) then
+    case state is
+      when "0111" =>
+        state := "1011";
+        out_value := value (15 downto 12);
+        out_pt := pti(3);
+      when "1011" =>
+        state := "1101";
+        out_value := value (11 downto 8);
+        out_pt := pti(2);
+      when "1101" =>
+        state := "1110";
+        out_value := value (7 downto 4);
+        out_pt := pti(1);
+      when others =>
+        state := "0111";
+        out_value := value (3 downto 0);
+        out_pt := pti(0);
+    end case;
+  end if;
+  an <= state;
+  selected_value <= out_value;
+  pto <= not out_pt;
+end process;
+  
+end simple_7seg;
diff --git a/fpga/examples/pong/vga.vhd b/fpga/examples/pong/vga.vhd
new file mode 100644
index 0000000..9d6a2f8
--- /dev/null
+++ b/fpga/examples/pong/vga.vhd
@@ -0,0 +1,124 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity vga is
+  port(clk : in std_logic;
+       hsync : out std_logic;
+       vsync : out std_logic;
+       active : out std_logic;
+       pixel_clk : out std_logic;
+       x_pos : out integer range 0 to 639;
+       y_pos : out integer range 0 to 479
+       );
+end vga;
+
+architecture vga of vga is
+  signal internal_hsync : std_logic;
+  signal internal_vsync : std_logic;
+  signal internal_pixel_clk : std_logic;
+  signal h_active : std_logic;
+  signal v_active : std_logic;
+
+begin
+
+  pixel_clk <= internal_pixel_clk;
+  hsync <= internal_hsync;
+  vsync <= internal_vsync;
+  active <= '1' when ( h_active = '1' ) and ( v_active = '1' ) else '0';
+
+  pixel_clock: process (clk)
+    variable tmp : std_logic := '0';
+  begin
+    if rising_edge(clk) then
+      tmp := not tmp;
+    end if;
+    internal_pixel_clk <= tmp;
+  end process pixel_clock;
+
+  h_pixel_counter : process (internal_pixel_clk)
+    constant line_length : integer := 800;
+    constant pulse_length : integer := 96;
+    constant front_porch : integer := 16;
+    constant back_porch : integer := 48;
+    variable counter : integer range 0 to line_length + 1 := 0;
+    variable sync_state : std_logic := '1';
+    variable h_state : std_logic := '0';
+    variable x_pos_v : integer range 0 to 640 := 0;
+  begin
+    if (rising_edge(internal_pixel_clk))
+    then
+      if counter = 0 then
+        sync_state := '0';
+        x_pos_v := 0;
+      end if;
+      if counter = pulse_length then
+        sync_state := '1';
+      end if;
+
+      if h_state = '1' then
+        x_pos_v := x_pos_v + 1;
+      end if;
+
+      if counter = front_porch + pulse_length then
+        h_state := '1';
+      end if;
+      if counter = line_length - back_porch then
+        h_state := '0';
+      end if;
+      
+      counter := counter + 1;
+      if counter = line_length then
+        counter := 0;
+      end if;
+    end if;
+    
+    internal_hsync <= sync_state;
+    h_active <= h_state;
+    x_pos <= x_pos_v;
+  end process h_pixel_counter;
+
+  v_pixel_counter : process (internal_hsync)
+    constant line_length : integer := 521;
+    constant pulse_length : integer := 2;
+    constant front_porch : integer := 10;
+    constant back_porch : integer := 29;
+    variable counter : integer range 0 to line_length + 1 := 0;
+    variable sync_state : std_logic := '1';
+    variable v_state : std_logic := '0';
+    variable y_pos_v : integer range 0 to 480 := 0;
+  begin
+    if (falling_edge(internal_hsync))
+    then
+      if counter = 0 then
+        sync_state := '0';
+        y_pos_v := 0;
+      end if;
+      if counter = pulse_length then
+        sync_state := '1';
+      end if;
+
+      if v_state = '1' then
+        y_pos_v := y_pos_v + 1;
+      end if;
+
+      if counter = pulse_length + front_porch then
+        v_state := '1';
+      end if;
+      if counter = line_length - back_porch then
+        v_state := '0';
+      end if;
+
+      counter := counter + 1;
+      if counter = line_length then
+        counter := 0;
+      end if;
+    end if;
+
+    internal_vsync <= sync_state;
+    v_active <= v_state;
+    y_pos <= y_pos_v;
+  end process v_pixel_counter;
+
+end vga;
hooks/post-receive
-- 
krobot-resources
 |