Index: FPGA/FTU/FTU_dac_control.vhd
===================================================================
--- FPGA/FTU/FTU_dac_control.vhd	(revision 156)
+++ FPGA/FTU/FTU_dac_control.vhd	(revision 156)
@@ -0,0 +1,180 @@
+----------------------------------------------------------------------------------
+-- Company:        ETH Zurich, Institute for Particle Physics
+-- Engineer:       P. Vogler, Q. Weitzel
+-- 
+-- Create Date:    16:24:08 01/19/2010 
+-- Design Name: 
+-- Module Name:    FTU_dac_control - Behavioral 
+-- Project Name: 
+-- Target Devices: 
+-- Tool versions: 
+-- Description:    control DAC on FTU board to set trigger thresholds 
+--
+-- Dependencies: 
+--
+-- Revision: 
+-- Revision 0.01 - File Created
+-- Additional Comments: 
+--
+----------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+---- Uncomment the following library declaration if instantiating
+---- any Xilinx primitives in this code.
+--library UNISIM;
+--use UNISIM.VComponents.all;
+
+entity FTU_dac_control is
+  port(
+    clk      : IN     STD_LOGIC;
+    reset    : IN     STD_LOGIC;
+    miso     : IN     STD_LOGIC;
+    clr      : OUT    STD_LOGIC;
+    mosi     : OUT    STD_LOGIC;
+    sck      : OUT    STD_LOGIC;
+    cs_ld    : OUT    STD_LOGIC
+  );
+end FTU_dac_control;
+
+architecture Behavioral of FTU_dac_control is
+
+  constant RESET_ACTIVE : std_logic := '0';
+  
+  component spi_interface_16
+    port(
+      clk              : IN    STD_LOGIC;
+      clkdiv           : IN    STD_LOGIC_VECTOR (1 DOWNTO 0);
+      cpha             : IN    STD_LOGIC;
+      cpol             : IN    STD_LOGIC;
+      miso             : IN    STD_LOGIC;
+      rcv_cpol         : IN    STD_LOGIC;
+      rcv_full_reset   : IN    STD_LOGIC;
+      reset            : IN    STD_LOGIC;
+      ss_in_n          : IN    STD_LOGIC;
+      ss_mask_reg      : IN    STD_LOGIC_VECTOR (7 DOWNTO 0);
+      start            : IN    STD_LOGIC;
+      xmit_data        : IN    STD_LOGIC_VECTOR (15 DOWNTO 0);
+      xmit_empty_reset : IN    STD_LOGIC;
+      rcv_load         : INOUT STD_LOGIC;
+      sck              : INOUT STD_LOGIC;
+      ss_in_int        : INOUT STD_LOGIC;
+      ss_n_int         : INOUT STD_LOGIC;
+      xmit_empty       : INOUT STD_LOGIC;
+      done             : OUT   STD_LOGIC;
+      mosi             : OUT   STD_LOGIC;
+      rcv_data         : OUT   STD_LOGIC_VECTOR (15 DOWNTO 0);
+      rcv_full         : OUT   STD_LOGIC;
+      ss_n             : OUT   STD_LOGIC_VECTOR (7 DOWNTO 0)
+    );
+  end component;
+
+  component upcnt16
+    port(
+      full  : out STD_LOGIC;
+      clr   : in  STD_LOGIC;
+      reset : in  STD_Logic;
+      clk   : in  STD_LOGIC
+    );
+  end component;
+
+  signal clk_sig          : std_logic;
+  signal done_sig         : std_logic;
+  signal start_sig        : std_logic;
+  signal slave_select_sig : std_logic;
+  signal full_sig         : std_logic;
+  signal clr_wcnt_sig     : std_logic;
+  signal s_clock_sig      : std_logic;
+  signal D_sig            : STD_LOGIC_VECTOR (15 DOWNTO 0);
+  signal ss_n_sig         : STD_LOGIC_VECTOR (7 DOWNTO 0);
+  signal reset_sig        : STD_LOGIC;
+  signal reset_sig_inv    : STD_LOGIC;
+
+  -- Build an enumerated type for the state machine
+  type state_type is (Idle);
+
+  -- Register to hold the current state
+  signal state, next_state: state_type;
+  
+begin
+
+  reset_sig <= reset;
+  reset_sig_inv <= not(reset);
+  clk_sig <= clk;
+  sck <= s_clock_sig;
+  clr <= reset_sig_inv;
+  cs_ld <= ss_n_sig(0);
+
+  -- FSM for dac control: first process
+  FSM_Registers: process(clk_sig, reset_sig)
+  begin
+    if reset_sig = '1' then
+      state <= Idle;
+    elsif Rising_edge(clk_sig) then
+      state <= next_state;
+    end if;
+  end process;
+
+  -- FSM for dac control: second process
+  FSM_logic: process(state)
+  begin
+    next_state <= state;
+    case state is
+      when Idle =>
+        D_sig <= "0001000100000000";
+        start_sig <= '0';
+        slave_select_sig <= '0';
+        clr_wcnt_sig <= '0';
+    end case;
+  end process;
+    
+  Inst_spi_interface_16 : spi_interface_16
+    port map(
+      clk=>clk_sig, clkdiv(1)=>'0', clkdiv(0)=>'0',
+      cpha=>'1', cpol=>'1', miso=>'1', rcv_cpol=>'1',
+      rcv_full_reset=>not(RESET_ACTIVE), reset=>reset_sig_inv, ss_in_n=>'1',
+      ss_mask_reg(7)=>'0', ss_mask_reg(6)=>'0',
+      ss_mask_reg(5)=>'0', ss_mask_reg(4)=>'0',
+      ss_mask_reg(3)=>'0', ss_mask_reg(2)=>'0',
+      ss_mask_reg(1)=>'0', ss_mask_reg(0)=>slave_select_sig,
+      start=>start_sig,
+      xmit_data(15)=>D_sig(15), xmit_data(14)=>D_sig(14),
+      xmit_data(13)=>D_sig(13), xmit_data(12)=>D_sig(12),
+      xmit_data(11)=>D_sig(11), xmit_data(10)=>D_sig(10),
+      xmit_data(9)=>D_sig(9),   xmit_data(8)=>D_sig(8),
+      xmit_data(7)=>D_sig(7),   xmit_data(6)=>D_sig(6),
+      xmit_data(5)=>D_sig(5),   xmit_data(4)=>D_sig(4),
+      xmit_data(3)=>D_sig(3),   xmit_data(2)=>D_sig(2),
+      xmit_data(1)=>D_sig(1),   xmit_data(0)=>D_sig(0),
+      xmit_empty_reset=>RESET_ACTIVE,
+      rcv_load=>open,
+      sck=>s_clock_sig,
+      ss_in_int=>open,
+      ss_n_int=>open,
+      xmit_empty=>open,
+      done=>done_sig, mosi=>mosi,rcv_data=>open,
+      --rcv_data(15)=>open, rcv_data(14)=>open,
+      --rcv_data(13)=>open, rcv_data(12)=>open,
+      --rcv_data(11)=>open, rcv_data(10)=>open,
+      --rcv_data(9)=>open,  rcv_data(8)=>open,
+      --rcv_data(7)=>open,  rcv_data(6)=>open,
+      --rcv_data(5)=>open,  rcv_data(4)=>open,
+      --rcv_data(3)=>open,  rcv_data(2)=>open,
+      --rcv_data(1)=>open,  rcv_data(0)=>open,
+      rcv_full=>open,ss_n=>ss_n_sig
+      --ss_n(7)=>open, ss_n(6)=>open, ss_n(5)=>open, ss_n(4)=>open,
+      --ss_n(3)=>open, ss_n(2)=>open, ss_n(1)=>open, ss_n(0)=>cs_ld
+    );
+
+  wait_cnt: upcnt16
+    port map(
+      full  => full_sig,
+      clr   => clr_wcnt_sig,
+      reset => reset_sig,
+      clk   => clk_sig
+    );
+  
+end Behavioral;
+
Index: FPGA/FTU/FTU_top_tb.vhd
===================================================================
--- FPGA/FTU/FTU_top_tb.vhd	(revision 156)
+++ FPGA/FTU/FTU_top_tb.vhd	(revision 156)
@@ -0,0 +1,126 @@
+--------------------------------------------------------------------------------
+-- Company:       ETH Zurich, Institute for Particle Physics
+-- Engineer:      P. Vogler, Q. Weitzel
+--
+-- Create Date:   14:57:43 01/19/2010
+-- Design Name:   
+-- Module Name:   /home/qweitzel/FPGA/FACT/FTU/source/FTU_top_tb.vhd
+-- Project Name:  FTUsim01
+-- Target Device:  
+-- Tool versions:  
+-- Description:   Testbench for top level entity of FACT FTU board 
+-- 
+-- VHDL Test Bench Created by ISE for module: FTU_top
+-- 
+-- Dependencies:
+-- 
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+-- Notes: 
+-- This testbench has been automatically generated using types std_logic and
+-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
+-- that these types always be used for the top-level I/O of a design in order
+-- to guarantee that the testbench will bind correctly to the post-implementation 
+-- simulation model.
+--------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+use IEEE.NUMERIC_STD.ALL;
+ 
+entity FTU_top_tb is
+end FTU_top_tb;
+
+architecture behavior of FTU_top_tb is 
+
+  -- Component Declaration for the Unit Under Test (UUT)
+ 
+  component FTU_top
+    port(
+      ext_clk   : IN  STD_LOGIC;
+      brd_add   : IN  STD_LOGIC_VECTOR(7 downto 0);
+      patch1    : IN  STD_LOGIC;
+      patch2    : IN  STD_LOGIC;
+      patch3    : IN  STD_LOGIC;
+      patch4    : IN  STD_LOGIC;
+      trig_prim : IN  STD_LOGIC;
+      miso      : IN  STD_LOGIC;
+      rx        : IN  STD_LOGIC;
+      enables   : OUT STD_LOGIC_VECTOR(35 downto 0);
+      clr       : OUT STD_LOGIC;
+      cs_ld     : OUT STD_LOGIC;
+      sck       : OUT STD_LOGIC;
+      mosi      : OUT STD_LOGIC;
+      tx        : OUT STD_LOGIC
+    );
+  end component;
+    
+  --Inputs
+  signal ext_clk   : STD_LOGIC := '0';
+  signal brd_add   : STD_LOGIC_VECTOR(7 downto 0) := (others => '0');
+  signal patch1    : STD_LOGIC := '0';
+  signal patch2    : STD_LOGIC := '0';
+  signal patch3    : STD_LOGIC := '0';
+  signal patch4    : STD_LOGIC := '0';
+  signal trig_prim : STD_LOGIC := '0';
+  signal miso      : STD_LOGIC := '0';
+  signal rx        : STD_LOGIC := '0';
+
+  --Outputs
+  signal enables : STD_LOGIC_VECTOR(35 downto 0);
+  signal clr     : STD_LOGIC;
+  signal cs_ld   : STD_LOGIC;
+  signal sck     : STD_LOGIC;
+  signal mosi    : STD_LOGIC;
+  signal tx      : STD_LOGIC;
+  
+  -- Clock period definitions
+  constant ext_clk_period : TIME := 20 ns;
+ 
+begin
+ 
+  -- Instantiate the Unit Under Test (UUT)
+  uut: FTU_top
+    port map(
+      ext_clk   => ext_clk,
+      brd_add   => brd_add,
+      patch1    => patch1,
+      patch2    => patch2,
+      patch3    => patch3,
+      patch4    => patch4,
+      trig_prim => trig_prim,
+      miso      => miso,
+      rx        => rx,
+      enables   => enables,
+      clr       => clr,
+      cs_ld     => cs_ld,
+      sck       => sck,
+      mosi      => mosi,
+      tx        => tx
+    );
+
+  -- Clock process definitions
+  ext_clk_proc: process
+  begin
+    ext_clk <= '0';
+    wait for ext_clk_period/2;
+    ext_clk <= '1';
+    wait for ext_clk_period/2;
+  end process ext_clk_proc;
+ 
+  -- Stimulus process
+  stim_proc: process
+  begin		
+    -- hold reset state for 100ms.
+    wait for 100ms;	
+    
+    wait for ext_clk_period*10;
+
+    -- insert stimulus here 
+
+    wait;
+  end process stim_proc;
+
+end;
Index: FPGA/FTU/counter/upcnt16.vhd
===================================================================
--- FPGA/FTU/counter/upcnt16.vhd	(revision 156)
+++ FPGA/FTU/counter/upcnt16.vhd	(revision 156)
@@ -0,0 +1,53 @@
+-- File:     upcnt16.vhd
+--
+-- Purpose:  Up 16-bit counter
+--
+-- Created:  7-25-00 ALS
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity upcnt16 is
+  port(
+    full  : out STD_LOGIC;
+    clr   : in  STD_LOGIC;
+    reset : in  STD_Logic;
+    clk   : in  STD_LOGIC
+  );
+
+end upcnt16;
+
+architecture DEFINITION of upcnt16 is
+
+  constant RESET_ACTIVE : std_logic := '0';
+  constant Cnt_full     : Unsigned (15 DOWNTO 0) :="1111111111111111";
+  
+  signal q : Unsigned (15 DOWNTO 0);
+
+begin
+  
+  process(clk, reset, clr)
+  begin
+    
+    if ((reset OR clr)='1') then
+      q <= (others => '0');-- Clear output register      
+    elsif (clk'event) and clk = '1' and (not(q = Cnt_full)) then-- On rising edge of clock count
+      q <= q + 1;
+    end if;
+    
+  end process;
+  
+  process(q)
+  begin
+    
+    if (q = Cnt_full) then
+      full <= '1';
+    else
+      full <= '0';
+    end if;
+    
+  end process;
+
+end DEFINITION;
Index: FPGA/FTU/counter/upcnt5.vhd
===================================================================
--- FPGA/FTU/counter/upcnt5.vhd	(revision 156)
+++ FPGA/FTU/counter/upcnt5.vhd	(revision 156)
@@ -0,0 +1,59 @@
+-- File:     upcnt5.vhd
+-- 
+-- Author:   Jennifer Jenkins
+-- Purpose:  Up 5-bit counter
+--
+-- Created:  5-3-99 JLJ
+-- Revised:  6-15-99 ALS
+
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified by Patrick Vogler
+--  18th November 2009
+--
+--  Counter width extended from 4 to 5 bit in order to extend the SPI interface from
+--  8 to 16 bit word size
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  21th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity upcnt5 is --*Mod: 4 to 5 bit
+  port(    
+    cnt_en       : in STD_LOGIC;                        -- Count enable          -- Load line enable
+    clr          : in STD_LOGIC;                        -- Active low clear
+    clk          : in STD_LOGIC;                        -- Clock
+    qout         : inout STD_LOGIC_VECTOR (4 downto 0)  --*Mod: 4 to 5 bit
+  );        
+end upcnt5;
+
+architecture DEFINITION of upcnt5 is
+
+constant RESET_ACTIVE : std_logic := '0';
+
+signal q_int : UNSIGNED (4 downto 0);  --*Mod: 4 to 5 bit
+
+begin
+
+  process(clk, clr)
+  begin  
+    -- Clear output register
+    if (clr = RESET_ACTIVE) then
+      q_int <= (others => '0');
+      -- On falling edge of clock count
+    elsif (clk'event) and clk = '1' then
+      if cnt_en = '1' then
+        q_int <= q_int + 1;
+      end if;
+    end if;
+  end process;
+
+  qout <= STD_LOGIC_VECTOR(q_int);
+
+end DEFINITION;
Index: FPGA/FTU/ip_cores/FTU_dac_dcm.vhd
===================================================================
--- FPGA/FTU/ip_cores/FTU_dac_dcm.vhd	(revision 156)
+++ FPGA/FTU/ip_cores/FTU_dac_dcm.vhd	(revision 156)
@@ -0,0 +1,90 @@
+--------------------------------------------------------------------------------
+-- Copyright (c) 1995-2009 Xilinx, Inc.  All rights reserved.
+--------------------------------------------------------------------------------
+--   ____  ____ 
+--  /   /\/   / 
+-- /___/  \  /    Vendor: Xilinx 
+-- \   \   \/     Version : 11.1
+--  \   \         Application : xaw2vhdl
+--  /   /         Filename : FTU_dac_dcm.vhd
+-- /___/   /\     Timestamp : 01/20/2010 16:36:17
+-- \   \  /  \ 
+--  \___\/\___\ 
+--
+--Command: xaw2vhdl-st /home/qweitzel/FPGA/FACT/FTU/source/ip_cores/FTU_dac_dcm.xaw /home/qweitzel/FPGA/FACT/FTU/source/ip_cores/FTU_dac_dcm
+--Design Name: FTU_dac_dcm
+--Device: xc3s400an-4fgg400
+--
+-- Module FTU_dac_dcm
+-- Generated by Xilinx Architecture Wizard
+-- Written for synthesis tool: XST
+-- Period Jitter (unit interval) for block DCM_SP_INST = 0.03 UI
+-- Period Jitter (Peak-to-Peak) for block DCM_SP_INST = 6.54 ns
+
+library ieee;
+use ieee.std_logic_1164.ALL;
+use ieee.numeric_std.ALL;
+library UNISIM;
+use UNISIM.Vcomponents.ALL;
+
+entity FTU_dac_dcm is
+   port ( CLKIN_IN        : in    std_logic; 
+          RST_IN          : in    std_logic; 
+          CLKFX_OUT       : out   std_logic; 
+          CLKIN_IBUFG_OUT : out   std_logic; 
+          LOCKED_OUT      : out   std_logic);
+end FTU_dac_dcm;
+
+architecture BEHAVIORAL of FTU_dac_dcm is
+   signal CLKFX_BUF       : std_logic;
+   signal CLKIN_IBUFG     : std_logic;
+   signal GND_BIT         : std_logic;
+begin
+   GND_BIT <= '0';
+   CLKIN_IBUFG_OUT <= CLKIN_IBUFG;
+   CLKFX_BUFG_INST : BUFG
+      port map (I=>CLKFX_BUF,
+                O=>CLKFX_OUT);
+   
+   CLKIN_IBUFG_INST : IBUFG
+      port map (I=>CLKIN_IN,
+                O=>CLKIN_IBUFG);
+   
+   DCM_SP_INST : DCM_SP
+   generic map( CLK_FEEDBACK => "NONE",
+            CLKDV_DIVIDE => 2.0,
+            CLKFX_DIVIDE => 20,
+            CLKFX_MULTIPLY => 2,
+            CLKIN_DIVIDE_BY_2 => FALSE,
+            CLKIN_PERIOD => 20.000,
+            CLKOUT_PHASE_SHIFT => "NONE",
+            DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
+            DFS_FREQUENCY_MODE => "LOW",
+            DLL_FREQUENCY_MODE => "LOW",
+            DUTY_CYCLE_CORRECTION => TRUE,
+            FACTORY_JF => x"C080",
+            PHASE_SHIFT => 0,
+            STARTUP_WAIT => FALSE)
+      port map (CLKFB=>GND_BIT,
+                CLKIN=>CLKIN_IBUFG,
+                DSSEN=>GND_BIT,
+                PSCLK=>GND_BIT,
+                PSEN=>GND_BIT,
+                PSINCDEC=>GND_BIT,
+                RST=>RST_IN,
+                CLKDV=>open,
+                CLKFX=>CLKFX_BUF,
+                CLKFX180=>open,
+                CLK0=>open,
+                CLK2X=>open,
+                CLK2X180=>open,
+                CLK90=>open,
+                CLK180=>open,
+                CLK270=>open,
+                LOCKED=>LOCKED_OUT,
+                PSDONE=>open,
+                STATUS=>open);
+   
+end BEHAVIORAL;
+
+
Index: FPGA/FTU/ip_cores/FTU_dac_dcm_arwz.ucf
===================================================================
--- FPGA/FTU/ip_cores/FTU_dac_dcm_arwz.ucf	(revision 156)
+++ FPGA/FTU/ip_cores/FTU_dac_dcm_arwz.ucf	(revision 156)
@@ -0,0 +1,17 @@
+# Generated by Xilinx Architecture Wizard
+# --- UCF Template Only ---
+# Cut and paste these attributes into the project's UCF file, if desired
+INST DCM_SP_INST CLK_FEEDBACK = NONE;
+INST DCM_SP_INST CLKDV_DIVIDE = 2.0;
+INST DCM_SP_INST CLKFX_DIVIDE = 20;
+INST DCM_SP_INST CLKFX_MULTIPLY = 2;
+INST DCM_SP_INST CLKIN_DIVIDE_BY_2 = FALSE;
+INST DCM_SP_INST CLKIN_PERIOD = 20.000;
+INST DCM_SP_INST CLKOUT_PHASE_SHIFT = NONE;
+INST DCM_SP_INST DESKEW_ADJUST = SYSTEM_SYNCHRONOUS;
+INST DCM_SP_INST DFS_FREQUENCY_MODE = LOW;
+INST DCM_SP_INST DLL_FREQUENCY_MODE = LOW;
+INST DCM_SP_INST DUTY_CYCLE_CORRECTION = TRUE;
+INST DCM_SP_INST FACTORY_JF = C080;
+INST DCM_SP_INST PHASE_SHIFT = 0;
+INST DCM_SP_INST STARTUP_WAIT = FALSE;
Index: FPGA/FTU/spi_interface/sck_logic_16.vhd
===================================================================
--- FPGA/FTU/spi_interface/sck_logic_16.vhd	(revision 156)
+++ FPGA/FTU/spi_interface/sck_logic_16.vhd	(revision 156)
@@ -0,0 +1,233 @@
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  File:          sck_logic_16.vhd
+--
+--
+--  Original file: sck_logic.vhd
+--
+
+--  Created: 8-23-00 ALS
+--  This file generates an internal SCK by dividing the system clock as determined by CLKDIV.
+--  This internal SCK has a CPHA=1 relationship to data and is used to clock the internal SPI
+--  shift register. This internal SCK is used to generate the desired output SCK as determined
+--  by CPHA and CPOL in the control register. The SCK output to the SPI bus is output only when
+--  the slave select signals are asserted, but the internal SCK runs continuously.
+--
+--  Revised: 8-28-00 ALS
+--  Revised: 9-11-00 ALS
+--  Revised: 10-17-00 ALS
+
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified from 8 to 16 bit word size by Patrick Vogler
+--  18th November 2009
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  21th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity sck_logic is
+  port(  
+    -- internal uC interface signals
+    clkdiv     : in    std_logic_vector(1 downto 0);   -- sets the clock divisor for sck clock
+    cpha       : in    std_logic;  -- sets clock phase for output sck clock
+    cpol       : in    std_logic;  -- sets clock polarity for output sck clock
+         
+    -- internal spi interface signals
+    clk0_mask  : in    std_logic;  -- clock mask for sck when cpha=0
+    clk1_mask  : in    std_logic;  -- clock mask for sck when cpha=1
+    sck_1      : inout std_logic;  -- internal sck created from dividing system clock
+    sck_int_re : out   std_logic;  -- rising edge of internal sck
+    sck_int_fe : out   std_logic;  -- falling edge of internal sck
+    sck_re     : out   std_logic;  -- rising edge of external sck
+    sck_fe     : out   std_logic;  -- falling edge of external sck
+    ss_in_int  : in    std_logic;  -- another master is on the bus
+         
+    -- external spi interface signals
+    sck        : inout std_logic;      -- sck as determined by cpha, cpol, and clkdiv
+         
+    -- clock and reset
+    reset      : in    std_logic;  -- active high reset    
+    clk        : in    std_logic   -- clock
+    
+  );
+        
+end sck_logic;
+
+architecture DEFINITION of sck_logic is
+
+--**************************** Constants ***************************************
+
+constant RESET_ACTIVE   : std_logic := '0';
+
+--**************************** Signals ***************************************
+
+signal clk_cnt      : STD_LOGIC_VECTOR(4 downto 0); -- clock divider output
+signal clk_cnt_en   : STD_LOGIC;            -- count enable for clock divider
+signal clk_cnt_rst  : STD_LOGIC;            -- clock count reset
+
+
+signal sck_int_d1   : STD_LOGIC;    -- sck_int delayed one clock for edge detection
+signal sck_int      : STD_LOGIC;    -- version of sck when CPHA=1
+signal sck_0        : STD_LOGIC;    -- version of sck when CPHA=0
+signal sck_out      : STD_LOGIC;    -- sck to be output if SS_IN_INT is not asserted
+signal sck_d1       : std_logic;    -- output sck delayed one clock for edge detection
+
+
+--**************************** Component Definitions  ********************************
+-- 5-bit counter for clock divider
+component upcnt5
+  port(          
+    cnt_en       : in STD_LOGIC;                        -- Count enable                      
+    clr          : in STD_LOGIC;                        -- Active high clear
+    clk          : in STD_LOGIC;                        -- Clock
+    qout         : inout STD_LOGIC_VECTOR (4 downto 0)    
+  );
+        
+end component;
+
+begin
+
+  --************************** Clock Divider Instantiation ********************************
+  CLK_DIVDR : upcnt5
+    port map(          
+      cnt_en       => clk_cnt_en,
+      clr          => clk_cnt_rst,
+      clk          => clk,
+      qout         => clk_cnt
+    );
+  -- This counter is always enabled, can't instantiate the counter with a literal
+  clk_cnt_en <= '1';
+
+  -- Clock counter is reset whenever reset is active and ss_in_int is asserted
+  clk_cnt_rst <= RESET_ACTIVE when reset = RESET_ACTIVE or ss_in_int = '0'
+                 else not(RESET_ACTIVE);
+
+  --************************** Internal SCK Generation ***************************************
+  -- SCK when CPHA=1 is simply the output of the clock divider determined by the CLK_DIV bits
+  -- SCK_INT is based off the CPHA=1 waveforms and is used as the internal SCK
+  -- SCK_INT is used to clock the SPI shift register, therefore, it runs before and after SS_N
+  -- is asserted
+  -- SCK_1 is SCK_INT when clk1_mask = 1. The clock mask blocks SCK_INT edges that are before
+  -- and after SS_N
+  sck_int_process: process (clk,reset)
+  begin
+    if reset = RESET_ACTIVE  then
+      sck_int <= '0';
+    elsif clk'event and clk = '1' then    
+      -- determine clock divider output based on control register
+      case clkdiv is
+        when "00" =>
+          sck_int <= clk_cnt(1);
+        when "01" =>
+          sck_int <= clk_cnt(2);
+        when "10" =>
+          sck_int <= clk_cnt(3);
+        when "11" =>
+          sck_int <= clk_cnt(4);
+        when others =>  -- error in register
+          sck_int <= '0';
+      end case;
+    end if;
+  end process;
+
+  sck_1 <= sck_int and clk1_mask;
+
+  -- Detect rising and falling edges of SCK_1 to use as state transition
+  sck_intedge_process: process(clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      sck_int_d1 <= '0';
+    elsif clk'event and clk = '1' then
+      sck_int_d1 <= sck_int;
+    end if;
+  end process;
+
+  sck_int_re <= '1' when sck_int = '1' and sck_int_d1 = '0'
+                else '0';
+  sck_int_fe <= '1' when sck_int = '0' and sck_int_d1 = '1'
+                else '0';
+
+  -- SCK when CPHA=0 is out of phase with internal SCK - therefore its toggle needs to be delayed
+  -- by the signal clk_mask and then its simply an inversion of the counter bit
+
+  sck_0_process: process (clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      sck_0 <= '0';
+    elsif clk'event and clk = '1' then        
+      if clk0_mask = '0' then
+        sck_0 <= '0';
+      else
+        case clkdiv is
+          when "00" =>
+            sck_0 <= not(clk_cnt(1));
+          when "01" =>
+            sck_0 <= not(clk_cnt(2));
+          when "10" =>
+            sck_0 <= not(clk_cnt(3));
+          when "11" =>
+            sck_0 <= not(clk_cnt(4));
+          when others =>  -- error in register
+            sck_0 <= '0';
+        end case;
+      end if;
+    end if;
+  end process;
+
+  --************************** External SCK Generation **********************************
+  -- This process outputs SCK based on the CPHA and CPOL parameters set in the control register
+  sck_out_process: process(clk, reset, cpol)
+    variable temp:  std_logic_vector(1 downto 0);
+  begin
+    if reset = RESET_ACTIVE then
+      sck_out <= '0';
+    elsif clk'event and clk = '1' then
+      temp := cpol & cpha;
+      case temp is
+        when "00" =>    -- polarity = 0, phase = 0
+          -- sck = sck_0
+          sck_out <= sck_0;
+        when "01" =>    -- polarity= 0, phase = 1
+          -- sck = sck_1
+          sck_out <= sck_1;
+        when "10" =>    -- polarity = 1, phase = 0
+          -- sck = not(sck_0)
+          sck_out <= not(sck_0);
+        when "11" =>    -- polarity = 1, phase = 1
+          -- sck = not(sck_1)
+          sck_out <= not(sck_1);
+        when others =>  -- default to sck_0
+          sck_out <= sck_0;
+      end case;
+    end if;
+  end process;
+
+  -- Detect rising and falling edges of SCK_OUT to use to end cycle correctly
+  -- and to keep RCV_LOAD signal 1 system clock in width
+  SCK_DELAY_PROCESS: process(clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      sck_d1 <= '0';
+    elsif clk'event and clk = '1' then
+      sck_d1 <= sck_out;
+    end if;
+  end process;
+
+  sck_re <= '1' when sck_out = '1' and sck_d1 = '0'
+            else '0';
+  sck_fe <= '1' when sck_out = '0' and sck_d1 = '1'
+            else '0';
+
+  -- The SCK output is 3-stated if the SS_IN_INT signal is asserted indicating that another
+  -- master is on the bus
+  sck <= sck_out when ss_in_int = '1'
+         else    'Z';
+
+end DEFINITION;
Index: FPGA/FTU/spi_interface/spi_control_sm_16.vhd
===================================================================
--- FPGA/FTU/spi_interface/spi_control_sm_16.vhd	(revision 156)
+++ FPGA/FTU/spi_interface/spi_control_sm_16.vhd	(revision 156)
@@ -0,0 +1,414 @@
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  File:          spi_control_sm_16.vhd
+--
+--
+--  Original file: spi_control_sm.vhd
+--
+--  Created:  8-23-00 ALS
+--  This file contains the overall control of the SPI interface. It generates the slave
+--  select signals and the masks so that the SCK signals output to the SPI bus align properly
+--  with the data. It generates the control signals to the shift register and the receive
+--  data register.
+--
+--  This SPI interface operates on bytes of data. When the START signal from the uC is
+--  asserted the byte-wide data in the SPI transmit register is transmitted on the SPI bus.
+--  When this transfer is complete, the BUSY signal is negated and the START signal is
+--  sampled. If the START signal is still asserted indicating that the uC has put new
+--  data in the SPI transmit register, the data in the transmit register will be transmitted.
+--  Each byte of data received from the SPI bus is captured in the receive register.The uC can
+--  read this data once the BUSY signal has negated.
+--
+--  Revised: 9-6-00 ALS
+--  Revised: 9-12-00 ALS
+--  Revised: 10-17-00 ALS
+--  Revised: 10-19-00 ALS
+--  Revised: 10-27-00 ALS
+--  Revised: 12-12-02 JRH
+
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified from 8 to 16 bit word size by Patrick Vogler
+--  18th November 2009
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  21th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity spi_control_sm is
+  port(
+    -- internal uC interface signals
+    start            : in    std_logic;                    -- start transfer
+    done             : out   std_logic;                    -- byte transfer is complete
+    rcv_load         : in    std_logic;                    -- load control signal to spi receive register
+    ss_mask_reg      : in    std_logic_vector(7 downto 0); -- uc slave select register, Caution! No modification, not word size
+    ss_in_int        : inout std_logic;                    -- internal sampled version of ss_in_n needed by uc to generate an interrupt
+    xmit_empty       : inout std_logic;                    -- flag indicating that spitr is empty
+    xmit_empty_reset : in    std_logic;                    -- xmit empty flag reset when spitr is written
+    rcv_full         : out   std_logic;                    -- flag indicating that spirr has new data
+    rcv_full_reset   : in    std_logic;                    -- rcv full flag reset when spirr is read
+    cpha             : in    std_logic;                    -- clock phase from uc
+    cpol             : in    std_logic;                    -- clock polarity from uc
+    
+    -- spi interface signals
+    ss_n             : out   std_logic_vector(7 downto 0); -- slave select signals Caution! NO modification slave select, not word size		
+    ss_in_n          : in    std_logic;                    -- input slave select indicating master bus contention
+    ss_n_int         : inout std_logic;                    -- internal ss_n that is masked with slave select register
+         
+    -- internal interface signals
+    sck_int        : in    std_logic;  -- internal version of sck with cpha=1
+    sck_int_re     : in    std_logic;  -- indicates rising edge on internal sck
+    sck_int_fe     : in    std_logic;  -- indicates falling edge on internal sck
+    sck_re         : in    std_logic;  -- indicates rising edge on external sck
+    sck_fe         : in    std_logic;  -- indicates falling edge on external sck
+    xmit_shift     : out   std_logic;  -- shift control signal to spi xmit shift register
+    xmit_load      : inout std_logic;  -- load control signal to the spi xmit shift register
+    clk1_mask      : out   std_logic;  -- masks cpha=1 version of sck
+    clk0_mask      : out   std_logic;  -- masks cpha=0 version of sck
+         
+    -- clock and reset
+    reset          : in    std_logic;  -- active low reset
+    clk            : in    std_logic   -- clock
+  );        
+end spi_control_sm;
+
+architecture DEFINITION of spi_control_sm is
+
+--**************************** Constants ***************************************
+
+constant RESET_ACTIVE   : std_logic := '0';
+
+constant SIXTEEN        : std_logic_vector(4 downto 0) := "10000"; -- *Mod: width changed from 4 to 5 bits, Caution! bit counter
+
+--**************************** Signals ***************************************
+
+type SPI_STATE_TYPE is (IDLE, ASSERT_SSN1, ASSERT_SSN2, UNMASK_SCK, XFER_BIT,
+                        ASSERT_DONE, CHK_START, MASK_SCK, HOLD_SSN1, HOLD_SSN2,
+                        NEGATE_SSN);
+
+signal spi_state, next_spi_state : SPI_STATE_TYPE;
+
+signal bit_cnt       : STD_LOGIC_VECTOR(4 downto 0); -- Caution! bit counter output *Mod: width changed from 4 to 5 bits
+signal bit_cnt_en    : STD_LOGIC;                    -- count enable for bit counter
+signal bit_cnt_rst   : STD_LOGIC;                    -- reset for bit counter from SPI control state machine
+signal bit_cnt_reset : STD_LOGIC;                    -- reset to bit counter that includes SS_IN_INT
+signal ss_in_neg     : STD_LOGIC;                    -- SS_IN_N sampled with rising edge of clk
+signal ss_in_pos     : STD_LOGIC;                    -- SS_IN_N sampled with negative edge of clk
+signal ss_n_out      : STD_LOGIC_VECTOR(7 downto 0); -- output SS_N that are 3-stated if SS_IN_INT is asserted indicating another master slave select,
+                                                     -- do not change width
+
+--**************************** Component Definitions  ********************************
+-- 5-bit counter for bit counter
+component upcnt5 --*Mod: 5 instead of 4 bit counter
+  port( 
+    cnt_en : in STD_LOGIC;                       -- Count enable                       
+    clr    : in STD_LOGIC;                       -- Active high clear
+    clk    : in STD_LOGIC;                       -- Clock
+    qout   : inout STD_LOGIC_VECTOR (4 downto 0) -- *Mod: 5 instead of 4 bit counter
+  );        
+end component;
+
+begin
+
+  --************************** Bit Counter Instantiation ********************************
+  BIT_CNTR : upcnt5 --*Mod: 5 instead of 4 bit counter
+    port map(
+      cnt_en       => bit_cnt_en,
+      clr          => bit_cnt_reset,
+      clk          => sck_int,
+      qout         => bit_cnt
+    );
+         
+  --************************** SS_IN_N Input synchronization *******************************
+  -- When the SS_IN_N input is asserted, it indicates that there is another master on the bus
+  -- that has selected this master as a slave. When this signal asserts, the SPI master needs
+  -- to reset and tristate outputs. Therefore, the SS_IN_N input should be synchronized with the
+  -- system clock to prevent glitches on this signal from reseting the SPI master. The proces
+  -- below first samples SS_IN_N with the rising edge of the system clock and the falling edge
+  -- of the system clock. If both of these samples show that the signal is asserted, then the
+  -- internal SS_IN_INT signal will assert. SS_IN_INT is passed to the uC logic to generate an
+  -- interrupt if interrupts have been enabled. It is also passed to the SCK logic and the
+  -- SPI Xmit shift register to tri-state the SCK and MOSI outputs.
+
+  ss_in_rising: process(clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      ss_in_pos <= '1';
+    elsif clk'event and clk = '1' then
+      ss_in_pos <= ss_in_n;
+    end if;
+  end process;
+
+  ss_in_falling: process (clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      ss_in_neg <= '1';
+    elsif clk'event and clk = '0' then
+      ss_in_neg <= ss_in_n;
+    end if;
+  end process;
+
+  ss_in_sample: process(clk,reset)
+  begin
+    if reset = RESET_ACTIVE then
+      ss_in_int <= '1';
+    elsif clk'event and clk = '1' then
+      if ss_in_pos = '0' and ss_in_neg = '0' then
+        ss_in_int <= '0';
+      else
+        ss_in_int <= '1';
+      end if;
+    end if;
+  end process;
+
+  --************************** Bit Counter reset ***************************************
+  -- The bit counter needs to be reset when the reset signal is asserted from the SPI control
+  -- state machine is asserted and when SS_IN_INT is asserted
+  -- is asserted
+  bit_cnt_reset <= RESET_ACTIVE when bit_cnt_rst = RESET_ACTIVE or ss_in_int = '0'
+                   else not(RESET_ACTIVE);
+
+  --************************** SPI Control State Machine *******************************
+  -- Register process registers next state signals
+  -- Return to IDLE state whenever SS_IN_INT is asserted
+
+  spi_sm_reg:process(clk, reset, ss_in_int)
+  begin
+    -- Set state to IDLE upon reset
+    if (reset = RESET_ACTIVE or ss_in_int = '0') then
+      spi_state <= IDLE;
+    elsif clk'event and clk = '1' then
+      spi_state <= next_spi_state;
+    end if;
+  end process;
+
+  -- Combinatorial process determines next state logic
+
+  spi_sm_comb: process(spi_state, start,bit_cnt, sck_re, sck_fe, sck_int_re, sck_int_fe,
+                       xmit_empty, cpha, cpol)
+
+  begin
+
+    -- set defaults
+    clk0_mask   <= '0';
+    clk1_mask   <= '0';
+    bit_cnt_en  <= '0';
+    bit_cnt_rst <= RESET_ACTIVE;
+    next_spi_state <= spi_state;
+    done        <= '0';
+    xmit_shift  <= '0';
+    xmit_load   <= '0';
+
+    case spi_state is
+      
+      --********************* IDLE State *****************
+      when IDLE =>
+        if start = '1' and xmit_empty = '0' then
+          next_spi_state <= ASSERT_SSN1;
+        end if;
+
+        --********************* ASSERT_SSN1 State *****************
+      when ASSERT_SSN1 =>
+        -- this state asserts SS_N and waits for first edge of SCK_INT
+        -- SS_N must be asserted ~1 SCK before SCK is output from chip     
+        if sck_int_re = '1' then
+          next_spi_state <= ASSERT_SSN2;
+        end if;
+            
+        --********************* ASSERT_SSN2 State *****************
+      when ASSERT_SSN2 =>
+        -- this state asserts SS_N and waits for next edge of SCK_INT
+        -- SS_N must be asserted ~1 SCK before SCK is output from chip
+        if sck_int_fe = '1' then
+          next_spi_state <= UNMASK_SCK;
+        end if;
+            
+        --********************* UNMASK_SCK State *****************
+      when UNMASK_SCK =>
+        bit_cnt_rst <= not(RESET_ACTIVE); -- release bit counter from reset
+        bit_cnt_en <= '1';  -- enable bit counter
+        clk1_mask <= '1';   -- unmask sck_1
+        xmit_load <= '1';   -- load SPI shift register
+        
+        if sck_int_re = '1' then
+          -- first rising edge of CPHA=1 clock with SS_N asserted
+          -- transition to XFER_BIT state and unmask CPHA=0 clk
+          next_spi_state <= XFER_BIT;
+        end if;
+        
+        --********************* XFER_BIT State *****************
+      when XFER_BIT =>
+        clk0_mask <= '1';   -- unmask CPHA=0 clock
+        clk1_mask <= '1';   -- unmask CPHA=1 clock
+        bit_cnt_en <= '1';  -- enable bit counter
+        bit_cnt_rst <= not(RESET_ACTIVE); -- release bit counter from reset
+        
+        xmit_shift <= '1';  -- enable shifting of SPI shift registers
+        
+        if bit_cnt = SIXTEEN  then       -- *Mod:  SIXTEEN instead of EIGHT bit
+          -- all 16 bits have transferred
+          next_spi_state <= ASSERT_DONE;
+        end if;
+        
+        --********************* ASSERT_DONE State *****************
+      when ASSERT_DONE =>
+        -- this state asserts done to the uC so that new data
+        -- can be written into the transmit register or data
+        -- can be read from the receive register
+        done <= '1';
+        clk0_mask <= '1';
+        clk1_mask <= '1';
+        xmit_shift <= '1';
+        if sck_int_fe = '1' then
+          next_spi_state <= CHK_START;
+        end if;
+        
+        --********************* CHK_START State *****************
+      when CHK_START =>
+        clk0_mask <= '1';
+        clk1_mask <= '1';
+        done <= '1';
+        bit_cnt_en <= '1';
+        bit_cnt_rst <= not(RESET_ACTIVE); -- release bit counter from reset
+        if cpha = '0' then
+          -- when CPHA = 0, have to negate slave select and then
+          -- re-assert it. Need to wait for last SCK pulse to complete
+          -- and mask SCK before negating SS_N.
+          if (sck_re = '1' and cpol = '1') or (sck_fe = '1' and cpol = '0') then
+            clk0_mask <= '0';
+            clk1_mask <= '0';
+            next_spi_state <= MASK_SCK;
+          end if;
+        elsif start = '1' and xmit_empty = '0' then
+          -- CPHA=1 and have more data to transfer, go back to
+          -- UNMASK_CK state
+          clk1_mask <= '1';
+          xmit_load <= '1';   -- load SPI shift register
+          next_spi_state <= UNMASK_SCK;
+        else
+          -- CPHA=1 and no more data to transfer
+          -- wait for last SCKs and then mask SCK
+          if (sck_re = '1' and cpol = '1') or (sck_fe = '1' and cpol = '0') then
+            clk0_mask <= '0';
+            clk1_mask <= '0';
+            next_spi_state <= MASK_SCK;
+          end if;
+          clk0_mask <= '0';
+          clk1_mask <= '1';
+        end if;
+        
+        --********************* MASK_SCK State *****************
+      when MASK_SCK =>
+        done <= '1';
+        -- wait for next internal SCK edge
+        -- to help provide SS_N hold time
+        if sck_int_fe <= '1' then
+          next_spi_state <= HOLD_SSN1;
+        end if;
+        
+        --********************* HOLD_SSN1 State *****************
+      when HOLD_SSN1 =>
+        -- This state waits for another SCK edge
+        -- to provide SS_N hold time
+        if  sck_int_fe = '1' then
+          next_spi_state <= HOLD_SSN2;
+        end if;
+        
+        --********************* HOLD_SSN2 State *****************
+      when HOLD_SSN2 =>
+        -- This state waits for another SCK edge
+        -- to provide SS_N hold time
+        if  sck_int_fe = '1' then
+          next_spi_state <= NEGATE_SSN;
+        end if;
+        
+        --********************* NEGATE_SSN State *****************
+      when NEGATE_SSN =>
+        -- SS_N should negate for an entire SCK
+        -- This state waits for an SCK edge
+        if sck_int_fe = '1' then
+          next_spi_state <= IDLE;
+        end if;
+        
+        --********************* Default State *****************
+      when others =>
+        next_spi_state <= IDLE;
+    end case;
+  end process;
+
+  -- assert slave select when spi_state machine is in any state but IDLE or NEGATE_SSN
+  ss_n_int <= '1' when (spi_state = IDLE or spi_state = NEGATE_SSN) else '0';
+
+  --xmit_load <= '1' when (spi_state = UNMASK_SCK) else '0';
+
+
+  --************************** Register Full/Empty flags *******************************
+  -- When data is loaded into the SPI transmit shift register from SPITR, the XMIT_EMPTY
+  -- flag is set, indicating to the uC that new data can be written into SPITR. Note that
+  -- the SPI transmit shift register is clocked from SCK, therefore, this flag is clocked
+  -- from SCK.
+  mt_flag_process: process (sck_int, xmit_empty_reset, reset)
+  begin
+    if xmit_empty_reset = RESET_ACTIVE or reset = RESET_ACTIVE then
+      xmit_empty <= '0';
+    elsif sck_int'event and sck_int = '1' then
+      if xmit_empty_reset = RESET_ACTIVE then
+        -- reset empty flag because uC has written data to SPITR
+        xmit_empty <= '0';
+      elsif xmit_load = '1' then
+        -- set empty flag because SPITR data has been loaded into
+        -- SPI transmit shift register
+        xmit_empty <= '1';
+      end if;
+    end if;
+  end process;
+
+  -- When data is loaded into SPIRR, the RCV_FULL flag is set, indicating to the uC that
+  -- new data from the SPI bus has been received.
+  full_flag_process: process (reset, clk)
+  begin
+    if reset = RESET_ACTIVE then
+      rcv_full <= '0';
+    elsif clk'event and clk = '1' then
+      if rcv_full_reset = RESET_ACTIVE then
+        -- reset the full flag because the spirr has been read
+        rcv_full <= '0';
+      elsif rcv_load = '1' then
+        -- set the full flag because data has been loaded in spirr
+        rcv_full <= '1';
+      end if;
+    end if;
+  end process;
+
+  --************************** Slave Selects *******************************
+  -- The internal slave select signal generated by the SPI Control state machine
+  -- is masked by the uC slave select register. The SS_N outputs are clocked on the
+  -- falling edge of the system clock.
+  ss_n_process: process ( reset, clk)
+    variable i : integer;
+
+  begin
+    if reset = RESET_ACTIVE then
+      ss_n_out <= (others => '1');
+    elsif clk'event and clk = '0' then
+      for i in 0 to 7 loop
+        if ss_n_int = '0' and ss_mask_reg (i) = '1' then
+          ss_n_out(i) <= '0';  -- assert corresponding slave select
+        else
+          ss_n_out(i) <= '1';
+        end if;
+      end loop;
+    end if;
+  end process;
+    
+  -- Slave selects are 3-stated if SS_IN_INT is asserted
+  ss_n <= ss_n_out when ss_in_int = '1'
+          else (others => 'Z');
+
+end DEFINITION;
Index: FPGA/FTU/spi_interface/spi_interface_16.vhd
===================================================================
--- FPGA/FTU/spi_interface/spi_interface_16.vhd	(revision 156)
+++ FPGA/FTU/spi_interface/spi_interface_16.vhd	(revision 156)
@@ -0,0 +1,226 @@
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  File:          spi_interface_16.vhd
+--
+--
+--  Original file: spi_interface.vhd
+--
+--  Created:  12-12-02 JRH
+--  This file contains the interconnect structure of the SPI interface portion of
+--  the SPI Master design.  It was originally created in schematic form, but was
+--  converted to VHDL from the VHF file generated by the ECS tool.
+--
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified from 8 to 16 bit word size by Patrick Vogler
+--  18th November 2009
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  20th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+library UNISIM;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+use UNISIM.Vcomponents.ALL;
+
+entity spi_interface_16 is
+  port(
+    clk              : IN    STD_LOGIC;
+    clkdiv           : IN    STD_LOGIC_VECTOR (1 downto 0);
+    cpha             : IN    STD_LOGIC;
+    cpol             : IN    STD_LOGIC;
+    miso             : IN    STD_LOGIC;
+    rcv_cpol         : IN    STD_LOGIC;
+    rcv_full_reset   : IN    STD_LOGIC;
+    reset            : IN    STD_LOGIC;
+    ss_in_n          : IN    STD_LOGIC;
+    ss_mask_reg      : IN    STD_LOGIC_VECTOR (7 downto 0);-- slave select signals, caution! NO modification, slave select, not word size
+    start            : IN    STD_LOGIC;
+    xmit_data        : IN    STD_LOGIC_VECTOR (15 downto 0);-- *Mod: 15 instead of 7, transmit data word extended from 8 to 16 bit
+    xmit_empty_reset : IN    STD_LOGIC;
+    done             : OUT   STD_LOGIC;
+    mosi             : OUT   STD_LOGIC;
+    rcv_data         : OUT   STD_LOGIC_VECTOR (15 downto 0);-- *Mod: 15 instead of 7, recieve data word extended from 8 to 16 bit
+    rcv_full         : OUT   STD_LOGIC;
+    ss_n             : OUT   STD_LOGIC_VECTOR (7 downto 0);-- slave select signals, caution! NO modification, slave select, not word size
+    rcv_load         : INOUT STD_LOGIC;
+    sck              : INOUT STD_LOGIC;
+    ss_in_int	     : INOUT STD_LOGIC;
+    ss_n_int	     : INOUT STD_LOGIC;
+    xmit_empty	     : INOUT STD_LOGIC
+  );
+end spi_interface_16;
+
+ARCHITECTURE SCHEMATIC OF spi_interface_16 IS
+
+  SIGNAL clk0_mask  : STD_LOGIC;
+  SIGNAL clk1_mask  : STD_LOGIC;
+  SIGNAL sck_1      : STD_LOGIC;
+  SIGNAL sck_fe     : STD_LOGIC;
+  SIGNAL sck_int_fe : STD_LOGIC;
+  SIGNAL sck_int_re : STD_LOGIC;
+  SIGNAL sck_re     : STD_LOGIC;
+  SIGNAL vcc        : STD_LOGIC;
+  SIGNAL xmit_load  : STD_LOGIC;
+  SIGNAL xmit_shift : STD_LOGIC;
+
+  ATTRIBUTE fpga_dont_touch : STRING;
+  ATTRIBUTE fpga_dont_touch OF XLXI_9 : LABEL IS "true";
+
+  COMPONENT sck_logic
+    PORT(
+      clk        : IN	 STD_LOGIC;
+      clk0_mask  : IN	 STD_LOGIC;
+      clk1_mask  : IN	 STD_LOGIC;
+      clkdiv     : IN	 STD_LOGIC_VECTOR (1 DOWNTO 0);
+      cpha       : IN	 STD_LOGIC;
+      cpol       : IN	 STD_LOGIC;
+      reset      : IN	 STD_LOGIC;
+      ss_in_int  : IN	 STD_LOGIC;
+      sck        : INOUT STD_LOGIC;
+      sck_1      : INOUT STD_LOGIC;
+      sck_fe     : OUT   STD_LOGIC;
+      sck_int_fe : OUT   STD_LOGIC;
+      sck_int_re : OUT	 STD_LOGIC;
+      sck_re     : OUT	 STD_LOGIC
+    );
+  END COMPONENT;
+
+  COMPONENT spi_control_sm
+    PORT(
+      clk              : IN    STD_LOGIC;
+      cpha             : IN    STD_LOGIC;
+      cpol             : IN    STD_LOGIC;
+      rcv_full_reset   : IN    STD_LOGIC;
+      rcv_load         : IN    STD_LOGIC;
+      reset            : IN    STD_LOGIC;
+      sck_fe           : IN    STD_LOGIC;
+      sck_int          : IN    STD_LOGIC;
+      sck_int_fe       : IN    STD_LOGIC;
+      sck_int_re       : IN    STD_LOGIC;
+      sck_re           : IN    STD_LOGIC;
+      ss_in_n	       : IN    STD_LOGIC;
+      ss_mask_reg      : IN    STD_LOGIC_VECTOR (7 DOWNTO 0);-- slave select signals, caution, NO modification, slave select, not word size
+      start            : IN    STD_LOGIC;
+      xmit_empty_reset : IN    STD_LOGIC;
+      ss_in_int        : INOUT STD_LOGIC;
+      ss_n_int         : INOUT STD_LOGIC;
+      xmit_empty       : INOUT STD_LOGIC;
+      xmit_load        : INOUT STD_LOGIC;
+      clk0_mask        : OUT   STD_LOGIC;
+      clk1_mask        : OUT   STD_LOGIC;
+      done             : OUT   STD_LOGIC;
+      rcv_full         : OUT   STD_LOGIC;
+      ss_n             : OUT   STD_LOGIC_VECTOR (7 DOWNTO 0); -- slave select signals, caution! NO modification slave select, not word size
+      xmit_shift       : OUT   STD_LOGIC
+    );
+  END COMPONENT;
+
+  COMPONENT spi_rcv_shift_reg
+    PORT(
+      cpol	: IN  STD_LOGIC;
+      miso	: IN  STD_LOGIC;
+      rcv_cpol	: IN  STD_LOGIC;
+      reset	: IN  STD_LOGIC;
+      sck_fe	: IN  STD_LOGIC;
+      sck_re	: IN  STD_LOGIC;
+      sclk	: IN  STD_LOGIC;
+      shift_en	: IN  STD_LOGIC;
+      ss_in_int	: IN  STD_LOGIC;
+      data_out	: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);-- *Mod: 15 instead of 7, recieve data word extended from 8 to 16 bit
+      rcv_load	: OUT STD_LOGIC
+    );
+  END COMPONENT;
+
+  COMPONENT spi_xmit_shift_reg
+    PORT(
+      data_in	: IN  STD_LOGIC_VECTOR (15 DOWNTO 0);-- *Mod: 15 instead of 7, transmit data word extended from 8 to 16 bit
+      data_ld	: IN  STD_LOGIC;
+      reset	: IN  STD_LOGIC;
+      sclk	: IN  STD_LOGIC;
+      shift_en	: IN  STD_LOGIC;
+      shift_in	: IN  STD_LOGIC;
+      ss_in_int	: IN  STD_LOGIC;
+      sys_clk	: IN  STD_LOGIC;
+      mosi	: OUT STD_LOGIC
+    );
+  END COMPONENT;
+
+BEGIN
+
+  XLXI_9 : NAND2B1
+    PORT MAP(
+      I0=>xmit_shift, I1=>xmit_shift, O=>vcc
+    );
+
+  SCK_GEN : sck_logic
+    PORT MAP(
+      clk=>clk, clk0_mask=>clk0_mask, clk1_mask=>clk1_mask,
+      clkdiv(1)=>clkdiv(1), clkdiv(0)=>clkdiv(0), cpha=>cpha, cpol=>cpol,
+      reset=>reset, ss_in_int=>ss_in_int, sck=>sck, sck_1=>sck_1,
+      sck_fe=>sck_fe, sck_int_fe=>sck_int_fe, sck_int_re=>sck_int_re,
+      sck_re=>sck_re
+    );
+
+  spi_ctrl_sm : spi_control_sm
+    PORT MAP(
+      clk=>clk, cpha=>cpha, cpol=>cpol,
+      rcv_full_reset=>rcv_full_reset, rcv_load=>rcv_load, reset=>reset,
+      sck_fe=>sck_fe, sck_int=>sck_1, sck_int_fe=>sck_int_fe,
+      sck_int_re=>sck_int_re, sck_re=>sck_re, ss_in_n=>ss_in_n,
+      ss_mask_reg(7)=>ss_mask_reg(7), ss_mask_reg(6)=>ss_mask_reg(6),
+      ss_mask_reg(5)=>ss_mask_reg(5), ss_mask_reg(4)=>ss_mask_reg(4),
+      ss_mask_reg(3)=>ss_mask_reg(3), ss_mask_reg(2)=>ss_mask_reg(2),
+      ss_mask_reg(1)=>ss_mask_reg(1), ss_mask_reg(0)=>ss_mask_reg(0),
+      start=>start, xmit_empty_reset=>xmit_empty_reset, ss_in_int=>ss_in_int,
+      ss_n_int=>ss_n_int, xmit_empty=>xmit_empty, xmit_load=>xmit_load,
+      clk0_mask=>clk0_mask, clk1_mask=>clk1_mask, done=>done,
+      rcv_full=>rcv_full, ss_n(7)=>ss_n(7), ss_n(6)=>ss_n(6), ss_n(5)=>ss_n(5),
+      ss_n(4)=>ss_n(4), ss_n(3)=>ss_n(3), ss_n(2)=>ss_n(2), ss_n(1)=>ss_n(1),
+      ss_n(0)=>ss_n(0), xmit_shift=>xmit_shift
+    );
+
+--------------------------------------------------------------------------
+-- *Mod:  recieve data word extended from 8 to 16 bit in this block ------
+  rcv_shift_reg : spi_rcv_shift_reg
+    PORT MAP(
+      cpol=>cpol, miso=>miso, rcv_cpol=>rcv_cpol, reset=>reset,
+      sck_fe=>sck_fe, sck_re=>sck_re, sclk=>sck, shift_en=>ss_n_int,
+      ss_in_int=>ss_in_int,
+      data_out(15)=>rcv_data(15), data_out(14)=>rcv_data(14),
+      data_out(13)=>rcv_data(13), data_out(12)=>rcv_data(12),
+      data_out(11)=>rcv_data(11), data_out(10)=>rcv_data(10),
+      data_out(9)=>rcv_data(9),   data_out(8)=>rcv_data(8),	
+      data_out(7)=>rcv_data(7),   data_out(6)=>rcv_data(6),
+      data_out(5)=>rcv_data(5),   data_out(4)=>rcv_data(4),
+      data_out(3)=>rcv_data(3),   data_out(2)=>rcv_data(2),
+      data_out(1)=>rcv_data(1),   data_out(0)=>rcv_data(0), 
+      rcv_load=>rcv_load
+    );
+-- *Mod:  recieve data word extended from 8 to 16 bit in this block -----
+-------------------------------------------------------------------------		
+
+--------------------------------------------------------------------------
+-- *Mod:  transmit data word extended from 8 to 16 bit in this block -----
+  xmit_shift_reg : spi_xmit_shift_reg
+    PORT MAP(
+      data_in(15)=>xmit_data(15), data_in(14)=>xmit_data(14),	
+      data_in(13)=>xmit_data(13), data_in(12)=>xmit_data(12),
+      data_in(11)=>xmit_data(11), data_in(10)=>xmit_data(10),
+      data_in(9)=>xmit_data(9),   data_in(8)=>xmit_data(8),
+      data_in(7)=>xmit_data(7),   data_in(6)=>xmit_data(6),
+      data_in(5)=>xmit_data(5),   data_in(4)=>xmit_data(4),
+      data_in(3)=>xmit_data(3),   data_in(2)=>xmit_data(2),
+      data_in(1)=>xmit_data(1),   data_in(0)=>xmit_data(0),
+      data_ld=>xmit_load,
+      reset=>reset, sclk=>sck_1, shift_en=>xmit_shift, shift_in=>vcc,
+      ss_in_int=>ss_in_int, sys_clk=>clk, mosi=>mosi
+    );
+-- *Mod:  transmit data word extended from 8 to 16 bit in this block -----
+--------------------------------------------------------------------------
+
+END SCHEMATIC;
Index: FPGA/FTU/spi_interface/spi_rcv_shift_reg_16.vhd
===================================================================
--- FPGA/FTU/spi_interface/spi_rcv_shift_reg_16.vhd	(revision 156)
+++ FPGA/FTU/spi_interface/spi_rcv_shift_reg_16.vhd	(revision 156)
@@ -0,0 +1,168 @@
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  File:          spi_rcv_shift_reg_16.vhd
+--
+--
+--  Original file: spi_rcv_shift_reg.vhd
+--
+--  Created:  9-6-00 ALS
+--  SPI shift register that shifts data in on MISO. No data is shifted out.
+--  This is an 8-bit register clocked on the outgoing SCK. The data input
+--  on the MISO pin is first clocked by two registers - one on the rising edge
+--  of SCK and one on the falling edge of SCK. The data selected to be input into the
+--  shift register is determined by a control bit in the control register (RCV_CPOL).
+--  When all bits have been shifted in, the data is loaded into the uC SPI Receive Data
+--  register.
+--
+--  Revised: 9-11-00 ALS
+--  Revised: 10-17-00 ALS
+--  Revised: 12-12-02 JRH
+    
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified from 8 to 16 bit word size by Patrick Vogler
+--  18th November 2009
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  21th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity spi_rcv_shift_reg is
+  port(  
+    -- shift control and data
+    miso      : in  STD_LOGIC;                       -- Serial data in
+    shift_en  : in  STD_LOGIC;                       -- Active low shift enable    
+
+    -- parallel data out
+    data_out  : out STD_LOGIC_VECTOR (15 downto 0); -- Shifted data, *Mod: 15 instead of 7, parallel output extended from 8 to 16 bit    
+
+    rcv_load  : out std_logic;                      -- load signal to uC register
+    
+    -- rising edge and falling SCK edges
+    sck_re    : in  std_logic;                      -- rising edge of SCK
+    sck_fe    : in  std_logic;                      -- falling edge of SCK
+         
+    -- uC configuration for receive clock polarity
+    rcv_cpol  : in  STD_LOGIC;                      -- receive clock polarity
+    cpol      : in  std_logic;                      -- spi clock polarity
+      
+    ss_in_int : in  STD_LOGIC;                      -- signal indicating another master is on the bus
+    
+    reset     : in  STD_LOGIC;                      -- reset
+    sclk      : in  STD_LOGIC                       -- clock        
+  );        
+end spi_rcv_shift_reg;
+
+architecture DEFINITION of spi_rcv_shift_reg is
+
+  --******************************** Constants ***********************
+  constant RESET_ACTIVE   : std_logic := '0';
+
+  --******************************** Signals *************************
+  signal data_int       : STD_LOGIC_VECTOR (15 downto 0);-- *Mod: 15 instead of 7, extension form 8 to 16 bit
+  signal shift_in       : STD_LOGIC;                     -- data to be shifted in
+  signal miso_neg       : STD_LOGIC;                     -- data clocked on neg SCK
+  signal miso_pos       : STD_LOGIC;                     -- data clocked on pos SCK
+
+  signal rcv_bitcnt_int : unsigned(2 downto 0); -- internal bit count
+  signal rcv_bitcnt     : std_logic_vector(2 downto 0); -- bit count
+
+begin
+
+  --******************************** SPI Receive Shift Register ***********************
+  -- This shift register is clocked on the SCK output from the CPLD
+
+  rcv_shift_reg: process(sclk, reset, ss_in_int)
+  begin          
+    -- Clear output register
+    if (reset = RESET_ACTIVE or ss_in_int = '0') then
+      data_int <= (others => '0');
+           
+      -- On rising edge of spi clock, shift in data
+    elsif sclk'event and sclk = '1' then
+
+      -- If shift enable is high
+      if shift_en = '0' then
+
+        -- Shift the data
+        data_int <= data_int(14 downto 0) & shift_in;   -- *Mod: 14 instead of 6
+            
+      end if;
+
+    end if;
+
+  end process;
+
+  --******************************** MISO Input Registers *********************** 
+  -- The MISO signal is clocked on both the rising and falling edges of SCK. The output
+  -- of both these registers is then multiplexed with the RCV_CPOL control bit choosing
+  -- which data is the valid data for the system. This data is then the input to the
+  -- shift register.
+
+  -- SCK rising edge register
+  inreg_pos: process (sclk, reset, ss_in_int)
+  begin
+    if reset = RESET_ACTIVE or ss_in_int = '0' then
+      miso_pos <= '0';
+    elsif sclk'event and sclk = '1' then    
+      miso_pos <= miso;
+    end if;
+  end process;
+
+  -- SCK falling edge register
+  inreg_neg: process (sclk, reset, ss_in_int)
+  begin
+    if reset = RESET_ACTIVE or ss_in_int = '0' then
+      miso_neg <= '0';
+    elsif sclk'event and sclk = '0' then    
+      miso_neg <= miso;
+    end if;
+  end process;
+
+  -- RCV_CPOL multiplexor to determine shift in data
+  miso_mux: process (miso_neg, miso_pos, rcv_cpol)
+  begin
+    if rcv_cpol = '1' then
+      shift_in <= miso_pos;
+    else
+      shift_in <= miso_neg;
+    end if;
+  end process;
+
+  --******************************** Parallel Data Out ***********************
+
+  data_out <= data_int(14 downto 0) & shift_in;	--*Mod: 14 instead of 6
+
+  --******************************** Receive Bit Counter ***********************
+  -- Count bits loading into the SPI receive shift register based on SCK
+  -- assert RCV_LOAD when bit count is 0
+  RCV_BITCNT_PROC: process(sclk, reset, shift_en)
+  begin
+    if reset = RESET_ACTIVE or shift_en = '1' then
+      rcv_bitcnt_int <= (others => '0');
+    elsif sclk'event and sclk = '1' then
+      rcv_bitcnt_int <= rcv_bitcnt_int + 1;
+    end if;
+  end process;
+
+  rcv_bitcnt <= STD_LOGIC_VECTOR(rcv_bitcnt_int);
+
+  --******************************** Receive Load ***********************
+  -- If RCV_CPOL = '0', want to assert RCV_LOAD with falling edge of SCK
+  -- If RCV_CPOL = '1', want to assert RCV_LOAD with rising edge of SCK 
+  -- only want RCV_LOAD to be 1 system clock pulse in width
+  rcv_load <= '1' when ( shift_en = '0' and
+                         (  (rcv_bitcnt="000" and cpol='0' and rcv_cpol='1' and sck_re='1')
+                            or (rcv_bitcnt="000" and cpol='1' and rcv_cpol='1' and sck_re='1')
+                            or (rcv_bitcnt="000" and cpol='0' and rcv_cpol='0' and sck_fe='1')
+                            or (rcv_bitcnt="111" and cpol='1' and rcv_cpol='0' and sck_fe='1') )
+                         )
+              else '0';
+
+end DEFINITION;
Index: FPGA/FTU/spi_interface/spi_xmit_shift_reg_16.vhd
===================================================================
--- FPGA/FTU/spi_interface/spi_xmit_shift_reg_16.vhd	(revision 156)
+++ FPGA/FTU/spi_interface/spi_xmit_shift_reg_16.vhd	(revision 156)
@@ -0,0 +1,102 @@
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  File:          spi_xmit_shift_reg_16.vhd
+--
+--
+--  Original file: spi_xmit_shift_reg.vhd
+--
+--  Created:  9-6-00 ALS
+--  SPI shift register that shifts data out on MOSI. No data is shifted in.
+--  This is an 8-bit, loadable register. The data output from the shift register is
+--  clocked one additional system clock to align the data with the outgoing clock on
+--  SCK.
+--
+--  Revised: 9-11-00 ALS
+--  Revised: 9-20-00 ALS
+
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+--  Modified from 8 to 16 bit word size by Patrick Vogler
+--  18th November 2009
+--
+--	 Modifications are marked by: *Mod: <modification>
+--
+--  Cleaned up by Quirin Weitzel
+--  21th January 2010
+---------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+entity spi_xmit_shift_reg is
+  port(
+    data_ld      : in STD_LOGIC;                      -- Data load enable
+    data_in      : in STD_LOGIC_VECTOR (15 downto 0); -- Data to load in, *Mod: 15 instead of 7, parallel input extended from 8 to 16 bit
+    shift_in     : in STD_LOGIC;                      -- Serial data in
+    shift_en     : in STD_LOGIC;                      -- Shift enable         
+    mosi         : out STD_LOGIC;                     -- Shift serial data out
+    ss_in_int    : in STD_LOGIC;                      -- another master is on bus
+    reset        : in STD_LOGIC;                      -- reset
+    sclk         : in STD_LOGIC;                      -- clock
+    sys_clk      : in STD_LOGIC                       -- system clock
+  );
+        
+end spi_xmit_shift_reg;
+
+architecture DEFINITION of spi_xmit_shift_reg is
+
+--******************************** Constants ***********************
+constant RESET_ACTIVE : std_logic := '0';
+
+--******************************** Signals *************************
+signal data_int     : STD_LOGIC_VECTOR (15 downto 0);-- *Mod: 15 instead of 7, parallel output extended from 8 to 16 bit
+signal mosi_int     : STD_LOGIC;
+
+begin
+
+  --******************************** SPI Xmit Shift Register ***********************
+  -- This shift register is clocked on SCK_1
+  xmit_shift_reg:  process(sclk, reset, ss_in_int)
+  begin    
+    -- Clear output register
+    if (reset = RESET_ACTIVE or ss_in_int = '0') then
+      data_int <= (others => '0');
+           
+      -- On rising edge of spi clock, shift data
+    elsif sclk'event and sclk = '1' then
+
+      -- Load data
+      if (data_ld = '1') then
+        data_int <= data_in;
+
+        -- If shift enable is high
+      elsif shift_en = '1' then
+
+        -- Shift the data
+        data_int <= data_int(14 downto 0) & shift_in; --*Mod: 14 instead of 6, shift register extended from 8 to 16 bit
+      end if;
+      
+    end if;
+
+  end process;
+
+  --******************************** MOSI Output Register ***********************
+  -- This output register is clocked on the system clock and aligns the data from the
+  -- shift register with the outgoing SCK
+  outreg: process (sys_clk, reset)
+  begin
+    if reset = RESET_ACTIVE then
+      mosi_int <= '0';
+    elsif sys_clk'event and sys_clk = '1' then
+      
+      mosi_int <= data_int(15); -- *Mod: 15 instead of 7, shift register extended form 8 to 16 bit
+    end if;
+  end process;
+
+  -- The MOSI output is 3-stated if the SS_IN_INT signal is asserted indicating that another
+  -- master is on the bus
+  mosi <= mosi_int when ss_in_int = '1' 
+          else    'Z';
+
+end DEFINITION;
