summaryrefslogtreecommitdiffstats
path: root/lab4
diff options
context:
space:
mode:
Diffstat (limited to 'lab4')
-rw-r--r--lab4/KBD_ENC.vhd277
-rw-r--r--lab4/Makefile68
-rw-r--r--lab4/Nexys3.ucf29
-rw-r--r--lab4/PICT_MEM.vhd58
-rw-r--r--lab4/VGA_MOTOR/Makefile68
-rw-r--r--lab4/VGA_MOTOR/Nexys3.ucf29
-rw-r--r--lab4/VGA_MOTOR/VGA_MOTOR.vhd447
-rw-r--r--lab4/VGA_MOTOR/VGA_lab.vhd70
-rw-r--r--lab4/VGA_MOTOR/VGA_lab_tb.vhd50
-rw-r--r--lab4/VGA_MOTOR/build/dc_synthesize.tcl95
-rw-r--r--lab4/VGA_MOTOR/build/design_compiler.mk30
-rw-r--r--lab4/VGA_MOTOR/build/digilentprog.mk6
-rw-r--r--lab4/VGA_MOTOR/build/precision-xilinx.mk59
-rw-r--r--lab4/VGA_MOTOR/build/util.mk59
-rw-r--r--lab4/VGA_MOTOR/build/vsim.mk61
-rw-r--r--lab4/VGA_MOTOR/build/xilinx-par.mk137
-rw-r--r--lab4/VGA_MOTOR/build/xst.mk130
-rw-r--r--lab4/VGA_MOTOR/sanitycheck21
-rw-r--r--lab4/VGA_MOTOR/sanitycheck.sh21
-rw-r--r--lab4/VGA_lab.vhd91
-rw-r--r--lab4/VGA_lab_tb.vhd111
-rw-r--r--lab4/build/dc_synthesize.tcl95
-rw-r--r--lab4/build/design_compiler.mk30
-rw-r--r--lab4/build/digilentprog.mk6
-rw-r--r--lab4/build/precision-xilinx.mk59
-rw-r--r--lab4/build/util.mk59
-rw-r--r--lab4/build/vsim.mk61
-rw-r--r--lab4/build/xilinx-par.mk137
-rw-r--r--lab4/build/xst.mk130
-rw-r--r--lab4/sanitycheck21
-rw-r--r--lab4/sanitycheck.sh21
31 files changed, 2536 insertions, 0 deletions
diff --git a/lab4/KBD_ENC.vhd b/lab4/KBD_ENC.vhd
new file mode 100644
index 0000000..6d4a0ab
--- /dev/null
+++ b/lab4/KBD_ENC.vhd
@@ -0,0 +1,277 @@
+--------------------------------------------------------------------------------
+-- KBD ENC
+-- Anders Nilsson
+-- 16-feb-2016
+-- Version 1.1
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+ -- and various arithmetic operations
+
+-- entity
+entity KBD_ENC is
+ port ( clk : in std_logic; -- system clock (100 MHz)
+ rst : in std_logic; -- reset signal
+ PS2KeyboardCLK : in std_logic; -- USB keyboard PS2 clock
+ PS2KeyboardData : in std_logic; -- USB keyboard PS2 data
+ data : out std_logic_vector(7 downto 0); -- tile data
+ addr : out unsigned(10 downto 0); -- tile address
+ we : out std_logic); -- write enable
+end KBD_ENC;
+
+-- architecture
+architecture behavioral of KBD_ENC is
+ signal PS2Clk : std_logic; -- Synchronized PS2 clock
+ signal PS2Data : std_logic; -- Synchronized PS2 data
+ signal PS2Clk_Q1, PS2Clk_Q2 : std_logic; -- PS2 clock one pulse flip flop
+ signal PS2Clk_op : std_logic; -- PS2 clock one pulse
+
+ signal PS2Data_sr : std_logic_vector(10 downto 0);-- PS2 data shift register
+
+ signal PS2BitCounter : unsigned(3 downto 0); -- PS2 bit counter
+ signal make_Q : std_logic; -- make one pulselse flip flop
+ signal make_op : std_logic; -- make one pulse
+
+ type state_type is (IDLE, MAKE, BREAK); -- declare state types for PS2
+ signal PS2state : state_type; -- PS2 state
+
+ signal ScanCode : std_logic_vector(7 downto 0); -- scan code
+ signal TileIndex : std_logic_vector(7 downto 0); -- tile index
+
+ type curmov_type is (FORWARD, BACKWARD, NEWLINE); -- declare cursor movement types
+ signal curMovement : curmov_type; -- cursor movement
+
+ signal curposX : unsigned(5 downto 0); -- cursor X position
+ signal curposY : unsigned(4 downto 0); -- cursor Y position
+
+ type wr_type is (STANDBY, WRINDEX, WRCUR); -- declare state types for write cycle
+ signal WRstate : wr_type; -- write cycle state
+
+begin
+
+ -- Synchronize PS2-KBD signals
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ PS2Clk <= PS2KeyboardCLK;
+ PS2Data <= PS2KeyboardData;
+ end if;
+ end process;
+
+
+ -- Generate one cycle pulse from PS2 clock, negative edge
+
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst='1' then
+ PS2Clk_Q1 <= '1';
+ PS2Clk_Q2 <= '0';
+ else
+ PS2Clk_Q1 <= PS2Clk;
+ PS2Clk_Q2 <= not PS2Clk_Q1;
+ end if;
+ end if;
+ end process;
+
+ PS2Clk_op <= (not PS2Clk_Q1) and (not PS2Clk_Q2);
+
+
+
+ -- PS2 data shift register
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * PS2_data_shift_reg *
+ -- * *
+ -- ***********************************
+
+
+
+
+ ScanCode <= PS2Data_sr(8 downto 1);
+
+ -- PS2 bit counter
+ -- The purpose of the PS2 bit counter is to tell the PS2 state machine when to change state
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * PS2_bit_Counter *
+ -- * *
+ -- ***********************************
+
+
+
+
+ -- PS2 state
+ -- Either MAKE or BREAK state is identified from the scancode
+ -- Only single character scan codes are identified
+ -- The behavior of multiple character scan codes is undefined
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * PS2_State *
+ -- * *
+ -- ***********************************
+
+
+
+
+ -- Scan Code -> Tile Index mapping
+ with ScanCode select
+ TileIndex <= x"00" when x"29", -- space
+ x"01" when x"1C", -- A
+ x"02" when x"32", -- B
+ x"03" when x"21", -- C
+ x"04" when x"23", -- D
+ x"05" when x"24", -- E
+ x"06" when x"2B", -- F
+ x"07" when x"34", -- G
+ x"08" when x"33", -- H
+ x"09" when x"43", -- I
+ x"0A" when x"3B", -- J
+ x"0B" when x"42", -- K
+ x"0C" when x"4B", -- L
+ x"0D" when x"3A", -- M
+ x"0E" when x"31", -- N
+ x"0F" when x"44", -- O
+ x"10" when x"4D", -- P
+ x"11" when x"15", -- Q
+ x"12" when x"2D", -- R
+ x"13" when x"1B", -- S
+ x"14" when x"2C", -- T
+ x"15" when x"3C", -- U
+ x"16" when x"2A", -- V
+ x"17" when x"1D", -- W
+ x"18" when x"22", -- X
+ x"19" when x"35", -- Y
+ x"1A" when x"1A", -- Z
+ x"1B" when x"54", -- Ć
+ x"1C" when x"52", -- Ä
+ x"1D" when x"4C", -- Ö
+ x"00" when others;
+
+
+ -- set cursor movement based on scan code
+ with ScanCode select
+ curMovement <= NEWLINE when x"5A", -- enter scancode (5A), so move cursor to next line
+ BACKWARD when x"66", -- backspace scancode (66), so move cursor backward
+ FORWARD when others; -- for all other scancodes, move cursor forward
+
+
+ -- curposX
+ -- update cursor X position based on current cursor position (curposX and curposY) and cursor
+ -- movement (curMovement)
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst='1' then
+ curposX <= (others => '0');
+ elsif (WRstate = WRINDEX) then
+ if (curMovement = FORWARD) then
+ if (curposX = 19) then
+ curposX <= (others => '0');
+ else
+ curposX <= curposX + 1;
+ end if;
+ elsif (curMovement = BACKWARD) then
+ if ((curposX = 0) and (curposY >= 0)) then
+ curposX <= to_unsigned(19, curposX'length);
+ else
+ curposX <= curposX - 1;
+ end if;
+ elsif (curMovement = NEWLINE) then
+ curposX <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ -- curposY
+ -- update cursor Y position based on current cursor position (curposX and curposY) and cursor
+ -- movement (curMovement)
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst='1' then
+ curposY <= (others => '0');
+ elsif (WRstate = WRINDEX) then
+ if (curMovement = FORWARD) then
+ if (curposX = 19) then
+ if (curposY = 14) then
+ curposY <= (others => '0');
+ else
+ curposY <= curposY + 1;
+ end if;
+ end if;
+ elsif (curMovement = BACKWARD) then
+ if (curposX = 0) then
+ if (curposY = 0) then
+ curposY <= to_unsigned(14, curposY'length);
+ else
+ curposY <= curposY - 1;
+ end if;
+ end if;
+ elsif (curMovement = NEWLINE) then
+ if (curposY = 14) then
+ curposY <= (others => '0');
+ else
+ curposY <= curposY + 1;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ -- write state
+ -- every write cycle begins with writing the character tile index at the current
+ -- cursor position, then moving to the next cursor position and there write the
+ -- cursor tile index
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst='1' then
+ WRstate <= STANDBY;
+ else
+ case WRstate is
+ when STANDBY =>
+ if (PS2state = MAKE) then
+ WRstate <= WRINDEX;
+ else
+ WRstate <= STANDBY;
+ end if;
+ when WRINDEX =>
+ WRstate <= WRCUR;
+ when WRCUR =>
+ WRstate <= STANDBY;
+ when others =>
+ WRstate <= STANDBY;
+ end case;
+ end if;
+ end if;
+ end process;
+
+
+ -- we will be enabled ('1') for two consecutive clock cycles during WRINDEX and WRCUR states
+ -- and disabled ('0') otherwise at STANDBY state
+ we <= '0' when (WRstate = STANDBY) else '1';
+
+
+ -- memory address is a composite of curposY and curposX
+ -- the "to_unsigned(20, 6)" is needed to generate a correct size of the resulting unsigned vector
+ addr <= to_unsigned(20, 6)*curposY + curposX;
+
+
+ -- data output is set to be x"1F" (cursor tile index) during WRCUR state, otherwise set as scan code tile index
+ data <= x"1F" when (WRstate = WRCUR) else TileIndex;
+
+
+end behavioral;
diff --git a/lab4/Makefile b/lab4/Makefile
new file mode 100644
index 0000000..b2c4161
--- /dev/null
+++ b/lab4/Makefile
@@ -0,0 +1,68 @@
+# Makefile for hardware implementation on Xilinx FPGAs and ASICs
+# Author: Andreas Ehliar <ehliar@isy.liu.se>
+#
+# T is the testbench file for this project
+# S is the synthesizable sources for this project
+# U is the UCF file
+# PART is the part
+
+# Important makefile targets:
+# make lab.sim GUI simulation
+# make lab.simc batch simulation
+# make lab.synth Synthesize
+# make lab.route Route the design
+# make lab.bitgen Generate bit file
+# make lab.timing Generate timing report
+# make lab.clean Use whenever you change settings in the Makefile!
+# make lab.prog Downloads the bitfile to the FPGA. NOTE: Does not
+# rebuild bitfile if source files have changed!
+# make clean Removes all generated files for all projects. Also
+# backup files (*~) are removed.
+#
+# VIKTIG NOTERING: Om du Àndrar vilka filer som finns med i projektet sÄ mÄste du köra
+# make lab.clean
+#
+# Syntesrapporten ligger i lab-synthdir/xst/synth/design.syr
+# Maprapporten (bra att kolla i för arearapportens skull) ligger i lab-synthdir/layoutdefault/design_map.mrp
+# Timingrapporten (skapas av make lab.timing) ligger i lab-synthdir/layoutdefault/design.trw
+
+# (Or proj2.simc, proj2.sim, etc, depending on the name of the
+# project)
+
+XILINX_INIT = source /opt/xilinx_ise/14.7/settings64.sh;
+PART=xc6slx16-3-csg324
+
+
+VGA_lab.%: S=VGA_lab.vhd KBD_ENC.vhd PICT_MEM.vhd VGA_MOTOR/VGA_MOTOR.vhd
+VGA_lab.%: T=VGA_lab_tb.vhd
+VGA_lab.%: U=Nexys3.ucf
+
+
+# Det hÀr Àr ett exempel pÄ hur man kan skriva en testbÀnk som Àr
+# relevant, Àven om man kör en simulering i batchlÀge (make batchlab.simc)
+#batchlab.%: S=lab.vhd leddriver.vhd
+#batchlab.%: T=batchlab_tb.vhd tb_print7seg.vhd
+#batchlab.%: U=lab.ucf
+
+
+# Misc functions that are good to have
+include build/util.mk
+# Setup simulation environment
+include build/vsim.mk
+# Setup synthesis environment
+include build/xst.mk
+# Setup backend flow environment
+include build/xilinx-par.mk
+# Setup tools for programming the FPGA
+include build/digilentprog.mk
+
+
+
+# Alternative synthesis methods
+# The following is for ASIC synthesis
+#include design_compiler.mk
+# The following is for synthesis to a Xilinx target using Precision.
+#include precision-xilinx.mk
+
+
+
diff --git a/lab4/Nexys3.ucf b/lab4/Nexys3.ucf
new file mode 100644
index 0000000..92129cb
--- /dev/null
+++ b/lab4/Nexys3.ucf
@@ -0,0 +1,29 @@
+## This file is a general .ucf for Nexys3 rev B board
+## To use it in a project:
+## - remove or comment the lines corresponding to unused pins
+## - rename the used signals according to the project
+
+##Clock signal
+Net "clk" LOC=V10 | IOSTANDARD=LVCMOS33;
+Net "clk" TNM_NET = sys_clk_pin;
+TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;
+
+Net "rst" LOC = B8 | IOSTANDARD = LVCMOS33; #Bank = 0, pin name = IO_L33P, Sch name = BTNS
+
+
+## Pic USB-HID interface
+Net "PS2KeyboardClk" LOC = L12 | IOSTANDARD = LVCMOS33 | PULLUP; #Bank = 1, pin name = IO_L40P_GCLK11_M1A5, Sch name = PIC-SCK1
+Net "PS2KeyboardData" LOC = J13 | IOSTANDARD = LVCMOS33 | PULLUP; #Bank = 1, pin name = IO_L39P_M1A3, Sch name = PIC-SDI1
+
+## VGA Connector
+NET "vgaRed<0>" LOC = U7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L43P, Sch name = RED0
+NET "vgaRed<1>" LOC = V7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L43N, Sch name = RED1
+NET "vgaRed<2>" LOC = N7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L44P, Sch name = RED2
+NET "vgaGreen<0>" LOC = P8 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L44N, Sch name = GRN0
+NET "vgaGreen<1>" LOC = T6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L45P, Sch name = GRN1
+NET "vgaGreen<2>" LOC = V6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L45N, Sch name = GRN2
+NET "vgaBlue<1>" LOC = R7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L46P, Sch name = BLU1
+NET "vgaBlue<2>" LOC = T7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L46N, Sch name = BLU2
+
+NET "Hsync" LOC = N6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L47P, Sch name = HSYNC
+NET "Vsync" LOC = P7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L47N, Sch name = VSYNC
diff --git a/lab4/PICT_MEM.vhd b/lab4/PICT_MEM.vhd
new file mode 100644
index 0000000..8b519a1
--- /dev/null
+++ b/lab4/PICT_MEM.vhd
@@ -0,0 +1,58 @@
+--------------------------------------------------------------------------------
+-- PICT MEM
+-- Anders Nilsson
+-- 16-feb-2016
+-- Version 1.1
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+
+
+-- entity
+entity PICT_MEM is
+ port ( clk : in std_logic;
+ -- port 1
+ we1 : in std_logic;
+ data_in1 : in std_logic_vector(7 downto 0);
+ data_out1 : out std_logic_vector(7 downto 0);
+ addr1 : in unsigned(10 downto 0);
+ -- port 2
+ we2 : in std_logic;
+ data_in2 : in std_logic_vector(7 downto 0);
+ data_out2 : out std_logic_vector(7 downto 0);
+ addr2 : in unsigned(10 downto 0));
+end PICT_MEM;
+
+
+-- architecture
+architecture Behavioral of PICT_MEM is
+
+ -- picture memory type
+ type ram_t is array (0 to 2047) of std_logic_vector(7 downto 0);
+ -- initiate picture memory to one cursor ("1F") followed by spaces ("00")
+ signal pictMem : ram_t := (0 => x"1F", others => (others => '0'));
+
+
+begin
+
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if (we1 = '1') then
+ pictMem(to_integer(addr1)) <= data_in1;
+ end if;
+ data_out1 <= pictMem(to_integer(addr1));
+
+ if (we2 = '1') then
+ pictMem(to_integer(addr2)) <= data_in2;
+ end if;
+ data_out2 <= pictMem(to_integer(addr2));
+ end if;
+ end process;
+
+
+end Behavioral;
+
diff --git a/lab4/VGA_MOTOR/Makefile b/lab4/VGA_MOTOR/Makefile
new file mode 100644
index 0000000..39b0850
--- /dev/null
+++ b/lab4/VGA_MOTOR/Makefile
@@ -0,0 +1,68 @@
+# Makefile for hardware implementation on Xilinx FPGAs and ASICs
+# Author: Andreas Ehliar <ehliar@isy.liu.se>
+#
+# T is the testbench file for this project
+# S is the synthesizable sources for this project
+# U is the UCF file
+# PART is the part
+
+# Important makefile targets:
+# make lab.sim GUI simulation
+# make lab.simc batch simulation
+# make lab.synth Synthesize
+# make lab.route Route the design
+# make lab.bitgen Generate bit file
+# make lab.timing Generate timing report
+# make lab.clean Use whenever you change settings in the Makefile!
+# make lab.prog Downloads the bitfile to the FPGA. NOTE: Does not
+# rebuild bitfile if source files have changed!
+# make clean Removes all generated files for all projects. Also
+# backup files (*~) are removed.
+#
+# VIKTIG NOTERING: Om du Àndrar vilka filer som finns med i projektet sÄ mÄste du köra
+# make lab.clean
+#
+# Syntesrapporten ligger i lab-synthdir/xst/synth/design.syr
+# Maprapporten (bra att kolla i för arearapportens skull) ligger i lab-synthdir/layoutdefault/design_map.mrp
+# Timingrapporten (skapas av make lab.timing) ligger i lab-synthdir/layoutdefault/design.trw
+
+# (Or proj2.simc, proj2.sim, etc, depending on the name of the
+# project)
+
+XILINX_INIT = source /opt/xilinx_ise/14.7/settings64.sh;
+PART=xc6slx16-3-csg324
+
+
+VGA_lab.%: S=VGA_lab.vhd VGA_MOTOR.vhd ../PICT_MEM.vhd
+VGA_lab.%: T=VGA_lab_tb.vhd
+VGA_lab.%: U=Nexys3.ucf
+
+
+# Det hÀr Àr ett exempel pÄ hur man kan skriva en testbÀnk som Àr
+# relevant, Àven om man kör en simulering i batchlÀge (make batchlab.simc)
+#batchlab.%: S=lab.vhd leddriver.vhd
+#batchlab.%: T=batchlab_tb.vhd tb_print7seg.vhd
+#batchlab.%: U=lab.ucf
+
+
+# Misc functions that are good to have
+include build/util.mk
+# Setup simulation environment
+include build/vsim.mk
+# Setup synthesis environment
+include build/xst.mk
+# Setup backend flow environment
+include build/xilinx-par.mk
+# Setup tools for programming the FPGA
+include build/digilentprog.mk
+
+
+
+# Alternative synthesis methods
+# The following is for ASIC synthesis
+#include design_compiler.mk
+# The following is for synthesis to a Xilinx target using Precision.
+#include precision-xilinx.mk
+
+
+
diff --git a/lab4/VGA_MOTOR/Nexys3.ucf b/lab4/VGA_MOTOR/Nexys3.ucf
new file mode 100644
index 0000000..ffdfca1
--- /dev/null
+++ b/lab4/VGA_MOTOR/Nexys3.ucf
@@ -0,0 +1,29 @@
+## This file is a general .ucf for Nexys3 rev B board
+## To use it in a project:
+## - remove or comment the lines corresponding to unused pins
+## - rename the used signals according to the project
+
+##Clock signal
+Net "clk" LOC=V10 | IOSTANDARD=LVCMOS33;
+Net "clk" TNM_NET = sys_clk_pin;
+TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;
+
+Net "rst" LOC = B8 | IOSTANDARD = LVCMOS33; #Bank = 0, pin name = IO_L33P, Sch name = BTNS
+
+
+## Pic USB-HID interface
+#Net "PS2KeyboardClk" LOC = L12 | IOSTANDARD = LVCMOS33 | PULLUP; #Bank = 1, pin name = IO_L40P_GCLK11_M1A5, Sch name = PIC-SCK1
+#Net "PS2KeyboardData" LOC = J13 | IOSTANDARD = LVCMOS33 | PULLUP; #Bank = 1, pin name = IO_L39P_M1A3, Sch name = PIC-SDI1
+
+## VGA Connector
+NET "vgaRed<0>" LOC = U7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L43P, Sch name = RED0
+NET "vgaRed<1>" LOC = V7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L43N, Sch name = RED1
+NET "vgaRed<2>" LOC = N7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L44P, Sch name = RED2
+NET "vgaGreen<0>" LOC = P8 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L44N, Sch name = GRN0
+NET "vgaGreen<1>" LOC = T6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L45P, Sch name = GRN1
+NET "vgaGreen<2>" LOC = V6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L45N, Sch name = GRN2
+NET "vgaBlue<1>" LOC = R7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L46P, Sch name = BLU1
+NET "vgaBlue<2>" LOC = T7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L46N, Sch name = BLU2
+
+NET "Hsync" LOC = N6 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L47P, Sch name = HSYNC
+NET "Vsync" LOC = P7 | IOSTANDARD = LVCMOS33; # Bank = 2, pin name = IO_L47N, Sch name = VSYNC
diff --git a/lab4/VGA_MOTOR/VGA_MOTOR.vhd b/lab4/VGA_MOTOR/VGA_MOTOR.vhd
new file mode 100644
index 0000000..dafe45d
--- /dev/null
+++ b/lab4/VGA_MOTOR/VGA_MOTOR.vhd
@@ -0,0 +1,447 @@
+--------------------------------------------------------------------------------
+-- VGA MOTOR
+-- Anders Nilsson
+-- 16-feb-2016
+-- Version 1.1
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+
+
+-- entity
+entity VGA_MOTOR is
+ port ( clk : in std_logic;
+ data : in std_logic_vector(7 downto 0);
+ addr : out unsigned(10 downto 0);
+ rst : in std_logic;
+ vgaRed : out std_logic_vector(2 downto 0);
+ vgaGreen : out std_logic_vector(2 downto 0);
+ vgaBlue : out std_logic_vector(2 downto 1);
+ Hsync : out std_logic;
+ Vsync : out std_logic);
+end VGA_MOTOR;
+
+
+-- architecture
+architecture Behavioral of VGA_MOTOR is
+
+ signal Xpixel : unsigned(9 downto 0); -- Horizontal pixel counter
+ signal Ypixel : unsigned(9 downto 0); -- Vertical pixel counter
+ signal ClkDiv : unsigned(1 downto 0); -- Clock divisor, to generate 25 MHz signal
+ signal Clk25 : std_logic; -- One pulse width 25 MHz signal
+
+ signal tilePixel : std_logic_vector(7 downto 0); -- Tile pixel data
+ signal tileAddr : unsigned(10 downto 0); -- Tile address
+
+ signal blank : std_logic; -- blanking signal
+
+
+ -- Tile memory type
+ type ram_t is array (0 to 2047) of std_logic_vector(7 downto 0);
+
+-- Tile memory
+ signal tileMem : ram_t :=
+ ( x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- space
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"00",x"00",x"00",x"FF",x"FF",x"FF", -- A
+ x"FF",x"00",x"00",x"FF",x"00",x"00",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"00",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF", -- B
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF", -- C
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- D
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- E
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- F
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- G
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- H
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- I
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- J
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- K
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- L
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- M
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- N
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- O
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- P
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- Q
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- R
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- S
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- T
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- U
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- V
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF", -- W
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"E0",x"E0",x"FF",x"FF",x"FF",x"E0",x"E0",x"FF", -- X
+ x"FF",x"E0",x"E0",x"FF",x"E0",x"E0",x"FF",x"FF",
+ x"FF",x"FF",x"E0",x"E0",x"E0",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"E0",x"E0",x"E0",x"FF",x"FF",x"FF",
+ x"FF",x"E0",x"E0",x"FF",x"E0",x"E0",x"FF",x"FF",
+ x"E0",x"E0",x"FF",x"FF",x"FF",x"E0",x"E0",x"FF",
+ x"E0",x"FF",x"FF",x"FF",x"FF",x"FF",x"E0",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"1C",x"1C",x"FF",x"FF",x"1C",x"1C",x"FF", -- Y
+ x"FF",x"1C",x"1C",x"FF",x"FF",x"1C",x"1C",x"FF",
+ x"FF",x"1C",x"1C",x"FF",x"FF",x"1C",x"1C",x"FF",
+ x"FF",x"FF",x"1C",x"1C",x"1C",x"1C",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"1C",x"1C",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"1C",x"1C",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"1C",x"1C",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"03",x"03",x"03",x"03",x"03",x"03",x"03",x"FF", -- Z
+ x"FF",x"FF",x"FF",x"FF",x"03",x"03",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"03",x"03",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"03",x"03",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"03",x"03",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"03",x"03",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"03",x"03",x"03",x"03",x"03",x"03",x"03",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"00",x"FF",x"FF",x"FF",x"FF", -- Ć
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"00",x"FF",x"00",x"FF",x"FF",x"FF", -- Ä
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"00",x"FF",x"00",x"FF",x"FF",x"FF", -- Ö
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"00",x"00",x"FF",x"FF",x"FF",x"00",x"00",x"FF",
+ x"FF",x"00",x"00",x"00",x"00",x"00",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+ x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+
+ x"FF",x"FF",x"27",x"27",x"27",x"27",x"FF",x"FF", -- PACMAN CURSOR
+ x"FF",x"27",x"27",x"27",x"27",x"27",x"27",x"FF",
+ x"27",x"27",x"27",x"27",x"E0",x"27",x"FF",x"FF",
+ x"27",x"27",x"27",x"27",x"27",x"FF",x"FF",x"FF",
+ x"27",x"27",x"27",x"27",x"27",x"FF",x"FF",x"FF",
+ x"27",x"27",x"27",x"27",x"27",x"27",x"FF",x"FF",
+ x"FF",x"27",x"27",x"27",x"27",x"27",x"27",x"FF",
+ x"FF",x"FF",x"27",x"27",x"27",x"27",x"FF",x"FF"
+
+ );
+
+begin
+
+ -- Clock divisor
+ -- Divide system clock (100 MHz) by 4
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst='1' then
+ ClkDiv <= (others => '0');
+ else
+ ClkDiv <= ClkDiv + 1;
+ end if;
+ end if;
+ end process;
+
+ -- 25 MHz clock (one system clock pulse width)
+ Clk25 <= '1' when (ClkDiv = 3) else '0';
+
+
+ -- Horizontal pixel counter
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * Xpixel *
+ -- * *
+ -- ***********************************
+
+
+
+ -- Horizontal sync
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * Hsync *
+ -- * *
+ -- ***********************************
+
+
+
+ -- Vertical pixel counter
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * Ypixel *
+ -- * *
+ -- ***********************************
+
+
+
+ -- Vertical sync
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * Vsync *
+ -- * *
+ -- ***********************************
+
+
+
+
+ -- Video blanking signal
+
+ -- ***********************************
+ -- * *
+ -- * VHDL for : *
+ -- * Blank *
+ -- * *
+ -- ***********************************
+
+
+
+
+ -- Tile memory
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if (blank = '0') then
+ tilePixel <= tileMem(to_integer(tileAddr));
+ else
+ tilePixel <= (others => '0');
+ end if;
+ end if;
+ end process;
+
+
+
+ -- Tile memory address composite
+ tileAddr <= unsigned(data(4 downto 0)) & Ypixel(4 downto 2) & Xpixel(4 downto 2);
+
+
+ -- Picture memory address composite
+ addr <= to_unsigned(20, 7) * Ypixel(8 downto 5) + Xpixel(9 downto 5);
+
+
+ -- VGA generation
+ vgaRed(2) <= tilePixel(7);
+ vgaRed(1) <= tilePixel(6);
+ vgaRed(0) <= tilePixel(5);
+ vgaGreen(2) <= tilePixel(4);
+ vgaGreen(1) <= tilePixel(3);
+ vgaGreen(0) <= tilePixel(2);
+ vgaBlue(2) <= tilePixel(1);
+ vgaBlue(1) <= tilePixel(0);
+
+
+end Behavioral;
+
diff --git a/lab4/VGA_MOTOR/VGA_lab.vhd b/lab4/VGA_MOTOR/VGA_lab.vhd
new file mode 100644
index 0000000..f96206a
--- /dev/null
+++ b/lab4/VGA_MOTOR/VGA_lab.vhd
@@ -0,0 +1,70 @@
+--------------------------------------------------------------------------------
+-- VGA lab
+-- Anders Nilsson
+-- 16-dec-2015
+-- Version 1.0
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+ -- and various arithmetic operations
+
+-- entity
+entity VGA_lab is
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic; -- vertical sync
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1)); -- VGA blue
+end VGA_lab;
+
+
+-- architecture
+architecture Behavioral of VGA_lab is
+
+ -- picture memory component
+ component PICT_MEM
+ port ( clk : in std_logic; -- system clock
+ -- port 1
+ we1 : in std_logic; -- write enable
+ data_in1 : in std_logic_vector(7 downto 0); -- data in
+ data_out1 : out std_logic_vector(7 downto 0); -- data out
+ addr1 : in unsigned(10 downto 0); -- address
+ -- port 2
+ we2 : in std_logic; -- write enable
+ data_in2 : in std_logic_vector(7 downto 0); -- data in
+ data_out2 : out std_logic_vector(7 downto 0); -- data out
+ addr2 : in unsigned(10 downto 0)); -- address
+ end component;
+
+ -- VGA motor component
+ component VGA_MOTOR
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ data : in std_logic_vector(7 downto 0); -- data
+ addr : out unsigned(10 downto 0); -- address
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1); -- VGA blue
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic); -- vertical sync
+ end component;
+
+ -- intermediate signals between PICT_MEM and VGA_MOTOR
+ signal data_out2_s : std_logic_vector(7 downto 0); -- data
+ signal addr2_s : unsigned(10 downto 0); -- address
+
+begin
+
+ -- picture memory component connection
+ U1 : PICT_MEM port map(clk=>clk, we1=>'0', data_in1=>"00000000", addr1=>"00000000000", we2=>'0', data_in2=>"00000000", data_out2=>data_out2_s, addr2=>addr2_s);
+
+ -- VGA motor component connection
+ U2 : VGA_MOTOR port map(clk=>clk, rst=>rst, data=>data_out2_s, addr=>addr2_s, vgaRed=>vgaRed, vgaGreen=>vgaGreen, vgaBlue=>vgaBlue, Hsync=>Hsync, Vsync=>Vsync);
+
+end Behavioral;
+
diff --git a/lab4/VGA_MOTOR/VGA_lab_tb.vhd b/lab4/VGA_MOTOR/VGA_lab_tb.vhd
new file mode 100644
index 0000000..67ae13b
--- /dev/null
+++ b/lab4/VGA_MOTOR/VGA_lab_tb.vhd
@@ -0,0 +1,50 @@
+--------------------------------------------------------------------------------
+-- VGA lab testbench
+-- Anders Nilsson
+-- 26-feb-2020
+-- Version 1.0
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+ -- and various arithmetic operations
+entity VGA_lab_tb is
+end entity;
+
+architecture func of VGA_lab_tb is
+
+ component VGA_lab
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic; -- vertical sync
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1)); -- VGA blue
+ end component;
+
+ signal clk : std_logic;
+ signal rst : std_logic;
+
+ constant clk_period : time := 10 ns;
+
+ begin
+
+ uut: VGA_lab port map(
+ clk => clk,
+ rst => rst
+ );
+
+ clk_process : process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+ rst <= '1', '0' after 25 ns;
+end architecture;
+
diff --git a/lab4/VGA_MOTOR/build/dc_synthesize.tcl b/lab4/VGA_MOTOR/build/dc_synthesize.tcl
new file mode 100644
index 0000000..45afc74
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/dc_synthesize.tcl
@@ -0,0 +1,95 @@
+sh date
+
+# set some per design variables FIXME - use these!
+# set LOG_PATH "synth/dc_test_synth/log/"
+# set GATE_PATH "synth/dc_test_synth/gate/"
+# set RTL_PATH "synth/dc_test_synth/verilog/"
+
+# Should be moved to a synthesis setup dot file?
+set target_library {/sw/mentor/libraries/cmos065_522/CORE65LPLVT_5.1/libs/CORE65LPLVT_nom_1.20V_25C.db}
+set link_library $target_library
+
+
+
+proc dir_exists {name} {
+ if { [catch {set type [file type $name] } ] } {
+ return 0;
+ }
+ if { $type == "directory" } {
+ return 1;
+ }
+ return 0;
+
+}
+
+source designinfo.tcl
+
+
+if {[dir_exists $TOPLEVEL.out]} {
+ sh rm -r ./$TOPLEVEL.out
+}
+sh mkdir ./$TOPLEVEL.out
+
+set power_preserve_rtl_hier_names true
+
+
+current_design $TOPLEVEL
+
+elaborate $TOPLEVEL
+
+# Set timing constaints, this says that a max of .5ns of delay from
+# input to output is allowable
+#set_max_delay .1 -from [all_inputs] -to [all_outputs]
+
+
+# If this were a clocked piece of logic we could set a clock
+# period to shoot for like this
+set_clock_gating_style -max_fanout 16
+
+# Some default settings, you probably need to change this for your
+# particular project!
+create_clock clk -period 2
+set_input_delay -clock clk 0.1 [all_inputs]
+set_output_delay -clock clk 0.1 [all_outputs]
+
+
+
+# FIXME - check this!
+#optimize_registers -sync_trans multiclass
+
+# Check for warnings/errors
+check_design
+
+# ungroup everything
+ungroup -flatten -all
+
+# flatten it all, this forces all the hierarchy to be flattened out
+set_flatten true -effort high
+uniquify
+
+# This forces the compiler to spend as much effort (and time)
+# compiling this RTL to achieve timing possible.
+#
+# Clock gating is enabled by default to reduce power.
+compile_ultra -gate_clock
+
+# Now that the compile is complete report on the results
+
+check_design > ./$TOPLEVEL.out/check_design.rpt
+
+report_constraint -all_violators -verbose > constraint.rpt
+report_wire_load > wire_load_model_used.rpt
+report_area > area.rpt
+report_qor > qor.rpt
+report_timing -max_paths 1000 > timing.rpt
+
+
+report_ultra_optimization > ultraopt.rpt
+report_power -verbose > power_estimate.rpt
+report_design > ./$TOPLEVEL.out/design_information.rpt
+report_resources > ./$TOPLEVEL.out/resources.rpt
+
+# Finally write the post synthesis netlist out to a verilog file
+write -f verilog -output synthesized_netlist.v -hierarchy
+
+quit
diff --git a/lab4/VGA_MOTOR/build/design_compiler.mk b/lab4/VGA_MOTOR/build/design_compiler.mk
new file mode 100644
index 0000000..35ed335
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/design_compiler.mk
@@ -0,0 +1,30 @@
+
+$(PROJNAME)-synthdir/dc/synth/synth.tcl: build/dc_synthesize.tcl
+ @echo
+ @echo '*** Copying synthesis script ***'
+ @echo
+ mkdir -p $(@D)
+ cp build/dc_synthesize.tcl $(@D)/synth.tcl
+
+$(PROJNAME)-synthdir/dc/synth/designinfo.tcl: $(S)
+ @echo
+ @echo '*** Generate design info script ***'
+ @echo
+ mkdir -p $(@D)
+ rm -f $(@D)/designtmp
+ echo 'set TOPLEVEL '$$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//')) >> $@.tmp
+ $(foreach i,$(filter %.v,$(S)), echo 'read_verilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.sv,$(S)), echo 'read_sverilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'read_vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'read_vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.v,$(S)), echo 'analyze -format verilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.sv,$(S)), echo 'analyze -format sverilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'analyze -format vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'analyze -format vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ mv $@.tmp $@
+
+$(PROJNAME)-synthdir/dc/synth/design.v: $(PROJNAME)-synthdir/dc/synth/synth.tcl $(PROJNAME)-synthdir/dc/synth/designinfo.tcl $(S)
+ cd $(PROJNAME)-synthdir/dc/synth; dc_shell -f synth.tcl
+
+%.synth:
+ $(NICE) $(MAKE) -f $(firstword $(MAKEFILE_LIST)) $*-synthdir/dc/synth/design.v PROJNAME="$*"
diff --git a/lab4/VGA_MOTOR/build/digilentprog.mk b/lab4/VGA_MOTOR/build/digilentprog.mk
new file mode 100644
index 0000000..8f55a5e
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/digilentprog.mk
@@ -0,0 +1,6 @@
+
+PROG:
+ djtgcfg prog -i 0 -d Nexys3 -f $(PROJNAME)-synthdir/layoutdefault/design.bit
+
+%.prog:
+ $(NICE) $(MAKE) -f Makefile PROG PROJNAME="$*"
diff --git a/lab4/VGA_MOTOR/build/precision-xilinx.mk b/lab4/VGA_MOTOR/build/precision-xilinx.mk
new file mode 100644
index 0000000..fafa3bc
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/precision-xilinx.mk
@@ -0,0 +1,59 @@
+PRECISION=precision
+
+# FIXME - different directoreis for different synthesis scripts?
+# For precision:
+$(PROJNAME)-synthdir/synth/precision/design.scr: $(S) | dump_synthsettings
+ @echo
+ @echo '*** Creating synthesis scripts for Precision ***'
+ @echo
+ mkdir -p $(@D)
+ rm -f $(@D)/design.scr;
+ echo set_results_dir . > $(@D)/design.scr
+ echo -n 'add_input_file {' >> $(@D)/design.scr
+ for i in $(S); do echo -n " \"$$PWD/$$i\"" >> $(@D)/design.scr; done
+ echo '}' >> $(@D)/design.scr
+ echo "setup_design -design "$$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//')) >> $(@D)/design.scr
+ echo 'setup_design -manufacturer $(PRECISION_MANUFACTURER) -family $(PRECISION_FAMILY) -part $(PRECISION_PART) -speed $(PRECISION_SPEEDGRADE)' >> $(@D)/design.scr
+ echo '$(PRECISION_EXTRA_OPTIONS)' >> $(@D)/design.scr
+ echo 'setup_design -basename design' >> $(@D)/design.scr
+ echo 'compile' >> $(@D)/design.scr
+ echo 'synthesize' >> $(@D)/design.scr
+ echo 'report_area > area.rpt' >> $(@D)/design.scr
+
+$(PROJNAME)-synthdir/synth/precision/design.edf: $(PROJNAME)-synthdir/synth/precision/design.scr
+ cd $(@D);$(NICE) $(PRECISION) -shell -file design.scr
+
+$(PROJNAME)-synthdir/synth/design.edf: $(PROJNAME)-synthdir/synth/precision/design.edf
+ cp $< $@
+
+dump_synthsettings:
+ @echo
+ @echo " *** Important settings for the Synthesis module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " Files to synthesize: $(S)"
+ @echo " Include directories: $(INCDIRS)"
+ @echo " FPGA part (PRECISION_PART): $(PRECISION_PART)"
+ @echo " FPGA familypart (PRECISION_FAMILY): $(PRECISION_FAMILY)"
+ @echo " FPGA manufacturer (PRECISION_MANUFACTURER): $(PRECISION_MANUFACTURER)"
+ @echo " FPGA speedgrade (PRECISION_SPEEDGRADE): $(PRECISION_SPEEDGRADE)"
+ @echo " Extra options to precision: $(PRECISION_EXTRA_OPTIONS)"
+ @echo
+
+export PRECISION_PART
+export PRECISION_FAMILY
+export PRECISION_MANUFACTURER
+export PRECISION_SPEEDGRADE
+export PRECISION_EXTRA_OPTIONS
+
+# How to handle EDN files?
+# $(PROJNAME)-synthdir/layoutdefault/design.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+# $(@D)/%.ngd: $(@D)/%.edf %.ucf
+# rm -rf $(@D)/_ngo
+# mkdir $(@D)/_ngo
+# cp *.edn $(@D)
+# cd $(@D); $(XILINX_INIT) ngdbuild -dd _ngo -nt timestamp -p $(PART) -uc $(PWD)/$*.ucf $*.edf $*.ngd
+
+
+%.synth:
+ $(NICE) $(MAKE) -f $(firstword $(MAKEFILE_LIST)) $*-synthdir/synth/precision/design.edf PROJNAME="$*"
diff --git a/lab4/VGA_MOTOR/build/util.mk b/lab4/VGA_MOTOR/build/util.mk
new file mode 100644
index 0000000..3bc84ca
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/util.mk
@@ -0,0 +1,59 @@
+# Make sure we can include this from more than one place without any
+# issues:
+ifneq ($(UTILISINCLUDED),1)
+
+
+# The default shell for make is /bin/sh which doesn't work for some of
+# the commands used in these files.
+SHELL=/bin/bash
+
+
+# Make sure we are running at low priority...
+NICE = nice -n 19
+
+# Reverses the order of all arguments given to the function.
+reverse_order = $(if $(1), $(word $(words $(1)),$(1)) $(call reverse_order,$(wordlist 2,$(words $(1)),dummy $(1))),$(1))
+
+# Fix the path by inserting ../../.. if the path is relative. If absolute, do nothing
+fixpath3 = $(shell echo "$(1)" | sed 's,^\([^/]\),../../../\1,')
+
+# Fix the path by inserting ../.. if the path is relative. If absolute, do nothing
+fixpath2 = $(shell echo "$(1)" | sed 's,^\([^/]\),../../\1,')
+
+
+# Fix the path by inserting ../ if the path is relative. If absolute, do nothing
+fixpath1 = $(shell echo "$(1)" | sed 's,^\([^/]\),../\1,')
+
+export S
+export INCDIRS
+export T
+export U
+export PART
+export PROJNAME
+
+
+sanitycheckclock:
+ $(foreach i,$(S), bash sanitycheck.sh "$(i)" &&) true
+
+sanitychecksynth: sanitycheckclock
+ @if [ "$(S)" == "" ]; then echo 'ERROR: No synthesizable files specified!';false;fi
+
+sanitychecktb: sanitycheckclock
+ @if [ "$(T)" == "" ]; then echo 'ERROR: No testbench files specified!';false;fi
+ @if [ "$(S)" == "" ]; then echo 'WARNING: No synthesizable files specified!';fi
+
+
+
+%.clean:
+ rm -rf "$*-synthdir" "$*-simdir"
+
+
+
+clean:
+ rm -rf *synthdir *simdir *~
+
+
+
+UTILISINCLUDED=1
+endif
+
diff --git a/lab4/VGA_MOTOR/build/vsim.mk b/lab4/VGA_MOTOR/build/vsim.mk
new file mode 100644
index 0000000..a15219b
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/vsim.mk
@@ -0,0 +1,61 @@
+# Needed for modelsim compilation of VHDL files
+T_REV=$(call reverse_order,$(T))
+S_REV=$(call reverse_order,$(S))
+
+#Enable this to set coverage...
+#COVERAGE=-cover bcst
+#FIXME - INCDIR handling
+
+VERILOGCOMPILE=vlog +acc $(COVERAGE) $(INCDIR)
+VHDLCOMPILE=vcom +acc $(COVERAGE)
+BATCHSIM?=vsim -c -do 'run -a;quit -f'
+GUISIM?=vsim
+
+# TODO: Don't recompile all files all the time!
+# (Re)compile all files used for the testbench
+
+$(PROJNAME)-simdir/work:
+ mkdir -p $(PROJNAME)-simdir
+ cd $(PROJNAME)-simdir;vlib work
+
+SIMTBFILES: $(PROJNAME)-simdir/work $(T_REV)
+ $(if $(filter %.vhd,$(T_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhd, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.vhdl,$(T_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhdl, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.v,$(T_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.v, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.sv,$(T_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.sv, $(T_REV)), $(call fixpath1,$(i))))
+
+SIMSYNTHFILES: $(PROJNAME)-simdir/work $(S_REV)
+ $(if $(filter %.vhd,$(S_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhd, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.vhdl,$(S_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhdl, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.v,$(S_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.v, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.sv,$(S_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.sv, $(S_REV)), $(call fixpath1,$(i))))
+
+
+SIMFILES: SIMSYNTHFILES SIMTBFILES sanitychecktb sanitycheck
+
+# FIXME - How to handle for example -L unisim ?
+SIM: SIMFILES
+ cd $(PROJNAME)-simdir;$(GUISIM) $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+SIMC: SIMFILES
+ cd $(PROJNAME)-simdir; $(BATCHSIM) $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+
+# vcom +acc $(PROJNAME)-synthdir/xst/synth//design_postsynth.vhd
+SYNTHSIMC: $(POSTSYNTHSIMNETLIST) SIMTBFILES
+ echo $*
+ $(NICE) $(MAKE) -f Makefile SIMC S="$(POSTSYNTHSIMNETLIST)" PROJNAME=$(PROJNAME) BATCHSIM="$(BATCHSIM) $(MODELSIM_POSTSYNTH_OPTIONS)"
+
+
+
+%.simfiles:
+ $(NICE) $(MAKE) -f Makefile SIMFILES PROJNAME="$*"
+
+%.sim:
+ $(NICE) $(MAKE) -f Makefile SIM PROJNAME="$*"
+
+%.simc:
+ $(NICE) $(MAKE) -f Makefile SIMC PROJNAME="$*"
+
+%.synthsimc:
+ $(NICE) $(MAKE) -f Makefile SYNTHSIMC PROJNAME="$*"
diff --git a/lab4/VGA_MOTOR/build/xilinx-par.mk b/lab4/VGA_MOTOR/build/xilinx-par.mk
new file mode 100644
index 0000000..f178422
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/xilinx-par.mk
@@ -0,0 +1,137 @@
+# FIXME - rule to create ngd file from edf file as well...
+
+dump_backendsettings:
+ @echo
+ @echo " *** Important settings for the Xilinx Backend module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " FPGA part (PART): $(PART)"
+ @echo " Constraints file: $(U)"
+ @echo
+
+
+# This is the default rule for NGDBuild when we are not trying to override our TIMESPEC
+$(PROJNAME)-synthdir/layoutdefault/%.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+# Running ngdbuild without any UCF file
+ if [ "$(U)" == "" ]; then \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) ../synth/design.ngc design.ngd;\
+ else \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc $(call fixpath2,$(U)) ../synth/design.ngc design.ngd;\
+ fi
+
+
+# This is the default rule for NGDBuild when we are not trying to override our TIMESPEC
+$(PROJNAME)-synthdir/layoutdefault/%.ngd: $(PROJNAME)-synthdir/synth/design.edf $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+# Running ngdbuild without any UCF file
+ if [ "$(U)" == "" ]; then \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) ../synth/design.edf design.ngd;\
+ else \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc $(call fixpath2,$(U)) ../synth/design.edf design.ngd;\
+ fi
+
+
+# This is the rule for NGDBuild when we are trying to override the TIMESPEC when using a project.fmax rule
+$(PROJNAME)-synthdir/layout%/design.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+ @if [ "$(U)" == "" ]; then \
+ echo 'Cannot synthesize to a specific MHz without a UCF file'; false; \
+ fi
+
+# At this point we try to override the default time constraint!
+ @if ! [ $$(grep -i TIMESPEC $(U) | wc -l) -eq 1 ]; then echo The script can only handle one timespec for now.;false;fi
+ @if ! egrep -q '^TIMESPEC ".*" *= *PERIOD *".*" *[0-9\.]+ *ns *HIGH *50 *% *;' $(U);then\
+ echo 'TIMESPEC line in UCF must be in the following format: TIMESPEC "name" = PERIOD 4.5 ns HIGH 50%;';\
+ false;\
+ fi
+ sed 's/^\(TIMESPEC *".*" *= *PERIOD *".*"\) *[0-9\.]\+ *ns *HIGH *50 *%; *$$/\1 $* HIGH 50%;/' < $(U) > $(@D)/design.ucf
+ @echo "*** UCF file setup for timespec $* ***"
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc design.ucf ../synth/design.ngc design.ngd
+
+
+
+# Map a design into the FPGA components
+$(PROJNAME)-synthdir/layout%/design_map.ncd $(PROJNAME)-synthdir/layout%/design.pcf: $(PROJNAME)-synthdir/layout%/design.ngd
+ @echo
+ @echo '*** Mapping design ***'
+ @echo
+ cd $(@D);$(XILINX_INIT) map -detail -u -p $(PART) -pr b -c 100 -o design_map.ncd design.ngd design.pcf
+
+# Rule for placing and routing a design
+$(PROJNAME)-synthdir/layout%/design.ncd: $(PROJNAME)-synthdir/layout%/design_map.ncd $(PROJNAME)-synthdir/layout%/design.pcf
+ @echo
+ @echo '*** Routing design ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) par -nopad -w -ol high design_map.ncd design.ncd design.pcf
+
+$(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd: $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ @echo
+ @echo '*** Creating post place and route netlist $* ***'
+ @echo
+ $(XILINX_INIT) netgen -w -ofmt vhdl $(@D)/design.ncd $@
+
+
+
+$(PROJNAME)-synthdir/layout%/design.twr: $(PROJNAME)-synthdir/layout%/design.ncd
+ @echo
+ @echo '*** Running static timing analysis ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) trce -v 1000 design.ncd design.pcf
+
+$(PROJNAME)-synthdir/layoutdefault/design.xdl: work $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ @echo
+ @echo '*** Creating XDL netlist ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) xdl -w -ncd2xdl design.ncd
+
+
+$(PROJNAME)-synthdir/layoutdefault/design.bit: $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ cd $(@D); $(XILINX_INIT) bitgen -w design.ncd
+
+
+# Duplicate the layout dependencies a couple of time with different
+# timespecs to enable parallel make to investigate several different
+# timing specs simultaneously on multi processor machines.
+#
+# Warning: You may have a limited amount of licenses for ISE!
+expandtimespec = $(shell echo 'scale=5;for(i=0;i<25;i+=1){$(1)-i*0.1;print " "}'|bc)
+$(PROJNAME)-synthdir/fmax.rpt: $(foreach i,$(call expandtimespec,$(TIMESPEC)),$(PROJNAME)-synthdir/layout$(i)/design.twr)
+ @echo
+ @echo '*** Maximum frequencies follow ***'
+ @echo
+ grep MHz $(PROJNAME)-synthdir/layout*/design.twr
+
+
+# The rules below are the only rules that are expected to actually be
+# called by a normal user of this makefile.
+
+%.bitgen: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.bit PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.fmax: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/fmax.rpt PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" TIMESPEC=$(TIMESPEC) INCDIRS="$(INCDIRS)"
+
+
+
+%.route: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.ncd PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.timing: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.twr PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.xdl: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.xdl PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
diff --git a/lab4/VGA_MOTOR/build/xst.mk b/lab4/VGA_MOTOR/build/xst.mk
new file mode 100644
index 0000000..0610f14
--- /dev/null
+++ b/lab4/VGA_MOTOR/build/xst.mk
@@ -0,0 +1,130 @@
+# Command to initialize the Xilinx environment
+# (Feel free to change to the 64 bit version if necessary.)
+#XILINX_INIT = source /sw/xilinx/ise_11.1i/ISE/settings32.sh;
+#XILINX_INIT = source /extra/ise_11.1/ISE/settings32.sh;
+
+
+
+
+# This rule is responsible for creating the XST synthesis script and
+# the PRJ file containing the name of the files we want to synthesize
+
+.PRECIOUS: $(PROJNAME)-synthdir/%.scr $(PROJNAME)-synthdir/%.prj %.ncd $(PROJNAME)-synthdir/%.ngc $(PROJNAME)-synthdir/%.ngd $(PROJNAME)-synthdir/%_map.ncd $(PROJNAME)-synthdir/%.ncd $(PROJNAME)-synthdir/%.edf %.ncd %.bit
+
+$(PROJNAME)-synthdir/xst/synth/design.scr: $(S)
+ @echo
+ @echo '*** Creating synthesis scripts ***'
+ @echo
+ mkdir -p $(@D)
+# We first create the project file
+ @rm -f $@.tmp
+ @echo "set -tmpdir tmpdir" > $@.tmp
+ @echo "run -ifn design.prj" >> $@.tmp
+ @echo "-ofn design.ngc" >> $@.tmp
+# The following lines finds the first specified synthesizable file,
+# removes the file extension by using sed and then removing the
+# directory part of the file by using basename. This is then used as
+# our top module!
+ echo "-top $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))" >> $@.tmp
+ echo "-p $(PART)" >> $@.tmp
+ echo $(XST_OPT) >> $@.tmp
+# First enter all Verilog files into the project file, then all VHDL files
+ rm -f $(@D)/design.prj
+ touch $(@D)/design.prj
+ $(foreach i,$(filter %.v,$(S)), echo 'verilog work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'vhdl work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'vhdl work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ mv $@.tmp $@
+
+# Synthesize the design based on the synthesis script
+# Clean out temporary directories to be sure no stale data is left...
+$(PROJNAME)-synthdir/xst/synth/design.ngc: $(PROJNAME)-synthdir/xst/synth/design.scr
+ @echo
+ @echo '*** Synthesizing ***'
+ @echo
+ rm -rf $(@D)/tmpdir
+ mkdir -p $(@D)/tmpdir
+ rm -rf $(@D)/xst
+ mkdir -p $(@D)/xst
+ cd $(@D); $(XILINX_INIT) xst -ifn design.scr -ofn design.syr
+
+POSTSYNTHSIMNETLIST=$(PROJNAME)-synthdir/xst/synth/design_postsynth.vhd
+
+$(POSTSYNTHSIMNETLIST): $(PROJNAME)-synthdir/xst/synth/design.ngc
+ @echo
+ @echo '*** Creating post synthesis netlist $* ***'
+ @echo
+ $(XILINX_INIT) netgen -w -ofmt vhdl $(@D)/design.ngc $@
+
+
+MODELSIM_POSTSYNTH_OPTIONS=-L unisim
+
+
+
+# TODO: Don't recompile all files all the time!
+PARSIM: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ cp $(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf .
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+# TODO: Don't recompile all files all the time!
+PARSIMC: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//')) -c -do 'run -a; quit -f'
+
+
+# TODO: Don't recompile all files all the time!
+POWERSIM: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -do 'vcd file activity.vcd;vcd add -r -internal -in -out uut/*; vcd on;run -a;vcd off;vcd flush;quit -f' -c -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+ $(XILINX_INIT) xpwr -v -a -s activity.vcd $(PROJNAME)-synthdir/layoutdefault/design.ncd
+
+$(PROJNAME)-synthdir/synth/design.ngc: $(PROJNAME)-synthdir/xst/synth/design.ngc
+ mkdir -p $(@D)
+ cp $< $@
+
+export XST_EXTRA_OPTIONS
+
+
+
+dump_synthsettings:
+ @echo
+ @echo " *** Important settings for the Synthesis module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " Files to synthesize: $(S)"
+ @echo " Include directories: $(INCDIRS)"
+ @echo " FPGA part (PART): $(PART)"
+ @echo " Extra options to XST: $(XST_EXTRA_OPTIONS) (FIXME - not implemented yet in Makefile!)"
+ @echo
+
+
+
+%.synth: sanitychecksynth
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/synth/design.ngc PROJNAME="$*"
+
+
+
+
+
+
+%.synthsim:
+ $(NICE) $(MAKE) -f Makefile SYNTHSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+%.parsim:
+ $(NICE) $(MAKE) -f Makefile PARSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+
+
+%.parsimc:
+ $(NICE) $(MAKE) -f Makefile PARSIMC PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+%.powersim:
+ $(NICE) $(MAKE) -f Makefile POWERSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+
+
+
+
+
+
diff --git a/lab4/VGA_MOTOR/sanitycheck b/lab4/VGA_MOTOR/sanitycheck
new file mode 100644
index 0000000..acdcc99
--- /dev/null
+++ b/lab4/VGA_MOTOR/sanitycheck
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if sed 's/--.*//' < "$1" | grep -n \'event
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet 'event. Om du vill kolla efter en klockflank bör rising_edge anvÀndas istÀllet. Om du vill anvÀnda 'event till nÄgot annat i syntetiserbar kod bör du antagligen tÀnka om."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'rising_edge *\(.*\)' | egrep -v 'rising_edge *\( *clk *\)'
+then
+ echo "ERROR in $1: Du försöker klocka pÄ nÄgot som antagligen inte Àr en riktigt klocka. Du bör enbart anvÀnda rising_edge(clk) i din syntetiserbara kod."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'falling_edge'
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet falling_edge i filen $1. I den hÀr kursen bör du inte behöva anvÀnda det nyckelordet."
+ exit 1
+fi
+
+
diff --git a/lab4/VGA_MOTOR/sanitycheck.sh b/lab4/VGA_MOTOR/sanitycheck.sh
new file mode 100644
index 0000000..acdcc99
--- /dev/null
+++ b/lab4/VGA_MOTOR/sanitycheck.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if sed 's/--.*//' < "$1" | grep -n \'event
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet 'event. Om du vill kolla efter en klockflank bör rising_edge anvÀndas istÀllet. Om du vill anvÀnda 'event till nÄgot annat i syntetiserbar kod bör du antagligen tÀnka om."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'rising_edge *\(.*\)' | egrep -v 'rising_edge *\( *clk *\)'
+then
+ echo "ERROR in $1: Du försöker klocka pÄ nÄgot som antagligen inte Àr en riktigt klocka. Du bör enbart anvÀnda rising_edge(clk) i din syntetiserbara kod."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'falling_edge'
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet falling_edge i filen $1. I den hÀr kursen bör du inte behöva anvÀnda det nyckelordet."
+ exit 1
+fi
+
+
diff --git a/lab4/VGA_lab.vhd b/lab4/VGA_lab.vhd
new file mode 100644
index 0000000..5aeca02
--- /dev/null
+++ b/lab4/VGA_lab.vhd
@@ -0,0 +1,91 @@
+--------------------------------------------------------------------------------
+-- VGA lab
+-- Anders Nilsson
+-- 16-dec-2015
+-- Version 1.0
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+ -- and various arithmetic operations
+
+-- entity
+entity VGA_lab is
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic; -- vertical sync
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1); -- VGA blue
+ PS2KeyboardCLK : in std_logic; -- PS2 clock
+ PS2KeyboardData : in std_logic); -- PS2 data
+end VGA_lab;
+
+
+-- architecture
+architecture Behavioral of VGA_lab is
+
+ -- PS2 keyboard encoder component
+ component KBD_ENC
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset signal
+ PS2KeyboardCLK : in std_logic; -- PS2 clock
+ PS2KeyboardData : in std_logic; -- PS2 data
+ data : out std_logic_vector(7 downto 0); -- tile data
+ addr : out unsigned(10 downto 0); -- tile address
+ we : out std_logic); -- write enable
+ end component;
+
+ -- picture memory component
+ component PICT_MEM
+ port ( clk : in std_logic; -- system clock
+ -- port 1
+ we1 : in std_logic; -- write enable
+ data_in1 : in std_logic_vector(7 downto 0); -- data in
+ data_out1 : out std_logic_vector(7 downto 0); -- data out
+ addr1 : in unsigned(10 downto 0); -- address
+ -- port 2
+ we2 : in std_logic; -- write enable
+ data_in2 : in std_logic_vector(7 downto 0); -- data in
+ data_out2 : out std_logic_vector(7 downto 0); -- data out
+ addr2 : in unsigned(10 downto 0)); -- address
+ end component;
+
+ -- VGA motor component
+ component VGA_MOTOR
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ data : in std_logic_vector(7 downto 0); -- data
+ addr : out unsigned(10 downto 0); -- address
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1); -- VGA blue
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic); -- vertical sync
+ end component;
+
+ -- intermediate signals between KBD_ENC and PICT_MEM
+ signal data_s : std_logic_vector(7 downto 0); -- data
+ signal addr_s : unsigned(10 downto 0); -- address
+ signal we_s : std_logic; -- write enable
+
+ -- intermediate signals between PICT_MEM and VGA_MOTOR
+ signal data_out2_s : std_logic_vector(7 downto 0); -- data
+ signal addr2_s : unsigned(10 downto 0); -- address
+
+begin
+
+ -- keyboard encoder component connection
+ U0 : KBD_ENC port map(clk=>clk, rst=>rst, PS2KeyboardCLK=>PS2KeyboardCLK, PS2KeyboardData=>PS2KeyboardData, data=>data_s, addr=>addr_s, we=>we_s);
+
+ -- picture memory component connection
+ U1 : PICT_MEM port map(clk=>clk, we1=>we_s, data_in1=>data_s, addr1=>addr_s, we2=>'0', data_in2=>"00000000", data_out2=>data_out2_s, addr2=>addr2_s);
+
+ -- VGA motor component connection
+ U2 : VGA_MOTOR port map(clk=>clk, rst=>rst, data=>data_out2_s, addr=>addr2_s, vgaRed=>vgaRed, vgaGreen=>vgaGreen, vgaBlue=>vgaBlue, Hsync=>Hsync, Vsync=>Vsync);
+
+end Behavioral;
+
diff --git a/lab4/VGA_lab_tb.vhd b/lab4/VGA_lab_tb.vhd
new file mode 100644
index 0000000..1e2b19a
--- /dev/null
+++ b/lab4/VGA_lab_tb.vhd
@@ -0,0 +1,111 @@
+--------------------------------------------------------------------------------
+-- VGA lab testbench
+-- Anders Nilsson
+-- 26-feb-2020
+-- Version 1.0
+
+
+-- library declaration
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL; -- basic IEEE library
+use IEEE.NUMERIC_STD.ALL; -- IEEE library for the unsigned type
+ -- and various arithmetic operations
+entity VGA_lab_tb is
+end entity;
+
+architecture func of VGA_lab_tb is
+
+ component VGA_lab
+ port ( clk : in std_logic; -- system clock
+ rst : in std_logic; -- reset
+ Hsync : out std_logic; -- horizontal sync
+ Vsync : out std_logic; -- vertical sync
+ vgaRed : out std_logic_vector(2 downto 0); -- VGA red
+ vgaGreen : out std_logic_vector(2 downto 0); -- VGA green
+ vgaBlue : out std_logic_vector(2 downto 1); -- VGA blue
+ PS2KeyboardCLK : in std_logic; -- PS2 clock
+ PS2KeyboardData : in std_logic); -- PS2 data
+ end component;
+
+ signal clk : std_logic;
+ signal rst : std_logic;
+ signal PS2KeyboardCLK : std_logic;
+ signal PS2KeyboardData : std_logic;
+
+ constant FPGA_clk_period : time := 10 ns;
+ constant PS2_clk_period : time := 60 us;
+ constant PS2_time : time := 1 ms;
+
+ begin
+
+ uut: VGA_lab port map(
+ clk => clk,
+ rst => rst,
+ PS2KeyboardCLK => PS2KeyboardCLK,
+ PS2KeyboardData => PS2KeyboardData
+ );
+
+ PS2_stimuli : process
+ type pattern_array is array(natural range <>) of unsigned(7 downto 0);
+ constant patterns : pattern_array :=
+ ("00011100", -- x"1C" = Make scancode 'A'
+ "11110000", -- x"F0" = Break ...
+ "00011100", -- x"1C" = ... scancode 'A'
+ "00110010", -- x"32" = Make scancode 'B'
+ "11110000", -- x"F0" = Break ...
+ "00110010", -- x"32" = ... scancode 'B'
+ "00110101", -- x"35" = Make scancode 'Y'
+ "11110000", -- x"F0" = Break ...
+ "00110101" -- x"35" = ... scancode 'Y'
+ );
+
+ begin
+ PS2KeyboardData <= '1'; -- initial value
+ PS2KeyboardCLK <= '1';
+ wait for PS2_time;
+ for i in patterns'range loop
+ PS2KeyboardData <= '0'; -- start bit
+ wait for PS2_clk_period/2;
+ PS2KeyboardCLK <= '0';
+ for j in 0 to 7 loop
+ wait for PS2_clk_period/2;
+ PS2KeyboardData <= patterns(i)(j); -- data bit(s)
+ PS2KeyboardCLK <= '1';
+ wait for PS2_clk_period/2;
+ PS2KeyboardCLK <= '0'; -- data valid on negative flank
+ end loop;
+ wait for PS2_clk_period/2;
+ PS2KeyboardData <= '0'; -- parity bit (bogus value, always '0')
+ PS2KeyboardCLK <= '1';
+ wait for PS2_clk_period/2;
+ PS2KeyboardCLK <= '0';
+ wait for PS2_clk_period/2;
+ PS2KeyboardData <= '1'; -- stop bit
+ PS2KeyboardCLK <= '1';
+ wait for PS2_clk_period/2;
+ PS2KeyboardCLK <= '0';
+ wait for PS2_clk_period/2;
+ PS2KeyboardCLK <= '1';
+ if (((i mod 3) = 0) or (((i+1) mod 3) = 0)) then
+ wait for PS2_time; -- wait between Make and Break
+ else
+ wait for PS2_clk_period/2;
+ end if;
+ end loop;
+ wait; -- for ever
+ end process;
+
+
+ clk_process : process
+ begin
+ clk <= '0';
+ wait for FPGA_clk_period/2;
+ clk <= '1';
+ wait for FPGA_clk_period/2;
+ end process;
+
+ rst <= '1', '0' after 25 ns;
+
+
+end architecture;
+
diff --git a/lab4/build/dc_synthesize.tcl b/lab4/build/dc_synthesize.tcl
new file mode 100644
index 0000000..45afc74
--- /dev/null
+++ b/lab4/build/dc_synthesize.tcl
@@ -0,0 +1,95 @@
+sh date
+
+# set some per design variables FIXME - use these!
+# set LOG_PATH "synth/dc_test_synth/log/"
+# set GATE_PATH "synth/dc_test_synth/gate/"
+# set RTL_PATH "synth/dc_test_synth/verilog/"
+
+# Should be moved to a synthesis setup dot file?
+set target_library {/sw/mentor/libraries/cmos065_522/CORE65LPLVT_5.1/libs/CORE65LPLVT_nom_1.20V_25C.db}
+set link_library $target_library
+
+
+
+proc dir_exists {name} {
+ if { [catch {set type [file type $name] } ] } {
+ return 0;
+ }
+ if { $type == "directory" } {
+ return 1;
+ }
+ return 0;
+
+}
+
+source designinfo.tcl
+
+
+if {[dir_exists $TOPLEVEL.out]} {
+ sh rm -r ./$TOPLEVEL.out
+}
+sh mkdir ./$TOPLEVEL.out
+
+set power_preserve_rtl_hier_names true
+
+
+current_design $TOPLEVEL
+
+elaborate $TOPLEVEL
+
+# Set timing constaints, this says that a max of .5ns of delay from
+# input to output is allowable
+#set_max_delay .1 -from [all_inputs] -to [all_outputs]
+
+
+# If this were a clocked piece of logic we could set a clock
+# period to shoot for like this
+set_clock_gating_style -max_fanout 16
+
+# Some default settings, you probably need to change this for your
+# particular project!
+create_clock clk -period 2
+set_input_delay -clock clk 0.1 [all_inputs]
+set_output_delay -clock clk 0.1 [all_outputs]
+
+
+
+# FIXME - check this!
+#optimize_registers -sync_trans multiclass
+
+# Check for warnings/errors
+check_design
+
+# ungroup everything
+ungroup -flatten -all
+
+# flatten it all, this forces all the hierarchy to be flattened out
+set_flatten true -effort high
+uniquify
+
+# This forces the compiler to spend as much effort (and time)
+# compiling this RTL to achieve timing possible.
+#
+# Clock gating is enabled by default to reduce power.
+compile_ultra -gate_clock
+
+# Now that the compile is complete report on the results
+
+check_design > ./$TOPLEVEL.out/check_design.rpt
+
+report_constraint -all_violators -verbose > constraint.rpt
+report_wire_load > wire_load_model_used.rpt
+report_area > area.rpt
+report_qor > qor.rpt
+report_timing -max_paths 1000 > timing.rpt
+
+
+report_ultra_optimization > ultraopt.rpt
+report_power -verbose > power_estimate.rpt
+report_design > ./$TOPLEVEL.out/design_information.rpt
+report_resources > ./$TOPLEVEL.out/resources.rpt
+
+# Finally write the post synthesis netlist out to a verilog file
+write -f verilog -output synthesized_netlist.v -hierarchy
+
+quit
diff --git a/lab4/build/design_compiler.mk b/lab4/build/design_compiler.mk
new file mode 100644
index 0000000..35ed335
--- /dev/null
+++ b/lab4/build/design_compiler.mk
@@ -0,0 +1,30 @@
+
+$(PROJNAME)-synthdir/dc/synth/synth.tcl: build/dc_synthesize.tcl
+ @echo
+ @echo '*** Copying synthesis script ***'
+ @echo
+ mkdir -p $(@D)
+ cp build/dc_synthesize.tcl $(@D)/synth.tcl
+
+$(PROJNAME)-synthdir/dc/synth/designinfo.tcl: $(S)
+ @echo
+ @echo '*** Generate design info script ***'
+ @echo
+ mkdir -p $(@D)
+ rm -f $(@D)/designtmp
+ echo 'set TOPLEVEL '$$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//')) >> $@.tmp
+ $(foreach i,$(filter %.v,$(S)), echo 'read_verilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.sv,$(S)), echo 'read_sverilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'read_vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'read_vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.v,$(S)), echo 'analyze -format verilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.sv,$(S)), echo 'analyze -format sverilog "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'analyze -format vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'analyze -format vhdl "$(call fixpath3,$(i))"' >> $@.tmp;)
+ mv $@.tmp $@
+
+$(PROJNAME)-synthdir/dc/synth/design.v: $(PROJNAME)-synthdir/dc/synth/synth.tcl $(PROJNAME)-synthdir/dc/synth/designinfo.tcl $(S)
+ cd $(PROJNAME)-synthdir/dc/synth; dc_shell -f synth.tcl
+
+%.synth:
+ $(NICE) $(MAKE) -f $(firstword $(MAKEFILE_LIST)) $*-synthdir/dc/synth/design.v PROJNAME="$*"
diff --git a/lab4/build/digilentprog.mk b/lab4/build/digilentprog.mk
new file mode 100644
index 0000000..8f55a5e
--- /dev/null
+++ b/lab4/build/digilentprog.mk
@@ -0,0 +1,6 @@
+
+PROG:
+ djtgcfg prog -i 0 -d Nexys3 -f $(PROJNAME)-synthdir/layoutdefault/design.bit
+
+%.prog:
+ $(NICE) $(MAKE) -f Makefile PROG PROJNAME="$*"
diff --git a/lab4/build/precision-xilinx.mk b/lab4/build/precision-xilinx.mk
new file mode 100644
index 0000000..fafa3bc
--- /dev/null
+++ b/lab4/build/precision-xilinx.mk
@@ -0,0 +1,59 @@
+PRECISION=precision
+
+# FIXME - different directoreis for different synthesis scripts?
+# For precision:
+$(PROJNAME)-synthdir/synth/precision/design.scr: $(S) | dump_synthsettings
+ @echo
+ @echo '*** Creating synthesis scripts for Precision ***'
+ @echo
+ mkdir -p $(@D)
+ rm -f $(@D)/design.scr;
+ echo set_results_dir . > $(@D)/design.scr
+ echo -n 'add_input_file {' >> $(@D)/design.scr
+ for i in $(S); do echo -n " \"$$PWD/$$i\"" >> $(@D)/design.scr; done
+ echo '}' >> $(@D)/design.scr
+ echo "setup_design -design "$$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//')) >> $(@D)/design.scr
+ echo 'setup_design -manufacturer $(PRECISION_MANUFACTURER) -family $(PRECISION_FAMILY) -part $(PRECISION_PART) -speed $(PRECISION_SPEEDGRADE)' >> $(@D)/design.scr
+ echo '$(PRECISION_EXTRA_OPTIONS)' >> $(@D)/design.scr
+ echo 'setup_design -basename design' >> $(@D)/design.scr
+ echo 'compile' >> $(@D)/design.scr
+ echo 'synthesize' >> $(@D)/design.scr
+ echo 'report_area > area.rpt' >> $(@D)/design.scr
+
+$(PROJNAME)-synthdir/synth/precision/design.edf: $(PROJNAME)-synthdir/synth/precision/design.scr
+ cd $(@D);$(NICE) $(PRECISION) -shell -file design.scr
+
+$(PROJNAME)-synthdir/synth/design.edf: $(PROJNAME)-synthdir/synth/precision/design.edf
+ cp $< $@
+
+dump_synthsettings:
+ @echo
+ @echo " *** Important settings for the Synthesis module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " Files to synthesize: $(S)"
+ @echo " Include directories: $(INCDIRS)"
+ @echo " FPGA part (PRECISION_PART): $(PRECISION_PART)"
+ @echo " FPGA familypart (PRECISION_FAMILY): $(PRECISION_FAMILY)"
+ @echo " FPGA manufacturer (PRECISION_MANUFACTURER): $(PRECISION_MANUFACTURER)"
+ @echo " FPGA speedgrade (PRECISION_SPEEDGRADE): $(PRECISION_SPEEDGRADE)"
+ @echo " Extra options to precision: $(PRECISION_EXTRA_OPTIONS)"
+ @echo
+
+export PRECISION_PART
+export PRECISION_FAMILY
+export PRECISION_MANUFACTURER
+export PRECISION_SPEEDGRADE
+export PRECISION_EXTRA_OPTIONS
+
+# How to handle EDN files?
+# $(PROJNAME)-synthdir/layoutdefault/design.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+# $(@D)/%.ngd: $(@D)/%.edf %.ucf
+# rm -rf $(@D)/_ngo
+# mkdir $(@D)/_ngo
+# cp *.edn $(@D)
+# cd $(@D); $(XILINX_INIT) ngdbuild -dd _ngo -nt timestamp -p $(PART) -uc $(PWD)/$*.ucf $*.edf $*.ngd
+
+
+%.synth:
+ $(NICE) $(MAKE) -f $(firstword $(MAKEFILE_LIST)) $*-synthdir/synth/precision/design.edf PROJNAME="$*"
diff --git a/lab4/build/util.mk b/lab4/build/util.mk
new file mode 100644
index 0000000..3bc84ca
--- /dev/null
+++ b/lab4/build/util.mk
@@ -0,0 +1,59 @@
+# Make sure we can include this from more than one place without any
+# issues:
+ifneq ($(UTILISINCLUDED),1)
+
+
+# The default shell for make is /bin/sh which doesn't work for some of
+# the commands used in these files.
+SHELL=/bin/bash
+
+
+# Make sure we are running at low priority...
+NICE = nice -n 19
+
+# Reverses the order of all arguments given to the function.
+reverse_order = $(if $(1), $(word $(words $(1)),$(1)) $(call reverse_order,$(wordlist 2,$(words $(1)),dummy $(1))),$(1))
+
+# Fix the path by inserting ../../.. if the path is relative. If absolute, do nothing
+fixpath3 = $(shell echo "$(1)" | sed 's,^\([^/]\),../../../\1,')
+
+# Fix the path by inserting ../.. if the path is relative. If absolute, do nothing
+fixpath2 = $(shell echo "$(1)" | sed 's,^\([^/]\),../../\1,')
+
+
+# Fix the path by inserting ../ if the path is relative. If absolute, do nothing
+fixpath1 = $(shell echo "$(1)" | sed 's,^\([^/]\),../\1,')
+
+export S
+export INCDIRS
+export T
+export U
+export PART
+export PROJNAME
+
+
+sanitycheckclock:
+ $(foreach i,$(S), bash sanitycheck.sh "$(i)" &&) true
+
+sanitychecksynth: sanitycheckclock
+ @if [ "$(S)" == "" ]; then echo 'ERROR: No synthesizable files specified!';false;fi
+
+sanitychecktb: sanitycheckclock
+ @if [ "$(T)" == "" ]; then echo 'ERROR: No testbench files specified!';false;fi
+ @if [ "$(S)" == "" ]; then echo 'WARNING: No synthesizable files specified!';fi
+
+
+
+%.clean:
+ rm -rf "$*-synthdir" "$*-simdir"
+
+
+
+clean:
+ rm -rf *synthdir *simdir *~
+
+
+
+UTILISINCLUDED=1
+endif
+
diff --git a/lab4/build/vsim.mk b/lab4/build/vsim.mk
new file mode 100644
index 0000000..a15219b
--- /dev/null
+++ b/lab4/build/vsim.mk
@@ -0,0 +1,61 @@
+# Needed for modelsim compilation of VHDL files
+T_REV=$(call reverse_order,$(T))
+S_REV=$(call reverse_order,$(S))
+
+#Enable this to set coverage...
+#COVERAGE=-cover bcst
+#FIXME - INCDIR handling
+
+VERILOGCOMPILE=vlog +acc $(COVERAGE) $(INCDIR)
+VHDLCOMPILE=vcom +acc $(COVERAGE)
+BATCHSIM?=vsim -c -do 'run -a;quit -f'
+GUISIM?=vsim
+
+# TODO: Don't recompile all files all the time!
+# (Re)compile all files used for the testbench
+
+$(PROJNAME)-simdir/work:
+ mkdir -p $(PROJNAME)-simdir
+ cd $(PROJNAME)-simdir;vlib work
+
+SIMTBFILES: $(PROJNAME)-simdir/work $(T_REV)
+ $(if $(filter %.vhd,$(T_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhd, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.vhdl,$(T_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhdl, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.v,$(T_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.v, $(T_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.sv,$(T_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.sv, $(T_REV)), $(call fixpath1,$(i))))
+
+SIMSYNTHFILES: $(PROJNAME)-simdir/work $(S_REV)
+ $(if $(filter %.vhd,$(S_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhd, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.vhdl,$(S_REV)), cd $(PROJNAME)-simdir; $(VHDLCOMPILE) $(foreach i, $(filter %.vhdl, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.v,$(S_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.v, $(S_REV)), $(call fixpath1,$(i))))
+ $(if $(filter %.sv,$(S_REV)), cd $(PROJNAME)-simdir; $(VERILOGCOMPILE) $(foreach i, $(filter %.sv, $(S_REV)), $(call fixpath1,$(i))))
+
+
+SIMFILES: SIMSYNTHFILES SIMTBFILES sanitychecktb sanitycheck
+
+# FIXME - How to handle for example -L unisim ?
+SIM: SIMFILES
+ cd $(PROJNAME)-simdir;$(GUISIM) $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+SIMC: SIMFILES
+ cd $(PROJNAME)-simdir; $(BATCHSIM) $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+
+# vcom +acc $(PROJNAME)-synthdir/xst/synth//design_postsynth.vhd
+SYNTHSIMC: $(POSTSYNTHSIMNETLIST) SIMTBFILES
+ echo $*
+ $(NICE) $(MAKE) -f Makefile SIMC S="$(POSTSYNTHSIMNETLIST)" PROJNAME=$(PROJNAME) BATCHSIM="$(BATCHSIM) $(MODELSIM_POSTSYNTH_OPTIONS)"
+
+
+
+%.simfiles:
+ $(NICE) $(MAKE) -f Makefile SIMFILES PROJNAME="$*"
+
+%.sim:
+ $(NICE) $(MAKE) -f Makefile SIM PROJNAME="$*"
+
+%.simc:
+ $(NICE) $(MAKE) -f Makefile SIMC PROJNAME="$*"
+
+%.synthsimc:
+ $(NICE) $(MAKE) -f Makefile SYNTHSIMC PROJNAME="$*"
diff --git a/lab4/build/xilinx-par.mk b/lab4/build/xilinx-par.mk
new file mode 100644
index 0000000..f178422
--- /dev/null
+++ b/lab4/build/xilinx-par.mk
@@ -0,0 +1,137 @@
+# FIXME - rule to create ngd file from edf file as well...
+
+dump_backendsettings:
+ @echo
+ @echo " *** Important settings for the Xilinx Backend module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " FPGA part (PART): $(PART)"
+ @echo " Constraints file: $(U)"
+ @echo
+
+
+# This is the default rule for NGDBuild when we are not trying to override our TIMESPEC
+$(PROJNAME)-synthdir/layoutdefault/%.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+# Running ngdbuild without any UCF file
+ if [ "$(U)" == "" ]; then \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) ../synth/design.ngc design.ngd;\
+ else \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc $(call fixpath2,$(U)) ../synth/design.ngc design.ngd;\
+ fi
+
+
+# This is the default rule for NGDBuild when we are not trying to override our TIMESPEC
+$(PROJNAME)-synthdir/layoutdefault/%.ngd: $(PROJNAME)-synthdir/synth/design.edf $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+# Running ngdbuild without any UCF file
+ if [ "$(U)" == "" ]; then \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) ../synth/design.edf design.ngd;\
+ else \
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc $(call fixpath2,$(U)) ../synth/design.edf design.ngd;\
+ fi
+
+
+# This is the rule for NGDBuild when we are trying to override the TIMESPEC when using a project.fmax rule
+$(PROJNAME)-synthdir/layout%/design.ngd: $(PROJNAME)-synthdir/synth/design.ngc $(U)
+ @echo
+ @echo '*** Producing NGD file ***'
+ @echo
+ rm -rf $(@D)/_ngo
+ mkdir -p $(@D)/_ngo
+ @if [ "$(U)" == "" ]; then \
+ echo 'Cannot synthesize to a specific MHz without a UCF file'; false; \
+ fi
+
+# At this point we try to override the default time constraint!
+ @if ! [ $$(grep -i TIMESPEC $(U) | wc -l) -eq 1 ]; then echo The script can only handle one timespec for now.;false;fi
+ @if ! egrep -q '^TIMESPEC ".*" *= *PERIOD *".*" *[0-9\.]+ *ns *HIGH *50 *% *;' $(U);then\
+ echo 'TIMESPEC line in UCF must be in the following format: TIMESPEC "name" = PERIOD 4.5 ns HIGH 50%;';\
+ false;\
+ fi
+ sed 's/^\(TIMESPEC *".*" *= *PERIOD *".*"\) *[0-9\.]\+ *ns *HIGH *50 *%; *$$/\1 $* HIGH 50%;/' < $(U) > $(@D)/design.ucf
+ @echo "*** UCF file setup for timespec $* ***"
+ cd $(@D); $(XILINX_INIT) ngdbuild -sd . -dd _ngo -nt timestamp -p $(PART) -uc design.ucf ../synth/design.ngc design.ngd
+
+
+
+# Map a design into the FPGA components
+$(PROJNAME)-synthdir/layout%/design_map.ncd $(PROJNAME)-synthdir/layout%/design.pcf: $(PROJNAME)-synthdir/layout%/design.ngd
+ @echo
+ @echo '*** Mapping design ***'
+ @echo
+ cd $(@D);$(XILINX_INIT) map -detail -u -p $(PART) -pr b -c 100 -o design_map.ncd design.ngd design.pcf
+
+# Rule for placing and routing a design
+$(PROJNAME)-synthdir/layout%/design.ncd: $(PROJNAME)-synthdir/layout%/design_map.ncd $(PROJNAME)-synthdir/layout%/design.pcf
+ @echo
+ @echo '*** Routing design ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) par -nopad -w -ol high design_map.ncd design.ncd design.pcf
+
+$(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd: $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ @echo
+ @echo '*** Creating post place and route netlist $* ***'
+ @echo
+ $(XILINX_INIT) netgen -w -ofmt vhdl $(@D)/design.ncd $@
+
+
+
+$(PROJNAME)-synthdir/layout%/design.twr: $(PROJNAME)-synthdir/layout%/design.ncd
+ @echo
+ @echo '*** Running static timing analysis ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) trce -v 1000 design.ncd design.pcf
+
+$(PROJNAME)-synthdir/layoutdefault/design.xdl: work $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ @echo
+ @echo '*** Creating XDL netlist ***'
+ @echo
+ cd $(@D); $(XILINX_INIT) xdl -w -ncd2xdl design.ncd
+
+
+$(PROJNAME)-synthdir/layoutdefault/design.bit: $(PROJNAME)-synthdir/layoutdefault/design.ncd
+ cd $(@D); $(XILINX_INIT) bitgen -w design.ncd
+
+
+# Duplicate the layout dependencies a couple of time with different
+# timespecs to enable parallel make to investigate several different
+# timing specs simultaneously on multi processor machines.
+#
+# Warning: You may have a limited amount of licenses for ISE!
+expandtimespec = $(shell echo 'scale=5;for(i=0;i<25;i+=1){$(1)-i*0.1;print " "}'|bc)
+$(PROJNAME)-synthdir/fmax.rpt: $(foreach i,$(call expandtimespec,$(TIMESPEC)),$(PROJNAME)-synthdir/layout$(i)/design.twr)
+ @echo
+ @echo '*** Maximum frequencies follow ***'
+ @echo
+ grep MHz $(PROJNAME)-synthdir/layout*/design.twr
+
+
+# The rules below are the only rules that are expected to actually be
+# called by a normal user of this makefile.
+
+%.bitgen: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.bit PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.fmax: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/fmax.rpt PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" TIMESPEC=$(TIMESPEC) INCDIRS="$(INCDIRS)"
+
+
+
+%.route: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.ncd PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.timing: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.twr PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" INCDIRS="$(INCDIRS)"
+
+%.xdl: dump_backendsettings
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/layoutdefault/design.xdl PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
diff --git a/lab4/build/xst.mk b/lab4/build/xst.mk
new file mode 100644
index 0000000..0610f14
--- /dev/null
+++ b/lab4/build/xst.mk
@@ -0,0 +1,130 @@
+# Command to initialize the Xilinx environment
+# (Feel free to change to the 64 bit version if necessary.)
+#XILINX_INIT = source /sw/xilinx/ise_11.1i/ISE/settings32.sh;
+#XILINX_INIT = source /extra/ise_11.1/ISE/settings32.sh;
+
+
+
+
+# This rule is responsible for creating the XST synthesis script and
+# the PRJ file containing the name of the files we want to synthesize
+
+.PRECIOUS: $(PROJNAME)-synthdir/%.scr $(PROJNAME)-synthdir/%.prj %.ncd $(PROJNAME)-synthdir/%.ngc $(PROJNAME)-synthdir/%.ngd $(PROJNAME)-synthdir/%_map.ncd $(PROJNAME)-synthdir/%.ncd $(PROJNAME)-synthdir/%.edf %.ncd %.bit
+
+$(PROJNAME)-synthdir/xst/synth/design.scr: $(S)
+ @echo
+ @echo '*** Creating synthesis scripts ***'
+ @echo
+ mkdir -p $(@D)
+# We first create the project file
+ @rm -f $@.tmp
+ @echo "set -tmpdir tmpdir" > $@.tmp
+ @echo "run -ifn design.prj" >> $@.tmp
+ @echo "-ofn design.ngc" >> $@.tmp
+# The following lines finds the first specified synthesizable file,
+# removes the file extension by using sed and then removing the
+# directory part of the file by using basename. This is then used as
+# our top module!
+ echo "-top $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))" >> $@.tmp
+ echo "-p $(PART)" >> $@.tmp
+ echo $(XST_OPT) >> $@.tmp
+# First enter all Verilog files into the project file, then all VHDL files
+ rm -f $(@D)/design.prj
+ touch $(@D)/design.prj
+ $(foreach i,$(filter %.v,$(S)), echo 'verilog work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ $(foreach i,$(filter %.vhd,$(S)), echo 'vhdl work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ $(foreach i,$(filter %.vhdl,$(S)), echo 'vhdl work "$(call fixpath3,$(i))"' >> $(@D)/design.prj;)
+ mv $@.tmp $@
+
+# Synthesize the design based on the synthesis script
+# Clean out temporary directories to be sure no stale data is left...
+$(PROJNAME)-synthdir/xst/synth/design.ngc: $(PROJNAME)-synthdir/xst/synth/design.scr
+ @echo
+ @echo '*** Synthesizing ***'
+ @echo
+ rm -rf $(@D)/tmpdir
+ mkdir -p $(@D)/tmpdir
+ rm -rf $(@D)/xst
+ mkdir -p $(@D)/xst
+ cd $(@D); $(XILINX_INIT) xst -ifn design.scr -ofn design.syr
+
+POSTSYNTHSIMNETLIST=$(PROJNAME)-synthdir/xst/synth/design_postsynth.vhd
+
+$(POSTSYNTHSIMNETLIST): $(PROJNAME)-synthdir/xst/synth/design.ngc
+ @echo
+ @echo '*** Creating post synthesis netlist $* ***'
+ @echo
+ $(XILINX_INIT) netgen -w -ofmt vhdl $(@D)/design.ngc $@
+
+
+MODELSIM_POSTSYNTH_OPTIONS=-L unisim
+
+
+
+# TODO: Don't recompile all files all the time!
+PARSIM: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ cp $(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf .
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+
+# TODO: Don't recompile all files all the time!
+PARSIMC: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//')) -c -do 'run -a; quit -f'
+
+
+# TODO: Don't recompile all files all the time!
+POWERSIM: work $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd SIMTBFILES
+ vcom +acc $(PROJNAME)-synthdir/layoutdefault/design_postpar.vhd
+ vsim -sdfmax /uut=$(PROJNAME)-synthdir/layoutdefault/design_postpar.sdf -do 'vcd file activity.vcd;vcd add -r -internal -in -out uut/*; vcd on;run -a;vcd off;vcd flush;quit -f' -c -L simprim $$(basename $$(echo $(firstword $(T)) | sed 's/\..*$$//'))
+ $(XILINX_INIT) xpwr -v -a -s activity.vcd $(PROJNAME)-synthdir/layoutdefault/design.ncd
+
+$(PROJNAME)-synthdir/synth/design.ngc: $(PROJNAME)-synthdir/xst/synth/design.ngc
+ mkdir -p $(@D)
+ cp $< $@
+
+export XST_EXTRA_OPTIONS
+
+
+
+dump_synthsettings:
+ @echo
+ @echo " *** Important settings for the Synthesis module ***"
+ @echo
+ @echo " Synthesis top module: $$(basename $$(echo $(firstword $(S)) | sed 's/\..*$$//'))"
+ @echo " Files to synthesize: $(S)"
+ @echo " Include directories: $(INCDIRS)"
+ @echo " FPGA part (PART): $(PART)"
+ @echo " Extra options to XST: $(XST_EXTRA_OPTIONS) (FIXME - not implemented yet in Makefile!)"
+ @echo
+
+
+
+%.synth: sanitychecksynth
+ $(NICE) $(MAKE) -f Makefile $*-synthdir/synth/design.ngc PROJNAME="$*"
+
+
+
+
+
+
+%.synthsim:
+ $(NICE) $(MAKE) -f Makefile SYNTHSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+%.parsim:
+ $(NICE) $(MAKE) -f Makefile PARSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+
+
+%.parsimc:
+ $(NICE) $(MAKE) -f Makefile PARSIMC PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+%.powersim:
+ $(NICE) $(MAKE) -f Makefile POWERSIM PROJNAME="$*" S="$(S)" U="$(U)" XST_OPT="$(XST_OPT)" PART="$(PART)" T="$(T)" INCDIRS="$(INCDIRS)"
+
+
+
+
+
+
+
diff --git a/lab4/sanitycheck b/lab4/sanitycheck
new file mode 100644
index 0000000..acdcc99
--- /dev/null
+++ b/lab4/sanitycheck
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if sed 's/--.*//' < "$1" | grep -n \'event
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet 'event. Om du vill kolla efter en klockflank bör rising_edge anvÀndas istÀllet. Om du vill anvÀnda 'event till nÄgot annat i syntetiserbar kod bör du antagligen tÀnka om."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'rising_edge *\(.*\)' | egrep -v 'rising_edge *\( *clk *\)'
+then
+ echo "ERROR in $1: Du försöker klocka pÄ nÄgot som antagligen inte Àr en riktigt klocka. Du bör enbart anvÀnda rising_edge(clk) i din syntetiserbara kod."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'falling_edge'
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet falling_edge i filen $1. I den hÀr kursen bör du inte behöva anvÀnda det nyckelordet."
+ exit 1
+fi
+
+
diff --git a/lab4/sanitycheck.sh b/lab4/sanitycheck.sh
new file mode 100644
index 0000000..acdcc99
--- /dev/null
+++ b/lab4/sanitycheck.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if sed 's/--.*//' < "$1" | grep -n \'event
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet 'event. Om du vill kolla efter en klockflank bör rising_edge anvÀndas istÀllet. Om du vill anvÀnda 'event till nÄgot annat i syntetiserbar kod bör du antagligen tÀnka om."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'rising_edge *\(.*\)' | egrep -v 'rising_edge *\( *clk *\)'
+then
+ echo "ERROR in $1: Du försöker klocka pÄ nÄgot som antagligen inte Àr en riktigt klocka. Du bör enbart anvÀnda rising_edge(clk) i din syntetiserbara kod."
+ exit 1
+fi
+
+if sed 's/--.*//' < "$1" | egrep -n 'falling_edge'
+then
+ echo "ERROR in $1: Du anvÀnder nyckelordet falling_edge i filen $1. I den hÀr kursen bör du inte behöva anvÀnda det nyckelordet."
+ exit 1
+fi
+
+