]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
new i2c handler
authorLudwig Maier <lmaier@crius.e12.ph.tum.de>
Mon, 11 Nov 2013 23:32:45 +0000 (00:32 +0100)
committerLudwig Maier <lmaier@crius.e12.ph.tum.de>
Mon, 11 Nov 2013 23:32:55 +0000 (00:32 +0100)
nxyter/compile_munich20.pl [new file with mode: 0755]
nxyter/compile_munich20.sh [new file with mode: 0755]
nxyter/source/nx_setup.vhd
nxyter/source/nxyter_components.vhd
nxyter/source/nxyter_fee_board.vhd
nxyter/source/nxyter_registers.vhd
nxyter/source/pulse_delay.vhd [new file with mode: 0644]
nxyter/source/registers.txt
nxyter/source/signal_async_to_pulse.vhd [new file with mode: 0644]
nxyter/trb3_periph.prj
nxyter/trb3_periph_constraints.lpf

diff --git a/nxyter/compile_munich20.pl b/nxyter/compile_munich20.pl
new file mode 100755 (executable)
index 0000000..2378e6b
--- /dev/null
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+use Data::Dumper;
+use warnings;
+use strict;
+
+
+
+
+###################################################################################
+#Settings for this project
+my $TOPNAME                      = "trb3_periph";  #Name of top-level entity
+my $lattice_path                 = '/usr/local/opt/lattice_diamond/diamond/2.0';
+my $synplify_path                = '/usr/local/opt/synplify/F-2012.03-SP1/';
+my $lm_license_file_for_synplify = "27000\@lxcad01.gsi.de";
+my $lm_license_file_for_par      = "1702\@hadeb05.gsi.de";
+###################################################################################
+
+
+
+
+
+
+
+
+use FileHandle;
+
+$ENV{'SYNPLIFY'}=$synplify_path;
+$ENV{'SYN_DISABLE_RAINBOW_DONGLE'}=1;
+$ENV{'LM_LICENSE_FILE'}=$lm_license_file_for_synplify;
+
+
+
+
+my $FAMILYNAME="LatticeECP3";
+my $DEVICENAME="LFE3-150EA";
+my $PACKAGE="FPBGA672";
+my $SPEEDGRADE="8";
+
+
+#create full lpf file
+system("cp ../base/$TOPNAME"."_nxyter.lpf workdir/$TOPNAME.lpf");
+system("cat ".$TOPNAME."_constraints.lpf >> workdir/$TOPNAME.lpf");
+
+
+#set -e
+#set -o errexit
+
+#generate timestamp
+my $t=time;
+my $fh = new FileHandle(">version.vhd");
+die "could not open file" if (! defined $fh);
+print $fh <<EOF;
+
+--## attention, automatically generated. Don't change by hand.
+library ieee;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.std_logic_ARITH.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+use ieee.numeric_std.all;
+
+package version is
+
+    constant VERSION_NUMBER_TIME  : integer   := $t;
+
+end package version;
+EOF
+$fh->close;
+
+system("env| grep LM_");
+my $r = "";
+
+my $c="$synplify_path/bin/synplify_premier_dp -batch $TOPNAME.prj";
+$r=execute($c, "do_not_exit" );
+
+
+chdir "workdir";
+$fh = new FileHandle("<$TOPNAME".".srr");
+my @a = <$fh>;
+$fh -> close;
+
+
+
+foreach (@a)
+{
+    if(/\@E:/)
+    {
+       print "\n";
+       $c="cat $TOPNAME.srr | grep \"\@E\"";
+       system($c);
+        print "\n\n";
+       exit 129;
+    }
+}
+
+
+$ENV{'LM_LICENSE_FILE'}=$lm_license_file_for_par;
+
+$c=qq| $lattice_path/ispfpga/bin/lin/edif2ngd -path "../" -path "." -l $FAMILYNAME -d $DEVICENAME "$TOPNAME.edf" "$TOPNAME.ngo" |;
+execute($c);
+
+$c=qq|$lattice_path/ispfpga/bin/lin/edfupdate   -t "$TOPNAME.tcy" -w "$TOPNAME.ngo" -m "$TOPNAME.ngo" "$TOPNAME.ngx"|;
+execute($c);
+
+$c=qq|$lattice_path/ispfpga/bin/lin/ngdbuild  -a $FAMILYNAME -d $DEVICENAME -p "$lattice_path/ispfpga/ep5c00/data" -dt "$TOPNAME.ngo" "$TOPNAME.ngd"|;
+execute($c);
+
+my $tpmap = $TOPNAME . "_map" ;
+
+$c=qq|$lattice_path/ispfpga/bin/lin/map  -retime -split_node -a $FAMILYNAME -p $DEVICENAME -t $PACKAGE -s $SPEEDGRADE "$TOPNAME.ngd" -pr "$TOPNAME.prf" -o "$tpmap.ncd"  -mp "$TOPNAME.mrp" "$TOPNAME.lpf"|;
+execute($c);
+
+system("rm $TOPNAME.ncd");
+
+
+$c=qq|$lattice_path/ispfpga/bin/lin/par -f "../$TOPNAME.p2t"  "$tpmap.ncd" "$TOPNAME.ncd" "$TOPNAME.prf"|;
+execute($c);
+
+# IOR IO Timing Report
+$c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|;
+execute($c);
+
+# TWR Timing Report
+$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 15 -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|;
+execute($c);
+
+$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 5 -o "$TOPNAME.twr.hold"  "$TOPNAME.ncd" "$TOPNAME.prf"|;
+execute($c);
+
+$c=qq|$lattice_path/ispfpga/bin/lin/ltxt2ptxt $TOPNAME.ncd|;
+execute($c);
+
+$c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w -g CfgMode:Disable -g RamCfg:Reset -g ES:No  $TOPNAME.ncd $TOPNAME.bit $TOPNAME.prf|;
+# $c=qq|$lattice_path/ispfpga/bin/lin/bitgen  -w "$TOPNAME.ncd"  "$TOPNAME.prf"|;
+execute($c);
+
+chdir "..";
+
+exit;
+
+sub execute {
+    my ($c, $op) = @_;
+    #print "option: $op \n";
+    $op = "" if(!$op);
+    print "\n\ncommand to execute: $c \n";
+    $r=system($c);
+    if($r) {
+       print "$!";
+       if($op ne "do_not_exit") {
+           exit;
+       }
+    }
+
+    return $r;
+
+}
diff --git a/nxyter/compile_munich20.sh b/nxyter/compile_munich20.sh
new file mode 100755 (executable)
index 0000000..bed8cfa
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+. /usr/local/opt/lattice_diamond/diamond/2.0/bin/lin/diamond_env
+
+exec ./compile_munich20.pl
index dcc3209aaae7b3f5d6c7caef54ba1325fe59444c..6fbf70db546b964e50c4254568463fa7b0ebe873 100644 (file)
@@ -5,6 +5,7 @@ use ieee.numeric_std.all;
 library work;
 use work.trb_net_std.all;
 use work.trb_net_components.all;
+use work.nxyter_components.all;
 
 entity nx_setup is
   port(
@@ -14,19 +15,21 @@ entity nx_setup is
     I2C_COMMAND_OUT      : out std_logic_vector(31 downto 0);
     I2C_COMMAND_BUSY_IN  : in  std_logic;
     I2C_DATA_IN          : in  std_logic_vector(31 downto 0);
-    I2C_LOCK             : out std_logic;
-
+    I2C_LOCK_OUT         : out std_logic;
+    I2C_ONLINE_OUT       : out std_logic;
+    I2C_REG_RESET_IN     : in  std_logic;
+    
     SPI_COMMAND_OUT      : out std_logic_vector(31 downto 0);
     SPI_COMMAND_BUSY_IN  : in  std_logic;
     SPI_DATA_IN          : in  std_logic_vector(31 downto 0);
-    SPI_LOCK             : out std_logic;
+    SPI_LOCK_OUT         : out std_logic;
     
     -- Slave bus         
     SLV_READ_IN          : in  std_logic;
     SLV_WRITE_IN         : in  std_logic;
     SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
     SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
-    SLV_ADDR_IN          : in std_logic_vector(15 downto 0);
+    SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
     SLV_ACK_OUT          : out std_logic;
     SLV_NO_MORE_DATA_OUT : out std_logic;
     SLV_UNKNOWN_ADDR_OUT : out std_logic;
@@ -38,6 +41,13 @@ end entity;
 
 architecture Behavioral of nx_setup is
 
+  -- I2C Command Multiplexer
+  signal i2c_lock_0      : std_logic;
+  signal i2c_lock_1      : std_logic;
+  signal i2c_lock_2      : std_logic;
+  signal i2c_lock_3      : std_logic;
+  signal i2c_command     : std_logic_vector(31 downto 0);
+  
   -- Send I2C Command
   type I2C_STATES is (I2C_IDLE,
                       I2C_WAIT_BUSY_HIGH,
@@ -46,43 +56,74 @@ architecture Behavioral of nx_setup is
 
   signal I2C_STATE : I2C_STATES;
   
-  signal spi_command_o : std_logic_vector(31 downto 0);
-  signal i2c_lock_o              : std_logic;
   signal i2c_command_o           : std_logic_vector(31 downto 0);
-  signal i2c_command             : std_logic_vector(31 downto 0);
-  signal i2c_command_busy        : std_logic;
+  signal i2c_command_busy_o      : std_logic;
   signal i2c_command_done        : std_logic;
+  signal i2c_error               : std_logic;
   signal i2c_data                : std_logic_vector(31 downto 0);
-
-  -- Read I2C Registers
-  type R_STATES is (R_IDLE,
-                    R_REGISTER,
-                    R_REGISTER_STORE,
-                    R_NEXT_REGISTER,
-                    R_WAIT_DONE
-                    );
   
-  signal R_STATE, R_STATE_RETURN : R_STATES;
-
-  signal nx_read_i2c_command     : std_logic_vector(31 downto 0);
-  signal nx_read_i2c_lock        : std_logic;        
-  signal r_register_ctr          : unsigned(5 downto 0);
+  -- I2C Register Ram
+  type i2c_ram_t is array(0 to 45) of std_logic_vector(7 downto 0);
+  signal i2c_ram                 : i2c_ram_t;
+  
+  type register_access_type_t is array(0 to 45) of std_logic;
+  constant register_access_type : register_access_type_t :=
+    ('1', '1', '1', '1', '1', '1', '1', '1',   --  0 ->  7
+     '1', '1', '1', '1', '1', '1', '1', '1',   --  8 -> 15
+     '1', '1', '1', '1', '1', '1', '1', '1',   -- 16 -> 23
+     '1', '1', '1', '1', '1', '1', '0', '0',   -- 24 -> 31 
+     '1', '1', '0', '0', '0', '0', '1', '1',   -- 32 -> 39
+     '0', '0', '0', '1', '1', '1'              -- 40 -> 45
+     );
+  
+  -- I2C RAM Handler
+  signal ram_index_0             : integer;
+  signal ram_index_1             : integer;
+  signal ram_data_0              : std_logic_vector(7 downto 0);
+  signal ram_data_1              : std_logic_vector(7 downto 0);
+  signal ram_write_0             : std_logic;
+  signal ram_write_1             : std_logic;
+  signal do_write                : std_logic;
 
-  -- Write I2C Registers
-  type W_STATES is (W_IDLE,
-                    W_REGISTER,
-                    W_NEXT_REGISTER,
-                    W_WAIT_DONE
+  -- DAC Trim FIFO RAM
+  type dac_ram_t is array(0 to 130) of std_logic_vector(5 downto 0);
+  signal dac_ram                 : dac_ram_t;
+  signal dac_ram_write_0         : std_logic;
+  signal dac_ram_write_1         : std_logic;
+  signal dac_ram_index_0         : integer;
+  signal dac_ram_index_1         : integer;
+  signal dac_ram_data_0          : std_logic_vector(5 downto 0);
+  signal dac_ram_data_1          : std_logic_vector(5 downto 0);
+  signal do_dac_write            : std_logic;
+      
+  -- Token Handler
+  signal i2c_read_token          : std_logic_vector(45 downto 0);
+  signal i2c_write_token         : std_logic_vector(45 downto 0);
+  
+  -- I2C Registers IO Handler
+  type T_STATES is (T_IDLE_TOKEN,
+                    T_WRITE_I2C_REGISTER,
+                    T_WAIT_I2C_WRITE_DONE,
+                    T_READ_I2C_REGISTER,
+                    T_WAIT_I2C_READ_DONE,
+                    T_READ_I2C_STORE_MEM,
+                    T_NEXT_TOKEN
                     );
 
-  signal W_STATE, W_STATE_RETURN : W_STATES;
+  signal T_STATE  : T_STATES;
 
   
-  signal nx_write_i2c_command    : std_logic_vector(31 downto 0);
-  signal nx_write_i2c_lock       : std_logic;        
-  signal w_register_ctr          : unsigned(5 downto 0);
-  
+  signal nx_i2c_command          : std_logic_vector(31 downto 0);
+  signal token_ctr               : unsigned(5 downto 0);
+  signal next_token              : std_logic;
+  signal read_token_clear        : std_logic_vector(45 downto 0);
+  signal write_token_clear       : std_logic_vector(45 downto 0);
+  signal i2c_lock_0_clear        : std_logic;
   
+  -- DAC Token Handler
+  signal dac_read_token          : std_logic_vector(128 downto 0);
+  signal dac_write_token         : std_logic_vector(128 downto 0);
+
   -- Read DAC I2C Registers
   type DR_STATES is (DR_IDLE,
                      DR_REGISTER,
@@ -92,11 +133,13 @@ architecture Behavioral of nx_setup is
                     );
   
   signal DR_STATE, DR_STATE_RETURN : DR_STATES;
-  
 
+  
   signal dac_read_i2c_command    : std_logic_vector(31 downto 0);
-  signal dac_read_i2c_lock       : std_logic;        
   signal r_fifo_ctr              : unsigned(7 downto 0);
+  signal dac_read_token_clear    : std_logic_vector(128 downto 0);
+  signal next_token_dac_r        : std_logic;
+  signal i2c_lock_1_clear        : std_logic;
 
   -- Write DAC I2C Registers
   type DW_STATES is (DW_IDLE,
@@ -108,55 +151,52 @@ architecture Behavioral of nx_setup is
   signal DW_STATE, DW_STATE_RETURN : DW_STATES;
 
   signal dac_write_i2c_command   : std_logic_vector(31 downto 0);
-  signal dac_write_i2c_lock      : std_logic;        
   signal w_fifo_ctr              : unsigned(7 downto 0);
-
+  signal dac_write_token_clear   : std_logic_vector(128 downto 0);
+  signal next_token_dac_w        : std_logic;
+  signal i2c_lock_2_clear        : std_logic;
+  
+  -- I2C Online Check
+  type R_STATES is (R_TIMER_RESTART,
+                    R_IDLE,
+                    R_READ_DUMMY,
+                    R_WAIT_DONE
+                    );
   
+  signal R_STATE : R_STATES;
+
+  signal wait_timer_init         : unsigned(31 downto 0);
+  signal wait_timer_done         : std_logic;
+  signal i2c_online_command      : std_logic_vector(31 downto 0);
+  signal i2c_lock_3_clear        : std_logic;
+  signal i2c_online_o            : std_logic;
+
+  -- I2C Status
+  signal i2c_online_t            : std_logic_vector(7 downto 0);
+  signal i2c_update_memory_p     : std_logic;
+  signal i2c_update_memory       : std_logic;
+  signal i2c_disable_memory      : std_logic;
+  signal i2c_reg_reset_in_s      : std_logic;
+  signal i2c_reg_reset_clear     : std_logic;
+    
   -- TRBNet Slave Bus
   signal slv_data_out_o          : std_logic_vector(31 downto 0);
   signal slv_no_more_data_o      : std_logic;
   signal slv_unknown_addr_o      : std_logic;
   signal slv_ack_o               : std_logic;
 
-  signal read_nx_i2c_all_start   : std_logic;
-  signal write_nx_i2c_all_start  : std_logic;
-  
-  signal read_dac_all_start      : std_logic;
-  signal write_dac_all_start     : std_logic;
+  signal i2c_read_token_r        : std_logic_vector(45 downto 0);
+  signal i2c_write_token_r       : std_logic_vector(45 downto 0);
 
-  -- I2C Register Ram
-  type i2c_ram_t is array(0 to 45) of std_logic_vector(7 downto 0);
-  signal i2c_ram                 : i2c_ram_t;
-  signal i2c_ram_write_0         : std_logic;
-  signal i2c_ram_write_1         : std_logic;
-  signal i2c_ram_input_addr_0    : unsigned(5 downto 0);
-  signal i2c_ram_input_addr_1    : unsigned(5 downto 0);
-  signal i2c_ram_input_0         : std_logic_vector(7 downto 0);
-  signal i2c_ram_input_1         : std_logic_vector(7 downto 0);
-  
-  type register_access_type_t is array(0 to 45) of std_logic;
-  constant register_access_type : register_access_type_t :=
-    ('1', '1', '1', '1', '1', '1', '1', '1',   --  0 ->  7
-     '1', '1', '1', '1', '1', '1', '1', '1',   --  8 -> 15
-     '1', '1', '1', '1', '1', '1', '1', '1',   -- 16 -> 23
-     '1', '1', '1', '1', '1', '1', '0', '0',   -- 24 -> 31 
-     '1', '1', '0', '0', '0', '0', '1', '1',   -- 32 -> 39
-     '0', '0', '0', '1', '1', '1'              -- 40 -> 45
-     );
-  
-  -- DAC Trim FIFO RAM
-  type dac_ram_t is array(0 to 130) of std_logic_vector(5 downto 0);
-  signal dac_ram                 : dac_ram_t;
-  signal dac_ram_write_0         : std_logic;
-  signal dac_ram_write_1         : std_logic;
-  signal dac_ram_input_addr_0    : unsigned(7 downto 0);
-  signal dac_ram_input_addr_1    : unsigned(7 downto 0);
-  signal dac_ram_input_0         : std_logic_vector(5 downto 0);
-  signal dac_ram_input_1         : std_logic_vector(5 downto 0);
-
-  signal ctr                     : std_logic_vector(5 downto 0);
-  signal i2c_ram_write_d         : std_logic;
-  signal dac_ram_write_d         : std_logic;
+  signal dac_read_token_r        : std_logic_vector(128 downto 0);
+  signal dac_write_token_r       : std_logic_vector(128 downto 0);
+
+  signal nxyter_polarity         : std_logic_vector(1 downto 0);  -- 0: negative
+  signal nxyter_testpulse        : std_logic_vector(1 downto 0);
+  signal nxyter_testtrigger      : std_logic_vector(1 downto 0);
+  signal nxyter_clock            : std_logic_vector(1 downto 0);
+  signal nxyter_testchannels     : std_logic_vector(2 downto 0); 
+  signal i2c_update_memory_r     : std_logic;
 begin
 
   -----------------------------------------------------------------------------
@@ -164,120 +204,198 @@ begin
   -----------------------------------------------------------------------------
 
   DEBUG_OUT(0)            <= CLK_IN;
-  DEBUG_OUT(1)            <= read_nx_i2c_all_start;
-  DEBUG_OUT(2)            <= write_nx_i2c_all_start;
-  DEBUG_OUT(3)            <= read_dac_all_start;
-  DEBUG_OUT(4)            <= write_dac_all_start;
-
-  DEBUG_OUT(5)            <= i2c_lock_o;
-  DEBUG_OUT(6)            <= i2c_command_busy;
-  DEBUG_OUT(7)            <= i2c_command_done;
-  DEBUG_OUT(8)            <= I2C_COMMAND_BUSY_IN;
-  
-  DEBUG_OUT(9)            <= i2c_ram_write_d;
-  DEBUG_OUT(10)           <= i2c_ram_write_0;
-  DEBUG_OUT(11)           <= i2c_ram_write_1;
-  DEBUG_OUT(12)           <= dac_ram_write_d;
-  DEBUG_OUT(13)           <= dac_ram_write_0;
-  DEBUG_OUT(14)           <= dac_ram_write_1;
-  DEBUG_OUT(15)           <= '0';
-
-  --DEBUG_OUT(14 downto 9)  <= ctr;
-  ctr <= std_logic_vector(r_register_ctr) or std_logic_vector(w_register_ctr);
-  
+  DEBUG_OUT(1)            <= I2C_COMMAND_BUSY_IN;
+  DEBUG_OUT(2)            <= i2c_command_busy_o;
+  DEBUG_OUT(3)            <= i2c_error;
+  DEBUG_OUT(4)            <= i2c_command_done;
+  DEBUG_OUT(5)            <= next_token_dac_r or
+                             next_token_dac_w;
+  DEBUG_OUT(6)            <= i2c_update_memory;
+  DEBUG_OUT(7)            <= i2c_lock_0_clear;
+  DEBUG_OUT(8)            <= i2c_lock_1_clear;
+  DEBUG_OUT(9)            <= i2c_lock_2_clear;
+  DEBUG_OUT(10)           <= i2c_lock_3_clear;
+  DEBUG_OUT(11)           <= i2c_online_o; 
+  DEBUG_OUT(12)           <= i2c_lock_0;
+  DEBUG_OUT(13)           <= i2c_lock_1;
+  DEBUG_OUT(14)           <= i2c_lock_2;
+  DEBUG_OUT(15)           <= i2c_lock_3;
+
   -----------------------------------------------------------------------------
 
-  PROC_I2C_RAM_WRITE_HANDLER: process(CLK_IN)
+  PROC_I2C_RAM: process(CLK_IN)
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
-        i2c_ram_write_d <= '0';
+        i2c_write_token_r   <= (others => '0');
+        do_write            <= '0';
       else
-        i2c_ram_write_d <= '0';
-        if (i2c_ram_write_0 = '1') then
-          i2c_ram(to_integer(i2c_ram_input_addr_0)) <= i2c_ram_input_0;
-          i2c_ram_write_d                           <= '1';
-        elsif (i2c_ram_write_1 = '1') then
-          i2c_ram(to_integer(i2c_ram_input_addr_1)) <= i2c_ram_input_1;
-          i2c_ram_write_d                           <= '1';
+        i2c_write_token_r   <= (others => '0');
+        do_write            <= '0';
+        
+        if (ram_write_0 = '1' and register_access_type(ram_index_0) = '1') then
+          i2c_ram(ram_index_0)           <= ram_data_0;
+          i2c_write_token_r(ram_index_0) <= '1';
+          do_write                       <= '1';
+        elsif (ram_write_1 = '1'                       and
+               register_access_type(ram_index_1) = '1' and
+               i2c_write_token(ram_index_1) = '0') then
+          i2c_ram(ram_index_1)           <= ram_data_1;
+          do_write                       <= '1';
+        elsif (nxyter_polarity(1) = '1') then
+          i2c_ram(33)(2)                 <= nxyter_polarity(0);
+          i2c_ram(32)(2)                 <= not nxyter_polarity(0);
+          i2c_write_token_r(33)          <= '1';
+          i2c_write_token_r(32)          <= '1';
+          do_write                       <= '1';
+        elsif (nxyter_clock(1) = '1') then
+          i2c_ram(33)(3)                 <= nxyter_clock(0);  
+          i2c_write_token_r(33)          <= '1';
+          do_write                       <= '1';
+        elsif (nxyter_testtrigger(1) = '1') then
+          i2c_ram(32)(3)                 <= nxyter_testtrigger(0);  
+          i2c_write_token_r(32)          <= '1';
+          do_write                       <= '1';
+        elsif (nxyter_testpulse(1) = '1') then
+          i2c_ram(32)(0)                 <= nxyter_testpulse(0);  
+          i2c_write_token_r(32)          <= '1';
+          do_write                       <= '1';
+        elsif (nxyter_testchannels(2) = '1') then
+          i2c_ram(33)(1 downto 0)        <= nxyter_testchannels(1 downto 0);
+          i2c_write_token_r(33)          <= '1';
+          do_write                       <= '1';
         end if;
       end if;
     end if;
-  end process PROC_I2C_RAM_WRITE_HANDLER;
+  end process PROC_I2C_RAM;
 
-  PROC_DAC_RAM_WRITE_HANDLER: process(CLK_IN)
+  PROC_DAC_RAM: process(CLK_IN)
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
-        dac_ram_write_d <= '0';
+        dac_write_token_r   <= (others => '0');
+        do_dac_write        <= '0';
       else
-        dac_ram_write_d <= '0';
+        dac_write_token_r   <= (others => '0');
+        do_dac_write        <= '0';
+        
         if (dac_ram_write_0 = '1') then
-          dac_ram(to_integer(dac_ram_input_addr_0)) <= dac_ram_input_0;
-          dac_ram_write_d                           <= '1';
-        elsif (dac_ram_write_1 = '1') then
-          dac_ram(to_integer(dac_ram_input_addr_1)) <= dac_ram_input_1;
-          dac_ram_write_d                           <= '1';
+          dac_ram(dac_ram_index_0)           <= dac_ram_data_0;
+          dac_write_token_r(dac_ram_index_0) <= '1';
+          do_dac_write                       <= '1';
+        elsif (dac_ram_write_1 = '1' and
+               dac_write_token(dac_ram_index_1) = '0') then
+          dac_ram(dac_ram_index_1)           <= dac_ram_data_1;
+          do_dac_write                       <= '1';
         end if;
       end if;
     end if;
-  end process PROC_DAC_RAM_WRITE_HANDLER;
-        
+  end process PROC_DAC_RAM;
+         
   -----------------------------------------------------------------------------
 
-  i2c_lock_o    <= nx_write_i2c_lock or
-                   nx_read_i2c_lock or
-                   dac_read_i2c_lock or
-                   dac_write_i2c_lock;
-  i2c_command   <= nx_write_i2c_command or
-                   nx_read_i2c_command or
-                   dac_read_i2c_command or
-                   dac_write_i2c_command;
+  PROC_I2C_COMMAND_MULTIPLEXER: process(CLK_IN)
+    variable locks : std_logic_vector(3 downto 0) := (others => '0');
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        i2c_lock_0       <= '0';
+        i2c_lock_1       <= '0';
+        i2c_lock_2       <= '0';
+        i2c_lock_3       <= '0';
+        i2c_command      <= (others => '0');
+      else
+        i2c_command      <= (others => '0');
+        locks := i2c_lock_3 & i2c_lock_2 & i2c_lock_1 & i2c_lock_0;
+        
+        -- Clear Locks
+        if (i2c_lock_0_clear = '1') then
+          i2c_lock_0          <= '0';
+        end if;
+        if (i2c_lock_1_clear = '1') then
+          i2c_lock_1          <= '0';
+        end if;
+        if (i2c_lock_2_clear = '1') then
+          i2c_lock_2          <= '0';
+        end if;
+        if (i2c_lock_3_clear = '1') then
+          i2c_lock_3          <= '0';
+        end if;
+
+        if (i2c_command_busy_o = '0') then
+          if (nx_i2c_command(31)  = '1'      and
+              ((locks and "1110") = "0000")  and
+              i2c_lock_0_clear    = '0') then
+            i2c_command       <= nx_i2c_command;
+            i2c_lock_0        <= '1';
+          elsif (dac_write_i2c_command(31) = '1'     and
+                 ((locks and "1011")       = "0000") and
+                 i2c_lock_2_clear          = '0') then
+            i2c_command       <= dac_write_i2c_command;
+            i2c_lock_2        <= '1';
+          elsif (dac_read_i2c_command(31) = '1'      and
+                 ((locks and "1101")      = "0000")  and
+                 i2c_lock_1_clear         = '0') then
+            i2c_command       <= dac_read_i2c_command;
+            i2c_lock_1        <= '1';
+          elsif (i2c_online_command(31) = '1'     and
+                 ((locks and "0111")    = "0000") and
+                 i2c_lock_3_clear       = '0') then
+            i2c_command       <= i2c_online_command;
+            i2c_lock_3        <= '1';
+          end if;
+        end if;
+      end if;
+    end if;
+  end process PROC_I2C_COMMAND_MULTIPLEXER;
 
   PROC_SEND_I2C_COMMAND: process(CLK_IN)
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
-        i2c_command_o    <= (others => '0');
-        i2c_command_busy <= '0';
-        i2c_command_done <= '0';
-        i2c_data         <= (others => '0');
-        I2C_STATE        <= I2C_IDLE;
+        i2c_command_o       <= (others => '0');
+        i2c_command_busy_o  <= '0';
+        i2c_command_done    <= '0';
+        i2c_error           <= '0';
+        i2c_data            <= (others => '0');
+        I2C_STATE           <= I2C_IDLE;
       else
-        i2c_command_o    <= (others => '0');
-        i2c_command_busy <= '0';
-        i2c_command_done <= '0';
+        i2c_command_o       <= (others => '0');
+        i2c_command_busy_o  <= '1';
+        i2c_command_done    <= '0';
+        i2c_error           <= '0';
         
         case I2C_STATE is
 
           when I2C_IDLE =>
             if (i2c_command(31) = '1') then
-              i2c_command_o    <= i2c_command;
-              i2c_command_busy <= '1';
-              I2C_STATE        <= I2C_WAIT_BUSY_HIGH;
+              i2c_command_o       <= i2c_command;
+              I2C_STATE           <= I2C_WAIT_BUSY_HIGH;
             else
-              I2C_STATE        <= I2C_IDLE;
+              i2c_command_busy_o  <= '0';
+              I2C_STATE           <= I2C_IDLE;
             end if;
 
           when I2C_WAIT_BUSY_HIGH =>
             if (I2C_COMMAND_BUSY_IN = '0') then
-              i2c_command_o    <= i2c_command_o;
-              i2c_command_busy <= '1';
-              I2C_STATE        <= I2C_WAIT_BUSY_HIGH;
+              i2c_command_o       <= i2c_command_o;
+              I2C_STATE           <= I2C_WAIT_BUSY_HIGH;
             else
-              i2c_command_busy <= '1';
-              I2C_STATE        <= I2C_WAIT_BUSY_LOW;
+              I2C_STATE           <= I2C_WAIT_BUSY_LOW;
             end if;
 
           when I2C_WAIT_BUSY_LOW =>
             if (I2C_COMMAND_BUSY_IN = '1') then
-              i2c_command_busy <= '1';
-              I2C_STATE        <= I2C_WAIT_BUSY_LOW;
+              I2C_STATE           <= I2C_WAIT_BUSY_LOW;
             else
-              i2c_data         <= I2C_DATA_IN;
-              i2c_command_done <= '1';
-              i2c_command_busy <= '1';
-              I2C_STATE        <= I2C_IDLE;
+              if (i2c_data(29 downto 24) ="000000") then
+                i2c_error         <= '0';
+              else
+                i2c_error         <= '1';
+              end if;
+              i2c_data            <= I2C_DATA_IN;
+              i2c_command_done    <= '1';
+              I2C_STATE           <= I2C_IDLE;
             end if;
         end case;
         
@@ -287,277 +405,464 @@ begin
 
   -----------------------------------------------------------------------------
   
-  PROC_READ_NX_REGISTERS: process(CLK_IN)
+  PROC_I2C_TOKEN_HANDLER: process(CLK_IN)
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
-        nx_read_i2c_command    <= (others => '0');
-        nx_read_i2c_lock       <= '0';
-        i2c_ram_input_0        <= (others => '0');
-        i2c_ram_input_addr_0   <= (others => '0');
-        i2c_ram_write_0        <= '0';
-        r_register_ctr         <= (others => '0');
-        
-        R_STATE_RETURN         <= R_IDLE;
-        R_STATE                <= R_IDLE;
+        i2c_read_token      <= (others => '0');
+        i2c_write_token     <= (others => '0');
       else
-        nx_read_i2c_command    <= (others => '0');
-        nx_read_i2c_lock       <= '1';
-        i2c_ram_input_0        <= (others => '0');
-        i2c_ram_input_addr_0   <= (others => '0');
-        i2c_ram_write_0        <= '0';
+        -- Write Token
+        if (unsigned(i2c_write_token_r)    /= 0) then
+          i2c_write_token   <= i2c_write_token or i2c_write_token_r;
+        elsif (unsigned(write_token_clear) /= 0) then
+          i2c_write_token   <= i2c_write_token and (not write_token_clear); 
+        end if;
 
-        case R_STATE is
-          when R_IDLE =>
-            if (read_nx_i2c_all_start = '1') then
-              R_STATE                           <= R_REGISTER;
-            else
-              nx_read_i2c_lock                  <= '0';
-              R_STATE                           <= R_IDLE;
-            end if;
-            r_register_ctr                      <= (others => '0');
-
-          when R_REGISTER =>
-           if (register_access_type(to_integer(r_register_ctr)) = '1') then
-             nx_read_i2c_command(31 downto 16)  <= x"ff08";
-             nx_read_i2c_command(15 downto 14)  <= (others => '0');
-             nx_read_i2c_command(13 downto  8)  <= r_register_ctr;
-             nx_read_i2c_command( 7 downto  0)  <= (others => '0');
-             R_STATE_RETURN                     <= R_REGISTER_STORE;
-             R_STATE                            <= R_WAIT_DONE;
-           else
-             R_STATE                            <= R_REGISTER_STORE;
-           end if;
-
-          when R_REGISTER_STORE =>
-            if (register_access_type(to_integer(r_register_ctr)) = '1') then
-              i2c_ram_input_0                   <= i2c_data(7 downto 0);
-            else
-              i2c_ram_input_0                   <= x"be";
-            end if;
-            i2c_ram_input_addr_0                <= r_register_ctr;
-            i2c_ram_write_0                     <= '1';
-            r_register_ctr                      <= r_register_ctr + 1;
-            R_STATE                             <= R_NEXT_REGISTER;
-            
-          when R_NEXT_REGISTER =>
-            if (r_register_ctr < x"2e") then
-              R_STATE                           <= R_REGISTER;
-            else
-              R_STATE                           <= R_IDLE;
-            end if;
-            
-          when R_WAIT_DONE =>
-            if (i2c_command_done = '0') then
-              R_STATE                           <= R_WAIT_DONE;
-            else
-              R_STATE                           <= R_STATE_RETURN;
-            end if;
+        -- Read Token
+        if (i2c_update_memory = '1') then
+          i2c_read_token    <= (others => '1');
+        elsif (unsigned(i2c_read_token_r) /= 0) then
+          i2c_read_token    <= i2c_read_token or i2c_read_token_r;
+        elsif (unsigned(read_token_clear) /= 0) then
+          i2c_read_token    <= i2c_read_token and (not read_token_clear); 
+        end if;
+      end if;
+    end if;
+  end process PROC_I2C_TOKEN_HANDLER;
 
-        end case;
-     end if;
+  PROC_DAC_TOKEN_HANDLER: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        dac_read_token     <= (others => '0');
+        dac_write_token    <= (others => '0');
+      else
+        -- Write Token
+        if (unsigned(dac_write_token_r) /= 0) then
+          dac_write_token   <= dac_write_token or dac_write_token_r;
+        elsif (unsigned(dac_write_token_clear) /= 0) then
+          dac_write_token   <= dac_write_token and (not dac_write_token_clear); 
+        end if;
+
+        -- Read Token
+        if (i2c_update_memory = '1') then
+          dac_read_token    <= (others => '1');
+        elsif (unsigned(dac_read_token_r) /= 0) then
+          dac_read_token    <= dac_read_token or dac_read_token_r;
+        elsif (unsigned(dac_read_token_clear) /= 0) then
+          dac_read_token    <= dac_read_token and (not dac_read_token_clear); 
+        end if;
+      end if;
     end if;
-  end process PROC_READ_NX_REGISTERS;
+  end process PROC_DAC_TOKEN_HANDLER;
 
-  PROC_WRITE_NX_REGISTERS: process(CLK_IN)
+  -----------------------------------------------------------------------------
+  
+  PROC_I2C_REGISTERS_HANDLER: process(CLK_IN)
+    variable index  : integer := 0;
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
-        nx_write_i2c_lock        <= '0';
-        nx_write_i2c_command     <= (others => '0');
-        w_register_ctr           <= (others => '0');
-        
-        W_STATE_RETURN           <= W_IDLE;
-        W_STATE                  <= W_IDLE;
+        nx_i2c_command           <= (others => '0');
+        token_ctr                <= (others => '0');
+        next_token               <= '0';
+        read_token_clear         <= (others => '0');
+        write_token_clear        <= (others => '0');
+        ram_write_1              <= '0';
+        i2c_lock_0_clear         <= '0';
+        T_STATE                  <= T_IDLE_TOKEN;
       else
-        nx_write_i2c_command     <= (others => '0');
-        nx_write_i2c_lock        <= '1';
-        
-        case W_STATE is
+        index                    :=  to_integer(unsigned(token_ctr));
+        nx_i2c_command           <= (others => '0');
+        next_token               <= '0';
+        read_token_clear         <= (others => '0');
+        write_token_clear        <= (others => '0');
+        ram_write_1              <= '0';
+        i2c_lock_0_clear         <= '0';
+
+        case T_STATE is
+          
+          when T_IDLE_TOKEN =>
+            if (register_access_type(index) = '1') then
+              if (i2c_write_token(index) = '1') then
+                T_STATE                          <= T_WRITE_I2C_REGISTER;
+              elsif (i2c_read_token(index) = '1') then
+                T_STATE                          <= T_READ_I2C_REGISTER;
+              else
+                T_STATE                          <= T_NEXT_TOKEN;
+              end if;
+            else
+              read_token_clear(index)            <= '1';
+              write_token_clear(index)           <= '1';
+              T_STATE                            <= T_NEXT_TOKEN;
+            end if;
 
-          when W_IDLE =>
-            if (write_nx_i2c_all_start = '1') then
-              W_STATE                            <= W_REGISTER;
+            -- Write I2C Register
+          when T_WRITE_I2C_REGISTER =>
+            nx_i2c_command(31 downto 16)         <= x"bf08";
+            nx_i2c_command(15 downto 14)         <= (others => '0');
+            nx_i2c_command(13 downto  8)         <= token_ctr;
+            nx_i2c_command( 7 downto  0)         <= i2c_ram(index);
+            if (i2c_lock_0 = '0') then
+              T_STATE                            <= T_WRITE_I2C_REGISTER;
             else
-              nx_write_i2c_lock                  <= '0';
-              W_STATE                            <= W_IDLE;
+              write_token_clear(index)           <= '1';
+              T_STATE                            <= T_WAIT_I2C_WRITE_DONE;
             end if;
-            w_register_ctr                       <= (others => '0');
-            
-          when W_REGISTER =>
-            if (register_access_type(
-              to_integer(unsigned(w_register_ctr))) = '1') 
-            then
-              nx_write_i2c_command(31 downto 16) <= x"bf08";
-              nx_write_i2c_command(15 downto 14) <= (others => '0');
-              nx_write_i2c_command(13 downto  8) <= w_register_ctr;
-              nx_write_i2c_command( 7 downto  0) <=
-                i2c_ram(to_integer(unsigned(w_register_ctr)));
-              W_STATE_RETURN                     <= W_NEXT_REGISTER;
-              W_STATE                            <= W_WAIT_DONE;
+
+          when T_WAIT_I2C_WRITE_DONE =>
+            if (i2c_command_done = '0') then
+              T_STATE                            <= T_WAIT_I2C_WRITE_DONE;
             else
-              W_STATE                            <= W_NEXT_REGISTER;
+              i2c_lock_0_clear                   <= '1';
+              T_STATE                            <= T_NEXT_TOKEN;
             end if;
-            w_register_ctr                       <= w_register_ctr + 1;
 
-          when W_NEXT_REGISTER =>
-            if (w_register_ctr < x"2e") then
-              W_STATE                            <= W_REGISTER;
+            -- Read I2C Register
+          when T_READ_I2C_REGISTER =>
+            nx_i2c_command(31 downto 16)         <= x"ff08";
+            nx_i2c_command(15 downto 14)         <= (others => '0');
+            nx_i2c_command(13 downto  8)         <= token_ctr;
+            nx_i2c_command( 7 downto  0)         <= (others => '0');
+            if (i2c_lock_0 = '0') then
+              T_STATE                            <= T_READ_I2C_REGISTER;
             else
-              W_STATE                            <= W_IDLE;
+              read_token_clear(index)            <= '1';
+              T_STATE                            <= T_WAIT_I2C_READ_DONE;
             end if;
 
-          when W_WAIT_DONE =>
+          when T_WAIT_I2C_READ_DONE =>
             if (i2c_command_done = '0') then
-              W_STATE                            <= W_WAIT_DONE;
+              T_STATE                            <= T_WAIT_I2C_READ_DONE;
             else
-              W_STATE                            <= W_STATE_RETURN;
+              T_STATE                            <= T_READ_I2C_STORE_MEM;
             end if;
 
+          when T_READ_I2C_STORE_MEM =>
+            ram_index_1                          <= index;
+            ram_data_1                           <= i2c_data(7 downto 0);
+            ram_write_1                          <= '1';
+            i2c_lock_0_clear                     <= '1';
+            T_STATE                              <= T_NEXT_TOKEN;
+            
+            -- Next Token
+          when T_NEXT_TOKEN =>
+            if (token_ctr < x"2e") then
+              token_ctr                          <= token_ctr + 1;
+            else
+              token_ctr                          <= (others => '0');
+            end if;
+            next_token                           <= '1';
+            T_STATE                              <= T_IDLE_TOKEN;
+            
         end case;
       end if;
     end if;
-  end process PROC_WRITE_NX_REGISTERS;
+  end process PROC_I2C_REGISTERS_HANDLER;
 
   -----------------------------------------------------------------------------
 
   PROC_READ_DAC_REGISTERS: process(CLK_IN)
+    variable index : integer := 0;
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
         dac_read_i2c_command   <= (others => '0');
-        dac_read_i2c_lock      <= '0';
-        dac_ram_write_0        <= '0';
-        dac_ram_input_addr_0   <= (others => '0');
-        dac_ram_input_0        <= (others => '0');
+        dac_ram_write_1        <= '0';
+        dac_ram_index_1        <= 0;
+        dac_ram_data_1         <= (others => '0');
         r_fifo_ctr             <= (others => '0');
-
+        dac_read_token_clear   <= (others => '0');
+        next_token_dac_r       <= '0';
+        i2c_lock_1_clear       <= '0';
         DR_STATE_RETURN        <= DR_IDLE;
         DR_STATE               <= DR_IDLE;
       else
         dac_read_i2c_command   <= (others => '0');
-        dac_read_i2c_lock      <= '1';
-        dac_ram_write_0        <= '0';
-        dac_ram_input_addr_0   <= (others => '0');
-        dac_ram_input_0        <= (others => '0');
+        dac_ram_write_1        <= '0';
+        dac_ram_index_1        <= 0;
+        dac_ram_data_1         <= (others => '0');
+        dac_read_token_clear   <= (others => '0');
+        next_token_dac_r       <= '0';
+        i2c_lock_1_clear       <= '0';
+        index                  := to_integer(r_fifo_ctr);
         
         case DR_STATE is
           when DR_IDLE =>
-            if (read_dac_all_start = '1') then
-              DR_STATE                          <= DR_REGISTER;
+            if (unsigned(dac_read_token) /= 0) then
+              DR_STATE                           <= DR_REGISTER;
             else
-              dac_read_i2c_lock                 <= '0';
-              DR_STATE                          <= DR_IDLE;
+              DR_STATE                           <= DR_IDLE;
             end if;
-            r_fifo_ctr                          <= (others => '0');
+            r_fifo_ctr                           <= (others => '0');
 
           when DR_REGISTER =>
-            dac_read_i2c_command(31 downto 16)  <= x"ff08";
-            dac_read_i2c_command(15 downto 8)   <= x"2a";  -- DAC Reg 42
-            dac_read_i2c_command(7 downto 0)    <= (others => '0');
-            DR_STATE_RETURN                     <= DR_WRITE_BACK;
-            DR_STATE                            <= DR_WAIT_DONE;
-
-          when DR_WRITE_BACK =>
-            -- Store FIFO Entry
-            dac_ram_input_0                     <= i2c_data(5 downto 0);
-            dac_ram_input_addr_0                <= r_fifo_ctr;
-            dac_ram_write_0                     <= '1';
-            
-            -- Write Data Back to FIFO
-            dac_read_i2c_command(31 downto 16)  <= x"bf08";
-            dac_read_i2c_command(15 downto 8)   <= x"2a";  -- DAC Reg 42
-            dac_read_i2c_command(5 downto 0)    <= i2c_data(5 downto 0);
-            dac_read_i2c_command(7 downto 6)    <= (others => '0');
-              r_fifo_ctr                        <= r_fifo_ctr + 1;
-            DR_STATE_RETURN                     <= DR_NEXT_REGISTER;
-            DR_STATE                            <= DR_WAIT_DONE;
-           
-          when DR_NEXT_REGISTER =>
-            if (r_fifo_ctr < x"81") then
-              DR_STATE                          <= DR_REGISTER;
+            dac_read_i2c_command(31 downto 16)   <= x"ff08";
+            dac_read_i2c_command(15 downto 8)    <= x"2a";  -- DAC Reg 42
+            dac_read_i2c_command(7 downto 0)     <= (others => '0');
+            if (i2c_lock_1 = '0') then
+              DR_STATE                            <= DR_REGISTER;
             else
-              DR_STATE                          <= DR_IDLE;
+              dac_read_token_clear(index)         <= '1';
+              DR_STATE_RETURN                     <= DR_WRITE_BACK;
+              DR_STATE                            <= DR_WAIT_DONE;
             end if;
             
+          when DR_WRITE_BACK =>
+            -- Store FIFO Entry
+            dac_ram_data_1                        <= i2c_data(5 downto 0);
+            dac_ram_index_1                       <= index;
+            dac_ram_write_1                       <= '1';
+                                                  
+            -- Write Data Back to FIFO            
+            dac_read_i2c_command(31 downto 16)    <= x"bf08";
+            dac_read_i2c_command(15 downto 8)     <= x"2a";  -- DAC Reg 42
+            dac_read_i2c_command(5 downto 0)      <= i2c_data(5 downto 0);
+            dac_read_i2c_command(7 downto 6)      <= (others => '0');
+            DR_STATE_RETURN                       <= DR_NEXT_REGISTER;
+            DR_STATE                              <= DR_WAIT_DONE;
+                                                  
+          when DR_NEXT_REGISTER =>
+            if (r_fifo_ctr < x"80") then          
+              r_fifo_ctr                          <= r_fifo_ctr + 1;
+              next_token_dac_r                    <= '1';
+              DR_STATE                            <= DR_REGISTER;
+            else                                  
+              i2c_lock_1_clear                    <= '1';
+              DR_STATE                            <= DR_IDLE;
+            end if;                               
+                                                  
           when DR_WAIT_DONE =>
-            if (i2c_command_done = '0') then
-              DR_STATE                          <= DR_WAIT_DONE;
-            else
-              DR_STATE                          <= DR_STATE_RETURN;
+            if (i2c_command_done = '0') then      
+              DR_STATE                            <= DR_WAIT_DONE;
+            else                                  
+              DR_STATE                            <= DR_STATE_RETURN;
             end if;
-
         end case;
-     end if;
+
+      end if;
     end if;
   end process PROC_READ_DAC_REGISTERS;
 
   PROC_WRITE_DAC_REGISTERS: process(CLK_IN)
+    variable index : integer := 0;
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
         dac_write_i2c_command  <= (others => '0');
-        dac_write_i2c_lock     <= '0';
         w_fifo_ctr             <= (others => '0');
-
+        dac_write_token_clear  <= (others => '0');
+        next_token_dac_w       <= '0';
+        i2c_lock_2_clear       <= '0';
         DW_STATE_RETURN        <= DW_IDLE;
         DW_STATE               <= DW_IDLE;
       else
         dac_write_i2c_command  <= (others => '0');
-        dac_write_i2c_lock     <= '1';
+        dac_write_token_clear  <= (others => '0');
+        next_token_dac_w       <= '0';
+        i2c_lock_2_clear       <= '0';
         
+        index                  := to_integer(w_fifo_ctr);
         case DW_STATE is
           when DW_IDLE =>
-            if (write_dac_all_start = '1') then
-              DW_STATE                          <= DW_REGISTER;
+            if (unsigned(dac_write_token) /= 0) then
+              DW_STATE                            <= DW_REGISTER;
             else
-              dac_write_i2c_lock                <= '0';
-              DW_STATE                          <= DW_IDLE;
+              DW_STATE                            <= DW_IDLE;
             end if;
-            w_fifo_ctr                          <= (others => '0');
+            w_fifo_ctr                            <= (others => '0');
 
           when DW_REGISTER =>
             dac_write_i2c_command(31 downto 16) <= x"ff08";
             dac_write_i2c_command(15 downto 8)  <= x"2a";  -- DAC Reg 42
             dac_write_i2c_command(7 downto 0)   <= (others => '0');
-            DW_STATE_RETURN                     <= DW_WRITE_BACK;
-            DW_STATE                            <= DW_WAIT_DONE;
+            dac_write_token_clear(index)        <= '1';
+            if (i2c_lock_2 = '0') then
+              DW_STATE                            <= DW_REGISTER;
+            else
+              dac_write_token_clear(index)        <= '1';
+              DW_STATE_RETURN                     <= DW_WRITE_BACK;
+              DW_STATE                            <= DW_WAIT_DONE;
+            end if;
             
           when DW_WRITE_BACK =>
             -- Write Data Back to FIFO
-            dac_write_i2c_command(31 downto 16) <= x"bf08";
-            dac_write_i2c_command(15 downto 8)  <= x"2a";  -- DAC Reg 42
-            dac_write_i2c_command(7 downto 6)   <= (others => '0');
-            dac_write_i2c_command(5 downto 0)   <=
-              dac_ram(to_integer(w_fifo_ctr));
-            w_fifo_ctr                        <= w_fifo_ctr + 1;
-            DW_STATE_RETURN                     <= DW_NEXT_REGISTER;
-            DW_STATE                            <= DW_WAIT_DONE;
-           
-          when DW_NEXT_REGISTER =>
-            if (w_fifo_ctr < x"81") then
-              DW_STATE                          <= DW_REGISTER;
+            dac_write_i2c_command(31 downto 16)   <= x"bf08";
+            dac_write_i2c_command(15 downto 8)    <= x"2a";  -- DAC Reg 42
+            dac_write_i2c_command(7 downto 6)     <= (others => '0');
+            dac_write_i2c_command(5 downto 0)     <= dac_ram(index);
+            DW_STATE_RETURN                       <= DW_NEXT_REGISTER;
+            DW_STATE                              <= DW_WAIT_DONE;
+                                                  
+          when DW_NEXT_REGISTER =>                
+            if (w_fifo_ctr < x"80") then          
+              w_fifo_ctr                            <= w_fifo_ctr + 1;
+              next_token_dac_w                    <= '1';
+              DW_STATE                            <= DW_REGISTER;
+            else                                  
+              i2c_lock_2_clear                    <= '1';
+              DW_STATE                            <= DW_IDLE;
+            end if;                               
+                                                  
+          when DW_WAIT_DONE =>                    
+            if (i2c_command_done = '0') then      
+              DW_STATE                            <= DW_WAIT_DONE;
+            else                                  
+              DW_STATE                            <= DW_STATE_RETURN;
+            end if;
+
+        end case;
+     end if;
+    end if;
+  end process PROC_WRITE_DAC_REGISTERS;
+
+  -----------------------------------------------------------------------------
+  
+  nx_timer_1: nx_timer
+    generic map (
+      CTR_WIDTH => 32
+      )
+    port map (
+      CLK_IN         => CLK_IN,
+      RESET_IN       => RESET_IN,
+      TIMER_START_IN => wait_timer_init,
+      TIMER_DONE_OUT => wait_timer_done
+      );
+  
+  PROC_I2C_ONLINE: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        i2c_online_command     <= (others => '0');
+        i2c_online_o           <= '0';
+        i2c_lock_3_clear       <= '0';
+        wait_timer_init        <= (others => '0');
+        R_STATE                <= R_TIMER_RESTART;
+      else
+        i2c_online_command     <= (others => '0');
+        i2c_lock_3_clear       <= '0';
+        wait_timer_init        <= (others => '0');
+
+        case R_STATE is
+
+          when R_TIMER_RESTART =>
+            wait_timer_init                    <= x"1dcd_6500"; -- 5s
+            R_STATE                            <= R_IDLE;
+
+          when R_IDLE =>
+            if (wait_timer_done = '1') then
+              R_STATE                          <= R_READ_DUMMY;
             else
-              DW_STATE                          <= DW_IDLE;
+              R_STATE                          <= R_IDLE;
             end if;
-            
-          when DW_WAIT_DONE =>
+
+          when R_READ_DUMMY =>
+            i2c_online_command(31 downto 16)   <= x"ff08";
+            i2c_online_command(15 downto 8)    <= x"1f";  -- Dummy register
+            i2c_online_command(7 downto 0)     <= (others => '0');
+            if (i2c_lock_3 = '0') then
+              R_STATE                          <= R_READ_DUMMY;
+            else
+              R_STATE                          <= R_WAIT_DONE;
+            end if;
+              
+          when R_WAIT_DONE =>
             if (i2c_command_done = '0') then
-              DW_STATE                          <= DW_WAIT_DONE;
+              R_STATE                          <= R_WAIT_DONE;
             else
-              DW_STATE                          <= DW_STATE_RETURN;
+              i2c_online_o                     <= not i2c_error;
+              i2c_lock_3_clear                 <= '1';
+              R_STATE                          <= R_TIMER_RESTART;
             end if;
 
         end case;
-     end if;
+
+      end if;
     end if;
-  end process PROC_WRITE_DAC_REGISTERS;
+  end process PROC_I2C_ONLINE;
+
+  PROC_I2C_STATUS: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        i2c_update_memory_p   <= '0';
+        i2c_disable_memory    <= '0';
+        i2c_online_t          <= (others => '0');
+        i2c_reg_reset_clear   <= '0';
+      else
+        i2c_reg_reset_clear   <= '0';
+
+        -- Shift Online
+        i2c_online_t(0)       <= i2c_online_o;
+        for I  in 1 to 7 loop
+          i2c_online_t(I)     <= i2c_online_t(I - 1);
+        end loop;  
+        
+        if (i2c_update_memory_r = '1') then
+          i2c_update_memory_p       <= '1';
+          i2c_disable_memory        <= '0';
+        else
+          
+          case i2c_online_t(7 downto 6) is
+            
+            when "00" =>
+              i2c_update_memory_p   <= '0';
+              i2c_disable_memory    <= '1';
+              
+            when "10" =>
+              i2c_update_memory_p   <= '0';
+              i2c_disable_memory    <= '1';
+              
+            when "01" =>
+              i2c_update_memory_p   <= '1';
+              i2c_disable_memory    <= '0';
+              
+            when "11" =>
+              if (i2c_reg_reset_in_s = '1' and I2C_REG_RESET_IN = '0') then
+                i2c_update_memory_p <= '1';
+                i2c_reg_reset_clear <= '1';
+              else
+                i2c_update_memory_p <= '0';
+              end if;
+              i2c_disable_memory    <= '0';
+
+          end case;
+        end if;
+      end if;
+    end if;
+  end process PROC_I2C_STATUS;
+
+  pulse_delay_1: pulse_delay
+    generic map (
+      DELAY => 10000
+      )
+    port map (
+      CLK_IN    => CLK_IN,
+      RESET_IN  => RESET_IN,
+      PULSE_IN  => i2c_update_memory_p,
+      PULSE_OUT => i2c_update_memory
+      );
   
+  PROC_REG_RESET: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        i2c_reg_reset_in_s    <= '0';
+      else
+        if (i2c_reg_reset_clear = '1') then
+          i2c_reg_reset_in_s  <= '0';
+        elsif(I2C_REG_RESET_IN = '1') then
+          i2c_reg_reset_in_s  <= '1';
+        end if;
+      end if;
+    end if;
+  end process PROC_REG_RESET;
+
   -----------------------------------------------------------------------------
   
   PROC_SLAVE_BUS: process(CLK_IN)
-    variable mem_address : unsigned(7 downto 0) := x"00";
-
+    variable index       : integer                      := 0;
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
@@ -566,107 +871,232 @@ begin
         slv_unknown_addr_o     <= '0';
         slv_ack_o              <= '0';
 
-        read_nx_i2c_all_start  <= '0';
-        write_nx_i2c_all_start <= '0';
-        read_dac_all_start     <= '0';
-        write_dac_all_start    <= '0';
+        ram_data_0             <= (others => '0');
+        ram_index_0            <= 0;
+        ram_write_0            <= '0';
+        i2c_read_token_r       <= (others => '0');
 
-        i2c_ram_input_1        <= (others => '0');
-        i2c_ram_input_addr_1   <= (others => '0');
-        i2c_ram_write_1        <= '0';
-        dac_ram_input_1        <= (others => '0');
-        dac_ram_input_addr_1   <= (others => '0');
-        dac_ram_write_1        <= '0';
+        dac_ram_data_0         <= (others => '0');
+        dac_ram_index_0        <= 0;
+        dac_ram_write_0        <= '0';
+        dac_read_token_r       <= (others => '0');
+        i2c_update_memory_r    <= '0';                
+        nxyter_clock           <= (others => '0');
+        nxyter_polarity        <= (others => '0');
+        nxyter_testtrigger     <= (others => '0');
+        nxyter_testpulse       <= (others => '0');
+        nxyter_testchannels    <= (others => '0');
       else                    
         slv_data_out_o         <= (others => '0');
         slv_unknown_addr_o     <= '0';
         slv_no_more_data_o     <= '0';
-
-        read_nx_i2c_all_start  <= '0';
-        write_nx_i2c_all_start <= '0';
-        read_dac_all_start     <= '0';
-        write_dac_all_start    <= '0';
-
-        i2c_ram_input_1        <= (others => '0');
-        i2c_ram_input_addr_1   <= (others => '0');
-        i2c_ram_write_1        <= '0';
-        dac_ram_input_1        <= (others => '0');
-        dac_ram_input_addr_1   <= (others => '0');
-        dac_ram_write_1        <= '0';
+        
+        ram_data_0             <= (others => '0');
+        ram_index_0            <= 0;
+        ram_write_0            <= '0';
+        i2c_read_token_r       <= (others => '0');
+        
+        dac_ram_data_0         <= (others => '0');
+        dac_ram_index_0        <= 0;
+        dac_ram_write_0        <= '0';
+        dac_read_token_r       <= (others => '0');
+        i2c_update_memory_r    <= '0';
+        nxyter_clock           <= (others => '0');
+        nxyter_polarity        <= (others => '0');
+        nxyter_testtrigger     <= (others => '0');
+        nxyter_testpulse       <= (others => '0');
+        nxyter_testchannels    <= (others => '0');
         
         if (SLV_WRITE_IN  = '1') then
-          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then
-            if (i2c_lock_o = '1') then
-              slv_no_more_data_o       <= '1';
-              slv_ack_o                <= '0';
-            else
-              if (register_access_type(
-                to_integer(unsigned(SLV_ADDR_IN(5 downto 0)))) = '1')
-              then
-                -- Write value to ram
-                i2c_ram_input_1        <= SLV_DATA_IN(7 downto 0);
-                i2c_ram_input_addr_1   <= unsigned(SLV_ADDR_IN(5 downto 0));
-                i2c_ram_write_1        <= '1';
-                slv_ack_o              <= '1';
-              end if;
-              slv_ack_o                <= '1';
+          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then
+            index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0)));
+            if (i2c_disable_memory = '0') then
+              ram_index_0                <= index;
+              ram_data_0                 <= SLV_DATA_IN(7 downto 0);
+              ram_write_0                <= '1';
             end if;
-
-          elsif (SLV_ADDR_IN >= x"0060" and SLV_ADDR_IN <= x"00e0") then
-            if (i2c_lock_o = '1') then
-              slv_no_more_data_o       <= '1';
-              slv_ack_o                <= '0';
-            else
-              -- Write value to ram
-              mem_address := unsigned(SLV_ADDR_IN(7 downto 0)) - x"60";
-              dac_ram_input_1          <= SLV_DATA_IN(5 downto 0);
-              dac_ram_input_addr_1     <= mem_address;
-              dac_ram_write_1          <= '1';
-              slv_ack_o                <= '1';
+            slv_ack_o                    <= '1';
+                      
+          elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN < x"0181") then
+            -- Write value to ram
+            index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0)));
+            if (i2c_disable_memory = '0') then
+              dac_ram_index_0            <= index;
+              dac_ram_data_0             <= SLV_DATA_IN(5 downto 0);
+              dac_ram_write_0            <= '1';
             end if;
+            slv_ack_o                    <= '1';
 
           else
             case SLV_ADDR_IN is
-              when x"0040" =>
-                read_nx_i2c_all_start  <= '1';
-                slv_ack_o              <= '1';
-
-              when x"0041" =>
-                write_nx_i2c_all_start <= '1';
-                slv_ack_o              <= '1';
-
-              when x"0042" =>
-                read_dac_all_start     <= '1';
-                slv_ack_o              <= '1';
-
-              when x"0043" =>
-                write_dac_all_start    <= '1';
-                slv_ack_o              <= '1';
-                              
+              when x"0050" =>
+                -- Nxyter Clock
+                if (i2c_disable_memory = '0') then
+                  nxyter_clock(0)        <= SLV_DATA_IN(0);
+                  nxyter_clock(1)        <= '1';
+                end if;
+                slv_ack_o                <= '1';
+                  
+              when x"0051" =>
+                -- Nxyter Polarity
+                if (i2c_disable_memory = '0') then
+                  nxyter_polarity(0)     <= SLV_DATA_IN(0);
+                  nxyter_polarity(1)     <= '1';
+                end if;
+                slv_ack_o                <= '1';  
+
+              when x"0053" =>
+                -- Nxyter Testpulse
+                if (i2c_disable_memory = '0') then
+                  nxyter_testpulse(0)    <= SLV_DATA_IN(0);
+                  nxyter_testpulse(1)    <= '1';
+                end if;
+                slv_ack_o                <= '1';
+                
+              when x"0054" =>
+                -- Nxyter Testtrigger
+                if (i2c_disable_memory = '0') then
+                  nxyter_testtrigger(0)  <= SLV_DATA_IN(0);
+                  nxyter_testtrigger(1)  <= '1';
+                end if;
+                slv_ack_o                <= '1';  
+
+              when x"0055" =>
+                -- Nxyter Testtrigger
+                if (i2c_disable_memory = '0') then
+                  nxyter_testchannels(1 downto 0) <= SLV_DATA_IN(1 downto 0);
+                  nxyter_testchannels(2) <= '1';
+                end if;
+                slv_ack_o                <= '1';
+                
+              when x"0060" =>
+                if (i2c_disable_memory = '0') then
+                  i2c_read_token_r       <= (others => '1');
+                end if;
+                slv_ack_o                <= '1';
+
+              when x"0061" =>
+                if (i2c_disable_memory = '0') then
+                  dac_read_token_r       <= (others => '1');
+                end if;
+                slv_ack_o                <= '1';
+
+              when x"0062" =>
+                if (i2c_disable_memory = '0') then
+                  i2c_update_memory_r    <= '1';
+                end if;
+                slv_ack_o                <= '1';
+                
               when others =>          
-                slv_unknown_addr_o     <= '1';
-                slv_ack_o              <= '0';    
+                slv_unknown_addr_o       <= '1';
+                slv_ack_o                <= '0';    
                                     
             end case;                     
           end if;
 
         elsif (SLV_READ_IN = '1') then
-          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then
-            slv_data_out_o(7 downto 0)  <= 
-              i2c_ram(to_integer(unsigned(SLV_ADDR_IN(5 downto 0))));
-            slv_data_out_o(31 downto 8) <= (others => '0');
-            slv_ack_o                   <= '1';
-          elsif (SLV_ADDR_IN >= x"0060" and SLV_ADDR_IN <= x"00e0") then
-            mem_address := unsigned(SLV_ADDR_IN(7 downto 0)) - x"60";
-            slv_data_out_o(5 downto 0)  <= dac_ram(to_integer(mem_address));
-            slv_data_out_o(31 downto 6) <= (others => '0');
-            slv_ack_o                   <= '1';
+          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then
+            index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0)));
+            if (i2c_disable_memory = '0') then
+              slv_data_out_o(7 downto 0)      <= i2c_ram(index);
+              slv_data_out_o(28 downto 8)     <= (others => '0');
+              slv_data_out_o(29)              <=
+                not register_access_type(index);
+              slv_data_out_o(30)              <= i2c_read_token(index);
+              slv_data_out_o(31)              <= i2c_write_token(index);
+            else
+              slv_data_out_o(31 downto 0)     <= (others => '1');
+            end if;
+            slv_ack_o                         <= '1';
+
+          elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN <= x"0180") then
+            index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0)));
+            if (i2c_disable_memory = '0') then
+              slv_data_out_o(5 downto 0)      <= dac_ram(index);
+              slv_data_out_o(31 downto 6)     <= (others => '0');
+              slv_data_out_o(30)              <= dac_read_token(index);
+              slv_data_out_o(31)              <= dac_write_token(index);
+            else
+              slv_data_out_o(31 downto 0)     <= (others => '1');
+            end if;  
+            slv_ack_o                         <= '1';
+
           else
-            slv_unknown_addr_o          <= '1';
-            slv_ack_o                   <= '0';
+            case SLV_ADDR_IN is
+              when x"0050" =>
+                -- Nxyter Clock
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(0)           <= i2c_ram(33)(3);
+                  slv_data_out_o(31 downto 1) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';
+                  
+              when x"0051" =>
+                -- Nxyter Polarity
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(0)           <= i2c_ram(33)(2);
+                  slv_data_out_o(31 downto 1) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';  
+
+              when x"0052" =>
+                -- Nxyter Testpulse Polarity
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(0)           <= i2c_ram(32)(2);
+                  slv_data_out_o(31 downto 1) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';
+
+              when x"0053" =>
+                -- Nxyter Testpulse
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(0)           <= i2c_ram(32)(0);
+                  slv_data_out_o(31 downto 1) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';
+
+              when x"0054" =>
+                -- Nxyter Testtrigger
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(0)           <= i2c_ram(32)(3);
+                  slv_data_out_o(31 downto 1) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';  
+
+              when x"0055" =>
+                -- Nxyter Testpulse Channels
+                if (i2c_disable_memory = '0') then
+                  slv_data_out_o(1 downto 0)  <= i2c_ram(33)(1 downto 0);
+                  slv_data_out_o(31 downto 2) <= (others => '0');
+                else
+                  slv_data_out_o(31 downto 0) <= (others => '1');
+                end if;
+                slv_ack_o                     <= '1';
+
+              when x"0056" =>
+                -- I2C Online
+                slv_data_out_o(0)             <= i2c_online_o;
+                slv_data_out_o(31 downto 2)   <= (others => '0');
+                slv_ack_o                     <= '1';
+
+              when others =>   
+                slv_unknown_addr_o            <= '1';
+                slv_ack_o                     <= '0';
+            end case;  
+
           end if;
         else                        
-          slv_ack_o                     <= '0';
+          slv_ack_o                         <= '0';
         end if;
         
       end if;
@@ -677,11 +1107,13 @@ begin
   -- Output Signals
   -----------------------------------------------------------------------------
   
-  I2C_COMMAND_OUT  <= i2c_command_o;
-  I2C_LOCK         <= i2c_lock_o;
+  I2C_COMMAND_OUT      <= i2c_command_o;
+  I2C_LOCK_OUT         <= i2c_command_busy_o;
+  I2C_ONLINE_OUT       <= i2c_online_o;
+
   
-  SPI_COMMAND_OUT  <= spi_command_o;
-  spi_command_o    <= (others => '0');
+  SPI_COMMAND_OUT      <= (others => '0');
+  SPI_LOCK_OUT         <= '0';
 
   -- Slave Bus
   SLV_DATA_OUT         <= slv_data_out_o;    
index 4587867090b9ff67dce8bc2ec541fb5ecc356d45..bbd317fc57854ea787c642a0f955960c53713270 100644 (file)
@@ -219,6 +219,8 @@ component nx_setup
     I2C_COMMAND_BUSY_IN  : in  std_logic;
     I2C_DATA_IN          : in  std_logic_vector(31 downto 0);
     I2C_LOCK_OUT         : out std_logic;
+    I2C_ONLINE_OUT       : out std_logic;
+    I2C_REG_RESET_IN     : in  std_logic;
     SPI_COMMAND_OUT      : out std_logic_vector(31 downto 0);
     SPI_COMMAND_BUSY_IN  : in  std_logic;
     SPI_DATA_IN          : in  std_logic_vector(31 downto 0);
@@ -591,6 +593,17 @@ component Gray_Encoder
     );
 end component;
 
+component pulse_delay
+  generic (
+    DELAY : integer range 2 to 16777216);
+  port (
+    CLK_IN    : in  std_logic;
+    RESET_IN  : in  std_logic;
+    PULSE_IN  : in  std_logic;
+    PULSE_OUT : out std_logic
+    );
+end component;
+
 -------------------------------------------------------------------------------
 -- PLLs
 -------------------------------------------------------------------------------
index 1316ea89b15a2d8fa49f2b597200f9f4794d3f18..d6f9d62c053770c1dd1a945db0204503a541fa9a 100644 (file)
@@ -118,7 +118,9 @@ architecture Behavioral of nXyter_FEE_board is
   signal nx_ts_reset_2          : std_logic;
   signal nx_ts_reset_o          : std_logic;
   signal i2c_reg_reset_o        : std_logic;
-                                
+  signal nxyter_offline_reg     : std_logic;
+  signal nxyter_offline         : std_logic;
+  
   -- NX Register Access         
   signal i2c_lock               : std_logic;
   signal i2c_command            : std_logic_vector(31 downto 0);
@@ -128,6 +130,7 @@ architecture Behavioral of nXyter_FEE_board is
   signal spi_command            : std_logic_vector(31 downto 0);
   signal spi_command_busy       : std_logic;
   signal spi_data               : std_logic_vector(31 downto 0);
+  signal nxyter_online_i2c      : std_logic;
                                 
   -- SPI Interface ADC          
   signal spi_sdi                : std_logic;
@@ -182,7 +185,6 @@ architecture Behavioral of nXyter_FEE_board is
   signal lvl2_trigger           : std_logic;
   signal trigger_busy           : std_logic;
   signal fast_clear             : std_logic;
-  signal nxyter_offline         : std_logic;
   signal fee_trg_release_o      : std_logic;
   signal trigger_testpulse      : std_logic;
 
@@ -250,7 +252,7 @@ begin
                                 6 => 4,          -- Data Validate
                                 7 => 4,          -- Trigger Handler
                                 8 => 4,          -- Trigger Validate
-                                9 => 8,          -- NX Setup
+                                9 => 9,          -- NX Setup
                                10 => 9,          -- NX Histograms
                                11 => 0,          -- Debug Handler
                                12 => 1,          -- Data Delay
@@ -296,16 +298,16 @@ begin
 -------------------------------------------------------------------------------
   nxyter_registers_1: nxyter_registers
     port map (
-      CLK_IN                 => CLK_IN,
-      RESET_IN               => RESET_IN,
+      CLK_IN                   => CLK_IN,
+      RESET_IN                 => RESET_IN,
 
-      PLL_NX_CLK_LOCK_IN     => PLL_NX_CLK_LOCK_IN, 
-      PLL_ADC_CLK_LOCK_IN    => PLL_ADC_CLK_LOCK_IN,
+      PLL_NX_CLK_LOCK_IN       => PLL_NX_CLK_LOCK_IN, 
+      PLL_ADC_CLK_LOCK_IN      => PLL_ADC_CLK_LOCK_IN,
      
-      I2C_SM_RESET_OUT       => i2c_sm_reset_o,
-      I2C_REG_RESET_OUT      => i2c_reg_reset_o,
-      NX_TS_RESET_OUT        => nx_ts_reset_1,
-      OFFLINE_OUT            => nxyter_offline,
+      I2C_SM_RESET_OUT         => i2c_sm_reset_o,
+      I2C_REG_RESET_OUT        => i2c_reg_reset_o,
+      NX_TS_RESET_OUT          => nx_ts_reset_1,
+      OFFLINE_OUT              => nxyter_offline_reg,
 
       NX_DATA_CLK_DPHASE_OUT   => nx1_data_clk_dphase,
       NX_DATA_CLK_FINEDELB_OUT => nx1_data_clk_finedelb,
@@ -314,16 +316,16 @@ begin
       NX_DATA_CLK_CLKOS_IN     => nx1_data_clk_clkos,
       NX_DATA_CLK_CLKOK_IN     => nx1_data_clk_clkok,
       
-      SLV_READ_IN            => slv_read(0),
-      SLV_WRITE_IN           => slv_write(0),
-      SLV_DATA_OUT           => slv_data_rd(0*32+31 downto 0*32),
-      SLV_DATA_IN            => slv_data_wr(0*32+31 downto 0*32),
-      SLV_ADDR_IN            => slv_addr(0*16+15 downto 0*16),
-      SLV_ACK_OUT            => slv_ack(0),
-      SLV_NO_MORE_DATA_OUT   => slv_no_more_data(0),
-      SLV_UNKNOWN_ADDR_OUT   => slv_unknown_addr(0),
-
-      DEBUG_OUT              => debug_line(0)
+      SLV_READ_IN              => slv_read(0),
+      SLV_WRITE_IN             => slv_write(0),
+      SLV_DATA_OUT             => slv_data_rd(0*32+31 downto 0*32),
+      SLV_DATA_IN              => slv_data_wr(0*32+31 downto 0*32),
+      SLV_ADDR_IN              => slv_addr(0*16+15 downto 0*16),
+      SLV_ACK_OUT              => slv_ack(0),
+      SLV_NO_MORE_DATA_OUT     => slv_no_more_data(0),
+      SLV_UNKNOWN_ADDR_OUT     => slv_unknown_addr(0),
+
+      DEBUG_OUT                => debug_line(0)
       );
 
   nx_setup_1: nx_setup
@@ -334,6 +336,8 @@ begin
       I2C_COMMAND_BUSY_IN  => i2c_command_busy,
       I2C_DATA_IN          => i2c_data,
       I2C_LOCK_OUT         => i2c_lock,
+      I2C_ONLINE_OUT       => nxyter_online_i2c,
+      I2C_REG_RESET_IN     => i2c_reg_reset_o,
       SPI_COMMAND_OUT      => spi_command,
       SPI_COMMAND_BUSY_IN  => spi_command_busy,
       SPI_DATA_IN          => spi_data,
@@ -349,6 +353,8 @@ begin
  
       DEBUG_OUT            => debug_line(1)
       );
+
+  nxyter_offline <= (not nxyter_online_i2c) or nxyter_offline_reg;
   
 -------------------------------------------------------------------------------
 -- I2C master block for accessing the nXyter
index 6a82ce646af9a876e35e8bfdcf73c34b3c686ade..539992a6cf3f7576ae6c01cbddfb6e47179f981b 100644 (file)
@@ -19,7 +19,7 @@ entity nxyter_registers is
     I2C_REG_RESET_OUT      : out std_logic;
     NX_TS_RESET_OUT        : out std_logic;
     OFFLINE_OUT            : out std_logic;
-
+        
     -- NX Data Clock Handler
     NX_DATA_CLK_DPHASE_OUT   : out std_logic_vector(3 downto 0);
     NX_DATA_CLK_FINEDELB_OUT : out std_logic_vector(3 downto 0);
diff --git a/nxyter/source/pulse_delay.vhd b/nxyter/source/pulse_delay.vhd
new file mode 100644 (file)
index 0000000..72e2b97
--- /dev/null
@@ -0,0 +1,97 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.nxyter_components.all;
+
+entity pulse_delay is
+  generic (
+    DELAY : integer range 2 to 16777216 := 100
+    );
+  port (
+    CLK_IN        : in  std_logic;  
+    RESET_IN      : in  std_logic;
+    
+    PULSE_IN      : in  std_logic;  
+    PULSE_OUT     : out std_logic
+    );
+
+end entity;
+
+architecture Behavioral of pulse_delay is
+
+  signal start_timer_x  : unsigned(23 downto 0);
+
+  signal start_timer    : unsigned(23 downto 0);
+  signal timer_done     : std_logic;
+  signal pulse_o        : std_logic;
+
+  type STATES is (IDLE,
+                  WAIT_TIMER
+                  );
+  signal STATE, NEXT_STATE : STATES;
+  
+begin
+  
+  nx_timer_1: nx_timer
+    generic map (
+      CTR_WIDTH => 24
+      )
+    port map (
+      CLK_IN          => CLK_IN,
+      RESET_IN        => RESET_IN,
+      TIMER_START_IN  => start_timer,
+      TIMER_DONE_OUT  => timer_done
+      );
+
+  PROC_CONVERT_TRANSFER: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        start_timer    <= (others => '0');
+        STATE          <= IDLE;
+      else
+        start_timer    <= start_timer_x;
+        STATE          <= NEXT_STATE;
+      end if;
+    end if;
+  end process PROC_CONVERT_TRANSFER; 
+  
+  PROC_CONVERT: process(STATE,
+                        PULSE_IN,
+                        timer_done
+                        )
+    constant TIMER_VALUE :
+    unsigned(23 downto 0) := to_unsigned(DELAY - 1, 24);
+
+  begin
+    pulse_o                <= '0';
+    case STATE is
+      when IDLE =>
+        if (PULSE_IN = '1') then
+          start_timer_x    <= TIMER_VALUE;
+          pulse_o          <= '0';
+          NEXT_STATE       <= WAIT_TIMER;
+        else
+          start_timer_x    <= (others => '0');
+          pulse_o                <= '0';
+          NEXT_STATE       <= IDLE;
+        end if;
+
+      when WAIT_TIMER =>
+        start_timer_x      <= (others => '0');
+        if (timer_done = '0') then
+          pulse_o                <= '0';
+          NEXT_STATE       <= WAIT_TIMER; 
+        else
+          pulse_o          <= '1';
+          NEXT_STATE       <= IDLE;
+        end if;
+
+    end case;
+  end process PROC_CONVERT;
+
+  -- Output Signals
+  PULSE_OUT   <= pulse_o;
+  
+end Behavioral;
index 87d834495304a9465a18b33520d60451d78f01a6..bbab26907960b6ab6e4c1a63e0e9a99db27b58da 100644 (file)
 
 -- NX I2C Setup Handler
 0x8200 : r/w   I2C Memeory Register (Depth: 0 - 45 ... 0x822c) 
-0x8260 : r/w   DAC Register Memory (Depth: 0 - 128 ... 0x82e0) 
-0x8240 : w     Read all I2C Registers into Memory     
-0x8241 : w     Write all Memory to I2C Registers     
-0x8242 : w     Read Trim DAC Register(129 deep FIFO) to Memory
-0x8243 : w     Write Memory to Trim DAC Register(129 deep FIFO)    
+0x8300 : r/w   DAC Register Memory (Depth: 0 - 128 ... 0x82e0) 
+0x8250 : r/w   Enable Nxyter Clock 
+0x8251 : r/w   Nxyter Polarity
+0x8252 : r     Nxyter Testpulse Polarity 
+0x8253 : r/w   Enable Nxyter Testpulse
+0x8254 : r/w   Enable Nxyter Testtrigger
+0x8255 : r/w   Nxyter Testpulse Channels (0: 0,4,..   1: 1,5,..
+                                          2: 2,6,..   3: 3,7,..)
+0x8256 : r     Nxyter I2C Online
+0x8260 : w     Read all I2C Registers into Memory     
+0x8261 : w     Read Trim DAC Register(129 deep FIFO) into Memory
 
 -- Trigger Generator
 0x8140 :  r/w  Length of Trigger TestPulse (12 Bit, in 4ns)
@@ -24,7 +30,7 @@
 -- Trigger Handler
 0x8160 :  r/w  Enable Testpulse Signal (default: off)
 0x8161 :  r/w  Delay Testpulse Signal after Trigger (12 Bit, in 10ns)
-0x8162 :  r    Accepted Trigger Rate (in Hz)
+0x8162 :  r    Accepted Trigger Rate (28 Bit, in Hz)
 0x8163 :  r/w  r: Invalid Timing Trigger Counter
                w: clear Counter
 
diff --git a/nxyter/source/signal_async_to_pulse.vhd b/nxyter/source/signal_async_to_pulse.vhd
new file mode 100644 (file)
index 0000000..526762f
--- /dev/null
@@ -0,0 +1,55 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.nxyter_components.all;
+
+entity signal_async_to_pulse is
+  generic (
+    NUM_FF : integer range 2 to 4 := 2
+    );
+  port (
+    CLK_IN       : in  std_logic;
+    RESET_IN     : in  std_logic;
+    PULSE_A_IN   : in  std_logic;
+    PULSE_OUT    : out std_logic
+    );
+
+end entity;
+
+architecture Behavioral of signal_async_to_pulse is
+  signal pulse_ff      : std_logic_vector(NUM_FF - 1 downto 0);
+  signal pulse_o       : std_logic;
+
+begin
+
+  -----------------------------------------------------------------------------
+  -- Clock CLK_IN Domain
+  -----------------------------------------------------------------------------
+
+  PROC_SYNC_PULSE: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      pulse_ff(NUM_FF - 1)             <= PULSE_A_IN;
+      if( RESET_IN = '1' ) then
+        pulse_ff(NUM_FF - 2 downto 0)  <= (others => '0');
+      else
+        for i in NUM_FF - 2 downto 0 loop
+          pulse_ff(i)                  <= pulse_ff(i + 1); 
+        end loop;
+      end if;
+    end if;
+  end process PROC_SYNC_PULSE;
+
+  level_to_pulse_1: level_to_pulse
+    port map (
+      CLK_IN    => CLK_IN,
+      RESET_IN  => RESET_IN,
+      LEVEL_IN  => pulse_ff(0),
+      PULSE_OUT => pulse_o
+      );
+
+  -- Outputs
+  PULSE_OUT     <= pulse_o;
+    
+end Behavioral;
index a61915db8bd548c0b6fe79c56083cc133831ceed..70f459d5cf970fa060db66a8ff753060cd5e9652 100644 (file)
@@ -158,6 +158,7 @@ add_file -vhdl -lib "work" "source/pulse_to_level.vhd"
 add_file -vhdl -lib "work" "source/pulse_dtrans.vhd"
 add_file -vhdl -lib "work" "source/signal_async_to_pulse.vhd"
 add_file -vhdl -lib "work" "source/signal_async_trans.vhd"
+add_file -vhdl -lib "work" "source/pulse_delay.vhd"
 add_file -vhdl -lib "work" "source/gray_decoder.vhd"
 add_file -vhdl -lib "work" "source/gray_encoder.vhd"
 add_file -vhdl -lib "work" "source/nx_timer.vhd"
index 6cbf6d30aced21c2d2964332bf8d6937fcebe4c0..a98ad15c2fda88bee9da023829d2c128637541c1 100644 (file)
@@ -39,7 +39,7 @@ BLOCK RD_DURING_WR_PATHS ;
   FREQUENCY PORT NX1_DATA_CLK_IN 125 MHz;
   FREQUENCY PORT NX2_DATA_CLK_IN 125 MHz;
   
-  USE PRIMARY NET "nx_main_clk"; 
+  USE PRIMARY NET "nx_main_clk_*"; 
   USE PRIMARY NET "clk_100_i_c";
   USE PRIMARY NET "CLK_PCLK_RIGHT_c";